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.
Files changed (76) hide show
  1. package/dist/SkillsRegistry-LXDK73BL.cjs +9 -0
  2. package/dist/SkillsRegistry-SP5MX7OA.js +9 -0
  3. package/dist/agents-FH47ZMOI.cjs +10 -0
  4. package/dist/{agents-OJWYZN6X.js → agents-NB5VQN6H.js} +2 -2
  5. package/dist/{agents-new-WQLJOXSS.js → agents-new-M325HGWT.js} +3 -2
  6. package/dist/agents-new-XLEU26YI.cjs +11 -0
  7. package/dist/{chunk-DD2YPHP5.cjs → chunk-2OBNJCG6.cjs} +15 -13
  8. package/dist/{chunk-NWXYG5PQ.js → chunk-37NUB5KX.js} +1 -1
  9. package/dist/{chunk-AL4Z4WKG.cjs → chunk-3DPDLZYY.cjs} +9 -7
  10. package/dist/chunk-3HPUOQJN.cjs +23 -0
  11. package/dist/{chunk-G7SYGATA.cjs → chunk-3ZUWWML7.cjs} +2 -2
  12. package/dist/{chunk-3Y6G5DUX.cjs → chunk-53YDUYNS.cjs} +10 -4
  13. package/dist/{chunk-PRZTK2FX.js → chunk-5WKR4HIB.js} +7 -5
  14. package/dist/{chunk-ZTA2ASFW.cjs → chunk-6ZGNSZRG.cjs} +1 -1
  15. package/dist/chunk-7BYSXAKS.js +23 -0
  16. package/dist/{chunk-6FEZ6JAQ.js → chunk-7HB7GSQF.js} +1 -1
  17. package/dist/{chunk-UBGEAEKS.js → chunk-AY2XV7TH.js} +1 -1
  18. package/dist/{chunk-7RRX7H2X.cjs → chunk-B5N5UAMO.cjs} +20 -12
  19. package/dist/{chunk-KZ2UXXLH.js → chunk-BAHUKJJR.js} +7 -5
  20. package/dist/{chunk-KT55HW6V.js → chunk-CHQMK2ZG.js} +1 -1
  21. package/dist/chunk-CVYEUA3D.cjs +528 -0
  22. package/dist/{chunk-MRQV5HMC.js → chunk-DE7YC5MB.js} +8 -6
  23. package/dist/{chunk-AD4O67ZA.cjs → chunk-EJ77L3KT.cjs} +10 -10
  24. package/dist/{chunk-737A24RB.js → chunk-FUEL6BK7.js} +9 -1
  25. package/dist/{chunk-6MCXWSR3.js → chunk-H4RPZD6H.js} +1 -1
  26. package/dist/chunk-JHGIWNHL.cjs +46 -0
  27. package/dist/{chunk-27JNK5TE.cjs → chunk-LUKMRIKJ.cjs} +40 -61
  28. package/dist/{chunk-4H3B46YX.js → chunk-MWLAHCU7.js} +9 -3
  29. package/dist/{chunk-QCMC2WOC.cjs → chunk-N6ZOJI2M.cjs} +4 -4
  30. package/dist/{chunk-2TPGTNNY.js → chunk-NGSLABLS.js} +37 -58
  31. package/dist/chunk-QHPFA6OE.js +46 -0
  32. package/dist/{chunk-M4LKQQHU.cjs → chunk-REPKBECD.cjs} +2 -2
  33. package/dist/chunk-SKU4M27Z.js +528 -0
  34. package/dist/chunk-W4XTDUGT.js +267 -0
  35. package/dist/{chunk-RDEROLKA.cjs → chunk-XAM7SFVB.cjs} +8 -6
  36. package/dist/chunk-XF4EQ3IV.cjs +267 -0
  37. package/dist/{chunk-IHJDYAYJ.cjs → chunk-XTHHDIBG.cjs} +9 -1
  38. package/dist/{chunk-5N3QP5LJ.js → chunk-YDH2BMEN.js} +19 -11
  39. package/dist/constants-ICQLSGZN.cjs +19 -0
  40. package/dist/constants-N3I2FHCM.js +19 -0
  41. package/dist/feedback-TOGESBX7.cjs +11 -0
  42. package/dist/{feedback-3THCLEBE.js → feedback-YGSYBQEW.js} +3 -2
  43. package/dist/index.cjs +1463 -1146
  44. package/dist/index.js +987 -670
  45. package/dist/login-QVBS7KBK.cjs +13 -0
  46. package/dist/login-XUVEFKCR.js +13 -0
  47. package/dist/logout-75YLPOBK.js +13 -0
  48. package/dist/logout-FYYR5KCP.cjs +13 -0
  49. package/dist/{permissions-CYW62ZK3.js → permissions-3GS4ZWVA.js} +2 -1
  50. package/dist/permissions-E3MTIE7D.cjs +10 -0
  51. package/dist/{skills-HF4SAF5O.js → skills-3M26KASS.js} +3 -1
  52. package/dist/skills-BOFY5RQN.cjs +13 -0
  53. package/dist/skills-install-WJ2LDRQG.js +680 -0
  54. package/dist/skills-install-Z3W5PQWQ.cjs +680 -0
  55. package/dist/skills-new-KIBUN63X.js +12 -0
  56. package/dist/skills-new-XDYS24XW.cjs +12 -0
  57. package/dist/{status-SLYYTKXD.js → status-6FY6RKIS.js} +1 -1
  58. package/dist/status-DJHDT6QH.cjs +9 -0
  59. package/dist/theme-2UK74UWR.cjs +13 -0
  60. package/dist/{theme-THMQ5AIN.js → theme-XNZ2X6HE.js} +3 -3
  61. package/package.json +1 -1
  62. package/dist/agents-EHLYBJLK.cjs +0 -10
  63. package/dist/agents-new-7VPASCBV.cjs +0 -10
  64. package/dist/chunk-NEAJ2UWG.js +0 -191
  65. package/dist/chunk-Z6SGIQWH.cjs +0 -191
  66. package/dist/feedback-PATTKRH5.cjs +0 -10
  67. package/dist/login-QJROML5I.js +0 -12
  68. package/dist/login-X66DSV75.cjs +0 -12
  69. package/dist/logout-3Z7R3F7J.cjs +0 -12
  70. package/dist/logout-RJ5OAXRI.js +0 -12
  71. package/dist/permissions-NOC5DMOH.cjs +0 -9
  72. package/dist/skills-U6J6DFLK.cjs +0 -11
  73. package/dist/skills-new-QDTNEG3R.js +0 -10
  74. package/dist/skills-new-UPVBHIF2.cjs +0 -10
  75. package/dist/status-GR73LEEN.cjs +0 -9
  76. package/dist/theme-YDANJLZR.cjs +0 -13
