@agentuity/cli 0.0.100 → 0.0.102

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 (264) hide show
  1. package/AGENTS.md +19 -188
  2. package/bin/cli.ts +13 -6
  3. package/dist/api.d.ts +1 -0
  4. package/dist/api.d.ts.map +1 -1
  5. package/dist/api.js +1 -1
  6. package/dist/api.js.map +1 -1
  7. package/dist/cli.d.ts.map +1 -1
  8. package/dist/cli.js +41 -12
  9. package/dist/cli.js.map +1 -1
  10. package/dist/cmd/ai/index.d.ts.map +1 -1
  11. package/dist/cmd/ai/index.js +6 -1
  12. package/dist/cmd/ai/index.js.map +1 -1
  13. package/dist/cmd/ai/prompt/agent.d.ts +7 -0
  14. package/dist/cmd/ai/prompt/agent.d.ts.map +1 -1
  15. package/dist/cmd/ai/prompt/agent.js +12 -323
  16. package/dist/cmd/ai/prompt/agent.js.map +1 -1
  17. package/dist/cmd/ai/prompt/api.d.ts +7 -0
  18. package/dist/cmd/ai/prompt/api.d.ts.map +1 -1
  19. package/dist/cmd/ai/prompt/api.js +12 -260
  20. package/dist/cmd/ai/prompt/api.js.map +1 -1
  21. package/dist/cmd/ai/prompt/version.d.ts +35 -0
  22. package/dist/cmd/ai/prompt/version.d.ts.map +1 -0
  23. package/dist/cmd/ai/prompt/version.js +55 -0
  24. package/dist/cmd/ai/prompt/version.js.map +1 -0
  25. package/dist/cmd/ai/prompt/web.d.ts +7 -0
  26. package/dist/cmd/ai/prompt/web.d.ts.map +1 -1
  27. package/dist/cmd/ai/prompt/web.js +12 -283
  28. package/dist/cmd/ai/prompt/web.js.map +1 -1
  29. package/dist/cmd/ai/skills/generate.d.ts +3 -0
  30. package/dist/cmd/ai/skills/generate.d.ts.map +1 -0
  31. package/dist/cmd/ai/skills/generate.js +65 -0
  32. package/dist/cmd/ai/skills/generate.js.map +1 -0
  33. package/dist/cmd/ai/skills/generator.d.ts +4 -0
  34. package/dist/cmd/ai/skills/generator.d.ts.map +1 -0
  35. package/dist/cmd/ai/skills/generator.js +402 -0
  36. package/dist/cmd/ai/skills/generator.js.map +1 -0
  37. package/dist/cmd/ai/skills/index.d.ts +4 -0
  38. package/dist/cmd/ai/skills/index.d.ts.map +1 -0
  39. package/dist/cmd/ai/skills/index.js +21 -0
  40. package/dist/cmd/ai/skills/index.js.map +1 -0
  41. package/dist/cmd/auth/signup.d.ts.map +1 -1
  42. package/dist/cmd/auth/signup.js +1 -0
  43. package/dist/cmd/auth/signup.js.map +1 -1
  44. package/dist/cmd/build/ast.d.ts +2 -1
  45. package/dist/cmd/build/ast.d.ts.map +1 -1
  46. package/dist/cmd/build/ast.js +135 -47
  47. package/dist/cmd/build/ast.js.map +1 -1
  48. package/dist/cmd/build/entry-generator.d.ts.map +1 -1
  49. package/dist/cmd/build/entry-generator.js +255 -188
  50. package/dist/cmd/build/entry-generator.js.map +1 -1
  51. package/dist/cmd/build/vite/agent-discovery.d.ts.map +1 -1
  52. package/dist/cmd/build/vite/agent-discovery.js +103 -45
  53. package/dist/cmd/build/vite/agent-discovery.js.map +1 -1
  54. package/dist/cmd/build/vite/bun-dev-server.d.ts +7 -1
  55. package/dist/cmd/build/vite/bun-dev-server.d.ts.map +1 -1
  56. package/dist/cmd/build/vite/bun-dev-server.js +52 -26
  57. package/dist/cmd/build/vite/bun-dev-server.js.map +1 -1
  58. package/dist/cmd/build/vite/docs-generator.d.ts +13 -0
  59. package/dist/cmd/build/vite/docs-generator.d.ts.map +1 -0
  60. package/dist/cmd/build/vite/docs-generator.js +81 -0
  61. package/dist/cmd/build/vite/docs-generator.js.map +1 -0
  62. package/dist/cmd/build/vite/index.d.ts +3 -3
  63. package/dist/cmd/build/vite/index.d.ts.map +1 -1
  64. package/dist/cmd/build/vite/index.js +9 -7
  65. package/dist/cmd/build/vite/index.js.map +1 -1
  66. package/dist/cmd/build/vite/lifecycle-generator.d.ts +1 -1
  67. package/dist/cmd/build/vite/lifecycle-generator.d.ts.map +1 -1
  68. package/dist/cmd/build/vite/lifecycle-generator.js +19 -5
  69. package/dist/cmd/build/vite/lifecycle-generator.js.map +1 -1
  70. package/dist/cmd/build/vite/metadata-generator.d.ts.map +1 -1
  71. package/dist/cmd/build/vite/metadata-generator.js +203 -7
  72. package/dist/cmd/build/vite/metadata-generator.js.map +1 -1
  73. package/dist/cmd/build/vite/prompt-generator.d.ts +23 -0
  74. package/dist/cmd/build/vite/prompt-generator.d.ts.map +1 -0
  75. package/dist/cmd/build/vite/prompt-generator.js +123 -0
  76. package/dist/cmd/build/vite/prompt-generator.js.map +1 -0
  77. package/dist/cmd/build/vite/registry-generator.d.ts +3 -3
  78. package/dist/cmd/build/vite/registry-generator.d.ts.map +1 -1
  79. package/dist/cmd/build/vite/registry-generator.js +644 -103
  80. package/dist/cmd/build/vite/registry-generator.js.map +1 -1
  81. package/dist/cmd/build/vite/route-discovery.d.ts +4 -0
  82. package/dist/cmd/build/vite/route-discovery.d.ts.map +1 -1
  83. package/dist/cmd/build/vite/route-discovery.js.map +1 -1
  84. package/dist/cmd/build/vite/server-bundler.d.ts +4 -0
  85. package/dist/cmd/build/vite/server-bundler.d.ts.map +1 -1
  86. package/dist/cmd/build/vite/server-bundler.js +63 -17
  87. package/dist/cmd/build/vite/server-bundler.js.map +1 -1
  88. package/dist/cmd/build/vite/vite-asset-server-config.d.ts.map +1 -1
  89. package/dist/cmd/build/vite/vite-asset-server-config.js +4 -0
  90. package/dist/cmd/build/vite/vite-asset-server-config.js.map +1 -1
  91. package/dist/cmd/build/vite/vite-builder.d.ts +1 -1
  92. package/dist/cmd/build/vite/vite-builder.d.ts.map +1 -1
  93. package/dist/cmd/build/vite/vite-builder.js +118 -96
  94. package/dist/cmd/build/vite/vite-builder.js.map +1 -1
  95. package/dist/cmd/build/vite-bundler.js +6 -6
  96. package/dist/cmd/build/vite-bundler.js.map +1 -1
  97. package/dist/cmd/cloud/deploy.d.ts.map +1 -1
  98. package/dist/cmd/cloud/deploy.js +89 -32
  99. package/dist/cmd/cloud/deploy.js.map +1 -1
  100. package/dist/cmd/cloud/keyvalue/create-namespace.d.ts.map +1 -1
  101. package/dist/cmd/cloud/keyvalue/create-namespace.js +3 -1
  102. package/dist/cmd/cloud/keyvalue/create-namespace.js.map +1 -1
  103. package/dist/cmd/cloud/keyvalue/delete-namespace.d.ts.map +1 -1
  104. package/dist/cmd/cloud/keyvalue/delete-namespace.js +3 -1
  105. package/dist/cmd/cloud/keyvalue/delete-namespace.js.map +1 -1
  106. package/dist/cmd/cloud/keyvalue/delete.d.ts.map +1 -1
  107. package/dist/cmd/cloud/keyvalue/delete.js +3 -1
  108. package/dist/cmd/cloud/keyvalue/delete.js.map +1 -1
  109. package/dist/cmd/cloud/keyvalue/set.d.ts.map +1 -1
  110. package/dist/cmd/cloud/keyvalue/set.js +4 -2
  111. package/dist/cmd/cloud/keyvalue/set.js.map +1 -1
  112. package/dist/cmd/cloud/stream/get.d.ts.map +1 -1
  113. package/dist/cmd/cloud/stream/get.js +2 -13
  114. package/dist/cmd/cloud/stream/get.js.map +1 -1
  115. package/dist/cmd/cloud/vector/delete-namespace.d.ts +3 -0
  116. package/dist/cmd/cloud/vector/delete-namespace.d.ts.map +1 -0
  117. package/dist/cmd/cloud/vector/delete-namespace.js +77 -0
  118. package/dist/cmd/cloud/vector/delete-namespace.js.map +1 -0
  119. package/dist/cmd/cloud/vector/index.d.ts.map +1 -1
  120. package/dist/cmd/cloud/vector/index.js +21 -4
  121. package/dist/cmd/cloud/vector/index.js.map +1 -1
  122. package/dist/cmd/cloud/vector/list-namespaces.d.ts +3 -0
  123. package/dist/cmd/cloud/vector/list-namespaces.d.ts.map +1 -0
  124. package/dist/cmd/cloud/vector/list-namespaces.js +42 -0
  125. package/dist/cmd/cloud/vector/list-namespaces.js.map +1 -0
  126. package/dist/cmd/cloud/vector/stats.d.ts +3 -0
  127. package/dist/cmd/cloud/vector/stats.d.ts.map +1 -0
  128. package/dist/cmd/cloud/vector/stats.js +142 -0
  129. package/dist/cmd/cloud/vector/stats.js.map +1 -0
  130. package/dist/cmd/cloud/vector/upsert.d.ts +3 -0
  131. package/dist/cmd/cloud/vector/upsert.d.ts.map +1 -0
  132. package/dist/cmd/cloud/vector/upsert.js +192 -0
  133. package/dist/cmd/cloud/vector/upsert.js.map +1 -0
  134. package/dist/cmd/dev/file-watcher.d.ts.map +1 -1
  135. package/dist/cmd/dev/file-watcher.js +94 -33
  136. package/dist/cmd/dev/file-watcher.js.map +1 -1
  137. package/dist/cmd/dev/index.d.ts.map +1 -1
  138. package/dist/cmd/dev/index.js +298 -61
  139. package/dist/cmd/dev/index.js.map +1 -1
  140. package/dist/cmd/dev/skills.d.ts +10 -0
  141. package/dist/cmd/dev/skills.d.ts.map +1 -0
  142. package/dist/cmd/dev/skills.js +57 -0
  143. package/dist/cmd/dev/skills.js.map +1 -0
  144. package/dist/cmd/dev/sync.d.ts.map +1 -1
  145. package/dist/cmd/dev/sync.js +19 -3
  146. package/dist/cmd/dev/sync.js.map +1 -1
  147. package/dist/cmd/index.d.ts.map +1 -1
  148. package/dist/cmd/index.js +1 -0
  149. package/dist/cmd/index.js.map +1 -1
  150. package/dist/cmd/project/create.d.ts.map +1 -1
  151. package/dist/cmd/project/create.js +3 -0
  152. package/dist/cmd/project/create.js.map +1 -1
  153. package/dist/cmd/project/template-flow.d.ts +1 -0
  154. package/dist/cmd/project/template-flow.d.ts.map +1 -1
  155. package/dist/cmd/project/template-flow.js +30 -5
  156. package/dist/cmd/project/template-flow.js.map +1 -1
  157. package/dist/cmd/setup/index.d.ts.map +1 -1
  158. package/dist/cmd/setup/index.js +1 -0
  159. package/dist/cmd/setup/index.js.map +1 -1
  160. package/dist/cmd/upgrade/index.d.ts +15 -0
  161. package/dist/cmd/upgrade/index.d.ts.map +1 -1
  162. package/dist/cmd/upgrade/index.js +59 -4
  163. package/dist/cmd/upgrade/index.js.map +1 -1
  164. package/dist/config.d.ts.map +1 -1
  165. package/dist/config.js +8 -0
  166. package/dist/config.js.map +1 -1
  167. package/dist/domain.d.ts +45 -0
  168. package/dist/domain.d.ts.map +1 -0
  169. package/dist/domain.js +200 -0
  170. package/dist/domain.js.map +1 -0
  171. package/dist/index.d.ts +0 -1
  172. package/dist/index.d.ts.map +1 -1
  173. package/dist/index.js +0 -1
  174. package/dist/index.js.map +1 -1
  175. package/dist/schema-generator.d.ts +2 -0
  176. package/dist/schema-generator.d.ts.map +1 -1
  177. package/dist/schema-generator.js +18 -0
  178. package/dist/schema-generator.js.map +1 -1
  179. package/dist/steps.d.ts +1 -1
  180. package/dist/steps.d.ts.map +1 -1
  181. package/dist/steps.js +16 -5
  182. package/dist/steps.js.map +1 -1
  183. package/dist/tui/prompt.d.ts +1 -2
  184. package/dist/tui/prompt.d.ts.map +1 -1
  185. package/dist/tui/prompt.js +8 -4
  186. package/dist/tui/prompt.js.map +1 -1
  187. package/dist/tui.d.ts +16 -0
  188. package/dist/tui.d.ts.map +1 -1
  189. package/dist/tui.js +23 -2
  190. package/dist/tui.js.map +1 -1
  191. package/dist/types.d.ts +9 -2
  192. package/dist/types.d.ts.map +1 -1
  193. package/dist/types.js +3 -3
  194. package/dist/types.js.map +1 -1
  195. package/package.json +5 -8
  196. package/src/api.ts +1 -1
  197. package/src/cli.ts +47 -12
  198. package/src/cmd/ai/index.ts +6 -1
  199. package/src/cmd/ai/prompt/agent.md +306 -0
  200. package/src/cmd/ai/prompt/agent.ts +12 -322
  201. package/src/cmd/ai/prompt/api.md +360 -0
  202. package/src/cmd/ai/prompt/api.ts +13 -260
  203. package/src/cmd/ai/prompt/version.ts +61 -0
  204. package/src/cmd/ai/prompt/web.md +509 -0
  205. package/src/cmd/ai/prompt/web.ts +12 -282
  206. package/src/cmd/ai/skills/generate.ts +75 -0
  207. package/src/cmd/ai/skills/generator.ts +519 -0
  208. package/src/cmd/ai/skills/index.ts +23 -0
  209. package/src/cmd/auth/signup.ts +1 -0
  210. package/src/cmd/build/ast.ts +161 -48
  211. package/src/cmd/build/entry-generator.ts +258 -187
  212. package/src/cmd/build/vite/agent-discovery.ts +151 -58
  213. package/src/cmd/build/vite/bun-dev-server.ts +57 -27
  214. package/src/cmd/build/vite/docs-generator.ts +87 -0
  215. package/src/cmd/build/vite/index.ts +9 -7
  216. package/src/cmd/build/vite/lifecycle-generator.ts +19 -5
  217. package/src/cmd/build/vite/metadata-generator.ts +251 -7
  218. package/src/cmd/build/vite/prompt-generator.ts +169 -0
  219. package/src/cmd/build/vite/registry-generator.ts +750 -108
  220. package/src/cmd/build/vite/route-discovery.ts +4 -0
  221. package/src/cmd/build/vite/server-bundler.ts +73 -23
  222. package/src/cmd/build/vite/vite-asset-server-config.ts +5 -0
  223. package/src/cmd/build/vite/vite-builder.ts +134 -100
  224. package/src/cmd/build/vite-bundler.ts +6 -6
  225. package/src/cmd/cloud/deploy.ts +114 -36
  226. package/src/cmd/cloud/keyvalue/create-namespace.ts +3 -1
  227. package/src/cmd/cloud/keyvalue/delete-namespace.ts +3 -1
  228. package/src/cmd/cloud/keyvalue/delete.ts +3 -1
  229. package/src/cmd/cloud/keyvalue/set.ts +4 -2
  230. package/src/cmd/cloud/stream/get.ts +2 -9
  231. package/src/cmd/cloud/vector/delete-namespace.ts +89 -0
  232. package/src/cmd/cloud/vector/index.ts +21 -4
  233. package/src/cmd/cloud/vector/list-namespaces.ts +46 -0
  234. package/src/cmd/cloud/vector/stats.ts +160 -0
  235. package/src/cmd/cloud/vector/upsert.ts +216 -0
  236. package/src/cmd/dev/file-watcher.ts +109 -34
  237. package/src/cmd/dev/index.ts +364 -60
  238. package/src/cmd/dev/skills.ts +82 -0
  239. package/src/cmd/dev/sync.ts +41 -6
  240. package/src/cmd/index.ts +1 -0
  241. package/src/cmd/project/create.ts +3 -0
  242. package/src/cmd/project/template-flow.ts +37 -5
  243. package/src/cmd/setup/index.ts +1 -0
  244. package/src/cmd/upgrade/index.ts +68 -4
  245. package/src/config.ts +9 -0
  246. package/src/domain.ts +273 -0
  247. package/src/index.ts +0 -5
  248. package/src/runtime-bootstrap.md +1 -1
  249. package/src/schema-generator.ts +23 -0
  250. package/src/steps.ts +16 -5
  251. package/src/tui/prompt.ts +11 -5
  252. package/src/tui.ts +21 -2
  253. package/src/types/md.d.ts +8 -0
  254. package/src/types.ts +12 -3
  255. package/dist/cmd/cloud/domain.d.ts +0 -17
  256. package/dist/cmd/cloud/domain.d.ts.map +0 -1
  257. package/dist/cmd/cloud/domain.js +0 -79
  258. package/dist/cmd/cloud/domain.js.map +0 -1
  259. package/dist/runtime-bootstrap.d.ts +0 -56
  260. package/dist/runtime-bootstrap.d.ts.map +0 -1
  261. package/dist/runtime-bootstrap.js +0 -95
  262. package/dist/runtime-bootstrap.js.map +0 -1
  263. package/src/cmd/cloud/domain.ts +0 -100
  264. package/src/runtime-bootstrap.ts +0 -131
