@powerformer/refly-cli 0.1.16 → 0.1.18

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/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,516 @@ 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, options) {
321
+ const skillDir = getReflyDomainSkillDir(skillName);
322
+ try {
323
+ ensureReflySkillsDir();
324
+ if (fs5.existsSync(skillDir)) {
325
+ if (options?.force) {
326
+ const skillMdPath2 = path5.join(skillDir, "SKILL.md");
327
+ fs5.writeFileSync(skillMdPath2, skillMdContent, { encoding: "utf-8", mode: 420 });
328
+ logger.debug(`Updated SKILL.md (force): ${skillMdPath2}`);
329
+ return createSkillSymlink(skillName);
330
+ }
331
+ return {
332
+ success: false,
333
+ skillName,
334
+ reflyPath: skillDir,
335
+ claudePath: getClaudeSkillSymlinkPath(skillName),
336
+ error: `Skill directory already exists: ${skillDir}`
337
+ };
338
+ }
339
+ fs5.mkdirSync(skillDir, { recursive: true, mode: 493 });
340
+ const skillMdPath = path5.join(skillDir, "SKILL.md");
341
+ fs5.writeFileSync(skillMdPath, skillMdContent, { encoding: "utf-8", mode: 420 });
342
+ logger.debug(`Created SKILL.md: ${skillMdPath}`);
343
+ return createSkillSymlink(skillName);
344
+ } catch (err) {
345
+ return {
346
+ success: false,
347
+ skillName,
348
+ reflyPath: skillDir,
349
+ claudePath: getClaudeSkillSymlinkPath(skillName),
350
+ error: err.message
351
+ };
352
+ }
353
+ }
354
+ function deleteDomainSkillWithSymlink(skillName) {
355
+ const symlinkRemoved = removeSkillSymlink(skillName);
356
+ const skillDir = getReflyDomainSkillDir(skillName);
357
+ let directoryRemoved = false;
358
+ try {
359
+ if (fs5.existsSync(skillDir)) {
360
+ fs5.rmSync(skillDir, { recursive: true, force: true });
361
+ directoryRemoved = true;
362
+ logger.info(`Removed skill directory: ${skillDir}`);
363
+ }
364
+ } catch (err) {
365
+ logger.error(`Failed to remove skill directory ${skillDir}:`, err);
366
+ }
367
+ return { symlinkRemoved, directoryRemoved };
368
+ }
369
+ function listSkillSymlinks() {
370
+ const claudeSkillsDir = getClaudeSkillsDir();
371
+ const results = [];
372
+ if (!fs5.existsSync(claudeSkillsDir)) {
373
+ return results;
374
+ }
375
+ try {
376
+ const entries = fs5.readdirSync(claudeSkillsDir, { withFileTypes: true });
377
+ for (const entry of entries) {
378
+ const fullPath = path5.join(claudeSkillsDir, entry.name);
379
+ try {
380
+ const stat = fs5.lstatSync(fullPath);
381
+ if (stat.isSymbolicLink()) {
382
+ const target = fs5.readlinkSync(fullPath);
383
+ const resolvedTarget = path5.resolve(path5.dirname(fullPath), target);
384
+ const isValid2 = fs5.existsSync(resolvedTarget);
385
+ results.push({
386
+ name: entry.name,
387
+ claudePath: fullPath,
388
+ target: resolvedTarget,
389
+ isValid: isValid2
390
+ });
391
+ }
392
+ } catch {
393
+ }
394
+ }
395
+ } catch {
396
+ }
397
+ return results;
398
+ }
399
+ function generateReflySkillMd(options) {
400
+ const {
401
+ name,
402
+ displayName,
403
+ description,
404
+ skillId,
405
+ workflowId,
406
+ installationId,
407
+ triggers = [],
408
+ tags = [],
409
+ version = "1.0.0",
410
+ inputSchema,
411
+ outputSchema
412
+ } = options;
413
+ const frontmatterLines = ["---", `name: ${name}`];
414
+ frontmatterLines.push(`description: ${description}`);
415
+ if (tags.length > 0) {
416
+ frontmatterLines.push("tags:");
417
+ frontmatterLines.push(...tags.map((t) => ` - ${t}`));
418
+ }
419
+ frontmatterLines.push(`version: ${version}`);
420
+ frontmatterLines.push(`skillId: ${skillId}`);
421
+ frontmatterLines.push(`workflowId: ${workflowId}`);
422
+ if (installationId) {
423
+ frontmatterLines.push(`installationId: ${installationId}`);
424
+ }
425
+ if (triggers.length > 0) {
426
+ frontmatterLines.push("triggers:");
427
+ frontmatterLines.push(...triggers.map((t) => ` - ${t}`));
428
+ }
429
+ frontmatterLines.push("---");
430
+ const title = displayName || name.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
431
+ const inputExample = inputSchema ? JSON.stringify(inputSchema, null, 2) : `{
432
+ "query": "your input here"
433
+ }`;
434
+ const runCommand = installationId ? `refly skill run ${installationId} --input '${inputSchema ? JSON.stringify(inputSchema) : "{}"}'` : `refly workflow run ${workflowId} --input '${inputSchema ? JSON.stringify(inputSchema) : "{}"}'`;
435
+ const outputSection = outputSchema ? `The skill returns:
436
+
437
+ \`\`\`json
438
+ ${JSON.stringify(outputSchema, null, 2)}
439
+ \`\`\`` : "The skill returns the workflow execution result.";
440
+ const content = `
441
+
442
+ # ${title}
443
+
444
+ ${description}
445
+
446
+ ## Usage
447
+
448
+ This skill is executed via Refly CLI:
449
+
450
+ \`\`\`bash
451
+ ${runCommand}
452
+ \`\`\`
453
+
454
+ ## Input
455
+
456
+ Provide input as JSON:
457
+
458
+ \`\`\`json
459
+ ${inputExample}
460
+ \`\`\`
461
+
462
+ ## Output
463
+
464
+ ${outputSection}
465
+
466
+ ## Rules
467
+
468
+ For workflow operations, refer to the base skill rules:
469
+ - Workflow: \`~/.claude/skills/refly/rules/workflow.md\`
470
+ - Node: \`~/.claude/skills/refly/rules/node.md\`
471
+ - File: \`~/.claude/skills/refly/rules/file.md\`
472
+ `;
473
+ return frontmatterLines.join("\n") + content;
474
+ }
475
+ function parseReflySkillMd(content) {
476
+ const frontmatterRegex = /^---\n([\s\S]*?)\n---\n?([\s\S]*)$/;
477
+ const match = content.match(frontmatterRegex);
478
+ if (!match) {
479
+ throw new Error("Invalid SKILL.md format: missing frontmatter");
480
+ }
481
+ const [, frontmatterStr, body] = match;
482
+ const meta = {};
483
+ const lines = frontmatterStr.split("\n");
484
+ let currentKey = null;
485
+ let currentArray = [];
486
+ for (const line of lines) {
487
+ const trimmed = line.trim();
488
+ if (trimmed.startsWith("- ")) {
489
+ if (currentKey) {
490
+ currentArray.push(trimmed.slice(2).trim());
491
+ }
492
+ continue;
493
+ }
494
+ if (currentKey && currentArray.length > 0) {
495
+ meta[currentKey] = currentArray;
496
+ currentArray = [];
497
+ currentKey = null;
498
+ }
499
+ const colonIndex = trimmed.indexOf(":");
500
+ if (colonIndex > 0) {
501
+ const key = trimmed.slice(0, colonIndex).trim();
502
+ const value = trimmed.slice(colonIndex + 1).trim();
503
+ if (value === "") {
504
+ currentKey = key;
505
+ currentArray = [];
506
+ } else {
507
+ meta[key] = value;
508
+ }
509
+ }
510
+ }
511
+ if (currentKey && currentArray.length > 0) {
512
+ meta[currentKey] = currentArray;
513
+ }
514
+ if (!meta.name) {
515
+ throw new Error('Invalid SKILL.md: missing required field "name"');
516
+ }
517
+ if (!meta.description) {
518
+ throw new Error('Invalid SKILL.md: missing required field "description"');
519
+ }
520
+ if (!meta.skillId) {
521
+ throw new Error('Invalid SKILL.md: missing required field "skillId"');
522
+ }
523
+ if (!meta.workflowId) {
524
+ throw new Error('Invalid SKILL.md: missing required field "workflowId"');
525
+ }
526
+ return {
527
+ meta,
528
+ body: body.trim(),
529
+ raw: content
530
+ };
531
+ }
532
+ var fs5, path5;
533
+ var init_symlink = __esm({
534
+ "src/skill/symlink.ts"() {
535
+ "use strict";
536
+ init_cjs_shims();
537
+ fs5 = __toESM(require("fs"));
538
+ path5 = __toESM(require("path"));
539
+ init_paths();
540
+ init_logger();
541
+ }
542
+ });
543
+
31
544
  // src/index.ts
