@gobing-ai/knowledge-kit 0.1.11 → 0.1.13

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 (137) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/dist/index.js +2372 -1722
  3. package/package.json +1 -1
  4. package/plugins/generations/image-gen/README.md +108 -0
  5. package/plugins/generations/image-gen/assets/sample/cover__clean-webapp-ui.jpg +0 -0
  6. package/plugins/generations/image-gen/assets/sample/cover__cute.jpg +0 -0
  7. package/plugins/generations/image-gen/assets/sample/cover__daily-news.jpg +0 -0
  8. package/plugins/generations/image-gen/assets/sample/cover__editorial.jpg +0 -0
  9. package/plugins/generations/image-gen/assets/sample/cover__fresh.jpg +0 -0
  10. package/plugins/generations/image-gen/assets/sample/cover__minimalist.jpg +0 -0
  11. package/plugins/generations/image-gen/assets/sample/cover__photorealistic.jpg +0 -0
  12. package/plugins/generations/image-gen/assets/sample/cover__sketch.jpg +0 -0
  13. package/plugins/generations/image-gen/assets/sample/cover__technical-diagram.jpg +0 -0
  14. package/plugins/generations/image-gen/assets/sample/cover__vibrant.jpg +0 -0
  15. package/plugins/generations/image-gen/assets/sample/cover__warm.jpg +0 -0
  16. package/plugins/generations/image-gen/assets/sample/cover__xhs-knowledge.jpg +0 -0
  17. package/plugins/generations/image-gen/assets/sample/daily-news-cover__clean-webapp-ui.jpg +0 -0
  18. package/plugins/generations/image-gen/assets/sample/daily-news-cover__cute.jpg +0 -0
  19. package/plugins/generations/image-gen/assets/sample/daily-news-cover__daily-news.jpg +0 -0
  20. package/plugins/generations/image-gen/assets/sample/daily-news-cover__editorial.jpg +0 -0
  21. package/plugins/generations/image-gen/assets/sample/daily-news-cover__fresh.jpg +0 -0
  22. package/plugins/generations/image-gen/assets/sample/daily-news-cover__minimalist.jpg +0 -0
  23. package/plugins/generations/image-gen/assets/sample/daily-news-cover__photorealistic.jpg +0 -0
  24. package/plugins/generations/image-gen/assets/sample/daily-news-cover__sketch.jpg +0 -0
  25. package/plugins/generations/image-gen/assets/sample/daily-news-cover__technical-diagram.jpg +0 -0
  26. package/plugins/generations/image-gen/assets/sample/daily-news-cover__vibrant.jpg +0 -0
  27. package/plugins/generations/image-gen/assets/sample/daily-news-cover__warm.jpg +0 -0
  28. package/plugins/generations/image-gen/assets/sample/daily-news-cover__xhs-knowledge.jpg +0 -0
  29. package/plugins/generations/image-gen/assets/sample/free__clean-webapp-ui.jpg +0 -0
  30. package/plugins/generations/image-gen/assets/sample/free__cute.jpg +0 -0
  31. package/plugins/generations/image-gen/assets/sample/free__daily-news.jpg +0 -0
  32. package/plugins/generations/image-gen/assets/sample/free__editorial.jpg +0 -0
  33. package/plugins/generations/image-gen/assets/sample/free__fresh.jpg +0 -0
  34. package/plugins/generations/image-gen/assets/sample/free__minimalist.jpg +0 -0
  35. package/plugins/generations/image-gen/assets/sample/free__photorealistic.jpg +0 -0
  36. package/plugins/generations/image-gen/assets/sample/free__sketch.jpg +0 -0
  37. package/plugins/generations/image-gen/assets/sample/free__technical-diagram.jpg +0 -0
  38. package/plugins/generations/image-gen/assets/sample/free__vibrant.jpg +0 -0
  39. package/plugins/generations/image-gen/assets/sample/free__warm.jpg +0 -0
  40. package/plugins/generations/image-gen/assets/sample/free__xhs-knowledge.jpg +0 -0
  41. package/plugins/generations/image-gen/assets/sample/illustration__clean-webapp-ui.jpg +0 -0
  42. package/plugins/generations/image-gen/assets/sample/illustration__cute.jpg +0 -0
  43. package/plugins/generations/image-gen/assets/sample/illustration__daily-news.jpg +0 -0
  44. package/plugins/generations/image-gen/assets/sample/illustration__editorial.jpg +0 -0
  45. package/plugins/generations/image-gen/assets/sample/illustration__fresh.jpg +0 -0
  46. package/plugins/generations/image-gen/assets/sample/illustration__minimalist.jpg +0 -0
  47. package/plugins/generations/image-gen/assets/sample/illustration__photorealistic.jpg +0 -0
  48. package/plugins/generations/image-gen/assets/sample/illustration__sketch.jpg +0 -0
  49. package/plugins/generations/image-gen/assets/sample/illustration__technical-diagram.jpg +0 -0
  50. package/plugins/generations/image-gen/assets/sample/illustration__vibrant.jpg +0 -0
  51. package/plugins/generations/image-gen/assets/sample/illustration__warm.jpg +0 -0
  52. package/plugins/generations/image-gen/assets/sample/illustration__xhs-knowledge.jpg +0 -0
  53. package/plugins/generations/image-gen/assets/sample/xhs-card__clean-webapp-ui.jpg +0 -0
  54. package/plugins/generations/image-gen/assets/sample/xhs-card__cute.jpg +0 -0
  55. package/plugins/generations/image-gen/assets/sample/xhs-card__daily-news.jpg +0 -0
  56. package/plugins/generations/image-gen/assets/sample/xhs-card__editorial.jpg +0 -0
  57. package/plugins/generations/image-gen/assets/sample/xhs-card__fresh.jpg +0 -0
  58. package/plugins/generations/image-gen/assets/sample/xhs-card__minimalist.jpg +0 -0
  59. package/plugins/generations/image-gen/assets/sample/xhs-card__photorealistic.jpg +0 -0
  60. package/plugins/generations/image-gen/assets/sample/xhs-card__sketch.jpg +0 -0
  61. package/plugins/generations/image-gen/assets/sample/xhs-card__technical-diagram.jpg +0 -0
  62. package/plugins/generations/image-gen/assets/sample/xhs-card__vibrant.jpg +0 -0
  63. package/plugins/generations/image-gen/assets/sample/xhs-card__warm.jpg +0 -0
  64. package/plugins/generations/image-gen/assets/sample/xhs-card__xhs-knowledge.jpg +0 -0
  65. package/plugins/generations/image-gen/dist/index.js +102 -58
  66. package/plugins/generations/image-gen/scripts/compose-e2e-artifact.ts +5 -21
  67. package/plugins/generations/image-gen/scripts/gen-samples.ts +208 -0
  68. package/plugins/generations/image-gen/src/compose/chromium.ts +2 -3
  69. package/plugins/generations/image-gen/src/presets.ts +6 -3
  70. package/plugins/generations/image-gen/src/providers/errors.ts +16 -1
  71. package/plugins/generations/image-gen/src/providers/minimax.ts +46 -17
  72. package/plugins/ingestions/web-search/src/index.ts +1 -1
  73. package/plugins/kk/README.md +18 -0
  74. package/plugins/kk/commands/image-extract.md +1 -0
  75. package/plugins/kk/commands/image-generate.md +1 -0
  76. package/plugins/kk/commands/tell-me.md +1 -0
  77. package/plugins/kk/commands/workflow-run.md +7 -1
  78. package/plugins/kk/decisions/extract/it-topics.yaml +24 -0
  79. package/plugins/kk/decisions/kk-itc.yaml +6 -4
  80. package/plugins/kk/plugin.json +1 -1
  81. package/plugins/kk/publish-presets/daily-ai-voice-migration.json +146 -0
  82. package/plugins/kk/publish-presets/daily-ai-voice.json +15 -7
  83. package/plugins/kk/schedules/kk-collect.grok-bot.md.tmpl +69 -0
  84. package/plugins/kk/schedules/kk-daily-ai-voice3.cron.tmpl +18 -0
  85. package/plugins/kk/schedules/kk-daily-publish3-cn-peak.cron.tmpl +15 -5
  86. package/plugins/kk/schedules/kk-daily-publish3-overseas.cron.tmpl +9 -4
  87. package/plugins/kk/scripts/daily-scheduled-run.ts +91 -41
  88. package/plugins/kk/scripts/daily-stages.ts +394 -53
  89. package/plugins/kk/scripts/kk-workflow-stages.ts +190 -0
  90. package/plugins/kk/scripts/safety-artifact-check.ts +70 -28
  91. package/plugins/kk/scripts/voice3-publish-window.ts +202 -0
  92. package/plugins/kk/skills/article-adapt/SKILL.md +1 -0
  93. package/plugins/kk/skills/audio-authoring/SKILL.md +1 -0
  94. package/plugins/kk/skills/content-judge/SKILL.md +1 -0
  95. package/plugins/kk/skills/content-safety/SKILL.md +1 -0
  96. package/plugins/kk/skills/content-safety/references/platforms/podcast-salty.md +41 -0
  97. package/plugins/kk/skills/content-safety/references/platforms/surfdash.md +36 -0
  98. package/plugins/kk/skills/content-safety/references/platforms/xhs.md +39 -0
  99. package/plugins/kk/skills/explain-things/SKILL.md +1 -0
  100. package/plugins/kk/skills/image-authoring/SKILL.md +1 -0
  101. package/plugins/kk/skills/itc-generating/SKILL.md +1 -0
  102. package/plugins/kk/skills/publish/SKILL.md +1 -0
  103. package/plugins/kk/skills/smart-seo/SKILL.md +1 -0
  104. package/plugins/kk/skills/storm-research/SKILL.md +1 -0
  105. package/plugins/kk/skills/taste-unslop/SKILL.md +1 -0
  106. package/plugins/kk/skills/topic/SKILL.md +1 -0
  107. package/plugins/kk/skills/web-automation/SKILL.md +1 -0
  108. package/plugins/kk/skills/xhs-images/SKILL.md +1 -0
  109. package/plugins/kk/workflows/kk-collect.yaml +3 -3
  110. package/plugins/kk/workflows/kk-daily-ai-voice2.yaml +21 -19
  111. package/plugins/kk/workflows/kk-daily-ai-voice3.yaml +163 -63
  112. package/plugins/kk/workflows/kk-daily-publish3.yaml +82 -26
  113. package/plugins/kk/workflows/kk-daily-safety.yaml +39 -31
  114. package/plugins/kk/workflows/kk-itc-author.yaml +75 -0
  115. package/plugins/kk/workflows/kk-itc-publish-tail.yaml +25 -3
  116. package/plugins/kk/workflows/kk-itc.yaml +36 -4
  117. package/plugins/publishings/linkedin-pub/dist/index.js +21333 -0
  118. package/plugins/publishings/linkedin-pub/dist/profile-check.js +21005 -0
  119. package/plugins/publishings/linkedin-pub/package.json +19 -0
  120. package/plugins/publishings/linkedin-pub/plugin.json +12 -0
  121. package/plugins/publishings/linkedin-pub/src/index.ts +705 -0
  122. package/plugins/publishings/linkedin-pub/src/profile-check.ts +17 -0
  123. package/plugins/publishings/linkedin-pub/tsconfig.json +4 -0
  124. package/plugins/publishings/surfdash-pub/dist/index.js +53 -24
  125. package/plugins/publishings/surfdash-pub/src/index.ts +72 -25
  126. package/plugins/publishings/threads-pub/dist/index.js +7 -0
  127. package/plugins/publishings/threads-pub/src/index.ts +12 -0
  128. package/plugins/publishings/wechatmp-pub/dist/index.js +176 -32
  129. package/plugins/publishings/wechatmp-pub/src/flow.ts +298 -52
  130. package/plugins/publishings/weibo-pub/dist/index.js +100 -7
  131. package/plugins/publishings/weibo-pub/src/index.ts +111 -11
  132. package/plugins/publishings/x-pub/dist/index.js +7 -0
  133. package/plugins/publishings/x-pub/src/index.ts +11 -0
  134. package/plugins/publishings/xhs-pub/dist/index.js +164 -12
  135. package/plugins/publishings/xhs-pub/dist/profile-check.js +11 -1
  136. package/plugins/publishings/xhs-pub/src/flow.ts +194 -23
  137. package/plugins/publishings/xhs-pub/src/page.ts +26 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gobing-ai/knowledge-kit",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
