@gobing-ai/knowledge-kit 0.0.36 → 0.1.0

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 (159) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/dist/board/collect/index.css +654 -16
  3. package/dist/board/collect/index.js +191 -64
  4. package/dist/board/daily-voice/index.css +679 -12
  5. package/dist/board/daily-voice/index.js +185 -66
  6. package/dist/board/itc/index.css +679 -13
  7. package/dist/board/itc/index.js +188 -66
  8. package/dist/index.js +2878 -152
  9. package/package.json +3 -2
  10. package/plugins/generations/content-gen/dist/index.js +158 -12
  11. package/plugins/generations/core-facts-gen/dist/index.js +158 -12
  12. package/plugins/generations/daily-article-gen/dist/index.js +158 -12
  13. package/plugins/generations/dailynews-gen/dist/index.js +180 -12
  14. package/plugins/generations/dailynews-gen/src/script-plan.ts +32 -0
  15. package/plugins/generations/episode-plan-gen/dist/index.js +158 -12
  16. package/plugins/generations/gemini-tts/README.md +4 -3
  17. package/plugins/generations/gemini-tts/dist/index.js +158 -12
  18. package/plugins/generations/image-gen/dist/index.js +158 -12
  19. package/plugins/generations/news-report-gen/dist/index.js +158 -12
  20. package/plugins/generations/omni-voice-gen/README.md +15 -4
  21. package/plugins/generations/omni-voice-gen/profiles.json +1 -2
  22. package/plugins/generations/voice-gen/dist/index.js +158 -12
  23. package/plugins/generations/voxcpm-tts/README.md +21 -1
  24. package/plugins/generations/voxcpm-tts/dist/index.js +173 -13
  25. package/plugins/generations/voxcpm-tts/scripts/audit-speaker-consistency.py +109 -0
  26. package/plugins/generations/voxcpm-tts/src/voxcpm-client.ts +28 -1
  27. package/plugins/ingestions/aihot-ingest/dist/index.js +158 -12
  28. package/plugins/ingestions/horizon-ingest/dist/index.js +158 -12
  29. package/plugins/ingestions/last30days-ingest/dist/index.js +158 -12
  30. package/plugins/ingestions/web-search/dist/index.js +158 -12
  31. package/plugins/kk/commands/workflow-run.md +56 -18
  32. package/plugins/kk/decisions/kk-itc.yaml +46 -0
  33. package/plugins/kk/decisions/kk-seo-keyword.yaml +57 -0
  34. package/plugins/kk/decisions/kk-seo-page.yaml +230 -0
  35. package/plugins/kk/decisions/kk-seo-pair.yaml +21 -0
  36. package/plugins/kk/decisions/kk-seo-site.yaml +90 -0
  37. package/plugins/kk/plugin.json +1 -1
  38. package/plugins/kk/publish-presets/chinese-article.json +14 -0
  39. package/plugins/kk/publish-presets/technical-article.json +14 -0
  40. package/plugins/kk/references/smart-seo-attribution.md +85 -0
  41. package/plugins/kk/scripts/daily-stages.ts +42 -2
  42. package/plugins/kk/scripts/daily-voice-style.zh.md +1 -1
  43. package/plugins/kk/scripts/itc-stages.ts +25 -118
  44. package/plugins/kk/scripts/kk-workflow-stages.ts +38 -1
  45. package/plugins/kk/scripts/seo-decisions.ts +477 -0
  46. package/plugins/kk/scripts/seo-enrich.ts +728 -0
  47. package/plugins/kk/scripts/seo-facts.ts +610 -0
  48. package/plugins/kk/scripts/seo-fetch.ts +766 -0
  49. package/plugins/kk/scripts/seo-report.ts +460 -0
  50. package/plugins/kk/scripts/seo-rules.ts +1882 -0
  51. package/plugins/kk/scripts/seo-stages.ts +1044 -0
  52. package/plugins/kk/skills/article-adapt/SKILL.md +2 -2
  53. package/plugins/kk/skills/smart-seo/SKILL.md +183 -0
  54. package/plugins/kk/skills/smart-seo/references/method.md +126 -0
  55. package/plugins/kk/skills/smart-seo/references/narrative.md +125 -0
  56. package/plugins/kk/skills/smart-seo/references/operations.md +202 -0
  57. package/plugins/kk/skills/smart-seo/references/seo-geo-sources.md +90 -0
  58. package/plugins/kk/workflows/feature-verification.yaml +28 -24
  59. package/plugins/kk/workflows/kk-daily-ai-voice2.yaml +86 -18
  60. package/plugins/kk/workflows/kk-itc-author.yaml +406 -0
  61. package/plugins/kk/workflows/kk-itc.yaml +208 -682
  62. package/plugins/kk/workflows/kk-smart-seo.yaml +251 -0
  63. package/plugins/publishings/bilibili-pub/dist/index.js +21782 -0
  64. package/plugins/publishings/bilibili-pub/dist/profile-check.js +20410 -0
  65. package/plugins/publishings/bilibili-pub/package.json +20 -0
  66. package/plugins/publishings/bilibili-pub/plugin.json +12 -0
  67. package/plugins/publishings/bilibili-pub/src/flow.ts +1296 -0
  68. package/plugins/publishings/bilibili-pub/src/index.ts +139 -0
  69. package/plugins/publishings/bilibili-pub/src/profile-check.ts +19 -0
  70. package/plugins/publishings/bilibili-pub/src/selectors.ts +222 -0
  71. package/plugins/publishings/bilibili-pub/tsconfig.json +4 -0
  72. package/plugins/publishings/cnblogs-pub/dist/index.js +21383 -0
  73. package/plugins/publishings/cnblogs-pub/dist/profile-check.js +20412 -0
  74. package/plugins/publishings/cnblogs-pub/package.json +19 -0
  75. package/plugins/publishings/cnblogs-pub/plugin.json +12 -0
  76. package/plugins/publishings/cnblogs-pub/src/flow.ts +708 -0
  77. package/plugins/publishings/cnblogs-pub/src/index.ts +172 -0
  78. package/plugins/publishings/cnblogs-pub/src/profile-check.ts +24 -0
  79. package/plugins/publishings/cnblogs-pub/src/selectors.ts +104 -0
  80. package/plugins/publishings/cnblogs-pub/tsconfig.json +4 -0
  81. package/plugins/publishings/csdn-pub/dist/index.js +21552 -0
  82. package/plugins/publishings/csdn-pub/dist/profile-check.js +20963 -0
  83. package/plugins/publishings/csdn-pub/package.json +19 -0
  84. package/plugins/publishings/csdn-pub/plugin.json +12 -0
  85. package/plugins/publishings/csdn-pub/src/index.ts +1178 -0
  86. package/plugins/publishings/csdn-pub/src/profile-check.ts +23 -0
  87. package/plugins/publishings/csdn-pub/tsconfig.json +4 -0
  88. package/plugins/publishings/emdash-pub/dist/index.js +158 -12
  89. package/plugins/publishings/emdash-pub/plugin.json +22 -1
  90. package/plugins/publishings/infoq-pub/dist/index.js +160 -12
  91. package/plugins/publishings/infoq-pub/dist/profile-check.js +160 -12
  92. package/plugins/publishings/infoq-pub/plugin.json +21 -0
  93. package/plugins/publishings/jike-pub/dist/index.js +21379 -0
  94. package/plugins/publishings/jike-pub/dist/profile-check.js +20951 -0
  95. package/plugins/publishings/jike-pub/package.json +19 -0
  96. package/plugins/publishings/jike-pub/plugin.json +12 -0
  97. package/plugins/publishings/jike-pub/src/index.ts +800 -0
  98. package/plugins/publishings/jike-pub/src/profile-check.ts +21 -0
  99. package/plugins/publishings/jike-pub/tsconfig.json +4 -0
  100. package/plugins/publishings/juejin-pub/dist/index.js +160 -12
  101. package/plugins/publishings/juejin-pub/dist/profile-check.js +160 -12
  102. package/plugins/publishings/juejin-pub/plugin.json +21 -0
  103. package/plugins/publishings/medium-pub/dist/index.js +158 -12
  104. package/plugins/publishings/medium-pub/plugin.json +22 -1
  105. package/plugins/publishings/podcast-pub/dist/index.js +158 -12
  106. package/plugins/publishings/qiita-pub/dist/index.js +158 -12
  107. package/plugins/publishings/qiita-pub/plugin.json +24 -1
  108. package/plugins/publishings/shipinhao-pub/dist/index.js +21715 -0
  109. package/plugins/publishings/shipinhao-pub/dist/profile-check.js +20431 -0
  110. package/plugins/publishings/shipinhao-pub/package.json +19 -0
  111. package/plugins/publishings/shipinhao-pub/plugin.json +12 -0
  112. package/plugins/publishings/shipinhao-pub/src/flow.ts +1323 -0
  113. package/plugins/publishings/shipinhao-pub/src/index.ts +173 -0
  114. package/plugins/publishings/shipinhao-pub/src/profile-check.ts +25 -0
  115. package/plugins/publishings/shipinhao-pub/src/selectors.ts +241 -0
  116. package/plugins/publishings/shipinhao-pub/tsconfig.json +4 -0
  117. package/plugins/publishings/sspai-pub/dist/index.js +21371 -0
  118. package/plugins/publishings/sspai-pub/dist/profile-check.js +20414 -0
  119. package/plugins/publishings/sspai-pub/package.json +19 -0
  120. package/plugins/publishings/sspai-pub/plugin.json +12 -0
  121. package/plugins/publishings/sspai-pub/src/flow.ts +624 -0
  122. package/plugins/publishings/sspai-pub/src/index.ts +167 -0
  123. package/plugins/publishings/sspai-pub/src/profile-check.ts +25 -0
  124. package/plugins/publishings/sspai-pub/src/selectors.ts +122 -0
  125. package/plugins/publishings/sspai-pub/tsconfig.json +4 -0
  126. package/plugins/publishings/substack-pub/dist/index.js +160 -12
  127. package/plugins/publishings/substack-pub/dist/profile-check.js +160 -12
  128. package/plugins/publishings/substack-pub/plugin.json +21 -0
  129. package/plugins/publishings/surfdash-pub/dist/index.js +158 -12
  130. package/plugins/publishings/surfdash-pub/plugin.json +22 -1
  131. package/plugins/publishings/threads-pub/dist/index.js +158 -12
  132. package/plugins/publishings/wechatmp-pub/dist/index.js +1669 -502
  133. package/plugins/publishings/wechatmp-pub/dist/profile-check.js +204 -21
  134. package/plugins/publishings/wechatmp-pub/plugin.json +32 -0
  135. package/plugins/publishings/wechatmp-pub/src/cgi-draft.ts +540 -0
  136. package/plugins/publishings/wechatmp-pub/src/cgi-media.ts +380 -0
  137. package/plugins/publishings/wechatmp-pub/src/cgi.ts +485 -0
  138. package/plugins/publishings/wechatmp-pub/src/flow.ts +104 -0
  139. package/plugins/publishings/weibo-pub/dist/index.js +160 -12
  140. package/plugins/publishings/weibo-pub/dist/profile-check.js +160 -12
  141. package/plugins/publishings/weibo-pub/plugin.json +35 -0
  142. package/plugins/publishings/x-pub/dist/index.js +160 -12
  143. package/plugins/publishings/x-pub/dist/profile-check.js +160 -12
  144. package/plugins/publishings/x-pub/plugin.json +40 -0
  145. package/plugins/publishings/xhs-pub/dist/index.js +160 -12
  146. package/plugins/publishings/xhs-pub/dist/profile-check.js +160 -12
  147. package/plugins/publishings/xhs-pub/plugin.json +37 -0
  148. package/plugins/publishings/xiaoyuzhou-pub/dist/index.js +21491 -0
  149. package/plugins/publishings/xiaoyuzhou-pub/dist/profile-check.js +20417 -0
  150. package/plugins/publishings/xiaoyuzhou-pub/package.json +19 -0
  151. package/plugins/publishings/xiaoyuzhou-pub/plugin.json +12 -0
  152. package/plugins/publishings/xiaoyuzhou-pub/src/flow.ts +826 -0
  153. package/plugins/publishings/xiaoyuzhou-pub/src/index.ts +174 -0
  154. package/plugins/publishings/xiaoyuzhou-pub/src/profile-check.ts +26 -0
  155. package/plugins/publishings/xiaoyuzhou-pub/src/selectors.ts +125 -0
  156. package/plugins/publishings/xiaoyuzhou-pub/tsconfig.json +4 -0
  157. package/plugins/publishings/zenn-pub/dist/index.js +158 -12
  158. package/plugins/publishings/zenn-pub/plugin.json +22 -1
  159. package/plugins/generations/omni-voice-gen/voices/robin-news.wav +0 -0
