@gobing-ai/knowledge-kit 0.0.32 → 0.0.33
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.
- package/.claude-plugin/marketplace.json +1 -1
- package/dist/index.js +32320 -15021
- package/package.json +4 -4
- package/plugins/generations/content-gen/dist/index.js +10 -9
- package/plugins/generations/core-facts-gen/dist/index.js +13 -12
- package/plugins/generations/daily-article-gen/dist/index.js +14 -13
- package/plugins/generations/daily-article-gen/src/index.ts +1 -1
- package/plugins/generations/dailynews-gen/dist/index.js +10 -9
- package/plugins/generations/episode-plan-gen/dist/index.js +58 -15
- package/plugins/generations/episode-plan-gen/src/index.ts +76 -6
- package/plugins/generations/gemini-tts/README.md +11 -0
- package/plugins/generations/gemini-tts/dist/index.js +10 -9
- package/plugins/generations/image-gen/dist/index.js +154 -151
- package/plugins/generations/image-gen/src/compose/chromium.ts +60 -42
- package/plugins/generations/news-report-gen/dist/index.js +13 -12
- package/plugins/generations/voice-gen/dist/index.js +10 -9
- package/plugins/ingestions/aihot-ingest/dist/index.js +13 -12
- package/plugins/ingestions/horizon-ingest/dist/index.js +13 -12
- package/plugins/ingestions/karakeep-local/dist/index.js +13 -13
- package/plugins/ingestions/last30days-ingest/dist/index.js +13 -12
- package/plugins/ingestions/web-search/dist/index.js +11 -10
- package/plugins/kk/README.md +38 -0
- package/plugins/kk/decisions/extract/ai-news.yaml +21 -0
- package/plugins/kk/decisions/kk-items.yaml +113 -0
- package/plugins/kk/plugin.json +1 -1
- package/plugins/kk/schedules/cron.tmpl +15 -0
- package/plugins/kk/schedules/launchd.plist.tmpl +77 -0
- package/plugins/kk/scripts/daily-stages.ts +1533 -0
- package/plugins/kk/scripts/kk-workflow-stages.ts +247 -1365
- package/plugins/kk/skills/content-safety/SKILL.md +38 -7
- package/plugins/kk/skills/web-automation/SKILL.md +100 -0
- package/plugins/kk/skills/web-automation/references/browser-launch.md +86 -0
- package/plugins/kk/workflows/kk-collect.yaml +258 -0
- package/plugins/kk/workflows/kk-daily-ai-voice.yaml +9 -3
- package/plugins/kk/workflows/kk-daily-ai-voice2.yaml +655 -0
- package/plugins/kk/workflows/kk-daily-safety.yaml +170 -0
- package/plugins/publishings/emdash-pub/dist/index.js +10 -9
- package/plugins/publishings/infoq-pub/dist/index.js +152 -59
- package/plugins/publishings/infoq-pub/plugin.json +1 -0
- package/plugins/publishings/infoq-pub/src/index.ts +167 -55
- package/plugins/publishings/infoq-pub/src/profile-check.ts +4 -2
- package/plugins/publishings/juejin-pub/dist/index.js +111 -30
- package/plugins/publishings/juejin-pub/plugin.json +1 -0
- package/plugins/publishings/juejin-pub/src/index.ts +49 -9
- package/plugins/publishings/medium-pub/dist/index.js +10 -9
- package/plugins/publishings/podcast-pub/dist/index.js +10 -9
- package/plugins/publishings/qiita-pub/dist/index.js +10 -9
- package/plugins/publishings/substack-pub/dist/index.js +105 -28
- package/plugins/publishings/substack-pub/plugin.json +1 -0
- package/plugins/publishings/substack-pub/src/index.ts +39 -8
- package/plugins/publishings/substack-pub/src/profile-check.ts +2 -0
- package/plugins/publishings/surfdash-pub/dist/index.js +10 -9
- package/plugins/publishings/wechatmp-pub/dist/index.js +115 -31
- package/plugins/publishings/wechatmp-pub/plugin.json +1 -0
- package/plugins/publishings/wechatmp-pub/src/index.ts +42 -9
- package/plugins/publishings/wechatmp-pub/src/profile-check.ts +84 -40
- package/plugins/publishings/x-pub/dist/index.js +114 -35
- package/plugins/publishings/x-pub/plugin.json +1 -0
- package/plugins/publishings/x-pub/src/index.ts +68 -14
- package/plugins/publishings/xhs-pub/dist/index.js +100 -54
- package/plugins/publishings/xhs-pub/plugin.json +1 -0
- package/plugins/publishings/xhs-pub/src/index.ts +8 -4
- package/plugins/publishings/xhs-pub/src/page.ts +4 -17
- package/plugins/publishings/xhs-pub/src/profile-check.ts +28 -15
- package/plugins/publishings/zenn-pub/dist/index.js +10 -9
|
@@ -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.
|
|
14645
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.5.18/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.
|
|
14656
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.5.18/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.
|
|
14679
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.5.18/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.
|
|
14682
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.5.18/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.
|
|
14685
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.5.18/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.
|
|
14703
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.5.18/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.
|
|
21701
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.5.18+ea28d47622d670ff/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.
|
|
21725
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.5.18+ea28d47622d670ff/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) {
|
|
@@ -21898,18 +21898,19 @@ var PluginManifestSchema = exports_external.looseObject({
|
|
|
21898
21898
|
name: exports_external.string().min(1),
|
|
21899
21899
|
kind: PluginKindSchema,
|
|
21900
21900
|
entry: exports_external.string().min(1),
|
|
21901
|
+
check: exports_external.string().min(1).optional(),
|
|
21901
21902
|
version: exports_external.string().optional(),
|
|
21902
21903
|
description: exports_external.string().optional(),
|
|
21903
21904
|
operations: exports_external.record(exports_external.string(), PluginOperationSchema).optional()
|
|
21904
21905
|
});
|
|
21905
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.5.
|
|
21906
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.5.18+ea28d47622d670ff/node_modules/@gobing-ai/ts-runtime/dist/index.js
|
|
21906
21907
|
init_file_system_node();
|
|
21907
21908
|
init_config();
|
|
21908
21909
|
|
|
21909
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.5.
|
|
21910
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.5.18+ea28d47622d670ff/node_modules/@gobing-ai/ts-runtime/dist/fs.js
|
|
21910
21911
|
init_file_system_node();
|
|
21911
21912
|
|
|
21912
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.5.
|
|
21913
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.5.18+ea28d47622d670ff/node_modules/@gobing-ai/ts-runtime/dist/path.js
|
|
21913
21914
|
function normalizeSeparators(path) {
|
|
21914
21915
|
return path.replaceAll("\\", "/");
|
|
21915
21916
|
}
|
|
@@ -21943,7 +21944,7 @@ function dirnamePath(path) {
|
|
|
21943
21944
|
return normalized.slice(0, index);
|
|
21944
21945
|
}
|
|
21945
21946
|
|
|
21946
|
-
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.5.
|
|
21947
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.5.18+ea28d47622d670ff/node_modules/@gobing-ai/ts-runtime/dist/fs.js
|
|
21947
21948
|
async function ensureDirForFile(path, fs = createNodeFileSystem()) {
|
|
21948
21949
|
await fs.ensureDir(dirnamePath(path));
|
|
21949
21950
|
}
|
|
@@ -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.
|
|
14645
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.5.18/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.
|
|
14656
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.5.18/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.
|
|
14679
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.5.18/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.
|
|
14682
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.5.18/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.
|
|
14685
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.5.18/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.
|
|
14703
|
+
// ../../node_modules/.bun/@gobing-ai+ts-utils@0.5.18/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.
|
|
21701
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.5.18+ea28d47622d670ff/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.
|
|
21725
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.5.18+ea28d47622d670ff/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.
|
|
21905
|
+
// ../../node_modules/.bun/@gobing-ai+ts-runtime@0.5.18+ea28d47622d670ff/node_modules/@gobing-ai/ts-runtime/dist/index.js
|
|
21905
21906
|
init_file_system_node();
|
|
21906
21907
|
init_config();
|
|
21907
21908
|
|
|
@@ -24036,7 +24037,7 @@ var ConfigError = class extends Error {
|
|
|
24036
24037
|
}
|
|
24037
24038
|
};
|
|
24038
24039
|
|
|
24039
|
-
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.5.
|
|
24040
|
+
// ../../node_modules/.bun/@gobing-ai+ts-infra@0.5.18+54f059b6897bbcdb/node_modules/@gobing-ai/ts-infra/dist/logger.js
|
|
24040
24041
|
var ROOT_CATEGORY = "app";
|
|
24041
24042
|
function toLogTapeLevel(level) {
|
|
24042
24043
|
return level === "warn" ? "warning" : level;
|
package/plugins/kk/README.md
CHANGED
|
@@ -11,6 +11,7 @@ It is a Claude Code / Superskill plugin, **not** a kk-core product plugin.
|
|
|
11
11
|
| `hooks/` | Hook definitions |
|
|
12
12
|
| `rules/` | Agent rules |
|
|
13
13
|
| `workflows/` | Design-time product YAML SSOT (ADR-009). Runtime dest is `$HOME/.config/kk/workflows` via `/workflow-run` |
|
|
14
|
+
| `schedules/` | launchd/cron **templates** for the shipped workflows (`kk schedule render` prints them) |
|
|
14
15
|
|
|
15
16
|
`agents/` is reserved for thin wrappers of fat skills. It is empty: `judge-tech` /
|
|
16
17
|
`judge-tone` / `judge-compliance` were retired (2026-08-19). Rubric selection lives on
|
|
@@ -26,3 +27,40 @@ Capability files **omit a leading `kk-`**. `superskill install` prefixes the plu
|
|
|
26
27
|
`skills/content-judge` installs as `kk:content-judge` (not `kk:kk-content-judge`). Same for `topic`,
|
|
27
28
|
`storm-research`, `itc-generating`, `explain-things` (via `/tell-me`), and `/workflow-run`. Product workflow YAML (`kk-storm-research.yaml`)
|
|
28
29
|
keeps its existing name — that is a workflow stem, not an installable agent capability.
|
|
30
|
+
|
|
31
|
+
## Schedule
|
|
32
|
+
|
|
33
|
+
`spur` **has no scheduler**, so kk ships templates and `kk schedule render` prints the artifact for
|
|
34
|
+
the platform — **installing it is an operator action** (kk never writes a crontab or a
|
|
35
|
+
`LaunchAgents` plist):
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# launchd (macOS): every 6 h at 04:00/10:00/16:00/22:00 local (StartCalendarInterval), one shared log
|
|
39
|
+
# 1. the log directory must exist — launchd opens StandardOutPath but never creates its parent
|
|
40
|
+
mkdir -p "$PWD/.works/kk-collect"
|
|
41
|
+
# 2. render + bootstrap (the plist carries the PATH launchd's default lacks)
|
|
42
|
+
kk schedule render kk-collect --platform launchd --repo "$PWD" \
|
|
43
|
+
> ~/Library/LaunchAgents/ai.gobing.kk-collect.plist
|
|
44
|
+
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/ai.gobing.kk-collect.plist
|
|
45
|
+
|
|
46
|
+
# cron: the same 6-hourly cadence (the rendered line carries its own mkdir + PATH).
|
|
47
|
+
# Merge, never replace: `| crontab -` discards every other job in the operator's crontab.
|
|
48
|
+
crontab -l > /tmp/kk-collect.cron 2>/dev/null || :
|
|
49
|
+
kk schedule render kk-collect --platform cron --repo "$PWD" >> /tmp/kk-collect.cron
|
|
50
|
+
crontab /tmp/kk-collect.cron
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Both rendered artifacts set `PATH` themselves (`{{home}}/.bun/bin`, `/opt/homebrew/bin`,
|
|
54
|
+
`/usr/local/bin`, then the system dirs). That is what the workflow's **children** need — `kk`, `jq` and
|
|
55
|
+
the plugins are all `#!/usr/bin/env bun` or PATH-resolved, and `launchd`/`cron` start with a minimal
|
|
56
|
+
`PATH`. It is **not** what resolves the scheduler's own command: launchd looks up a *relative*
|
|
57
|
+
`ProgramArguments[0]` with its fixed `_PATH_STDPATH` before the job environment exists, so the plist
|
|
58
|
+
also carries an absolute `Program` (`{{home}}/.bun/bin/spur`) while keeping `ProgramArguments` as the
|
|
59
|
+
frozen argv. Set both to wherever `spur`/`bun` actually live, and `mkdir -p` the log directory first
|
|
60
|
+
(cron's `>>` aborts before the command runs when its directory is missing).
|
|
61
|
+
|
|
62
|
+
`kk-collect` collects every ingestion source into the kk store and never publishes. Two ticks that
|
|
63
|
+
overlap are **one** collection: the first state takes `kk store lock acquire --name collect` and a
|
|
64
|
+
tick that finds the claim inside its TTL exits 0 (`skipped`) without collecting. Before relying on
|
|
65
|
+
the schedule, check the store is reachable from the scheduled checkout (`kk store migrate`), and
|
|
66
|
+
`tail -f "$PWD/.works/kk-collect/launchd.log"` after the first launch.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# ai-news topic profile (task 0210 R1, design kk-collect-and-daily-voice2.md §4).
|
|
2
|
+
#
|
|
3
|
+
# The episode pool for the daily AI-news workflow: every labelled item in the
|
|
4
|
+
# launch/industry categories with a substantive body and real audience signal,
|
|
5
|
+
# most time-sensitive first. `kk store extract --topic ai-news` compiles this into
|
|
6
|
+
# one parameterized query over `items` + `labels` — a new topic is a new file here,
|
|
7
|
+
# never a code change.
|
|
8
|
+
#
|
|
9
|
+
# Keys are decision ids from the sibling catalog (plugins/kk/decisions/kk-items.yaml);
|
|
10
|
+
# an unknown key or decision id fails loud with `kk.store.profile.invalid`.
|
|
11
|
+
# `limit` is omitted: the compiler's episode-cap default (20) applies unless
|
|
12
|
+
# `kk store extract --limit` overrides it.
|
|
13
|
+
topic: ai-news
|
|
14
|
+
where:
|
|
15
|
+
kk-item-category: { in: [ai-news, ai-industry] }
|
|
16
|
+
# quality 2, not 3: real ingest bodies (last30days/aihot summaries) are stub-length, so the
|
|
17
|
+
# heuristic labeler tops out at 1-2 and a gte-3 gate empties every real pool (task 0212 dogfood
|
|
18
|
+
# finding). Raise this back when a full-text ingest source lands.
|
|
19
|
+
kk-item-quality: { gte: 2 }
|
|
20
|
+
kk-item-importance: { gte: 3 }
|
|
21
|
+
order: [kk-item-urgency desc, kk-item-impact desc, first_seen_at desc]
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# kk item-label decision catalog (task 0209, design §4).
|
|
2
|
+
#
|
|
3
|
+
# One decision per item label `kk store label` writes: the MECE category plus the
|
|
4
|
+
# four 0–5 QC dimensions. The rubric texts and the choice vocabulary mirror
|
|
5
|
+
# episode-plan-gen's keyword heuristic (`classifyCategory` / `scoreDimensions`), so a
|
|
6
|
+
# model answer and a heuristic answer are directly comparable rows in `labels`.
|
|
7
|
+
#
|
|
8
|
+
# Resolution: registered through `decisions.paths` in `.spur/config.yaml`
|
|
9
|
+
# (project-relative `plugins/kk/decisions`). No kk workflow reads this catalog as a
|
|
10
|
+
# `decide` action; `kk store label` calls `spur decision run` and degrades to the
|
|
11
|
+
# heuristic when the backend does not answer.
|
|
12
|
+
$schema: "@gobing-ai/spur/schemas/decision-catalog.schema.json"
|
|
13
|
+
version: 1
|
|
14
|
+
|
|
15
|
+
defaults:
|
|
16
|
+
# ADR-125 value, in lockstep with config/decisions/task-pipeline.yaml. A model answer
|
|
17
|
+
# below this resolves to the decision's declared fallback with source: default.
|
|
18
|
+
minConfidence: 0.8
|
|
19
|
+
|
|
20
|
+
decisions:
|
|
21
|
+
kk-item-category:
|
|
22
|
+
type: choice
|
|
23
|
+
description: Which MECE category does this collected item belong to?
|
|
24
|
+
parameters:
|
|
25
|
+
title:
|
|
26
|
+
type: string
|
|
27
|
+
description: Item title (the heuristic's first keyword surface).
|
|
28
|
+
source:
|
|
29
|
+
type: string
|
|
30
|
+
description: Ingest plugin that produced the item (e.g. aihot, rss, polymarket).
|
|
31
|
+
criteria:
|
|
32
|
+
ai-news: Launch, release, announcement or product news about AI — the company/lab keyword surface.
|
|
33
|
+
ai-technical: Engineering substance — APIs, SDKs, tutorials, benchmarks, architectures, inference.
|
|
34
|
+
ai-research: Research output — papers, alignment, evaluations, novel findings.
|
|
35
|
+
ai-industry: Company and market signals — funding, acquisitions, valuation, policy, regulation, litigation.
|
|
36
|
+
non-ai: No AI signal survives the keyword scan, or a deny rule (non-AI source, junk phrase, non-AI tag) wins.
|
|
37
|
+
fallback: non-ai
|
|
38
|
+
|
|
39
|
+
kk-item-quality:
|
|
40
|
+
type: score
|
|
41
|
+
description: How substantive is the item's body (length and sourcedness)?
|
|
42
|
+
parameters:
|
|
43
|
+
title:
|
|
44
|
+
type: string
|
|
45
|
+
description: Item title.
|
|
46
|
+
source:
|
|
47
|
+
type: string
|
|
48
|
+
description: Ingest plugin that produced the item.
|
|
49
|
+
criteria:
|
|
50
|
+
- Empty or unusable body — nothing to read.
|
|
51
|
+
- Headline echo — a stub body under 300 characters, source mention only.
|
|
52
|
+
- Around 1.5k characters — a short but substantive report.
|
|
53
|
+
- Around 3k characters — a fully developed report.
|
|
54
|
+
- Around 4.5k characters — a detailed report with context.
|
|
55
|
+
- Around 6k characters or more, or any substantive body carrying a verifiable source URL.
|
|
56
|
+
fallback: 2
|
|
57
|
+
|
|
58
|
+
kk-item-importance:
|
|
59
|
+
type: score
|
|
60
|
+
description: How much does the item matter to an AI audience (source tier plus relevance)?
|
|
61
|
+
parameters:
|
|
62
|
+
title:
|
|
63
|
+
type: string
|
|
64
|
+
description: Item title.
|
|
65
|
+
source:
|
|
66
|
+
type: string
|
|
67
|
+
description: Ingest plugin that produced the item.
|
|
68
|
+
criteria:
|
|
69
|
+
- No audience signal at all.
|
|
70
|
+
- Tail source or unknown origin — incidental aggregation.
|
|
71
|
+
- Tail source (reddit, youtube, github, polymarket) — worth a slot on a thin day.
|
|
72
|
+
- Ranked feed (rss, horizon) — a horizon-ranked story.
|
|
73
|
+
- Human-curated front page (aihot) — the editor's own pick.
|
|
74
|
+
- Any tier whose relevance score is 0.8 or higher — a signal-confirmed story.
|
|
75
|
+
fallback: 2
|
|
76
|
+
|
|
77
|
+
kk-item-urgency:
|
|
78
|
+
type: score
|
|
79
|
+
description: How time-sensitive is the item relative to the plan date?
|
|
80
|
+
parameters:
|
|
81
|
+
title:
|
|
82
|
+
type: string
|
|
83
|
+
description: Item title.
|
|
84
|
+
source:
|
|
85
|
+
type: string
|
|
86
|
+
description: Ingest plugin that produced the item.
|
|
87
|
+
criteria:
|
|
88
|
+
- No publication date and no curated-recency signal — urgency cannot be judged (the heuristic never files this level).
|
|
89
|
+
- Published more than 7 days before the plan date — stale, archive material.
|
|
90
|
+
- Published 3 to 7 days before the plan date — cooling (the heuristic never files this level).
|
|
91
|
+
- Published within the last 7 days, or an undated same-day curated source — the default.
|
|
92
|
+
- Published 1 to 2 days before the plan date — still breaking.
|
|
93
|
+
- Published on or after the plan date — same-day news.
|
|
94
|
+
fallback: 2
|
|
95
|
+
|
|
96
|
+
kk-item-impact:
|
|
97
|
+
type: score
|
|
98
|
+
description: How large is the item's measured engagement?
|
|
99
|
+
parameters:
|
|
100
|
+
title:
|
|
101
|
+
type: string
|
|
102
|
+
description: Item title.
|
|
103
|
+
source:
|
|
104
|
+
type: string
|
|
105
|
+
description: Ingest plugin that produced the item.
|
|
106
|
+
criteria:
|
|
107
|
+
- No engagement recorded at all — unmeasurable reach (the heuristic never files this level).
|
|
108
|
+
- Engagement magnitude 1 or less — a single mention.
|
|
109
|
+
- Engagement magnitude above 1 — the item is being shared.
|
|
110
|
+
- Engagement magnitude above 10 — a discussion thread.
|
|
111
|
+
- Engagement magnitude above 100 — a widely shared story.
|
|
112
|
+
- Engagement magnitude above 1000 — a breakout story.
|
|
113
|
+
fallback: 2
|
package/plugins/kk/plugin.json
CHANGED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# kk-collect — standalone 6-hourly collection (04:00/10:00/16:00/22:00 local) into the kk store.
|
|
2
|
+
#
|
|
3
|
+
# Rendered by `kk schedule render kk-collect --platform cron --repo <checkout>`; kk never edits
|
|
4
|
+
# the operator's crontab. Operator action (plugins/kk/README.md §Schedule) — MERGE, never replace:
|
|
5
|
+
#
|
|
6
|
+
# crontab -l > /tmp/kk-collect.cron 2>/dev/null || :
|
|
7
|
+
# kk schedule render kk-collect --platform cron --repo "$PWD" >> /tmp/kk-collect.cron
|
|
8
|
+
# crontab /tmp/kk-collect.cron
|
|
9
|
+
#
|
|
10
|
+
# `kk store lock` is the single-flight guard, so an overlapping tick exits 0 without collecting.
|
|
11
|
+
#
|
|
12
|
+
# `mkdir -p` + an explicit PATH are load-bearing, not decoration: cron runs with a minimal PATH (no
|
|
13
|
+
# `spur`/`kk`/`jq`/`bun`) and its `>>` redirect fails on a missing directory BEFORE the command runs,
|
|
14
|
+
# so a bare line would produce no log and no tick. The README install steps mirror this.
|
|
15
|
+
0 4,10,16,22 * * * cd {{repo}} && mkdir -p .works/kk-collect && PATH="{{home}}/.bun/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin" spur workflow run plugins/kk/workflows/kk-collect.yaml >> {{repo}}/.works/kk-collect/launchd.log 2>&1
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<!-- kk-collect — standalone 6-hourly collection (04:00/10:00/16:00/22:00 local) into the kk store.
|
|
4
|
+
|
|
5
|
+
Rendered by `kk schedule render kk-collect --platform launchd --repo <checkout>`; kk never
|
|
6
|
+
installs it. Operator action (plugins/kk/README.md §Schedule):
|
|
7
|
+
|
|
8
|
+
kk schedule render kk-collect --platform launchd --repo "$PWD" \
|
|
9
|
+
> ~/Library/LaunchAgents/ai.gobing.kk-collect.plist
|
|
10
|
+
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/ai.gobing.kk-collect.plist
|
|
11
|
+
|
|
12
|
+
StartCalendarInterval fires at 04:00/10:00/16:00/22:00 local wall-clock time (6 h cadence);
|
|
13
|
+
hours the machine is asleep through coalesce into one run at wake (launchd.plist(5)), where cron
|
|
14
|
+
would skip. The engine runs one node at a time and `kk store lock` is the single-flight guard,
|
|
15
|
+
so overlap is answered with `skipped`, never with two collectors. -->
|
|
16
|
+
<plist version="1.0">
|
|
17
|
+
<dict>
|
|
18
|
+
<key>Label</key>
|
|
19
|
+
<string>ai.gobing.kk-collect</string>
|
|
20
|
+
<!-- launchd resolves a RELATIVE ProgramArguments[0] with its own _PATH_STDPATH
|
|
21
|
+
(/usr/bin:/bin:/usr/sbin:/sbin) before the job environment exists, so a bare `spur` fails with
|
|
22
|
+
posix_spawn error 0x2 no matter what PATH this plist sets (man launchd.plist: ProgramArguments).
|
|
23
|
+
`Program` is the absolute executable launchd execs; ProgramArguments keeps R6's frozen argv. -->
|
|
24
|
+
<key>Program</key>
|
|
25
|
+
<string>{{home}}/.bun/bin/spur</string>
|
|
26
|
+
<key>ProgramArguments</key>
|
|
27
|
+
<array>
|
|
28
|
+
<string>spur</string>
|
|
29
|
+
<string>workflow</string>
|
|
30
|
+
<string>run</string>
|
|
31
|
+
<string>plugins/kk/workflows/kk-collect.yaml</string>
|
|
32
|
+
</array>
|
|
33
|
+
<key>WorkingDirectory</key>
|
|
34
|
+
<string>{{repo}}</string>
|
|
35
|
+
<key>StartCalendarInterval</key>
|
|
36
|
+
<array>
|
|
37
|
+
<dict>
|
|
38
|
+
<key>Hour</key>
|
|
39
|
+
<integer>4</integer>
|
|
40
|
+
<key>Minute</key>
|
|
41
|
+
<integer>0</integer>
|
|
42
|
+
</dict>
|
|
43
|
+
<dict>
|
|
44
|
+
<key>Hour</key>
|
|
45
|
+
<integer>10</integer>
|
|
46
|
+
<key>Minute</key>
|
|
47
|
+
<integer>0</integer>
|
|
48
|
+
</dict>
|
|
49
|
+
<dict>
|
|
50
|
+
<key>Hour</key>
|
|
51
|
+
<integer>16</integer>
|
|
52
|
+
<key>Minute</key>
|
|
53
|
+
<integer>0</integer>
|
|
54
|
+
</dict>
|
|
55
|
+
<dict>
|
|
56
|
+
<key>Hour</key>
|
|
57
|
+
<integer>22</integer>
|
|
58
|
+
<key>Minute</key>
|
|
59
|
+
<integer>0</integer>
|
|
60
|
+
</dict>
|
|
61
|
+
</array>
|
|
62
|
+
<!-- The job environment applies only AFTER exec, so it is not what resolves `spur` above —
|
|
63
|
+
it is what the workflow's own children need (`kk`, `jq`, `bun` are all `#!/usr/bin/env bun`
|
|
64
|
+
or PATH-resolved). -->
|
|
65
|
+
<key>EnvironmentVariables</key>
|
|
66
|
+
<dict>
|
|
67
|
+
<key>PATH</key>
|
|
68
|
+
<string>{{home}}/.bun/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
|
69
|
+
</dict>
|
|
70
|
+
<key>StandardOutPath</key>
|
|
71
|
+
<string>{{repo}}/.works/kk-collect/launchd.log</string>
|
|
72
|
+
<key>StandardErrorPath</key>
|
|
73
|
+
<string>{{repo}}/.works/kk-collect/launchd.log</string>
|
|
74
|
+
<key>RunAtLoad</key>
|
|
75
|
+
<false/>
|
|
76
|
+
</dict>
|
|
77
|
+
</plist>
|