@@ -0,0 +1,519 @@
1
+ import type {
2
+ CLISchema,
3
+ SchemaCommand,
4
+ SchemaOption,
5
+ SchemaArgument,
6
+ } from '../../../schema-generator';
7
+ import * as path from 'node:path';
8
+
9
+ interface SkillInfo {
10
+ skillPath: string;
11
+ skillName: string;
12
+ command: SchemaCommand;
13
+ fullCommandPath: string[];
14
+ }
15
+
16
+ const EXCLUDED_COMMANDS = new Set(['ai', 'help', 'version']);
17
+
18
+ function isValidSkillName(name: string): boolean {
19
+ if (name.length < 1 || name.length > 64) return false;
20
+ if (!/^[a-z0-9-]+$/.test(name)) return false;
21
+ if (name.startsWith('-') || name.endsWith('-')) return false;
22
+ if (name.includes('--')) return false;
23
+ return true;
24
+ }
25
+
26
+ function toSkillName(parts: string[]): string {
27
+ return parts.join('-').toLowerCase();
28
+ }
29
+
30
+ function enhanceDescription(command: SchemaCommand, fullPath: string[]): string {
31
+ let description = command.description;
32
+
33
+ const context = getCommandContext(command, fullPath);
34
+ if (context) {
35
+ description = `${description}. ${context}`;
36
+ }
37
+
38
+ if (description.length > 1024) {
39
+ description = description.substring(0, 1021) + '...';
40
+ }
41
+
42
+ return description;
43
+ }
44
+
45
+ function getCommandContext(command: SchemaCommand, fullPath: string[]): string {
46
+ const parts: string[] = [];
47
+
48
+ if (command.requires?.auth) {
49
+ parts.push('Requires authentication');
50
+ }
51
+
52
+ if (fullPath.includes('cloud')) {
53
+ parts.push('Use for Agentuity cloud platform operations');
54
+ } else if (fullPath.includes('auth')) {
55
+ parts.push('Use for managing authentication credentials');
56
+ } else if (fullPath.includes('project')) {
57
+ parts.push('Use for project management operations');
58
+ }
59
+
60
+ return parts.join('. ');
61
+ }
62
+
63
+ function collectLeafCommands(
64
+ command: SchemaCommand,
65
+ parentPath: string[],
66
+ baseDir: string,
67
+ _isHidden: boolean
68
+ ): SkillInfo[] {
69
+ const skills: SkillInfo[] = [];
70
+ const currentPath = [...parentPath, command.name];
71
+
72
+ // Skip commands marked with skipSkill
73
+ if (command.skipSkill) {
74
+ return skills;
75
+ }
76
+
77
+ // Skip toplevel aliases (subcommands that have toplevel: true create duplicates)
78
+ if (command.toplevel && parentPath.length === 0) {
79
+ return skills;
80
+ }
81
+
82
+ if (command.subcommands && command.subcommands.length > 0) {
83
+ for (const sub of command.subcommands) {
84
+ skills.push(...collectLeafCommands(sub, currentPath, baseDir, _isHidden));
85
+ }
86
+ } else {
87
+ const skillName = `agentuity-cli-${toSkillName(currentPath)}`;
88
+
89
+ if (!isValidSkillName(skillName)) {
90
+ return skills;
91
+ }
92
+
93
+ const skillPath = path.join(baseDir, skillName, 'SKILL.md');
94
+
95
+ skills.push({
96
+ skillPath,
97
+ skillName,
98
+ command,
99
+ fullCommandPath: currentPath,
100
+ });
101
+ }
102
+
103
+ return skills;
104
+ }
105
+
106
+ function formatPrerequisites(command: SchemaCommand): string[] {
107
+ const prereqs: string[] = [];
108
+
109
+ if (command.requires?.auth) {
110
+ prereqs.push('Authenticated with `agentuity auth login`');
111
+ }
112
+
113
+ if (command.requires?.project) {
114
+ prereqs.push('Project context required (run from project directory or use `--project-id`)');
115
+ }
116
+
117
+ if (command.requires?.org) {
118
+ prereqs.push('Organization context required (`--org-id` or default org)');
119
+ }
120
+
121
+ if (command.prerequisites) {
122
+ prereqs.push(...command.prerequisites);
123
+ }
124
+
125
+ return prereqs;
126
+ }
127
+
128
+ function formatOptionsTable(options: SchemaOption[]): string {
129
+ if (options.length === 0) return '';
130
+
131
+ const lines: string[] = [
132
+ '| Option | Type | Required | Default | Description |',
133
+ '|--------|------|----------|---------|-------------|',
134
+ ];
135
+
136
+ for (const opt of options) {
137
+ const optName = `\`--${opt.name}\``;
138
+ const optType = opt.enum ? opt.enum.join(' \\| ') : opt.type;
139
+ const required = opt.required ? 'Yes' : 'No';
140
+ const defaultVal = opt.default !== undefined ? `\`${JSON.stringify(opt.default)}\`` : '-';
141
+ const desc = opt.description ?? '-';
142
+
143
+ lines.push(`| ${optName} | ${optType} | ${required} | ${defaultVal} | ${desc} |`);
144
+ }
145
+
146
+ return lines.join('\n');
147
+ }
148
+
149
+ function formatArgumentsTable(args: SchemaArgument[]): string {
150
+ if (args.length === 0) return '';
151
+
152
+ const lines: string[] = [
153
+ '| Argument | Type | Required | Description |',
154
+ '|----------|------|----------|-------------|',
155
+ ];
156
+
157
+ for (const arg of args) {
158
+ const argName = `\`<${arg.name}${arg.variadic ? '...' : ''}>\``;
159
+ const argType = arg.variadic ? 'array' : arg.type;
160
+ const required = arg.required ? 'Yes' : 'No';
161
+ const desc = arg.description ?? '-';
162
+
163
+ lines.push(`| ${argName} | ${argType} | ${required} | ${desc} |`);
164
+ }
165
+
166
+ return lines.join('\n');
167
+ }
168
+
169
+ function formatExamples(command: SchemaCommand): string {
170
+ if (!command.examples || command.examples.length === 0) {
171
+ return '';
172
+ }
173
+
174
+ const lines: string[] = [];
175
+
176
+ for (const example of command.examples) {
177
+ lines.push(`${example.description}:`);
178
+ lines.push('');
179
+ lines.push('```bash');
180
+ lines.push(example.command);
181
+ lines.push('```');
182
+ lines.push('');
183
+ }
184
+
185
+ return lines.join('\n').trim();
186
+ }
187
+
188
+ function formatResponse(command: SchemaCommand): string {
189
+ if (!command.response) {
190
+ return '';
191
+ }
192
+
193
+ const response = command.response as Record<string, unknown>;
194
+ const lines: string[] = [];
195
+
196
+ if (response.type === 'object' && response.properties) {
197
+ const props = response.properties as Record<string, { type?: string; description?: string }>;
198
+
199
+ lines.push('Returns JSON object:');
200
+ lines.push('');
201
+ lines.push('```json');
202
+ const sample: Record<string, string> = {};
203
+ for (const [key, val] of Object.entries(props)) {
204
+ sample[key] = val.type ?? 'unknown';
205
+ }
206
+ lines.push(JSON.stringify(sample, null, 2));
207
+ lines.push('```');
208
+ lines.push('');
209
+ lines.push('| Field | Type | Description |');
210
+ lines.push('|-------|------|-------------|');
211
+
212
+ for (const [key, val] of Object.entries(props)) {
213
+ lines.push(`| \`${key}\` | ${val.type ?? 'unknown'} | ${val.description ?? '-'} |`);
214
+ }
215
+ } else if (response.type) {
216
+ lines.push(`Returns: \`${response.type}\``);
217
+ }
218
+
219
+ return lines.join('\n');
220
+ }
221
+
222
+ function buildUsageString(command: SchemaCommand, fullPath: string[]): string {
223
+ const parts = ['agentuity', ...fullPath];
224
+
225
+ if (command.arguments) {
226
+ for (const arg of command.arguments) {
227
+ const argStr = arg.required
228
+ ? `<${arg.name}${arg.variadic ? '...' : ''}>`
229
+ : `[${arg.name}${arg.variadic ? '...' : ''}]`;
230
+ parts.push(argStr);
231
+ }
232
+ }
233
+
234
+ if (command.options && command.options.length > 0) {
235
+ parts.push('[options]');
236
+ }
237
+
238
+ return parts.join(' ');
239
+ }
240
+
241
+ function escapeYamlString(str: string): string {
242
+ // Check if string needs quoting:
243
+ // - Contains YAML special characters
244
+ // - Has leading/trailing whitespace
245
+ // - Looks like a boolean, null, or number
246
+ // - Contains control characters
247
+ const specialCharsRegex = /[:[\]{}#&*!|>'"%@`,?<>=~-]/;
248
+ // eslint-disable-next-line no-control-regex
249
+ const controlCharsRegex = new RegExp('[\\x00-\\x1f\\x7f]');
250
+ const needsQuoting =
251
+ specialCharsRegex.test(str) ||
252
+ controlCharsRegex.test(str) ||
253
+ str !== str.trim() ||
254
+ /^(true|false|yes|no|on|off|null|~)$/i.test(str) ||
255
+ /^-?(\d+\.?\d*|\.\d+)(e[+-]?\d+)?$/i.test(str) ||
256
+ str === '';
257
+
258
+ if (!needsQuoting) {
259
+ return str;
260
+ }
261
+
262
+ // Escape special characters for double-quoted YAML string
263
+ // eslint-disable-next-line no-control-regex
264
+ const nonPrintableRegex = new RegExp('[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]', 'g');
265
+ const escaped = str
266
+ .replace(/\\/g, '\\\\')
267
+ .replace(/"/g, '\\"')
268
+ .replace(/\n/g, '\\n')
269
+ .replace(/\r/g, '\\r')
270
+ .replace(/\t/g, '\\t')
271
+ .replace(nonPrintableRegex, (char) => {
272
+ const code = char.charCodeAt(0);
273
+ return `\\x${code.toString(16).padStart(2, '0')}`;
274
+ });
275
+
276
+ return `"${escaped}"`;
277
+ }
278
+
279
+ function buildArgumentHint(command: SchemaCommand): string | null {
280
+ if (!command.arguments || command.arguments.length === 0) {
281
+ return null;
282
+ }
283
+
284
+ const hints = command.arguments.map((arg) => {
285
+ const name = arg.variadic ? `${arg.name}...` : arg.name;
286
+ return arg.required ? `<${name}>` : `[${name}]`;
287
+ });
288
+
289
+ return hints.join(' ');
290
+ }
291
+
292
+ function generateSkillContent(skill: SkillInfo, version: string): string {
293
+ const { command, skillName, fullCommandPath } = skill;
294
+ const fullCommand = ['agentuity', ...fullCommandPath].join(' ');
295
+
296
+ const enhancedDescription = enhanceDescription(command, fullCommandPath);
297
+ const tags = command.tags?.join(' ') ?? '';
298
+ const argumentHint = buildArgumentHint(command);
299
+
300
+ const lines: string[] = [
301
+ '---',
302
+ `name: ${skillName}`,
303
+ `description: ${escapeYamlString(enhancedDescription)}`,
304
+ `version: "${version}"`,
305
+ 'license: Apache-2.0',
306
+ `allowed-tools: "Bash(agentuity:*)"`,
307
+ ];
308
+
309
+ if (argumentHint) {
310
+ lines.push(`argument-hint: "${argumentHint}"`);
311
+ }
312
+
313
+ lines.push('metadata:');
314
+ lines.push(` command: "${fullCommand}"`);
315
+
316
+ if (tags) {
317
+ lines.push(` tags: "${tags}"`);
318
+ }
319
+
320
+ lines.push('---');
321
+ lines.push('');
322
+
323
+ const title = fullCommandPath.map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join(' ');
324
+ lines.push(`# ${title}`);
325
+ lines.push('');
326
+ lines.push(command.description);
327
+ lines.push('');
328
+
329
+ const prerequisites = formatPrerequisites(command);
330
+ if (prerequisites.length > 0) {
331
+ lines.push('## Prerequisites');
332
+ lines.push('');
333
+ for (const prereq of prerequisites) {
334
+ lines.push(`- ${prereq}`);
335
+ }
336
+ lines.push('');
337
+ }
338
+
339
+ lines.push('## Usage');
340
+ lines.push('');
341
+ lines.push('```bash');
342
+ lines.push(buildUsageString(command, fullCommandPath));
343
+ lines.push('```');
344
+ lines.push('');
345
+
346
+ if (command.arguments && command.arguments.length > 0) {
347
+ lines.push('## Arguments');
348
+ lines.push('');
349
+ lines.push(formatArgumentsTable(command.arguments));
350
+ lines.push('');
351
+ }
352
+
353
+ if (command.options && command.options.length > 0) {
354
+ lines.push('## Options');
355
+ lines.push('');
356
+ lines.push(formatOptionsTable(command.options));
357
+ lines.push('');
358
+ }
359
+
360
+ const examples = formatExamples(command);
361
+ if (examples) {
362
+ lines.push('## Examples');
363
+ lines.push('');
364
+ lines.push(examples);
365
+ lines.push('');
366
+ }
367
+
368
+ const response = formatResponse(command);
369
+ if (response) {
370
+ lines.push('## Output');
371
+ lines.push('');
372
+ lines.push(response);
373
+ lines.push('');
374
+ }
375
+
376
+ return lines.join('\n');
377
+ }
378
+
379
+ function collectAllSkills(
380
+ schema: CLISchema,
381
+ outputDir: string,
382
+ includeHidden: boolean
383
+ ): SkillInfo[] {
384
+ const baseDir = path.join(outputDir, 'skills');
385
+ const allSkills: SkillInfo[] = [];
386
+
387
+ for (const command of schema.commands) {
388
+ if (EXCLUDED_COMMANDS.has(command.name)) {
389
+ continue;
390
+ }
391
+
392
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
393
+ const isHidden = (command as any).hidden === true;
394
+ if (isHidden && !includeHidden) {
395
+ continue;
396
+ }
397
+
398
+ const skills = collectLeafCommands(command, [], baseDir, isHidden);
399
+ allSkills.push(...skills);
400
+ }
401
+
402
+ return allSkills;
403
+ }
404
+
405
+ function generateReadme(version: string, skills: SkillInfo[]): string {
406
+ const groups = new Map<string, SkillInfo[]>();
407
+ for (const skill of skills) {
408
+ const group = skill.fullCommandPath[0];
409
+ if (!groups.has(group)) {
410
+ groups.set(group, []);
411
+ }
412
+ groups.get(group)!.push(skill);
413
+ }
414
+
415
+ const lines: string[] = [
416
+ '# Agentuity CLI Skills',
417
+ '',
418
+ 'This directory contains auto-generated [Agent Skills](https://agentskills.io) for the Agentuity CLI.',
419
+ '',
420
+ '## What are Agent Skills?',
421
+ '',
422
+ 'Agent Skills are modular capabilities that extend AI coding agents. Each skill is a directory',
423
+ 'containing a `SKILL.md` file with instructions that agents read when performing relevant tasks.',
424
+ '',
425
+ 'Learn more at the [Agent Skills Specification](https://agentskills.io/specification).',
426
+ '',
427
+ '## Generated From',
428
+ '',
429
+ `- **CLI Version**: ${version}`,
430
+ `- **Generated**: ${new Date().toISOString().split('T')[0]}`,
431
+ `- **Total Skills**: ${skills.length}`,
432
+ '',
433
+ '## Available Skills',
434
+ '',
435
+ ];
436
+
437
+ for (const [group, groupSkills] of [...groups.entries()].sort()) {
438
+ lines.push(`### ${group}`);
439
+ lines.push('');
440
+ lines.push('| Skill | Command | Description |');
441
+ lines.push('|-------|---------|-------------|');
442
+
443
+ for (const skill of groupSkills.sort((a, b) => a.skillName.localeCompare(b.skillName))) {
444
+ const cmd = `\`agentuity ${skill.fullCommandPath.join(' ')}\``;
445
+ const desc =
446
+ skill.command.description.substring(0, 60) +
447
+ (skill.command.description.length > 60 ? '...' : '');
448
+ lines.push(`| [${skill.skillName}](./${skill.skillName}) | ${cmd} | ${desc} |`);
449
+ }
450
+
451
+ lines.push('');
452
+ }
453
+
454
+ lines.push('## Usage');
455
+ lines.push('');
456
+ lines.push(
457
+ 'These skills are designed for AI coding agents that support the Agent Skills format.'
458
+ );
459
+ lines.push(
460
+ 'Place this directory in your project or install globally for your agent to discover.'
461
+ );
462
+ lines.push('');
463
+ lines.push('## Regenerating');
464
+ lines.push('');
465
+ lines.push('To regenerate these skills with the latest CLI schema:');
466
+ lines.push('');
467
+ lines.push('```bash');
468
+ lines.push('agentuity ai skills generate --output ./skills');
469
+ lines.push('```');
470
+ lines.push('');
471
+ lines.push('---');
472
+ lines.push('');
473
+ lines.push('*This file was auto-generated by the Agentuity CLI. Do not edit manually.*');
474
+ lines.push('');
475
+
476
+ return lines.join('\n');
477
+ }
478
+
479
+ export function collectSkillsForPreview(
480
+ schema: CLISchema,
481
+ outputDir: string,
482
+ includeHidden: boolean
483
+ ): string[] {
484
+ const allSkills = collectAllSkills(schema, outputDir, includeHidden);
485
+ return allSkills.map((s) => s.skillPath);
486
+ }
487
+
488
+ export async function generateSkills(
489
+ schema: CLISchema,
490
+ outputDir: string,
491
+ includeHidden: boolean
492
+ ): Promise<number> {
493
+ const allSkills = collectAllSkills(schema, outputDir, includeHidden);
494
+
495
+ if (allSkills.length === 0) {
496
+ return 0;
497
+ }
498
+
499
+ const baseDir = path.join(outputDir, 'skills');
500
+ let created = 0;
501
+
502
+ for (const skill of allSkills) {
503
+ const content = generateSkillContent(skill, schema.version);
504
+ const skillDir = path.dirname(skill.skillPath);
505
+
506
+ await Bun.$`mkdir -p ${skillDir}`.quiet();
507
+ await Bun.write(Bun.file(skill.skillPath), content);
508
+ created++;
509
+ }
510
+
511
+ const readmePath = path.join(baseDir, 'README.md');
512
+ const readmeContent = generateReadme(schema.version, allSkills);
513
+ await Bun.write(Bun.file(readmePath), readmeContent);
514
+
515
+ const versionPath = path.join(baseDir, 'agentuity-version.txt');
516
+ await Bun.write(Bun.file(versionPath), schema.version);
517
+
518
+ return created;
519
+ }
@@ -0,0 +1,23 @@
1
+ import type { CommandDefinition } from '../../../types';
2
+ import { createCommand } from '../../../types';
3
+ import { generateSubcommand } from './generate';
4
+ import { getCommand } from '../../../command-prefix';
5
+
6
+ export const skillsCommand: CommandDefinition = createCommand({
7
+ name: 'skills',
8
+ description: 'Generate Agent Skills from CLI schema',
9
+ tags: ['read-only', 'fast'],
10
+ examples: [
11
+ {
12
+ command: getCommand('ai skills generate --output ./skills'),
13
+ description: 'Generate skills to a directory',
14
+ },
15
+ {
16
+ command: getCommand('--dry-run ai skills generate --output ./skills'),
17
+ description: 'Preview without writing files',
18
+ },
19
+ ],
20
+ subcommands: [generateSubcommand],
21
+ });
22
+
23
+ export default skillsCommand;
@@ -11,6 +11,7 @@ export const signupCommand = createSubcommand({
11
11
  description: 'Create a new Agentuity Cloud Platform account',
12
12
  tags: ['mutating', 'creates-resource', 'slow', 'api-intensive'],
13
13
  toplevel: true,
14
+ skipSkill: true,
14
15
  idempotent: false,
15
16
  requires: { apiClient: true },
16
17
  examples: [