@crewx/cli 0.8.4-rc.0 → 0.8.4-rc.1

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 (220) hide show
  1. package/README.md +33 -33
  2. package/bin/crewx +2 -2
  3. package/dist/commands/agent.js +23 -23
  4. package/dist/commands/init.js +20 -20
  5. package/dist/commands/task-db.d.ts +33 -0
  6. package/dist/commands/task-db.js +107 -0
  7. package/dist/examples/deny-secrets-plugin.d.ts +22 -0
  8. package/dist/examples/deny-secrets-plugin.js +40 -0
  9. package/dist/main.js +72 -72
  10. package/dist/plugins/examples/echo-hook.d.ts +24 -0
  11. package/dist/plugins/examples/echo-hook.js +60 -0
  12. package/dist/plugins/examples/verify-echo-hook.d.ts +8 -0
  13. package/dist/plugins/examples/verify-echo-hook.js +47 -0
  14. package/dist/plugins/sqlite-tracing.d.ts +11 -0
  15. package/dist/plugins/sqlite-tracing.js +19 -0
  16. package/dist/repository/workspace.repository.d.ts +26 -0
  17. package/dist/repository/workspace.repository.js +111 -0
  18. package/dist/schema/tasks.d.ts +7 -0
  19. package/dist/schema/tasks.js +48 -0
  20. package/package.json +18 -18
  21. package/dist/ai-provider.service.d.ts +0 -34
  22. package/dist/ai-provider.service.js +0 -311
  23. package/dist/ai-provider.service.js.map +0 -1
  24. package/dist/ai.service.d.ts +0 -17
  25. package/dist/ai.service.js +0 -51
  26. package/dist/ai.service.js.map +0 -1
  27. package/dist/app.module.d.ts +0 -5
  28. package/dist/app.module.js +0 -165
  29. package/dist/app.module.js.map +0 -1
  30. package/dist/cli/agent.handler.d.ts +0 -2
  31. package/dist/cli/agent.handler.js +0 -186
  32. package/dist/cli/agent.handler.js.map +0 -1
  33. package/dist/cli/builtin.handler.d.ts +0 -3
  34. package/dist/cli/builtin.handler.js +0 -110
  35. package/dist/cli/builtin.handler.js.map +0 -1
  36. package/dist/cli/chat.handler.d.ts +0 -20
  37. package/dist/cli/chat.handler.js +0 -446
  38. package/dist/cli/chat.handler.js.map +0 -1
  39. package/dist/cli/cli.handler.d.ts +0 -4
  40. package/dist/cli/cli.handler.js +0 -119
  41. package/dist/cli/cli.handler.js.map +0 -1
  42. package/dist/cli/doctor.handler.d.ts +0 -38
  43. package/dist/cli/doctor.handler.js +0 -495
  44. package/dist/cli/doctor.handler.js.map +0 -1
  45. package/dist/cli/execute.handler.d.ts +0 -2
  46. package/dist/cli/execute.handler.js +0 -321
  47. package/dist/cli/execute.handler.js.map +0 -1
  48. package/dist/cli/help.handler.d.ts +0 -2
  49. package/dist/cli/help.handler.js +0 -10
  50. package/dist/cli/help.handler.js.map +0 -1
  51. package/dist/cli/init.handler.d.ts +0 -26
  52. package/dist/cli/init.handler.js +0 -450
  53. package/dist/cli/init.handler.js.map +0 -1
  54. package/dist/cli/log.handler.d.ts +0 -2
  55. package/dist/cli/log.handler.js +0 -69
  56. package/dist/cli/log.handler.js.map +0 -1
  57. package/dist/cli/mcp.handler.d.ts +0 -3
  58. package/dist/cli/mcp.handler.js +0 -121
  59. package/dist/cli/mcp.handler.js.map +0 -1
  60. package/dist/cli/query.handler.d.ts +0 -2
  61. package/dist/cli/query.handler.js +0 -379
  62. package/dist/cli/query.handler.js.map +0 -1
  63. package/dist/cli/skill.handler.d.ts +0 -2
  64. package/dist/cli/skill.handler.js +0 -252
  65. package/dist/cli/skill.handler.js.map +0 -1
  66. package/dist/cli/slack-files.handler.d.ts +0 -2
  67. package/dist/cli/slack-files.handler.js +0 -291
  68. package/dist/cli/slack-files.handler.js.map +0 -1
  69. package/dist/cli/template.handler.d.ts +0 -2
  70. package/dist/cli/template.handler.js +0 -188
  71. package/dist/cli/template.handler.js.map +0 -1
  72. package/dist/cli/templates.handler.d.ts +0 -2
  73. package/dist/cli/templates.handler.js +0 -100
  74. package/dist/cli/templates.handler.js.map +0 -1
  75. package/dist/cli-options.d.ts +0 -39
  76. package/dist/cli-options.js +0 -355
  77. package/dist/cli-options.js.map +0 -1
  78. package/dist/config/timeout.config.d.ts +0 -14
  79. package/dist/config/timeout.config.js +0 -34
  80. package/dist/config/timeout.config.js.map +0 -1
  81. package/dist/conversation/base-conversation-history.provider.d.ts +0 -12
  82. package/dist/conversation/base-conversation-history.provider.js +0 -45
  83. package/dist/conversation/base-conversation-history.provider.js.map +0 -1
  84. package/dist/conversation/cli-conversation-history.provider.d.ts +0 -16
  85. package/dist/conversation/cli-conversation-history.provider.js +0 -111
  86. package/dist/conversation/cli-conversation-history.provider.js.map +0 -1
  87. package/dist/conversation/conversation-provider.factory.d.ts +0 -10
  88. package/dist/conversation/conversation-provider.factory.js +0 -50
  89. package/dist/conversation/conversation-provider.factory.js.map +0 -1
  90. package/dist/conversation/index.d.ts +0 -6
  91. package/dist/conversation/index.js +0 -27
  92. package/dist/conversation/index.js.map +0 -1
  93. package/dist/conversation/slack-conversation-history.provider.d.ts +0 -29
  94. package/dist/conversation/slack-conversation-history.provider.js +0 -302
  95. package/dist/conversation/slack-conversation-history.provider.js.map +0 -1
  96. package/dist/crewx.tool.d.ts +0 -359
  97. package/dist/crewx.tool.js +0 -2501
  98. package/dist/crewx.tool.js.map +0 -1
  99. package/dist/crewx.tool.spec.d.ts +0 -1
  100. package/dist/crewx.tool.spec.js +0 -158
  101. package/dist/crewx.tool.spec.js.map +0 -1
  102. package/dist/guards/bearer-auth.guard.d.ts +0 -7
  103. package/dist/guards/bearer-auth.guard.js +0 -44
  104. package/dist/guards/bearer-auth.guard.js.map +0 -1
  105. package/dist/health.controller.d.ts +0 -6
  106. package/dist/health.controller.js +0 -32
  107. package/dist/health.controller.js.map +0 -1
  108. package/dist/main.js.map +0 -1
  109. package/dist/mcp.controller.d.ts +0 -8
  110. package/dist/mcp.controller.js +0 -62
  111. package/dist/mcp.controller.js.map +0 -1
  112. package/dist/package.json +0 -3
  113. package/dist/providers/dynamic-provider.factory.d.ts +0 -15
  114. package/dist/providers/dynamic-provider.factory.js +0 -133
  115. package/dist/providers/dynamic-provider.factory.js.map +0 -1
  116. package/dist/providers/logger.adapter.d.ts +0 -6
  117. package/dist/providers/logger.adapter.js +0 -102
  118. package/dist/providers/logger.adapter.js.map +0 -1
  119. package/dist/services/agent-loader.service.d.ts +0 -35
  120. package/dist/services/agent-loader.service.js +0 -622
  121. package/dist/services/agent-loader.service.js.map +0 -1
  122. package/dist/services/auth.service.d.ts +0 -9
  123. package/dist/services/auth.service.js +0 -47
  124. package/dist/services/auth.service.js.map +0 -1
  125. package/dist/services/config-validator.service.d.ts +0 -29
  126. package/dist/services/config-validator.service.js +0 -483
  127. package/dist/services/config-validator.service.js.map +0 -1
  128. package/dist/services/config.service.d.ts +0 -45
  129. package/dist/services/config.service.js +0 -352
  130. package/dist/services/config.service.js.map +0 -1
  131. package/dist/services/document-loader.service.d.ts +0 -21
  132. package/dist/services/document-loader.service.js +0 -156
  133. package/dist/services/document-loader.service.js.map +0 -1
  134. package/dist/services/help.service.d.ts +0 -5
  135. package/dist/services/help.service.js +0 -139
  136. package/dist/services/help.service.js.map +0 -1
  137. package/dist/services/intelligent-compression.service.d.ts +0 -20
  138. package/dist/services/intelligent-compression.service.js +0 -179
  139. package/dist/services/intelligent-compression.service.js.map +0 -1
  140. package/dist/services/mcp-client.service.d.ts +0 -26
  141. package/dist/services/mcp-client.service.js +0 -81
  142. package/dist/services/mcp-client.service.js.map +0 -1
  143. package/dist/services/parallel-processing.service.d.ts +0 -108
  144. package/dist/services/parallel-processing.service.js +0 -333
  145. package/dist/services/parallel-processing.service.js.map +0 -1
  146. package/dist/services/provider-bridge.service.d.ts +0 -35
  147. package/dist/services/provider-bridge.service.js +0 -224
  148. package/dist/services/provider-bridge.service.js.map +0 -1
  149. package/dist/services/remote-agent.service.d.ts +0 -50
  150. package/dist/services/remote-agent.service.js +0 -171
  151. package/dist/services/remote-agent.service.js.map +0 -1
  152. package/dist/services/result-formatter.service.d.ts +0 -27
  153. package/dist/services/result-formatter.service.js +0 -126
  154. package/dist/services/result-formatter.service.js.map +0 -1
  155. package/dist/services/skill-loader.service.d.ts +0 -15
  156. package/dist/services/skill-loader.service.js +0 -278
  157. package/dist/services/skill-loader.service.js.map +0 -1
  158. package/dist/services/skill.service.d.ts +0 -67
  159. package/dist/services/skill.service.js +0 -670
  160. package/dist/services/skill.service.js.map +0 -1
  161. package/dist/services/skill.service.spec.d.ts +0 -1
  162. package/dist/services/skill.service.spec.js +0 -35
  163. package/dist/services/skill.service.spec.js.map +0 -1
  164. package/dist/services/task-management.service.d.ts +0 -65
  165. package/dist/services/task-management.service.js +0 -288
  166. package/dist/services/task-management.service.js.map +0 -1
  167. package/dist/services/template.service.d.ts +0 -61
  168. package/dist/services/template.service.js +0 -416
  169. package/dist/services/template.service.js.map +0 -1
  170. package/dist/services/tool-call.service.d.ts +0 -19
  171. package/dist/services/tool-call.service.js +0 -1061
  172. package/dist/services/tool-call.service.js.map +0 -1
  173. package/dist/services/tracing.service.d.ts +0 -200
  174. package/dist/services/tracing.service.js +0 -1290
  175. package/dist/services/tracing.service.js.map +0 -1
  176. package/dist/slack/formatters/message.formatter.d.ts +0 -32
  177. package/dist/slack/formatters/message.formatter.js +0 -352
  178. package/dist/slack/formatters/message.formatter.js.map +0 -1
  179. package/dist/slack/services/slack-file-download.service.d.ts +0 -58
  180. package/dist/slack/services/slack-file-download.service.js +0 -558
  181. package/dist/slack/services/slack-file-download.service.js.map +0 -1
  182. package/dist/slack/slack-bot.d.ts +0 -33
  183. package/dist/slack/slack-bot.js +0 -567
  184. package/dist/slack/slack-bot.js.map +0 -1
  185. package/dist/stderr.logger.d.ts +0 -8
  186. package/dist/stderr.logger.js +0 -26
  187. package/dist/stderr.logger.js.map +0 -1
  188. package/dist/types/usage.types.d.ts +0 -107
  189. package/dist/types/usage.types.js +0 -3
  190. package/dist/types/usage.types.js.map +0 -1
  191. package/dist/utils/config-utils.d.ts +0 -15
  192. package/dist/utils/config-utils.js +0 -69
  193. package/dist/utils/config-utils.js.map +0 -1
  194. package/dist/utils/extract-text.d.ts +0 -1
  195. package/dist/utils/extract-text.js +0 -15
  196. package/dist/utils/extract-text.js.map +0 -1
  197. package/dist/utils/mcp-installer.d.ts +0 -20
  198. package/dist/utils/mcp-installer.js +0 -199
  199. package/dist/utils/mcp-installer.js.map +0 -1
  200. package/dist/utils/project-hash.d.ts +0 -6
  201. package/dist/utils/project-hash.js +0 -70
  202. package/dist/utils/project-hash.js.map +0 -1
  203. package/dist/utils/simple-security.d.ts +0 -3
  204. package/dist/utils/simple-security.js +0 -20
  205. package/dist/utils/simple-security.js.map +0 -1
  206. package/dist/utils/stdin-utils.d.ts +0 -6
  207. package/dist/utils/stdin-utils.js +0 -109
  208. package/dist/utils/stdin-utils.js.map +0 -1
  209. package/dist/utils/template-processor.d.ts +0 -4
  210. package/dist/utils/template-processor.js +0 -266
  211. package/dist/utils/template-processor.js.map +0 -1
  212. package/dist/utils/terminal-message-formatter.d.ts +0 -23
  213. package/dist/utils/terminal-message-formatter.js +0 -136
  214. package/dist/utils/terminal-message-formatter.js.map +0 -1
  215. package/dist/version.d.ts +0 -1
  216. package/dist/version.js +0 -17
  217. package/dist/version.js.map +0 -1
  218. package/dist/workspace.service.d.ts +0 -44
  219. package/dist/workspace.service.js +0 -299
  220. package/dist/workspace.service.js.map +0 -1
