@gobing-ai/knowledge-kit 0.0.6 → 0.0.8

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 (50) hide show
  1. package/dist/index.js +21643 -11933
  2. package/package.json +4 -1
  3. package/plugins/generations/content-gen/package.json +2 -1
  4. package/plugins/generations/content-gen/src/index.ts +9 -8
  5. package/plugins/generations/content-gen/src/storm.ts +12 -4
  6. package/plugins/generations/voice-gen/package.json +17 -0
  7. package/plugins/generations/voice-gen/plugin.json +6 -0
  8. package/plugins/generations/voice-gen/src/concat.ts +218 -0
  9. package/plugins/generations/voice-gen/src/index.ts +213 -0
  10. package/plugins/generations/voice-gen/src/voicebox-client.ts +223 -0
  11. package/plugins/generations/voice-gen/src/voicescript.ts +365 -0
  12. package/plugins/generations/voice-gen/tsconfig.json +8 -0
  13. package/plugins/ingestions/karakeep-local/package.json +17 -0
  14. package/plugins/ingestions/karakeep-local/src/index.ts +31 -26
  15. package/plugins/ingestions/karakeep-local/tsconfig.json +4 -0
  16. package/plugins/ingestions/web-search/package.json +4 -1
  17. package/plugins/ingestions/web-search/src/index.ts +299 -17
  18. package/plugins/kk/README.md +12 -1
  19. package/plugins/kk/commands/workflow-run.md +202 -0
  20. package/plugins/kk/config.example.yaml +34 -0
  21. package/plugins/kk/scripts/render-md.ts +150 -0
  22. package/plugins/kk/skills/{kk-judge → content-judge}/SKILL.md +13 -14
  23. package/plugins/kk/skills/{kk-judge → content-judge}/references/rubrics.md +2 -2
  24. package/plugins/kk/skills/{kk-judge → content-judge}/references/workflow-integration.md +17 -15
  25. package/plugins/kk/skills/itc-generating/SKILL.md +147 -0
  26. package/plugins/kk/skills/itc-generating/references/generic-craft.md +80 -0
  27. package/plugins/kk/skills/itc-generating/references/platform-english.md +72 -0
  28. package/plugins/kk/skills/itc-generating/references/platform-wechat.md +60 -0
  29. package/plugins/kk/skills/itc-generating/references/skill-authoring.md +62 -0
  30. package/plugins/kk/skills/storm-research/SKILL.md +173 -0
  31. package/plugins/kk/skills/{kk-topic → topic}/SKILL.md +4 -4
  32. package/plugins/kk/workflows/judge-gated-publish-example.yaml +101 -0
  33. package/plugins/kk/workflows/kk-ingest-generate-publish.yaml +72 -0
  34. package/plugins/kk/workflows/kk-itc.yaml +285 -0
  35. package/plugins/kk/workflows/kk-solo-podcast.yaml +374 -0
  36. package/plugins/kk/workflows/kk-storm-research.yaml +184 -0
  37. package/plugins/kk/workflows/validate-voicescript.ts +226 -0
  38. package/plugins/publishings/emdash-pub/package.json +17 -0
  39. package/plugins/publishings/emdash-pub/plugin.json +7 -0
  40. package/plugins/publishings/emdash-pub/src/index.ts +450 -0
  41. package/plugins/publishings/emdash-pub/tsconfig.json +4 -0
  42. package/plugins/publishings/qiita-pub/package.json +2 -1
  43. package/plugins/publishings/qiita-pub/src/index.ts +9 -9
  44. package/plugins/publishings/surfdash-pub/package.json +2 -1
  45. package/plugins/publishings/surfdash-pub/src/index.ts +16 -11
  46. package/plugins/publishings/zenn-pub/package.json +2 -1
  47. package/plugins/publishings/zenn-pub/src/index.ts +11 -11
  48. package/plugins/kk/agents/kk-judge-compliance.md +0 -37
  49. package/plugins/kk/agents/kk-judge-tech.md +0 -35
  50. package/plugins/kk/agents/kk-judge-tone.md +0 -37
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "../../../tooling/typescript/base.json",
3
+ "include": ["src", "tests"]
4
+ }
@@ -8,7 +8,8 @@
8
8
  "dependencies": {
9
9
  "@gobing-ai/kk-core": "workspace:*",
10
10
  "@gobing-ai/publish-harness": "workspace:*",
11
- "@gobing-ai/utils": "workspace:*"
11
+ "@gobing-ai/ts-runtime": "catalog:",
12
+ "@gobing-ai/ts-utils": "catalog:"
12
13
  },