@@ -0,0 +1,46 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/skills/types.ts
2
+ var SKILL_CONSTRAINTS = {
3
+ NAME_MAX_LENGTH: 64,
4
+ NAME_PATTERN: /^[a-z0-9-]+$/,
5
+ DESCRIPTION_MAX_LENGTH: 1024,
6
+ COMPATIBILITY_MAX_LENGTH: 500
7
+ };
8
+ function isValidSkillName(name) {
9
+ if (!name || typeof name !== "string") return false;
10
+ if (name.length > SKILL_CONSTRAINTS.NAME_MAX_LENGTH) return false;
11
+ return SKILL_CONSTRAINTS.NAME_PATTERN.test(name);
12
+ }
13
+ function validateSkillFrontmatter(frontmatter) {
14
+ const errors = [];
15
+ if (!frontmatter.name) {
16
+ errors.push("Missing required field: name");
17
+ } else if (!isValidSkillName(frontmatter.name)) {
18
+ errors.push(`Invalid name: must be 1-${SKILL_CONSTRAINTS.NAME_MAX_LENGTH} chars, lowercase alphanumeric with hyphens only`);
19
+ }
20
+ if (!frontmatter.description) {
21
+ errors.push("Missing required field: description");
22
+ } else if (frontmatter.description.length > SKILL_CONSTRAINTS.DESCRIPTION_MAX_LENGTH) {
23
+ errors.push(`Description exceeds ${SKILL_CONSTRAINTS.DESCRIPTION_MAX_LENGTH} characters`);
24
+ }
25
+ if (frontmatter.compatibility && frontmatter.compatibility.length > SKILL_CONSTRAINTS.COMPATIBILITY_MAX_LENGTH) {
26
+ errors.push(`Compatibility exceeds ${SKILL_CONSTRAINTS.COMPATIBILITY_MAX_LENGTH} characters`);
27
+ }
28
+ return {
29
+ valid: errors.length === 0,
30
+ errors
31
+ };
32
+ }
33
+
34
+
35
+
36
+
37
+ exports.isValidSkillName = isValidSkillName; exports.validateSkillFrontmatter = validateSkillFrontmatter;
38
+ /**
39
+ * @license
40
+ * Copyright 2025 Autohand AI LLC
41
+ * SPDX-License-Identifier: Apache-2.0
42
+ *
43
+ * Skills Types - Agent Skills standard implementation
44
+ * Skills are instruction packages (workflows, guides) that provide specialized
45
+ * instructions to the agent, similar to on-demand AGENTS.md files.
46
+ */
@@ -1,47 +1,17 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 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 _chunkIHJDYAYJcjs = require('./chunk-IHJDYAYJ.cjs');
3
+ var _chunkJHGIWNHLcjs = require('./chunk-JHGIWNHL.cjs');
4
+
5
+
6
+ var _chunk3HPUOQJNcjs = require('./chunk-3HPUOQJN.cjs');
7
+
8
+
9
+ var _chunkXTHHDIBGcjs = require('./chunk-XTHHDIBG.cjs');
4
10
 
5
11
  // src/commands/skills-new.ts
6
12
  var _path = require('path'); var _path2 = _interopRequireDefault(_path);
7
13
  var _fsextra = require('fs-extra'); var _fsextra2 = _interopRequireDefault(_fsextra);
8
14
  var _chalk = require('chalk'); var _chalk2 = _interopRequireDefault(_chalk);
9
- var _enquirer = require('enquirer'); var _enquirer2 = _interopRequireDefault(_enquirer);
10
-
11
- // src/skills/types.ts
12
- var SKILL_CONSTRAINTS = {
13
- NAME_MAX_LENGTH: 64,
14
- NAME_PATTERN: /^[a-z0-9-]+$/,
15
- DESCRIPTION_MAX_LENGTH: 1024,
16
- COMPATIBILITY_MAX_LENGTH: 500
17
- };
18
- function isValidSkillName(name) {
19
- if (!name || typeof name !== "string") return false;
20
- if (name.length > SKILL_CONSTRAINTS.NAME_MAX_LENGTH) return false;
21
- return SKILL_CONSTRAINTS.NAME_PATTERN.test(name);
22
- }
23
- function validateSkillFrontmatter(frontmatter) {
24
- const errors = [];
25
- if (!frontmatter.name) {
26
- errors.push("Missing required field: name");
27
- } else if (!isValidSkillName(frontmatter.name)) {
28
- errors.push(`Invalid name: must be 1-${SKILL_CONSTRAINTS.NAME_MAX_LENGTH} chars, lowercase alphanumeric with hyphens only`);
29
- }
30
- if (!frontmatter.description) {
31
- errors.push("Missing required field: description");
32
- } else if (frontmatter.description.length > SKILL_CONSTRAINTS.DESCRIPTION_MAX_LENGTH) {
33
- errors.push(`Description exceeds ${SKILL_CONSTRAINTS.DESCRIPTION_MAX_LENGTH} characters`);
34
- }
35
- if (frontmatter.compatibility && frontmatter.compatibility.length > SKILL_CONSTRAINTS.COMPATIBILITY_MAX_LENGTH) {
36
- errors.push(`Compatibility exceeds ${SKILL_CONSTRAINTS.COMPATIBILITY_MAX_LENGTH} characters`);
37
- }
38
- return {
39
- valid: errors.length === 0,
40
- errors
41
- };
42
- }
43
-
44
- // src/commands/skills-new.ts
45
15
  var metadata = {
46
16
  command: "/skills new",
47
17
  description: "create a new skill from a description",
@@ -55,7 +25,7 @@ async function createSkill(ctx) {
55
25
  console.log(_chalk2.default.red("Skills registry not available."));
56
26
  return null;
57
27
  }
58
- const answers = await _enquirer2.default.prompt([
28
+ const answers = await _chunk3HPUOQJNcjs.safePrompt.call(void 0, [
59
29
  {
60
30
  type: "input",
61
31
  name: "name",
@@ -64,7 +34,7 @@ async function createSkill(ctx) {
64
34
  if (typeof val !== "string" || !val.trim()) {
65
35
  return "Name is required";
66
36
  }
67
- if (!isValidSkillName(val.trim())) {
37
+ if (!_chunkJHGIWNHLcjs.isValidSkillName.call(void 0, val.trim())) {
68
38
  return "Name must be lowercase alphanumeric with hyphens only (max 64 chars)";
69
39
  }
70
40
  return true;
@@ -85,21 +55,39 @@ async function createSkill(ctx) {
85
55
  }
86
56
  }
87
57
  ]);
58
+ if (!answers) {
59
+ console.log(_chalk2.default.gray("Cancelled."));
60
+ return null;
61
+ }
88
62
  const name = answers.name.trim().toLowerCase();
89
63
  const description = answers.description.trim();
90
64
  if (!name) {
91
65
  console.log(_chalk2.default.gray("Canceled: no name provided."));
92
66
  return null;
93
67
  }
68
+ const storageResult = await _chunk3HPUOQJNcjs.safePrompt.call(void 0, {
69
+ type: "select",
70
+ name: "level",
71
+ message: "Where should this skill be saved?",
72
+ choices: [
73
+ { name: "project", message: `Project level (.autohand/skills/) - specific to this project` },
74
+ { name: "user", message: `User level (~/.autohand/skills/) - available in all projects` }
75
+ ]
76
+ });
77
+ if (!storageResult) {
78
+ console.log(_chalk2.default.gray("Cancelled."));
79
+ return null;
80
+ }
81
+ const storageLevel = storageResult.level;
94
82
  if (skillsRegistry.hasSkill(name)) {
95
83
  console.log(_chalk2.default.yellow(`A skill named "${name}" already exists.`));
96
- const { overwrite } = await _enquirer2.default.prompt({
84
+ const result = await _chunk3HPUOQJNcjs.safePrompt.call(void 0, {
97
85
  type: "confirm",
98
86
  name: "overwrite",
99
87
  message: "Do you want to overwrite it?",
100
88
  initial: false
101
89
  });
102
- if (!overwrite) {
90
+ if (!result || !result.overwrite) {
103
91
  console.log(_chalk2.default.gray("Canceled."));
104
92
  return null;
105
93
  }
@@ -112,7 +100,7 @@ async function createSkill(ctx) {
112
100
  console.log(_chalk2.default.gray(` Similarity: ${(match.score * 100).toFixed(0)}%`));
113
101
  }
114
102
  console.log();
115
- const { proceed } = await _enquirer2.default.prompt({
103
+ const result = await _chunk3HPUOQJNcjs.safePrompt.call(void 0, {
116
104
  type: "select",
117
105
  name: "proceed",
118
106
  message: "How would you like to proceed?",
@@ -122,11 +110,11 @@ async function createSkill(ctx) {
122
110
  { name: "cancel", message: "Cancel" }
123
111
  ]
124
112
  });
125
- if (proceed === "cancel") {
113
+ if (!result || result.proceed === "cancel") {
126
114
  console.log(_chalk2.default.gray("Canceled."));
127
115
  return null;
128
116
  }
129
- if (proceed === "use") {
117
+ if (result.proceed === "use") {
130
118
  const existingSkill = similar[0].skill;
131
119
  skillsRegistry.activateSkill(existingSkill.name);
132
120
  console.log(_chalk2.default.green(`\u2713 Activated existing skill: ${existingSkill.name}`));
@@ -162,17 +150,18 @@ Output only the raw markdown content, no code fences.`
162
150
  console.log(content.length > 800 ? content.slice(0, 800) + "\n...(truncated)" : content);
163
151
  console.log(_chalk2.default.gray("\u2500".repeat(50)));
164
152
  console.log();
165
- const { confirm } = await _enquirer2.default.prompt({
153
+ const confirmResult = await _chunk3HPUOQJNcjs.safePrompt.call(void 0, {
166
154
  type: "confirm",
167
155
  name: "confirm",
168
156
  message: "Save this skill?",
169
157
  initial: true
170
158
  });
171
- if (!confirm) {
159
+ if (!confirmResult || !confirmResult.confirm) {
172
160
  console.log(_chalk2.default.gray("Canceled."));
173
161
  return null;
174
162
  }
175
- const skillDir = _path2.default.join(_chunkIHJDYAYJcjs.AUTOHAND_PATHS.skills, name);
163
+ const baseDir = storageLevel === "project" ? _path2.default.join(ctx.workspaceRoot, ".autohand", "skills") : _chunkXTHHDIBGcjs.AUTOHAND_PATHS.skills;
164
+ const skillDir = _path2.default.join(baseDir, name);
176
165
  const skillPath = _path2.default.join(skillDir, "SKILL.md");
177
166
  try {
178
167
  await _fsextra2.default.ensureDir(skillDir);
@@ -180,13 +169,13 @@ Output only the raw markdown content, no code fences.`
180
169
  console.log(_chalk2.default.green(`\u2713 Saved new skill to ${skillPath}`));
181
170
  const success = await skillsRegistry.saveSkill(name, content);
182
171
  if (success) {
183
- const { activate } = await _enquirer2.default.prompt({
172
+ const activateResult = await _chunk3HPUOQJNcjs.safePrompt.call(void 0, {
184
173
  type: "confirm",
185
174
  name: "activate",
186
175
  message: "Activate this skill now?",
187
176
  initial: true
188
177
  });
189
- if (activate) {
178
+ if (_optionalChain([activateResult, 'optionalAccess', _ => _.activate])) {
190
179
  skillsRegistry.activateSkill(name);
191
180
  console.log(_chalk2.default.green(`\u2713 Skill "${name}" is now active.`));
192
181
  }
@@ -232,17 +221,7 @@ description: <description here>
232
221
 
233
222
 
234
223
 
235
-
236
- exports.validateSkillFrontmatter = validateSkillFrontmatter; exports.metadata = metadata; exports.createSkill = createSkill;
237
- /**
238
- * @license
239
- * Copyright 2025 Autohand AI LLC
240
- * SPDX-License-Identifier: Apache-2.0
241
- *
242
- * Skills Types - Agent Skills standard implementation
243
- * Skills are instruction packages (workflows, guides) that provide specialized
244
- * instructions to the agent, similar to on-demand AGENTS.md files.
245
- */
224
+ exports.metadata = metadata; exports.createSkill = createSkill;
246
225
  /**
247
226
  * @license
248
227
  * Copyright 2025 Autohand AI LLC
@@ -1,12 +1,14 @@
1
+ import {
2
+ safePrompt
3
+ } from "./chunk-7BYSXAKS.js";
1
4
  import {
2
5
  AUTOHAND_PATHS
3
- } from "./chunk-737A24RB.js";
6
+ } from "./chunk-FUEL6BK7.js";
4
7
 
5
8
  // src/commands/agents-new.ts
6
9
  import path from "path";
7
10
  import fs from "fs-extra";
8
11
  import chalk from "chalk";
9
- import enquirer from "enquirer";
10
12
  var metadata = {
11
13
  command: "/agents new",
12
14
  description: "create a new sub-agent from a description",
@@ -14,7 +16,7 @@ var metadata = {
14
16
  prd: "prd/sub_agents_architecture.md"
15
17
  };
16
18
  async function createAgent(ctx) {
17
- const answers = await enquirer.prompt([
19
+ const answers = await safePrompt([
18
20
  {
19
21
  type: "input",
20
22
  name: "name",
@@ -27,6 +29,10 @@ async function createAgent(ctx) {
27
29
  message: "Briefly describe what the agent should do"
28
30
  }
29
31
  ]);
32
+ if (!answers) {
33
+ console.log(chalk.gray("Cancelled."));
34
+ return null;
35
+ }
30
36
  const name = answers.name.trim();
31
37
  const description = answers.description.trim();
32
38
  if (!name) {
@@ -1,6 +1,6 @@
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 _chunkIHJDYAYJcjs = require('./chunk-IHJDYAYJ.cjs');
3
+ var _chunkXTHHDIBGcjs = require('./chunk-XTHHDIBG.cjs');
4
4
 
5
5
  // src/ui/theme/Theme.ts
6
6
  var Theme = class {
@@ -907,9 +907,9 @@ function useTheme() {
907
907
  var _fsextra = require('fs-extra'); var _fsextra2 = _interopRequireDefault(_fsextra);
908
908
 
909
909
  var _yaml = require('yaml'); var _yaml2 = _interopRequireDefault(_yaml);
910
- var DEFAULT_CONFIG_PATH = _chunkIHJDYAYJcjs.AUTOHAND_FILES.configJson;
911
- var YAML_CONFIG_PATH = _chunkIHJDYAYJcjs.AUTOHAND_FILES.configYaml;
912
- var YML_CONFIG_PATH = _chunkIHJDYAYJcjs.AUTOHAND_FILES.configYml;
910
+ var DEFAULT_CONFIG_PATH = _chunkXTHHDIBGcjs.AUTOHAND_FILES.configJson;
911
+ var YAML_CONFIG_PATH = _chunkXTHHDIBGcjs.AUTOHAND_FILES.configYaml;
912
+ var YML_CONFIG_PATH = _chunkXTHHDIBGcjs.AUTOHAND_FILES.configYml;
913
913
  var DEFAULT_BASE_URL = "https://openrouter.ai/api/v1";
914
914
  var DEFAULT_OLLAMA_URL = "http://localhost:11434";
915
915
  var DEFAULT_LLAMACPP_URL = "http://localhost:8080";
@@ -1,47 +1,17 @@
1
+ import {
2
+ isValidSkillName
3
+ } from "./chunk-QHPFA6OE.js";
4
+ import {
5
+ safePrompt
6
+ } from "./chunk-7BYSXAKS.js";
1
7
  import {
2
8
  AUTOHAND_PATHS
3
- } from "./chunk-737A24RB.js";
9
+ } from "./chunk-FUEL6BK7.js";
4
10
 
5
11
  // src/commands/skills-new.ts
6
12
  import path from "path";
7
13
  import fs from "fs-extra";
8
14
  import chalk from "chalk";
9
- import enquirer from "enquirer";
10
-
11
- // src/skills/types.ts
12
- var SKILL_CONSTRAINTS = {
13
- NAME_MAX_LENGTH: 64,
14
- NAME_PATTERN: /^[a-z0-9-]+$/,
15
- DESCRIPTION_MAX_LENGTH: 1024,
16
- COMPATIBILITY_MAX_LENGTH: 500
17
- };
18
- function isValidSkillName(name) {
19
- if (!name || typeof name !== "string") return false;
20
- if (name.length > SKILL_CONSTRAINTS.NAME_MAX_LENGTH) return false;
21
- return SKILL_CONSTRAINTS.NAME_PATTERN.test(name);
22
- }
23
- function validateSkillFrontmatter(frontmatter) {
24
- const errors = [];
25
- if (!frontmatter.name) {
26
- errors.push("Missing required field: name");
27
- } else if (!isValidSkillName(frontmatter.name)) {
28
- errors.push(`Invalid name: must be 1-${SKILL_CONSTRAINTS.NAME_MAX_LENGTH} chars, lowercase alphanumeric with hyphens only`);
29
- }
30
- if (!frontmatter.description) {
31
- errors.push("Missing required field: description");
32
- } else if (frontmatter.description.length > SKILL_CONSTRAINTS.DESCRIPTION_MAX_LENGTH) {
33
- errors.push(`Description exceeds ${SKILL_CONSTRAINTS.DESCRIPTION_MAX_LENGTH} characters`);
34
- }
35
- if (frontmatter.compatibility && frontmatter.compatibility.length > SKILL_CONSTRAINTS.COMPATIBILITY_MAX_LENGTH) {
36
- errors.push(`Compatibility exceeds ${SKILL_CONSTRAINTS.COMPATIBILITY_MAX_LENGTH} characters`);
37
- }
38
- return {
39
- valid: errors.length === 0,
40
- errors
41
- };
42
- }
43
-
44
- // src/commands/skills-new.ts
45
15
  var metadata = {
46
16
  command: "/skills new",
47
17
  description: "create a new skill from a description",
@@ -55,7 +25,7 @@ async function createSkill(ctx) {
55
25
  console.log(chalk.red("Skills registry not available."));
56
26
  return null;
57
27
  }
58
- const answers = await enquirer.prompt([
28
+ const answers = await safePrompt([
59
29
  {
60
30
  type: "input",
61
31
  name: "name",
@@ -85,21 +55,39 @@ async function createSkill(ctx) {
85
55
  }
86
56
  }
87
57
  ]);
58
+ if (!answers) {
59
+ console.log(chalk.gray("Cancelled."));
60
+ return null;
61
+ }
88
62
  const name = answers.name.trim().toLowerCase();
89
63
  const description = answers.description.trim();
90
64
  if (!name) {
91
65
  console.log(chalk.gray("Canceled: no name provided."));
92
66
  return null;
93
67
  }
68
+ const storageResult = await safePrompt({
69
+ type: "select",
70
+ name: "level",
71
+ message: "Where should this skill be saved?",
72
+ choices: [
73
+ { name: "project", message: `Project level (.autohand/skills/) - specific to this project` },
74
+ { name: "user", message: `User level (~/.autohand/skills/) - available in all projects` }
75
+ ]
76
+ });
77
+ if (!storageResult) {
78
+ console.log(chalk.gray("Cancelled."));
79
+ return null;
80
+ }
81
+ const storageLevel = storageResult.level;
94
82
  if (skillsRegistry.hasSkill(name)) {
95
83
  console.log(chalk.yellow(`A skill named "${name}" already exists.`));
96
- const { overwrite } = await enquirer.prompt({
84
+ const result = await safePrompt({
97
85
  type: "confirm",
98
86
  name: "overwrite",
99
87
  message: "Do you want to overwrite it?",
100
88
  initial: false
101
89
  });
102
- if (!overwrite) {
90
+ if (!result || !result.overwrite) {
103
91
  console.log(chalk.gray("Canceled."));
104
92
  return null;
105
93
  }
@@ -112,7 +100,7 @@ async function createSkill(ctx) {
112
100
  console.log(chalk.gray(` Similarity: ${(match.score * 100).toFixed(0)}%`));
113
101
  }
114
102
  console.log();
115
- const { proceed } = await enquirer.prompt({
103
+ const result = await safePrompt({
116
104
  type: "select",
117
105
  name: "proceed",
118
106
  message: "How would you like to proceed?",
@@ -122,11 +110,11 @@ async function createSkill(ctx) {
122
110
  { name: "cancel", message: "Cancel" }
123
111
  ]
124
112
  });
125
- if (proceed === "cancel") {
113
+ if (!result || result.proceed === "cancel") {
126
114
  console.log(chalk.gray("Canceled."));
127
115
  return null;
128
116
  }
129
- if (proceed === "use") {
117
+ if (result.proceed === "use") {
130
118
  const existingSkill = similar[0].skill;
131
119
  skillsRegistry.activateSkill(existingSkill.name);
132
120
  console.log(chalk.green(`\u2713 Activated existing skill: ${existingSkill.name}`));
@@ -162,17 +150,18 @@ Output only the raw markdown content, no code fences.`
162
150
  console.log(content.length > 800 ? content.slice(0, 800) + "\n...(truncated)" : content);
163
151
  console.log(chalk.gray("\u2500".repeat(50)));
164
152
  console.log();
165
- const { confirm } = await enquirer.prompt({
153
+ const confirmResult = await safePrompt({
166
154
  type: "confirm",
167
155
  name: "confirm",
168
156
  message: "Save this skill?",
169
157
  initial: true
170
158
  });
171
- if (!confirm) {
159
+ if (!confirmResult || !confirmResult.confirm) {
172
160
  console.log(chalk.gray("Canceled."));
173
161
  return null;
174
162
  }
175
- const skillDir = path.join(AUTOHAND_PATHS.skills, name);
163
+ const baseDir = storageLevel === "project" ? path.join(ctx.workspaceRoot, ".autohand", "skills") : AUTOHAND_PATHS.skills;
164
+ const skillDir = path.join(baseDir, name);
176
165
  const skillPath = path.join(skillDir, "SKILL.md");
177
166
  try {
178
167
  await fs.ensureDir(skillDir);
@@ -180,13 +169,13 @@ Output only the raw markdown content, no code fences.`
180
169
  console.log(chalk.green(`\u2713 Saved new skill to ${skillPath}`));
181
170
  const success = await skillsRegistry.saveSkill(name, content);
182
171
  if (success) {
183
- const { activate } = await enquirer.prompt({
172
+ const activateResult = await safePrompt({
184
173
  type: "confirm",
185
174
  name: "activate",
186
175
  message: "Activate this skill now?",
187
176
  initial: true
188
177
  });
189
- if (activate) {
178
+ if (activateResult?.activate) {
190
179
  skillsRegistry.activateSkill(name);
191
180
  console.log(chalk.green(`\u2713 Skill "${name}" is now active.`));
192
181
  }
@@ -230,19 +219,9 @@ description: <description here>
230
219
  }
231
220
 
232
221
  export {
233
- validateSkillFrontmatter,
234
222
  metadata,
235
223
  createSkill
236
224
  };
237
- /**
238
- * @license
239
- * Copyright 2025 Autohand AI LLC
240
- * SPDX-License-Identifier: Apache-2.0
241
- *
242
- * Skills Types - Agent Skills standard implementation
243
- * Skills are instruction packages (workflows, guides) that provide specialized
244
- * instructions to the agent, similar to on-demand AGENTS.md files.
245
- */
246
225
  /**
247
226
  * @license
248
227
  * Copyright 2025 Autohand AI LLC
@@ -0,0 +1,46 @@
1
+ // src/skills/types.ts
2
+ var SKILL_CONSTRAINTS = {
3
+ NAME_MAX_LENGTH: 64,
4
+ NAME_PATTERN: /^[a-z0-9-]+$/,
5
+ DESCRIPTION_MAX_LENGTH: 1024,
6
+ COMPATIBILITY_MAX_LENGTH: 500
7
+ };
8
+ function isValidSkillName(name) {
9
+ if (!name || typeof name !== "string") return false;
10
+ if (name.length > SKILL_CONSTRAINTS.NAME_MAX_LENGTH) return false;
11
+ return SKILL_CONSTRAINTS.NAME_PATTERN.test(name);
12
+ }
13
+ function validateSkillFrontmatter(frontmatter) {
14
+ const errors = [];
15
+ if (!frontmatter.name) {
16
+ errors.push("Missing required field: name");
17
+ } else if (!isValidSkillName(frontmatter.name)) {
18
+ errors.push(`Invalid name: must be 1-${SKILL_CONSTRAINTS.NAME_MAX_LENGTH} chars, lowercase alphanumeric with hyphens only`);
19
+ }
20
+ if (!frontmatter.description) {
21
+ errors.push("Missing required field: description");
22
+ } else if (frontmatter.description.length > SKILL_CONSTRAINTS.DESCRIPTION_MAX_LENGTH) {
23
+ errors.push(`Description exceeds ${SKILL_CONSTRAINTS.DESCRIPTION_MAX_LENGTH} characters`);
24
+ }
25
+ if (frontmatter.compatibility && frontmatter.compatibility.length > SKILL_CONSTRAINTS.COMPATIBILITY_MAX_LENGTH) {
26
+ errors.push(`Compatibility exceeds ${SKILL_CONSTRAINTS.COMPATIBILITY_MAX_LENGTH} characters`);
27
+ }
28
+ return {
29
+ valid: errors.length === 0,
30
+ errors
31
+ };
32
+ }
33
+
34
+ export {
35
+ isValidSkillName,
36
+ validateSkillFrontmatter
37
+ };
38
+ /**
39
+ * @license
40
+ * Copyright 2025 Autohand AI LLC
41
+ * SPDX-License-Identifier: Apache-2.0
42
+ *
43
+ * Skills Types - Agent Skills standard implementation
44
+ * Skills are instruction packages (workflows, guides) that provide specialized
45
+ * instructions to the agent, similar to on-demand AGENTS.md files.
46
+ */
@@ -1,12 +1,12 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
- var _chunkIHJDYAYJcjs = require('./chunk-IHJDYAYJ.cjs');
3
+ var _chunkXTHHDIBGcjs = require('./chunk-XTHHDIBG.cjs');
4
4
 
5
5
  // src/auth/AuthClient.ts
6
6
  var DEFAULT_TIMEOUT = 1e4;
7
7
  var AuthClient = class {
8
8
  constructor(config = {}) {
9
- this.baseUrl = config.baseUrl || _chunkIHJDYAYJcjs.AUTH_CONFIG.apiBaseUrl;
9
+ this.baseUrl = config.baseUrl || _chunkXTHHDIBGcjs.AUTH_CONFIG.apiBaseUrl;
10
10
  this.timeout = config.timeout || DEFAULT_TIMEOUT;
11
11
  }
12
12
  /**