@powerformer/refly-cli 0.1.15 → 0.1.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/refly.js +1814 -803
- package/dist/bin/refly.js.map +1 -1
- package/dist/index.d.ts +32 -3
- package/dist/index.js +616 -150
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/skill/SKILL.md +21 -19
- package/skill/references/skill.md +29 -64
- package/skill/registry.json +0 -15
package/dist/index.js
CHANGED
|
@@ -6,6 +6,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __getProtoOf = Object.getPrototypeOf;
|
|
8
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __esm = (fn, res) => function __init() {
|
|
10
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
11
|
+
};
|
|
9
12
|
var __export = (target, all) => {
|
|
10
13
|
for (var name in all)
|
|
11
14
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -28,6 +31,510 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
31
|
));
|
|
29
32
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
33
|
|
|
34
|
+
// ../../node_modules/.pnpm/tsup@8.5.1_@swc+core@1.12.14_@swc+helpers@0.5.17__jiti@2.6.1_postcss@8.5.6_tsx@4.20.6_typescript@5.8.3_yaml@2.8.0/node_modules/tsup/assets/cjs_shims.js
|
|
35
|
+
var init_cjs_shims = __esm({
|
|
36
|
+
"../../node_modules/.pnpm/tsup@8.5.1_@swc+core@1.12.14_@swc+helpers@0.5.17__jiti@2.6.1_postcss@8.5.6_tsx@4.20.6_typescript@5.8.3_yaml@2.8.0/node_modules/tsup/assets/cjs_shims.js"() {
|
|
37
|
+
"use strict";
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// src/config/paths.ts
|
|
42
|
+
function getReflyDir() {
|
|
43
|
+
const dir = path.join(os.homedir(), ".refly");
|
|
44
|
+
ensureDir(dir);
|
|
45
|
+
return dir;
|
|
46
|
+
}
|
|
47
|
+
function getClaudeCommandsDir() {
|
|
48
|
+
return path.join(os.homedir(), ".claude", "commands");
|
|
49
|
+
}
|
|
50
|
+
function ensureDir(dir) {
|
|
51
|
+
if (!fs.existsSync(dir)) {
|
|
52
|
+
fs.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function getConfigPath() {
|
|
56
|
+
return path.join(getReflyDir(), "config.json");
|
|
57
|
+
}
|
|
58
|
+
function getReflySkillsDir() {
|
|
59
|
+
return path.join(getReflyDir(), "skills");
|
|
60
|
+
}
|
|
61
|
+
function getReflyBaseSkillDir() {
|
|
62
|
+
return path.join(getReflySkillsDir(), "base");
|
|
63
|
+
}
|
|
64
|
+
function getReflyDomainSkillDir(skillName) {
|
|
65
|
+
return path.join(getReflySkillsDir(), skillName);
|
|
66
|
+
}
|
|
67
|
+
function getClaudeSkillsDir() {
|
|
68
|
+
return path.join(os.homedir(), ".claude", "skills");
|
|
69
|
+
}
|
|
70
|
+
function getClaudeSkillSymlinkPath(skillName) {
|
|
71
|
+
return path.join(getClaudeSkillsDir(), skillName);
|
|
72
|
+
}
|
|
73
|
+
function ensureReflySkillsDir() {
|
|
74
|
+
const dir = getReflySkillsDir();
|
|
75
|
+
if (!fs.existsSync(dir)) {
|
|
76
|
+
fs.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function ensureClaudeSkillsDir() {
|
|
80
|
+
const dir = getClaudeSkillsDir();
|
|
81
|
+
if (!fs.existsSync(dir)) {
|
|
82
|
+
fs.mkdirSync(dir, { recursive: true, mode: 493 });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
var os, path, fs;
|
|
86
|
+
var init_paths = __esm({
|
|
87
|
+
"src/config/paths.ts"() {
|
|
88
|
+
"use strict";
|
|
89
|
+
init_cjs_shims();
|
|
90
|
+
os = __toESM(require("os"));
|
|
91
|
+
path = __toESM(require("path"));
|
|
92
|
+
fs = __toESM(require("fs"));
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// src/utils/logger.ts
|
|
97
|
+
function redact(message) {
|
|
98
|
+
let result = message;
|
|
99
|
+
for (const pattern of SENSITIVE_PATTERNS) {
|
|
100
|
+
result = result.replace(pattern, "[REDACTED]");
|
|
101
|
+
}
|
|
102
|
+
return result;
|
|
103
|
+
}
|
|
104
|
+
var fs3, path3, LOG_FILE, MAX_LOG_SIZE, LOG_LEVELS, SENSITIVE_PATTERNS, Logger, logger;
|
|
105
|
+
var init_logger = __esm({
|
|
106
|
+
"src/utils/logger.ts"() {
|
|
107
|
+
"use strict";
|
|
108
|
+
init_cjs_shims();
|
|
109
|
+
fs3 = __toESM(require("fs"));
|
|
110
|
+
path3 = __toESM(require("path"));
|
|
111
|
+
init_paths();
|
|
112
|
+
LOG_FILE = "cli.log";
|
|
113
|
+
MAX_LOG_SIZE = 5 * 1024 * 1024;
|
|
114
|
+
LOG_LEVELS = {
|
|
115
|
+
debug: 0,
|
|
116
|
+
info: 1,
|
|
117
|
+
warn: 2,
|
|
118
|
+
error: 3
|
|
119
|
+
};
|
|
120
|
+
SENSITIVE_PATTERNS = [
|
|
121
|
+
/Bearer\s+[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_]+/gi,
|
|
122
|
+
/[A-Za-z0-9]{32,}/g,
|
|
123
|
+
// API keys
|
|
124
|
+
/"(access_?token|refresh_?token|api_?key|secret|password)":\s*"[^"]+"/gi
|
|
125
|
+
];
|
|
126
|
+
Logger = class {
|
|
127
|
+
level = "info";
|
|
128
|
+
logToFile = false;
|
|
129
|
+
setLevel(level) {
|
|
130
|
+
this.level = level;
|
|
131
|
+
}
|
|
132
|
+
enableFileLogging() {
|
|
133
|
+
this.logToFile = true;
|
|
134
|
+
}
|
|
135
|
+
shouldLog(level) {
|
|
136
|
+
return LOG_LEVELS[level] >= LOG_LEVELS[this.level];
|
|
137
|
+
}
|
|
138
|
+
formatMessage(level, message) {
|
|
139
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
140
|
+
const safeMessage = redact(message);
|
|
141
|
+
return `[${timestamp}] [${level.toUpperCase()}] ${safeMessage}`;
|
|
142
|
+
}
|
|
143
|
+
writeToFile(formatted) {
|
|
144
|
+
if (!this.logToFile) return;
|
|
145
|
+
try {
|
|
146
|
+
const logPath = path3.join(getReflyDir(), LOG_FILE);
|
|
147
|
+
try {
|
|
148
|
+
const stats = fs3.statSync(logPath);
|
|
149
|
+
if (stats.size > MAX_LOG_SIZE) {
|
|
150
|
+
fs3.renameSync(logPath, `${logPath}.old`);
|
|
151
|
+
}
|
|
152
|
+
} catch {
|
|
153
|
+
}
|
|
154
|
+
fs3.appendFileSync(logPath, `${formatted}
|
|
155
|
+
`);
|
|
156
|
+
} catch {
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
debug(message, ...args) {
|
|
160
|
+
if (!this.shouldLog("debug")) return;
|
|
161
|
+
const formatted = this.formatMessage("debug", this.interpolate(message, args));
|
|
162
|
+
this.writeToFile(formatted);
|
|
163
|
+
}
|
|
164
|
+
info(message, ...args) {
|
|
165
|
+
if (!this.shouldLog("info")) return;
|
|
166
|
+
const formatted = this.formatMessage("info", this.interpolate(message, args));
|
|
167
|
+
this.writeToFile(formatted);
|
|
168
|
+
}
|
|
169
|
+
warn(message, ...args) {
|
|
170
|
+
if (!this.shouldLog("warn")) return;
|
|
171
|
+
const formatted = this.formatMessage("warn", this.interpolate(message, args));
|
|
172
|
+
this.writeToFile(formatted);
|
|
173
|
+
}
|
|
174
|
+
error(message, ...args) {
|
|
175
|
+
if (!this.shouldLog("error")) return;
|
|
176
|
+
const formatted = this.formatMessage("error", this.interpolate(message, args));
|
|
177
|
+
this.writeToFile(formatted);
|
|
178
|
+
}
|
|
179
|
+
interpolate(message, args) {
|
|
180
|
+
if (args.length === 0) return message;
|
|
181
|
+
return `${message} ${args.map((a) => JSON.stringify(a)).join(" ")}`;
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
logger = new Logger();
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// src/skill/symlink.ts
|
|
189
|
+
var symlink_exports = {};
|
|
190
|
+
__export(symlink_exports, {
|
|
191
|
+
createReflySkillWithSymlink: () => createReflySkillWithSymlink,
|
|
192
|
+
createSkillSymlink: () => createSkillSymlink,
|
|
193
|
+
deleteDomainSkillWithSymlink: () => deleteDomainSkillWithSymlink,
|
|
194
|
+
generateReflySkillMd: () => generateReflySkillMd,
|
|
195
|
+
initializeBaseSkillSymlink: () => initializeBaseSkillSymlink,
|
|
196
|
+
isSkillSymlinkValid: () => isSkillSymlinkValid,
|
|
197
|
+
listSkillSymlinks: () => listSkillSymlinks,
|
|
198
|
+
parseReflySkillMd: () => parseReflySkillMd,
|
|
199
|
+
removeSkillSymlink: () => removeSkillSymlink
|
|
200
|
+
});
|
|
201
|
+
function createSkillSymlink(skillName) {
|
|
202
|
+
const reflyPath = skillName === "refly" ? getReflyBaseSkillDir() : getReflyDomainSkillDir(skillName);
|
|
203
|
+
const claudePath = getClaudeSkillSymlinkPath(skillName);
|
|
204
|
+
try {
|
|
205
|
+
ensureReflySkillsDir();
|
|
206
|
+
ensureClaudeSkillsDir();
|
|
207
|
+
if (!fs5.existsSync(reflyPath)) {
|
|
208
|
+
return {
|
|
209
|
+
success: false,
|
|
210
|
+
skillName,
|
|
211
|
+
reflyPath,
|
|
212
|
+
claudePath,
|
|
213
|
+
error: `Source skill directory does not exist: ${reflyPath}`
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
if (fs5.existsSync(claudePath) || fs5.lstatSync(claudePath).isSymbolicLink()) {
|
|
217
|
+
const stat = fs5.lstatSync(claudePath);
|
|
218
|
+
if (stat.isSymbolicLink()) {
|
|
219
|
+
fs5.unlinkSync(claudePath);
|
|
220
|
+
logger.debug(`Removed existing symlink: ${claudePath}`);
|
|
221
|
+
} else if (stat.isDirectory()) {
|
|
222
|
+
logger.warn(`Cannot create symlink: ${claudePath} is a directory, not a symlink`);
|
|
223
|
+
return {
|
|
224
|
+
success: false,
|
|
225
|
+
skillName,
|
|
226
|
+
reflyPath,
|
|
227
|
+
claudePath,
|
|
228
|
+
error: `Target path is a directory, not a symlink: ${claudePath}`
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
fs5.symlinkSync(reflyPath, claudePath, "dir");
|
|
233
|
+
logger.info(`Created symlink: ${claudePath} -> ${reflyPath}`);
|
|
234
|
+
return {
|
|
235
|
+
success: true,
|
|
236
|
+
skillName,
|
|
237
|
+
reflyPath,
|
|
238
|
+
claudePath
|
|
239
|
+
};
|
|
240
|
+
} catch (err) {
|
|
241
|
+
if (err.code === "ENOENT") {
|
|
242
|
+
try {
|
|
243
|
+
fs5.symlinkSync(reflyPath, claudePath, "dir");
|
|
244
|
+
logger.info(`Created symlink: ${claudePath} -> ${reflyPath}`);
|
|
245
|
+
return {
|
|
246
|
+
success: true,
|
|
247
|
+
skillName,
|
|
248
|
+
reflyPath,
|
|
249
|
+
claudePath
|
|
250
|
+
};
|
|
251
|
+
} catch (innerErr) {
|
|
252
|
+
return {
|
|
253
|
+
success: false,
|
|
254
|
+
skillName,
|
|
255
|
+
reflyPath,
|
|
256
|
+
claudePath,
|
|
257
|
+
error: innerErr.message
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return {
|
|
262
|
+
success: false,
|
|
263
|
+
skillName,
|
|
264
|
+
reflyPath,
|
|
265
|
+
claudePath,
|
|
266
|
+
error: err.message
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
function removeSkillSymlink(skillName) {
|
|
271
|
+
const claudePath = getClaudeSkillSymlinkPath(skillName);
|
|
272
|
+
try {
|
|
273
|
+
if (!fs5.existsSync(claudePath)) {
|
|
274
|
+
logger.debug(`Symlink not found: ${claudePath}`);
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
const stat = fs5.lstatSync(claudePath);
|
|
278
|
+
if (!stat.isSymbolicLink()) {
|
|
279
|
+
logger.warn(`Not a symlink: ${claudePath}`);
|
|
280
|
+
return false;
|
|
281
|
+
}
|
|
282
|
+
fs5.unlinkSync(claudePath);
|
|
283
|
+
logger.info(`Removed symlink: ${claudePath}`);
|
|
284
|
+
return true;
|
|
285
|
+
} catch (err) {
|
|
286
|
+
logger.error(`Failed to remove symlink ${claudePath}:`, err);
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
function isSkillSymlinkValid(skillName) {
|
|
291
|
+
const claudePath = getClaudeSkillSymlinkPath(skillName);
|
|
292
|
+
const expectedTarget = skillName === "refly" ? getReflyBaseSkillDir() : getReflyDomainSkillDir(skillName);
|
|
293
|
+
try {
|
|
294
|
+
if (!fs5.existsSync(claudePath)) {
|
|
295
|
+
return { exists: false, isSymlink: false, isValid: false };
|
|
296
|
+
}
|
|
297
|
+
const stat = fs5.lstatSync(claudePath);
|
|
298
|
+
if (!stat.isSymbolicLink()) {
|
|
299
|
+
return { exists: true, isSymlink: false, isValid: false };
|
|
300
|
+
}
|
|
301
|
+
const target = fs5.readlinkSync(claudePath);
|
|
302
|
+
const resolvedTarget = path5.resolve(path5.dirname(claudePath), target);
|
|
303
|
+
const isValid2 = resolvedTarget === expectedTarget && fs5.existsSync(resolvedTarget);
|
|
304
|
+
return {
|
|
305
|
+
exists: true,
|
|
306
|
+
isSymlink: true,
|
|
307
|
+
isValid: isValid2,
|
|
308
|
+
target: resolvedTarget
|
|
309
|
+
};
|
|
310
|
+
} catch {
|
|
311
|
+
return { exists: false, isSymlink: false, isValid: false };
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
function initializeBaseSkillSymlink() {
|
|
315
|
+
const baseDir = getReflyBaseSkillDir();
|
|
316
|
+
ensureDir(baseDir);
|
|
317
|
+
ensureDir(path5.join(baseDir, "rules"));
|
|
318
|
+
return createSkillSymlink("refly");
|
|
319
|
+
}
|
|
320
|
+
function createReflySkillWithSymlink(skillName, skillMdContent) {
|
|
321
|
+
const skillDir = getReflyDomainSkillDir(skillName);
|
|
322
|
+
try {
|
|
323
|
+
ensureReflySkillsDir();
|
|
324
|
+
if (fs5.existsSync(skillDir)) {
|
|
325
|
+
return {
|
|
326
|
+
success: false,
|
|
327
|
+
skillName,
|
|
328
|
+
reflyPath: skillDir,
|
|
329
|
+
claudePath: getClaudeSkillSymlinkPath(skillName),
|
|
330
|
+
error: `Skill directory already exists: ${skillDir}`
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
fs5.mkdirSync(skillDir, { recursive: true, mode: 493 });
|
|
334
|
+
const skillMdPath = path5.join(skillDir, "SKILL.md");
|
|
335
|
+
fs5.writeFileSync(skillMdPath, skillMdContent, { encoding: "utf-8", mode: 420 });
|
|
336
|
+
logger.debug(`Created SKILL.md: ${skillMdPath}`);
|
|
337
|
+
return createSkillSymlink(skillName);
|
|
338
|
+
} catch (err) {
|
|
339
|
+
return {
|
|
340
|
+
success: false,
|
|
341
|
+
skillName,
|
|
342
|
+
reflyPath: skillDir,
|
|
343
|
+
claudePath: getClaudeSkillSymlinkPath(skillName),
|
|
344
|
+
error: err.message
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
function deleteDomainSkillWithSymlink(skillName) {
|
|
349
|
+
const symlinkRemoved = removeSkillSymlink(skillName);
|
|
350
|
+
const skillDir = getReflyDomainSkillDir(skillName);
|
|
351
|
+
let directoryRemoved = false;
|
|
352
|
+
try {
|
|
353
|
+
if (fs5.existsSync(skillDir)) {
|
|
354
|
+
fs5.rmSync(skillDir, { recursive: true, force: true });
|
|
355
|
+
directoryRemoved = true;
|
|
356
|
+
logger.info(`Removed skill directory: ${skillDir}`);
|
|
357
|
+
}
|
|
358
|
+
} catch (err) {
|
|
359
|
+
logger.error(`Failed to remove skill directory ${skillDir}:`, err);
|
|
360
|
+
}
|
|
361
|
+
return { symlinkRemoved, directoryRemoved };
|
|
362
|
+
}
|
|
363
|
+
function listSkillSymlinks() {
|
|
364
|
+
const claudeSkillsDir = getClaudeSkillsDir();
|
|
365
|
+
const results = [];
|
|
366
|
+
if (!fs5.existsSync(claudeSkillsDir)) {
|
|
367
|
+
return results;
|
|
368
|
+
}
|
|
369
|
+
try {
|
|
370
|
+
const entries = fs5.readdirSync(claudeSkillsDir, { withFileTypes: true });
|
|
371
|
+
for (const entry of entries) {
|
|
372
|
+
const fullPath = path5.join(claudeSkillsDir, entry.name);
|
|
373
|
+
try {
|
|
374
|
+
const stat = fs5.lstatSync(fullPath);
|
|
375
|
+
if (stat.isSymbolicLink()) {
|
|
376
|
+
const target = fs5.readlinkSync(fullPath);
|
|
377
|
+
const resolvedTarget = path5.resolve(path5.dirname(fullPath), target);
|
|
378
|
+
const isValid2 = fs5.existsSync(resolvedTarget);
|
|
379
|
+
results.push({
|
|
380
|
+
name: entry.name,
|
|
381
|
+
claudePath: fullPath,
|
|
382
|
+
target: resolvedTarget,
|
|
383
|
+
isValid: isValid2
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
} catch {
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
} catch {
|
|
390
|
+
}
|
|
391
|
+
return results;
|
|
392
|
+
}
|
|
393
|
+
function generateReflySkillMd(options) {
|
|
394
|
+
const {
|
|
395
|
+
name,
|
|
396
|
+
displayName,
|
|
397
|
+
description,
|
|
398
|
+
skillId,
|
|
399
|
+
workflowId,
|
|
400
|
+
installationId,
|
|
401
|
+
triggers = [],
|
|
402
|
+
tags = [],
|
|
403
|
+
version = "1.0.0",
|
|
404
|
+
inputSchema,
|
|
405
|
+
outputSchema
|
|
406
|
+
} = options;
|
|
407
|
+
const frontmatterLines = ["---", `name: ${name}`];
|
|
408
|
+
frontmatterLines.push(`description: ${description}`);
|
|
409
|
+
if (tags.length > 0) {
|
|
410
|
+
frontmatterLines.push("tags:");
|
|
411
|
+
frontmatterLines.push(...tags.map((t) => ` - ${t}`));
|
|
412
|
+
}
|
|
413
|
+
frontmatterLines.push(`version: ${version}`);
|
|
414
|
+
frontmatterLines.push(`skillId: ${skillId}`);
|
|
415
|
+
frontmatterLines.push(`workflowId: ${workflowId}`);
|
|
416
|
+
if (installationId) {
|
|
417
|
+
frontmatterLines.push(`installationId: ${installationId}`);
|
|
418
|
+
}
|
|
419
|
+
if (triggers.length > 0) {
|
|
420
|
+
frontmatterLines.push("triggers:");
|
|
421
|
+
frontmatterLines.push(...triggers.map((t) => ` - ${t}`));
|
|
422
|
+
}
|
|
423
|
+
frontmatterLines.push("---");
|
|
424
|
+
const title = displayName || name.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
425
|
+
const inputExample = inputSchema ? JSON.stringify(inputSchema, null, 2) : `{
|
|
426
|
+
"query": "your input here"
|
|
427
|
+
}`;
|
|
428
|
+
const runCommand = installationId ? `refly skill run ${installationId} --input '${inputSchema ? JSON.stringify(inputSchema) : "{}"}'` : `refly workflow run ${workflowId} --input '${inputSchema ? JSON.stringify(inputSchema) : "{}"}'`;
|
|
429
|
+
const outputSection = outputSchema ? `The skill returns:
|
|
430
|
+
|
|
431
|
+
\`\`\`json
|
|
432
|
+
${JSON.stringify(outputSchema, null, 2)}
|
|
433
|
+
\`\`\`` : "The skill returns the workflow execution result.";
|
|
434
|
+
const content = `
|
|
435
|
+
|
|
436
|
+
# ${title}
|
|
437
|
+
|
|
438
|
+
${description}
|
|
439
|
+
|
|
440
|
+
## Usage
|
|
441
|
+
|
|
442
|
+
This skill is executed via Refly CLI:
|
|
443
|
+
|
|
444
|
+
\`\`\`bash
|
|
445
|
+
${runCommand}
|
|
446
|
+
\`\`\`
|
|
447
|
+
|
|
448
|
+
## Input
|
|
449
|
+
|
|
450
|
+
Provide input as JSON:
|
|
451
|
+
|
|
452
|
+
\`\`\`json
|
|
453
|
+
${inputExample}
|
|
454
|
+
\`\`\`
|
|
455
|
+
|
|
456
|
+
## Output
|
|
457
|
+
|
|
458
|
+
${outputSection}
|
|
459
|
+
|
|
460
|
+
## Rules
|
|
461
|
+
|
|
462
|
+
For workflow operations, refer to the base skill rules:
|
|
463
|
+
- Workflow: \`~/.claude/skills/refly/rules/workflow.md\`
|
|
464
|
+
- Node: \`~/.claude/skills/refly/rules/node.md\`
|
|
465
|
+
- File: \`~/.claude/skills/refly/rules/file.md\`
|
|
466
|
+
`;
|
|
467
|
+
return frontmatterLines.join("\n") + content;
|
|
468
|
+
}
|
|
469
|
+
function parseReflySkillMd(content) {
|
|
470
|
+
const frontmatterRegex = /^---\n([\s\S]*?)\n---\n?([\s\S]*)$/;
|
|
471
|
+
const match = content.match(frontmatterRegex);
|
|
472
|
+
if (!match) {
|
|
473
|
+
throw new Error("Invalid SKILL.md format: missing frontmatter");
|
|
474
|
+
}
|
|
475
|
+
const [, frontmatterStr, body] = match;
|
|
476
|
+
const meta = {};
|
|
477
|
+
const lines = frontmatterStr.split("\n");
|
|
478
|
+
let currentKey = null;
|
|
479
|
+
let currentArray = [];
|
|
480
|
+
for (const line of lines) {
|
|
481
|
+
const trimmed = line.trim();
|
|
482
|
+
if (trimmed.startsWith("- ")) {
|
|
483
|
+
if (currentKey) {
|
|
484
|
+
currentArray.push(trimmed.slice(2).trim());
|
|
485
|
+
}
|
|
486
|
+
continue;
|
|
487
|
+
}
|
|
488
|
+
if (currentKey && currentArray.length > 0) {
|
|
489
|
+
meta[currentKey] = currentArray;
|
|
490
|
+
currentArray = [];
|
|
491
|
+
currentKey = null;
|
|
492
|
+
}
|
|
493
|
+
const colonIndex = trimmed.indexOf(":");
|
|
494
|
+
if (colonIndex > 0) {
|
|
495
|
+
const key = trimmed.slice(0, colonIndex).trim();
|
|
496
|
+
const value = trimmed.slice(colonIndex + 1).trim();
|
|
497
|
+
if (value === "") {
|
|
498
|
+
currentKey = key;
|
|
499
|
+
currentArray = [];
|
|
500
|
+
} else {
|
|
501
|
+
meta[key] = value;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
if (currentKey && currentArray.length > 0) {
|
|
506
|
+
meta[currentKey] = currentArray;
|
|
507
|
+
}
|
|
508
|
+
if (!meta.name) {
|
|
509
|
+
throw new Error('Invalid SKILL.md: missing required field "name"');
|
|
510
|
+
}
|
|
511
|
+
if (!meta.description) {
|
|
512
|
+
throw new Error('Invalid SKILL.md: missing required field "description"');
|
|
513
|
+
}
|
|
514
|
+
if (!meta.skillId) {
|
|
515
|
+
throw new Error('Invalid SKILL.md: missing required field "skillId"');
|
|
516
|
+
}
|
|
517
|
+
if (!meta.workflowId) {
|
|
518
|
+
throw new Error('Invalid SKILL.md: missing required field "workflowId"');
|
|
519
|
+
}
|
|
520
|
+
return {
|
|
521
|
+
meta,
|
|
522
|
+
body: body.trim(),
|
|
523
|
+
raw: content
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
var fs5, path5;
|
|
527
|
+
var init_symlink = __esm({
|
|
528
|
+
"src/skill/symlink.ts"() {
|
|
529
|
+
"use strict";
|
|
530
|
+
init_cjs_shims();
|
|
531
|
+
fs5 = __toESM(require("fs"));
|
|
532
|
+
path5 = __toESM(require("path"));
|
|
533
|
+
init_paths();
|
|
534
|
+
init_logger();
|
|
535
|
+
}
|
|
536
|
+
});
|
|
537
|
+
|
|
31
538
|
// src/index.ts
|
|
32
539
|
var src_exports = {};
|
|
33
540
|
__export(src_exports, {
|
|
@@ -45,8 +552,16 @@ __export(src_exports, {
|
|
|
45
552
|
verifyConnection: () => verifyConnection
|
|
46
553
|
});
|
|
47
554
|
module.exports = __toCommonJS(src_exports);
|
|
555
|
+
init_cjs_shims();
|
|
556
|
+
|
|
557
|
+
// src/utils/output.ts
|
|
558
|
+
init_cjs_shims();
|
|
559
|
+
|
|
560
|
+
// src/utils/formatter.ts
|
|
561
|
+
init_cjs_shims();
|
|
48
562
|
|
|
49
563
|
// src/utils/ui.ts
|
|
564
|
+
init_cjs_shims();
|
|
50
565
|
var Style = {
|
|
51
566
|
// Reset
|
|
52
567
|
RESET: "\x1B[0m",
|
|
@@ -146,12 +661,14 @@ var ErrorCodes = {
|
|
|
146
661
|
};
|
|
147
662
|
|
|
148
663
|
// src/utils/errors.ts
|
|
664
|
+
init_cjs_shims();
|
|
149
665
|
var CLIError = class extends Error {
|
|
150
|
-
constructor(code, message, details, hint) {
|
|
666
|
+
constructor(code, message, details, hint, suggestedFix) {
|
|
151
667
|
super(message);
|
|
152
668
|
this.code = code;
|
|
153
669
|
this.details = details;
|
|
154
670
|
this.hint = hint;
|
|
671
|
+
this.suggestedFix = suggestedFix;
|
|
155
672
|
this.name = "CLIError";
|
|
156
673
|
}
|
|
157
674
|
};
|
|
@@ -172,11 +689,15 @@ var NetworkError = class extends CLIError {
|
|
|
172
689
|
};
|
|
173
690
|
|
|
174
691
|
// src/config/config.ts
|
|
692
|
+
init_cjs_shims();
|
|
175
693
|
var fs2 = __toESM(require("fs"));
|
|
176
694
|
var path2 = __toESM(require("path"));
|
|
177
695
|
var os2 = __toESM(require("os"));
|
|
178
696
|
var crypto = __toESM(require("crypto"));
|
|
179
697
|
|
|
698
|
+
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/index.js
|
|
699
|
+
init_cjs_shims();
|
|
700
|
+
|
|
180
701
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js
|
|
181
702
|
var external_exports = {};
|
|
182
703
|
__export(external_exports, {
|
|
@@ -288,8 +809,19 @@ __export(external_exports, {
|
|
|
288
809
|
util: () => util,
|
|
289
810
|
void: () => voidType
|
|
290
811
|
});
|
|
812
|
+
init_cjs_shims();
|
|
813
|
+
|
|
814
|
+
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.js
|
|
815
|
+
init_cjs_shims();
|
|
816
|
+
|
|
817
|
+
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.js
|
|
818
|
+
init_cjs_shims();
|
|
819
|
+
|
|
820
|
+
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.js
|
|
821
|
+
init_cjs_shims();
|
|
291
822
|
|
|
292
823
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.js
|
|
824
|
+
init_cjs_shims();
|
|
293
825
|
var util;
|
|
294
826
|
(function(util2) {
|
|
295
827
|
util2.assertEqual = (_) => {
|
|
@@ -654,9 +1186,10 @@ function getErrorMap() {
|
|
|
654
1186
|
}
|
|
655
1187
|
|
|
656
1188
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
|
|
1189
|
+
init_cjs_shims();
|
|
657
1190
|
var makeIssue = (params) => {
|
|
658
|
-
const { data, path:
|
|
659
|
-
const fullPath = [...
|
|
1191
|
+
const { data, path: path7, errorMaps, issueData } = params;
|
|
1192
|
+
const fullPath = [...path7, ...issueData.path || []];
|
|
660
1193
|
const fullIssue = {
|
|
661
1194
|
...issueData,
|
|
662
1195
|
path: fullPath
|
|
@@ -763,7 +1296,11 @@ var isDirty = (x) => x.status === "dirty";
|
|
|
763
1296
|
var isValid = (x) => x.status === "valid";
|
|
764
1297
|
var isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise;
|
|
765
1298
|
|
|
1299
|
+
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js
|
|
1300
|
+
init_cjs_shims();
|
|
1301
|
+
|
|
766
1302
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js
|
|
1303
|
+
init_cjs_shims();
|
|
767
1304
|
var errorUtil;
|
|
768
1305
|
(function(errorUtil2) {
|
|
769
1306
|
errorUtil2.errToObj = (message) => typeof message === "string" ? { message } : message || {};
|
|
@@ -772,11 +1309,11 @@ var errorUtil;
|
|
|
772
1309
|
|
|
773
1310
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js
|
|
774
1311
|
var ParseInputLazyPath = class {
|
|
775
|
-
constructor(parent, value,
|
|
1312
|
+
constructor(parent, value, path7, key) {
|
|
776
1313
|
this._cachedPath = [];
|
|
777
1314
|
this.parent = parent;
|
|
778
1315
|
this.data = value;
|
|
779
|
-
this._path =
|
|
1316
|
+
this._path = path7;
|
|
780
1317
|
this._key = key;
|
|
781
1318
|
}
|
|
782
1319
|
get path() {
|
|
@@ -4218,31 +4755,8 @@ var coerce = {
|
|
|
4218
4755
|
};
|
|
4219
4756
|
var NEVER = INVALID;
|
|
4220
4757
|
|
|
4221
|
-
// src/config/paths.ts
|
|
4222
|
-
var os = __toESM(require("os"));
|
|
4223
|
-
var path = __toESM(require("path"));
|
|
4224
|
-
var fs = __toESM(require("fs"));
|
|
4225
|
-
function getReflyDir() {
|
|
4226
|
-
const dir = path.join(os.homedir(), ".refly");
|
|
4227
|
-
ensureDir(dir);
|
|
4228
|
-
return dir;
|
|
4229
|
-
}
|
|
4230
|
-
function getClaudeSkillDir() {
|
|
4231
|
-
return path.join(os.homedir(), ".claude", "skills", "refly");
|
|
4232
|
-
}
|
|
4233
|
-
function getClaudeCommandsDir() {
|
|
4234
|
-
return path.join(os.homedir(), ".claude", "commands");
|
|
4235
|
-
}
|
|
4236
|
-
function ensureDir(dir) {
|
|
4237
|
-
if (!fs.existsSync(dir)) {
|
|
4238
|
-
fs.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
4239
|
-
}
|
|
4240
|
-
}
|
|
4241
|
-
function getConfigPath() {
|
|
4242
|
-
return path.join(getReflyDir(), "config.json");
|
|
4243
|
-
}
|
|
4244
|
-
|
|
4245
4758
|
// src/config/config.ts
|
|
4759
|
+
init_paths();
|
|
4246
4760
|
var ConfigSchema = external_exports.object({
|
|
4247
4761
|
version: external_exports.number().default(1),
|
|
4248
4762
|
auth: external_exports.object({
|
|
@@ -4272,7 +4786,7 @@ var ConfigSchema = external_exports.object({
|
|
|
4272
4786
|
installedAt: external_exports.string().optional()
|
|
4273
4787
|
}).optional()
|
|
4274
4788
|
});
|
|
4275
|
-
var DEFAULT_API_ENDPOINT = "https://api.
|
|
4789
|
+
var DEFAULT_API_ENDPOINT = "https://refly-api.powerformer.net";
|
|
4276
4790
|
var DEFAULT_CONFIG = {
|
|
4277
4791
|
version: 1,
|
|
4278
4792
|
api: {
|
|
@@ -4370,101 +4884,17 @@ function getApiKey() {
|
|
|
4370
4884
|
}
|
|
4371
4885
|
|
|
4372
4886
|
// src/api/client.ts
|
|
4887
|
+
init_cjs_shims();
|
|
4373
4888
|
var fs4 = __toESM(require("fs"));
|
|
4374
4889
|
var import_node_fs = require("fs");
|
|
4375
4890
|
var path4 = __toESM(require("path"));
|
|
4376
4891
|
var import_mime = __toESM(require("mime"));
|
|
4377
|
-
|
|
4378
|
-
// src/utils/logger.ts
|
|
4379
|
-
var fs3 = __toESM(require("fs"));
|
|
4380
|
-
var path3 = __toESM(require("path"));
|
|
4381
|
-
var LOG_FILE = "cli.log";
|
|
4382
|
-
var MAX_LOG_SIZE = 5 * 1024 * 1024;
|
|
4383
|
-
var LOG_LEVELS = {
|
|
4384
|
-
debug: 0,
|
|
4385
|
-
info: 1,
|
|
4386
|
-
warn: 2,
|
|
4387
|
-
error: 3
|
|
4388
|
-
};
|
|
4389
|
-
var SENSITIVE_PATTERNS = [
|
|
4390
|
-
/Bearer\s+[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_]+/gi,
|
|
4391
|
-
/[A-Za-z0-9]{32,}/g,
|
|
4392
|
-
// API keys
|
|
4393
|
-
/"(access_?token|refresh_?token|api_?key|secret|password)":\s*"[^"]+"/gi
|
|
4394
|
-
];
|
|
4395
|
-
function redact(message) {
|
|
4396
|
-
let result = message;
|
|
4397
|
-
for (const pattern of SENSITIVE_PATTERNS) {
|
|
4398
|
-
result = result.replace(pattern, "[REDACTED]");
|
|
4399
|
-
}
|
|
4400
|
-
return result;
|
|
4401
|
-
}
|
|
4402
|
-
var Logger = class {
|
|
4403
|
-
level = "info";
|
|
4404
|
-
logToFile = false;
|
|
4405
|
-
setLevel(level) {
|
|
4406
|
-
this.level = level;
|
|
4407
|
-
}
|
|
4408
|
-
enableFileLogging() {
|
|
4409
|
-
this.logToFile = true;
|
|
4410
|
-
}
|
|
4411
|
-
shouldLog(level) {
|
|
4412
|
-
return LOG_LEVELS[level] >= LOG_LEVELS[this.level];
|
|
4413
|
-
}
|
|
4414
|
-
formatMessage(level, message) {
|
|
4415
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
4416
|
-
const safeMessage = redact(message);
|
|
4417
|
-
return `[${timestamp}] [${level.toUpperCase()}] ${safeMessage}`;
|
|
4418
|
-
}
|
|
4419
|
-
writeToFile(formatted) {
|
|
4420
|
-
if (!this.logToFile) return;
|
|
4421
|
-
try {
|
|
4422
|
-
const logPath = path3.join(getReflyDir(), LOG_FILE);
|
|
4423
|
-
try {
|
|
4424
|
-
const stats = fs3.statSync(logPath);
|
|
4425
|
-
if (stats.size > MAX_LOG_SIZE) {
|
|
4426
|
-
fs3.renameSync(logPath, `${logPath}.old`);
|
|
4427
|
-
}
|
|
4428
|
-
} catch {
|
|
4429
|
-
}
|
|
4430
|
-
fs3.appendFileSync(logPath, `${formatted}
|
|
4431
|
-
`);
|
|
4432
|
-
} catch {
|
|
4433
|
-
}
|
|
4434
|
-
}
|
|
4435
|
-
debug(message, ...args) {
|
|
4436
|
-
if (!this.shouldLog("debug")) return;
|
|
4437
|
-
const formatted = this.formatMessage("debug", this.interpolate(message, args));
|
|
4438
|
-
this.writeToFile(formatted);
|
|
4439
|
-
}
|
|
4440
|
-
info(message, ...args) {
|
|
4441
|
-
if (!this.shouldLog("info")) return;
|
|
4442
|
-
const formatted = this.formatMessage("info", this.interpolate(message, args));
|
|
4443
|
-
this.writeToFile(formatted);
|
|
4444
|
-
}
|
|
4445
|
-
warn(message, ...args) {
|
|
4446
|
-
if (!this.shouldLog("warn")) return;
|
|
4447
|
-
const formatted = this.formatMessage("warn", this.interpolate(message, args));
|
|
4448
|
-
this.writeToFile(formatted);
|
|
4449
|
-
}
|
|
4450
|
-
error(message, ...args) {
|
|
4451
|
-
if (!this.shouldLog("error")) return;
|
|
4452
|
-
const formatted = this.formatMessage("error", this.interpolate(message, args));
|
|
4453
|
-
this.writeToFile(formatted);
|
|
4454
|
-
}
|
|
4455
|
-
interpolate(message, args) {
|
|
4456
|
-
if (args.length === 0) return message;
|
|
4457
|
-
return `${message} ${args.map((a) => JSON.stringify(a)).join(" ")}`;
|
|
4458
|
-
}
|
|
4459
|
-
};
|
|
4460
|
-
var logger = new Logger();
|
|
4461
|
-
|
|
4462
|
-
// src/api/client.ts
|
|
4892
|
+
init_logger();
|
|
4463
4893
|
var DEFAULT_TIMEOUT = 3e4;
|
|
4464
|
-
async function apiRequest(
|
|
4894
|
+
async function apiRequest(path7, options = {}) {
|
|
4465
4895
|
const { method = "GET", body, query, timeout = DEFAULT_TIMEOUT, requireAuth = true } = options;
|
|
4466
4896
|
const endpoint = getApiEndpoint();
|
|
4467
|
-
let url = `${endpoint}${
|
|
4897
|
+
let url = `${endpoint}${path7}`;
|
|
4468
4898
|
if (query && Object.keys(query).length > 0) {
|
|
4469
4899
|
const params = new URLSearchParams(query);
|
|
4470
4900
|
url = `${url}?${params.toString()}`;
|
|
@@ -4502,7 +4932,7 @@ async function apiRequest(path6, options = {}) {
|
|
|
4502
4932
|
const controller = new AbortController();
|
|
4503
4933
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
4504
4934
|
try {
|
|
4505
|
-
logger.debug(`API Request: ${method} ${
|
|
4935
|
+
logger.debug(`API Request: ${method} ${path7}`);
|
|
4506
4936
|
const response = await fetch(url, {
|
|
4507
4937
|
method,
|
|
4508
4938
|
headers,
|
|
@@ -4594,7 +5024,8 @@ function mapAPIError(status, response) {
|
|
|
4594
5024
|
cliError.code || "UNKNOWN",
|
|
4595
5025
|
cliError.message || "Unknown error",
|
|
4596
5026
|
void 0,
|
|
4597
|
-
cliError.hint
|
|
5027
|
+
cliError.hint,
|
|
5028
|
+
cliError.suggestedFix
|
|
4598
5029
|
);
|
|
4599
5030
|
}
|
|
4600
5031
|
const errCode = response.errCode ?? response.error ?? "UNKNOWN";
|
|
@@ -4646,21 +5077,42 @@ async function verifyConnection() {
|
|
|
4646
5077
|
}
|
|
4647
5078
|
|
|
4648
5079
|
// src/skill/installer.ts
|
|
4649
|
-
|
|
4650
|
-
var
|
|
5080
|
+
init_cjs_shims();
|
|
5081
|
+
var fs6 = __toESM(require("fs"));
|
|
5082
|
+
var path6 = __toESM(require("path"));
|
|
5083
|
+
init_paths();
|
|
5084
|
+
init_logger();
|
|
5085
|
+
init_symlink();
|
|
5086
|
+
function removeOldSkillDirectory() {
|
|
5087
|
+
const claudeSkillPath = getClaudeSkillSymlinkPath("refly");
|
|
5088
|
+
if (!fs6.existsSync(claudeSkillPath)) {
|
|
5089
|
+
return;
|
|
5090
|
+
}
|
|
5091
|
+
try {
|
|
5092
|
+
const stat = fs6.lstatSync(claudeSkillPath);
|
|
5093
|
+
if (stat.isSymbolicLink()) {
|
|
5094
|
+
fs6.unlinkSync(claudeSkillPath);
|
|
5095
|
+
} else if (stat.isDirectory()) {
|
|
5096
|
+
fs6.rmSync(claudeSkillPath, { recursive: true, force: true });
|
|
5097
|
+
logger.info("Removed old skill directory");
|
|
5098
|
+
}
|
|
5099
|
+
} catch (err) {
|
|
5100
|
+
logger.warn("Failed to remove old directory:", err);
|
|
5101
|
+
}
|
|
5102
|
+
}
|
|
4651
5103
|
function getPackageSkillDir() {
|
|
4652
5104
|
const possiblePaths = [
|
|
4653
|
-
|
|
5105
|
+
path6.join(__dirname, "..", "..", "skill"),
|
|
4654
5106
|
// Built package: dist/bin/../../skill
|
|
4655
|
-
|
|
5107
|
+
path6.join(__dirname, "..", "..", "..", "skill"),
|
|
4656
5108
|
// Development: dist/bin/../../../skill
|
|
4657
|
-
|
|
5109
|
+
path6.join(__dirname, "..", "skill")
|
|
4658
5110
|
// Alternative: dist/../skill
|
|
4659
5111
|
];
|
|
4660
5112
|
logger.debug("Looking for skill files, __dirname:", __dirname);
|
|
4661
5113
|
for (const p of possiblePaths) {
|
|
4662
|
-
const resolved =
|
|
4663
|
-
const exists =
|
|
5114
|
+
const resolved = path6.resolve(p);
|
|
5115
|
+
const exists = fs6.existsSync(resolved);
|
|
4664
5116
|
logger.debug(` Checking path: ${resolved} - exists: ${exists}`);
|
|
4665
5117
|
if (exists) {
|
|
4666
5118
|
return resolved;
|
|
@@ -4672,42 +5124,52 @@ function installSkill() {
|
|
|
4672
5124
|
const result = {
|
|
4673
5125
|
skillInstalled: false,
|
|
4674
5126
|
skillPath: null,
|
|
5127
|
+
symlinkPath: null,
|
|
4675
5128
|
commandsInstalled: false,
|
|
4676
5129
|
commandsPath: null,
|
|
4677
5130
|
version: getSkillVersion()
|
|
4678
5131
|
};
|
|
4679
5132
|
const sourceDir = getPackageSkillDir();
|
|
4680
5133
|
logger.debug("Source skill directory:", sourceDir);
|
|
4681
|
-
|
|
5134
|
+
ensureReflySkillsDir();
|
|
5135
|
+
const targetDir = getReflyBaseSkillDir();
|
|
4682
5136
|
logger.debug("Target skill directory:", targetDir);
|
|
4683
5137
|
try {
|
|
4684
5138
|
ensureDir(targetDir);
|
|
4685
|
-
ensureDir(
|
|
5139
|
+
ensureDir(path6.join(targetDir, "rules"));
|
|
4686
5140
|
logger.debug("Created target directories");
|
|
4687
5141
|
} catch (err) {
|
|
4688
5142
|
logger.error("Failed to create target directories:", err);
|
|
4689
5143
|
throw err;
|
|
4690
5144
|
}
|
|
4691
|
-
const skillSource =
|
|
4692
|
-
const skillTarget =
|
|
5145
|
+
const skillSource = path6.join(sourceDir, "SKILL.md");
|
|
5146
|
+
const skillTarget = path6.join(targetDir, "SKILL.md");
|
|
4693
5147
|
logger.debug(`Copying SKILL.md: ${skillSource} -> ${skillTarget}`);
|
|
4694
|
-
if (
|
|
4695
|
-
|
|
5148
|
+
if (fs6.existsSync(skillSource)) {
|
|
5149
|
+
fs6.copyFileSync(skillSource, skillTarget);
|
|
4696
5150
|
result.skillInstalled = true;
|
|
4697
5151
|
result.skillPath = targetDir;
|
|
4698
5152
|
logger.debug("SKILL.md copied successfully");
|
|
4699
5153
|
} else {
|
|
4700
5154
|
logger.warn("SKILL.md source not found:", skillSource);
|
|
4701
5155
|
}
|
|
4702
|
-
const refsSource =
|
|
4703
|
-
const
|
|
4704
|
-
if (
|
|
4705
|
-
const files =
|
|
4706
|
-
logger.debug(`Copying ${files.length}
|
|
5156
|
+
const refsSource = path6.join(sourceDir, "references");
|
|
5157
|
+
const rulesTarget = path6.join(targetDir, "rules");
|
|
5158
|
+
if (fs6.existsSync(refsSource)) {
|
|
5159
|
+
const files = fs6.readdirSync(refsSource);
|
|
5160
|
+
logger.debug(`Copying ${files.length} rule files`);
|
|
4707
5161
|
for (const file of files) {
|
|
4708
|
-
|
|
5162
|
+
fs6.copyFileSync(path6.join(refsSource, file), path6.join(rulesTarget, file));
|
|
4709
5163
|
}
|
|
4710
5164
|
}
|
|
5165
|
+
removeOldSkillDirectory();
|
|
5166
|
+
const symlinkResult = createSkillSymlink("refly");
|
|
5167
|
+
if (symlinkResult.success) {
|
|
5168
|
+
result.symlinkPath = symlinkResult.claudePath;
|
|
5169
|
+
logger.info(`Created symlink: ${symlinkResult.claudePath} -> ${symlinkResult.reflyPath}`);
|
|
5170
|
+
} else {
|
|
5171
|
+
logger.warn(`Failed to create symlink: ${symlinkResult.error}`);
|
|
5172
|
+
}
|
|
4711
5173
|
const commandsDir = getClaudeCommandsDir();
|
|
4712
5174
|
logger.debug("Commands directory:", commandsDir);
|
|
4713
5175
|
ensureDir(commandsDir);
|
|
@@ -4719,20 +5181,21 @@ function installSkill() {
|
|
|
4719
5181
|
updateSkillInfo(result.version);
|
|
4720
5182
|
logger.info("Skill installation complete:", {
|
|
4721
5183
|
skillInstalled: result.skillInstalled,
|
|
5184
|
+
symlinkPath: result.symlinkPath,
|
|
4722
5185
|
commandsInstalled: result.commandsInstalled
|
|
4723
5186
|
});
|
|
4724
5187
|
return result;
|
|
4725
5188
|
}
|
|
4726
5189
|
function installSlashCommands(sourceDir, targetDir) {
|
|
4727
|
-
const commandsSource =
|
|
4728
|
-
if (!
|
|
5190
|
+
const commandsSource = path6.join(sourceDir, "..", "commands");
|
|
5191
|
+
if (!fs6.existsSync(commandsSource)) {
|
|
4729
5192
|
return false;
|
|
4730
5193
|
}
|
|
4731
5194
|
try {
|
|
4732
|
-
const files =
|
|
5195
|
+
const files = fs6.readdirSync(commandsSource);
|
|
4733
5196
|
for (const file of files) {
|
|
4734
5197
|
if (file.endsWith(".md")) {
|
|
4735
|
-
|
|
5198
|
+
fs6.copyFileSync(path6.join(commandsSource, file), path6.join(targetDir, file));
|
|
4736
5199
|
}
|
|
4737
5200
|
}
|
|
4738
5201
|
return files.length > 0;
|
|
@@ -4742,8 +5205,8 @@ function installSlashCommands(sourceDir, targetDir) {
|
|
|
4742
5205
|
}
|
|
4743
5206
|
function getSkillVersion() {
|
|
4744
5207
|
try {
|
|
4745
|
-
const skillPath =
|
|
4746
|
-
const content =
|
|
5208
|
+
const skillPath = path6.join(getPackageSkillDir(), "SKILL.md");
|
|
5209
|
+
const content = fs6.readFileSync(skillPath, "utf-8");
|
|
4747
5210
|
const versionMatch = content.match(/version:\s*(\d+\.\d+\.\d+)/);
|
|
4748
5211
|
if (versionMatch) {
|
|
4749
5212
|
return versionMatch[1];
|
|
@@ -4751,23 +5214,26 @@ function getSkillVersion() {
|
|
|
4751
5214
|
} catch {
|
|
4752
5215
|
}
|
|
4753
5216
|
try {
|
|
4754
|
-
const pkgPath =
|
|
4755
|
-
const pkg = JSON.parse(
|
|
5217
|
+
const pkgPath = path6.join(__dirname, "..", "..", "package.json");
|
|
5218
|
+
const pkg = JSON.parse(fs6.readFileSync(pkgPath, "utf-8"));
|
|
4756
5219
|
return pkg.version;
|
|
4757
5220
|
} catch {
|
|
4758
5221
|
return "0.1.0";
|
|
4759
5222
|
}
|
|
4760
5223
|
}
|
|
4761
5224
|
function isSkillInstalled() {
|
|
4762
|
-
const skillPath =
|
|
4763
|
-
if (!
|
|
5225
|
+
const skillPath = path6.join(getReflyBaseSkillDir(), "SKILL.md");
|
|
5226
|
+
if (!fs6.existsSync(skillPath)) {
|
|
4764
5227
|
return { installed: false, upToDate: false };
|
|
4765
5228
|
}
|
|
4766
5229
|
const currentVersion = getSkillVersion();
|
|
5230
|
+
const { isSkillSymlinkValid: isSkillSymlinkValid2 } = (init_symlink(), __toCommonJS(symlink_exports));
|
|
5231
|
+
const symlinkStatus = isSkillSymlinkValid2("refly");
|
|
4767
5232
|
return {
|
|
4768
5233
|
installed: true,
|
|
4769
5234
|
upToDate: true,
|
|
4770
|
-
currentVersion
|
|
5235
|
+
currentVersion,
|
|
5236
|
+
symlinkValid: symlinkStatus.isValid
|
|
4771
5237
|
};
|
|
4772
5238
|
}
|
|
4773
5239
|
// Annotate the CommonJS export names for ESM import in node:
|