@gobing-ai/knowledge-kit 0.1.11 → 0.1.12

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 (126) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/dist/index.js +2359 -1721
  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 +11 -3
  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-stages.ts +346 -48
  88. package/plugins/kk/scripts/kk-workflow-stages.ts +190 -0
  89. package/plugins/kk/scripts/safety-artifact-check.ts +70 -28
  90. package/plugins/kk/scripts/voice3-publish-window.ts +202 -0
  91. package/plugins/kk/skills/article-adapt/SKILL.md +1 -0
  92. package/plugins/kk/skills/audio-authoring/SKILL.md +1 -0
  93. package/plugins/kk/skills/content-judge/SKILL.md +1 -0
  94. package/plugins/kk/skills/content-safety/SKILL.md +1 -0
  95. package/plugins/kk/skills/explain-things/SKILL.md +1 -0
  96. package/plugins/kk/skills/image-authoring/SKILL.md +1 -0
  97. package/plugins/kk/skills/itc-generating/SKILL.md +1 -0
  98. package/plugins/kk/skills/publish/SKILL.md +1 -0
  99. package/plugins/kk/skills/smart-seo/SKILL.md +1 -0
  100. package/plugins/kk/skills/storm-research/SKILL.md +1 -0
  101. package/plugins/kk/skills/taste-unslop/SKILL.md +1 -0
  102. package/plugins/kk/skills/topic/SKILL.md +1 -0
  103. package/plugins/kk/skills/web-automation/SKILL.md +1 -0
  104. package/plugins/kk/skills/xhs-images/SKILL.md +1 -0
  105. package/plugins/kk/workflows/kk-daily-ai-voice2.yaml +9 -7
  106. package/plugins/kk/workflows/kk-daily-ai-voice3.yaml +161 -61
  107. package/plugins/kk/workflows/kk-daily-publish3.yaml +82 -26
  108. package/plugins/kk/workflows/kk-daily-safety.yaml +39 -31
  109. package/plugins/kk/workflows/kk-itc-author.yaml +75 -0
  110. package/plugins/kk/workflows/kk-itc-publish-tail.yaml +25 -3
  111. package/plugins/kk/workflows/kk-itc.yaml +36 -4
  112. package/plugins/publishings/linkedin-pub/dist/index.js +21333 -0
  113. package/plugins/publishings/linkedin-pub/dist/profile-check.js +21005 -0
  114. package/plugins/publishings/linkedin-pub/package.json +19 -0
  115. package/plugins/publishings/linkedin-pub/plugin.json +12 -0
  116. package/plugins/publishings/linkedin-pub/src/index.ts +705 -0
  117. package/plugins/publishings/linkedin-pub/src/profile-check.ts +17 -0
  118. package/plugins/publishings/linkedin-pub/tsconfig.json +4 -0
  119. package/plugins/publishings/surfdash-pub/dist/index.js +1 -1
  120. package/plugins/publishings/surfdash-pub/src/index.ts +3 -1
  121. package/plugins/publishings/threads-pub/dist/index.js +7 -0
  122. package/plugins/publishings/threads-pub/src/index.ts +12 -0
  123. package/plugins/publishings/wechatmp-pub/dist/index.js +5 -2
  124. package/plugins/publishings/wechatmp-pub/src/flow.ts +11 -3
  125. package/plugins/publishings/x-pub/dist/index.js +7 -0
  126. package/plugins/publishings/x-pub/src/index.ts +11 -0
