@gobing-ai/knowledge-kit 0.0.32 → 0.0.34

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 (72) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/dist/index.js +43047 -24724
  3. package/package.json +4 -4
  4. package/plugins/generations/content-gen/dist/index.js +10 -9
  5. package/plugins/generations/core-facts-gen/dist/index.js +13 -12
  6. package/plugins/generations/daily-article-gen/dist/index.js +16 -21
  7. package/plugins/generations/daily-article-gen/src/index.ts +8 -12
  8. package/plugins/generations/dailynews-gen/dist/index.js +23 -21
  9. package/plugins/generations/dailynews-gen/src/script-builder.ts +25 -26
  10. package/plugins/generations/episode-plan-gen/dist/index.js +58 -15
  11. package/plugins/generations/episode-plan-gen/src/index.ts +76 -6
  12. package/plugins/generations/gemini-tts/README.md +11 -0
  13. package/plugins/generations/gemini-tts/dist/index.js +10 -9
  14. package/plugins/generations/image-gen/dist/index.js +171 -153
  15. package/plugins/generations/image-gen/presets/formats/xhs-card.yaml +16 -14
  16. package/plugins/generations/image-gen/presets/styles/xhs-knowledge.yaml +2 -2
  17. package/plugins/generations/image-gen/src/compose/card.ts +17 -2
  18. package/plugins/generations/image-gen/src/compose/chromium.ts +60 -42
  19. package/plugins/generations/news-report-gen/dist/index.js +13 -12
  20. package/plugins/generations/voice-gen/dist/index.js +10 -9
  21. package/plugins/ingestions/aihot-ingest/dist/index.js +13 -12
  22. package/plugins/ingestions/horizon-ingest/dist/index.js +13 -12
  23. package/plugins/ingestions/karakeep-local/dist/index.js +13 -13
  24. package/plugins/ingestions/last30days-ingest/dist/index.js +13 -12
  25. package/plugins/ingestions/web-search/dist/index.js +11 -10
  26. package/plugins/kk/README.md +38 -0
  27. package/plugins/kk/decisions/extract/ai-news.yaml +27 -0
  28. package/plugins/kk/decisions/kk-items.yaml +179 -0
  29. package/plugins/kk/plugin.json +1 -1
  30. package/plugins/kk/schedules/cron.tmpl +15 -0
  31. package/plugins/kk/schedules/launchd.plist.tmpl +77 -0
  32. package/plugins/kk/scripts/daily-stages.ts +2023 -0
  33. package/plugins/kk/scripts/daily-voice-style.zh.md +15 -10
  34. package/plugins/kk/scripts/kk-workflow-stages.ts +253 -1368
  35. package/plugins/kk/skills/content-safety/SKILL.md +39 -8
  36. package/plugins/kk/skills/content-safety/references/platforms/apple-podcasts.md +2 -2
  37. package/plugins/kk/skills/web-automation/SKILL.md +100 -0
  38. package/plugins/kk/skills/web-automation/references/browser-launch.md +86 -0
  39. package/plugins/kk/workflows/kk-collect.yaml +256 -0
  40. package/plugins/kk/workflows/kk-daily-ai-voice.yaml +9 -3
  41. package/plugins/kk/workflows/kk-daily-ai-voice2.yaml +774 -0
  42. package/plugins/kk/workflows/kk-daily-safety.yaml +167 -0
  43. package/plugins/publishings/emdash-pub/dist/index.js +10 -9
  44. package/plugins/publishings/infoq-pub/dist/index.js +152 -59
  45. package/plugins/publishings/infoq-pub/plugin.json +1 -0
  46. package/plugins/publishings/infoq-pub/src/index.ts +167 -55
  47. package/plugins/publishings/infoq-pub/src/profile-check.ts +4 -2
  48. package/plugins/publishings/juejin-pub/dist/index.js +111 -30
  49. package/plugins/publishings/juejin-pub/plugin.json +1 -0
  50. package/plugins/publishings/juejin-pub/src/index.ts +49 -9
  51. package/plugins/publishings/medium-pub/dist/index.js +10 -9
  52. package/plugins/publishings/podcast-pub/dist/index.js +10 -9
  53. package/plugins/publishings/qiita-pub/dist/index.js +10 -9
  54. package/plugins/publishings/substack-pub/dist/index.js +105 -28
  55. package/plugins/publishings/substack-pub/plugin.json +1 -0
  56. package/plugins/publishings/substack-pub/src/index.ts +39 -8
  57. package/plugins/publishings/substack-pub/src/profile-check.ts +2 -0
  58. package/plugins/publishings/surfdash-pub/dist/index.js +10 -9
  59. package/plugins/publishings/wechatmp-pub/dist/index.js +115 -31
  60. package/plugins/publishings/wechatmp-pub/plugin.json +1 -0
  61. package/plugins/publishings/wechatmp-pub/src/index.ts +42 -9
  62. package/plugins/publishings/wechatmp-pub/src/profile-check.ts +84 -40
  63. package/plugins/publishings/x-pub/dist/index.js +114 -35
  64. package/plugins/publishings/x-pub/plugin.json +1 -0
  65. package/plugins/publishings/x-pub/src/index.ts +68 -14
  66. package/plugins/publishings/xhs-pub/dist/index.js +154 -59
  67. package/plugins/publishings/xhs-pub/plugin.json +1 -0
  68. package/plugins/publishings/xhs-pub/src/flow.ts +9 -3
  69. package/plugins/publishings/xhs-pub/src/index.ts +119 -9
  70. package/plugins/publishings/xhs-pub/src/page.ts +4 -17
  71. package/plugins/publishings/xhs-pub/src/profile-check.ts +28 -15
  72. package/plugins/publishings/zenn-pub/dist/index.js +10 -9