@@ -11987,6 +11987,83 @@ import { parseArgs } from "util";
11987
11987
  // ../../plugins/generations/voice-gen/src/index.ts
11988
11988
  import { basename, dirname as dirname2, extname, join as join2, resolve } from "path";
11989
11989
 
11990
+ // ../../packages/kk-core/src/content-limits.ts
11991
+ var PLATFORM_CONTENT_LIMITS = Object.freeze({
11992
+ schemaVersion: 5,
11993
+ tagLimits: Object.freeze({
11994
+ default: 7,
11995
+ imageText: Object.freeze({
11996
+ instagram: 5,
11997
+ douyin: 5,
11998
+ kuaishou: 4,
11999
+ weixin: 1,
12000
+ xiaohongshu: 10
12001
+ }),
12002
+ shortVideo: Object.freeze({
12003
+ douyin: 5,
12004
+ kuaishou: 4,
12005
+ xiaohongshu: 10,
12006
+ bilibili: 10,
12007
+ zhihu: 5,
12008
+ tiktok: 20,
12009
+ youtube: 60
12010
+ })
12011
+ }),
12012
+ titleCapabilities: Object.freeze({
12013
+ dynamic: Object.freeze({
12014
+ bilibili: Object.freeze({ max: 20, unit: "utf16_code_units" }),
12015
+ zhihu: Object.freeze({ max: 50, unit: "utf16_code_units" }),
12016
+ douban: Object.freeze({ max: 70, unit: "utf16_code_units" }),
12017
+ x: null,
12018
+ threads: null,
12019
+ weibo: null,
12020
+ jike: null,
12021
+ zsxq: null,
12022
+ toutiao: null,
12023
+ juejin: null
12024
+ }),
12025
+ imageText: Object.freeze({
12026
+ xiaohongshu: Object.freeze({ max: 20, unit: "xiaohongshu_title_weighted" }),
12027
+ weixin: Object.freeze({ max: 20, unit: "utf16_code_units" }),
12028
+ douyin: Object.freeze({ max: 20, unit: "utf16_code_units" }),
12029
+ shipinhao: Object.freeze({ max: 22, unit: "utf16_code_units" }),
12030
+ reddit: Object.freeze({ max: 300, unit: "utf16_code_units" })
12031
+ }),
12032
+ article: Object.freeze({
12033
+ juejin: Object.freeze({ max: 100, unit: "utf16_code_units" }),
12034
+ csdn: Object.freeze({ max: 100, unit: "utf16_code_units" }),
12035
+ cnblogs: Object.freeze({ max: 128, unit: "utf16_code_units" }),
12036
+ weibo: Object.freeze({ max: 30, unit: "utf16_code_units" }),
12037
+ sspai: Object.freeze({ max: 80, unit: "utf16_code_units" })
12038
+ }),
12039
+ shortVideo: Object.freeze({
12040
+ shipinhao: Object.freeze({ max: 16, unit: "utf16_code_units" }),
12041
+ douyin: Object.freeze({ max: 30, unit: "utf16_code_units" }),
12042
+ bilibili: Object.freeze({ max: 80, unit: "utf16_code_units" })
12043
+ })
12044
+ }),
12045
+ bodyCapabilities: Object.freeze({
12046
+ dynamic: Object.freeze({
12047
+ threads: Object.freeze({ max: 500, unit: "unicode_code_points", behavior: "split_thread" }),
12048
+ x: Object.freeze({ max: 280, unit: "weighted", behavior: "split_thread" }),
12049
+ weibo: Object.freeze({ max: 2000, unit: "unicode_code_points" }),
12050
+ jike: Object.freeze({ max: 1000, unit: "unicode_code_points" })
12051
+ }),
12052
+ imageText: Object.freeze({
12053
+ xiaohongshu: Object.freeze({ max: 1000, unit: "unicode_code_points" }),
12054
+ douyin: Object.freeze({ max: 1000, unit: "unicode_code_points" })
12055
+ }),
12056
+ article: Object.freeze({
12057
+ wechatmp: Object.freeze({ max: 50000, unit: "unicode_code_points" }),
12058
+ juejin: Object.freeze({ max: 50000, unit: "unicode_code_points" })
12059
+ }),
12060
+ shortVideo: Object.freeze({
12061
+ douyin: Object.freeze({ max: 1000, unit: "unicode_code_points" }),
12062
+ kuaishou: Object.freeze({ max: 1000, unit: "unicode_code_points" }),
12063
+ shipinhao: Object.freeze({ max: 1000, unit: "unicode_code_points" })
12064
+ })
12065
+ })
12066
+ });
11990
12067
  // ../../packages/kk-core/src/kinds.ts