4
4
  "description": "An ingest → create → publish content pipeline CLI (Bun).",
5
5
  "repository": {
6
6
  "type": "git",
@@ -0,0 +1,108 @@
1
+ # image-gen
2
+
3
+ Image generation plugin (`kind: generator`): `free`, `cover` and `illustration` jobs over the
4
+ `Doc[] → Content` contract. Every image is one **format** (canvas, template, job) composed with one
5
+ **style** (visual modifiers); any format pairs with any style.
6
+
7
+ This page is the preset index: one sample per shipped format × style pair, so you can pick a
8
+ combination by eye. Pass the pair as `metadata.imageGen.format` / `metadata.imageGen.style`, or
9
+ `--format` / `--style` to the `kk:image-generate` skill. Omitting the style uses the format's
10
+ default (★ below).
11
+
12
+ Samples: provider `minimax`, model `image-01`, downscaled to 640px JPEG. Inputs are fixed per
13
+ job — subject “a request flowing through an API gateway to three microservices”; cover title “Building Reliable AI Agents”. Regenerate with
14
+ `bun plugins/generations/image-gen/scripts/gen-samples.ts` (see its header for flags).
15
+
16
+ ## Formats
17
+
18
+ | Format | Job | Aspect | Size | Default style | Description |
19
+ | --- | --- | --- | --- | --- | --- |
20
+ | [`cover`](#format-cover) | cover | 21:9 | 1344×576 | vibrant | Article cover image template (21:9 ultrawide cinematic aspect ratio) |
21
+ | [`daily-news-cover`](#format-daily-news-cover) | cover | 21:9 | 1344×576 | daily-news | Daily AI tech-sharing episode cover — fixed composition and palette; subject is the only per-run input |
22
+ | [`free`](#format-free) | free | 1:1 | 1024×1024 | vibrant | General-purpose image generation template with rich art direction defaults |
23
+ | [`illustration`](#format-illustration) | illustration | 4:3 | 1152×864 | technical-diagram | Article illustration template for inline images (4:3 aspect ratio) |
24
+ | [`xhs-card`](#format-xhs-card) | free | 3:4 | 1080×1440 | xhs-knowledge | Xiaohongshu (XHS) knowledge card — 3:4 portrait card. Chinese headline and bullets are typeset from Noto Sans SC via headless Chromium; the provider prompt is the illustration only and must not ask for writing. Adapted from baoyu-xhs-images (MIT © Jim Liu); see plugins/kk/skills/xhs-images/references/card-layouts.md. |
25
+
26
+ ## Styles
27
+
28
+ | Style | Description | Best for |
29
+ | --- | --- | --- |
30
+ | `clean-webapp-ui` | Clean light-mode web-app interface — neutral near-white surfaces, card grid, restrained steel-blue and warm-tan accents on an ink text base. | productivity-tool interfaces, dashboards, knowledge-base and bookmark apps, clean SaaS pages |
31
+ | `cute` | Sweet, playful aesthetic with pastel colors and rounded forms. Kawaii-influenced with soft gradients, gentle curves, and approachable design. Highly engaging on social platforms targeting younger demographics. | |
32
+ | `daily-news` | House style for the kk-daily-ai-voice cover series — flat editorial vector, navy/blue/amber | |
33
+ | `editorial` | Sophisticated, magazine-quality design with strong typography presence and deliberate composition. High-contrast with bold design choices. Communicates authority, expertise, and premium quality. | |
34
+ | `fresh` | Clean, natural aesthetic with bright whites and green-toned accents. Evokes clarity, health, and new beginnings. Light and airy with generous whitespace. | |
35
+ | `minimalist` | Simple, clean aesthetic with plenty of whitespace. Focus on essential elements with subtle colors and elegant composition. Less is more — every element serves a purpose. | |
36
+ | `photorealistic` | Highly detailed, realistic images with professional photography quality. Natural lighting, realistic textures, and cinematic depth create convincing photographic results. | |
37
+ | `sketch` | Hand-drawn, artistic feel with organic lines and pencil drawing aesthetic. Warm and approachable with natural imperfections that convey authenticity and human touch. | |
38
+ | `technical-diagram` | Clean, technical illustrations with precise lines and professional diagram style. Minimal color palette focused on clarity and technical accuracy. Communicates complexity with visual simplicity. | |
39
+ | `vibrant` | Bold colors and high contrast for eye-catching visuals. Energetic and dynamic composition designed to grab attention. Maximum visual impact with saturated hues and dramatic lighting. | |
40
+ | `warm` | Cozy, friendly aesthetic with warm color temperature and inviting atmosphere. Evokes comfort, trust, and approachability. Popular on lifestyle and social media platforms. | |
41
+ | `xhs-knowledge` | Notion-like knowledge card aesthetic for XHS image-text series — simple light background, clean information layout, soft accent colors, rounded card zones. Adapted from baoyu-xhs-images "knowledge card" style guidance (MIT © Jim Liu); see plugins/kk/skills/xhs-images/references/card-layouts.md. | |
42
+
43
+ ## Gallery
44
+
45
+ <a id="format-cover"></a>
46
+
47
+ ### cover
48
+
49
+ cover job · 21:9 · default style `vibrant`
50
+
51
+ | | | |
52
+ | --- | --- | --- |
53
+ | <img src="assets/sample/cover__clean-webapp-ui.jpg" alt="cover × clean-webapp-ui" width="260"><br>`clean-webapp-ui` | <img src="assets/sample/cover__cute.jpg" alt="cover × cute" width="260"><br>`cute` | <img src="assets/sample/cover__daily-news.jpg" alt="cover × daily-news" width="260"><br>`daily-news` |
54
+ | <img src="assets/sample/cover__editorial.jpg" alt="cover × editorial" width="260"><br>`editorial` | <img src="assets/sample/cover__fresh.jpg" alt="cover × fresh" width="260"><br>`fresh` | <img src="assets/sample/cover__minimalist.jpg" alt="cover × minimalist" width="260"><br>`minimalist` |
55
+ | <img src="assets/sample/cover__photorealistic.jpg" alt="cover × photorealistic" width="260"><br>`photorealistic` | <img src="assets/sample/cover__sketch.jpg" alt="cover × sketch" width="260"><br>`sketch` | <img src="assets/sample/cover__technical-diagram.jpg" alt="cover × technical-diagram" width="260"><br>`technical-diagram` |
56
+ | <img src="assets/sample/cover__vibrant.jpg" alt="cover × vibrant" width="260"><br>`vibrant` ★ | <img src="assets/sample/cover__warm.jpg" alt="cover × warm" width="260"><br>`warm` | <img src="assets/sample/cover__xhs-knowledge.jpg" alt="cover × xhs-knowledge" width="260"><br>`xhs-knowledge` |
57
+
58
+ <a id="format-daily-news-cover"></a>
59
+
60
+ ### daily-news-cover
61
+
62
+ cover job · 21:9 · default style `daily-news`
63
+
64
+ | | | |
65
+ | --- | --- | --- |
66
+ | <img src="assets/sample/daily-news-cover__clean-webapp-ui.jpg" alt="daily-news-cover × clean-webapp-ui" width="260"><br>`clean-webapp-ui` | <img src="assets/sample/daily-news-cover__cute.jpg" alt="daily-news-cover × cute" width="260"><br>`cute` | <img src="assets/sample/daily-news-cover__daily-news.jpg" alt="daily-news-cover × daily-news" width="260"><br>`daily-news` ★ |
67
+ | <img src="assets/sample/daily-news-cover__editorial.jpg" alt="daily-news-cover × editorial" width="260"><br>`editorial` | <img src="assets/sample/daily-news-cover__fresh.jpg" alt="daily-news-cover × fresh" width="260"><br>`fresh` | <img src="assets/sample/daily-news-cover__minimalist.jpg" alt="daily-news-cover × minimalist" width="260"><br>`minimalist` |
68
+ | <img src="assets/sample/daily-news-cover__photorealistic.jpg" alt="daily-news-cover × photorealistic" width="260"><br>`photorealistic` | <img src="assets/sample/daily-news-cover__sketch.jpg" alt="daily-news-cover × sketch" width="260"><br>`sketch` | <img src="assets/sample/daily-news-cover__technical-diagram.jpg" alt="daily-news-cover × technical-diagram" width="260"><br>`technical-diagram` |
69
+ | <img src="assets/sample/daily-news-cover__vibrant.jpg" alt="daily-news-cover × vibrant" width="260"><br>`vibrant` | <img src="assets/sample/daily-news-cover__warm.jpg" alt="daily-news-cover × warm" width="260"><br>`warm` | <img src="assets/sample/daily-news-cover__xhs-knowledge.jpg" alt="daily-news-cover × xhs-knowledge" width="260"><br>`xhs-knowledge` |
70
+
71
+ <a id="format-free"></a>
72
+
73
+ ### free
74
+
75
+ free job · 1:1 · default style `vibrant`
76
+
77
+ | | | |
78
+ | --- | --- | --- |
79
+ | <img src="assets/sample/free__clean-webapp-ui.jpg" alt="free × clean-webapp-ui" width="260"><br>`clean-webapp-ui` | <img src="assets/sample/free__cute.jpg" alt="free × cute" width="260"><br>`cute` | <img src="assets/sample/free__daily-news.jpg" alt="free × daily-news" width="260"><br>`daily-news` |
80
+ | <img src="assets/sample/free__editorial.jpg" alt="free × editorial" width="260"><br>`editorial` | <img src="assets/sample/free__fresh.jpg" alt="free × fresh" width="260"><br>`fresh` | <img src="assets/sample/free__minimalist.jpg" alt="free × minimalist" width="260"><br>`minimalist` |
81
+ | <img src="assets/sample/free__photorealistic.jpg" alt="free × photorealistic" width="260"><br>`photorealistic` | <img src="assets/sample/free__sketch.jpg" alt="free × sketch" width="260"><br>`sketch` | <img src="assets/sample/free__technical-diagram.jpg" alt="free × technical-diagram" width="260"><br>`technical-diagram` |
82
+ | <img src="assets/sample/free__vibrant.jpg" alt="free × vibrant" width="260"><br>`vibrant` ★ | <img src="assets/sample/free__warm.jpg" alt="free × warm" width="260"><br>`warm` | <img src="assets/sample/free__xhs-knowledge.jpg" alt="free × xhs-knowledge" width="260"><br>`xhs-knowledge` |
83
+
84
+ <a id="format-illustration"></a>
85
+
86
+ ### illustration
87
+
88
+ illustration job · 4:3 · default style `technical-diagram`
89
+
90
+ | | | |
91
+ | --- | --- | --- |
92
+ | <img src="assets/sample/illustration__clean-webapp-ui.jpg" alt="illustration × clean-webapp-ui" width="260"><br>`clean-webapp-ui` | <img src="assets/sample/illustration__cute.jpg" alt="illustration × cute" width="260"><br>`cute` | <img src="assets/sample/illustration__daily-news.jpg" alt="illustration × daily-news" width="260"><br>`daily-news` |
93
+ | <img src="assets/sample/illustration__editorial.jpg" alt="illustration × editorial" width="260"><br>`editorial` | <img src="assets/sample/illustration__fresh.jpg" alt="illustration × fresh" width="260"><br>`fresh` | <img src="assets/sample/illustration__minimalist.jpg" alt="illustration × minimalist" width="260"><br>`minimalist` |
94
+ | <img src="assets/sample/illustration__photorealistic.jpg" alt="illustration × photorealistic" width="260"><br>`photorealistic` | <img src="assets/sample/illustration__sketch.jpg" alt="illustration × sketch" width="260"><br>`sketch` | <img src="assets/sample/illustration__technical-diagram.jpg" alt="illustration × technical-diagram" width="260"><br>`technical-diagram` ★ |
95
+ | <img src="assets/sample/illustration__vibrant.jpg" alt="illustration × vibrant" width="260"><br>`vibrant` | <img src="assets/sample/illustration__warm.jpg" alt="illustration × warm" width="260"><br>`warm` | <img src="assets/sample/illustration__xhs-knowledge.jpg" alt="illustration × xhs-knowledge" width="260"><br>`xhs-knowledge` |
96
+
97
+ <a id="format-xhs-card"></a>
98
+
99
+ ### xhs-card
100
+
101
+ free job · 3:4 · default style `xhs-knowledge`
102
+
103
+ | | | |
104
+ | --- | --- | --- |
105
+ | <img src="assets/sample/xhs-card__clean-webapp-ui.jpg" alt="xhs-card × clean-webapp-ui" width="260"><br>`clean-webapp-ui` | <img src="assets/sample/xhs-card__cute.jpg" alt="xhs-card × cute" width="260"><br>`cute` | <img src="assets/sample/xhs-card__daily-news.jpg" alt="xhs-card × daily-news" width="260"><br>`daily-news` |
106
+ | <img src="assets/sample/xhs-card__editorial.jpg" alt="xhs-card × editorial" width="260"><br>`editorial` | <img src="assets/sample/xhs-card__fresh.jpg" alt="xhs-card × fresh" width="260"><br>`fresh` | <img src="assets/sample/xhs-card__minimalist.jpg" alt="xhs-card × minimalist" width="260"><br>`minimalist` |
107
+ | <img src="assets/sample/xhs-card__photorealistic.jpg" alt="xhs-card × photorealistic" width="260"><br>`photorealistic` | <img src="assets/sample/xhs-card__sketch.jpg" alt="xhs-card × sketch" width="260"><br>`sketch` | <img src="assets/sample/xhs-card__technical-diagram.jpg" alt="xhs-card × technical-diagram" width="260"><br>`technical-diagram` |
108
+ | <img src="assets/sample/xhs-card__vibrant.jpg" alt="xhs-card × vibrant" width="260"><br>`vibrant` | <img src="assets/sample/xhs-card__warm.jpg" alt="xhs-card × warm" width="260"><br>`warm` | <img src="assets/sample/xhs-card__xhs-knowledge.jpg" alt="xhs-card × xhs-knowledge" width="260"><br>`xhs-knowledge` ★ |
@@ -12985,10 +12985,11 @@ function resolvePlaceholder(expr, vars, formatName) {
12985
12985
  const name = expr.slice(0, pipe).trim();
12986
12986
  const fallback = expr.slice(pipe + 1).trimStart();
12987
12987
  const value = vars[name];
12988
+ const slot = `{{${name}}}`;
12988
12989
  if (!value) {
12989
- return fallback;
12990
+ return fallback.includes(slot) ? "" : fallback;
12990
12991
  }
12991
- return fallback.includes(`{{${name}}}`) ? fallback.split(`{{${name}}}`).join(value) : value;
12992
+ return fallback.includes(slot) ? fallback.split(slot).join(value) : value;
12992
12993
  }
12993
12994
  const name = expr.trim();
12994
12995
  const value = vars[name];
@@ -14702,10 +14703,75 @@ var createJimeng = (options) => {
14702
14703
  };
14703
14704
 
14704
14705
  // ../../plugins/generations/image-gen/src/providers/minimax.ts
14706
+ init_dist();
14705
14707
  import { Buffer as Buffer7 } from "buffer";
14708
+ import { setTimeout as delay } from "timers/promises";
14709
+
14710
+ // ../../plugins/generations/image-gen/src/providers/errors.ts
14711
+ function minimaxErrorClass(code) {
14712
+ if ([1026, 1027, 1040, 1046].includes(code))
14713
+ return "policy";
14714
+ if ([1004, 2049].includes(code))
14715
+ return "auth";
14716
+ if ([1002, 1008, 1039, 1045, 2056].includes(code))
14717
+ return "quota";
14718
+ if ([1000, 1001, 1024, 1033].includes(code))
14719
+ return "transient";
14720
+ return "unknown";
14721
+ }
14722
+ var POLICY_RE = /content[_ -]?policy|moderation|safety|sensitive|inappropriate|violat|blocked/i;
14723
+ var AUTH_RE = /api[_ -]?key|unauthori[sz]ed|authenticat|forbidden|requires [A-Z_]+|is required/i;
14724
+ var QUOTA_RE = /quota|rate[_ -]?limit|insufficient|balance|billing|exceeded|too many requests/i;
14725
+ var TRANSIENT_RE = /timed? ?out|ECONNRESET|ETIMEDOUT|ECONNREFUSED|fetch failed|socket|model loading/i;
14726
+ var TRANSIENT_NAMES = new Set(["TimeoutError", "AbortError"]);
14727
+ function statusesIn(message) {
14728
+ const statuses = [];
14729
+ for (const match of message.matchAll(/\((\d{3})\)|HTTP\s+(\d{3})\b|:\s*(\d{3})\s*$/gi)) {
14730
+ const status = match[1] ?? match[2] ?? match[3];
14731
+ if (status !== undefined)
14732
+ statuses.push(Number(status));
14733
+ }
14734
+ return statuses;
14735
+ }
14736
+ function partsOf(err) {
14737
+ if (typeof err !== "object" || err === null)
14738
+ return { name: "", message: "" };
14739
+ const candidate = err;
14740
+ return {
14741
+ name: typeof candidate.name === "string" ? candidate.name : "",
14742
+ message: typeof candidate.message === "string" ? candidate.message : ""
14743
+ };
14744
+ }
14745
+ function classifyProviderError(err) {
14746
+ const parts = partsOf(err);
14747
+ const statuses = statusesIn(parts.message);
14748
+ const miniCode = /^MiniMax API error \(status_code=(\d+)\):/.exec(parts.message)?.[1];
14749
+ const miniClass = miniCode === undefined ? "unknown" : minimaxErrorClass(Number(miniCode));
14750
+ if (miniClass === "policy" || POLICY_RE.test(parts.message))
14751
+ return "policy";
14752
+ if (miniCode !== undefined)
14753
+ return miniClass;
14754
+ if (statuses.some((status) => status === 401 || status === 403) || AUTH_RE.test(parts.message))
14755
+ return "auth";
14756
+ if (statuses.some((status) => status === 402 || status === 429) || QUOTA_RE.test(parts.message))
14757
+ return "quota";
14758
+ if (TRANSIENT_NAMES.has(parts.name) || statuses.some((status) => status === 408 || status >= 500 && status <= 599) || TRANSIENT_RE.test(parts.message)) {
14759
+ return "transient";
14760
+ }
14761
+ return "unknown";
14762
+ }
14763
+ function isFallbackEligible(cls) {
14764
+ return cls !== "policy";
14765
+ }
14766
+
14767
+ // ../../plugins/generations/image-gen/src/providers/minimax.ts
14706
14768
  var DEFAULT_MODEL9 = "image-01";
14707
14769
  var MAX_REFERENCE_IMAGE_BYTES = 10 * 1024 * 1024;
14708
14770
  var SUPPORTED_ASPECT_RATIOS = new Set(["1:1", "16:9", "4:3", "3:2", "2:3", "3:4", "9:16", "21:9"]);
14771
+ function responseError(result) {
14772
+ const code = result?.base_resp?.status_code;
14773
+ return code !== undefined && code !== 0 ? new Error(`MiniMax API error (status_code=${code}): ${result.base_resp?.status_msg ?? "unknown error"}`) : null;
14774
+ }
14709
14775
  function isAcceptablePixelSize(width, height) {
14710
14776
  return width >= 512 && width <= 2048 && height >= 512 && height <= 2048 && width % 8 === 0 && height % 8 === 0;
14711
14777
  }
@@ -14769,10 +14835,9 @@ async function buildSubjectReference(referenceImages) {
14769
14835
  return subjectReference;
14770
14836
  }
14771
14837
  async function extractImageFromResponse4(result, fetchFn = fetch, timeoutMs = PROVIDER_REQUEST_TIMEOUT_MS) {
14772
- const baseResp = result.base_resp;
14773
- if (baseResp?.status_code !== undefined && baseResp.status_code !== 0) {
14774
- throw new Error(baseResp.status_msg ?? `MiniMax API returned status_code=${baseResp.status_code}`);
14775
- }
14838
+ const error = responseError(result);
14839
+ if (error !== null)
14840
+ throw error;
14776
14841
  const base64Image = result.data?.image_base64?.[0];
14777
14842
  if (base64Image !== undefined)
14778
14843
  return Uint8Array.from(Buffer7.from(base64Image, "base64"));
@@ -14809,16 +14874,37 @@ var createMinimax = (options) => {
14809
14874
  body.subject_reference = subjectReference;
14810
14875
  const base = (readEnv("MINIMAX_BASE_URL") || "https://api.minimaxi.com").replace(/\/+$/g, "");
14811
14876
  const url = base.endsWith("/v1") ? `${base}/image_generation` : `${base}/v1/image_generation`;
14812
- const response = await fetchFn(url, {
14813
- method: "POST",
14814
- headers: { "content-type": "application/json", authorization: `Bearer ${apiKey}` },
14815
- body: JSON.stringify(body),
14816
- signal: AbortSignal.timeout(timeoutMs)
14817
- });
14818
- if (!response.ok) {
14819
- throw new Error(`MiniMax API error (${response.status}): ${await response.text()}`);
14820
- }
14821
- const bytes = await extractImageFromResponse4(await response.json(), fetchFn, timeoutMs);
14877
+ const signal = AbortSignal.timeout(timeoutMs);
14878
+ let result;
14879
+ for (let attempt = 1;; attempt += 1) {
14880
+ signal.throwIfAborted();
14881
+ const response = await fetchFn(url, {
14882
+ method: "POST",
14883
+ headers: { "content-type": "application/json", authorization: `Bearer ${apiKey}` },
14884
+ body: JSON.stringify(body),
14885
+ signal
14886
+ });
14887
+ let error;
14888
+ if (response.ok) {
14889
+ result = await response.json();
14890
+ error = responseError(result);
14891
+ if (error === null)
14892
+ break;
14893
+ } else {
14894
+ const detail = await response.text();
14895
+ let businessError = null;
14896
+ try {
14897
+ businessError = responseError(JSON.parse(detail));
14898
+ } catch {}
14899
+ error = businessError ?? new Error(`MiniMax API error (${response.status}): ${detail}`);
14900
+ }
14901
+ if (attempt >= 3 || classifyProviderError(error) !== "transient")
14902
+ throw error;
14903
+ const delayMs = attempt * 1000;
14904
+ echoError(`WARN image-gen: ${error.message}; retrying MiniMax (${attempt + 1}/3) after ${delayMs}ms`);
14905
+ await delay(delayMs, undefined, { signal });
14906
+ }
14907
+ const bytes = await extractImageFromResponse4(result, fetchFn, timeoutMs);
14822
14908
  return { bytes, extension: "jpg", provider: "minimax", model: req.model };
14823
14909
  }
14824
14910
  };
@@ -15483,48 +15569,6 @@ var createZai = (options) => {
15483
15569
  };
15484
15570
  };
15485
15571
 
15486
- // ../../plugins/generations/image-gen/src/providers/errors.ts
15487
- var POLICY_RE = /content[_ -]?policy|moderation|safety|sensitive|inappropriate|violat|blocked/i;
15488
- var AUTH_RE = /api[_ -]?key|unauthori[sz]ed|authenticat|forbidden|requires [A-Z_]+|is required/i;
15489
- var QUOTA_RE = /quota|rate[_ -]?limit|insufficient|balance|billing|exceeded|too many requests/i;
15490
- var TRANSIENT_RE = /timed? ?out|ECONNRESET|ETIMEDOUT|ECONNREFUSED|fetch failed|socket|model loading/i;
15491
- var TRANSIENT_NAMES = new Set(["TimeoutError", "AbortError"]);
15492
- function statusesIn(message) {
15493
- const statuses = [];
15494
- for (const match of message.matchAll(/\((\d{3})\)|HTTP\s+(\d{3})\b|:\s*(\d{3})\s*$/gi)) {
15495
- const status = match[1] ?? match[2] ?? match[3];
15496
- if (status !== undefined)
15497
- statuses.push(Number(status));
15498
- }
15499
- return statuses;
15500
- }
15501
- function partsOf(err) {
15502
- if (typeof err !== "object" || err === null)
15503
- return { name: "", message: "" };
15504
- const candidate = err;
15505
- return {
15506
- name: typeof candidate.name === "string" ? candidate.name : "",
15507
- message: typeof candidate.message === "string" ? candidate.message : ""
15508
- };
15509
- }
15510
- function classifyProviderError(err) {
15511
- const parts = partsOf(err);
15512
- const statuses = statusesIn(parts.message);
15513
- if (POLICY_RE.test(parts.message))
15514
- return "policy";
15515
- if (statuses.some((status) => status === 401 || status === 403) || AUTH_RE.test(parts.message))
15516
- return "auth";
15517
- if (statuses.some((status) => status === 402 || status === 429) || QUOTA_RE.test(parts.message))
15518
- return "quota";
15519
- if (TRANSIENT_NAMES.has(parts.name) || statuses.some((status) => status === 408 || status >= 500 && status <= 599) || TRANSIENT_RE.test(parts.message)) {
15520
- return "transient";
15521
- }
15522
- return "unknown";
15523
- }
15524
- function isFallbackEligible(cls) {
15525
- return cls !== "policy";
15526
- }
15527
-
15528
15572
  // ../../plugins/generations/image-gen/src/providers/types.ts
15529
15573
  var IMAGE_GEN_PROVIDER_ENV = "IMAGE_GEN_PROVIDER";
15530
15574
  var NEVER_AUTO = new Set(["codex-cli"]);
@@ -10,11 +10,8 @@
10
10
  * bun scripts/compose-e2e-artifact.ts with # one variant (fixture illustration)
11
11
  * bun scripts/compose-e2e-artifact.ts r2 # 0181 R2: good card + overflow refusal
12
12
  *
13
- * Each variant runs in its own subprocess (the wrapper spawns `bun <self>
14
- * <variant>`): under Bun 1.3.14 a third Chromium compose cycle within one
15
- * process can hang the Playwright driver, while a two-compose pair is stable.
16
- * Production composes one card per image-gen invocation, so the per-process
17
- * pair matches the real spend path.
13
+ * All variants run in one process: the Bun 1.3.14 third-compose-cycle hang that
14
+ * forced a subprocess per variant is gone on Bun 1.4.3 (re-measured 2026-11-04).
18
15
  */
19
16
  import { join } from 'node:path';
20
17
  import { imageDimensions } from '../src/bytes';
@@ -110,22 +107,9 @@ if (variant === 'without' || variant === 'with') {
110
107
  } else if (variant === 'r2') {
111
108
  await runR2();
112
109
  } else if (variant === undefined) {
113
- // Bounded: a Chromium cycle can occasionally hang under Bun 1.3.14 (driver
114
- // contention right after a sibling subprocess); timeout + one clean retry.
115
- for (const v of ['without', 'with', 'r2'] as const) {
116
- let proc = Bun.spawnSync(['bun', import.meta.path, v], { stdout: 'pipe', stderr: 'pipe', timeout: 120_000 });
117
- if (proc.exitCode !== 0) {
118
- console.log(`[${v}] attempt 1 failed (exit ${proc.exitCode}); retrying once...`);
119
- proc = Bun.spawnSync(['bun', import.meta.path, v], { stdout: 'pipe', stderr: 'pipe', timeout: 120_000 });
120
- }
121
- const out = new TextDecoder().decode(proc.stdout);
122
- const err = new TextDecoder().decode(proc.stderr);
123
- if (out) process.stdout.write(out);
124
- if (proc.exitCode !== 0) {
125
- process.stderr.write(err);
126
- process.exit(proc.exitCode ?? 1);
127
- }
128
- }
110
+ await runPair('without');
111
+ await runPair('with');
112
+ await runR2();
129
113
  console.log(
130
114
  'E2E compose artifacts written (.spur/run/0180 both variants, .spur/run/0181 R2) — SHA-256 deterministic.',
131
115
  );