13
14
  "devDependencies": {
14
15
  "@types/bun": "1.3.14"
@@ -1,9 +1,9 @@
1
- import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';
2
1
  import { dirname } from 'node:path';
3
2
  import { parseArgs } from 'node:util';
4
3
  import { type Content, ContentSchema, type Result, ResultSchema } from '@gobing-ai/kk-core';
5
4
  import { FakeFileCliTransport, type PublishTransport, type PublishTransportPayload } from '@gobing-ai/publish-harness';
6
- import { logger } from '@gobing-ai/utils';
5
+ import { createNodeFileSystem } from '@gobing-ai/ts-runtime';
6
+ import { echoError } from '@gobing-ai/ts-utils';
7
7
 
8
8
  /** Qiita API v2 article-create endpoint (audited from wt-publish-to-qiita). */
9
9
  const QIITA_ITEMS_URL = 'https://qiita.com/api/v2/items';
@@ -192,9 +192,9 @@ export function getPublishTransport(): PublishTransport {
192
192
  async function writePublishResult(outputPath: string, result: Result): Promise<void> {
193
193
  const outDir = dirname(outputPath);
194
194
  if (outDir && outDir !== '.') {
195
- await mkdir(outDir, { recursive: true });
195
+ await createNodeFileSystem().ensureDir(outDir);
196
196
  }
197
- await writeFile(outputPath, JSON.stringify(result, null, 2), 'utf-8');
197
+ await createNodeFileSystem().writeFile(outputPath, JSON.stringify(result, null, 2));
198
198
  }
199
199
 
200
200
  /**
@@ -208,11 +208,11 @@ export async function processPublishIO(
208
208
  outputPath: string,
209
209
  transport: PublishTransport = getPublishTransport(),
210
210
  ): Promise<void> {
211
- await rm(outputPath, { force: true });
211
+ await createNodeFileSystem().deleteFile(outputPath);
212
212
 
213
213
  let content: Content;
214
214
  try {
215
- const rawInput = await readFile(inputPath, 'utf-8');
215
+ const rawInput = await createNodeFileSystem().readFile(inputPath);
216
216
  content = ContentSchema.parse(JSON.parse(rawInput));
217
217
  } catch (error: unknown) {
218
218
  const message = `Invalid Content input: ${error instanceof Error ? error.message : String(error)}`;
@@ -239,12 +239,12 @@ export async function main(): Promise<number> {
239
239
  },
240
240
  }));
241
241
  } catch (error: unknown) {
242
- logger.error(`Invalid arguments: ${error instanceof Error ? error.message : String(error)}`);
242
+ echoError(`Invalid arguments: ${error instanceof Error ? error.message : String(error)}`);
243
243
  return 1;
244
244
  }
245
245
 
246
246
  if (!values.in || !values.out) {
247
- logger.error('Missing required arguments: --in and --out');
247
+ echoError('Missing required arguments: --in and --out');
248
248
  return 1;
249
249
  }
250
250
 
@@ -252,7 +252,7 @@ export async function main(): Promise<number> {
252
252
  await processPublishIO(values.in, values.out);
253
253
  return 0;
254
254
  } catch (error: unknown) {
255
- logger.error(`qiita-pub failed: ${error instanceof Error ? error.message : String(error)}`);
255
+ echoError(`qiita-pub failed: ${error instanceof Error ? error.message : String(error)}`);
256
256
  return 1;
257
257
  }
258
258
  }
@@ -8,7 +8,8 @@
8
8
  "dependencies": {
9
9
  "@gobing-ai/kk-core": "workspace:*",
10
10
  "@gobing-ai/publish-harness": "workspace:*",
11
- "@gobing-ai/utils": "workspace:*"
11
+ "@gobing-ai/ts-runtime": "catalog:",
12
+ "@gobing-ai/ts-utils": "catalog:"
12
13
  },
13
14
  "devDependencies": {
14
15
  "@types/bun": "1.3.14"
@@ -1,9 +1,9 @@
1
- import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';
2
1
  import { dirname, join } from 'node:path';
3
2
  import { parseArgs } from 'node:util';
4
3
  import { type Content, ContentSchema, type Result, ResultSchema } from '@gobing-ai/kk-core';
5
4
  import type { PublishTransport, PublishTransportPayload } from '@gobing-ai/publish-harness';
6
- import { logger } from '@gobing-ai/utils';
5
+ import { createNodeFileSystem } from '@gobing-ai/ts-runtime';
6
+ import { echoError } from '@gobing-ai/ts-utils';
7
7
 
8
8
  /**
9
9
  * Options for mapping Content into Surfing Markdown with frontmatter.
@@ -88,14 +88,14 @@ export class PostsurfingFileCliTransport implements PublishTransport {
88
88
  public async publish(payload: PublishTransportPayload): Promise<Result> {
89
89
  const markdown = mapContentToSurfingMarkdown(payload.content);
90
90
  const tempDir = join(process.cwd(), '.tmp-surfdash');
91
- await mkdir(tempDir, { recursive: true });
91
+ await createNodeFileSystem().ensureDir(tempDir);
92
92
 
93
93
  const titleSlug = slugify(payload.content.title ?? 'post');
94
94
  const fileName = `${titleSlug || 'post'}-${Date.now()}.md`;
95
95
  const filePath = join(tempDir, fileName);
96
96
 
97
97
  try {
98
- await writeFile(filePath, markdown, 'utf-8');
98
+ await createNodeFileSystem().writeFile(filePath, markdown);
99
99
  const postsurfingBin = process.env.POSTSURFING_BIN ?? 'postsurfing';
100
100
 
101
101
  const proc = Bun.spawn([postsurfingBin, 'publish', filePath], {
@@ -130,7 +130,12 @@ export class PostsurfingFileCliTransport implements PublishTransport {
130
130
  error: `Postsurfing transport error: ${err instanceof Error ? err.message : String(err)}`,
131
131
  });
132
132
  } finally {
133
- await rm(filePath, { force: true }).catch(() => {});
133
+ // Best-effort temp cleanup: a failure here must not mask the publish result.
134
+ try {
135
+ await createNodeFileSystem().deleteFile(filePath);
136
+ } catch {
137
+ // ignore
138
+ }
134
139
  }
135
140
  }
136
141
  }
@@ -154,8 +159,8 @@ export async function processPublishIO(
154
159
  outputPath: string,
155
160
  transport: PublishTransport = getPublishTransport(),
156
161
  ): Promise<void> {
157
- await rm(outputPath, { force: true });
158
- const rawInput = await readFile(inputPath, 'utf-8');
162
+ await createNodeFileSystem().deleteFile(outputPath);
163
+ const rawInput = await createNodeFileSystem().readFile(inputPath);
159
164
  const content = ContentSchema.parse(JSON.parse(rawInput));
160
165
 
161
166
  const result = await transport.publish({ content });
@@ -163,10 +168,10 @@ export async function processPublishIO(
163
168
 
164
169
  const outDir = dirname(outputPath);
165
170
  if (outDir && outDir !== '.') {
166
- await mkdir(outDir, { recursive: true });
171
+ await createNodeFileSystem().ensureDir(outDir);
167
172
  }
168
173
 
169
- await writeFile(outputPath, JSON.stringify(validatedResult, null, 2), 'utf-8');
174
+ await createNodeFileSystem().writeFile(outputPath, JSON.stringify(validatedResult, null, 2));
170
175
 
171
176
  if (!validatedResult.ok) {
172
177
  throw new Error(validatedResult.error ?? 'Publish failed');
@@ -182,7 +187,7 @@ export async function main(): Promise<number> {
182
187
  });
183
188
 
184
189
  if (!values.in || !values.out) {
185
- logger.error('Missing required arguments: --in and --out');
190
+ echoError('Missing required arguments: --in and --out');
186
191
  return 1;
187
192
  }
188
193
 
@@ -190,7 +195,7 @@ export async function main(): Promise<number> {
190
195
  await processPublishIO(values.in, values.out);
191
196
  return 0;
192
197
  } catch (error: unknown) {
193
- logger.error(`surfdash-pub failed: ${error instanceof Error ? error.message : String(error)}`);
198
+ echoError(`surfdash-pub failed: ${error instanceof Error ? error.message : String(error)}`);
194
199
  return 1;
195
200
  }
196
201
  }
@@ -8,7 +8,8 @@
8
8
  "dependencies": {
9
9
  "@gobing-ai/kk-core": "workspace:*",
10
10
  "@gobing-ai/publish-harness": "workspace:*",
11
- "@gobing-ai/utils": "workspace:*"
11
+ "@gobing-ai/ts-runtime": "catalog:",
12
+ "@gobing-ai/ts-utils": "catalog:"
12
13
  },
13
14
  "devDependencies": {
14
15
  "@types/bun": "1.3.14"
@@ -1,10 +1,10 @@
1
- import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';
2
1
  import { homedir } from 'node:os';
3
2
  import { dirname, join } from 'node:path';
4
3
  import { parseArgs } from 'node:util';
5
4
  import { type Content, ContentSchema, type Result, ResultSchema } from '@gobing-ai/kk-core';
6
5
  import { FakeFileCliTransport, type PublishTransport, type PublishTransportPayload } from '@gobing-ai/publish-harness';
7
- import { logger } from '@gobing-ai/utils';
6
+ import { createNodeFileSystem } from '@gobing-ai/ts-runtime';
7
+ import { echoError } from '@gobing-ai/ts-utils';
8
8
 
9
9
  /**
10
10
  * Converts a string into a lowercase hyphenated tag (slug) per the publish spec tags convention.
@@ -163,7 +163,7 @@ export class ZennCliFileCliTransport implements PublishTransport {
163
163
  const repoPath = repo.startsWith('~') ? join(homedir(), repo.slice(2)) : repo;
164
164
 
165
165
  try {
166
- await mkdir(repoPath, { recursive: true });
166
+ await createNodeFileSystem().ensureDir(repoPath);
167
167
 
168
168
  const cliArgs = ['--yes', 'zenn', 'new:article', '--slug', slug, '--title', title, '--type', type];
169
169
  if (emoji) {
@@ -179,9 +179,9 @@ export class ZennCliFileCliTransport implements PublishTransport {
179
179
  }
180
180
 
181
181
  const articleDir = join(repoPath, 'articles');
182
- await mkdir(articleDir, { recursive: true });
182
+ await createNodeFileSystem().ensureDir(articleDir);
183
183
  const articlePath = join(articleDir, `${slug}.md`);
184
- await writeFile(articlePath, markdown, 'utf-8');
184
+ await createNodeFileSystem().writeFile(articlePath, markdown);
185
185
 
186
186
  if (published) {
187
187
  const gitSteps: string[][] = [
@@ -246,9 +246,9 @@ export function getPublishTransport(): PublishTransport {
246
246
  async function writePublishResult(outputPath: string, result: Result): Promise<void> {
247
247
  const outDir = dirname(outputPath);
248
248
  if (outDir && outDir !== '.') {
249
- await mkdir(outDir, { recursive: true });
249
+ await createNodeFileSystem().ensureDir(outDir);
250
250
  }
251
- await writeFile(outputPath, JSON.stringify(result, null, 2), 'utf-8');
251
+ await createNodeFileSystem().writeFile(outputPath, JSON.stringify(result, null, 2));
252
252
  }
253
253
 
254
254
  /**
@@ -262,11 +262,11 @@ export async function processPublishIO(
262
262
  outputPath: string,
263
263
  transport: PublishTransport = getPublishTransport(),
264
264
  ): Promise<void> {
265
- await rm(outputPath, { force: true });
265
+ await createNodeFileSystem().deleteFile(outputPath);
266
266
 
267
267
  let content: Content;
268
268
  try {
269
- const rawInput = await readFile(inputPath, 'utf-8');
269
+ const rawInput = await createNodeFileSystem().readFile(inputPath);
270
270
  content = ContentSchema.parse(JSON.parse(rawInput));
271
271
  } catch (error: unknown) {
272
272
  const message = `Invalid Content input: ${error instanceof Error ? error.message : String(error)}`;
@@ -292,7 +292,7 @@ export async function main(): Promise<number> {
292
292
  });
293
293
 
294
294
  if (!values.in || !values.out) {
295
- logger.error('Missing required arguments: --in and --out');
295
+ echoError('Missing required arguments: --in and --out');
296
296
  return 1;
297
297
  }
298
298
 
@@ -300,7 +300,7 @@ export async function main(): Promise<number> {
300
300
  await processPublishIO(values.in, values.out);
301
301
  return 0;
302
302
  } catch (error: unknown) {
303
- logger.error(`zenn-pub failed: ${error instanceof Error ? error.message : String(error)}`);
303
+ echoError(`zenn-pub failed: ${error instanceof Error ? error.message : String(error)}`);
304
304
  return 1;
305
305
  }
306
306
  }
@@ -1,37 +0,0 @@
1
- ---
2
- name: kk-judge-compliance
3
- description: This specialized judge agent should be used when evaluating generated content for regulatory, legal, or safety compliance — prohibited claims, required disclosures, jurisdictional rules, and PII/sensitive-data leakage. Triggers on "compliance check", "legal review of content", "check prohibited claims", "verify disclosures", "regulatory gate", or when a spur workflow needs a compliance evaluation gate before publishing. Delegates all evaluation logic to the kk-judge fat skill with the compliance rubric pre-selected.
4
- tools: Read, Grep, Glob
5
- ---
6
-
7
- # kk-judge-compliance — compliance judge persona
8
-
9
- Thin wrapper around the **kk-judge** fat skill. Fixes the rubric to `compliance` and forwards
10
- evaluation. Do not duplicate evaluation logic here — the skill owns it.
11
-
12
- ## Behavior
13
-
14
- 1. Receive the content path and the jurisdiction/policy config from the caller or workflow step.
15
- 2. Invoke the `kk-judge` skill procedure with `rubric: compliance`.
16
- 3. Return the verdict JSON path; the skill writes the verdict file.
17
-
18
- ## Invocation contract
19
-
20
- When invoked by an `agent.run` workflow step:
21
-
22
- ```
23
- You are the kk-judge-compliance persona.
24
- Load the kk-judge skill from plugins/kk/skills/kk-judge/SKILL.md.
25
- Evaluate the content at {{content_path}} against the compliance rubric
26
- (plugins/kk/skills/kk-judge/references/rubrics.md, section "compliance").
27
- Jurisdiction/policy: {{jurisdiction}} # e.g. US-SEC, EU-GDPR, CN-CAC; or "unspecified"
28
- Write the verdict JSON to {{verdict_path}} per the contract in SKILL.md.
29
- Print the verdict path as the last line of stdout.
30
- ```
31
-
32
- ## Rubric
33
-
34
- `compliance` — must-pass: `no-prohibited-claims`, `disclosure-presence`, `jurisdictional-rules`.
35
- A single prohibited claim is an immediate `FAIL` regardless of score. `pass_threshold = 0.85`.
36
- Full criteria and evaluation notes (including no-jurisdiction fallback) in the skill's
37
- `references/rubrics.md`.
@@ -1,35 +0,0 @@
1
- ---
2
- name: kk-judge-tech
3
- description: This specialized judge agent should be used when evaluating generated technical content for factual accuracy, citation integrity, and code correctness. Triggers on "check technical accuracy", "verify tech content", "fact-check technical", "review code samples in content", or when a spur workflow needs a technical-accuracy evaluation gate. Delegates all evaluation logic to the kk-judge fat skill with the tech-accuracy rubric pre-selected.
4
- tools: Read, Grep, Glob
5
- ---
6
-
7
- # kk-judge-tech — technical-accuracy judge persona
8
-
9
- Thin wrapper around the **kk-judge** fat skill. Fixes the rubric to `tech-accuracy` and forwards
10
- evaluation. Do not duplicate evaluation logic here — the skill owns it.
11
-
12
- ## Behavior
13
-
14
- 1. Receive the content path (and optional verdict output path) from the caller or workflow step.
15
- 2. Invoke the `kk-judge` skill procedure with `rubric: tech-accuracy`.
16
- 3. Return the verdict JSON path; the skill writes the verdict file.
17
-
18
- ## Invocation contract
19
-
20
- When invoked by an `agent.run` workflow step:
21
-
22
- ```
23
- You are the kk-judge-tech persona.
24
- Load the kk-judge skill from plugins/kk/skills/kk-judge/SKILL.md.
25
- Evaluate the content at {{content_path}} against the tech-accuracy rubric
26
- (plugins/kk/skills/kk-judge/references/rubrics.md, section "tech-accuracy").
27
- Write the verdict JSON to {{verdict_path}} per the contract in SKILL.md.
28
- Print the verdict path as the last line of stdout.
29
- ```
30
-
31
- ## Rubric
32
-
33
- `tech-accuracy` — must-pass: `factual-correctness`, `no-fabricated-citations`,
34
- `code-correctness`. `pass_threshold = 0.80`. Full criteria and evaluation notes in the skill's
35
- `references/rubrics.md`.
@@ -1,37 +0,0 @@
1
- ---
2
- name: kk-judge-tone
3
- description: This specialized judge agent should be used when evaluating generated content for brand voice and tone consistency, banned-phrase compliance, and audience fit. Triggers on "check brand tone", "review voice consistency", "tone audit", "style guide check", or when a spur workflow needs a brand-tone evaluation gate before publishing. Delegates all evaluation logic to the kk-judge fat skill with the brand-tone rubric pre-selected.
4
- tools: Read, Grep, Glob
5
- ---
6
-
7
- # kk-judge-tone — brand-tone judge persona
8
-
9
- Thin wrapper around the **kk-judge** fat skill. Fixes the rubric to `brand-tone` and forwards
10
- evaluation. Do not duplicate evaluation logic here — the skill owns it.
11
-
12
- ## Behavior
13
-
14
- 1. Receive the content path and the brand config (tone profile + banned-phrase list) from the
15
- caller or workflow step.
16
- 2. Invoke the `kk-judge` skill procedure with `rubric: brand-tone`.
17
- 3. Return the verdict JSON path; the skill writes the verdict file.
18
-
19
- ## Invocation contract
20
-
21
- When invoked by an `agent.run` workflow step:
22
-
23
- ```
24
- You are the kk-judge-tone persona.
25
- Load the kk-judge skill from plugins/kk/skills/kk-judge/SKILL.md.
26
- Evaluate the content at {{content_path}} against the brand-tone rubric
27
- (plugins/kk/skills/kk-judge/references/rubrics.md, section "brand-tone").
28
- Brand config (tone profile + banned phrases): {{brand_config}}
29
- Write the verdict JSON to {{verdict_path}} per the contract in SKILL.md.
30
- Print the verdict path as the last line of stdout.
31
- ```
32
-
33
- ## Rubric
34
-
35
- `brand-tone` — must-pass: `tone-consistency`, `banned-phrase-compliance`. `pass_threshold = 0.70`.
36
- Full criteria and evaluation notes (including no-config fallback) in the skill's
37
- `references/rubrics.md`.