11991
12068
  init_zod();
11992
12069
 
@@ -12077,6 +12154,67 @@ var BrowserSessionDescriptorSchema = object2({
12077
12154
  }
12078
12155
  }).optional()
12079
12156
  }).strict();
12157
+ var ContentCountUnitSchema = _enum([
12158
+ "utf16_code_units",
12159
+ "unicode_code_points",
12160
+ "weighted",
12161
+ "xiaohongshu_title_weighted"
12162
+ ]);
12163
+ var LimitEntrySchema = object2({
12164
+ max: number2().int().positive(),
12165
+ unit: ContentCountUnitSchema
12166
+ }).strict();
12167
+ var PublishingProfileLimitsSchema = object2({
12168
+ title: LimitEntrySchema.optional(),
12169
+ body: LimitEntrySchema.optional()
12170
+ }).strict();
12171
+ var PublishingProfileRequiresSchema = object2({
12172
+ cover: boolean2().optional(),
12173
+ orderedImages: boolean2().optional()
12174
+ }).strict();
12175
+ var PublishingProfileModeBindingSchema = object2({
12176
+ metadata: record(string2(), unknown())
12177
+ }).strict();
12178
+ var PublishingProfileModesSchema = object2({
12179
+ draft: PublishingProfileModeBindingSchema.optional(),
12180
+ live: PublishingProfileModeBindingSchema.optional()
12181
+ }).strict().superRefine((modes, ctx) => {
12182
+ if (modes.draft === undefined && modes.live === undefined) {
12183
+ ctx.addIssue({
12184
+ code: "custom",
12185
+ message: 'modes must define at least one of "draft" or "live"'
12186
+ });
12187
+ }
12188
+ });
12189
+ var PublishingProfileSchema = object2({
12190
+ format: string2().min(1),
12191
+ locale: string2().regex(/^(source|[a-z]{2,3}(-[A-Za-z0-9]+)*)$/, {
12192
+ message: 'locale must be "source" or a valid language tag'
12193
+ }),
12194
+ limits: PublishingProfileLimitsSchema.optional(),
12195
+ requires: PublishingProfileRequiresSchema.optional(),
12196
+ modes: PublishingProfileModesSchema
12197
+ }).strict();
12198
+ var PublishingCapabilitiesSchema = object2({
12199
+ defaultProfile: string2().min(1),
12200
+ profiles: record(string2().regex(/^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/), PublishingProfileSchema)
12201
+ }).strict().superRefine((data, ctx) => {
12202
+ const keys = Object.keys(data.profiles);
12203
+ if (keys.length === 0) {
12204
+ ctx.addIssue({
12205
+ code: "custom",
12206
+ path: ["profiles"],
12207
+ message: "profiles record must be nonempty"
12208
+ });
12209
+ }
12210
+ if (!(data.defaultProfile in data.profiles)) {
12211
+ ctx.addIssue({
12212
+ code: "custom",
12213
+ path: ["defaultProfile"],
12214
+ message: `defaultProfile "${data.defaultProfile}" must reference a declared profile`
12215
+ });
12216
+ }
12217
+ });
12080
12218
  var PluginManifestSchemaBase = looseObject({
12081
12219
  name: string2().min(1),
12082
12220
  kind: PluginKindSchema,
@@ -12085,23 +12223,31 @@ var PluginManifestSchemaBase = looseObject({
12085
12223
  version: string2().optional(),
12086
12224
  description: string2().optional(),
12087
12225
  operations: record(string2(), PluginOperationSchema).optional(),
12088
- browserSession: BrowserSessionDescriptorSchema.optional()
12226
+ browserSession: BrowserSessionDescriptorSchema.optional(),
12227
+ publishing: PublishingCapabilitiesSchema.optional()
12089
12228
  });
12090
12229
  var PluginManifestSchema = PluginManifestSchemaBase.superRefine((manifest, ctx) => {
12091
- if (manifest.browserSession === undefined)
12092
- return;
12093
- if (manifest.kind !== "publish") {
12094
- ctx.addIssue({
12095
- code: "custom",
12096
- path: ["browserSession"],
12097
- message: `browserSession requires kind "publish", not "${manifest.kind}"`
12098
- });
12230
+ if (manifest.browserSession !== undefined) {
12231
+ if (manifest.kind !== "publish") {
12232
+ ctx.addIssue({
12233
+ code: "custom",
12234
+ path: ["browserSession"],
12235
+ message: `browserSession requires kind "publish", not "${manifest.kind}"`
12236
+ });
12237
+ }
12238
+ if (manifest.check === undefined) {
12239
+ ctx.addIssue({
12240
+ code: "custom",
12241
+ path: ["browserSession"],
12242
+ message: "browserSession requires a check probe entry that owns the session routines"
12243
+ });
12244
+ }
12099
12245
  }
12100
- if (manifest.check === undefined) {
12246
+ if (manifest.publishing !== undefined && manifest.kind !== "publish") {
12101
12247
  ctx.addIssue({
12102
12248
  code: "custom",
12103
- path: ["browserSession"],
12104
- message: "browserSession requires a check probe entry that owns the session routines"
12249
+ path: ["publishing"],
12250
+ message: `publishing requires kind "publish", not "${manifest.kind}"`
12105
12251
  });
12106
12252
  }
12107
12253
  });
@@ -12309,6 +12309,83 @@ var init_chromium = __esm(() => {
12309
12309
  import { dirname as dirname3, join as join4 } from "path";
12310
12310
  import { parseArgs } from "util";
12311
12311
 
12312
+ // ../../packages/kk-core/src/content-limits.ts
12313
+ var PLATFORM_CONTENT_LIMITS = Object.freeze({
12314
+ schemaVersion: 5,
12315
+ tagLimits: Object.freeze({
12316
+ default: 7,
12317
+ imageText: Object.freeze({
12318
+ instagram: 5,
12319
+ douyin: 5,
12320
+ kuaishou: 4,
12321
+ weixin: 1,
12322
+ xiaohongshu: 10
12323
+ }),
12324
+ shortVideo: Object.freeze({
12325
+ douyin: 5,
12326
+ kuaishou: 4,
12327
+ xiaohongshu: 10,
12328
+ bilibili: 10,
12329
+ zhihu: 5,
12330
+ tiktok: 20,
12331
+ youtube: 60
12332
+ })
12333
+ }),
12334
+ titleCapabilities: Object.freeze({
12335
+ dynamic: Object.freeze({
12336
+ bilibili: Object.freeze({ max: 20, unit: "utf16_code_units" }),
12337
+ zhihu: Object.freeze({ max: 50, unit: "utf16_code_units" }),
12338
+ douban: Object.freeze({ max: 70, unit: "utf16_code_units" }),
12339
+ x: null,
12340
+ threads: null,
12341
+ weibo: null,
12342
+ jike: null,
12343
+ zsxq: null,
12344
+ toutiao: null,
12345
+ juejin: null
12346
+ }),
12347
+ imageText: Object.freeze({
12348
+ xiaohongshu: Object.freeze({ max: 20, unit: "xiaohongshu_title_weighted" }),
12349
+ weixin: Object.freeze({ max: 20, unit: "utf16_code_units" }),
12350
+ douyin: Object.freeze({ max: 20, unit: "utf16_code_units" }),
12351
+ shipinhao: Object.freeze({ max: 22, unit: "utf16_code_units" }),
12352
+ reddit: Object.freeze({ max: 300, unit: "utf16_code_units" })
12353
+ }),
12354
+ article: Object.freeze({
12355
+ juejin: Object.freeze({ max: 100, unit: "utf16_code_units" }),
12356
+ csdn: Object.freeze({ max: 100, unit: "utf16_code_units" }),
12357
+ cnblogs: Object.freeze({ max: 128, unit: "utf16_code_units" }),
12358
+ weibo: Object.freeze({ max: 30, unit: "utf16_code_units" }),
12359
+ sspai: Object.freeze({ max: 80, unit: "utf16_code_units" })
12360
+ }),
12361
+ shortVideo: Object.freeze({
12362
+ shipinhao: Object.freeze({ max: 16, unit: "utf16_code_units" }),
12363
+ douyin: Object.freeze({ max: 30, unit: "utf16_code_units" }),
12364
+ bilibili: Object.freeze({ max: 80, unit: "utf16_code_units" })
12365
+ })
12366
+ }),
12367
+ bodyCapabilities: Object.freeze({
12368
+ dynamic: Object.freeze({
12369
+ threads: Object.freeze({ max: 500, unit: "unicode_code_points", behavior: "split_thread" }),
12370
+ x: Object.freeze({ max: 280, unit: "weighted", behavior: "split_thread" }),
12371
+ weibo: Object.freeze({ max: 2000, unit: "unicode_code_points" }),
12372
+ jike: Object.freeze({ max: 1000, unit: "unicode_code_points" })
12373
+ }),
12374
+ imageText: Object.freeze({
12375
+ xiaohongshu: Object.freeze({ max: 1000, unit: "unicode_code_points" }),
12376
+ douyin: Object.freeze({ max: 1000, unit: "unicode_code_points" })
12377
+ }),
12378
+ article: Object.freeze({
12379
+ wechatmp: Object.freeze({ max: 50000, unit: "unicode_code_points" }),
12380
+ juejin: Object.freeze({ max: 50000, unit: "unicode_code_points" })
12381
+ }),
12382
+ shortVideo: Object.freeze({
12383
+ douyin: Object.freeze({ max: 1000, unit: "unicode_code_points" }),
12384
+ kuaishou: Object.freeze({ max: 1000, unit: "unicode_code_points" }),
12385
+ shipinhao: Object.freeze({ max: 1000, unit: "unicode_code_points" })
12386
+ })
12387
+ })
12388
+ });
12312
12389
  // ../../packages/kk-core/src/kinds.ts
12313
12390
  init_zod();
12314
12391
 
@@ -12399,6 +12476,67 @@ var BrowserSessionDescriptorSchema = object({
12399
12476
  }
12400
12477
  }).optional()
12401
12478
  }).strict();
12479
+ var ContentCountUnitSchema = _enum([
12480
+ "utf16_code_units",
12481
+ "unicode_code_points",
12482
+ "weighted",
12483
+ "xiaohongshu_title_weighted"
12484
+ ]);
12485
+ var LimitEntrySchema = object({
12486
+ max: number2().int().positive(),
12487
+ unit: ContentCountUnitSchema
12488
+ }).strict();
12489
+ var PublishingProfileLimitsSchema = object({
12490
+ title: LimitEntrySchema.optional(),
12491
+ body: LimitEntrySchema.optional()
12492
+ }).strict();
12493
+ var PublishingProfileRequiresSchema = object({
12494
+ cover: boolean2().optional(),
12495
+ orderedImages: boolean2().optional()
12496
+ }).strict();
12497
+ var PublishingProfileModeBindingSchema = object({
12498
+ metadata: record(string2(), unknown())
12499
+ }).strict();
12500
+ var PublishingProfileModesSchema = object({
12501
+ draft: PublishingProfileModeBindingSchema.optional(),
12502
+ live: PublishingProfileModeBindingSchema.optional()
12503
+ }).strict().superRefine((modes, ctx) => {
12504
+ if (modes.draft === undefined && modes.live === undefined) {
12505
+ ctx.addIssue({
12506
+ code: "custom",
12507
+ message: 'modes must define at least one of "draft" or "live"'
12508
+ });
12509
+ }
12510
+ });
12511
+ var PublishingProfileSchema = object({
12512
+ format: string2().min(1),
12513
+ locale: string2().regex(/^(source|[a-z]{2,3}(-[A-Za-z0-9]+)*)$/, {
12514
+ message: 'locale must be "source" or a valid language tag'
12515
+ }),
12516
+ limits: PublishingProfileLimitsSchema.optional(),
12517
+ requires: PublishingProfileRequiresSchema.optional(),
12518
+ modes: PublishingProfileModesSchema
12519
+ }).strict();
12520
+ var PublishingCapabilitiesSchema = object({
12521
+ defaultProfile: string2().min(1),
12522
+ profiles: record(string2().regex(/^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/), PublishingProfileSchema)
12523
+ }).strict().superRefine((data, ctx) => {
12524
+ const keys = Object.keys(data.profiles);
12525
+ if (keys.length === 0) {
12526
+ ctx.addIssue({
12527
+ code: "custom",
12528
+ path: ["profiles"],
12529
+ message: "profiles record must be nonempty"
12530
+ });
12531
+ }
12532
+ if (!(data.defaultProfile in data.profiles)) {
12533
+ ctx.addIssue({
12534
+ code: "custom",
12535
+ path: ["defaultProfile"],
12536
+ message: `defaultProfile "${data.defaultProfile}" must reference a declared profile`
12537
+ });
12538
+ }
12539
+ });
12402
12540
  var PluginManifestSchemaBase = looseObject({
12403
12541
  name: string2().min(1),
12404
12542
  kind: PluginKindSchema,
@@ -12407,23 +12545,31 @@ var PluginManifestSchemaBase = looseObject({
12407
12545
  version: string2().optional(),
12408
12546
  description: string2().optional(),
12409
12547
  operations: record(string2(), PluginOperationSchema).optional(),
12410
- browserSession: BrowserSessionDescriptorSchema.optional()
12548
+ browserSession: BrowserSessionDescriptorSchema.optional(),
12549
+ publishing: PublishingCapabilitiesSchema.optional()
12411
12550
  });
12412
12551
  var PluginManifestSchema = PluginManifestSchemaBase.superRefine((manifest, ctx) => {
12413
- if (manifest.browserSession === undefined)
12414
- return;
12415
- if (manifest.kind !== "publish") {
12416
- ctx.addIssue({
12417
- code: "custom",
12418
- path: ["browserSession"],
12419
- message: `browserSession requires kind "publish", not "${manifest.kind}"`
12420
- });
12552
+ if (manifest.browserSession !== undefined) {
12553
+ if (manifest.kind !== "publish") {
12554
+ ctx.addIssue({
12555
+ code: "custom",
12556
+ path: ["browserSession"],
12557
+ message: `browserSession requires kind "publish", not "${manifest.kind}"`
12558
+ });
12559
+ }
12560
+ if (manifest.check === undefined) {
12561
+ ctx.addIssue({
12562
+ code: "custom",
12563
+ path: ["browserSession"],
12564
+ message: "browserSession requires a check probe entry that owns the session routines"
12565
+ });
12566
+ }
12421
12567
  }
12422
- if (manifest.check === undefined) {
12568
+ if (manifest.publishing !== undefined && manifest.kind !== "publish") {
12423
12569
  ctx.addIssue({
12424
12570
  code: "custom",
12425
- path: ["browserSession"],
12426
- message: "browserSession requires a check probe entry that owns the session routines"
12571
+ path: ["publishing"],
12572
+ message: `publishing requires kind "publish", not "${manifest.kind}"`
12427
12573
  });
12428
12574
  }
12429
12575
  });
@@ -11984,6 +11984,83 @@ var init_file_system_node = () => {};
11984
11984
  import { dirname as dirname2 } from "path";
11985
11985
  import { parseArgs } from "util";
11986
11986
 
11987
+ // ../../packages/kk-core/src/content-limits.ts
11988
+ var PLATFORM_CONTENT_LIMITS = Object.freeze({
11989
+ schemaVersion: 5,
11990
+ tagLimits: Object.freeze({
11991
+ default: 7,
11992
+ imageText: Object.freeze({
11993
+ instagram: 5,
11994
+ douyin: 5,
11995
+ kuaishou: 4,
11996
+ weixin: 1,
11997
+ xiaohongshu: 10
11998
+ }),
11999
+ shortVideo: Object.freeze({
12000
+ douyin: 5,
12001
+ kuaishou: 4,
12002
+ xiaohongshu: 10,
12003
+ bilibili: 10,
12004
+ zhihu: 5,
12005
+ tiktok: 20,
12006
+ youtube: 60
12007
+ })
12008
+ }),
12009
+ titleCapabilities: Object.freeze({
12010
+ dynamic: Object.freeze({
12011
+ bilibili: Object.freeze({ max: 20, unit: "utf16_code_units" }),
12012
+ zhihu: Object.freeze({ max: 50, unit: "utf16_code_units" }),
12013
+ douban: Object.freeze({ max: 70, unit: "utf16_code_units" }),
12014
+ x: null,
12015
+ threads: null,
12016
+ weibo: null,
12017
+ jike: null,
12018
+ zsxq: null,
12019
+ toutiao: null,
12020
+ juejin: null
12021
+ }),
12022
+ imageText: Object.freeze({
12023
+ xiaohongshu: Object.freeze({ max: 20, unit: "xiaohongshu_title_weighted" }),
12024
+ weixin: Object.freeze({ max: 20, unit: "utf16_code_units" }),
12025
+ douyin: Object.freeze({ max: 20, unit: "utf16_code_units" }),
12026
+ shipinhao: Object.freeze({ max: 22, unit: "utf16_code_units" }),
12027
+ reddit: Object.freeze({ max: 300, unit: "utf16_code_units" })
12028
+ }),
12029
+ article: Object.freeze({
12030
+ juejin: Object.freeze({ max: 100, unit: "utf16_code_units" }),
12031
+ csdn: Object.freeze({ max: 100, unit: "utf16_code_units" }),
12032
+ cnblogs: Object.freeze({ max: 128, unit: "utf16_code_units" }),
12033
+ weibo: Object.freeze({ max: 30, unit: "utf16_code_units" }),
12034
+ sspai: Object.freeze({ max: 80, unit: "utf16_code_units" })
12035
+ }),
12036
+ shortVideo: Object.freeze({
12037
+ shipinhao: Object.freeze({ max: 16, unit: "utf16_code_units" }),
12038
+ douyin: Object.freeze({ max: 30, unit: "utf16_code_units" }),
12039
+ bilibili: Object.freeze({ max: 80, unit: "utf16_code_units" })
12040
+ })
12041
+ }),
12042
+ bodyCapabilities: Object.freeze({
12043
+ dynamic: Object.freeze({
12044
+ threads: Object.freeze({ max: 500, unit: "unicode_code_points", behavior: "split_thread" }),
12045
+ x: Object.freeze({ max: 280, unit: "weighted", behavior: "split_thread" }),
12046
+ weibo: Object.freeze({ max: 2000, unit: "unicode_code_points" }),
12047
+ jike: Object.freeze({ max: 1000, unit: "unicode_code_points" })
12048
+ }),
12049
+ imageText: Object.freeze({
12050
+ xiaohongshu: Object.freeze({ max: 1000, unit: "unicode_code_points" }),
12051
+ douyin: Object.freeze({ max: 1000, unit: "unicode_code_points" })
12052
+ }),
12053
+ article: Object.freeze({
12054
+ wechatmp: Object.freeze({ max: 50000, unit: "unicode_code_points" }),
12055
+ juejin: Object.freeze({ max: 50000, unit: "unicode_code_points" })
12056
+ }),
12057
+ shortVideo: Object.freeze({
12058
+ douyin: Object.freeze({ max: 1000, unit: "unicode_code_points" }),
12059
+ kuaishou: Object.freeze({ max: 1000, unit: "unicode_code_points" }),
12060
+ shipinhao: Object.freeze({ max: 1000, unit: "unicode_code_points" })
12061
+ })
12062
+ })
12063
+ });
11987
12064
  // ../../packages/kk-core/src/kinds.ts
11988
12065
  init_zod();
11989
12066
 
@@ -12074,6 +12151,67 @@ var BrowserSessionDescriptorSchema = object({
12074
12151
  }
12075
12152
  }).optional()
12076
12153
  }).strict();
12154
+ var ContentCountUnitSchema = _enum([
12155
+ "utf16_code_units",
12156
+ "unicode_code_points",
12157
+ "weighted",
12158
+ "xiaohongshu_title_weighted"
12159
+ ]);
12160
+ var LimitEntrySchema = object({
12161
+ max: number2().int().positive(),
12162
+ unit: ContentCountUnitSchema
12163
+ }).strict();
12164
+ var PublishingProfileLimitsSchema = object({
12165
+ title: LimitEntrySchema.optional(),
12166
+ body: LimitEntrySchema.optional()
12167
+ }).strict();
12168
+ var PublishingProfileRequiresSchema = object({
12169
+ cover: boolean2().optional(),
12170
+ orderedImages: boolean2().optional()
12171
+ }).strict();
12172
+ var PublishingProfileModeBindingSchema = object({
12173
+ metadata: record(string2(), unknown())
12174
+ }).strict();
12175
+ var PublishingProfileModesSchema = object({
12176
+ draft: PublishingProfileModeBindingSchema.optional(),
12177
+ live: PublishingProfileModeBindingSchema.optional()
12178
+ }).strict().superRefine((modes, ctx) => {
12179
+ if (modes.draft === undefined && modes.live === undefined) {
12180
+ ctx.addIssue({
12181
+ code: "custom",
12182
+ message: 'modes must define at least one of "draft" or "live"'
12183
+ });
12184
+ }
12185
+ });
12186
+ var PublishingProfileSchema = object({
12187
+ format: string2().min(1),
12188
+ locale: string2().regex(/^(source|[a-z]{2,3}(-[A-Za-z0-9]+)*)$/, {
12189
+ message: 'locale must be "source" or a valid language tag'
12190
+ }),
12191
+ limits: PublishingProfileLimitsSchema.optional(),
12192
+ requires: PublishingProfileRequiresSchema.optional(),
12193
+ modes: PublishingProfileModesSchema
12194
+ }).strict();
12195
+ var PublishingCapabilitiesSchema = object({
12196
+ defaultProfile: string2().min(1),
12197
+ profiles: record(string2().regex(/^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/), PublishingProfileSchema)
12198
+ }).strict().superRefine((data, ctx) => {
12199
+ const keys = Object.keys(data.profiles);
12200
+ if (keys.length === 0) {
12201
+ ctx.addIssue({
12202
+ code: "custom",
12203
+ path: ["profiles"],
12204
+ message: "profiles record must be nonempty"
12205
+ });
12206
+ }
12207
+ if (!(data.defaultProfile in data.profiles)) {
12208
+ ctx.addIssue({
12209
+ code: "custom",
12210
+ path: ["defaultProfile"],
12211
+ message: `defaultProfile "${data.defaultProfile}" must reference a declared profile`
12212
+ });
12213
+ }
12214
+ });
12077
12215
  var PluginManifestSchemaBase = looseObject({
12078
12216
  name: string2().min(1),
12079
12217
  kind: PluginKindSchema,
@@ -12082,23 +12220,31 @@ var PluginManifestSchemaBase = looseObject({
12082
12220
  version: string2().optional(),
12083
12221
  description: string2().optional(),
12084
12222
  operations: record(string2(), PluginOperationSchema).optional(),
12085
- browserSession: BrowserSessionDescriptorSchema.optional()
12223
+ browserSession: BrowserSessionDescriptorSchema.optional(),
12224
+ publishing: PublishingCapabilitiesSchema.optional()
12086
12225
  });
12087
12226
  var PluginManifestSchema = PluginManifestSchemaBase.superRefine((manifest, ctx) => {
12088
- if (manifest.browserSession === undefined)
12089
- return;
12090
- if (manifest.kind !== "publish") {
12091
- ctx.addIssue({
12092
- code: "custom",
12093
- path: ["browserSession"],
12094
- message: `browserSession requires kind "publish", not "${manifest.kind}"`
12095
- });
12227
+ if (manifest.browserSession !== undefined) {
12228
+ if (manifest.kind !== "publish") {
12229
+ ctx.addIssue({
12230
+ code: "custom",
12231
+ path: ["browserSession"],
12232
+ message: `browserSession requires kind "publish", not "${manifest.kind}"`
12233
+ });
12234
+ }
12235
+ if (manifest.check === undefined) {
12236
+ ctx.addIssue({
12237
+ code: "custom",
12238
+ path: ["browserSession"],
12239
+ message: "browserSession requires a check probe entry that owns the session routines"
12240
+ });
12241
+ }
12096
12242
  }
12097
- if (manifest.check === undefined) {
12243
+ if (manifest.publishing !== undefined && manifest.kind !== "publish") {
12098
12244
  ctx.addIssue({
12099
12245
  code: "custom",
12100
- path: ["browserSession"],
12101
- message: "browserSession requires a check probe entry that owns the session routines"
12246
+ path: ["publishing"],
12247
+ message: `publishing requires kind "publish", not "${manifest.kind}"`
12102
12248
  });
12103
12249
  }
12104
12250
  });
@@ -10,9 +10,12 @@ spur workflow run plugins/kk/workflows/kk-daily-ai-voice.yaml \
10
10
  --vars '{"voice_generator":"voice-gen"}' # other vars per your kk config
11
11
  ```
12
12
 
13
- > **Voice identity:** the shipped `robin-news` profile is an instruct placeholder. For a real
14
- > operator voice, record a 3–10 s clip into a private registry (`OMNIVOICE_PROFILE_REGISTRY`)
15
- > and it supersedes the committed entry.
13
+ > **Voice identity:** the shipped `robin-news` profile is an instruct placeholder — it pins no
14
+ > speaker, so a multi-segment render can change voice between segments. For a real operator voice,
15
+ > keep a 3–10 s clip outside the repo (e.g. `~/.config/kk/voices/robin-news.wav`), record it in a
16
+ > private registry (`OMNIVOICE_PROFILE_REGISTRY`, e.g. `~/.config/kk/omni-voice-profiles.json`,
17
+ > wired through `plugins.generations.omni-voice-gen.env`), and it supersedes the committed entry.
18
+ > Voice assets are never committed (task 0159).
16
19
 
17
20
  ## Setup
18
21
 
@@ -51,7 +54,15 @@ Profiles map a name to one of three voice-specification kinds. The registry live
51
54
  |------|-----------|-------------|
52
55
  | **Clone** | `{ "ref_audio": "<path>", "ref_text": "<transcript>" }` | 3–10 s reference clip + its transcript |
53
56
  | **Saved prompt** | `{ "prompt": "<path>.pt" }` | Pre-computed clone prompt via `create_voice_clone_prompt` |
54
- | **Instruct** | `{ "instruct": "<description>" }` | Text description of the desired voice style |
57
+ | **Instruct** | `{ "instruct": "<tokens>" }` | Voice style from OmniVoice's allowlisted tokens |
58
+
59
+ **Instruct vocabulary** (OmniVoice rejects anything else with *Unsupported instruct items*, so
60
+ only these are usable): gender `male`/`female`; age `child`, `teenager`, `young adult`,
61
+ `middle-aged`, `elderly`; pitch `very low pitch` … `very high pitch`; style `whisper`; accent
62
+ `american accent`, `british accent`, … — English tokens comma+space separated; the Chinese
63
+ equivalents use a full-width comma. Free-form prose like *"clear, natural, calm news
64
+ broadcast"* fails validation, and an instruct pins no speaker identity anyway: every request
65
+ draws a new voice, so use a clone profile for multi-segment work.
55
66
 
56
67
  ### Creating a profile (clone example)
57
68
 
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "robin-news": {
3
- "ref_audio": "voices/robin-news.wav",
4
- "ref_text": "本届赛事由北京市人民政府、中央广播电视总台、世界机器人合作组织、亚太机器人世界杯国际理事会联合主办。来自六大洲 16 个国家的 666 支队伍、2056 台机器人参赛,队伍数量较首届增长 138%,机器人"
3
+ "instruct": "male, middle-aged, moderate pitch"
5
4
  },
6
5
  "sample-clone": {
7
6
  "ref_audio": "voices/sample-ref.wav",