@@ -10,10 +10,11 @@ import {
10
10
  import {
11
11
  checkChannelSession,
12
12
  createShadowFinder,
13
+ kkBrowserLauncher,
13
14
  resolveChannelProfileDir,
14
15
  type ShadowCdpSession,
15
16
  } from '@gobing-ai/publish-harness/browser';
16
- import { type BrowserLauncher, openPersistentBrowser } from '@gobing-ai/ts-browser-automation';
17
+ import type { BrowserLauncher } from '@gobing-ai/ts-browser-automation';
17
18
  import { createNodeFileSystem } from '@gobing-ai/ts-runtime';
18
19
  import { echoError } from '@gobing-ai/ts-utils';
19
20
  import { type AutomationGuard, createAutomationGuard } from './automation-guard';
@@ -72,6 +73,71 @@ function fail(error: string): Result {
72
73
  return ResultSchema.parse({ ok: false, target: TARGET, error });
73
74
  }
74
75
 
76
+ /** One operation of a visit: its own Content and the mode input validated before any browser work. */
77
+ interface VisitOperation {
78
+ content: Content;
79
+ input: ModeInput;
80
+ }
81
+
82
+ /**
83
+ * A follow-up operation of a visit: planned, or refused with the reason it never reached the console.
84
+ * A refused follow-up is reported as its own failed Result entry — it can never fail the note the
85
+ * visit was opened for (ADR-025 amendment 2026-10-09).
86
+ */
87
+ type VisitFollowUp = { content: Content; operation: string; input: ModeInput } | { operation: string; error: string };
88
+
89
+ interface VisitPlan {
90
+ /** The requested operation, resolved and validated exactly as before task 0236. */
91
+ primary: VisitOperation;
92
+ /** The primary Content's `metadata.followUps`, in declared order. */
93
+ followUps: VisitFollowUp[];
94
+ }
95
+
96
+ /**
97
+ * Plan a visit (ADR-025 amendment 2026-10-09, task 0236 option A): the requested operation plus the
98
+ * follow-ups the caller attached to the primary Content's `metadata.followUps`. One headed visit may
99
+ * compose several notes under ONE cap entry — the cap still counts visits, not notes.
100
+ *
101
+ * The primary is planned as it always was: an unplannable primary is a `fail` and no browser opens.
102
+ * A follow-up that cannot be planned (not a Content, an undeclared operation, a missing or unreadable
103
+ * artifact) is refused here, before any console work, and reported as its own entry instead. A
104
+ * `metadata.followUps` that is not an array is a caller error, so it fails loud before any browser.
105
+ */
106
+ async function planVisit(
107
+ primary: VisitOperation,
108
+ content: Content,
109
+ ): Promise<{ plan: VisitPlan; error?: undefined } | { plan?: undefined; error: string }> {
110
+ const raw = content.metadata?.followUps;
111
+ if (raw === undefined) return { plan: { primary, followUps: [] } };
112
+ if (!Array.isArray(raw)) {
113
+ return {
114
+ error: `followUps validation: Content.metadata.followUps must be an array of Content objects, got ${typeof raw}`,
115
+ };
116
+ }
117
+ const followUps: VisitFollowUp[] = [];
118
+ for (const [index, entry] of raw.entries()) {
119
+ const label = `followUps[${index}]`;
120
+ const parsed = ContentSchema.safeParse(entry);
121
+ if (!parsed.success) {
122
+ followUps.push({ operation: label, error: `${label} is not a Content object` });
123
+ continue;
124
+ }
125
+ const operation = typeof parsed.data.metadata?.operation === 'string' ? parsed.data.metadata.operation : label;
126
+ const requested = resolveXhsOperation(undefined, parsed.data);
127
+ if (requested.error !== undefined) {
128
+ followUps.push({ operation, error: requested.error });
129
+ continue;
130
+ }
131
+ const validation = await validateModeInput(requested.operation, parsed.data);
132
+ if (validation.error !== undefined) {
133
+ followUps.push({ operation, error: validation.error });
134
+ continue;
135
+ }
136
+ followUps.push({ content: parsed.data, operation: requested.operation, input: validation.input });
137
+ }
138
+ return { plan: { primary, followUps } };
139
+ }
140
+
75
141
  /** CDP is Chromium-only; when unavailable the submit step fails loud instead of guessing. */
76
142
  export async function createShadowProbe(
77
143
  context: { newCDPSession?(page: unknown): Promise<ShadowCdpSession> },
@@ -93,15 +159,15 @@ export async function isXhsConsoleReady(page: XhsPage): Promise<boolean> {
93
159
  }
94
160
 
95
161
  /**
96
- * Production launcher: the upstream typed persistent-context opener (0177). Named so the
162
+ * Production launcher: the harness kk launcher (0214; full-Chromium channel + stealth). Named so the
97
163
  * migration is provable offline — tests assert this binding, never launch a real browser.
98
164
  */
99
- export const defaultLauncher = openPersistentBrowser;
165
+ export const defaultLauncher = kkBrowserLauncher.launch;
100
166
 
101
167
  /**
102
168
  * Build the default page opener. The launcher is injected so the seam (page wrapping, shadow
103
169
  * probe wiring, context close, launch-failure message) is testable without launching a browser;
104
- * production uses the upstream typed `openPersistentBrowser` (@gobing-ai/ts-browser-automation).
170
+ * production uses the harness `kkBrowserLauncher` (@gobing-ai/publish-harness/browser, 0214).
105
171
  */
106
172
  export function makeDefaultOpenPage(
107
173
  launch: (options: { profileDir: string; headless: boolean }) => Promise<unknown> = defaultLauncher,
@@ -147,6 +213,8 @@ export interface SessionCheckOptions {
147
213
  profileDir: string;
148
214
  timeoutMs?: number;
149
215
  launcher?: BrowserLauncher;
216
+ /** 0216: skip the headless pass and probe headed only (manual `check --headed`). */
217
+ headedOnly?: boolean;
150
218
  }
151
219
 
152
220
  /**
@@ -173,6 +241,7 @@ export async function checkXhsProfileSession(opts: SessionCheckOptions): Promise
173
241
  profileDir: opts.profileDir,
174
242
  launcher: opts.launcher,
175
243
  timeoutMs: opts.timeoutMs ?? PREFLIGHT_TIMEOUT_MS,
244
+ headedOnly: opts.headedOnly === true,
176
245
  },
177
246
  );
178
247
  }
@@ -235,13 +304,20 @@ export class XhsBrowserTransport implements PublishTransport {
235
304
  if (validation.error !== undefined) return fail(validation.error);
236
305
  const input: ModeInput = validation.input;
237
306
 
307
+ // ADR-025 amendment (2026-10-09, task 0236 option A): one visit may compose more than one
308
+ // note. The follow-ups ride the primary Content's `metadata.followUps` and are planned here,
309
+ // with the primary, before any browser work.
310
+ const visited = await planVisit({ content: payload.content, input }, payload.content);
311
+ if (visited.error !== undefined) return fail(visited.error);
312
+ const visit = visited.plan;
313
+
238
314
  const override = typeof payload.options?.profileDir === 'string' ? payload.options.profileDir : undefined;
239
315
  const profileDir = resolveChannelProfileDir(CHANNEL, override);
240
- const publishStatus = payload.content.metadata?.publishStatus === 'public' ? 'public' : 'draft';
241
316
 
242
317
  // ADR-025 automation guard — both gates run before any browser opens.
243
318
  // 1. Frequency cap: the operator's platform warning makes a repeated console visit an
244
- // account-level risk, not merely a failed run.
319
+ // account-level risk, not merely a failed run. The cap counts VISITS: one allow/record
320
+ // per visit covers every note the visit composes.
245
321
  const cap = this.automation.allow('publish');
246
322
  if (!cap.allowed) return fail(`automation cap: ${cap.reason}`);
247
323
  // 2. Headless session preflight: an unauthenticated profile must never produce a headed
@@ -262,6 +338,41 @@ export class XhsBrowserTransport implements PublishTransport {
262
338
  return fail(error instanceof Error ? error.message : String(error));
263
339
  }
264
340
  const { page, close } = opened;
341
+ try {
342
+ // The visit's own Result is the primary operation's: a failed primary ends the visit, as
343
+ // it always did, and only a primary that stood reports its follow-ups.
344
+ const primary = await this.runStep(visit.primary.input, visit.primary.content, page, profileDir);
345
+ if (!primary.ok || visit.followUps.length === 0) return primary;
346
+ // One Result entry per operation, in declared order; a refused and a failed follow-up
347
+ // are the same kind of entry, and neither can fail the note the visit was opened for.
348
+ const followUps: Result[] = [];
349
+ for (const followUp of visit.followUps) {
350
+ const step =
351
+ 'error' in followUp
352
+ ? fail(`follow-up (${followUp.operation}): ${followUp.error}`)
353
+ : await this.runStep(followUp.input, followUp.content, page, profileDir);
354
+ // Every entry names the operation it was planned under — a failed or refused one too,
355
+ // so the caller can tell which note fell; the step's own metadata wins.
356
+ followUps.push(
357
+ ResultSchema.parse({ ...step, metadata: { operation: followUp.operation, ...step.metadata } }),
358
+ );
359
+ }
360
+ return ResultSchema.parse({ ...primary, metadata: { ...primary.metadata, followUps } });
361
+ } finally {
362
+ await close();
363
+ }
364
+ }
365
+
366
+ /**
367
+ * Run one operation of the visit in the page the visit already opened. Every step enters the
368
+ * console from its landing view: the primary needs the login gate and the pre-entry draft
369
+ * baseline, and a follow-up needs both again — the previous note's editor replaces the header,
370
+ * and the baseline must be read before THIS note's mode is entered.
371
+ *
372
+ * A step never throws: its failure is that operation's own `ok:false` Result, which is what keeps
373
+ * a failed follow-up from failing the visit (ADR-025 amendment 2026-10-09).
374
+ */
375
+ private async runStep(input: ModeInput, content: Content, page: XhsPage, profileDir: string): Promise<Result> {
265
376
  const act = async <T>(what: string, fn: () => Promise<T>): Promise<T> => {
266
377
  try {
267
378
  return await fn();
@@ -279,6 +390,7 @@ export class XhsBrowserTransport implements PublishTransport {
279
390
  );
280
391
  }
281
392
 
393
+ const publishStatus = content.metadata?.publishStatus === 'public' ? 'public' : 'draft';
282
394
  // The draft counter and any save timestamps exist only on the landing view, so the
283
395
  // baseline is captured before the mode is entered (the editor replaces the header).
284
396
  const draftBaseline =
@@ -286,7 +398,7 @@ export class XhsBrowserTransport implements PublishTransport {
286
398
 
287
399
  return await runMode(input, {
288
400
  page,
289
- content: payload.content,
401
+ content,
290
402
  publishStatus,
291
403
  profileDir,
292
404
  driver: this.driver,
@@ -297,8 +409,6 @@ export class XhsBrowserTransport implements PublishTransport {
297
409
  });
298
410
  } catch (error) {
299
411
  return fail(error instanceof Error ? error.message : String(error));
300
- } finally {
301
- await close();
302
412
  }
303
413
  }
304
414
  }
@@ -1,4 +1,5 @@
1
1
  import { trySelectors } from '@gobing-ai/publish-harness';
2
+ import { waitUntil } from '@gobing-ai/publish-harness/browser';
2
3
 
3
4
  /**
4
5
  * The console's page seam (ADR-029) and the helpers every xhs operation shares.
@@ -10,6 +11,9 @@ import { trySelectors } from '@gobing-ai/publish-harness';
10
11
  */
11
12
 
12
13
  export const POLL_MS = 500;
14
+
15
+ // The shared poll (0184 R2); re-exported so flow/index keep importing it from here.
16
+ export { waitUntil };
13
17
  export const STEP_TIMEOUT_MS = 30_000;
14
18
 
15
19
  /** The console's mode tab bar; it mounts late and renders every tab several times over. */
@@ -120,23 +124,6 @@ export async function clickCreatorTab(
120
124
  }
121
125
  }
122
126
 
123
- /**
124
- * Poll `predicate` every `pollMs` until the deadline, then evaluate it one final time. The trailing
125
- * call matters: the condition often becomes true exactly at the boundary.
126
- */
127
- export async function waitUntil(
128
- predicate: () => Promise<boolean>,
129
- timeoutMs: number,
130
- pollMs = POLL_MS,
131
- ): Promise<boolean> {
132
- const deadline = Date.now() + timeoutMs;
133
- while (Date.now() < deadline) {
134
- if (await predicate()) return true;
135
- await new Promise((resolve) => setTimeout(resolve, pollMs));
136
- }
137
- return predicate();
138
- }
139
-
140
127
  export function wrapPlaywrightPage(raw: unknown, shadow?: ShadowProbe): XhsPage {
141
128
  const pw = raw as {
142
129
  goto(url: string, options?: Record<string, unknown>): Promise<unknown>;
@@ -6,7 +6,8 @@
6
6
  * - `login` recovers an absent/expired session headed via the upstream
7
7
  * `loginWithProfile`, polled with the same XHS-owned readiness gate the publish
8
8
  * flow uses;
9
- * - `check` reopens the existing profile headless and reports the session as
9
+ * - `check` reopens the existing profile (headless by default; `--headed` skips the headless
10
+ * pass and probes headed only, 0216) and reports the session as
10
11
  * `verified` or `refused` — a site refusal, expired session, or missing profile
11
12
  * is an explicit failed readiness, never a success. The upstream launcher never
12
13
  * creates a profile headless, so a check cannot fabricate a session from a
@@ -21,7 +22,7 @@
21
22
  * the full recipe lives in docs/design/xhs-image-cards.md.
22
23
  */
23
24
  import { parseArgs } from 'node:util';
24
- import { resolveChannelProfileDir } from '@gobing-ai/publish-harness/browser';
25
+ import { kkBrowserLauncher, resolveChannelProfileDir } from '@gobing-ai/publish-harness/browser';
25
26
  import { type BrowserLauncher, loginWithProfile } from '@gobing-ai/ts-browser-automation';
26
27
  import { echo, echoError } from '@gobing-ai/ts-utils';
27
28
  import { type AutomationGuard, createAutomationGuard } from './automation-guard';
@@ -60,11 +61,20 @@ export async function loginProfile(opts: ProfileLoginOptions): Promise<void> {
60
61
  url: PUBLISH_URL,
61
62
  isAuthenticated: (page) => isXhsConsoleReady(wrapPlaywrightPage(page)),
62
63
  timeoutMs: opts.timeoutMs ?? LOGIN_TIMEOUT_MS,
63
- launcher: opts.launcher,
64
+ launcher: opts.launcher ?? kkBrowserLauncher,
64
65
  });
65
66
  }
66
67
 
67
- /** `login|check [--profile <dir>] [--timeout <ms>]`; profile precedence matches the publish flow. */
68
+ /** Exit 2 with the human usage on stderr and the ADR-032 `error` verdict as the last stdout line. */
69
+ function usageError(message: string): number {
70
+ echoError(
71
+ `profile-check: ${message} — usage: profile-check.ts [login|check] [--profile <dir>] [--timeout <ms>] [--headed]`,
72
+ );
73
+ echo(JSON.stringify({ status: 'error', detail: message }));
74
+ return 2;
75
+ }
76
+
77
+ /** `login|check [--profile <dir>] [--timeout <ms>] [--headed]`; profile precedence matches the publish flow. */
68
78
  export async function main(
69
79
  argv: string[] = process.argv.slice(2),
70
80
  launcher?: BrowserLauncher,
@@ -73,13 +83,19 @@ export async function main(
73
83
  let command: string;
74
84
  let profileDir: string;
75
85
  let timeoutMs: number | undefined;
86
+ let headed = false;
76
87
  try {
77
88
  const { positionals, values } = parseArgs({
78
89
  args: argv,
79
90
  allowPositionals: true,
80
- options: { profile: { type: 'string' }, timeout: { type: 'string' } },
91
+ options: {
92
+ profile: { type: 'string' },
93
+ timeout: { type: 'string' },
94
+ headed: { type: 'boolean' },
95
+ },
81
96
  });
82
97
  command = positionals[0] ?? 'check';
98
+ headed = values.headed === true;
83
99
  if (values.timeout !== undefined) {
84
100
  timeoutMs = Number(values.timeout);
85
101
  if (!Number.isFinite(timeoutMs) || timeoutMs < 0) {
@@ -88,10 +104,7 @@ export async function main(
88
104
  }
89
105
  profileDir = resolveChannelProfileDir(CHANNEL, values.profile);
90
106
  } catch (error) {
91
- echoError(
92
- `profile-check: ${error instanceof Error ? error.message : String(error)} — usage: profile-check.ts [login|check] [--profile <dir>] [--timeout <ms>]`,
93
- );
94
- return 1;
107
+ return usageError(error instanceof Error ? error.message : String(error));
95
108
  }
96
109
  if (command === 'login') {
97
110
  try {
@@ -104,21 +117,21 @@ export async function main(
104
117
  }
105
118
  }
106
119
  if (command !== 'check') {
107
- echoError(
108
- `profile-check: unknown command '${command}' — usage: profile-check.ts [login|check] [--profile <dir>] [--timeout <ms>]`,
109
- );
110
- return 1;
120
+ return usageError(`unknown command '${command}'`);
111
121
  }
112
122
  // ADR-025: a manual session check is a real console visit, so it draws on the shared 2h
113
123
  // automation budget rather than a separate one. `login` is deliberately uncapped above: it is
114
124
  // operator-interactive, so capping it would only block recovery from an expired session.
115
125
  const cap = guard.allow('check');
116
126
  if (!cap.allowed) {
117
- echoError(`profile-check: ${cap.reason}`);
127
+ // The budget refusal is still a readiness verdict (0216 contract): emit the JSON line so
128
+ // `kk plugin check` reports a refusal with the operator hint instead of a malformed probe.
129
+ echo(JSON.stringify({ status: 'refused', profileDir, detail: `xhs readiness refused: ${cap.reason}` }));
130
+ echoError(cap.reason);
118
131
  return 1;
119
132
  }
120
133
  guard.record('check');
121
- const outcome = await checkXhsProfileSession({ profileDir, timeoutMs, launcher });
134
+ const outcome = await checkXhsProfileSession({ profileDir, timeoutMs, launcher, headedOnly: headed });
122
135
  echo(JSON.stringify(outcome));
123
136
  if (outcome.status !== 'verified') {
124
137
  echoError(outcome.detail);
@@ -14642,7 +14642,7 @@ var init_zod = __esm(() => {
14642
14642
  init_external();
14643
14643
  });
14644
14644
 
14645
- // ../../node_modules/.bun/@gobing-ai+ts-utils@0.5.15/node_modules/@gobing-ai/ts-utils/dist/errors.js
14645
+ // ../../node_modules/.bun/@gobing-ai+ts-utils@0.5.21/node_modules/@gobing-ai/ts-utils/dist/errors.js
14646
14646
  var ErrorCode;
14647
14647
  var init_errors3 = __esm(() => {
14648
14648
  ErrorCode = {
@@ -14653,7 +14653,7 @@ var init_errors3 = __esm(() => {
14653
14653
  };
14654
14654
  });
14655
14655
 
14656
- // ../../node_modules/.bun/@gobing-ai+ts-utils@0.5.15/node_modules/@gobing-ai/ts-utils/dist/api-response.js
14656
+ // ../../node_modules/.bun/@gobing-ai+ts-utils@0.5.21/node_modules/@gobing-ai/ts-utils/dist/api-response.js
14657
14657
  var API_ERROR_CODES, ERROR_CODE_TO_HTTP, CLIENT_SAFE_CODES;
14658
14658
  var init_api_response = __esm(() => {
14659
14659
  init_errors3();
@@ -14676,13 +14676,13 @@ var init_api_response = __esm(() => {
14676
14676
  CLIENT_SAFE_CODES = new Set([ErrorCode.NotFound, ErrorCode.Validation, ErrorCode.Conflict]);
14677
14677
  });
14678
14678
 
14679
- // ../../node_modules/.bun/@gobing-ai+ts-utils@0.5.15/node_modules/@gobing-ai/ts-utils/dist/cursor.js
14679
+ // ../../node_modules/.bun/@gobing-ai+ts-utils@0.5.21/node_modules/@gobing-ai/ts-utils/dist/cursor.js
14680
14680
  var init_cursor = () => {};
14681
14681
 
14682
- // ../../node_modules/.bun/@gobing-ai+ts-utils@0.5.15/node_modules/@gobing-ai/ts-utils/dist/event-severity.js
14682
+ // ../../node_modules/.bun/@gobing-ai+ts-utils@0.5.21/node_modules/@gobing-ai/ts-utils/dist/event-severity.js
14683
14683
  var init_event_severity = () => {};
14684
14684
 
14685
- // ../../node_modules/.bun/@gobing-ai+ts-utils@0.5.15/node_modules/@gobing-ai/ts-utils/dist/output.js
14685
+ // ../../node_modules/.bun/@gobing-ai+ts-utils@0.5.21/node_modules/@gobing-ai/ts-utils/dist/output.js
14686
14686
  function processStream(name) {
14687
14687
  const proc = globalThis.process;
14688
14688
  const stream = proc?.[name];
@@ -14700,7 +14700,7 @@ function echoError(message, target = defaultStderrTarget ?? processStream("stder
14700
14700
  }
14701
14701
  var defaultStderrTarget;
14702
14702
 
14703
- // ../../node_modules/.bun/@gobing-ai+ts-utils@0.5.15/node_modules/@gobing-ai/ts-utils/dist/index.js
14703
+ // ../../node_modules/.bun/@gobing-ai+ts-utils@0.5.21/node_modules/@gobing-ai/ts-utils/dist/index.js
14704
14704
  var init_dist = __esm(() => {
14705
14705
  init_api_response();
14706
14706
  init_cursor();
@@ -21698,7 +21698,7 @@ var init_dist2 = __esm(() => {
21698
21698
  $visitAsync = visit.visitAsync;
21699
21699
  });
21700
21700
 
21701
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.5.15/node_modules/@gobing-ai/ts-runtime/dist/config.js
21701
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.5.21+44edd5c4d6372504/node_modules/@gobing-ai/ts-runtime/dist/config.js
21702
21702
  var configSchema;
21703
21703
  var init_config = __esm(() => {
21704
21704
  init_dist2();
@@ -21722,7 +21722,7 @@ var init_config = __esm(() => {
21722
21722
  });
21723
21723
  });
21724
21724
 
21725
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.5.15/node_modules/@gobing-ai/ts-runtime/dist/file-system-node.js
21725
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.5.21+44edd5c4d6372504/node_modules/@gobing-ai/ts-runtime/dist/file-system-node.js
21726
21726
  import { appendFileSync, cpSync, createReadStream, createWriteStream, existsSync, mkdirSync, readdirSync, readFileSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "fs";
21727
21727
  import { dirname, resolve as resolvePath } from "path";
21728
21728
  function createNodeFileSystem(root, paths) {
@@ -21897,11 +21897,12 @@ var PluginManifestSchema = exports_external.looseObject({
21897
21897
  name: exports_external.string().min(1),
21898
21898
  kind: PluginKindSchema,
21899
21899
  entry: exports_external.string().min(1),
21900
+ check: exports_external.string().min(1).optional(),
21900
21901
  version: exports_external.string().optional(),
21901
21902
  description: exports_external.string().optional(),
21902
21903
  operations: exports_external.record(exports_external.string(), PluginOperationSchema).optional()
21903
21904
  });
21904
- // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.5.15/node_modules/@gobing-ai/ts-runtime/dist/index.js
21905
+ // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.5.21+44edd5c4d6372504/node_modules/@gobing-ai/ts-runtime/dist/index.js
21905
21906
  init_file_system_node();
21906
21907
  init_config();
21907
21908