left-skills 0.2.0 → 0.3.0
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/README.md +2 -0
- package/README.zh.md +2 -0
- package/dist/cli.js +84 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -56,6 +56,8 @@ npm uninstall -g left-skills # remove binary
|
|
|
56
56
|
left-skills usage # human-readable report
|
|
57
57
|
left-skills usage --json # for AI (JSON)
|
|
58
58
|
left-skills usage --since 7 # last 7 days
|
|
59
|
+
left-skills doctor # diagnose install (✓/✗ + fix)
|
|
60
|
+
left-skills report --markdown > report.md # export report
|
|
59
61
|
```
|
|
60
62
|
|
|
61
63
|
Example:
|
package/README.zh.md
CHANGED
package/dist/cli.js
CHANGED
|
@@ -3201,6 +3201,22 @@ function relativeTime(iso) {
|
|
|
3201
3201
|
if (days === 1) return "1 \u5929\u524D";
|
|
3202
3202
|
return `${days} \u5929\u524D`;
|
|
3203
3203
|
}
|
|
3204
|
+
function formatMarkdown(report) {
|
|
3205
|
+
const lines = [];
|
|
3206
|
+
lines.push(`# left-skills usage report`);
|
|
3207
|
+
lines.push("");
|
|
3208
|
+
lines.push(`Generated: ${report.generated_at} | Skills: ${report.skills.length}`);
|
|
3209
|
+
lines.push("");
|
|
3210
|
+
lines.push("| skill | manual | AI | mention | total | last |");
|
|
3211
|
+
lines.push("|---|---|---|---|---|---|");
|
|
3212
|
+
for (const s of report.skills) {
|
|
3213
|
+
const total = s.manual + s.ai + s.mention;
|
|
3214
|
+
const last = s.last_used ? relativeTime(s.last_used) : "-";
|
|
3215
|
+
const mark = total === 0 ? " \u26A0" : "";
|
|
3216
|
+
lines.push(`| ${s.name}${mark} | ${s.manual} | ${s.ai} | ${s.mention} | ${total} | ${last} |`);
|
|
3217
|
+
}
|
|
3218
|
+
return lines.join("\n");
|
|
3219
|
+
}
|
|
3204
3220
|
|
|
3205
3221
|
// src/install.ts
|
|
3206
3222
|
var import_node_fs3 = require("fs");
|
|
@@ -3272,10 +3288,64 @@ function globalSettingsPath() {
|
|
|
3272
3288
|
return (0, import_node_path3.join)((0, import_node_os3.homedir)(), ".claude", "settings.json");
|
|
3273
3289
|
}
|
|
3274
3290
|
|
|
3291
|
+
// src/doctor.ts
|
|
3292
|
+
var import_node_fs4 = require("fs");
|
|
3293
|
+
var import_node_os4 = require("os");
|
|
3294
|
+
var import_node_path4 = require("path");
|
|
3295
|
+
var import_node_child_process = require("child_process");
|
|
3296
|
+
function checkBinary() {
|
|
3297
|
+
try {
|
|
3298
|
+
const path = (0, import_node_child_process.execSync)("which left-skills", { encoding: "utf-8" }).trim();
|
|
3299
|
+
return { name: "binary in PATH", ok: true, detail: path };
|
|
3300
|
+
} catch {
|
|
3301
|
+
return { name: "binary in PATH", ok: false, detail: "left-skills \u547D\u4EE4\u627E\u4E0D\u5230", fix: "npm i -g left-skills" };
|
|
3302
|
+
}
|
|
3303
|
+
}
|
|
3304
|
+
function checkHook() {
|
|
3305
|
+
const settingsPath = (0, import_node_path4.join)((0, import_node_os4.homedir)(), ".claude", "settings.json");
|
|
3306
|
+
if (!(0, import_node_fs4.existsSync)(settingsPath)) {
|
|
3307
|
+
return { name: "hook in settings", ok: false, detail: "~/.claude/settings.json \u4E0D\u5B58\u5728", fix: "left-skills install --write" };
|
|
3308
|
+
}
|
|
3309
|
+
try {
|
|
3310
|
+
const settings = JSON.parse((0, import_node_fs4.readFileSync)(settingsPath, "utf-8"));
|
|
3311
|
+
const hooks = settings.hooks || {};
|
|
3312
|
+
const hasLeft = Object.values(hooks).some(
|
|
3313
|
+
(entries) => entries.some((e) => (e.hooks || []).some((h) => h.command && h.command.includes("left-skills")))
|
|
3314
|
+
);
|
|
3315
|
+
return hasLeft ? { name: "hook in settings", ok: true, detail: "~/.claude/settings.json \u6709 left-skills hook" } : { name: "hook in settings", ok: false, detail: "settings.json \u65E0 left-skills hook", fix: "left-skills install --write" };
|
|
3316
|
+
} catch {
|
|
3317
|
+
return { name: "hook in settings", ok: false, detail: "settings.json \u89E3\u6790\u5931\u8D25", fix: "\u68C0\u67E5 ~/.claude/settings.json JSON" };
|
|
3318
|
+
}
|
|
3319
|
+
}
|
|
3320
|
+
function checkUsageFile() {
|
|
3321
|
+
const usagePath = (0, import_node_path4.join)((0, import_node_os4.homedir)(), ".left-skills", "usage.json");
|
|
3322
|
+
return (0, import_node_fs4.existsSync)(usagePath) ? { name: "usage.json", ok: true, detail: "~/.left-skills/usage.json \u5B58\u5728" } : { name: "usage.json", ok: false, detail: "~/.left-skills/usage.json \u4E0D\u5B58\u5728(\u9996\u6B21\u7528\u540E\u521B\u5EFA)", fix: "\u6253 /skill \u6216 AI \u8C03 skill \u89E6\u53D1 hook \u8BB0\u5F55" };
|
|
3323
|
+
}
|
|
3324
|
+
function checkHookCanRun() {
|
|
3325
|
+
try {
|
|
3326
|
+
(0, import_node_child_process.execSync)('echo "{}" | left-skills hook UserPromptExpansion', { encoding: "utf-8", stdio: "pipe" });
|
|
3327
|
+
return { name: "hook command runs", ok: true, detail: "left-skills hook \u80FD\u6267\u884C" };
|
|
3328
|
+
} catch {
|
|
3329
|
+
return { name: "hook command runs", ok: false, detail: "left-skills hook \u547D\u4EE4\u6267\u884C\u5931\u8D25", fix: "\u68C0\u67E5 left-skills binary / node" };
|
|
3330
|
+
}
|
|
3331
|
+
}
|
|
3332
|
+
function checkNodeVersion() {
|
|
3333
|
+
try {
|
|
3334
|
+
const ver = (0, import_node_child_process.execSync)("node --version", { encoding: "utf-8" }).trim();
|
|
3335
|
+
const major = parseInt(ver.slice(1).split(".")[0], 10);
|
|
3336
|
+
return major >= 18 ? { name: "node version", ok: true, detail: `${ver} (\u226518)` } : { name: "node version", ok: false, detail: `${ver} (<18)`, fix: "\u5347\u7EA7 node \u5230 18+" };
|
|
3337
|
+
} catch {
|
|
3338
|
+
return { name: "node version", ok: false, detail: "node \u547D\u4EE4\u627E\u4E0D\u5230", fix: "\u88C5 node 18+" };
|
|
3339
|
+
}
|
|
3340
|
+
}
|
|
3341
|
+
function runDoctor() {
|
|
3342
|
+
return [checkBinary(), checkHook(), checkUsageFile(), checkHookCanRun(), checkNodeVersion()];
|
|
3343
|
+
}
|
|
3344
|
+
|
|
3275
3345
|
// package.json
|
|
3276
3346
|
var package_default = {
|
|
3277
3347
|
name: "left-skills",
|
|
3278
|
-
version: "0.
|
|
3348
|
+
version: "0.3.0",
|
|
3279
3349
|
description: "\u7ED9 AI \u7528\u7684 skill \u751F\u547D\u5468\u671F\u7BA1\u7406\u5DE5\u5177 \u2014 MVP: skill \u8C03\u7528\u4F7F\u7528\u7EDF\u8BA1",
|
|
3280
3350
|
bin: {
|
|
3281
3351
|
"left-skills": "./dist/cli.js"
|
|
@@ -3329,6 +3399,19 @@ program2.command("usage").description("skill \u8C03\u7528\u4F7F\u7528\u62A5\u544
|
|
|
3329
3399
|
console.log(formatHuman(report));
|
|
3330
3400
|
}
|
|
3331
3401
|
});
|
|
3402
|
+
program2.command("report").description("\u5BFC\u51FA usage \u62A5\u544A markdown(\u53EF > report.md \u5206\u4EAB)").option("--markdown", "\u8F93\u51FA markdown(\u9ED8\u8BA4\u5373 markdown)").option("--since <days>", "\u65F6\u95F4\u7A97\u53E3(\u5929,\u9ED8\u8BA4 30)", "30").action((opts) => {
|
|
3403
|
+
const since = parseInt(opts.since, 10) || 30;
|
|
3404
|
+
const report = buildReport(since);
|
|
3405
|
+
console.log(formatMarkdown(report));
|
|
3406
|
+
});
|
|
3407
|
+
program2.command("doctor").description("\u8BCA\u65AD left-skills \u5B89\u88C5/hook \u914D\u7F6E(\u2713/\u2717 + \u4FEE\u590D\u5EFA\u8BAE)").action(() => {
|
|
3408
|
+
const results = runDoctor();
|
|
3409
|
+
for (const r of results) {
|
|
3410
|
+
const mark = r.ok ? "\u2713" : "\u2717";
|
|
3411
|
+
console.log(`${mark} ${r.name}: ${r.detail}`);
|
|
3412
|
+
if (r.fix) console.log(` \u2192 \u4FEE\u590D: ${r.fix}`);
|
|
3413
|
+
}
|
|
3414
|
+
});
|
|
3332
3415
|
program2.command("install").description("\u8F93\u51FA hook \u914D\u7F6E\u7247\u6BB5(\u9ED8\u8BA4)\u6216 --write \u81EA\u52A8\u5199\u8FDB ~/.claude/settings.json(\u5408\u5E76+\u5907\u4EFD .bak)").option("--write", "\u81EA\u52A8\u5199 hook \u5230 settings.json(\u5408\u5E76\u53BB\u91CD + \u5907\u4EFD .bak)", false).action((opts) => {
|
|
3333
3416
|
if (opts.write) {
|
|
3334
3417
|
const path = globalSettingsPath();
|