@@ -1,670 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
22
- return c > 3 && r && Object.defineProperty(target, key, r), r;
23
- };
24
- var __importStar = (this && this.__importStar) || (function () {
25
- var ownKeys = function(o) {
26
- ownKeys = Object.getOwnPropertyNames || function (o) {
27
- var ar = [];
28
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
- return ar;
30
- };
31
- return ownKeys(o);
32
- };
33
- return function (mod) {
34
- if (mod && mod.__esModule) return mod;
35
- var result = {};
36
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
- __setModuleDefault(result, mod);
38
- return result;
39
- };
40
- })();
41
- var __metadata = (this && this.__metadata) || function (k, v) {
42
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
43
- };
44
- var SkillService_1;
45
- Object.defineProperty(exports, "__esModule", { value: true });
46
- exports.SkillService = void 0;
47
- const common_1 = require("@nestjs/common");
48
- const fs = __importStar(require("fs"));
49
- const path = __importStar(require("path"));
50
- const yaml = __importStar(require("js-yaml"));
51
- const crewx_sdk_1 = require("@sowonai/crewx-sdk");
52
- const child_process_1 = require("child_process");
53
- const tracing_service_1 = require("./tracing.service");
54
- let SkillService = SkillService_1 = class SkillService {
55
- constructor() {
56
- this.logger = new common_1.Logger(SkillService_1.name);
57
- this.tracingService = null;
58
- this.crewxDir = path.join(process.cwd(), '.crewx');
59
- this.installedSkillsDir = path.join(this.crewxDir, 'skills');
60
- this.skillsDirs = [
61
- path.join(process.cwd(), 'skills'),
62
- this.installedSkillsDir
63
- ];
64
- this.initTracing();
65
- }
66
- initTracing() {
67
- try {
68
- this.tracingService = new tracing_service_1.TracingService();
69
- this.tracingService.onModuleInit();
70
- }
71
- catch (error) {
72
- this.logger.warn(`Failed to initialize TracingService for skill tracking: ${error}`);
73
- this.tracingService = null;
74
- }
75
- }
76
- loadCrewxConfig() {
77
- try {
78
- const configPath = path.join(process.cwd(), 'crewx.yaml');
79
- if (!fs.existsSync(configPath))
80
- return null;
81
- const content = fs.readFileSync(configPath, 'utf-8');
82
- return yaml.load(content);
83
- }
84
- catch (e) {
85
- this.logger.warn(`Failed to parse crewx.yaml: ${e}`);
86
- return null;
87
- }
88
- }
89
- getRegistries() {
90
- try {
91
- const config = this.loadCrewxConfig();
92
- const registries = config?.skills?.registries;
93
- if (!Array.isArray(registries))
94
- return [];
95
- return registries.filter((r) => r && typeof r === 'object' && typeof r.id === 'string');
96
- }
97
- catch {
98
- return [];
99
- }
100
- }
101
- ensureCrewxDir() {
102
- if (!fs.existsSync(this.crewxDir)) {
103
- fs.mkdirSync(this.crewxDir, { recursive: true });
104
- }
105
- }
106
- ensureInstalledSkillsDir() {
107
- this.ensureCrewxDir();
108
- if (!fs.existsSync(this.installedSkillsDir)) {
109
- fs.mkdirSync(this.installedSkillsDir, { recursive: true });
110
- }
111
- }
112
- parseSource(source) {
113
- if (source.startsWith('npm:')) {
114
- return { type: 'npm', package: source.slice(4) };
115
- }
116
- if (source.startsWith('template:')) {
117
- return { type: 'template', name: source.slice(9) };
118
- }
119
- if (source.startsWith('github:')) {
120
- const rest = source.slice(7);
121
- const atIndex = rest.lastIndexOf('@');
122
- if (atIndex > 0 && !rest.slice(0, atIndex).includes('/')) {
123
- return null;
124
- }
125
- if (atIndex > 0) {
126
- return { type: 'github', repo: rest.slice(0, atIndex), version: rest.slice(atIndex + 1) };
127
- }
128
- return { type: 'github', repo: rest };
129
- }
130
- return null;
131
- }
132
- async discover() {
133
- const skills = [];
134
- for (const dirPath of this.skillsDirs) {
135
- if (!fs.existsSync(dirPath))
136
- continue;
137
- try {
138
- const dirs = fs.readdirSync(dirPath, { withFileTypes: true })
139
- .filter(d => d.isDirectory());
140
- for (const dir of dirs) {
141
- const skillPath = path.join(dirPath, dir.name);
142
- const skillMdPath = path.join(skillPath, 'SKILL.md');
143
- if (fs.existsSync(skillMdPath)) {
144
- try {
145
- const manifest = (0, crewx_sdk_1.parseSkillManifestFromFile)(skillMdPath, {
146
- loadContent: false,
147
- validationMode: 'lenient'
148
- });
149
- const entryPoint = this.detectEntryPoint(skillPath, dir.name);
150
- const source = dirPath === this.installedSkillsDir ? 'installed' : 'custom';
151
- skills.push({
152
- name: manifest.metadata.name || dir.name,
153
- description: manifest.metadata.description || '',
154
- version: manifest.metadata.version || '0.0.0',
155
- entryPoint: entryPoint || null,
156
- path: skillPath,
157
- source,
158
- });
159
- }
160
- catch (e) {
161
- this.logger.debug(`Failed to parse SKILL.md in ${skillPath}: ${e}`);
162
- }
163
- }
164
- }
165
- }
166
- catch (e) {
167
- this.logger.warn(`Failed to read skills directory ${dirPath}: ${e}`);
168
- }
169
- }
170
- return skills;
171
- }
172
- async getSkill(name) {
173
- const skills = await this.discover();
174
- return skills.find(s => s.name === name) || null;
175
- }
176
- detectEntryPoint(skillPath, skillName) {
177
- const candidates = [
178
- `${skillName}.js`,
179
- `${skillName}.sh`,
180
- `${skillName}.py`,
181
- 'index.js',
182
- 'main.js',
183
- ];
184
- for (const candidate of candidates) {
185
- const fullPath = path.join(skillPath, candidate);
186
- if (fs.existsSync(fullPath)) {
187
- return candidate;
188
- }
189
- }
190
- return null;
191
- }
192
- async execute(name, args) {
193
- const skill = await this.getSkill(name);
194
- if (!skill) {
195
- throw new Error(`Skill '${name}' not found`);
196
- }
197
- if (!skill.entryPoint) {
198
- const skillMdPath = path.join(skill.path, 'SKILL.md');
199
- const content = fs.readFileSync(skillMdPath, 'utf-8');
200
- console.log(content);
201
- return { code: 0, output: content };
202
- }
203
- const entryPoint = skill.entryPoint;
204
- const entryPath = path.join(skill.path, entryPoint);
205
- const taskId = process.env.CREWX_TASK_ID;
206
- const spanAlreadyCreated = process.env.CREWX_SKILL_SPAN_CREATED === 'true';
207
- let spanId = null;
208
- const startTime = Date.now();
209
- if (taskId && this.tracingService?.isEnabled() && !spanAlreadyCreated) {
210
- spanId = this.tracingService.createSpan({
211
- task_id: taskId,
212
- name: `skill:${name}`,
213
- kind: tracing_service_1.SpanKind.INTERNAL,
214
- input: JSON.stringify({ skill: name, args }),
215
- });
216
- }
217
- return new Promise((resolve, reject) => {
218
- let command;
219
- let cmdArgs;
220
- if (entryPoint.endsWith('.js')) {
221
- command = 'node';
222
- cmdArgs = [entryPath, ...args];
223
- }
224
- else if (entryPoint.endsWith('.sh')) {
225
- command = 'sh';
226
- cmdArgs = [entryPath, ...args];
227
- }
228
- else if (entryPoint.endsWith('.py')) {
229
- command = 'python3';
230
- cmdArgs = [entryPath, ...args];
231
- }
232
- else {
233
- if (spanId && this.tracingService) {
234
- this.tracingService.failSpan(spanId, `Unsupported entry point: ${entryPoint}`);
235
- }
236
- reject(new Error(`Unsupported entry point: ${entryPoint}`));
237
- return;
238
- }
239
- const child = (0, child_process_1.spawn)(command, cmdArgs, {
240
- cwd: skill.path,
241
- stdio: 'inherit'
242
- });
243
- child.on('close', (code) => {
244
- const durationMs = Date.now() - startTime;
245
- if (spanId && this.tracingService) {
246
- if (code === 0) {
247
- this.tracingService.completeSpan(spanId, JSON.stringify({
248
- code,
249
- duration_ms: durationMs
250
- }));
251
- }
252
- else {
253
- this.tracingService.failSpan(spanId, `Skill exited with code ${code}`);
254
- }
255
- }
256
- resolve({ code: code || 0, output: '' });
257
- });
258
- child.on('error', (err) => {
259
- if (spanId && this.tracingService) {
260
- this.tracingService.failSpan(spanId, err.message);
261
- }
262
- reject(err);
263
- });
264
- });
265
- }
266
- async executeShell(name, commandString) {
267
- const skill = await this.getSkill(name);
268
- if (!skill) {
269
- throw new Error(`Skill '${name}' not found`);
270
- }
271
- const taskId = process.env.CREWX_TASK_ID;
272
- const env = {
273
- ...process.env,
274
- SKILL_DIR: skill.path,
275
- CREWX_TASK_ID: taskId || '',
276
- };
277
- const spanAlreadyCreated = process.env.CREWX_SKILL_SPAN_CREATED === 'true';
278
- let spanId = null;
279
- const startTime = Date.now();
280
- if (taskId && this.tracingService?.isEnabled() && !spanAlreadyCreated) {
281
- spanId = this.tracingService.createSpan({
282
- task_id: taskId,
283
- name: `skill:exec:${name}`,
284
- kind: tracing_service_1.SpanKind.INTERNAL,
285
- input: JSON.stringify({ skill: name, command: commandString }),
286
- });
287
- }
288
- return new Promise((resolve, reject) => {
289
- const child = (0, child_process_1.spawn)(commandString, {
290
- cwd: process.cwd(),
291
- shell: true,
292
- env: env,
293
- stdio: 'inherit',
294
- });
295
- child.on('close', (code) => {
296
- const durationMs = Date.now() - startTime;
297
- if (spanId && this.tracingService) {
298
- if (code === 0) {
299
- this.tracingService.completeSpan(spanId, JSON.stringify({ code, duration_ms: durationMs }));
300
- }
301
- else {
302
- this.tracingService.failSpan(spanId, `Skill shell exited with code ${code}`);
303
- }
304
- }
305
- resolve({ code: code || 0 });
306
- });
307
- child.on('error', (err) => {
308
- if (spanId && this.tracingService) {
309
- this.tracingService.failSpan(spanId, err.message);
310
- }
311
- reject(err);
312
- });
313
- });
314
- }
315
- async add(sourceStr) {
316
- const source = this.parseSource(sourceStr);
317
- if (!source) {
318
- return {
319
- success: false,
320
- name: '',
321
- message: `Invalid source format: ${sourceStr}. Use npm:<package>, template:<name>, or github:<owner/repo>`
322
- };
323
- }
324
- switch (source.type) {
325
- case 'npm':
326
- return this.addFromNpm(source.package);
327
- case 'template':
328
- return this.addFromTemplate(source.name);
329
- case 'github':
330
- return {
331
- success: false,
332
- name: '',
333
- message: 'GitHub source is planned for Phase 1.5 (v0.8.1+). Use npm: or template: for now.'
334
- };
335
- default:
336
- return { success: false, name: '', message: `Unknown source type` };
337
- }
338
- }
339
- validatePackageName(packageName) {
340
- if (packageName.startsWith('-')) {
341
- return false;
342
- }
343
- const validNpmPackagePattern = /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*(@[a-z0-9-._~]+)?$/i;
344
- return validNpmPackagePattern.test(packageName);
345
- }
346
- async addFromNpm(packageName) {
347
- this.ensureInstalledSkillsDir();
348
- if (!this.validatePackageName(packageName)) {
349
- return {
350
- success: false,
351
- name: '',
352
- message: `Invalid package name: ${packageName}. Package name contains invalid characters.`
353
- };
354
- }
355
- try {
356
- const tempDir = path.join(this.crewxDir, '.tmp-install');
357
- if (fs.existsSync(tempDir)) {
358
- fs.rmSync(tempDir, { recursive: true });
359
- }
360
- fs.mkdirSync(tempDir, { recursive: true });
361
- fs.writeFileSync(path.join(tempDir, 'package.json'), JSON.stringify({ name: 'temp', private: true }));
362
- this.logger.log(`Installing ${packageName} from npm...`);
363
- (0, child_process_1.execSync)(`npm install ${packageName} --prefix "${tempDir}"`, {
364
- stdio: 'inherit'
365
- });
366
- const nodeModulesPath = path.join(tempDir, 'node_modules');
367
- const installedPkgPath = this.findInstalledPackage(nodeModulesPath, packageName);
368
- if (!installedPkgPath) {
369
- fs.rmSync(tempDir, { recursive: true });
370
- return { success: false, name: '', message: `Failed to locate installed package: ${packageName}` };
371
- }
372
- const skillMdPath = path.join(installedPkgPath, 'SKILL.md');
373
- if (!fs.existsSync(skillMdPath)) {
374
- fs.rmSync(tempDir, { recursive: true });
375
- return { success: false, name: '', message: `Package ${packageName} does not contain a SKILL.md file` };
376
- }
377
- const manifest = (0, crewx_sdk_1.parseSkillManifestFromFile)(skillMdPath, {
378
- loadContent: false,
379
- validationMode: 'lenient'
380
- });
381
- const skillName = manifest.metadata.name || path.basename(installedPkgPath);
382
- const skillVersion = manifest.metadata.version || '0.0.0';
383
- const customSkillPath = path.join(process.cwd(), 'skills', skillName);
384
- if (fs.existsSync(customSkillPath)) {
385
- fs.rmSync(tempDir, { recursive: true });
386
- return {
387
- success: false,
388
- name: skillName,
389
- message: `Skill '${skillName}' already exists in skills/ directory (custom skills take priority)`
390
- };
391
- }
392
- const targetPath = path.join(this.installedSkillsDir, skillName);
393
- if (fs.existsSync(targetPath)) {
394
- fs.rmSync(targetPath, { recursive: true });
395
- }
396
- this.copyDir(installedPkgPath, targetPath);
397
- fs.rmSync(tempDir, { recursive: true });
398
- return {
399
- success: true,
400
- name: skillName,
401
- message: `Successfully installed ${skillName}@${skillVersion} from npm:${packageName}`
402
- };
403
- }
404
- catch (e) {
405
- return { success: false, name: '', message: `Failed to install from npm: ${e}` };
406
- }
407
- }
408
- findInstalledPackage(nodeModulesPath, packageName) {
409
- if (packageName.startsWith('@')) {
410
- const parts = packageName.split('/');
411
- const scope = parts[0];
412
- const name = parts[1];
413
- if (scope && name) {
414
- const scopedPath = path.join(nodeModulesPath, scope, name);
415
- if (fs.existsSync(scopedPath)) {
416
- return scopedPath;
417
- }
418
- }
419
- }
420
- else {
421
- const directPath = path.join(nodeModulesPath, packageName);
422
- if (fs.existsSync(directPath)) {
423
- return directPath;
424
- }
425
- }
426
- return null;
427
- }
428
- copyDir(src, dest) {
429
- fs.mkdirSync(dest, { recursive: true });
430
- const entries = fs.readdirSync(src, { withFileTypes: true });
431
- for (const entry of entries) {
432
- const srcPath = path.join(src, entry.name);
433
- const destPath = path.join(dest, entry.name);
434
- if (entry.isDirectory()) {
435
- if (entry.name === 'node_modules')
436
- continue;
437
- this.copyDir(srcPath, destPath);
438
- }
439
- else {
440
- fs.copyFileSync(srcPath, destPath);
441
- }
442
- }
443
- }
444
- async addFromTemplate(templateName) {
445
- this.ensureInstalledSkillsDir();
446
- const builtInTemplates = {
447
- hello: {
448
- description: 'Simple greeting demo skill',
449
- files: {
450
- 'SKILL.md': `---
451
- name: {{name}}
452
- description: A simple greeting skill
453
- version: 0.0.1
454
- ---
455
-
456
- # {{name}} Skill
457
-
458
- A simple greeting skill created from template.
459
-
460
- ## Usage
461
- \`\`\`bash
462
- node skills/{{name}}/{{name}}.js [name]
463
- \`\`\`
464
- `,
465
- '{{name}}.js': `#!/usr/bin/env node
466
-
467
- const args = process.argv.slice(2);
468
-
469
- if (args.includes('--help') || args.includes('-h')) {
470
- console.log('Usage: node {{name}}.js [name]');
471
- process.exit(0);
472
- }
473
-
474
- const name = args[0] || 'World';
475
- console.log(\`Hello, \${name}! (from {{name}} skill)\`);
476
- `
477
- }
478
- },
479
- memory: {
480
- description: 'Key-value memory storage skill',
481
- files: {
482
- 'SKILL.md': `---
483
- name: {{name}}
484
- description: Simple key-value memory storage
485
- version: 0.0.1
486
- ---
487
-
488
- # {{name}} Skill
489
-
490
- A simple key-value memory storage skill.
491
-
492
- ## Commands
493
- - \`save <key> <value>\` - Save a value
494
- - \`load <key>\` - Load a value
495
- - \`list\` - List all keys
496
- - \`delete <key>\` - Delete a key
497
- `,
498
- '{{name}}.js': `#!/usr/bin/env node
499
-
500
- const fs = require('fs');
501
- const path = require('path');
502
-
503
- const dataFile = path.join(__dirname, 'data.json');
504
-
505
- function loadData() {
506
- try {
507
- return JSON.parse(fs.readFileSync(dataFile, 'utf-8'));
508
- } catch {
509
- return {};
510
- }
511
- }
512
-
513
- function saveData(data) {
514
- fs.writeFileSync(dataFile, JSON.stringify(data, null, 2));
515
- }
516
-
517
- const [command, ...args] = process.argv.slice(2);
518
-
519
- switch (command) {
520
- case 'save':
521
- const data = loadData();
522
- data[args[0]] = args.slice(1).join(' ');
523
- saveData(data);
524
- console.log(\`Saved: \${args[0]}\`);
525
- break;
526
- case 'load':
527
- const stored = loadData();
528
- console.log(stored[args[0]] || '(not found)');
529
- break;
530
- case 'list':
531
- console.log(Object.keys(loadData()).join('\\n') || '(empty)');
532
- break;
533
- case 'delete':
534
- const d = loadData();
535
- delete d[args[0]];
536
- saveData(d);
537
- console.log(\`Deleted: \${args[0]}\`);
538
- break;
539
- default:
540
- console.log('Usage: {{name}}.js <save|load|list|delete> [args]');
541
- }
542
- `
543
- }
544
- },
545
- api: {
546
- description: 'HTTP API client skill',
547
- files: {
548
- 'SKILL.md': `---
549
- name: {{name}}
550
- description: HTTP API client skill
551
- version: 0.0.1
552
- ---
553
-
554
- # {{name}} Skill
555
-
556
- An HTTP API client skill for making REST requests.
557
-
558
- ## Commands
559
- - \`get <url>\` - GET request
560
- - \`post <url> <data>\` - POST request with JSON data
561
- `,
562
- '{{name}}.js': `#!/usr/bin/env node
563
-
564
- const https = require('https');
565
- const http = require('http');
566
-
567
- const [method, url, ...rest] = process.argv.slice(2);
568
-
569
- if (!method || !url) {
570
- console.log('Usage: {{name}}.js <get|post> <url> [data]');
571
- process.exit(1);
572
- }
573
-
574
- const client = url.startsWith('https') ? https : http;
575
-
576
- const req = client.request(url, { method: method.toUpperCase() }, (res) => {
577
- let data = '';
578
- res.on('data', chunk => data += chunk);
579
- res.on('end', () => console.log(data));
580
- });
581
-
582
- if (method.toLowerCase() === 'post' && rest.length) {
583
- req.setHeader('Content-Type', 'application/json');
584
- req.write(rest.join(' '));
585
- }
586
-
587
- req.end();
588
- `
589
- }
590
- }
591
- };
592
- const template = builtInTemplates[templateName];
593
- if (!template) {
594
- const available = Object.keys(builtInTemplates).join(', ');
595
- return {
596
- success: false,
597
- name: '',
598
- message: `Template '${templateName}' not found. Available: ${available}`
599
- };
600
- }
601
- let skillName = templateName;
602
- let counter = 1;
603
- while (fs.existsSync(path.join(this.installedSkillsDir, skillName)) ||
604
- fs.existsSync(path.join(process.cwd(), 'skills', skillName))) {
605
- skillName = `${templateName}-${counter}`;
606
- counter++;
607
- }
608
- const targetPath = path.join(this.installedSkillsDir, skillName);
609
- fs.mkdirSync(targetPath, { recursive: true });
610
- for (const [fileNameTemplate, contentTemplate] of Object.entries(template.files)) {
611
- const fileName = fileNameTemplate.replace(/\{\{name\}\}/g, skillName);
612
- const content = contentTemplate.replace(/\{\{name\}\}/g, skillName);
613
- const filePath = path.join(targetPath, fileName);
614
- fs.writeFileSync(filePath, content);
615
- if (fileName.endsWith('.js')) {
616
- fs.chmodSync(filePath, '755');
617
- }
618
- }
619
- return {
620
- success: true,
621
- name: skillName,
622
- message: `Successfully created skill '${skillName}' from template '${templateName}' at .crewx/skills/${skillName}/`
623
- };
624
- }
625
- validateSkillName(name) {
626
- if (name === '.' || name === '..') {
627
- return false;
628
- }
629
- if (name.includes('/') || name.includes('\\') || name.includes('..')) {
630
- return false;
631
- }
632
- const validSkillNamePattern = /^[a-z0-9-._~]+$/i;
633
- return validSkillNamePattern.test(name);
634
- }
635
- async remove(name) {
636
- if (!this.validateSkillName(name)) {
637
- return {
638
- success: false,
639
- message: `Invalid skill name: '${name}'. Skill name cannot contain path separators (/, \\, ..).`
640
- };
641
- }
642
- const installedPath = path.join(this.installedSkillsDir, name);
643
- if (!fs.existsSync(installedPath)) {
644
- const customPath = path.join(process.cwd(), 'skills', name);
645
- if (fs.existsSync(customPath)) {
646
- return {
647
- success: false,
648
- message: `'${name}' is a custom skill in skills/ directory. Remove it manually if intended.`
649
- };
650
- }
651
- return { success: false, message: `Skill '${name}' not found in installed skills.` };
652
- }
653
- try {
654
- fs.rmSync(installedPath, { recursive: true });
655
- return { success: true, message: `Successfully removed skill '${name}'` };
656
- }
657
- catch (e) {
658
- return { success: false, message: `Failed to remove skill '${name}': ${e}` };
659
- }
660
- }
661
- getAvailableTemplates() {
662
- return ['hello', 'memory', 'api'];
663
- }
664
- };
665
- exports.SkillService = SkillService;
666
- exports.SkillService = SkillService = SkillService_1 = __decorate([
667
- (0, common_1.Injectable)(),
668
- __metadata("design:paramtypes", [])
669
- ], SkillService);
670
- //# sourceMappingURL=skill.service.js.map