32
545
  var src_exports = {};
33
546
  __export(src_exports, {
@@ -45,8 +558,16 @@ __export(src_exports, {
45
558
  verifyConnection: () => verifyConnection
46
559
  });
47
560
  module.exports = __toCommonJS(src_exports);
561
+ init_cjs_shims();
562
+
563
+ // src/utils/output.ts
564
+ init_cjs_shims();
565
+
566
+ // src/utils/formatter.ts
567
+ init_cjs_shims();
48
568
 
49
569
  // src/utils/ui.ts
570
+ init_cjs_shims();
50
571
  var Style = {
51
572
  // Reset
52
573
  RESET: "\x1B[0m",
@@ -142,16 +663,20 @@ var ErrorCodes = {
142
663
  CONFLICT: "CONFLICT",
143
664
  PERMISSION_DENIED: "PERMISSION_DENIED",
144
665
  INVALID_INPUT: "INVALID_INPUT",
145
- INTERNAL_ERROR: "INTERNAL_ERROR"
666
+ INTERNAL_ERROR: "INTERNAL_ERROR",
667
+ // Variables
668
+ MISSING_VARIABLES: "MISSING_VARIABLES"
146
669
  };
147
670
 
148
671
  // src/utils/errors.ts
672
+ init_cjs_shims();
149
673
  var CLIError = class extends Error {
150
- constructor(code, message, details, hint) {
674
+ constructor(code, message, details, hint, suggestedFix) {
151
675
  super(message);
152
676
  this.code = code;
153
677
  this.details = details;
154
678
  this.hint = hint;
679
+ this.suggestedFix = suggestedFix;
155
680
  this.name = "CLIError";
156
681
  }
157
682
  };
@@ -172,11 +697,15 @@ var NetworkError = class extends CLIError {
172
697
  };
173
698
 
174
699
  // src/config/config.ts
700
+ init_cjs_shims();
175
701
  var fs2 = __toESM(require("fs"));
176
702
  var path2 = __toESM(require("path"));
177
703
  var os2 = __toESM(require("os"));
178
704
  var crypto = __toESM(require("crypto"));
179
705
 
706
+ // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/index.js
707
+ init_cjs_shims();
708
+
180
709
  // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js
181
710
  var external_exports = {};
182
711
  __export(external_exports, {
@@ -288,8 +817,19 @@ __export(external_exports, {
288
817
  util: () => util,
289
818
  void: () => voidType
290
819
  });
820
+ init_cjs_shims();
821
+
822
+ // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.js
823
+ init_cjs_shims();
824
+
825
+ // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.js
826
+ init_cjs_shims();
827
+
828
+ // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.js
829
+ init_cjs_shims();
291
830
 
292
831
  // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.js
832
+ init_cjs_shims();
293
833
  var util;
294
834
  (function(util2) {
295
835
  util2.assertEqual = (_) => {
@@ -654,9 +1194,10 @@ function getErrorMap() {
654
1194
  }
655
1195
 
656
1196
  // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
1197
+ init_cjs_shims();
657
1198
  var makeIssue = (params) => {
658
- const { data, path: path6, errorMaps, issueData } = params;
659
- const fullPath = [...path6, ...issueData.path || []];
1199
+ const { data, path: path7, errorMaps, issueData } = params;
1200
+ const fullPath = [...path7, ...issueData.path || []];
660
1201
  const fullIssue = {
661
1202
  ...issueData,
662
1203
  path: fullPath
@@ -763,7 +1304,11 @@ var isDirty = (x) => x.status === "dirty";
763
1304
  var isValid = (x) => x.status === "valid";
764
1305
  var isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise;
765
1306
 
1307
+ // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js
1308
+ init_cjs_shims();
1309
+
766
1310
  // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js
1311
+ init_cjs_shims();
767
1312
  var errorUtil;
768
1313
  (function(errorUtil2) {
769
1314
  errorUtil2.errToObj = (message) => typeof message === "string" ? { message } : message || {};
@@ -772,11 +1317,11 @@ var errorUtil;
772
1317
 
773
1318
  // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js
774
1319
  var ParseInputLazyPath = class {
775
- constructor(parent, value, path6, key) {
1320
+ constructor(parent, value, path7, key) {
776
1321
  this._cachedPath = [];
777
1322
  this.parent = parent;
778
1323
  this.data = value;
779
- this._path = path6;
1324
+ this._path = path7;
780
1325
  this._key = key;
781
1326
  }
782
1327
  get path() {
@@ -4218,31 +4763,8 @@ var coerce = {
4218
4763
  };
4219
4764
  var NEVER = INVALID;
4220
4765
 
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
4766
  // src/config/config.ts
4767
+ init_paths();
4246
4768
  var ConfigSchema = external_exports.object({
4247
4769
  version: external_exports.number().default(1),
4248
4770
  auth: external_exports.object({
@@ -4370,101 +4892,17 @@ function getApiKey() {
4370
4892
  }
4371
4893
 
4372
4894
  // src/api/client.ts
4895
+ init_cjs_shims();
4373
4896
  var fs4 = __toESM(require("fs"));
4374
4897
  var import_node_fs = require("fs");
4375
4898
  var path4 = __toESM(require("path"));
4376
4899
  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
4900
+ init_logger();
4463
4901
  var DEFAULT_TIMEOUT = 3e4;
4464
- async function apiRequest(path6, options = {}) {
4902
+ async function apiRequest(path7, options = {}) {
4465
4903
  const { method = "GET", body, query, timeout = DEFAULT_TIMEOUT, requireAuth = true } = options;
4466
4904
  const endpoint = getApiEndpoint();
4467
- let url = `${endpoint}${path6}`;
4905
+ let url = `${endpoint}${path7}`;
4468
4906
  if (query && Object.keys(query).length > 0) {
4469
4907
  const params = new URLSearchParams(query);
4470
4908
  url = `${url}?${params.toString()}`;
@@ -4502,7 +4940,7 @@ async function apiRequest(path6, options = {}) {
4502
4940
  const controller = new AbortController();
4503
4941
  const timeoutId = setTimeout(() => controller.abort(), timeout);
4504
4942
  try {
4505
- logger.debug(`API Request: ${method} ${path6}`);
4943
+ logger.debug(`API Request: ${method} ${path7}`);
4506
4944
  const response = await fetch(url, {
4507
4945
  method,
4508
4946
  headers,
@@ -4594,7 +5032,8 @@ function mapAPIError(status, response) {
4594
5032
  cliError.code || "UNKNOWN",
4595
5033
  cliError.message || "Unknown error",
4596
5034
  void 0,
4597
- cliError.hint
5035
+ cliError.hint,
5036
+ cliError.suggestedFix
4598
5037
  );
4599
5038
  }
4600
5039
  const errCode = response.errCode ?? response.error ?? "UNKNOWN";
@@ -4646,21 +5085,42 @@ async function verifyConnection() {
4646
5085
  }
4647
5086
 
4648
5087
  // src/skill/installer.ts
4649
- var fs5 = __toESM(require("fs"));
4650
- var path5 = __toESM(require("path"));
5088
+ init_cjs_shims();
5089
+ var fs6 = __toESM(require("fs"));
5090
+ var path6 = __toESM(require("path"));
5091
+ init_paths();
5092
+ init_logger();
5093
+ init_symlink();
5094
+ function removeOldSkillDirectory() {
5095
+ const claudeSkillPath = getClaudeSkillSymlinkPath("refly");
5096
+ if (!fs6.existsSync(claudeSkillPath)) {
5097
+ return;
5098
+ }
5099
+ try {
5100
+ const stat = fs6.lstatSync(claudeSkillPath);
5101
+ if (stat.isSymbolicLink()) {
5102
+ fs6.unlinkSync(claudeSkillPath);
5103
+ } else if (stat.isDirectory()) {
5104
+ fs6.rmSync(claudeSkillPath, { recursive: true, force: true });
5105
+ logger.info("Removed old skill directory");
5106
+ }
5107
+ } catch (err) {
5108
+ logger.warn("Failed to remove old directory:", err);
5109
+ }
5110
+ }
4651
5111
  function getPackageSkillDir() {
4652
5112
  const possiblePaths = [
4653
- path5.join(__dirname, "..", "..", "skill"),
5113
+ path6.join(__dirname, "..", "..", "skill"),
4654
5114
  // Built package: dist/bin/../../skill
4655
- path5.join(__dirname, "..", "..", "..", "skill"),
5115
+ path6.join(__dirname, "..", "..", "..", "skill"),
4656
5116
  // Development: dist/bin/../../../skill
4657
- path5.join(__dirname, "..", "skill")
5117
+ path6.join(__dirname, "..", "skill")
4658
5118
  // Alternative: dist/../skill
4659
5119
  ];
4660
5120
  logger.debug("Looking for skill files, __dirname:", __dirname);
4661
5121
  for (const p of possiblePaths) {
4662
- const resolved = path5.resolve(p);
4663
- const exists = fs5.existsSync(resolved);
5122
+ const resolved = path6.resolve(p);
5123
+ const exists = fs6.existsSync(resolved);
4664
5124
  logger.debug(` Checking path: ${resolved} - exists: ${exists}`);
4665
5125
  if (exists) {
4666
5126
  return resolved;
@@ -4672,42 +5132,52 @@ function installSkill() {
4672
5132
  const result = {
4673
5133
  skillInstalled: false,
4674
5134
  skillPath: null,
5135
+ symlinkPath: null,
4675
5136
  commandsInstalled: false,
4676
5137
  commandsPath: null,
4677
5138
  version: getSkillVersion()
4678
5139
  };
4679
5140
  const sourceDir = getPackageSkillDir();
4680
5141
  logger.debug("Source skill directory:", sourceDir);
4681
- const targetDir = getClaudeSkillDir();
5142
+ ensureReflySkillsDir();
5143
+ const targetDir = getReflyBaseSkillDir();
4682
5144
  logger.debug("Target skill directory:", targetDir);
4683
5145
  try {
4684
5146
  ensureDir(targetDir);
4685
- ensureDir(path5.join(targetDir, "references"));
5147
+ ensureDir(path6.join(targetDir, "rules"));
4686
5148
  logger.debug("Created target directories");
4687
5149
  } catch (err) {
4688
5150
  logger.error("Failed to create target directories:", err);
4689
5151
  throw err;
4690
5152
  }
4691
- const skillSource = path5.join(sourceDir, "SKILL.md");
4692
- const skillTarget = path5.join(targetDir, "SKILL.md");
5153
+ const skillSource = path6.join(sourceDir, "SKILL.md");
5154
+ const skillTarget = path6.join(targetDir, "SKILL.md");
4693
5155
  logger.debug(`Copying SKILL.md: ${skillSource} -> ${skillTarget}`);
4694
- if (fs5.existsSync(skillSource)) {
4695
- fs5.copyFileSync(skillSource, skillTarget);
5156
+ if (fs6.existsSync(skillSource)) {
5157
+ fs6.copyFileSync(skillSource, skillTarget);
4696
5158
  result.skillInstalled = true;
4697
5159
  result.skillPath = targetDir;
4698
5160
  logger.debug("SKILL.md copied successfully");
4699
5161
  } else {
4700
5162
  logger.warn("SKILL.md source not found:", skillSource);
4701
5163
  }
4702
- const refsSource = path5.join(sourceDir, "references");
4703
- const refsTarget = path5.join(targetDir, "references");
4704
- if (fs5.existsSync(refsSource)) {
4705
- const files = fs5.readdirSync(refsSource);
4706
- logger.debug(`Copying ${files.length} reference files`);
5164
+ const refsSource = path6.join(sourceDir, "references");
5165
+ const rulesTarget = path6.join(targetDir, "rules");
5166
+ if (fs6.existsSync(refsSource)) {
5167
+ const files = fs6.readdirSync(refsSource);
5168
+ logger.debug(`Copying ${files.length} rule files`);
4707
5169
  for (const file of files) {
4708
- fs5.copyFileSync(path5.join(refsSource, file), path5.join(refsTarget, file));
5170
+ fs6.copyFileSync(path6.join(refsSource, file), path6.join(rulesTarget, file));
4709
5171
  }
4710
5172
  }
5173
+ removeOldSkillDirectory();
5174
+ const symlinkResult = createSkillSymlink("refly");
5175
+ if (symlinkResult.success) {
5176
+ result.symlinkPath = symlinkResult.claudePath;
5177
+ logger.info(`Created symlink: ${symlinkResult.claudePath} -> ${symlinkResult.reflyPath}`);
5178
+ } else {
5179
+ logger.warn(`Failed to create symlink: ${symlinkResult.error}`);
5180
+ }
4711
5181
  const commandsDir = getClaudeCommandsDir();
4712
5182
  logger.debug("Commands directory:", commandsDir);
4713
5183
  ensureDir(commandsDir);
@@ -4719,20 +5189,21 @@ function installSkill() {
4719
5189
  updateSkillInfo(result.version);
4720
5190
  logger.info("Skill installation complete:", {
4721
5191
  skillInstalled: result.skillInstalled,
5192
+ symlinkPath: result.symlinkPath,
4722
5193
  commandsInstalled: result.commandsInstalled
4723
5194
  });
4724
5195
  return result;
4725
5196
  }
4726
5197
  function installSlashCommands(sourceDir, targetDir) {
4727
- const commandsSource = path5.join(sourceDir, "..", "commands");
4728
- if (!fs5.existsSync(commandsSource)) {
5198
+ const commandsSource = path6.join(sourceDir, "..", "commands");
5199
+ if (!fs6.existsSync(commandsSource)) {
4729
5200
  return false;
4730
5201
  }
4731
5202
  try {
4732
- const files = fs5.readdirSync(commandsSource);
5203
+ const files = fs6.readdirSync(commandsSource);
4733
5204
  for (const file of files) {
4734
5205
  if (file.endsWith(".md")) {
4735
- fs5.copyFileSync(path5.join(commandsSource, file), path5.join(targetDir, file));
5206
+ fs6.copyFileSync(path6.join(commandsSource, file), path6.join(targetDir, file));
4736
5207
  }
4737
5208
  }
4738
5209
  return files.length > 0;
@@ -4742,8 +5213,8 @@ function installSlashCommands(sourceDir, targetDir) {
4742
5213
  }
4743
5214
  function getSkillVersion() {
4744
5215
  try {
4745
- const skillPath = path5.join(getPackageSkillDir(), "SKILL.md");
4746
- const content = fs5.readFileSync(skillPath, "utf-8");
5216
+ const skillPath = path6.join(getPackageSkillDir(), "SKILL.md");
5217
+ const content = fs6.readFileSync(skillPath, "utf-8");
4747
5218
  const versionMatch = content.match(/version:\s*(\d+\.\d+\.\d+)/);
4748
5219
  if (versionMatch) {
4749
5220
  return versionMatch[1];
@@ -4751,23 +5222,26 @@ function getSkillVersion() {
4751
5222
  } catch {
4752
5223
  }
4753
5224
  try {
4754
- const pkgPath = path5.join(__dirname, "..", "..", "package.json");
4755
- const pkg = JSON.parse(fs5.readFileSync(pkgPath, "utf-8"));
5225
+ const pkgPath = path6.join(__dirname, "..", "..", "package.json");
5226
+ const pkg = JSON.parse(fs6.readFileSync(pkgPath, "utf-8"));
4756
5227
  return pkg.version;
4757
5228
  } catch {
4758
5229
  return "0.1.0";
4759
5230
  }
4760
5231
  }
4761
5232
  function isSkillInstalled() {
4762
- const skillPath = path5.join(getClaudeSkillDir(), "SKILL.md");
4763
- if (!fs5.existsSync(skillPath)) {
5233
+ const skillPath = path6.join(getReflyBaseSkillDir(), "SKILL.md");
5234
+ if (!fs6.existsSync(skillPath)) {
4764
5235
  return { installed: false, upToDate: false };
4765
5236
  }
4766
5237
  const currentVersion = getSkillVersion();
5238
+ const { isSkillSymlinkValid: isSkillSymlinkValid2 } = (init_symlink(), __toCommonJS(symlink_exports));
5239
+ const symlinkStatus = isSkillSymlinkValid2("refly");
4767
5240
  return {
4768
5241
  installed: true,
4769
5242
  upToDate: true,
4770
- currentVersion
5243
+ currentVersion,
5244
+ symlinkValid: symlinkStatus.isValid
4771
5245
  };
4772
5246
  }
4773
5247
  // Annotate the CommonJS export names for ESM import in node: