autohand-cli 0.6.2 → 0.6.4

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 (217) hide show
  1. package/README.md +1 -0
  2. package/dist/agents-EHLYBJLK.cjs +10 -0
  3. package/dist/{agents-7GZ2VBYU.js → agents-OJWYZN6X.js} +1 -0
  4. package/dist/agents-new-7VPASCBV.cjs +10 -0
  5. package/dist/{agents-new-VALZG4B5.js → agents-new-WQLJOXSS.js} +1 -0
  6. package/dist/chunk-27JNK5TE.cjs +252 -0
  7. package/dist/{chunk-JUDX6E53.js → chunk-3Y6G5DUX.cjs} +21 -21
  8. package/dist/{chunk-QE5RKNVN.js → chunk-4AMTDSQ3.cjs} +9 -9
  9. package/dist/{chunk-KERHTHMK.js → chunk-6MCXWSR3.js} +10 -8
  10. package/dist/chunk-7RRX7H2X.cjs +104 -0
  11. package/dist/chunk-AD4O67ZA.cjs +93 -0
  12. package/dist/chunk-AL4Z4WKG.cjs +59 -0
  13. package/dist/chunk-BEIG7V7Q.cjs +51 -0
  14. package/dist/{chunk-2DEJU7WQ.js → chunk-C3IFF3EH.cjs} +33 -33
  15. package/dist/chunk-DD2YPHP5.cjs +133 -0
  16. package/dist/chunk-FFA4LDAO.cjs +55 -0
  17. package/dist/{chunk-UNS4S6J3.js → chunk-G7SYGATA.cjs} +38 -38
  18. package/dist/chunk-IHJDYAYJ.cjs +77 -0
  19. package/dist/chunk-JBKP2CLA.cjs +364 -0
  20. package/dist/chunk-JSBRDJBE.js +30 -0
  21. package/dist/chunk-KNLBEUAV.cjs +57 -0
  22. package/dist/chunk-KT55HW6V.js +168 -0
  23. package/dist/{chunk-7WBK33MM.js → chunk-KZ2UXXLH.js} +4 -2
  24. package/dist/chunk-M4LKQQHU.cjs +168 -0
  25. package/dist/chunk-M7RVTUWE.cjs +145 -0
  26. package/dist/chunk-MFK6HE47.cjs +33 -0
  27. package/dist/{chunk-RUQVXU6K.js → chunk-MRQV5HMC.js} +4 -2
  28. package/dist/chunk-N254NRHT.cjs +30 -0
  29. package/dist/chunk-NWXYG5PQ.js +93 -0
  30. package/dist/chunk-QCMC2WOC.cjs +1135 -0
  31. package/dist/chunk-RDEROLKA.cjs +79 -0
  32. package/dist/chunk-RYY5I7QN.cjs +49 -0
  33. package/dist/chunk-UBGEAEKS.js +1135 -0
  34. package/dist/chunk-V5MTBGM4.cjs +20 -0
  35. package/dist/chunk-VMMGT42E.cjs +60 -0
  36. package/dist/chunk-WBDPILKI.cjs +19 -0
  37. package/dist/chunk-XT4OSHSB.cjs +20 -0
  38. package/dist/{chunk-TVWTD63Y.js → chunk-Z3Q2AFDS.js} +1 -0
  39. package/dist/chunk-Z4J4W6YQ.cjs +339 -0
  40. package/dist/chunk-Z6SGIQWH.cjs +191 -0
  41. package/dist/{chunk-GX24PC3L.js → chunk-ZTA2ASFW.cjs} +64 -48
  42. package/dist/completion-AMEZDTFT.cjs +11 -0
  43. package/dist/{completion-Y42FKDT3.js → completion-HR3ZT55J.js} +1 -0
  44. package/dist/{export-WJ5P6E5Z.js → export-MYBJZD3H.js} +1 -0
  45. package/dist/export-ULYYSO5V.cjs +9 -0
  46. package/dist/{feedback-RJNBUBDQ.js → feedback-3THCLEBE.js} +1 -0
  47. package/dist/feedback-PATTKRH5.cjs +10 -0
  48. package/dist/{formatters-UG6VZJJ5.js → formatters-3POW3KMP.js} +1 -0
  49. package/dist/formatters-UMUJYWV5.cjs +9 -0
  50. package/dist/help-2PR7P4UJ.cjs +11 -0
  51. package/dist/{help-CNOV6OXY.js → help-AW4QPGIW.js} +2 -1
  52. package/dist/index.cjs +12594 -9303
  53. package/dist/index.js +9726 -2878
  54. package/dist/{init-DML7AOII.js → init-HAQKREMF.js} +1 -0
  55. package/dist/init-OLSCW7ZC.cjs +9 -0
  56. package/dist/lint-D5UOJWIK.cjs +9 -0
  57. package/dist/{lint-TA2ZHVLM.js → lint-NJPZWVN2.js} +1 -0
  58. package/dist/login-QJROML5I.js +12 -0
  59. package/dist/login-X66DSV75.cjs +12 -0
  60. package/dist/logout-3Z7R3F7J.cjs +12 -0
  61. package/dist/logout-RJ5OAXRI.js +12 -0
  62. package/dist/memory-77SWEZYB.cjs +9 -0
  63. package/dist/{memory-4GSP7NKV.js → memory-F3V5FW6W.js} +1 -0
  64. package/dist/model-B2PE6XFS.cjs +9 -0
  65. package/dist/{model-HKEFSH5E.js → model-JC53RT7A.js} +1 -0
  66. package/dist/{new-EEZC4XXV.js → new-356ITOM7.js} +1 -0
  67. package/dist/new-J3ABPMW4.cjs +9 -0
  68. package/dist/{permissions-XJKYKDBG.js → permissions-CYW62ZK3.js} +1 -0
  69. package/dist/permissions-NOC5DMOH.cjs +9 -0
  70. package/dist/{quit-RSYIERO5.js → quit-2QWJ75GZ.js} +1 -0
  71. package/dist/quit-DQ57J67A.cjs +9 -0
  72. package/dist/resume-43XMN4CL.cjs +9 -0
  73. package/dist/{resume-2NERFSTD.js → resume-GA7YZJSO.js} +1 -0
  74. package/dist/session-BSU2L5UI.cjs +9 -0
  75. package/dist/{session-H5QWKE5E.js → session-SZMRN5KG.js} +1 -0
  76. package/dist/sessions-CVOZGTKR.cjs +9 -0
  77. package/dist/{sessions-4KXIT76T.js → sessions-OJ4DRK3P.js} +1 -0
  78. package/dist/{skills-POKNCIQV.js → skills-HF4SAF5O.js} +1 -0
  79. package/dist/skills-U6J6DFLK.cjs +11 -0
  80. package/dist/{skills-new-5VCNKQDP.js → skills-new-QDTNEG3R.js} +1 -0
  81. package/dist/skills-new-UPVBHIF2.cjs +10 -0
  82. package/dist/status-GR73LEEN.cjs +9 -0
  83. package/dist/{status-DCVSUWZG.js → status-SLYYTKXD.js} +2 -1
  84. package/dist/theme-THMQ5AIN.js +13 -0
  85. package/dist/theme-YDANJLZR.cjs +13 -0
  86. package/dist/{undo-7QJBXARS.js → undo-3Q44LSVS.js} +1 -0
  87. package/dist/undo-WF5HB5VU.cjs +9 -0
  88. package/package.json +10 -8
  89. package/dist/agents-32JB7KMB.js +0 -9
  90. package/dist/agents-3K6PHXQ6.js +0 -9
  91. package/dist/agents-A7AUMVQD.js +0 -8
  92. package/dist/agents-AHFECO5Q.js +0 -9
  93. package/dist/agents-DQFYBMJG.js +0 -8
  94. package/dist/agents-GX6L7BXZ.js +0 -9
  95. package/dist/agents-IWJJ7YJM.js +0 -8
  96. package/dist/agents-J2QLDVOP.js +0 -9
  97. package/dist/agents-OWTSY74S.js +0 -9
  98. package/dist/agents-RB34F4XE.js +0 -9
  99. package/dist/agents-XL27P67O.js +0 -9
  100. package/dist/agents-new-5I3B2W2I.js +0 -9
  101. package/dist/agents-new-CHV2AV34.js +0 -9
  102. package/dist/agents-new-F6F2VMDB.js +0 -9
  103. package/dist/agents-new-FDMUH7NL.js +0 -9
  104. package/dist/agents-new-GBF6JJIA.js +0 -9
  105. package/dist/agents-new-GCZEY4TE.js +0 -8
  106. package/dist/agents-new-OCIB72NU.js +0 -9
  107. package/dist/agents-new-PQGD47BZ.js +0 -9
  108. package/dist/agents-new-V6BNVJAB.js +0 -9
  109. package/dist/agents-new-WQUEZ2XH.js +0 -8
  110. package/dist/chunk-2EPIFDFM.js +0 -68
  111. package/dist/chunk-2FUWKZFN.js +0 -68
  112. package/dist/chunk-2HIILNYH.js +0 -197
  113. package/dist/chunk-2QAL3HH4.js +0 -79
  114. package/dist/chunk-3FRM7HJY.js +0 -57
  115. package/dist/chunk-3OD5MR23.js +0 -384
  116. package/dist/chunk-4LDR3Y3A.js +0 -79
  117. package/dist/chunk-4LLTISFP.js +0 -288
  118. package/dist/chunk-4UISIRMD.js +0 -288
  119. package/dist/chunk-4VWPX2X3.js +0 -131
  120. package/dist/chunk-7FMMKTRG.js +0 -64
  121. package/dist/chunk-7MFSCH7E.js +0 -382
  122. package/dist/chunk-7TV5KURP.js +0 -79
  123. package/dist/chunk-7XN6PAKV.js +0 -79
  124. package/dist/chunk-A7HRTONQ.js +0 -382
  125. package/dist/chunk-ALMJANSA.js +0 -197
  126. package/dist/chunk-CD7GNBIE.js +0 -288
  127. package/dist/chunk-CV3LEQRD.js +0 -57
  128. package/dist/chunk-CYY7D5TQ.js +0 -57
  129. package/dist/chunk-DAHMHLM6.js +0 -102
  130. package/dist/chunk-DAMLAWGE.js +0 -68
  131. package/dist/chunk-F4YPGOQJ.js +0 -105
  132. package/dist/chunk-FQDXFNOI.js +0 -57
  133. package/dist/chunk-FQI7EJY2.js +0 -105
  134. package/dist/chunk-GAJCZDZ5.js +0 -286
  135. package/dist/chunk-GEOP77H3.js +0 -79
  136. package/dist/chunk-GRX3IQHC.js +0 -131
  137. package/dist/chunk-H53NQAC2.js +0 -131
  138. package/dist/chunk-HJYISR7Y.js +0 -382
  139. package/dist/chunk-HLSI4HQM.js +0 -105
  140. package/dist/chunk-IAOMCEYU.js +0 -68
  141. package/dist/chunk-J7RENRJG.js +0 -382
  142. package/dist/chunk-JZQKOM7X.js +0 -382
  143. package/dist/chunk-K75NWR5V.js +0 -108
  144. package/dist/chunk-KCMWJB53.js +0 -288
  145. package/dist/chunk-KJ4M6KAK.js +0 -57
  146. package/dist/chunk-L3JXU574.js +0 -77
  147. package/dist/chunk-LR2XPUPT.js +0 -236
  148. package/dist/chunk-MCWNGAZG.js +0 -198
  149. package/dist/chunk-MQTBFYEG.js +0 -288
  150. package/dist/chunk-NCUJWSGP.js +0 -287
  151. package/dist/chunk-NWEUBPSG.js +0 -79
  152. package/dist/chunk-OJ5EBWOQ.js +0 -232
  153. package/dist/chunk-PKQZWNS2.js +0 -131
  154. package/dist/chunk-PQJIQBQ5.js +0 -57
  155. package/dist/chunk-PX5AGAEX.js +0 -105
  156. package/dist/chunk-Q7HX4VZD.js +0 -197
  157. package/dist/chunk-QLVXFPE3.js +0 -145
  158. package/dist/chunk-QUC577LO.js +0 -79
  159. package/dist/chunk-RAL2W5UX.js +0 -55
  160. package/dist/chunk-RANNBYFJ.js +0 -105
  161. package/dist/chunk-RCSSFUGL.js +0 -131
  162. package/dist/chunk-RZ7TASUI.js +0 -57
  163. package/dist/chunk-SN7D2PJO.js +0 -68
  164. package/dist/chunk-T4WQUJAE.js +0 -79
  165. package/dist/chunk-U2Z5BABG.js +0 -57
  166. package/dist/chunk-UHC4DIK5.js +0 -105
  167. package/dist/chunk-UW2LYWIM.js +0 -131
  168. package/dist/chunk-VRCQBFSX.js +0 -102
  169. package/dist/chunk-W76N6IZV.js +0 -197
  170. package/dist/chunk-WMC556GK.js +0 -131
  171. package/dist/chunk-WTEZYXD2.js +0 -67
  172. package/dist/chunk-X7EWON4T.js +0 -105
  173. package/dist/chunk-XARAKKJ4.js +0 -197
  174. package/dist/chunk-Y6JDGDEE.js +0 -197
  175. package/dist/chunk-Y7FSNXMR.js +0 -382
  176. package/dist/chunk-YPZMUIB5.js +0 -50
  177. package/dist/chunk-ZMDUVLR4.js +0 -148
  178. package/dist/chunk-ZRFAICDG.js +0 -382
  179. package/dist/export-HEFUNSR4.js +0 -8
  180. package/dist/feedback-3U2WYQK6.js +0 -9
  181. package/dist/feedback-5IIX372K.js +0 -9
  182. package/dist/feedback-6S6DWGIU.js +0 -9
  183. package/dist/feedback-7DEOY2AP.js +0 -9
  184. package/dist/feedback-BBQT42R6.js +0 -9
  185. package/dist/feedback-CGCSAWQT.js +0 -9
  186. package/dist/feedback-NEDFOKMA.js +0 -9
  187. package/dist/feedback-OXGGJVNA.js +0 -9
  188. package/dist/feedback-ZJECE2FS.js +0 -8
  189. package/dist/help-NQUZ7TNJ.js +0 -10
  190. package/dist/login-D53NQ7UY.js +0 -10
  191. package/dist/login-GPXDNB2F.js +0 -10
  192. package/dist/login-HDF4GSTP.js +0 -10
  193. package/dist/login-HXQ3FDA7.js +0 -10
  194. package/dist/login-SDAZTJAK.js +0 -10
  195. package/dist/login-SM6LEDDA.js +0 -10
  196. package/dist/login-TDI7HBRZ.js +0 -10
  197. package/dist/login-Y7XXSNOZ.js +0 -10
  198. package/dist/logout-32RNT7G2.js +0 -10
  199. package/dist/logout-43W7N6JU.js +0 -10
  200. package/dist/logout-6KCD4WA3.js +0 -10
  201. package/dist/logout-BMHTSXIY.js +0 -10
  202. package/dist/logout-JNNJJYYL.js +0 -10
  203. package/dist/logout-LW42QASH.js +0 -10
  204. package/dist/logout-QLWM6P26.js +0 -10
  205. package/dist/logout-TL7GLGWU.js +0 -10
  206. package/dist/memory-GVYG653L.js +0 -8
  207. package/dist/new-MCN36AOD.js +0 -8
  208. package/dist/status-F6TQOCON.js +0 -8
  209. package/dist/status-IT5CYW37.js +0 -8
  210. package/dist/status-MRJOSVE3.js +0 -8
  211. package/dist/status-MWFV2DZG.js +0 -8
  212. package/dist/status-N3PMJRSB.js +0 -8
  213. package/dist/status-NK7YSBXZ.js +0 -8
  214. package/dist/status-QLQ5ZKJ3.js +0 -8
  215. package/dist/status-SQEFMII5.js +0 -8
  216. package/dist/status-U33PEUBO.js +0 -8
  217. package/dist/status-XAJH67SE.js +0 -8
package/README.md CHANGED
@@ -307,6 +307,7 @@ docker run -it autohand
307
307
 
308
308
  ## Documentation
309
309
 
310
+ - [Playbook](AUTOHAND_PLAYBOOK.md) - 20 use cases for the software development lifecycle
310
311
  - [Features](docs/features.md) - Complete feature list
311
312
  - [Agent Skills](docs/agent-skills.md) - Skills system guide
312
313
  - [Configuration Reference](docs/config-reference.md) - All config options
@@ -0,0 +1,10 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+ var _chunkG7SYGATAcjs = require('./chunk-G7SYGATA.cjs');
5
+ require('./chunk-IHJDYAYJ.cjs');
6
+ require('./chunk-N254NRHT.cjs');
7
+
8
+
9
+
10
+ exports.handler = _chunkG7SYGATAcjs.handler; exports.metadata = _chunkG7SYGATAcjs.metadata;
@@ -3,6 +3,7 @@ import {
3
3
  metadata
4
4
  } from "./chunk-6FEZ6JAQ.js";
5
5
  import "./chunk-737A24RB.js";
6
+ import "./chunk-JSBRDJBE.js";
6
7
  export {
7
8
  handler,
8
9
  metadata
@@ -0,0 +1,10 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+ var _chunk3Y6G5DUXcjs = require('./chunk-3Y6G5DUX.cjs');
5
+ require('./chunk-IHJDYAYJ.cjs');
6
+ require('./chunk-N254NRHT.cjs');
7
+
8
+
9
+
10
+ exports.createAgent = _chunk3Y6G5DUXcjs.createAgent; exports.metadata = _chunk3Y6G5DUXcjs.metadata;
@@ -3,6 +3,7 @@ import {
3
3
  metadata
4
4
  } from "./chunk-4H3B46YX.js";
5
5
  import "./chunk-737A24RB.js";
6
+ import "./chunk-JSBRDJBE.js";
6
7
  export {
7
8
  createAgent,
8
9
  metadata
@@ -0,0 +1,252 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
2
+
3
+ var _chunkIHJDYAYJcjs = require('./chunk-IHJDYAYJ.cjs');
4
+
5
+ // src/commands/skills-new.ts
6
+ var _path = require('path'); var _path2 = _interopRequireDefault(_path);
7
+ var _fsextra = require('fs-extra'); var _fsextra2 = _interopRequireDefault(_fsextra);
8
+ 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
+ var metadata = {
46
+ command: "/skills new",
47
+ description: "create a new skill from a description",
48
+ implemented: true,
49
+ prd: "prd/skills_feature.md"
50
+ };
51
+ var SIMILARITY_THRESHOLD = 0.9;
52
+ async function createSkill(ctx) {
53
+ const { llm, skillsRegistry } = ctx;
54
+ if (!skillsRegistry) {
55
+ console.log(_chalk2.default.red("Skills registry not available."));
56
+ return null;
57
+ }
58
+ const answers = await _enquirer2.default.prompt([
59
+ {
60
+ type: "input",
61
+ name: "name",
62
+ message: "Skill name (lowercase, hyphens allowed)",
63
+ validate: (val) => {
64
+ if (typeof val !== "string" || !val.trim()) {
65
+ return "Name is required";
66
+ }
67
+ if (!isValidSkillName(val.trim())) {
68
+ return "Name must be lowercase alphanumeric with hyphens only (max 64 chars)";
69
+ }
70
+ return true;
71
+ }
72
+ },
73
+ {
74
+ type: "input",
75
+ name: "description",
76
+ message: "Describe what this skill should help with",
77
+ validate: (val) => {
78
+ if (typeof val !== "string" || !val.trim()) {
79
+ return "Description is required";
80
+ }
81
+ if (val.length > 1024) {
82
+ return "Description must be 1024 characters or less";
83
+ }
84
+ return true;
85
+ }
86
+ }
87
+ ]);
88
+ const name = answers.name.trim().toLowerCase();
89
+ const description = answers.description.trim();
90
+ if (!name) {
91
+ console.log(_chalk2.default.gray("Canceled: no name provided."));
92
+ return null;
93
+ }
94
+ if (skillsRegistry.hasSkill(name)) {
95
+ console.log(_chalk2.default.yellow(`A skill named "${name}" already exists.`));
96
+ const { overwrite } = await _enquirer2.default.prompt({
97
+ type: "confirm",
98
+ name: "overwrite",
99
+ message: "Do you want to overwrite it?",
100
+ initial: false
101
+ });
102
+ if (!overwrite) {
103
+ console.log(_chalk2.default.gray("Canceled."));
104
+ return null;
105
+ }
106
+ }
107
+ const similar = skillsRegistry.findSimilar(description, SIMILARITY_THRESHOLD);
108
+ if (similar.length > 0) {
109
+ console.log(_chalk2.default.yellow("\nFound similar existing skill(s):"));
110
+ for (const match of similar.slice(0, 3)) {
111
+ console.log(_chalk2.default.gray(` - ${match.skill.name}: ${match.skill.description}`));
112
+ console.log(_chalk2.default.gray(` Similarity: ${(match.score * 100).toFixed(0)}%`));
113
+ }
114
+ console.log();
115
+ const { proceed } = await _enquirer2.default.prompt({
116
+ type: "select",
117
+ name: "proceed",
118
+ message: "How would you like to proceed?",
119
+ choices: [
120
+ { name: "continue", message: "Continue creating new skill" },
121
+ { name: "use", message: `Use existing skill "${similar[0].skill.name}" instead` },
122
+ { name: "cancel", message: "Cancel" }
123
+ ]
124
+ });
125
+ if (proceed === "cancel") {
126
+ console.log(_chalk2.default.gray("Canceled."));
127
+ return null;
128
+ }
129
+ if (proceed === "use") {
130
+ const existingSkill = similar[0].skill;
131
+ skillsRegistry.activateSkill(existingSkill.name);
132
+ console.log(_chalk2.default.green(`\u2713 Activated existing skill: ${existingSkill.name}`));
133
+ return `Activated existing skill "${existingSkill.name}".`;
134
+ }
135
+ }
136
+ console.log(_chalk2.default.cyan("\nGenerating skill content..."));
137
+ const prompt = buildPrompt(name, description);
138
+ let content;
139
+ try {
140
+ const completion = await llm.complete({
141
+ messages: [
142
+ {
143
+ role: "system",
144
+ content: `You are an expert at creating Agent Skills (SKILL.md files).
145
+ Generate a complete SKILL.md file with proper YAML frontmatter and markdown body.
146
+ The skill should provide clear, actionable instructions that an AI agent can follow.
147
+ Focus on practical workflows and step-by-step guidance.
148
+ Output only the raw markdown content, no code fences.`
149
+ },
150
+ { role: "user", content: prompt }
151
+ ],
152
+ maxTokens: 1500
153
+ });
154
+ content = completion.content.trim();
155
+ } catch (error) {
156
+ console.error(_chalk2.default.red(`Failed to generate skill: ${error.message}`));
157
+ return null;
158
+ }
159
+ console.log();
160
+ console.log(_chalk2.default.bold("Preview:"));
161
+ console.log(_chalk2.default.gray("\u2500".repeat(50)));
162
+ console.log(content.length > 800 ? content.slice(0, 800) + "\n...(truncated)" : content);
163
+ console.log(_chalk2.default.gray("\u2500".repeat(50)));
164
+ console.log();
165
+ const { confirm } = await _enquirer2.default.prompt({
166
+ type: "confirm",
167
+ name: "confirm",
168
+ message: "Save this skill?",
169
+ initial: true
170
+ });
171
+ if (!confirm) {
172
+ console.log(_chalk2.default.gray("Canceled."));
173
+ return null;
174
+ }
175
+ const skillDir = _path2.default.join(_chunkIHJDYAYJcjs.AUTOHAND_PATHS.skills, name);
176
+ const skillPath = _path2.default.join(skillDir, "SKILL.md");
177
+ try {
178
+ await _fsextra2.default.ensureDir(skillDir);
179
+ await _fsextra2.default.writeFile(skillPath, content + "\n", "utf8");
180
+ console.log(_chalk2.default.green(`\u2713 Saved new skill to ${skillPath}`));
181
+ const success = await skillsRegistry.saveSkill(name, content);
182
+ if (success) {
183
+ const { activate } = await _enquirer2.default.prompt({
184
+ type: "confirm",
185
+ name: "activate",
186
+ message: "Activate this skill now?",
187
+ initial: true
188
+ });
189
+ if (activate) {
190
+ skillsRegistry.activateSkill(name);
191
+ console.log(_chalk2.default.green(`\u2713 Skill "${name}" is now active.`));
192
+ }
193
+ }
194
+ } catch (error) {
195
+ console.error(_chalk2.default.red(`Failed to save skill: ${error.message}`));
196
+ return null;
197
+ }
198
+ return `Created new skill: ${name}`;
199
+ }
200
+ function buildPrompt(name, description) {
201
+ return `Create a SKILL.md file for a skill named "${name}".
202
+
203
+ Description: ${description}
204
+
205
+ The file must have:
206
+ 1. YAML frontmatter with:
207
+ - name: ${name}
208
+ - description: A clear one-line description (max 100 chars)
209
+ - Optional: license, compatibility, allowed-tools
210
+
211
+ 2. Markdown body with:
212
+ - A heading with the skill name
213
+ - Clear purpose statement
214
+ - Step-by-step workflow or instructions
215
+ - Best practices or tips
216
+ - Example usage if applicable
217
+
218
+ Make the instructions practical and actionable for an AI coding agent.
219
+ Keep the total content concise but complete (200-400 words in body).
220
+
221
+ Output format:
222
+ ---
223
+ name: ${name}
224
+ description: <description here>
225
+ ---
226
+
227
+ # <Title>
228
+
229
+ <body content here>`;
230
+ }
231
+
232
+
233
+
234
+
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
+ */
246
+ /**
247
+ * @license
248
+ * Copyright 2025 Autohand AI LLC
249
+ * SPDX-License-Identifier: Apache-2.0
250
+ *
251
+ * Skills new command - Generate a new skill from description using LLM
252
+ */
@@ -1,12 +1,12 @@
1
- import {
2
- AUTOHAND_PATHS
3
- } from "./chunk-7FMMKTRG.js";
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
2
+
3
+ var _chunkIHJDYAYJcjs = require('./chunk-IHJDYAYJ.cjs');
4
4
 
5
5
  // src/commands/agents-new.ts
6
- import path from "path";
7
- import fs from "fs-extra";
8
- import chalk from "chalk";
9
- import enquirer from "enquirer";
6
+ var _path = require('path'); var _path2 = _interopRequireDefault(_path);
7
+ var _fsextra = require('fs-extra'); var _fsextra2 = _interopRequireDefault(_fsextra);
8
+ var _chalk = require('chalk'); var _chalk2 = _interopRequireDefault(_chalk);
9
+ var _enquirer = require('enquirer'); var _enquirer2 = _interopRequireDefault(_enquirer);
10
10
  var metadata = {
11
11
  command: "/agents new",
12
12
  description: "create a new sub-agent from a description",
@@ -14,7 +14,7 @@ var metadata = {
14
14
  prd: "prd/sub_agents_architecture.md"
15
15
  };
16
16
  async function createAgent(ctx) {
17
- const answers = await enquirer.prompt([
17
+ const answers = await _enquirer2.default.prompt([
18
18
  {
19
19
  type: "input",
20
20
  name: "name",
@@ -30,11 +30,11 @@ async function createAgent(ctx) {
30
30
  const name = answers.name.trim();
31
31
  const description = answers.description.trim();
32
32
  if (!name) {
33
- console.log(chalk.gray("Canceled: no name provided."));
33
+ console.log(_chalk2.default.gray("Canceled: no name provided."));
34
34
  return null;
35
35
  }
36
36
  const filename = await ensureUniqueFilename(name);
37
- const filePath = path.join(getAgentsDir(), filename);
37
+ const filePath = _path2.default.join(getAgentsDir(), filename);
38
38
  const prompt = buildPrompt(name, description);
39
39
  let content;
40
40
  try {
@@ -50,15 +50,15 @@ async function createAgent(ctx) {
50
50
  });
51
51
  content = completion.content.trim();
52
52
  } catch (error) {
53
- console.error(chalk.red(`Failed to generate agent: ${error.message}`));
53
+ console.error(_chalk2.default.red(`Failed to generate agent: ${error.message}`));
54
54
  return null;
55
55
  }
56
56
  try {
57
- await fs.ensureDir(getAgentsDir());
58
- await fs.writeFile(filePath, content + "\n", "utf8");
59
- console.log(chalk.green(`Saved new agent to ${filePath}`));
57
+ await _fsextra2.default.ensureDir(getAgentsDir());
58
+ await _fsextra2.default.writeFile(filePath, content + "\n", "utf8");
59
+ console.log(_chalk2.default.green(`Saved new agent to ${filePath}`));
60
60
  } catch (error) {
61
- console.error(chalk.red(`Failed to save agent: ${error.message}`));
61
+ console.error(_chalk2.default.red(`Failed to save agent: ${error.message}`));
62
62
  return null;
63
63
  }
64
64
  return null;
@@ -77,7 +77,7 @@ function buildPrompt(name, description) {
77
77
  ].filter(Boolean).join("\n");
78
78
  }
79
79
  function getAgentsDir() {
80
- return AUTOHAND_PATHS.agents;
80
+ return _chunkIHJDYAYJcjs.AUTOHAND_PATHS.agents;
81
81
  }
82
82
  function slugify(input) {
83
83
  return input.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "agent";
@@ -87,17 +87,17 @@ async function ensureUniqueFilename(name) {
87
87
  const dir = getAgentsDir();
88
88
  let candidate = `${base}.md`;
89
89
  let counter = 1;
90
- while (await fs.pathExists(path.join(dir, candidate))) {
90
+ while (await _fsextra2.default.pathExists(_path2.default.join(dir, candidate))) {
91
91
  candidate = `${base}-${counter}.md`;
92
92
  counter += 1;
93
93
  }
94
94
  return candidate;
95
95
  }
96
96
 
97
- export {
98
- metadata,
99
- createAgent
100
- };
97
+
98
+
99
+
100
+ exports.metadata = metadata; exports.createAgent = createAgent;
101
101
  /**
102
102
  * @license
103
103
  * Copyright 2025 Autohand AI LLC
@@ -1,15 +1,15 @@
1
- // src/commands/new.ts
2
- import chalk from "chalk";
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }// src/commands/new.ts
2
+ var _chalk = require('chalk'); var _chalk2 = _interopRequireDefault(_chalk);
3
3
  async function newConversation(ctx) {
4
4
  const currentSession = ctx.sessionManager.getCurrentSession();
5
5
  if (currentSession) {
6
6
  await ctx.sessionManager.closeSession("Session ended - new conversation started");
7
7
  }
8
- ctx.resetConversation();
8
+ await ctx.resetConversation();
9
9
  await ctx.sessionManager.createSession(ctx.workspaceRoot, ctx.model);
10
10
  console.log();
11
- console.log(chalk.cyan("New conversation started."));
12
- console.log(chalk.gray("Previous session saved. Ready for new instructions."));
11
+ console.log(_chalk2.default.cyan("New conversation started."));
12
+ console.log(_chalk2.default.gray("Previous session saved. Ready for new instructions."));
13
13
  console.log();
14
14
  return null;
15
15
  }
@@ -19,10 +19,10 @@ var metadata = {
19
19
  implemented: true
20
20
  };
21
21
 
22
- export {
23
- newConversation,
24
- metadata
25
- };
22
+
23
+
24
+
25
+ exports.newConversation = newConversation; exports.metadata = metadata;
26
26
  /**
27
27
  * @license
28
28
  * Copyright 2025 Autohand AI LLC
@@ -5,7 +5,8 @@ import readline from "readline";
5
5
  // package.json
6
6
  var package_default = {
7
7
  name: "autohand-cli",
8
- version: "0.6.2",
8
+ version: "0.6.4",
9
+ licenses: "SEE LICENSE IN LICENSE",
9
10
  description: "Autohand interactive coding agent CLI powered by LLMs.",
10
11
  type: "module",
11
12
  bin: {
@@ -17,17 +18,17 @@ var package_default = {
17
18
  ],
18
19
  scripts: {
19
20
  go: 'bun run build && ./install-local.sh && echo "COMPLETED"',
20
- build: "tsup src/index.ts --format esm,cjs --dts",
21
- dev: "tsx src/index.ts",
21
+ build: "tsup",
22
+ dev: "bun src/index.ts",
22
23
  typecheck: "tsc --noEmit",
23
24
  lint: "eslint .",
24
25
  test: "vitest run",
25
26
  start: "node dist/index.js",
26
- "compile:macos-arm64": "bun build ./src/index.ts --compile --target=bun-darwin-arm64 --outfile ./binaries/autohand-macos-arm64",
27
- "compile:macos-x64": "bun build ./src/index.ts --compile --target=bun-darwin-x64 --outfile ./binaries/autohand-macos-x64",
28
- "compile:linux-x64": "bun build ./src/index.ts --compile --target=bun-linux-x64 --outfile ./binaries/autohand-linux-x64",
29
- "compile:linux-arm64": "bun build ./src/index.ts --compile --target=bun-linux-arm64 --outfile ./binaries/autohand-linux-arm64",
30
- "compile:windows-x64": "bun build ./src/index.ts --compile --target=bun-windows-x64 --outfile ./binaries/autohand-windows-x64.exe",
27
+ "compile:macos-arm64": "bun build ./src/index.ts --compile --target=bun-darwin-arm64 --external react-devtools-core --outfile ./binaries/autohand-macos-arm64",
28
+ "compile:macos-x64": "bun build ./src/index.ts --compile --target=bun-darwin-x64 --external react-devtools-core --outfile ./binaries/autohand-macos-x64",
29
+ "compile:linux-x64": "bun build ./src/index.ts --compile --target=bun-linux-x64 --external react-devtools-core --outfile ./binaries/autohand-linux-x64",
30
+ "compile:linux-arm64": "bun build ./src/index.ts --compile --target=bun-linux-arm64 --external react-devtools-core --outfile ./binaries/autohand-linux-arm64",
31
+ "compile:windows-x64": "bun build ./src/index.ts --compile --target=bun-windows-x64 --external react-devtools-core --outfile ./binaries/autohand-windows-x64.exe",
31
32
  "compile:all": "bun run compile:macos-arm64 && bun run compile:macos-x64 && bun run compile:linux-x64 && bun run compile:linux-arm64 && bun run compile:windows-x64",
32
33
  link: "bun link"
33
34
  },
@@ -49,6 +50,7 @@ var package_default = {
49
50
  "fs-extra": "^11.3.2",
50
51
  ignore: "^5.3.1",
51
52
  ink: "^4.4.1",
53
+ "ink-spinner": "^5.0.0",
52
54
  open: "^10.1.0",
53
55
  ora: "^9.0.0",
54
56
  react: "^18.2.0",
@@ -0,0 +1,104 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }// src/commands/permissions.ts
2
+ var _chalk = require('chalk'); var _chalk2 = _interopRequireDefault(_chalk);
3
+ var _enquirer = require('enquirer'); var _enquirer2 = _interopRequireDefault(_enquirer);
4
+ async function permissions(ctx) {
5
+ const whitelist = ctx.permissionManager.getWhitelist();
6
+ const blacklist = ctx.permissionManager.getBlacklist();
7
+ const settings = ctx.permissionManager.getSettings();
8
+ console.log();
9
+ console.log(_chalk2.default.bold.cyan("Permissions"));
10
+ console.log(_chalk2.default.gray("\u2500".repeat(50)));
11
+ console.log(_chalk2.default.gray(`Mode: ${settings.mode || "interactive"}`));
12
+ console.log();
13
+ if (whitelist.length === 0 && blacklist.length === 0) {
14
+ console.log(_chalk2.default.gray("No saved permissions yet."));
15
+ console.log();
16
+ console.log(_chalk2.default.gray("When you approve or deny a tool/command, it will be saved here."));
17
+ console.log(_chalk2.default.gray("Approved items are auto-allowed; denied items are auto-blocked."));
18
+ return null;
19
+ }
20
+ if (whitelist.length > 0) {
21
+ console.log(_chalk2.default.bold.green("Approved (Whitelist)"));
22
+ console.log();
23
+ whitelist.forEach((pattern, index) => {
24
+ console.log(_chalk2.default.green(` ${index + 1}. ${pattern}`));
25
+ });
26
+ console.log();
27
+ }
28
+ if (blacklist.length > 0) {
29
+ console.log(_chalk2.default.bold.red("Denied (Blacklist)"));
30
+ console.log();
31
+ blacklist.forEach((pattern, index) => {
32
+ console.log(_chalk2.default.red(` ${index + 1}. ${pattern}`));
33
+ });
34
+ console.log();
35
+ }
36
+ console.log(_chalk2.default.gray("\u2500".repeat(50)));
37
+ console.log(_chalk2.default.gray(`Total: ${whitelist.length} approved, ${blacklist.length} denied`));
38
+ console.log();
39
+ const { action } = await _enquirer2.default.prompt({
40
+ type: "select",
41
+ name: "action",
42
+ message: "What would you like to do?",
43
+ choices: [
44
+ { name: "done", message: "Done" },
45
+ { name: "remove_approved", message: "Remove an approved item" },
46
+ { name: "remove_denied", message: "Remove a denied item" },
47
+ { name: "clear_all", message: "Clear all permissions" }
48
+ ]
49
+ });
50
+ if (action === "done") {
51
+ return null;
52
+ }
53
+ if (action === "remove_approved" && whitelist.length > 0) {
54
+ const { pattern } = await _enquirer2.default.prompt({
55
+ type: "select",
56
+ name: "pattern",
57
+ message: "Select item to remove from approved list:",
58
+ choices: whitelist.map((p) => ({ name: p, message: p }))
59
+ });
60
+ await ctx.permissionManager.removeFromWhitelist(pattern);
61
+ console.log(_chalk2.default.yellow(`Removed "${pattern}" from approved list.`));
62
+ } else if (action === "remove_denied" && blacklist.length > 0) {
63
+ const { pattern } = await _enquirer2.default.prompt({
64
+ type: "select",
65
+ name: "pattern",
66
+ message: "Select item to remove from denied list:",
67
+ choices: blacklist.map((p) => ({ name: p, message: p }))
68
+ });
69
+ await ctx.permissionManager.removeFromBlacklist(pattern);
70
+ console.log(_chalk2.default.yellow(`Removed "${pattern}" from denied list.`));
71
+ } else if (action === "clear_all") {
72
+ const { confirm } = await _enquirer2.default.prompt({
73
+ type: "confirm",
74
+ name: "confirm",
75
+ message: "Clear all saved permissions? This cannot be undone.",
76
+ initial: false
77
+ });
78
+ if (confirm) {
79
+ for (const pattern of [...whitelist]) {
80
+ await ctx.permissionManager.removeFromWhitelist(pattern);
81
+ }
82
+ for (const pattern of [...blacklist]) {
83
+ await ctx.permissionManager.removeFromBlacklist(pattern);
84
+ }
85
+ console.log(_chalk2.default.yellow("All permissions cleared."));
86
+ }
87
+ }
88
+ return null;
89
+ }
90
+ var metadata = {
91
+ command: "/permissions",
92
+ description: "view and manage tool/command approvals",
93
+ implemented: true
94
+ };
95
+
96
+
97
+
98
+
99
+ exports.permissions = permissions; exports.metadata = metadata;
100
+ /**
101
+ * @license
102
+ * Copyright 2025 Autohand AI LLC
103
+ * SPDX-License-Identifier: Apache-2.0
104
+ */
@@ -0,0 +1,93 @@
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
+
3
+
4
+
5
+
6
+
7
+
8
+ var _chunkQCMC2WOCcjs = require('./chunk-QCMC2WOC.cjs');
9
+
10
+ // src/commands/theme.ts
11
+ var _chalk = require('chalk'); var _chalk2 = _interopRequireDefault(_chalk);
12
+ var _enquirer = require('enquirer'); var _enquirer2 = _interopRequireDefault(_enquirer);
13
+ async function theme(ctx) {
14
+ const { Select } = _enquirer2.default;
15
+ const themes = _chunkQCMC2WOCcjs.listAvailableThemes.call(void 0, );
16
+ const currentTheme = _chunkQCMC2WOCcjs.isThemeInitialized.call(void 0, ) ? _chunkQCMC2WOCcjs.getTheme.call(void 0, ).name : _optionalChain([ctx, 'access', _ => _.config, 'access', _2 => _2.ui, 'optionalAccess', _3 => _3.theme]) || "dark";
17
+ console.log(_chalk2.default.cyan("\n\u{1F3A8} Theme Selection\n"));
18
+ console.log(_chalk2.default.gray(`Current theme: ${_chalk2.default.white(currentTheme)}`));
19
+ console.log(_chalk2.default.gray(`Custom themes location: ${_chunkQCMC2WOCcjs.CUSTOM_THEMES_DIR}
20
+ `));
21
+ const choices = themes.map((name) => ({
22
+ name,
23
+ message: name === currentTheme ? `${name} (current)` : name,
24
+ hint: name === "dark" ? "Default dark theme" : name === "light" ? "Light theme" : "Custom theme"
25
+ }));
26
+ try {
27
+ const prompt = new Select({
28
+ name: "theme",
29
+ message: "Select a theme:",
30
+ choices,
31
+ initial: themes.indexOf(currentTheme)
32
+ });
33
+ const selected = await prompt.run();
34
+ if (selected === currentTheme) {
35
+ console.log(_chalk2.default.gray("\nNo change made."));
36
+ return null;
37
+ }
38
+ _chunkQCMC2WOCcjs.initTheme.call(void 0, selected);
39
+ ctx.config.ui = { ...ctx.config.ui, theme: selected };
40
+ await _chunkQCMC2WOCcjs.saveConfig.call(void 0, ctx.config);
41
+ console.log(_chalk2.default.green(`
42
+ \u2713 Theme changed to '${selected}'`));
43
+ const newTheme = _chunkQCMC2WOCcjs.getTheme.call(void 0, );
44
+ console.log("\nTheme preview:");
45
+ console.log(` ${newTheme.fg("accent", "\u25CF accent")} ${newTheme.fg("success", "\u25CF success")} ${newTheme.fg("error", "\u25CF error")} ${newTheme.fg("warning", "\u25CF warning")}`);
46
+ console.log(` ${newTheme.fg("muted", "\u25CF muted")} ${newTheme.fg("dim", "\u25CF dim")} ${newTheme.fg("text", "\u25CF text")}`);
47
+ console.log();
48
+ return null;
49
+ } catch (e) {
50
+ console.log(_chalk2.default.gray("\nTheme selection cancelled."));
51
+ return null;
52
+ }
53
+ }
54
+ async function themeInfo() {
55
+ if (!_chunkQCMC2WOCcjs.isThemeInitialized.call(void 0, )) {
56
+ console.log(_chalk2.default.yellow("Theme not initialized."));
57
+ return null;
58
+ }
59
+ const currentTheme = _chunkQCMC2WOCcjs.getTheme.call(void 0, );
60
+ console.log(_chalk2.default.cyan("\n\u{1F3A8} Current Theme Info\n"));
61
+ console.log(_chalk2.default.gray(`Name: ${_chalk2.default.white(currentTheme.name)}`));
62
+ console.log(_chalk2.default.gray(`Color mode: ${_chalk2.default.white(currentTheme.getColorMode())}`));
63
+ console.log(_chalk2.default.gray(`Custom themes dir: ${_chunkQCMC2WOCcjs.CUSTOM_THEMES_DIR}`));
64
+ console.log();
65
+ console.log("Color preview:");
66
+ console.log(` ${currentTheme.fg("accent", "\u25CF accent")} ${currentTheme.fg("success", "\u25CF success")} ${currentTheme.fg("error", "\u25CF error")} ${currentTheme.fg("warning", "\u25CF warning")}`);
67
+ console.log(` ${currentTheme.fg("muted", "\u25CF muted")} ${currentTheme.fg("dim", "\u25CF dim")} ${currentTheme.fg("text", "\u25CF text")}`);
68
+ console.log();
69
+ console.log("Syntax colors:");
70
+ console.log(` ${currentTheme.fg("syntaxKeyword", "keyword")} ${currentTheme.fg("syntaxString", '"string"')} ${currentTheme.fg("syntaxNumber", "42")} ${currentTheme.fg("syntaxComment", "// comment")}`);
71
+ console.log(` ${currentTheme.fg("syntaxFunction", "function")} ${currentTheme.fg("syntaxType", "Type")} ${currentTheme.fg("syntaxVariable", "variable")}`);
72
+ console.log();
73
+ console.log("Diff colors:");
74
+ console.log(` ${currentTheme.fg("diffAdded", "+ added")} ${currentTheme.fg("diffRemoved", "- removed")} ${currentTheme.fg("diffContext", " context")}`);
75
+ console.log();
76
+ return null;
77
+ }
78
+ var metadata = {
79
+ command: "/theme",
80
+ description: "change the color theme",
81
+ implemented: true
82
+ };
83
+
84
+
85
+
86
+
87
+
88
+ exports.theme = theme; exports.themeInfo = themeInfo; exports.metadata = metadata;
89
+ /**
90
+ * @license
91
+ * Copyright 2025 Autohand AI LLC
92
+ * SPDX-License-Identifier: Apache-2.0
93
+ */