skillwiki 0.2.1 → 0.2.3
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/dist/cli.js +36 -14
- package/package.json +1 -1
- package/skills/.claude-plugin/plugin.json +1 -1
- package/skills/package.json +1 -1
- package/skills/proj-distill/SKILL.md +6 -0
package/dist/cli.js
CHANGED
|
@@ -101,6 +101,7 @@ var sha256Hex = z.string().regex(/^[0-9a-f]{64}$/);
|
|
|
101
101
|
var RawSourceSchema = z.object({
|
|
102
102
|
title: z.string().min(1).optional(),
|
|
103
103
|
source_url: z.string().nullable(),
|
|
104
|
+
created: isoDate.optional(),
|
|
104
105
|
ingested: isoDate,
|
|
105
106
|
ingested_by: z.enum(["wiki-ingest", "proj-work", "manual"]).optional(),
|
|
106
107
|
sha256: sha256Hex.optional(),
|
|
@@ -1649,7 +1650,8 @@ async function runInit(input) {
|
|
|
1649
1650
|
return [
|
|
1650
1651
|
"---",
|
|
1651
1652
|
"source_url:",
|
|
1652
|
-
"
|
|
1653
|
+
"created: {{date:YYYY-MM-DD}}",
|
|
1654
|
+
"ingested: # filled by ingest pipeline",
|
|
1653
1655
|
"kind: # idea | bug | task | note | other",
|
|
1654
1656
|
'project: # optional: "[[slug]]"',
|
|
1655
1657
|
"---",
|
|
@@ -2964,21 +2966,35 @@ function checkSkillsInstalled(home, cwd) {
|
|
|
2964
2966
|
function checkDuplicateSkills(home) {
|
|
2965
2967
|
const plugin = findPlugin(home);
|
|
2966
2968
|
const skillsDir = join21(home, ".claude", "skills");
|
|
2967
|
-
|
|
2969
|
+
const agentSkillDirs = [
|
|
2970
|
+
{ label: "~/.codex/skills/", path: join21(home, ".codex", "skills") },
|
|
2971
|
+
{ label: "~/.agents/skills/", path: join21(home, ".agents", "skills") }
|
|
2972
|
+
];
|
|
2973
|
+
if (!plugin) {
|
|
2968
2974
|
return check("pass", "skills_duplicate", "Skills not duplicated", "Single install channel");
|
|
2969
2975
|
}
|
|
2970
2976
|
const pluginSkills = findSkillNames(plugin.installPath);
|
|
2971
2977
|
const cliSkills = findSkillNames(skillsDir);
|
|
2972
|
-
const
|
|
2973
|
-
|
|
2974
|
-
|
|
2978
|
+
const cliDuplicates = cliSkills.filter((name) => pluginSkills.includes(name));
|
|
2979
|
+
const agentDuplicates = [];
|
|
2980
|
+
for (const { label, path } of agentSkillDirs) {
|
|
2981
|
+
const overlap = findSkillNames(path).filter((name) => pluginSkills.includes(name));
|
|
2982
|
+
if (overlap.length > 0) {
|
|
2983
|
+
agentDuplicates.push({ dir: label, names: overlap });
|
|
2984
|
+
}
|
|
2975
2985
|
}
|
|
2976
|
-
|
|
2977
|
-
"
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2986
|
+
if (cliDuplicates.length === 0 && agentDuplicates.length === 0) {
|
|
2987
|
+
return check("pass", "skills_duplicate", "Skills not duplicated", "No overlap between plugin and other channels");
|
|
2988
|
+
}
|
|
2989
|
+
const parts = [];
|
|
2990
|
+
if (cliDuplicates.length > 0) {
|
|
2991
|
+
parts.push(`${cliDuplicates.length} skill(s) in both plugin and ~/.claude/skills/ \u2014 remove CLI copies: rm -r ~/.claude/skills/{${cliDuplicates.slice(0, 3).join(",")}${cliDuplicates.length > 3 ? ",\u2026" : ""}}`);
|
|
2992
|
+
}
|
|
2993
|
+
for (const { dir, names } of agentDuplicates) {
|
|
2994
|
+
parts.push(`${names.length} stale skill(s) in ${dir} \u2014 plugin provides: ${names.slice(0, 3).join(", ")}${names.length > 3 ? ", \u2026" : ""}`);
|
|
2995
|
+
}
|
|
2996
|
+
const status = cliDuplicates.length > 0 ? "warn" : "info";
|
|
2997
|
+
return check(status, "skills_duplicate", "Skills not duplicated", parts.join("; "));
|
|
2982
2998
|
}
|
|
2983
2999
|
function checkNpmUpdate(home, currentVersion) {
|
|
2984
3000
|
const { hasUpdate, latest } = latestFromCache(home, currentVersion);
|
|
@@ -3097,7 +3113,7 @@ function checkDotStoreClean(resolvedPath) {
|
|
|
3097
3113
|
if (found.length === 0) {
|
|
3098
3114
|
return check("pass", "dsstore_clean", "No .DS_Store in raw/", "No .DS_Store files found");
|
|
3099
3115
|
}
|
|
3100
|
-
return check("
|
|
3116
|
+
return check("info", "dsstore_clean", "No .DS_Store in raw/", `${found.length} .DS_Store file(s) found \u2014 remove with: find ${rawDir} -name .DS_Store -delete`);
|
|
3101
3117
|
}
|
|
3102
3118
|
function checkSyncLastPush(resolvedPath) {
|
|
3103
3119
|
if (resolvedPath === void 0) {
|
|
@@ -3193,18 +3209,22 @@ async function runDoctor(input) {
|
|
|
3193
3209
|
checks.push(checkPluginVersionDrift(input.home, input.currentVersion));
|
|
3194
3210
|
const summary = {
|
|
3195
3211
|
pass: checks.filter((c) => c.status === "pass").length,
|
|
3212
|
+
info: checks.filter((c) => c.status === "info").length,
|
|
3196
3213
|
warn: checks.filter((c) => c.status === "warn").length,
|
|
3197
3214
|
error: checks.filter((c) => c.status === "error").length
|
|
3198
3215
|
};
|
|
3199
3216
|
const exitCode = summary.error > 0 ? ExitCode.DOCTOR_HAS_ERRORS : summary.warn > 0 ? ExitCode.DOCTOR_HAS_WARNINGS : ExitCode.OK;
|
|
3200
|
-
const statusIcon = { pass: "\u2713", warn: "\u26A0", error: "\u2717" };
|
|
3217
|
+
const statusIcon = { pass: "\u2713", info: "i", warn: "\u26A0", error: "\u2717" };
|
|
3201
3218
|
const lines = checks.map((c) => {
|
|
3202
3219
|
const icon = statusIcon[c.status];
|
|
3203
3220
|
const padded = c.label.padEnd(24);
|
|
3204
3221
|
return ` ${icon} ${padded} ${c.detail}`;
|
|
3205
3222
|
});
|
|
3206
3223
|
lines.push("");
|
|
3207
|
-
|
|
3224
|
+
const summaryParts = [`${summary.pass} pass`];
|
|
3225
|
+
if (summary.info > 0) summaryParts.push(`${summary.info} info`);
|
|
3226
|
+
summaryParts.push(`${summary.warn} warn`, `${summary.error} error`);
|
|
3227
|
+
lines.push(summaryParts.join(" \xB7 "));
|
|
3208
3228
|
const humanHint = lines.join("\n");
|
|
3209
3229
|
return { exitCode, result: ok({ checks, summary, humanHint }) };
|
|
3210
3230
|
}
|
|
@@ -4430,6 +4450,7 @@ function buildRawContent(sourceUrl, ingested, sha256, body) {
|
|
|
4430
4450
|
const lines = [
|
|
4431
4451
|
"---",
|
|
4432
4452
|
sourceUrl !== null ? `source_url: "${sourceUrl}"` : "source_url:",
|
|
4453
|
+
`created: ${ingested}`,
|
|
4433
4454
|
`ingested: ${ingested}`,
|
|
4434
4455
|
`sha256: ${sha256}`,
|
|
4435
4456
|
`ingested_by: wiki-ingest`,
|
|
@@ -5373,6 +5394,7 @@ This is a seed concept page. Concept pages capture topics, patterns, and ideas t
|
|
|
5373
5394
|
};
|
|
5374
5395
|
var EXAMPLE_RAW = `---
|
|
5375
5396
|
source_url: https://example.com
|
|
5397
|
+
created: ${TODAY}
|
|
5376
5398
|
ingested: ${TODAY}
|
|
5377
5399
|
sha256: 0000000000000000000000000000000000000000000000000000000000000000
|
|
5378
5400
|
---
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skillwiki",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"skills": "./",
|
|
5
5
|
"description": "Project-aware Karpathy-style knowledge base for Claude Code: 18 prompt-only skills (wiki-*, proj-*, using-skillwiki) backed by the deterministic `skillwiki` CLI.",
|
|
6
6
|
"author": {
|
package/skills/package.json
CHANGED
|
@@ -33,6 +33,12 @@ When reading retros as source material:
|
|
|
33
33
|
`provenance: project` and
|
|
34
34
|
`provenance_projects: ["[[slug]]"]`. Validate with
|
|
35
35
|
`skillwiki validate`.
|
|
36
|
+
- **Tag hygiene:** `tags:` must only contain entries from
|
|
37
|
+
`{vault}/SCHEMA.md` taxonomy. Never derive tags from prose text
|
|
38
|
+
(lesson/evidence sections) — use only established taxonomy tags
|
|
39
|
+
(e.g., `dev-loop`, `lint`, `vault`). If no relevant taxonomy tag
|
|
40
|
+
exists, use `[dev-loop]` as the safe default rather than inventing
|
|
41
|
+
new tags. New tags must be added to SCHEMA.md first.
|
|
36
42
|
3. **Backlink.** Set `promoted_to: "[[concept-slug]]"` on the source
|
|
37
43
|
compound entry. For retro-sourced distillation, skip backlink (log.md
|
|
38
44
|
entries are append-only) and instead add `sources:` citing the vault
|