left-skills 0.6.0 → 0.8.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/dist/cli.js +190 -31
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -6709,8 +6709,8 @@ function formatMarkdown(report) {
|
|
|
6709
6709
|
|
|
6710
6710
|
// src/install.ts
|
|
6711
6711
|
var import_node_fs3 = require("fs");
|
|
6712
|
-
var import_node_os3 = require("os");
|
|
6713
6712
|
var import_node_path3 = require("path");
|
|
6713
|
+
var import_node_os3 = require("os");
|
|
6714
6714
|
function hookSnippet() {
|
|
6715
6715
|
const cmd = "left-skills hook";
|
|
6716
6716
|
return {
|
|
@@ -6776,6 +6776,43 @@ function removeHooksFromSettings(settingsPath) {
|
|
|
6776
6776
|
function globalSettingsPath() {
|
|
6777
6777
|
return (0, import_node_path3.join)((0, import_node_os3.homedir)(), ".claude", "settings.json");
|
|
6778
6778
|
}
|
|
6779
|
+
var SKILL_MD_CONTENT = `---
|
|
6780
|
+
name: left-skills
|
|
6781
|
+
description: \u7BA1\u7406 AI skill \u751F\u547D\u5468\u671F(lint \u68C0\u67E5\u8D28\u91CF / usage \u7EDF\u8BA1\u7528\u9891 / evolve \u6539\u8FDB / inspire \u53D1\u73B0\u65B0 skill)\u3002\u7528\u6237\u60F3\u7BA1 skill \u8D28\u91CF\u65F6\u89E6\u53D1\u3002
|
|
6782
|
+
---
|
|
6783
|
+
|
|
6784
|
+
# left-skills
|
|
6785
|
+
|
|
6786
|
+
left-skills \u662F skill \u751F\u547D\u5468\u671F\u7BA1\u7406 CLI\u3002\u901A\u8FC7\u8FD9\u4E2A skill,\u4F60\u53EF\u4EE5\u5728\u5BF9\u8BDD\u91CC\u89E6\u53D1 left-skills \u547D\u4EE4\u3002
|
|
6787
|
+
|
|
6788
|
+
## \u5B50\u547D\u4EE4
|
|
6789
|
+
|
|
6790
|
+
- \`left-skills lint\` \u2014 \u9759\u6001\u8D28\u91CF\u68C0\u67E5 SKILL.md(0-100 \u5206)
|
|
6791
|
+
- \`left-skills usage\` \u2014 skill \u8C03\u7528\u4F7F\u7528\u62A5\u544A
|
|
6792
|
+
- \`left-skills evolve <skill>\` \u2014 \u6536\u96C6 usage+lint \u4FE1\u53F7,\u8F93\u51FA\u6539\u8FDB prompt(\u7ED9 AI,\u4EBA\u5BA1)
|
|
6793
|
+
- \`left-skills inspire\` \u2014 \u626B\u4F1A\u8BDD\u627E\u91CD\u590D\u547D\u4EE4,\u63D0\u8BAE\u5199 skill
|
|
6794
|
+
- \`left-skills doctor\` \u2014 \u8BCA\u65AD\u5B89\u88C5/hook \u914D\u7F6E
|
|
6795
|
+
- \`left-skills report --markdown\` \u2014 \u5BFC\u51FA usage \u62A5\u544A
|
|
6796
|
+
- \`left-skills install --write\` \u2014 \u914D hook + \u653E\u8FD9\u4E2A skill
|
|
6797
|
+
- \`left-skills uninstall\` \u2014 \u5220 hook + \u5220\u8FD9\u4E2A skill
|
|
6798
|
+
|
|
6799
|
+
## \u600E\u4E48\u7528
|
|
6800
|
+
|
|
6801
|
+
\u7528\u6237\u60F3\u7BA1 skill \u8D28\u91CF\u65F6,\u8DD1\u5BF9\u5E94 \`left-skills <\u547D\u4EE4>\`(\u7528 Bash \u5DE5\u5177),\u628A\u8F93\u51FA\u7ED9\u7528\u6237\u3002\u4E0D\u77E5\u9053\u54EA\u4E2A\u547D\u4EE4\u65F6\u8DD1 \`left-skills --help\`\u3002
|
|
6802
|
+
|
|
6803
|
+
\u8DD1\u5B8C\u8F93\u51FA\u662F prompt/\u62A5\u544A,\u4EBA\u5BA1\u540E\u5E94\u7528(\u4E0D\u81EA\u52A8\u6539 skill)\u3002
|
|
6804
|
+
`;
|
|
6805
|
+
function writeSkillWrapper() {
|
|
6806
|
+
const skillDir = (0, import_node_path3.join)((0, import_node_os3.homedir)(), ".claude", "skills", "left-skills");
|
|
6807
|
+
(0, import_node_fs3.mkdirSync)(skillDir, { recursive: true });
|
|
6808
|
+
(0, import_node_fs3.writeFileSync)((0, import_node_path3.join)(skillDir, "SKILL.md"), SKILL_MD_CONTENT, "utf-8");
|
|
6809
|
+
}
|
|
6810
|
+
function removeSkillWrapper() {
|
|
6811
|
+
const skillDir = (0, import_node_path3.join)((0, import_node_os3.homedir)(), ".claude", "skills", "left-skills");
|
|
6812
|
+
if ((0, import_node_fs3.existsSync)(skillDir)) {
|
|
6813
|
+
(0, import_node_fs3.rmSync)(skillDir, { recursive: true, force: true });
|
|
6814
|
+
}
|
|
6815
|
+
}
|
|
6779
6816
|
|
|
6780
6817
|
// src/doctor.ts
|
|
6781
6818
|
var import_node_fs4 = require("fs");
|
|
@@ -6992,22 +7029,67 @@ function evolvePrompt(skillName) {
|
|
|
6992
7029
|
}
|
|
6993
7030
|
|
|
6994
7031
|
// src/inspire.ts
|
|
7032
|
+
var import_node_fs8 = require("fs");
|
|
7033
|
+
var import_node_path8 = require("path");
|
|
7034
|
+
var import_node_os8 = require("os");
|
|
7035
|
+
|
|
7036
|
+
// src/llm.ts
|
|
6995
7037
|
var import_node_fs7 = require("fs");
|
|
6996
|
-
var import_node_path7 = require("path");
|
|
6997
7038
|
var import_node_os7 = require("os");
|
|
7039
|
+
var import_node_path7 = require("path");
|
|
7040
|
+
var ANTHROPIC_API_URL = "https://api.anthropic.com/v1/messages";
|
|
7041
|
+
function getApiKey() {
|
|
7042
|
+
const env = process.env.ANTHROPIC_API_KEY;
|
|
7043
|
+
if (env) return env;
|
|
7044
|
+
try {
|
|
7045
|
+
const settings = JSON.parse((0, import_node_fs7.readFileSync)((0, import_node_path7.join)((0, import_node_os7.homedir)(), ".claude", "settings.json"), "utf-8"));
|
|
7046
|
+
return settings.env?.ANTHROPIC_API_KEY || null;
|
|
7047
|
+
} catch {
|
|
7048
|
+
return null;
|
|
7049
|
+
}
|
|
7050
|
+
}
|
|
7051
|
+
async function llmAnalyze(prompt, system) {
|
|
7052
|
+
const apiKey = getApiKey();
|
|
7053
|
+
if (!apiKey) return null;
|
|
7054
|
+
const model = process.env.ANTHROPIC_MODEL || "claude-sonnet-4-6";
|
|
7055
|
+
try {
|
|
7056
|
+
const response = await fetch(ANTHROPIC_API_URL, {
|
|
7057
|
+
method: "POST",
|
|
7058
|
+
headers: {
|
|
7059
|
+
"Content-Type": "application/json",
|
|
7060
|
+
"x-api-key": apiKey,
|
|
7061
|
+
"anthropic-version": "2023-06-01"
|
|
7062
|
+
},
|
|
7063
|
+
body: JSON.stringify({
|
|
7064
|
+
model,
|
|
7065
|
+
max_tokens: 1024,
|
|
7066
|
+
system,
|
|
7067
|
+
messages: [{ role: "user", content: prompt }]
|
|
7068
|
+
})
|
|
7069
|
+
});
|
|
7070
|
+
if (!response.ok) return null;
|
|
7071
|
+
const data = await response.json();
|
|
7072
|
+
return data.content?.[0]?.text || null;
|
|
7073
|
+
} catch {
|
|
7074
|
+
return null;
|
|
7075
|
+
}
|
|
7076
|
+
}
|
|
7077
|
+
|
|
7078
|
+
// src/inspire.ts
|
|
6998
7079
|
function scanSessions(sinceDays = 30) {
|
|
6999
|
-
const projectsDir = (0,
|
|
7080
|
+
const projectsDir = (0, import_node_path8.join)((0, import_node_os8.homedir)(), ".claude", "projects");
|
|
7000
7081
|
const cmdCount = /* @__PURE__ */ new Map();
|
|
7001
|
-
|
|
7082
|
+
const seqCount = /* @__PURE__ */ new Map();
|
|
7083
|
+
if (!(0, import_node_fs8.existsSync)(projectsDir)) return { cmdCount, seqCount };
|
|
7002
7084
|
const cutoff = Date.now() - sinceDays * 864e5;
|
|
7003
|
-
for (const project of (0,
|
|
7085
|
+
for (const project of (0, import_node_fs8.readdirSync)(projectsDir, { withFileTypes: true })) {
|
|
7004
7086
|
if (!project.isDirectory()) continue;
|
|
7005
|
-
const projectDir = (0,
|
|
7006
|
-
for (const file of (0,
|
|
7087
|
+
const projectDir = (0, import_node_path8.join)(projectsDir, project.name);
|
|
7088
|
+
for (const file of (0, import_node_fs8.readdirSync)(projectDir)) {
|
|
7007
7089
|
if (!file.endsWith(".jsonl")) continue;
|
|
7008
|
-
const filePath = (0, import_node_path7.join)(projectDir, file);
|
|
7009
7090
|
try {
|
|
7010
|
-
const content = (0,
|
|
7091
|
+
const content = (0, import_node_fs8.readFileSync)((0, import_node_path8.join)(projectDir, file), "utf-8");
|
|
7092
|
+
const toolNames = [];
|
|
7011
7093
|
for (const line of content.split("\n")) {
|
|
7012
7094
|
if (!line.trim()) continue;
|
|
7013
7095
|
try {
|
|
@@ -7017,10 +7099,13 @@ function scanSessions(sinceDays = 30) {
|
|
|
7017
7099
|
const msg = obj.message;
|
|
7018
7100
|
if (msg && msg.content && Array.isArray(msg.content)) {
|
|
7019
7101
|
for (const block of msg.content) {
|
|
7020
|
-
if (block.type === "tool_use"
|
|
7021
|
-
|
|
7022
|
-
if (
|
|
7023
|
-
|
|
7102
|
+
if (block.type === "tool_use") {
|
|
7103
|
+
toolNames.push(block.name);
|
|
7104
|
+
if (block.name === "Bash") {
|
|
7105
|
+
const cmd = block.input?.command;
|
|
7106
|
+
if (cmd && cmd.length >= 30) {
|
|
7107
|
+
cmdCount.set(cmd, (cmdCount.get(cmd) || 0) + 1);
|
|
7108
|
+
}
|
|
7024
7109
|
}
|
|
7025
7110
|
}
|
|
7026
7111
|
}
|
|
@@ -7028,31 +7113,101 @@ function scanSessions(sinceDays = 30) {
|
|
|
7028
7113
|
} catch {
|
|
7029
7114
|
}
|
|
7030
7115
|
}
|
|
7116
|
+
for (let i = 0; i + 2 < toolNames.length; i++) {
|
|
7117
|
+
const seq = toolNames.slice(i, i + 3).join(",");
|
|
7118
|
+
seqCount.set(seq, (seqCount.get(seq) || 0) + 1);
|
|
7119
|
+
}
|
|
7031
7120
|
} catch {
|
|
7032
7121
|
}
|
|
7033
7122
|
}
|
|
7034
7123
|
}
|
|
7035
|
-
return cmdCount;
|
|
7124
|
+
return { cmdCount, seqCount };
|
|
7125
|
+
}
|
|
7126
|
+
function skeletonize(cmd) {
|
|
7127
|
+
return cmd.replace(/"[^"]*"/g, "*").replace(/'[^']*'/g, "*").replace(/\/[^\s"']+/g, "/*").replace(/\s+/g, " ").trim();
|
|
7036
7128
|
}
|
|
7037
|
-
function
|
|
7038
|
-
const
|
|
7039
|
-
|
|
7040
|
-
|
|
7041
|
-
|
|
7129
|
+
function isNoise(skeleton) {
|
|
7130
|
+
const simple = /^(echo|ls|cat|cd|pwd|clear|exit|which|whoami|date|uptime)\b/i;
|
|
7131
|
+
return simple.test(skeleton) || skeleton.length < 10;
|
|
7132
|
+
}
|
|
7133
|
+
function isSeqNoise(seq) {
|
|
7134
|
+
const parts = seq.split(",");
|
|
7135
|
+
if (parts.every((p) => p === parts[0])) return true;
|
|
7136
|
+
return false;
|
|
7137
|
+
}
|
|
7138
|
+
async function inspirePrompt(sinceDays = 30) {
|
|
7139
|
+
const { cmdCount, seqCount } = scanSessions(sinceDays);
|
|
7140
|
+
const skeletonCount = /* @__PURE__ */ new Map();
|
|
7141
|
+
for (const [cmd, count] of cmdCount) {
|
|
7142
|
+
const skeleton = skeletonize(cmd);
|
|
7143
|
+
if (isNoise(skeleton)) continue;
|
|
7144
|
+
const existing = skeletonCount.get(skeleton);
|
|
7145
|
+
if (existing) {
|
|
7146
|
+
existing.count += count;
|
|
7147
|
+
if (existing.examples.length < 2) existing.examples.push(cmd.slice(0, 80));
|
|
7148
|
+
} else {
|
|
7149
|
+
skeletonCount.set(skeleton, { count, examples: [cmd.slice(0, 80)] });
|
|
7150
|
+
}
|
|
7151
|
+
}
|
|
7152
|
+
const cmdCandidates = [...skeletonCount.entries()].filter(([, info]) => info.count >= 3).sort((a, b) => b[1].count - a[1].count);
|
|
7153
|
+
const seqCandidates = [...seqCount.entries()].filter(([seq, count]) => count >= 3 && !isSeqNoise(seq)).sort((a, b) => b[1] - a[1]).slice(0, 10);
|
|
7154
|
+
if (cmdCandidates.length === 0 && seqCandidates.length === 0) {
|
|
7155
|
+
return "\u65E0\u91CD\u590D\u6A21\u5F0F(Bash \u9AA8\u67B6 \u22653 \u6216 tool \u5E8F\u5217 \u22653),\u6682\u4E0D\u5EFA\u8BAE\u5199 skill\u3002\n(\u8BD5\u66F4\u591A\u5929?left-skills inspire --since 90)";
|
|
7042
7156
|
}
|
|
7157
|
+
const installed = listInstalledSkills();
|
|
7158
|
+
const llmPrompt = `\u4F60\u53CD\u590D\u8DD1\u8FD9\u4E9B(${cmdCandidates.length} \u4E2A Bash \u9AA8\u67B6 + ${seqCandidates.length} \u4E2A tool \u5E8F\u5217):
|
|
7159
|
+
|
|
7160
|
+
## Bash \u9AA8\u67B6\u5019\u9009
|
|
7161
|
+
${cmdCandidates.slice(0, 10).map(([sk, info]) => `- ${sk}(${info.count} \u6B21,\u4F8B: ${info.examples[0]})`).join("\n") || "(\u65E0)"}
|
|
7162
|
+
|
|
7163
|
+
## tool \u5E8F\u5217\u5019\u9009(all tools,\u5DE5\u4F5C\u6D41)
|
|
7164
|
+
${seqCandidates.map(([seq, count]) => `- ${seq}(${count} \u6B21)`).join("\n") || "(\u65E0)"}
|
|
7165
|
+
|
|
7166
|
+
\u5DF2\u88C5 skill(\u907F\u514D\u91CD\u590D\u63D0\u8BAE):
|
|
7167
|
+
${installed.length > 0 ? installed.map((s) => "- " + s).join("\n") : "(\u65E0)"}
|
|
7168
|
+
|
|
7169
|
+
\u8BF7\u5224\u65AD:\u54EA\u4E9B\u8BE5\u5199 skill(\u81EA\u52A8\u5316)?\u6311 1-2 \u4E2A\u6700\u9891\u7E41\u7684,\u751F\u6210 SKILL.md \u8349\u7A3F\u6307\u4EE4\u3002
|
|
7170
|
+
- description \u8BF4\u660E"\u4F55\u65F6\u7528"(\u8BA9 AI \u81EA\u51B3\u89E6\u53D1)
|
|
7171
|
+
- body \u542B\u8BE5\u547D\u4EE4/\u5DE5\u4F5C\u6D41(\u81EA\u52A8\u5316)
|
|
7172
|
+
- **\u542B test cases(Happy/Edge/Error 3 \u573A\u666F)**(\u7ED9\u4EBA\u5BA1\u9A8C)
|
|
7173
|
+
- \u4E0D\u8981\u63D0\u8BAE\u5DF2\u88C5 skill \u91CD\u590D\u7684`;
|
|
7174
|
+
const system = "\u4F60\u662F skill \u67B6\u6784\u5E08\u3002\u4ECE\u91CD\u590D\u547D\u4EE4/\u5DE5\u4F5C\u6D41\u5224\u65AD\u8BE5\u4E0D\u8BE5\u5199 skill,\u907F\u514D\u91CD\u590D\u5DF2\u88C5\u7684\u3002\u8F93\u51FA\u542B test cases \u7684\u6539\u8FDB\u6307\u4EE4(\u7ED9\u4EBA\u5BA1,\u4E0D\u81EA\u52A8\u521B\u5EFA)\u3002";
|
|
7175
|
+
const llmResult = await llmAnalyze(llmPrompt, system);
|
|
7043
7176
|
const lines = [];
|
|
7044
|
-
lines.push("# inspire:\u4F60\u53CD\u590D\u8DD1\u7684\u547D\u4EE4(\u5EFA\u8BAE\u5199 skill \u81EA\u52A8\u5316)");
|
|
7177
|
+
lines.push("# inspire:\u4F60\u53CD\u590D\u8DD1\u7684\u547D\u4EE4 + \u5DE5\u4F5C\u6D41(\u5EFA\u8BAE\u5199 skill \u81EA\u52A8\u5316)");
|
|
7178
|
+
lines.push("");
|
|
7179
|
+
lines.push("## Bash \u9AA8\u67B6\u5019\u9009(\u6B63\u5219\u7C97\u7B5B \u22653)");
|
|
7180
|
+
if (cmdCandidates.length > 0) {
|
|
7181
|
+
for (const [sk, info] of cmdCandidates) lines.push(`- ${sk}(${info.count} \u6B21)`);
|
|
7182
|
+
} else {
|
|
7183
|
+
lines.push("(\u65E0)");
|
|
7184
|
+
}
|
|
7045
7185
|
lines.push("");
|
|
7046
|
-
lines.push("## \
|
|
7047
|
-
|
|
7048
|
-
lines.push(`-
|
|
7186
|
+
lines.push("## tool \u5E8F\u5217\u5019\u9009(all tools,\u5DE5\u4F5C\u6D41 \u22653)");
|
|
7187
|
+
if (seqCandidates.length > 0) {
|
|
7188
|
+
for (const [seq, count] of seqCandidates) lines.push(`- ${seq}(${count} \u6B21)`);
|
|
7189
|
+
} else {
|
|
7190
|
+
lines.push("(\u65E0)");
|
|
7191
|
+
}
|
|
7192
|
+
lines.push("");
|
|
7193
|
+
lines.push("## \u5DF2\u88C5 skill(OBSERVE,\u907F\u514D\u91CD\u590D)");
|
|
7194
|
+
if (installed.length > 0) {
|
|
7195
|
+
for (const s of installed) lines.push(`- ${s}`);
|
|
7196
|
+
} else {
|
|
7197
|
+
lines.push("(\u65E0)");
|
|
7049
7198
|
}
|
|
7050
7199
|
lines.push("");
|
|
7051
|
-
|
|
7052
|
-
|
|
7053
|
-
|
|
7054
|
-
|
|
7055
|
-
|
|
7200
|
+
if (llmResult) {
|
|
7201
|
+
lines.push("## LLM \u7CBE\u63D0(\u542B test cases \u6307\u4EE4,\u4EBA\u5BA1)");
|
|
7202
|
+
lines.push(llmResult);
|
|
7203
|
+
} else {
|
|
7204
|
+
lines.push("## \u6539\u8FDB\u6307\u4EE4(\u7ED9 AI,\u65E0 LLM \u964D\u7EA7\u7EAF\u6B63\u5219)");
|
|
7205
|
+
lines.push("\u8BF7\u57FA\u4E8E\u4EE5\u4E0A\u5019\u9009,\u6311 1-2 \u4E2A\u6700\u9891\u7E41\u7684,\u751F\u6210 SKILL.md \u8349\u7A3F:");
|
|
7206
|
+
lines.push('- description \u8BF4\u660E"\u4F55\u65F6\u7528"');
|
|
7207
|
+
lines.push("- body \u542B\u8BE5\u547D\u4EE4/\u5DE5\u4F5C\u6D41");
|
|
7208
|
+
lines.push("- **\u542B test cases(Happy/Edge/Error)**");
|
|
7209
|
+
lines.push("- \u4E0D\u8981\u63D0\u8BAE\u5DF2\u88C5 skill \u91CD\u590D\u7684");
|
|
7210
|
+
}
|
|
7056
7211
|
lines.push("");
|
|
7057
7212
|
lines.push("\u751F\u6210\u8349\u7A3F,\u6211\u5BA1\u8FC7\u540E\u4E22\u8FDB .claude/skills/(\u4E0D\u81EA\u52A8\u521B\u5EFA)\u3002");
|
|
7058
7213
|
return lines.join("\n");
|
|
@@ -7061,7 +7216,7 @@ function inspirePrompt(sinceDays = 30) {
|
|
|
7061
7216
|
// package.json
|
|
7062
7217
|
var package_default = {
|
|
7063
7218
|
name: "left-skills",
|
|
7064
|
-
version: "0.
|
|
7219
|
+
version: "0.8.0",
|
|
7065
7220
|
description: "\u7ED9 AI \u7528\u7684 skill \u751F\u547D\u5468\u671F\u7BA1\u7406\u5DE5\u5177 \u2014 MVP: skill \u8C03\u7528\u4F7F\u7528\u7EDF\u8BA1",
|
|
7066
7221
|
bin: {
|
|
7067
7222
|
"left-skills": "./dist/cli.js"
|
|
@@ -7122,9 +7277,9 @@ program2.command("lint").description("\u9759\u6001\u8D28\u91CF\u68C0\u67E5 SKILL
|
|
|
7122
7277
|
program2.command("evolve <skill>").description("\u6536\u96C6 usage+lint \u4FE1\u53F7,\u8F93\u51FA\u6539\u8FDB prompt(\u7ED9 AI,\u4EBA\u5BA1,\u4E0D\u81EA\u52A8\u6539)").action((skill) => {
|
|
7123
7278
|
console.log(evolvePrompt(skill));
|
|
7124
7279
|
});
|
|
7125
|
-
program2.command("inspire").description("\u626B\u4F1A\u8BDD\u627E\u91CD\u590D\u547D\u4EE4,\u63D0\u8BAE\u5199 skill(\u7ED9 AI,\u4EBA\u5BA1,\u4E0D\u81EA\u52A8\u521B\u5EFA)").option("--since <days>", "\u65F6\u95F4\u7A97\u53E3(\u5929,\u9ED8\u8BA4 30)", "30").action((opts) => {
|
|
7280
|
+
program2.command("inspire").description("\u626B\u4F1A\u8BDD\u627E\u91CD\u590D\u547D\u4EE4,\u63D0\u8BAE\u5199 skill(hybrid \u6B63\u5219+LLM,\u7ED9 AI,\u4EBA\u5BA1,\u4E0D\u81EA\u52A8\u521B\u5EFA)").option("--since <days>", "\u65F6\u95F4\u7A97\u53E3(\u5929,\u9ED8\u8BA4 30)", "30").action(async (opts) => {
|
|
7126
7281
|
const since = parseInt(opts.since, 10) || 30;
|
|
7127
|
-
console.log(inspirePrompt(since));
|
|
7282
|
+
console.log(await inspirePrompt(since));
|
|
7128
7283
|
});
|
|
7129
7284
|
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) => {
|
|
7130
7285
|
const since = parseInt(opts.since, 10) || 30;
|
|
@@ -7143,7 +7298,9 @@ program2.command("install").description("\u8F93\u51FA hook \u914D\u7F6E\u7247\u6
|
|
|
7143
7298
|
if (opts.write) {
|
|
7144
7299
|
const path = globalSettingsPath();
|
|
7145
7300
|
writeHooksToSettings(path);
|
|
7301
|
+
writeSkillWrapper();
|
|
7146
7302
|
console.log(`\u2713 hook \u5DF2\u5199\u5165 ${path}(\u5DF2\u5907\u4EFD .bak)`);
|
|
7303
|
+
console.log(`\u2713 skill wrapper \u5DF2\u653E ~/.claude/skills/left-skills/SKILL.md(/left-skills slash \u89E6\u53D1)`);
|
|
7147
7304
|
console.log(" \u6253 /skill \u6216 AI \u8C03 skill \u4F1A\u81EA\u52A8\u8BB0\u5F55,\u8DD1 left-skills usage \u770B\u62A5\u544A");
|
|
7148
7305
|
} else {
|
|
7149
7306
|
console.log(JSON.stringify(hookSnippet(), null, 2));
|
|
@@ -7153,7 +7310,9 @@ program2.command("install").description("\u8F93\u51FA hook \u914D\u7F6E\u7247\u6
|
|
|
7153
7310
|
program2.command("uninstall").description("\u5220 ~/.claude/settings.json \u7684 left-skills hook(\u5E72\u51C0\u5378\u8F7D,\u5907\u4EFD .bak)").action(() => {
|
|
7154
7311
|
const path = globalSettingsPath();
|
|
7155
7312
|
removeHooksFromSettings(path);
|
|
7313
|
+
removeSkillWrapper();
|
|
7156
7314
|
console.log(`\u2713 left-skills hook \u5DF2\u4ECE ${path} \u5220\u9664(\u5DF2\u5907\u4EFD .bak)`);
|
|
7315
|
+
console.log(`\u2713 skill wrapper \u5DF2\u5220 ~/.claude/skills/left-skills/`);
|
|
7157
7316
|
console.log(" \u518D\u8DD1 npm uninstall -g left-skills \u5378\u8F7D binary");
|
|
7158
7317
|
});
|
|
7159
7318
|
program2.command("hook <event>").description("hook \u5165\u53E3(\u8BFB stdin payload)").action(async (event) => {
|