@@ -0,0 +1,17 @@
1
+ /**
2
+ * LinkedIn profile-session capability (0328 R2).
3
+ *
4
+ * `login` opens the feed in a headed browser and resolves only once LinkedIn's readiness predicate
5
+ * passes; `check` reopens the profile headlessly and reports `verified` or `refused` without
6
+ * posting. Arg parsing, profile precedence (`--profile` > `LINKEDIN_PROFILE_DIR` >
7
+ * `KK_BROWSER_PROFILE_DIR` > `~/.config/kk/browser-profiles/linkedin`, ADR-042) and the exit codes
8
+ * (0 verified, 1 refused, 2 usage error) all live in the shared `runProfileCli`, so the publish
9
+ * preflight (`kk plugin check linkedin-pub` and the publish-matrix probe) and this CLI apply one
10
+ * gate.
11
+ */
12
+ import { runProfileCli } from '@gobing-ai/publish-harness/browser';
13
+ import { LINKEDIN_CONFIG } from './index';
14
+
15
+ if (import.meta.main) {
16
+ process.exit(await runProfileCli(LINKEDIN_CONFIG, Bun.argv.slice(2)));
17
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "../../../tooling/typescript/base.json",
3
+ "include": ["src", "tests"]
4
+ }
@@ -13079,7 +13079,7 @@ function normalizeLocaleFrontmatter(markdown) {
13079
13079
  const close = lines.findIndex((l, i) => i > 0 && l.trim() === "---");
13080
13080
  if (close < 0)
13081
13081
  return markdown;
13082
- const head = lines.slice(1, close).filter((l) => !/^canonical\s*:/.test(l)).map((l) => /^draft\s*:/.test(l) ? "draft: false" : l);
13082
+ const head = lines.slice(1, close).filter((l) => !/^canonical\s*:.*\/zh\//.test(l)).map((l) => /^draft\s*:/.test(l) ? "draft: false" : l);
13083
13083
  return [lines[0], ...head, ...lines.slice(close)].join(`
13084
13084
  `);
13085
13085
  }
@@ -735,7 +735,9 @@ export function normalizeLocaleFrontmatter(markdown: string): string {
735
735
  if (close < 0) return markdown;
736
736
  const head = lines
737
737
  .slice(1, close)
738
- .filter((l) => !/^canonical\s*:/.test(l))
738
+ // Only the zh scaffold's canonical is stale; a sibling's own (refined) canonical must survive,
739
+ // or the orchestrator re-dumps the frontmatter and the byte-exact drift gate fails.
740
+ .filter((l) => !/^canonical\s*:.*\/zh\//.test(l))
739
741
  .map((l) => (/^draft\s*:/.test(l) ? 'draft: false' : l));
740
742
  return [lines[0], ...head, ...lines.slice(close)].join('\n');
741
743
  }
@@ -12391,6 +12391,13 @@ class ThreadsPostApiTransport {
12391
12391
  const unsupported = refuseUnsupportedOptions(payload.options, payload.content);
12392
12392
  if (unsupported !== undefined)
12393
12393
  return fail(unsupported);
12394
+ const requestedStatus = payload.content.metadata?.publishStatus;
12395
+ if (requestedStatus === "draft") {
12396
+ return fail("threads post has no draft: the Threads API publishes immediately \u2014 plan this target dummy/off or launch it live");
12397
+ }
12398
+ if (requestedStatus !== undefined && requestedStatus !== "public") {
12399
+ return fail(`unknown publishStatus '${String(requestedStatus)}' (expected absent, 'draft' or 'public')`);
12400
+ }
12394
12401
  const missing = TOKEN_ENVS.filter((key) => {
12395
12402
  const value = process.env[key];
12396
12403
  return !value || value.trim().length === 0;
@@ -146,6 +146,18 @@ export class ThreadsPostApiTransport implements PublishTransport {
146
146
  const unsupported = refuseUnsupportedOptions(payload.options, payload.content);
147
147
  if (unsupported !== undefined) return fail(unsupported);
148
148
 
149
+ // 0330 R2: the post API publishes immediately — there is no draft. Intercept before the
150
+ // credential lookup so a planned draft never reaches Threads, and fail closed on unknown modes.
151
+ const requestedStatus = payload.content.metadata?.publishStatus;
152
+ if (requestedStatus === 'draft') {
153
+ return fail(
154
+ 'threads post has no draft: the Threads API publishes immediately — plan this target dummy/off or launch it live',
155
+ );
156
+ }
157
+ if (requestedStatus !== undefined && requestedStatus !== 'public') {
158
+ return fail(`unknown publishStatus '${String(requestedStatus)}' (expected absent, 'draft' or 'public')`);
159
+ }
160
+
149
161
  const missing = TOKEN_ENVS.filter((key) => {
150
162
  const value = process.env[key];
151
163
  return !value || value.trim().length === 0;
@@ -23504,6 +23504,8 @@ function publicSnapshotIsIncomplete(expected, actual) {
23504
23504
  return true;
23505
23505
  if (!snapshotValueIsEmpty(expected.body) && snapshotValueIsEmpty(actual.body))
23506
23506
  return true;
23507
+ if (actual.body.length < expected.body.length && expected.body.startsWith(actual.body))
23508
+ return true;
23507
23509
  if (expected.media.length > actual.media.length)
23508
23510
  return true;
23509
23511
  if (!snapshotValueIsEmpty(expected.cover) && snapshotValueIsEmpty(actual.cover))
@@ -23659,8 +23661,9 @@ async function recoverStaleVersion(deps, entry, saved) {
23659
23661
  }, deps.draftTimeoutMs, deps.pollMs);
23660
23662
  if (!snapshotSettled || latestSnapshot === null)
23661
23663
  return fail("public stale-version recovery: latest editor snapshot was unreadable; no second \u53D1\u8868 click attempted");
23664
+ const latestBody = latestSnapshot.body;
23662
23665
  if (differences.length > 0)
23663
- return fail(`public stale-version recovery: latest editor content mismatch (${differences.join(", ")}); no second \u53D1\u8868 click attempted`);
23666
+ return fail(`public stale-version recovery: latest editor content mismatch (${differences.join(", ")}; body ${latestBody.length}/${saved.snapshot.body.length} chars); no second \u53D1\u8868 click attempted`);
23664
23667
  if (!await waitForPublicEditorReadiness(latestEditor, deps))
23665
23668
  return fail("public stale-version recovery: latest editor did not provide two consecutive recognized readiness probes; no second \u53D1\u8868 click attempted");
23666
23669
  return {
@@ -23716,7 +23719,7 @@ function shouldNotifySubscribers(content) {
23716
23719
  return wechatmp.notifySubscribers !== false;
23717
23720
  }
23718
23721
  async function confirmPublicPublish(page, notifySubscribers, stepTimeoutMs, pollMs) {
23719
- const confirmationTimeoutMs = Math.min(CONFIRM_TIMEOUT_MS, stepTimeoutMs);
23722
+ const confirmationTimeoutMs = stepTimeoutMs;
23720
23723
  const dialog = await findUniqueVisibleSelector(page, PUBLISH_DIALOG, confirmationTimeoutMs, pollMs);
23721
23724
  if (dialog.selector === undefined) {
23722
23725
  if (dialog.reason === "missing") {
@@ -1590,6 +1590,9 @@ function snapshotValueIsEmpty(value: string): boolean {
1590
1590
  function publicSnapshotIsIncomplete(expected: PublicDraftSnapshot, actual: PublicDraftSnapshot): boolean {
1591
1591
  if (!snapshotValueIsEmpty(expected.title) && snapshotValueIsEmpty(actual.title)) return true;
1592
1592
  if (!snapshotValueIsEmpty(expected.body) && snapshotValueIsEmpty(actual.body)) return true;
1593
+ // The editor renders a long body progressively; a strict prefix is still hydrating, not a
1594
+ // different version (20261104: 查看新草稿 failed on its first non-empty read).
1595
+ if (actual.body.length < expected.body.length && expected.body.startsWith(actual.body)) return true;
1593
1596
  if (expected.media.length > actual.media.length) return true;
1594
1597
  if (!snapshotValueIsEmpty(expected.cover) && snapshotValueIsEmpty(actual.cover)) return true;
1595
1598
  if (expected.originalUrl !== '' && actual.originalUrl === '') return true;
@@ -1837,9 +1840,11 @@ async function recoverStaleVersion(
1837
1840
  return fail(
1838
1841
  'public stale-version recovery: latest editor snapshot was unreadable; no second 发表 click attempted',
1839
1842
  );
1843
+ // TS narrows the closure-assigned `let` to never after the null guard; re-read it through a cast.
1844
+ const latestBody = (latestSnapshot as PublicDraftSnapshot).body;
1840
1845
  if (differences.length > 0)
1841
1846
  return fail(
1842
- `public stale-version recovery: latest editor content mismatch (${differences.join(', ')}); no second 发表 click attempted`,
1847
+ `public stale-version recovery: latest editor content mismatch (${differences.join(', ')}; body ${latestBody.length}/${saved.snapshot.body.length} chars); no second 发表 click attempted`,
1843
1848
  );
1844
1849
 
1845
1850
  if (!(await waitForPublicEditorReadiness(latestEditor, deps)))
@@ -1948,7 +1953,10 @@ async function confirmPublicPublish(
1948
1953
  stepTimeoutMs: number,
1949
1954
  pollMs: number,
1950
1955
  ): Promise<Result | PublicConfirmation | PreconfirmationStaleVersion> {
1951
- const confirmationTimeoutMs = Math.min(CONFIRM_TIMEOUT_MS, stepTimeoutMs);
1956
+ // Not CONFIRM_TIMEOUT_MS: this dialog runs a server-side check before it mounts (3.6s on an idle
1957
+ // editor, 2026-11-04), so a 5s cap reported it missing on 2026-11-03/04. Waiting costs nothing
1958
+ // irreversible — no click happens until the dialog is uniquely observed.
1959
+ const confirmationTimeoutMs = stepTimeoutMs;
1952
1960
  const dialog = await findUniqueVisibleSelector(page, PUBLISH_DIALOG, confirmationTimeoutMs, pollMs);
1953
1961
  if (dialog.selector === undefined) {
1954
1962
  if (dialog.reason === 'missing') {
@@ -2234,7 +2242,7 @@ export async function runMode(input: ModeInput, deps: ModeRunDeps): Promise<Resu
2234
2242
  * TypeScript only — no Python, no theme CLI.
2235
2243
  *
2236
2244
  * Kept instead of the shared `markdownToHtml` because the two differ on safety, measured on Bun
2237
- * 1.3.14: `Bun.markdown.html` passes raw HTML straight through (`<script>` included) and renders
2245
+ * 1.3.14 and again on 1.4.3: `Bun.markdown.html` passes raw HTML straight through (`<script>` included) and renders
2238
2246
  * `javascript:` link destinations, while this renderer escapes text and refuses non-http(s) link
2239
2247
  * schemes (R9). The *insertion* is the shared `pasteHtml` either way, so the ADR-029 rail holds.
2240
2248
  */
@@ -21008,6 +21008,13 @@ function resolveOperation(options, content) {
21008
21008
  class XPostApiTransport {
21009
21009
  kind = "file-cli";
21010
21010
  async publish(payload) {
21011
+ const requestedStatus = payload.content.metadata?.publishStatus;
21012
+ if (requestedStatus === "draft") {
21013
+ return fail("x post has no draft: the post API publishes immediately \u2014 plan this target dummy/off or launch it live");
21014
+ }
21015
+ if (requestedStatus !== undefined && requestedStatus !== "public") {
21016
+ return fail(`unknown publishStatus '${String(requestedStatus)}' (expected absent, 'draft' or 'public')`);
21017
+ }
21011
21018
  const missing = TOKEN_ENVS.filter((key) => {
21012
21019
  const value = process.env[key];
21013
21020
  return !value || value.trim().length === 0;
@@ -105,6 +105,17 @@ export class XPostApiTransport implements PublishTransport {
105
105
  public readonly kind = 'file-cli';
106
106
 
107
107
  public async publish(payload: PublishTransportPayload): Promise<Result> {
108
+ // 0330 R2: the post API publishes immediately — there is no draft. Intercept before the
109
+ // credential lookup so a planned draft never touches X, and fail closed on unknown modes.
110
+ const requestedStatus = payload.content.metadata?.publishStatus;
111
+ if (requestedStatus === 'draft') {
112
+ return fail(
113
+ 'x post has no draft: the post API publishes immediately — plan this target dummy/off or launch it live',
114
+ );
115
+ }
116
+ if (requestedStatus !== undefined && requestedStatus !== 'public') {
117
+ return fail(`unknown publishStatus '${String(requestedStatus)}' (expected absent, 'draft' or 'public')`);
118
+ }
108
119
  const missing = TOKEN_ENVS.filter((key) => {
109
120
  const value = process.env[key];
110
121
  return !value || value.trim().length === 0;