autohand-cli 0.6.4 → 0.6.7
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/SkillsRegistry-LXDK73BL.cjs +9 -0
- package/dist/SkillsRegistry-SP5MX7OA.js +9 -0
- package/dist/agents-FH47ZMOI.cjs +10 -0
- package/dist/{agents-OJWYZN6X.js → agents-NB5VQN6H.js} +2 -2
- package/dist/{agents-new-WQLJOXSS.js → agents-new-M325HGWT.js} +3 -2
- package/dist/agents-new-XLEU26YI.cjs +11 -0
- package/dist/{chunk-DD2YPHP5.cjs → chunk-2OBNJCG6.cjs} +15 -13
- package/dist/{chunk-NWXYG5PQ.js → chunk-37NUB5KX.js} +1 -1
- package/dist/{chunk-AL4Z4WKG.cjs → chunk-3DPDLZYY.cjs} +9 -7
- package/dist/chunk-3HPUOQJN.cjs +23 -0
- package/dist/{chunk-G7SYGATA.cjs → chunk-3ZUWWML7.cjs} +2 -2
- package/dist/{chunk-3Y6G5DUX.cjs → chunk-53YDUYNS.cjs} +10 -4
- package/dist/{chunk-PRZTK2FX.js → chunk-5WKR4HIB.js} +7 -5
- package/dist/{chunk-ZTA2ASFW.cjs → chunk-6ZGNSZRG.cjs} +1 -1
- package/dist/chunk-7BYSXAKS.js +23 -0
- package/dist/{chunk-6FEZ6JAQ.js → chunk-7HB7GSQF.js} +1 -1
- package/dist/{chunk-UBGEAEKS.js → chunk-AY2XV7TH.js} +1 -1
- package/dist/{chunk-7RRX7H2X.cjs → chunk-B5N5UAMO.cjs} +20 -12
- package/dist/{chunk-KZ2UXXLH.js → chunk-BAHUKJJR.js} +7 -5
- package/dist/{chunk-KT55HW6V.js → chunk-CHQMK2ZG.js} +1 -1
- package/dist/chunk-CVYEUA3D.cjs +528 -0
- package/dist/{chunk-MRQV5HMC.js → chunk-DE7YC5MB.js} +8 -6
- package/dist/{chunk-AD4O67ZA.cjs → chunk-EJ77L3KT.cjs} +10 -10
- package/dist/{chunk-737A24RB.js → chunk-FUEL6BK7.js} +9 -1
- package/dist/{chunk-6MCXWSR3.js → chunk-H4RPZD6H.js} +1 -1
- package/dist/chunk-JHGIWNHL.cjs +46 -0
- package/dist/{chunk-27JNK5TE.cjs → chunk-LUKMRIKJ.cjs} +40 -61
- package/dist/{chunk-4H3B46YX.js → chunk-MWLAHCU7.js} +9 -3
- package/dist/{chunk-QCMC2WOC.cjs → chunk-N6ZOJI2M.cjs} +4 -4
- package/dist/{chunk-2TPGTNNY.js → chunk-NGSLABLS.js} +37 -58
- package/dist/chunk-QHPFA6OE.js +46 -0
- package/dist/{chunk-M4LKQQHU.cjs → chunk-REPKBECD.cjs} +2 -2
- package/dist/chunk-SKU4M27Z.js +528 -0
- package/dist/chunk-W4XTDUGT.js +267 -0
- package/dist/{chunk-RDEROLKA.cjs → chunk-XAM7SFVB.cjs} +8 -6
- package/dist/chunk-XF4EQ3IV.cjs +267 -0
- package/dist/{chunk-IHJDYAYJ.cjs → chunk-XTHHDIBG.cjs} +9 -1
- package/dist/{chunk-5N3QP5LJ.js → chunk-YDH2BMEN.js} +19 -11
- package/dist/constants-ICQLSGZN.cjs +19 -0
- package/dist/constants-N3I2FHCM.js +19 -0
- package/dist/feedback-TOGESBX7.cjs +11 -0
- package/dist/{feedback-3THCLEBE.js → feedback-YGSYBQEW.js} +3 -2
- package/dist/index.cjs +1463 -1146
- package/dist/index.js +987 -670
- package/dist/login-QVBS7KBK.cjs +13 -0
- package/dist/login-XUVEFKCR.js +13 -0
- package/dist/logout-75YLPOBK.js +13 -0
- package/dist/logout-FYYR5KCP.cjs +13 -0
- package/dist/{permissions-CYW62ZK3.js → permissions-3GS4ZWVA.js} +2 -1
- package/dist/permissions-E3MTIE7D.cjs +10 -0
- package/dist/{skills-HF4SAF5O.js → skills-3M26KASS.js} +3 -1
- package/dist/skills-BOFY5RQN.cjs +13 -0
- package/dist/skills-install-WJ2LDRQG.js +680 -0
- package/dist/skills-install-Z3W5PQWQ.cjs +680 -0
- package/dist/skills-new-KIBUN63X.js +12 -0
- package/dist/skills-new-XDYS24XW.cjs +12 -0
- package/dist/{status-SLYYTKXD.js → status-6FY6RKIS.js} +1 -1
- package/dist/status-DJHDT6QH.cjs +9 -0
- package/dist/theme-2UK74UWR.cjs +13 -0
- package/dist/{theme-THMQ5AIN.js → theme-XNZ2X6HE.js} +3 -3
- package/package.json +1 -1
- package/dist/agents-EHLYBJLK.cjs +0 -10
- package/dist/agents-new-7VPASCBV.cjs +0 -10
- package/dist/chunk-NEAJ2UWG.js +0 -191
- package/dist/chunk-Z6SGIQWH.cjs +0 -191
- package/dist/feedback-PATTKRH5.cjs +0 -10
- package/dist/login-QJROML5I.js +0 -12
- package/dist/login-X66DSV75.cjs +0 -12
- package/dist/logout-3Z7R3F7J.cjs +0 -12
- package/dist/logout-RJ5OAXRI.js +0 -12
- package/dist/permissions-NOC5DMOH.cjs +0 -9
- package/dist/skills-U6J6DFLK.cjs +0 -11
- package/dist/skills-new-QDTNEG3R.js +0 -10
- package/dist/skills-new-UPVBHIF2.cjs +0 -10
- package/dist/status-GR73LEEN.cjs +0 -9
- package/dist/theme-YDANJLZR.cjs +0 -13
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
// src/commands/skills.ts
|
|
2
|
+
async function skills(ctx, args = []) {
|
|
3
|
+
const { skillsRegistry } = ctx;
|
|
4
|
+
if (!skillsRegistry) {
|
|
5
|
+
return "Skills registry not available.";
|
|
6
|
+
}
|
|
7
|
+
const subcommand = args[0]?.toLowerCase();
|
|
8
|
+
const skillName = args.slice(1).join(" ").trim() || args[1];
|
|
9
|
+
switch (subcommand) {
|
|
10
|
+
case "install":
|
|
11
|
+
case "get":
|
|
12
|
+
case "add":
|
|
13
|
+
return handleSkillsInstall(ctx, skillName);
|
|
14
|
+
case "use":
|
|
15
|
+
case "activate":
|
|
16
|
+
return activateSkill(skillsRegistry, skillName);
|
|
17
|
+
case "deactivate":
|
|
18
|
+
case "off":
|
|
19
|
+
return deactivateSkill(skillsRegistry, skillName);
|
|
20
|
+
case "info":
|
|
21
|
+
case "show":
|
|
22
|
+
return showSkillInfo(skillsRegistry, skillName);
|
|
23
|
+
default:
|
|
24
|
+
return listSkills(skillsRegistry);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function generateSkillSuggestion(skillName, description) {
|
|
28
|
+
const desc = description.toLowerCase();
|
|
29
|
+
if (desc.includes("commit") || desc.includes("git")) {
|
|
30
|
+
return `Help me write a great commit message for my recent changes`;
|
|
31
|
+
}
|
|
32
|
+
if (desc.includes("test") || desc.includes("testing")) {
|
|
33
|
+
return `Write comprehensive tests for the code I'm working on`;
|
|
34
|
+
}
|
|
35
|
+
if (desc.includes("review") || desc.includes("code review")) {
|
|
36
|
+
return `Review my code and suggest improvements`;
|
|
37
|
+
}
|
|
38
|
+
if (desc.includes("document") || desc.includes("docs")) {
|
|
39
|
+
return `Generate documentation for the current file`;
|
|
40
|
+
}
|
|
41
|
+
if (desc.includes("refactor")) {
|
|
42
|
+
return `Help me refactor this code for better readability`;
|
|
43
|
+
}
|
|
44
|
+
if (desc.includes("debug") || desc.includes("fix")) {
|
|
45
|
+
return `Help me debug the issue I'm seeing`;
|
|
46
|
+
}
|
|
47
|
+
if (desc.includes("api") || desc.includes("endpoint")) {
|
|
48
|
+
return `Help me design a new API endpoint`;
|
|
49
|
+
}
|
|
50
|
+
if (desc.includes("database") || desc.includes("sql") || desc.includes("schema")) {
|
|
51
|
+
return `Help me design the database schema`;
|
|
52
|
+
}
|
|
53
|
+
if (desc.includes("ui") || desc.includes("component") || desc.includes("frontend")) {
|
|
54
|
+
return `Create a new UI component`;
|
|
55
|
+
}
|
|
56
|
+
if (desc.includes("deploy") || desc.includes("ci") || desc.includes("pipeline")) {
|
|
57
|
+
return `Help me set up the deployment pipeline`;
|
|
58
|
+
}
|
|
59
|
+
if (desc.includes("security") || desc.includes("auth")) {
|
|
60
|
+
return `Review security concerns in my code`;
|
|
61
|
+
}
|
|
62
|
+
if (desc.includes("performance") || desc.includes("optimize")) {
|
|
63
|
+
return `Analyze and optimize performance`;
|
|
64
|
+
}
|
|
65
|
+
return `Use ${skillName} to help with: ${description.slice(0, 50)}...`;
|
|
66
|
+
}
|
|
67
|
+
function listSkills(registry) {
|
|
68
|
+
const allSkills = registry.listSkills();
|
|
69
|
+
const activeSkills = registry.getActiveSkills();
|
|
70
|
+
const lines = [];
|
|
71
|
+
lines.push("");
|
|
72
|
+
lines.push("\u{1F4DA} **Available Skills**");
|
|
73
|
+
lines.push("");
|
|
74
|
+
if (allSkills.length === 0) {
|
|
75
|
+
lines.push("No skills found yet.");
|
|
76
|
+
lines.push("");
|
|
77
|
+
lines.push("**Get started:**");
|
|
78
|
+
lines.push("");
|
|
79
|
+
lines.push("{{action:\u{1F310} Browse Community Skills|/skills install}}");
|
|
80
|
+
lines.push("{{action:\u2728 Create New Skill|/skills new}}");
|
|
81
|
+
lines.push("");
|
|
82
|
+
lines.push("_Skills can be added in:_");
|
|
83
|
+
lines.push("- `~/.autohand/skills/<skill-name>/SKILL.md`");
|
|
84
|
+
lines.push("- `<project>/.autohand/skills/<skill-name>/SKILL.md`");
|
|
85
|
+
return lines.join("\n");
|
|
86
|
+
}
|
|
87
|
+
const bySource = /* @__PURE__ */ new Map();
|
|
88
|
+
for (const skill of allSkills) {
|
|
89
|
+
const existing = bySource.get(skill.source) ?? [];
|
|
90
|
+
existing.push(skill);
|
|
91
|
+
bySource.set(skill.source, existing);
|
|
92
|
+
}
|
|
93
|
+
const sourceLabels = {
|
|
94
|
+
"codex-user": "\u{1F4C1} Codex User Skills",
|
|
95
|
+
"claude-user": "\u{1F4C1} Claude User Skills",
|
|
96
|
+
"claude-project": "\u{1F4C1} Project Skills",
|
|
97
|
+
"autohand-user": "\u{1F4C1} Autohand User Skills",
|
|
98
|
+
"autohand-project": "\u{1F4C1} Project Skills"
|
|
99
|
+
};
|
|
100
|
+
for (const [source, skills2] of bySource) {
|
|
101
|
+
lines.push(`**${sourceLabels[source] || source}**`);
|
|
102
|
+
lines.push("");
|
|
103
|
+
for (const skill of skills2) {
|
|
104
|
+
const isActive = skill.isActive;
|
|
105
|
+
const statusIcon = isActive ? "\u{1F7E2}" : "\u26AA";
|
|
106
|
+
const statusText = isActive ? " _(active)_" : "";
|
|
107
|
+
lines.push(`${statusIcon} **${skill.name}**${statusText}`);
|
|
108
|
+
lines.push(` ${skill.description}`);
|
|
109
|
+
if (isActive) {
|
|
110
|
+
const suggestion = generateSkillSuggestion(skill.name, skill.description);
|
|
111
|
+
lines.push(` {{action:\u{1F4A1} Try it|${suggestion}}} {{action:\u2139\uFE0F Info|/skills info ${skill.name}}} {{action:\u23F8\uFE0F Deactivate|/skills deactivate ${skill.name}}}`);
|
|
112
|
+
} else {
|
|
113
|
+
lines.push(` {{action:\u25B6\uFE0F Activate|/skills use ${skill.name}}} {{action:\u2139\uFE0F Info|/skills info ${skill.name}}}`);
|
|
114
|
+
}
|
|
115
|
+
lines.push("");
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
lines.push("\u2500".repeat(40));
|
|
119
|
+
lines.push(`\u{1F4CA} **${allSkills.length}** skills available, **${activeSkills.length}** active`);
|
|
120
|
+
lines.push("");
|
|
121
|
+
lines.push("**Quick Actions:**");
|
|
122
|
+
lines.push("{{action:\u{1F310} Browse Community|/skills install}} {{action:\u2728 Create New|/skills new}}");
|
|
123
|
+
return lines.join("\n");
|
|
124
|
+
}
|
|
125
|
+
function activateSkill(registry, name) {
|
|
126
|
+
if (!name) {
|
|
127
|
+
return "Usage: /skills use <skill-name>";
|
|
128
|
+
}
|
|
129
|
+
const skill = registry.getSkill(name);
|
|
130
|
+
if (!skill) {
|
|
131
|
+
const lines = [`Skill not found: ${name}`];
|
|
132
|
+
const similar = registry.findSimilar(name, 0.2);
|
|
133
|
+
if (similar.length > 0) {
|
|
134
|
+
lines.push("Did you mean:");
|
|
135
|
+
for (const match of similar.slice(0, 3)) {
|
|
136
|
+
lines.push(` - ${match.skill.name}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return lines.join("\n");
|
|
140
|
+
}
|
|
141
|
+
if (skill.isActive) {
|
|
142
|
+
return `Skill "${name}" is already active.`;
|
|
143
|
+
}
|
|
144
|
+
const success = registry.activateSkill(name);
|
|
145
|
+
if (success) {
|
|
146
|
+
return `\u2713 Activated skill: ${name}
|
|
147
|
+
${skill.description}`;
|
|
148
|
+
} else {
|
|
149
|
+
return `Failed to activate skill: ${name}`;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
function deactivateSkill(registry, name) {
|
|
153
|
+
if (!name) {
|
|
154
|
+
return "Usage: /skills deactivate <skill-name>";
|
|
155
|
+
}
|
|
156
|
+
const skill = registry.getSkill(name);
|
|
157
|
+
if (!skill) {
|
|
158
|
+
return `Skill not found: ${name}`;
|
|
159
|
+
}
|
|
160
|
+
if (!skill.isActive) {
|
|
161
|
+
return `Skill "${name}" is not active.`;
|
|
162
|
+
}
|
|
163
|
+
const success = registry.deactivateSkill(name);
|
|
164
|
+
if (success) {
|
|
165
|
+
return `\u2713 Deactivated skill: ${name}`;
|
|
166
|
+
} else {
|
|
167
|
+
return `Failed to deactivate skill: ${name}`;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
function showSkillInfo(registry, name) {
|
|
171
|
+
if (!name) {
|
|
172
|
+
return "Usage: /skills info <skill-name>";
|
|
173
|
+
}
|
|
174
|
+
const skill = registry.getSkill(name);
|
|
175
|
+
if (!skill) {
|
|
176
|
+
return `Skill not found: ${name}`;
|
|
177
|
+
}
|
|
178
|
+
const lines = [];
|
|
179
|
+
lines.push("");
|
|
180
|
+
lines.push(`\u{1F4CB} **Skill: ${skill.name}**`);
|
|
181
|
+
lines.push("");
|
|
182
|
+
if (skill.isActive) {
|
|
183
|
+
lines.push(`**Status:** \u{1F7E2} Active`);
|
|
184
|
+
const suggestion = generateSkillSuggestion(skill.name, skill.description);
|
|
185
|
+
lines.push("");
|
|
186
|
+
lines.push(`{{action:\u{1F4A1} Try it now|${suggestion}}} {{action:\u23F8\uFE0F Deactivate|/skills deactivate ${skill.name}}}`);
|
|
187
|
+
} else {
|
|
188
|
+
lines.push(`**Status:** \u26AA Inactive`);
|
|
189
|
+
lines.push("");
|
|
190
|
+
lines.push(`{{action:\u25B6\uFE0F Activate|/skills use ${skill.name}}}`);
|
|
191
|
+
}
|
|
192
|
+
lines.push("");
|
|
193
|
+
lines.push("\u2500".repeat(40));
|
|
194
|
+
lines.push("");
|
|
195
|
+
lines.push(`**Description:** ${skill.description}`);
|
|
196
|
+
lines.push(`**Source:** ${skill.source}`);
|
|
197
|
+
lines.push(`**Path:** \`${skill.path}\``);
|
|
198
|
+
if (skill.license) {
|
|
199
|
+
lines.push(`**License:** ${skill.license}`);
|
|
200
|
+
}
|
|
201
|
+
if (skill.compatibility) {
|
|
202
|
+
lines.push(`**Compatibility:** ${skill.compatibility}`);
|
|
203
|
+
}
|
|
204
|
+
if (skill["allowed-tools"]) {
|
|
205
|
+
lines.push(`**Allowed Tools:** ${skill["allowed-tools"]}`);
|
|
206
|
+
}
|
|
207
|
+
if (skill.metadata && Object.keys(skill.metadata).length > 0) {
|
|
208
|
+
lines.push("");
|
|
209
|
+
lines.push("**Metadata:**");
|
|
210
|
+
for (const [key, value] of Object.entries(skill.metadata)) {
|
|
211
|
+
lines.push(`- ${key}: ${value}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
lines.push("");
|
|
215
|
+
lines.push("**Content Preview:**");
|
|
216
|
+
lines.push("```");
|
|
217
|
+
const bodyPreview = skill.body.length > 500 ? skill.body.slice(0, 500) + "\n... (truncated)" : skill.body;
|
|
218
|
+
lines.push(bodyPreview || "(no body content)");
|
|
219
|
+
lines.push("```");
|
|
220
|
+
lines.push("");
|
|
221
|
+
lines.push("{{action:\u2190 Back to Skills|/skills}}");
|
|
222
|
+
return lines.join("\n");
|
|
223
|
+
}
|
|
224
|
+
async function handleSkillsInstall(ctx, skillName) {
|
|
225
|
+
const { skillsRegistry, workspaceRoot } = ctx;
|
|
226
|
+
if (!workspaceRoot) {
|
|
227
|
+
return "Workspace root not available.";
|
|
228
|
+
}
|
|
229
|
+
const { skillsInstall } = await import("./skills-install-WJ2LDRQG.js");
|
|
230
|
+
const result = await skillsInstall(
|
|
231
|
+
{
|
|
232
|
+
skillsRegistry,
|
|
233
|
+
workspaceRoot
|
|
234
|
+
},
|
|
235
|
+
skillName
|
|
236
|
+
);
|
|
237
|
+
return result ?? "Skills install completed.";
|
|
238
|
+
}
|
|
239
|
+
var metadata = {
|
|
240
|
+
command: "/skills",
|
|
241
|
+
description: "list and manage available skills",
|
|
242
|
+
implemented: true
|
|
243
|
+
};
|
|
244
|
+
var useMetadata = {
|
|
245
|
+
command: "/skills use",
|
|
246
|
+
description: "activate a skill",
|
|
247
|
+
implemented: true
|
|
248
|
+
};
|
|
249
|
+
var installMetadata = {
|
|
250
|
+
command: "/skills install",
|
|
251
|
+
description: "browse and install community skills",
|
|
252
|
+
implemented: true
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
export {
|
|
256
|
+
skills,
|
|
257
|
+
metadata,
|
|
258
|
+
useMetadata,
|
|
259
|
+
installMetadata
|
|
260
|
+
};
|
|
261
|
+
/**
|
|
262
|
+
* @license
|
|
263
|
+
* Copyright 2025 Autohand AI LLC
|
|
264
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
265
|
+
*
|
|
266
|
+
* Skills command - List and manage available skills
|
|
267
|
+
*/
|
|
@@ -1,26 +1,28 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunk3HPUOQJNcjs = require('./chunk-3HPUOQJN.cjs');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
var _chunkXTHHDIBGcjs = require('./chunk-XTHHDIBG.cjs');
|
|
4
7
|
|
|
5
8
|
// src/commands/feedback.ts
|
|
6
9
|
var _fsextra = require('fs-extra'); var _fsextra2 = _interopRequireDefault(_fsextra);
|
|
7
10
|
var _chalk = require('chalk'); var _chalk2 = _interopRequireDefault(_chalk);
|
|
8
|
-
var _enquirer = require('enquirer'); var _enquirer2 = _interopRequireDefault(_enquirer);
|
|
9
11
|
var metadata = {
|
|
10
12
|
command: "/feedback",
|
|
11
13
|
description: "share feedback with environment details",
|
|
12
14
|
implemented: true
|
|
13
15
|
};
|
|
14
16
|
async function feedback(_ctx) {
|
|
15
|
-
const answer = await
|
|
17
|
+
const answer = await _chunk3HPUOQJNcjs.safePrompt.call(void 0, [
|
|
16
18
|
{
|
|
17
19
|
type: "input",
|
|
18
20
|
name: "feedback",
|
|
19
21
|
message: "What worked? What broke?"
|
|
20
22
|
}
|
|
21
23
|
]);
|
|
22
|
-
if (!_optionalChain([answer, 'access', _ => _.feedback, 'optionalAccess', _2 => _2.trim, 'call', _3 => _3()])) {
|
|
23
|
-
console.log(_chalk2.default.gray("Feedback discarded
|
|
24
|
+
if (!answer || !_optionalChain([answer, 'access', _ => _.feedback, 'optionalAccess', _2 => _2.trim, 'call', _3 => _3()])) {
|
|
25
|
+
console.log(_chalk2.default.gray("Feedback discarded."));
|
|
24
26
|
return null;
|
|
25
27
|
}
|
|
26
28
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -38,7 +40,7 @@ async function feedback(_ctx) {
|
|
|
38
40
|
runtimeError: runtimeError ? formatError(runtimeError) : null
|
|
39
41
|
};
|
|
40
42
|
try {
|
|
41
|
-
const feedbackPath =
|
|
43
|
+
const feedbackPath = _chunkXTHHDIBGcjs.AUTOHAND_FILES.feedbackLog;
|
|
42
44
|
await _fsextra2.default.ensureFile(feedbackPath);
|
|
43
45
|
await _fsextra2.default.appendFile(feedbackPath, JSON.stringify(payload) + "\n", "utf8");
|
|
44
46
|
console.log(_chalk2.default.green("Feedback recorded."));
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/commands/skills.ts
|
|
2
|
+
async function skills(ctx, args = []) {
|
|
3
|
+
const { skillsRegistry } = ctx;
|
|
4
|
+
if (!skillsRegistry) {
|
|
5
|
+
return "Skills registry not available.";
|
|
6
|
+
}
|
|
7
|
+
const subcommand = _optionalChain([args, 'access', _ => _[0], 'optionalAccess', _2 => _2.toLowerCase, 'call', _3 => _3()]);
|
|
8
|
+
const skillName = args.slice(1).join(" ").trim() || args[1];
|
|
9
|
+
switch (subcommand) {
|
|
10
|
+
case "install":
|
|
11
|
+
case "get":
|
|
12
|
+
case "add":
|
|
13
|
+
return handleSkillsInstall(ctx, skillName);
|
|
14
|
+
case "use":
|
|
15
|
+
case "activate":
|
|
16
|
+
return activateSkill(skillsRegistry, skillName);
|
|
17
|
+
case "deactivate":
|
|
18
|
+
case "off":
|
|
19
|
+
return deactivateSkill(skillsRegistry, skillName);
|
|
20
|
+
case "info":
|
|
21
|
+
case "show":
|
|
22
|
+
return showSkillInfo(skillsRegistry, skillName);
|
|
23
|
+
default:
|
|
24
|
+
return listSkills(skillsRegistry);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function generateSkillSuggestion(skillName, description) {
|
|
28
|
+
const desc = description.toLowerCase();
|
|
29
|
+
if (desc.includes("commit") || desc.includes("git")) {
|
|
30
|
+
return `Help me write a great commit message for my recent changes`;
|
|
31
|
+
}
|
|
32
|
+
if (desc.includes("test") || desc.includes("testing")) {
|
|
33
|
+
return `Write comprehensive tests for the code I'm working on`;
|
|
34
|
+
}
|
|
35
|
+
if (desc.includes("review") || desc.includes("code review")) {
|
|
36
|
+
return `Review my code and suggest improvements`;
|
|
37
|
+
}
|
|
38
|
+
if (desc.includes("document") || desc.includes("docs")) {
|
|
39
|
+
return `Generate documentation for the current file`;
|
|
40
|
+
}
|
|
41
|
+
if (desc.includes("refactor")) {
|
|
42
|
+
return `Help me refactor this code for better readability`;
|
|
43
|
+
}
|
|
44
|
+
if (desc.includes("debug") || desc.includes("fix")) {
|
|
45
|
+
return `Help me debug the issue I'm seeing`;
|
|
46
|
+
}
|
|
47
|
+
if (desc.includes("api") || desc.includes("endpoint")) {
|
|
48
|
+
return `Help me design a new API endpoint`;
|
|
49
|
+
}
|
|
50
|
+
if (desc.includes("database") || desc.includes("sql") || desc.includes("schema")) {
|
|
51
|
+
return `Help me design the database schema`;
|
|
52
|
+
}
|
|
53
|
+
if (desc.includes("ui") || desc.includes("component") || desc.includes("frontend")) {
|
|
54
|
+
return `Create a new UI component`;
|
|
55
|
+
}
|
|
56
|
+
if (desc.includes("deploy") || desc.includes("ci") || desc.includes("pipeline")) {
|
|
57
|
+
return `Help me set up the deployment pipeline`;
|
|
58
|
+
}
|
|
59
|
+
if (desc.includes("security") || desc.includes("auth")) {
|
|
60
|
+
return `Review security concerns in my code`;
|
|
61
|
+
}
|
|
62
|
+
if (desc.includes("performance") || desc.includes("optimize")) {
|
|
63
|
+
return `Analyze and optimize performance`;
|
|
64
|
+
}
|
|
65
|
+
return `Use ${skillName} to help with: ${description.slice(0, 50)}...`;
|
|
66
|
+
}
|
|
67
|
+
function listSkills(registry) {
|
|
68
|
+
const allSkills = registry.listSkills();
|
|
69
|
+
const activeSkills = registry.getActiveSkills();
|
|
70
|
+
const lines = [];
|
|
71
|
+
lines.push("");
|
|
72
|
+
lines.push("\u{1F4DA} **Available Skills**");
|
|
73
|
+
lines.push("");
|
|
74
|
+
if (allSkills.length === 0) {
|
|
75
|
+
lines.push("No skills found yet.");
|
|
76
|
+
lines.push("");
|
|
77
|
+
lines.push("**Get started:**");
|
|
78
|
+
lines.push("");
|
|
79
|
+
lines.push("{{action:\u{1F310} Browse Community Skills|/skills install}}");
|
|
80
|
+
lines.push("{{action:\u2728 Create New Skill|/skills new}}");
|
|
81
|
+
lines.push("");
|
|
82
|
+
lines.push("_Skills can be added in:_");
|
|
83
|
+
lines.push("- `~/.autohand/skills/<skill-name>/SKILL.md`");
|
|
84
|
+
lines.push("- `<project>/.autohand/skills/<skill-name>/SKILL.md`");
|
|
85
|
+
return lines.join("\n");
|
|
86
|
+
}
|
|
87
|
+
const bySource = /* @__PURE__ */ new Map();
|
|
88
|
+
for (const skill of allSkills) {
|
|
89
|
+
const existing = _nullishCoalesce(bySource.get(skill.source), () => ( []));
|
|
90
|
+
existing.push(skill);
|
|
91
|
+
bySource.set(skill.source, existing);
|
|
92
|
+
}
|
|
93
|
+
const sourceLabels = {
|
|
94
|
+
"codex-user": "\u{1F4C1} Codex User Skills",
|
|
95
|
+
"claude-user": "\u{1F4C1} Claude User Skills",
|
|
96
|
+
"claude-project": "\u{1F4C1} Project Skills",
|
|
97
|
+
"autohand-user": "\u{1F4C1} Autohand User Skills",
|
|
98
|
+
"autohand-project": "\u{1F4C1} Project Skills"
|
|
99
|
+
};
|
|
100
|
+
for (const [source, skills2] of bySource) {
|
|
101
|
+
lines.push(`**${sourceLabels[source] || source}**`);
|
|
102
|
+
lines.push("");
|
|
103
|
+
for (const skill of skills2) {
|
|
104
|
+
const isActive = skill.isActive;
|
|
105
|
+
const statusIcon = isActive ? "\u{1F7E2}" : "\u26AA";
|
|
106
|
+
const statusText = isActive ? " _(active)_" : "";
|
|
107
|
+
lines.push(`${statusIcon} **${skill.name}**${statusText}`);
|
|
108
|
+
lines.push(` ${skill.description}`);
|
|
109
|
+
if (isActive) {
|
|
110
|
+
const suggestion = generateSkillSuggestion(skill.name, skill.description);
|
|
111
|
+
lines.push(` {{action:\u{1F4A1} Try it|${suggestion}}} {{action:\u2139\uFE0F Info|/skills info ${skill.name}}} {{action:\u23F8\uFE0F Deactivate|/skills deactivate ${skill.name}}}`);
|
|
112
|
+
} else {
|
|
113
|
+
lines.push(` {{action:\u25B6\uFE0F Activate|/skills use ${skill.name}}} {{action:\u2139\uFE0F Info|/skills info ${skill.name}}}`);
|
|
114
|
+
}
|
|
115
|
+
lines.push("");
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
lines.push("\u2500".repeat(40));
|
|
119
|
+
lines.push(`\u{1F4CA} **${allSkills.length}** skills available, **${activeSkills.length}** active`);
|
|
120
|
+
lines.push("");
|
|
121
|
+
lines.push("**Quick Actions:**");
|
|
122
|
+
lines.push("{{action:\u{1F310} Browse Community|/skills install}} {{action:\u2728 Create New|/skills new}}");
|
|
123
|
+
return lines.join("\n");
|
|
124
|
+
}
|
|
125
|
+
function activateSkill(registry, name) {
|
|
126
|
+
if (!name) {
|
|
127
|
+
return "Usage: /skills use <skill-name>";
|
|
128
|
+
}
|
|
129
|
+
const skill = registry.getSkill(name);
|
|
130
|
+
if (!skill) {
|
|
131
|
+
const lines = [`Skill not found: ${name}`];
|
|
132
|
+
const similar = registry.findSimilar(name, 0.2);
|
|
133
|
+
if (similar.length > 0) {
|
|
134
|
+
lines.push("Did you mean:");
|
|
135
|
+
for (const match of similar.slice(0, 3)) {
|
|
136
|
+
lines.push(` - ${match.skill.name}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return lines.join("\n");
|
|
140
|
+
}
|
|
141
|
+
if (skill.isActive) {
|
|
142
|
+
return `Skill "${name}" is already active.`;
|
|
143
|
+
}
|
|
144
|
+
const success = registry.activateSkill(name);
|
|
145
|
+
if (success) {
|
|
146
|
+
return `\u2713 Activated skill: ${name}
|
|
147
|
+
${skill.description}`;
|
|
148
|
+
} else {
|
|
149
|
+
return `Failed to activate skill: ${name}`;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
function deactivateSkill(registry, name) {
|
|
153
|
+
if (!name) {
|
|
154
|
+
return "Usage: /skills deactivate <skill-name>";
|
|
155
|
+
}
|
|
156
|
+
const skill = registry.getSkill(name);
|
|
157
|
+
if (!skill) {
|
|
158
|
+
return `Skill not found: ${name}`;
|
|
159
|
+
}
|
|
160
|
+
if (!skill.isActive) {
|
|
161
|
+
return `Skill "${name}" is not active.`;
|
|
162
|
+
}
|
|
163
|
+
const success = registry.deactivateSkill(name);
|
|
164
|
+
if (success) {
|
|
165
|
+
return `\u2713 Deactivated skill: ${name}`;
|
|
166
|
+
} else {
|
|
167
|
+
return `Failed to deactivate skill: ${name}`;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
function showSkillInfo(registry, name) {
|
|
171
|
+
if (!name) {
|
|
172
|
+
return "Usage: /skills info <skill-name>";
|
|
173
|
+
}
|
|
174
|
+
const skill = registry.getSkill(name);
|
|
175
|
+
if (!skill) {
|
|
176
|
+
return `Skill not found: ${name}`;
|
|
177
|
+
}
|
|
178
|
+
const lines = [];
|
|
179
|
+
lines.push("");
|
|
180
|
+
lines.push(`\u{1F4CB} **Skill: ${skill.name}**`);
|
|
181
|
+
lines.push("");
|
|
182
|
+
if (skill.isActive) {
|
|
183
|
+
lines.push(`**Status:** \u{1F7E2} Active`);
|
|
184
|
+
const suggestion = generateSkillSuggestion(skill.name, skill.description);
|
|
185
|
+
lines.push("");
|
|
186
|
+
lines.push(`{{action:\u{1F4A1} Try it now|${suggestion}}} {{action:\u23F8\uFE0F Deactivate|/skills deactivate ${skill.name}}}`);
|
|
187
|
+
} else {
|
|
188
|
+
lines.push(`**Status:** \u26AA Inactive`);
|
|
189
|
+
lines.push("");
|
|
190
|
+
lines.push(`{{action:\u25B6\uFE0F Activate|/skills use ${skill.name}}}`);
|
|
191
|
+
}
|
|
192
|
+
lines.push("");
|
|
193
|
+
lines.push("\u2500".repeat(40));
|
|
194
|
+
lines.push("");
|
|
195
|
+
lines.push(`**Description:** ${skill.description}`);
|
|
196
|
+
lines.push(`**Source:** ${skill.source}`);
|
|
197
|
+
lines.push(`**Path:** \`${skill.path}\``);
|
|
198
|
+
if (skill.license) {
|
|
199
|
+
lines.push(`**License:** ${skill.license}`);
|
|
200
|
+
}
|
|
201
|
+
if (skill.compatibility) {
|
|
202
|
+
lines.push(`**Compatibility:** ${skill.compatibility}`);
|
|
203
|
+
}
|
|
204
|
+
if (skill["allowed-tools"]) {
|
|
205
|
+
lines.push(`**Allowed Tools:** ${skill["allowed-tools"]}`);
|
|
206
|
+
}
|
|
207
|
+
if (skill.metadata && Object.keys(skill.metadata).length > 0) {
|
|
208
|
+
lines.push("");
|
|
209
|
+
lines.push("**Metadata:**");
|
|
210
|
+
for (const [key, value] of Object.entries(skill.metadata)) {
|
|
211
|
+
lines.push(`- ${key}: ${value}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
lines.push("");
|
|
215
|
+
lines.push("**Content Preview:**");
|
|
216
|
+
lines.push("```");
|
|
217
|
+
const bodyPreview = skill.body.length > 500 ? skill.body.slice(0, 500) + "\n... (truncated)" : skill.body;
|
|
218
|
+
lines.push(bodyPreview || "(no body content)");
|
|
219
|
+
lines.push("```");
|
|
220
|
+
lines.push("");
|
|
221
|
+
lines.push("{{action:\u2190 Back to Skills|/skills}}");
|
|
222
|
+
return lines.join("\n");
|
|
223
|
+
}
|
|
224
|
+
async function handleSkillsInstall(ctx, skillName) {
|
|
225
|
+
const { skillsRegistry, workspaceRoot } = ctx;
|
|
226
|
+
if (!workspaceRoot) {
|
|
227
|
+
return "Workspace root not available.";
|
|
228
|
+
}
|
|
229
|
+
const { skillsInstall } = await Promise.resolve().then(() => _interopRequireWildcard(require("./skills-install-Z3W5PQWQ.cjs")));
|
|
230
|
+
const result = await skillsInstall(
|
|
231
|
+
{
|
|
232
|
+
skillsRegistry,
|
|
233
|
+
workspaceRoot
|
|
234
|
+
},
|
|
235
|
+
skillName
|
|
236
|
+
);
|
|
237
|
+
return _nullishCoalesce(result, () => ( "Skills install completed."));
|
|
238
|
+
}
|
|
239
|
+
var metadata = {
|
|
240
|
+
command: "/skills",
|
|
241
|
+
description: "list and manage available skills",
|
|
242
|
+
implemented: true
|
|
243
|
+
};
|
|
244
|
+
var useMetadata = {
|
|
245
|
+
command: "/skills use",
|
|
246
|
+
description: "activate a skill",
|
|
247
|
+
implemented: true
|
|
248
|
+
};
|
|
249
|
+
var installMetadata = {
|
|
250
|
+
command: "/skills install",
|
|
251
|
+
description: "browse and install community skills",
|
|
252
|
+
implemented: true
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
exports.skills = skills; exports.metadata = metadata; exports.useMetadata = useMetadata; exports.installMetadata = installMetadata;
|
|
261
|
+
/**
|
|
262
|
+
* @license
|
|
263
|
+
* Copyright 2025 Autohand AI LLC
|
|
264
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
265
|
+
*
|
|
266
|
+
* Skills command - List and manage available skills
|
|
267
|
+
*/
|
|
@@ -60,6 +60,12 @@ var SKILL_LOCATIONS = [
|
|
|
60
60
|
{ basePath: AUTOHAND_PATHS.skills, source: "autohand-user", recursive: true }
|
|
61
61
|
// Project-level Autohand skills are resolved at runtime with workspaceRoot
|
|
62
62
|
];
|
|
63
|
+
function getProjectSkillLocations(workspaceRoot) {
|
|
64
|
+
return [
|
|
65
|
+
{ basePath: _path2.default.join(workspaceRoot, ".claude", "skills"), source: "claude-project", recursive: false },
|
|
66
|
+
{ basePath: _path2.default.join(workspaceRoot, PROJECT_DIR_NAME, "skills"), source: "autohand-project", recursive: true }
|
|
67
|
+
];
|
|
68
|
+
}
|
|
63
69
|
|
|
64
70
|
|
|
65
71
|
|
|
@@ -67,7 +73,9 @@ var SKILL_LOCATIONS = [
|
|
|
67
73
|
|
|
68
74
|
|
|
69
75
|
|
|
70
|
-
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
exports.AUTOHAND_HOME = AUTOHAND_HOME; exports.AUTOHAND_PATHS = AUTOHAND_PATHS; exports.AUTOHAND_FILES = AUTOHAND_FILES; exports.PROJECT_DIR_NAME = PROJECT_DIR_NAME; exports.AUTH_CONFIG = AUTH_CONFIG; exports.SKILL_LOCATIONS = SKILL_LOCATIONS; exports.getProjectSkillLocations = getProjectSkillLocations;
|
|
71
79
|
/**
|
|
72
80
|
* @license
|
|
73
81
|
* Copyright 2025 Autohand AI LLC
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
safePrompt
|
|
3
|
+
} from "./chunk-7BYSXAKS.js";
|
|
4
|
+
|
|
1
5
|
// src/commands/permissions.ts
|
|
2
6
|
import chalk from "chalk";
|
|
3
|
-
import enquirer from "enquirer";
|
|
4
7
|
async function permissions(ctx) {
|
|
5
8
|
const whitelist = ctx.permissionManager.getWhitelist();
|
|
6
9
|
const blacklist = ctx.permissionManager.getBlacklist();
|
|
@@ -36,7 +39,7 @@ async function permissions(ctx) {
|
|
|
36
39
|
console.log(chalk.gray("\u2500".repeat(50)));
|
|
37
40
|
console.log(chalk.gray(`Total: ${whitelist.length} approved, ${blacklist.length} denied`));
|
|
38
41
|
console.log();
|
|
39
|
-
const
|
|
42
|
+
const actionResult = await safePrompt({
|
|
40
43
|
type: "select",
|
|
41
44
|
name: "action",
|
|
42
45
|
message: "What would you like to do?",
|
|
@@ -47,35 +50,40 @@ async function permissions(ctx) {
|
|
|
47
50
|
{ name: "clear_all", message: "Clear all permissions" }
|
|
48
51
|
]
|
|
49
52
|
});
|
|
50
|
-
if (action === "done") {
|
|
53
|
+
if (!actionResult || actionResult.action === "done") {
|
|
51
54
|
return null;
|
|
52
55
|
}
|
|
56
|
+
const { action } = actionResult;
|
|
53
57
|
if (action === "remove_approved" && whitelist.length > 0) {
|
|
54
|
-
const
|
|
58
|
+
const result = await safePrompt({
|
|
55
59
|
type: "select",
|
|
56
60
|
name: "pattern",
|
|
57
61
|
message: "Select item to remove from approved list:",
|
|
58
62
|
choices: whitelist.map((p) => ({ name: p, message: p }))
|
|
59
63
|
});
|
|
60
|
-
|
|
61
|
-
|
|
64
|
+
if (result) {
|
|
65
|
+
await ctx.permissionManager.removeFromWhitelist(result.pattern);
|
|
66
|
+
console.log(chalk.yellow(`Removed "${result.pattern}" from approved list.`));
|
|
67
|
+
}
|
|
62
68
|
} else if (action === "remove_denied" && blacklist.length > 0) {
|
|
63
|
-
const
|
|
69
|
+
const result = await safePrompt({
|
|
64
70
|
type: "select",
|
|
65
71
|
name: "pattern",
|
|
66
72
|
message: "Select item to remove from denied list:",
|
|
67
73
|
choices: blacklist.map((p) => ({ name: p, message: p }))
|
|
68
74
|
});
|
|
69
|
-
|
|
70
|
-
|
|
75
|
+
if (result) {
|
|
76
|
+
await ctx.permissionManager.removeFromBlacklist(result.pattern);
|
|
77
|
+
console.log(chalk.yellow(`Removed "${result.pattern}" from denied list.`));
|
|
78
|
+
}
|
|
71
79
|
} else if (action === "clear_all") {
|
|
72
|
-
const
|
|
80
|
+
const result = await safePrompt({
|
|
73
81
|
type: "confirm",
|
|
74
82
|
name: "confirm",
|
|
75
83
|
message: "Clear all saved permissions? This cannot be undone.",
|
|
76
84
|
initial: false
|
|
77
85
|
});
|
|
78
|
-
if (confirm) {
|
|
86
|
+
if (result?.confirm) {
|
|
79
87
|
for (const pattern of [...whitelist]) {
|
|
80
88
|
await ctx.permissionManager.removeFromWhitelist(pattern);
|
|
81
89
|
}
|