@powerformer/refly-cli 0.1.17 → 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/bin/refly.js +708 -204
- package/dist/bin/refly.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +10 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/bin/refly.js
CHANGED
|
@@ -989,7 +989,7 @@ var require_command = __commonJS({
|
|
|
989
989
|
init_cjs_shims();
|
|
990
990
|
var EventEmitter = require("events").EventEmitter;
|
|
991
991
|
var childProcess2 = require("child_process");
|
|
992
|
-
var
|
|
992
|
+
var path23 = require("path");
|
|
993
993
|
var fs27 = require("fs");
|
|
994
994
|
var process8 = require("process");
|
|
995
995
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
@@ -1922,9 +1922,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1922
1922
|
let launchWithNode = false;
|
|
1923
1923
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
1924
1924
|
function findFile(baseDir, baseName) {
|
|
1925
|
-
const localBin =
|
|
1925
|
+
const localBin = path23.resolve(baseDir, baseName);
|
|
1926
1926
|
if (fs27.existsSync(localBin)) return localBin;
|
|
1927
|
-
if (sourceExt.includes(
|
|
1927
|
+
if (sourceExt.includes(path23.extname(baseName))) return void 0;
|
|
1928
1928
|
const foundExt = sourceExt.find(
|
|
1929
1929
|
(ext) => fs27.existsSync(`${localBin}${ext}`)
|
|
1930
1930
|
);
|
|
@@ -1942,17 +1942,17 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1942
1942
|
} catch (err) {
|
|
1943
1943
|
resolvedScriptPath = this._scriptPath;
|
|
1944
1944
|
}
|
|
1945
|
-
executableDir =
|
|
1946
|
-
|
|
1945
|
+
executableDir = path23.resolve(
|
|
1946
|
+
path23.dirname(resolvedScriptPath),
|
|
1947
1947
|
executableDir
|
|
1948
1948
|
);
|
|
1949
1949
|
}
|
|
1950
1950
|
if (executableDir) {
|
|
1951
1951
|
let localFile = findFile(executableDir, executableFile);
|
|
1952
1952
|
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
|
1953
|
-
const legacyName =
|
|
1953
|
+
const legacyName = path23.basename(
|
|
1954
1954
|
this._scriptPath,
|
|
1955
|
-
|
|
1955
|
+
path23.extname(this._scriptPath)
|
|
1956
1956
|
);
|
|
1957
1957
|
if (legacyName !== this._name) {
|
|
1958
1958
|
localFile = findFile(
|
|
@@ -1963,7 +1963,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1963
1963
|
}
|
|
1964
1964
|
executableFile = localFile || executableFile;
|
|
1965
1965
|
}
|
|
1966
|
-
launchWithNode = sourceExt.includes(
|
|
1966
|
+
launchWithNode = sourceExt.includes(path23.extname(executableFile));
|
|
1967
1967
|
let proc;
|
|
1968
1968
|
if (process8.platform !== "win32") {
|
|
1969
1969
|
if (launchWithNode) {
|
|
@@ -2803,7 +2803,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2803
2803
|
* @return {Command}
|
|
2804
2804
|
*/
|
|
2805
2805
|
nameFromFilename(filename) {
|
|
2806
|
-
this._name =
|
|
2806
|
+
this._name = path23.basename(filename, path23.extname(filename));
|
|
2807
2807
|
return this;
|
|
2808
2808
|
}
|
|
2809
2809
|
/**
|
|
@@ -2817,9 +2817,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2817
2817
|
* @param {string} [path]
|
|
2818
2818
|
* @return {(string|null|Command)}
|
|
2819
2819
|
*/
|
|
2820
|
-
executableDir(
|
|
2821
|
-
if (
|
|
2822
|
-
this._executableDir =
|
|
2820
|
+
executableDir(path24) {
|
|
2821
|
+
if (path24 === void 0) return this._executableDir;
|
|
2822
|
+
this._executableDir = path24;
|
|
2823
2823
|
return this;
|
|
2824
2824
|
}
|
|
2825
2825
|
/**
|
|
@@ -3392,11 +3392,17 @@ function initializeBaseSkillSymlink() {
|
|
|
3392
3392
|
ensureDir(path4.join(baseDir, "rules"));
|
|
3393
3393
|
return createSkillSymlink("refly");
|
|
3394
3394
|
}
|
|
3395
|
-
function createReflySkillWithSymlink(skillName, skillMdContent) {
|
|
3395
|
+
function createReflySkillWithSymlink(skillName, skillMdContent, options) {
|
|
3396
3396
|
const skillDir = getReflyDomainSkillDir(skillName);
|
|
3397
3397
|
try {
|
|
3398
3398
|
ensureReflySkillsDir();
|
|
3399
3399
|
if (fs4.existsSync(skillDir)) {
|
|
3400
|
+
if (options?.force) {
|
|
3401
|
+
const skillMdPath2 = path4.join(skillDir, "SKILL.md");
|
|
3402
|
+
fs4.writeFileSync(skillMdPath2, skillMdContent, { encoding: "utf-8", mode: 420 });
|
|
3403
|
+
logger.debug(`Updated SKILL.md (force): ${skillMdPath2}`);
|
|
3404
|
+
return createSkillSymlink(skillName);
|
|
3405
|
+
}
|
|
3400
3406
|
return {
|
|
3401
3407
|
success: false,
|
|
3402
3408
|
skillName,
|
|
@@ -4881,12 +4887,14 @@ var ErrorCodes = {
|
|
|
4881
4887
|
CONFLICT: "CONFLICT",
|
|
4882
4888
|
PERMISSION_DENIED: "PERMISSION_DENIED",
|
|
4883
4889
|
INVALID_INPUT: "INVALID_INPUT",
|
|
4884
|
-
INTERNAL_ERROR: "INTERNAL_ERROR"
|
|
4890
|
+
INTERNAL_ERROR: "INTERNAL_ERROR",
|
|
4891
|
+
// Variables
|
|
4892
|
+
MISSING_VARIABLES: "MISSING_VARIABLES"
|
|
4885
4893
|
};
|
|
4886
4894
|
|
|
4887
4895
|
// src/bin/refly.ts
|
|
4888
4896
|
var fs26 = __toESM(require("fs"));
|
|
4889
|
-
var
|
|
4897
|
+
var path22 = __toESM(require("path"));
|
|
4890
4898
|
|
|
4891
4899
|
// src/commands/init.ts
|
|
4892
4900
|
init_cjs_shims();
|
|
@@ -5391,8 +5399,8 @@ function getErrorMap() {
|
|
|
5391
5399
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
|
|
5392
5400
|
init_cjs_shims();
|
|
5393
5401
|
var makeIssue = (params) => {
|
|
5394
|
-
const { data, path:
|
|
5395
|
-
const fullPath = [...
|
|
5402
|
+
const { data, path: path23, errorMaps, issueData } = params;
|
|
5403
|
+
const fullPath = [...path23, ...issueData.path || []];
|
|
5396
5404
|
const fullIssue = {
|
|
5397
5405
|
...issueData,
|
|
5398
5406
|
path: fullPath
|
|
@@ -5512,11 +5520,11 @@ var errorUtil;
|
|
|
5512
5520
|
|
|
5513
5521
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js
|
|
5514
5522
|
var ParseInputLazyPath = class {
|
|
5515
|
-
constructor(parent, value,
|
|
5523
|
+
constructor(parent, value, path23, key) {
|
|
5516
5524
|
this._cachedPath = [];
|
|
5517
5525
|
this.parent = parent;
|
|
5518
5526
|
this.data = value;
|
|
5519
|
-
this._path =
|
|
5527
|
+
this._path = path23;
|
|
5520
5528
|
this._key = key;
|
|
5521
5529
|
}
|
|
5522
5530
|
get path() {
|
|
@@ -9878,10 +9886,10 @@ var NetworkError = class extends CLIError {
|
|
|
9878
9886
|
// src/api/client.ts
|
|
9879
9887
|
init_logger();
|
|
9880
9888
|
var DEFAULT_TIMEOUT = 3e4;
|
|
9881
|
-
async function apiRequest(
|
|
9889
|
+
async function apiRequest(path23, options = {}) {
|
|
9882
9890
|
const { method = "GET", body, query, timeout = DEFAULT_TIMEOUT, requireAuth = true } = options;
|
|
9883
9891
|
const endpoint = getApiEndpoint();
|
|
9884
|
-
let url = `${endpoint}${
|
|
9892
|
+
let url = `${endpoint}${path23}`;
|
|
9885
9893
|
if (query && Object.keys(query).length > 0) {
|
|
9886
9894
|
const params = new URLSearchParams(query);
|
|
9887
9895
|
url = `${url}?${params.toString()}`;
|
|
@@ -9919,7 +9927,7 @@ async function apiRequest(path22, options = {}) {
|
|
|
9919
9927
|
const controller = new AbortController();
|
|
9920
9928
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
9921
9929
|
try {
|
|
9922
|
-
logger.debug(`API Request: ${method} ${
|
|
9930
|
+
logger.debug(`API Request: ${method} ${path23}`);
|
|
9923
9931
|
const response = await fetch(url, {
|
|
9924
9932
|
method,
|
|
9925
9933
|
headers,
|
|
@@ -10034,10 +10042,10 @@ function mapAPIError(status, response) {
|
|
|
10034
10042
|
}
|
|
10035
10043
|
return new CLIError(errCode, errMsg);
|
|
10036
10044
|
}
|
|
10037
|
-
async function apiRequestStream(
|
|
10045
|
+
async function apiRequestStream(path23, options = {}) {
|
|
10038
10046
|
const { timeout = 3e5 } = options;
|
|
10039
10047
|
const endpoint = getApiEndpoint();
|
|
10040
|
-
const url = `${endpoint}${
|
|
10048
|
+
const url = `${endpoint}${path23}`;
|
|
10041
10049
|
const headers = {
|
|
10042
10050
|
"User-Agent": "refly-cli/0.1.0"
|
|
10043
10051
|
};
|
|
@@ -10068,7 +10076,7 @@ async function apiRequestStream(path22, options = {}) {
|
|
|
10068
10076
|
const controller = new AbortController();
|
|
10069
10077
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
10070
10078
|
try {
|
|
10071
|
-
logger.debug(`API Stream Request: GET ${
|
|
10079
|
+
logger.debug(`API Stream Request: GET ${path23}`);
|
|
10072
10080
|
const response = await fetch(url, {
|
|
10073
10081
|
method: "GET",
|
|
10074
10082
|
headers,
|
|
@@ -10252,6 +10260,22 @@ async function apiUploadDriveFile(filePath, canvasId, options) {
|
|
|
10252
10260
|
throw error;
|
|
10253
10261
|
}
|
|
10254
10262
|
}
|
|
10263
|
+
async function apiGetWorkflowVariables(canvasId) {
|
|
10264
|
+
return apiRequest("/v1/canvas/workflow/variables", {
|
|
10265
|
+
query: { canvasId }
|
|
10266
|
+
});
|
|
10267
|
+
}
|
|
10268
|
+
async function apiUpdateWorkflowVariables(canvasId, variables) {
|
|
10269
|
+
return apiRequest("/v1/canvas/workflow/variables", {
|
|
10270
|
+
method: "POST",
|
|
10271
|
+
body: { canvasId, variables }
|
|
10272
|
+
});
|
|
10273
|
+
}
|
|
10274
|
+
async function apiGetActionResult(resultId) {
|
|
10275
|
+
return apiRequest("/v1/cli/action/result", {
|
|
10276
|
+
query: { resultId }
|
|
10277
|
+
});
|
|
10278
|
+
}
|
|
10255
10279
|
|
|
10256
10280
|
// src/commands/login.ts
|
|
10257
10281
|
init_logger();
|
|
@@ -10726,7 +10750,7 @@ var import_node_child_process6 = require("child_process");
|
|
|
10726
10750
|
var import_node_fs5 = __toESM(require("fs"));
|
|
10727
10751
|
init_logger();
|
|
10728
10752
|
init_paths();
|
|
10729
|
-
var CLI_VERSION = "0.1.
|
|
10753
|
+
var CLI_VERSION = "0.1.18";
|
|
10730
10754
|
var NPM_TAG = "test";
|
|
10731
10755
|
function compareSemver(a, b) {
|
|
10732
10756
|
const parseVersion = (v) => {
|
|
@@ -10982,16 +11006,16 @@ configCommand.action(() => {
|
|
|
10982
11006
|
};
|
|
10983
11007
|
ok("config", safeConfig);
|
|
10984
11008
|
});
|
|
10985
|
-
function getNestedValue(obj,
|
|
10986
|
-
return
|
|
11009
|
+
function getNestedValue(obj, path23) {
|
|
11010
|
+
return path23.split(".").reduce((current, key) => {
|
|
10987
11011
|
if (current && typeof current === "object" && key in current) {
|
|
10988
11012
|
return current[key];
|
|
10989
11013
|
}
|
|
10990
11014
|
return void 0;
|
|
10991
11015
|
}, obj);
|
|
10992
11016
|
}
|
|
10993
|
-
function setNestedValue(obj,
|
|
10994
|
-
const keys =
|
|
11017
|
+
function setNestedValue(obj, path23, value) {
|
|
11018
|
+
const keys = path23.split(".");
|
|
10995
11019
|
const lastKey = keys.pop();
|
|
10996
11020
|
let current = obj;
|
|
10997
11021
|
for (const key of keys) {
|
|
@@ -11441,6 +11465,77 @@ function determineFileType(filePath, mimeType) {
|
|
|
11441
11465
|
return "document";
|
|
11442
11466
|
}
|
|
11443
11467
|
|
|
11468
|
+
// src/utils/variable-check.ts
|
|
11469
|
+
init_cjs_shims();
|
|
11470
|
+
function checkRequiredVariables(definitions, providedInput) {
|
|
11471
|
+
const missing = [];
|
|
11472
|
+
const suggestedInput = { ...providedInput };
|
|
11473
|
+
for (const def of definitions) {
|
|
11474
|
+
if (!def.required) continue;
|
|
11475
|
+
const key = def.name;
|
|
11476
|
+
const hasValue = key in providedInput && providedInput[key] !== void 0 && providedInput[key] !== null;
|
|
11477
|
+
if (!hasValue) {
|
|
11478
|
+
missing.push(def);
|
|
11479
|
+
if (def.default !== void 0) {
|
|
11480
|
+
suggestedInput[key] = def.default;
|
|
11481
|
+
} else {
|
|
11482
|
+
suggestedInput[key] = "<value>";
|
|
11483
|
+
}
|
|
11484
|
+
}
|
|
11485
|
+
}
|
|
11486
|
+
return {
|
|
11487
|
+
valid: missing.length === 0,
|
|
11488
|
+
missing,
|
|
11489
|
+
suggestedInput
|
|
11490
|
+
};
|
|
11491
|
+
}
|
|
11492
|
+
function buildMissingVariablesError(commandType, targetId, targetName, result) {
|
|
11493
|
+
const displayName = targetName ? `"${targetName}"` : targetId;
|
|
11494
|
+
const inputJson = JSON.stringify(result.suggestedInput);
|
|
11495
|
+
const suggestedCommand = commandType === "workflow" ? `refly workflow run ${targetId} --input '${inputJson}'` : `refly skill run --name <name> --input '${inputJson}'`;
|
|
11496
|
+
return {
|
|
11497
|
+
code: "MISSING_VARIABLES",
|
|
11498
|
+
message: `Missing required variables for ${commandType} ${displayName}`,
|
|
11499
|
+
details: {
|
|
11500
|
+
missingVariables: result.missing.map((v) => ({
|
|
11501
|
+
name: v.name,
|
|
11502
|
+
type: v.variableType || "string",
|
|
11503
|
+
required: true,
|
|
11504
|
+
default: v.default,
|
|
11505
|
+
description: v.description
|
|
11506
|
+
})),
|
|
11507
|
+
suggestedInput: result.suggestedInput,
|
|
11508
|
+
suggestedCommand
|
|
11509
|
+
},
|
|
11510
|
+
hint: "Provide the missing variables via --input. See suggestedInput for the expected format.",
|
|
11511
|
+
suggestedFix: {
|
|
11512
|
+
field: "--input",
|
|
11513
|
+
format: "json-object",
|
|
11514
|
+
example: inputJson
|
|
11515
|
+
},
|
|
11516
|
+
recoverable: true
|
|
11517
|
+
};
|
|
11518
|
+
}
|
|
11519
|
+
function variablesToObject(variables) {
|
|
11520
|
+
const result = {};
|
|
11521
|
+
for (const v of variables) {
|
|
11522
|
+
if (!v.value || v.value.length === 0) continue;
|
|
11523
|
+
const firstValue = v.value[0];
|
|
11524
|
+
if (typeof firstValue === "object" && firstValue !== null) {
|
|
11525
|
+
if ("resource" in firstValue && typeof firstValue.resource === "object") {
|
|
11526
|
+
result[v.name] = firstValue;
|
|
11527
|
+
} else if ("text" in firstValue) {
|
|
11528
|
+
result[v.name] = firstValue.text;
|
|
11529
|
+
} else {
|
|
11530
|
+
result[v.name] = firstValue;
|
|
11531
|
+
}
|
|
11532
|
+
} else {
|
|
11533
|
+
result[v.name] = firstValue;
|
|
11534
|
+
}
|
|
11535
|
+
}
|
|
11536
|
+
return result;
|
|
11537
|
+
}
|
|
11538
|
+
|
|
11444
11539
|
// src/commands/workflow/run.ts
|
|
11445
11540
|
async function confirmAction(question) {
|
|
11446
11541
|
const rl = readline2.createInterface({ input: import_node_process8.stdin, output: import_node_process8.stdout });
|
|
@@ -11511,6 +11606,11 @@ async function collectFileVariables(workflowId, existingInput, noPrompt) {
|
|
|
11511
11606
|
} catch (_error) {
|
|
11512
11607
|
return [];
|
|
11513
11608
|
}
|
|
11609
|
+
let savedVariables = [];
|
|
11610
|
+
try {
|
|
11611
|
+
savedVariables = await apiGetWorkflowVariables(workflowId);
|
|
11612
|
+
} catch (_error) {
|
|
11613
|
+
}
|
|
11514
11614
|
const resourceVars = (workflow.variables ?? []).filter(
|
|
11515
11615
|
(v) => v.variableType === "resource" && v.required === true
|
|
11516
11616
|
);
|
|
@@ -11518,33 +11618,35 @@ async function collectFileVariables(workflowId, existingInput, noPrompt) {
|
|
|
11518
11618
|
return [];
|
|
11519
11619
|
}
|
|
11520
11620
|
const invalidFormatVars = [];
|
|
11621
|
+
const hasValidFileValue = (variable) => {
|
|
11622
|
+
if (!variable) return false;
|
|
11623
|
+
const values = variable.value;
|
|
11624
|
+
if (!Array.isArray(values) || values.length === 0) return false;
|
|
11625
|
+
return values.some((val) => {
|
|
11626
|
+
const fileId = val?.resource?.fileId || val?.fileId;
|
|
11627
|
+
return typeof fileId === "string" && fileId.length > 0;
|
|
11628
|
+
});
|
|
11629
|
+
};
|
|
11521
11630
|
const missingVars = resourceVars.filter((v) => {
|
|
11522
|
-
const
|
|
11631
|
+
const providedInInput = existingInput.find(
|
|
11523
11632
|
(input3) => v.variableId && input3.variableId === v.variableId || v.name && input3.name === v.name
|
|
11524
11633
|
);
|
|
11525
|
-
|
|
11526
|
-
|
|
11527
|
-
|
|
11528
|
-
|
|
11529
|
-
|
|
11634
|
+
const savedValue = savedVariables.find(
|
|
11635
|
+
(saved) => v.variableId && saved.variableId === v.variableId || v.name && saved.name === v.name
|
|
11636
|
+
);
|
|
11637
|
+
if (providedInInput) {
|
|
11638
|
+
if (hasValidFileValue(providedInInput)) {
|
|
11639
|
+
return false;
|
|
11640
|
+
}
|
|
11530
11641
|
invalidFormatVars.push({
|
|
11531
11642
|
name: v.name,
|
|
11532
|
-
reason: "
|
|
11643
|
+
reason: "invalid format in --input"
|
|
11533
11644
|
});
|
|
11534
|
-
return true;
|
|
11535
11645
|
}
|
|
11536
|
-
|
|
11537
|
-
|
|
11538
|
-
return typeof fileId === "string" && fileId.length > 0;
|
|
11539
|
-
});
|
|
11540
|
-
if (!hasValidFileId) {
|
|
11541
|
-
invalidFormatVars.push({
|
|
11542
|
-
name: v.name,
|
|
11543
|
-
reason: "no valid fileId found in value"
|
|
11544
|
-
});
|
|
11545
|
-
return true;
|
|
11646
|
+
if (hasValidFileValue(savedValue)) {
|
|
11647
|
+
return false;
|
|
11546
11648
|
}
|
|
11547
|
-
return
|
|
11649
|
+
return true;
|
|
11548
11650
|
});
|
|
11549
11651
|
if (missingVars.length === 0) {
|
|
11550
11652
|
return [];
|
|
@@ -11693,6 +11795,24 @@ async function runWorkflow(workflowId, options) {
|
|
|
11693
11795
|
});
|
|
11694
11796
|
return;
|
|
11695
11797
|
}
|
|
11798
|
+
if (options?.noPrompt && workflow?.variables) {
|
|
11799
|
+
const inputObject = variablesToObject(inputVars);
|
|
11800
|
+
const checkResult = checkRequiredVariables(workflow.variables, inputObject);
|
|
11801
|
+
if (!checkResult.valid) {
|
|
11802
|
+
const errorPayload = buildMissingVariablesError(
|
|
11803
|
+
"workflow",
|
|
11804
|
+
workflowId,
|
|
11805
|
+
workflow.name,
|
|
11806
|
+
checkResult
|
|
11807
|
+
);
|
|
11808
|
+
fail(ErrorCodes.MISSING_VARIABLES, errorPayload.message, {
|
|
11809
|
+
details: errorPayload.details,
|
|
11810
|
+
hint: errorPayload.hint,
|
|
11811
|
+
suggestedFix: errorPayload.suggestedFix,
|
|
11812
|
+
recoverable: errorPayload.recoverable
|
|
11813
|
+
});
|
|
11814
|
+
}
|
|
11815
|
+
}
|
|
11696
11816
|
const uploadedVars = await collectFileVariables(
|
|
11697
11817
|
workflowId,
|
|
11698
11818
|
inputVars,
|
|
@@ -12659,132 +12779,389 @@ var workflowNodeOutputCommand = new Command("node-output").description("Get node
|
|
|
12659
12779
|
|
|
12660
12780
|
// src/commands/workflow/edit.ts
|
|
12661
12781
|
init_cjs_shims();
|
|
12662
|
-
var
|
|
12663
|
-
var workflowEditCommand = new Command("edit").description("Edit a workflow plan using semantic operations").argument("<planId>", "Workflow Plan ID").option("--ops <json>", "Operations array as JSON").option("--ops-file <path>", "Read operations from file").option("--update-title <title>", "Shortcut: update workflow title").option("--delete-task <taskId>", "Shortcut: delete a task").option("--delete-variable <variableId>", "Shortcut: delete a variable").action(async (planId, options) => {
|
|
12782
|
+
var workflowEditCommand = new Command("edit").description("Edit a workflow using natural language").argument("<id>", "Canvas ID (c-xxx)").option("--query <text>", "Edit instruction in natural language").option("--session-id <id>", "Session ID (cs-xxx) for context continuity").option("--timeout <ms>", "Timeout for AI processing", "60000").action(async (id, options) => {
|
|
12664
12783
|
try {
|
|
12665
|
-
|
|
12666
|
-
|
|
12667
|
-
|
|
12668
|
-
|
|
12669
|
-
|
|
12670
|
-
|
|
12671
|
-
|
|
12672
|
-
if (options.opsFile) {
|
|
12673
|
-
try {
|
|
12674
|
-
const filePath = options.opsFile;
|
|
12675
|
-
if (!fs14.existsSync(filePath)) {
|
|
12676
|
-
fail(ErrorCodes.NOT_FOUND, `Operations file not found: ${filePath}`);
|
|
12677
|
-
}
|
|
12678
|
-
const fileContent = fs14.readFileSync(filePath, "utf-8");
|
|
12679
|
-
const fileOps = JSON.parse(fileContent);
|
|
12680
|
-
if (Array.isArray(fileOps)) {
|
|
12681
|
-
operations.push(...fileOps);
|
|
12682
|
-
} else {
|
|
12683
|
-
fail(ErrorCodes.INVALID_INPUT, "Operations file must contain a JSON array", {
|
|
12684
|
-
hint: opsFormatHint,
|
|
12685
|
-
suggestedFix: {
|
|
12686
|
-
field: "--ops-file",
|
|
12687
|
-
format: "json-array",
|
|
12688
|
-
example: '[{"op": "updateTitle", "title": "New Title"}]'
|
|
12689
|
-
}
|
|
12690
|
-
});
|
|
12784
|
+
if (!options.query) {
|
|
12785
|
+
fail(ErrorCodes.INVALID_INPUT, "--query is required", {
|
|
12786
|
+
hint: "Provide a natural language description of the edit you want to make",
|
|
12787
|
+
suggestedFix: {
|
|
12788
|
+
field: "--query",
|
|
12789
|
+
format: "string",
|
|
12790
|
+
example: 'refly workflow edit c-xxx --query "\u6DFB\u52A0\u4E00\u4E2A\u7528 nano banana \u751F\u6210\u56FE\u7247\u7684\u4EFB\u52A1"'
|
|
12691
12791
|
}
|
|
12692
|
-
}
|
|
12693
|
-
|
|
12694
|
-
|
|
12695
|
-
|
|
12696
|
-
|
|
12697
|
-
|
|
12698
|
-
|
|
12699
|
-
|
|
12700
|
-
|
|
12701
|
-
|
|
12702
|
-
|
|
12703
|
-
|
|
12704
|
-
|
|
12705
|
-
|
|
12792
|
+
});
|
|
12793
|
+
}
|
|
12794
|
+
if (!id.startsWith("c-")) {
|
|
12795
|
+
fail(ErrorCodes.INVALID_INPUT, "Only Canvas ID (c-xxx) is supported", {
|
|
12796
|
+
hint: 'Use the Canvas ID format starting with "c-"',
|
|
12797
|
+
suggestedFix: {
|
|
12798
|
+
field: "id",
|
|
12799
|
+
format: "canvas-id",
|
|
12800
|
+
example: "c-abc123"
|
|
12801
|
+
}
|
|
12802
|
+
});
|
|
12803
|
+
}
|
|
12804
|
+
const timeout = Number.parseInt(options.timeout);
|
|
12805
|
+
const response = await apiRequest(
|
|
12806
|
+
"/v1/cli/workflow/edit",
|
|
12807
|
+
{
|
|
12808
|
+
method: "POST",
|
|
12809
|
+
body: {
|
|
12810
|
+
canvasId: id,
|
|
12811
|
+
query: options.query,
|
|
12812
|
+
sessionId: options.sessionId,
|
|
12813
|
+
timeout
|
|
12814
|
+
},
|
|
12815
|
+
timeout: timeout + 5e3
|
|
12816
|
+
// Add buffer for network
|
|
12817
|
+
}
|
|
12818
|
+
);
|
|
12819
|
+
const result = response.data ?? response;
|
|
12820
|
+
ok("workflow.edit", {
|
|
12821
|
+
canvasId: result.canvasId,
|
|
12822
|
+
planId: result.planId,
|
|
12823
|
+
version: result.version,
|
|
12824
|
+
toolUsed: result.toolUsed,
|
|
12825
|
+
sessionId: result.sessionId,
|
|
12826
|
+
plan: {
|
|
12827
|
+
title: result.plan.title,
|
|
12828
|
+
taskCount: result.plan.tasks?.length ?? 0,
|
|
12829
|
+
variableCount: result.plan.variables?.length ?? 0,
|
|
12830
|
+
tasks: result.plan.tasks?.map((t) => ({
|
|
12831
|
+
id: t.id,
|
|
12832
|
+
title: t.title
|
|
12833
|
+
})),
|
|
12834
|
+
variables: result.plan.variables?.map((v) => ({
|
|
12835
|
+
variableId: v.variableId,
|
|
12836
|
+
name: v.name
|
|
12837
|
+
}))
|
|
12706
12838
|
}
|
|
12839
|
+
});
|
|
12840
|
+
} catch (error) {
|
|
12841
|
+
if (error instanceof CLIError) {
|
|
12842
|
+
fail(error.code, error.message, {
|
|
12843
|
+
details: error.details,
|
|
12844
|
+
hint: error.hint,
|
|
12845
|
+
suggestedFix: error.suggestedFix
|
|
12846
|
+
});
|
|
12707
12847
|
}
|
|
12708
|
-
|
|
12709
|
-
|
|
12710
|
-
|
|
12711
|
-
|
|
12712
|
-
|
|
12713
|
-
|
|
12714
|
-
|
|
12715
|
-
|
|
12848
|
+
fail(
|
|
12849
|
+
ErrorCodes.INTERNAL_ERROR,
|
|
12850
|
+
error instanceof Error ? error.message : "Failed to edit workflow"
|
|
12851
|
+
);
|
|
12852
|
+
}
|
|
12853
|
+
});
|
|
12854
|
+
|
|
12855
|
+
// src/commands/workflow/variables.ts
|
|
12856
|
+
init_cjs_shims();
|
|
12857
|
+
function getFileTypeCategory(mimeType) {
|
|
12858
|
+
if (mimeType.startsWith("image/")) return "image";
|
|
12859
|
+
if (mimeType.startsWith("video/")) return "video";
|
|
12860
|
+
if (mimeType.startsWith("audio/")) return "audio";
|
|
12861
|
+
if (mimeType === "application/pdf") return "document";
|
|
12862
|
+
if (mimeType.includes("word") || mimeType.includes("document")) return "document";
|
|
12863
|
+
if (mimeType.includes("sheet") || mimeType.includes("excel")) return "document";
|
|
12864
|
+
if (mimeType.includes("presentation") || mimeType.includes("powerpoint")) return "document";
|
|
12865
|
+
if (mimeType.startsWith("text/")) return "document";
|
|
12866
|
+
return "document";
|
|
12867
|
+
}
|
|
12868
|
+
async function getFileMetadata(fileId) {
|
|
12869
|
+
try {
|
|
12870
|
+
return await apiRequest(`/v1/cli/drive/files/${fileId}?includeContent=false`);
|
|
12871
|
+
} catch {
|
|
12872
|
+
return null;
|
|
12873
|
+
}
|
|
12874
|
+
}
|
|
12875
|
+
function parseVarArgs(varArgs) {
|
|
12876
|
+
const result = {};
|
|
12877
|
+
for (const arg of varArgs) {
|
|
12878
|
+
const eqIndex = arg.indexOf("=");
|
|
12879
|
+
if (eqIndex === -1) {
|
|
12880
|
+
throw new CLIError(
|
|
12881
|
+
ErrorCodes.INVALID_INPUT,
|
|
12882
|
+
`Invalid --var format: "${arg}"`,
|
|
12883
|
+
void 0,
|
|
12884
|
+
"Use format: --var key=value"
|
|
12885
|
+
);
|
|
12886
|
+
}
|
|
12887
|
+
const key = arg.slice(0, eqIndex);
|
|
12888
|
+
const value = arg.slice(eqIndex + 1);
|
|
12889
|
+
result[key] = value;
|
|
12890
|
+
}
|
|
12891
|
+
return result;
|
|
12892
|
+
}
|
|
12893
|
+
function formatVariable(v) {
|
|
12894
|
+
const hasValue = Array.isArray(v.value) && v.value.length > 0;
|
|
12895
|
+
return {
|
|
12896
|
+
name: v.name,
|
|
12897
|
+
variableId: v.variableId,
|
|
12898
|
+
type: v.variableType || "string",
|
|
12899
|
+
required: v.required ?? false,
|
|
12900
|
+
hasValue,
|
|
12901
|
+
value: hasValue ? v.value : void 0,
|
|
12902
|
+
description: v.description
|
|
12903
|
+
};
|
|
12904
|
+
}
|
|
12905
|
+
var variablesListCommand = new Command("list").description("List workflow variables with current values").argument("<workflowId>", "Workflow ID (canvas ID)").action(async (workflowId) => {
|
|
12906
|
+
try {
|
|
12907
|
+
const variables = await apiGetWorkflowVariables(workflowId);
|
|
12908
|
+
const formatted = variables.map(formatVariable);
|
|
12909
|
+
ok("workflow.variables.list", {
|
|
12910
|
+
workflowId,
|
|
12911
|
+
variables: formatted,
|
|
12912
|
+
count: variables.length
|
|
12913
|
+
});
|
|
12914
|
+
} catch (error) {
|
|
12915
|
+
if (error instanceof CLIError) {
|
|
12916
|
+
fail(error.code, error.message, {
|
|
12917
|
+
details: error.details,
|
|
12918
|
+
hint: error.hint,
|
|
12919
|
+
suggestedFix: error.suggestedFix
|
|
12920
|
+
});
|
|
12921
|
+
}
|
|
12922
|
+
fail(
|
|
12923
|
+
ErrorCodes.INTERNAL_ERROR,
|
|
12924
|
+
error instanceof Error ? error.message : "Failed to list variables"
|
|
12925
|
+
);
|
|
12926
|
+
}
|
|
12927
|
+
});
|
|
12928
|
+
var variablesGetCommand = new Command("get").description("Get a single workflow variable by name").argument("<workflowId>", "Workflow ID (canvas ID)").argument("<varName>", "Variable name to get").action(async (workflowId, varName) => {
|
|
12929
|
+
try {
|
|
12930
|
+
const variables = await apiGetWorkflowVariables(workflowId);
|
|
12931
|
+
const variable = variables.find((v) => v.name === varName || v.variableId === varName);
|
|
12932
|
+
if (!variable) {
|
|
12933
|
+
const availableNames = variables.map((v) => v.name).join(", ");
|
|
12934
|
+
fail(ErrorCodes.NOT_FOUND, `Variable not found: ${varName}`, {
|
|
12935
|
+
hint: `Available variables: ${availableNames}`
|
|
12936
|
+
});
|
|
12937
|
+
return;
|
|
12938
|
+
}
|
|
12939
|
+
ok("workflow.variables.get", {
|
|
12940
|
+
workflowId,
|
|
12941
|
+
variable: formatVariable(variable)
|
|
12942
|
+
});
|
|
12943
|
+
} catch (error) {
|
|
12944
|
+
if (error instanceof CLIError) {
|
|
12945
|
+
fail(error.code, error.message, {
|
|
12946
|
+
details: error.details,
|
|
12947
|
+
hint: error.hint,
|
|
12948
|
+
suggestedFix: error.suggestedFix
|
|
12949
|
+
});
|
|
12950
|
+
}
|
|
12951
|
+
fail(
|
|
12952
|
+
ErrorCodes.INTERNAL_ERROR,
|
|
12953
|
+
error instanceof Error ? error.message : "Failed to get variable"
|
|
12954
|
+
);
|
|
12955
|
+
}
|
|
12956
|
+
});
|
|
12957
|
+
var variablesSetCommand = new Command("set").description("Set variable values for a workflow").argument("<workflowId>", "Workflow ID (canvas ID)").option("--var <key=value...>", "Variable value in key=value format (can be repeated)").option("--input <json>", "Variable values as JSON object").option("--clear <name>", "Clear value for a specific variable").action(
|
|
12958
|
+
async (workflowId, options) => {
|
|
12959
|
+
try {
|
|
12960
|
+
const currentVars = await apiGetWorkflowVariables(workflowId);
|
|
12961
|
+
let newValues = {};
|
|
12962
|
+
if (options.input) {
|
|
12963
|
+
try {
|
|
12964
|
+
const parsed = JSON.parse(options.input);
|
|
12965
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
12966
|
+
fail(ErrorCodes.INVALID_INPUT, "Input must be a JSON object", {
|
|
12967
|
+
hint: `Use format: '{"varName": "value"}'`,
|
|
12968
|
+
suggestedFix: {
|
|
12969
|
+
field: "--input",
|
|
12970
|
+
format: "json-object",
|
|
12971
|
+
example: '{"varName": "value"}'
|
|
12972
|
+
}
|
|
12973
|
+
});
|
|
12974
|
+
}
|
|
12975
|
+
newValues = { ...parsed };
|
|
12976
|
+
} catch {
|
|
12977
|
+
fail(ErrorCodes.INVALID_INPUT, "Invalid JSON in --input", {
|
|
12978
|
+
hint: "Ensure the input is valid JSON",
|
|
12716
12979
|
suggestedFix: {
|
|
12717
|
-
field: "--
|
|
12718
|
-
format: "json-
|
|
12719
|
-
example: '
|
|
12980
|
+
field: "--input",
|
|
12981
|
+
format: "json-object",
|
|
12982
|
+
example: '{"varName": "value"}'
|
|
12720
12983
|
}
|
|
12721
12984
|
});
|
|
12722
12985
|
}
|
|
12723
|
-
}
|
|
12724
|
-
|
|
12725
|
-
|
|
12726
|
-
|
|
12727
|
-
|
|
12728
|
-
|
|
12729
|
-
|
|
12986
|
+
}
|
|
12987
|
+
if (options.var && options.var.length > 0) {
|
|
12988
|
+
const varBindings = parseVarArgs(options.var);
|
|
12989
|
+
newValues = { ...newValues, ...varBindings };
|
|
12990
|
+
}
|
|
12991
|
+
if (options.clear) {
|
|
12992
|
+
newValues[options.clear] = null;
|
|
12993
|
+
}
|
|
12994
|
+
if (Object.keys(newValues).length === 0) {
|
|
12995
|
+
fail(ErrorCodes.INVALID_INPUT, "No variables specified", {
|
|
12996
|
+
hint: `Use --var key=value, --input '{"key": "value"}', or --clear <name>`
|
|
12997
|
+
});
|
|
12998
|
+
}
|
|
12999
|
+
const fileIds = Object.values(newValues).filter(
|
|
13000
|
+
(v) => typeof v === "string" && v.startsWith("df-")
|
|
13001
|
+
);
|
|
13002
|
+
const fileMetadataMap = /* @__PURE__ */ new Map();
|
|
13003
|
+
for (const fileId of fileIds) {
|
|
13004
|
+
const metadata = await getFileMetadata(fileId);
|
|
13005
|
+
if (metadata) {
|
|
13006
|
+
fileMetadataMap.set(fileId, metadata);
|
|
13007
|
+
}
|
|
13008
|
+
}
|
|
13009
|
+
const updatedVars = currentVars.map((v) => {
|
|
13010
|
+
const name = v.name;
|
|
13011
|
+
if (name in newValues) {
|
|
13012
|
+
const newValue = newValues[name];
|
|
13013
|
+
if (newValue === null) {
|
|
13014
|
+
return { ...v, value: [] };
|
|
12730
13015
|
}
|
|
13016
|
+
if (typeof newValue === "string") {
|
|
13017
|
+
if (newValue.startsWith("df-")) {
|
|
13018
|
+
const metadata = fileMetadataMap.get(newValue);
|
|
13019
|
+
return {
|
|
13020
|
+
...v,
|
|
13021
|
+
value: [
|
|
13022
|
+
{
|
|
13023
|
+
type: "resource",
|
|
13024
|
+
resource: {
|
|
13025
|
+
fileId: newValue,
|
|
13026
|
+
name: metadata?.name || "",
|
|
13027
|
+
fileType: metadata ? getFileTypeCategory(metadata.type) : "document",
|
|
13028
|
+
storageKey: metadata?.storageKey || ""
|
|
13029
|
+
}
|
|
13030
|
+
}
|
|
13031
|
+
]
|
|
13032
|
+
};
|
|
13033
|
+
}
|
|
13034
|
+
return {
|
|
13035
|
+
...v,
|
|
13036
|
+
value: [{ type: "text", text: newValue }]
|
|
13037
|
+
};
|
|
13038
|
+
}
|
|
13039
|
+
if (Array.isArray(newValue)) {
|
|
13040
|
+
return { ...v, value: newValue };
|
|
13041
|
+
}
|
|
13042
|
+
return v;
|
|
13043
|
+
}
|
|
13044
|
+
return v;
|
|
13045
|
+
});
|
|
13046
|
+
const definedNames = new Set(currentVars.map((v) => v.name));
|
|
13047
|
+
const unknownVars = Object.keys(newValues).filter((k) => !definedNames.has(k));
|
|
13048
|
+
if (unknownVars.length > 0) {
|
|
13049
|
+
fail(ErrorCodes.INVALID_INPUT, `Unknown variables: ${unknownVars.join(", ")}`, {
|
|
13050
|
+
hint: `Available variables: ${Array.from(definedNames).join(", ")}`
|
|
12731
13051
|
});
|
|
12732
13052
|
}
|
|
12733
|
-
|
|
12734
|
-
|
|
12735
|
-
|
|
12736
|
-
|
|
12737
|
-
|
|
13053
|
+
const result = await apiUpdateWorkflowVariables(workflowId, updatedVars);
|
|
13054
|
+
ok("workflow.variables.set", {
|
|
13055
|
+
workflowId,
|
|
13056
|
+
updated: Object.keys(newValues),
|
|
13057
|
+
variables: result.map(formatVariable)
|
|
12738
13058
|
});
|
|
13059
|
+
} catch (error) {
|
|
13060
|
+
if (error instanceof CLIError) {
|
|
13061
|
+
fail(error.code, error.message, {
|
|
13062
|
+
details: error.details,
|
|
13063
|
+
hint: error.hint,
|
|
13064
|
+
suggestedFix: error.suggestedFix
|
|
13065
|
+
});
|
|
13066
|
+
}
|
|
13067
|
+
fail(
|
|
13068
|
+
ErrorCodes.INTERNAL_ERROR,
|
|
13069
|
+
error instanceof Error ? error.message : "Failed to set variables"
|
|
13070
|
+
);
|
|
12739
13071
|
}
|
|
12740
|
-
|
|
12741
|
-
|
|
12742
|
-
|
|
12743
|
-
|
|
12744
|
-
|
|
13072
|
+
}
|
|
13073
|
+
);
|
|
13074
|
+
var workflowVariablesCommand = new Command("variables").description("Manage workflow variable values").addCommand(variablesListCommand).addCommand(variablesGetCommand).addCommand(variablesSetCommand);
|
|
13075
|
+
|
|
13076
|
+
// src/commands/workflow/result.ts
|
|
13077
|
+
init_cjs_shims();
|
|
13078
|
+
function formatResult(result, options) {
|
|
13079
|
+
const output3 = {
|
|
13080
|
+
resultId: result.resultId,
|
|
13081
|
+
version: result.version,
|
|
13082
|
+
title: result.title,
|
|
13083
|
+
type: result.type,
|
|
13084
|
+
status: result.status
|
|
13085
|
+
};
|
|
13086
|
+
if (result.workflowExecutionId) {
|
|
13087
|
+
output3.workflowExecutionId = result.workflowExecutionId;
|
|
13088
|
+
}
|
|
13089
|
+
if (result.workflowNodeExecutionId) {
|
|
13090
|
+
output3.workflowNodeExecutionId = result.workflowNodeExecutionId;
|
|
13091
|
+
}
|
|
13092
|
+
output3.timing = {
|
|
13093
|
+
createdAt: result.createdAt,
|
|
13094
|
+
updatedAt: result.updatedAt
|
|
13095
|
+
};
|
|
13096
|
+
if (result.errors && result.errors.length > 0) {
|
|
13097
|
+
output3.errors = result.errors;
|
|
13098
|
+
}
|
|
13099
|
+
if (result.errorType) {
|
|
13100
|
+
output3.errorType = result.errorType;
|
|
13101
|
+
}
|
|
13102
|
+
if (result.outputUrl) {
|
|
13103
|
+
output3.outputUrl = result.outputUrl;
|
|
13104
|
+
}
|
|
13105
|
+
if (result.files && result.files.length > 0) {
|
|
13106
|
+
output3.files = result.files;
|
|
13107
|
+
}
|
|
13108
|
+
if (result.modelInfo) {
|
|
13109
|
+
output3.modelInfo = result.modelInfo;
|
|
13110
|
+
}
|
|
13111
|
+
if (options.includeSteps && result.steps) {
|
|
13112
|
+
if (options.raw) {
|
|
13113
|
+
output3.steps = result.steps;
|
|
13114
|
+
} else {
|
|
13115
|
+
output3.steps = result.steps.map((step) => ({
|
|
13116
|
+
name: step.name,
|
|
13117
|
+
contentPreview: step.content?.substring(0, 200) + (step.content && step.content.length > 200 ? "..." : ""),
|
|
13118
|
+
toolCallsCount: step.toolCalls?.length || 0,
|
|
13119
|
+
...options.includeToolCalls && step.toolCalls ? {
|
|
13120
|
+
toolCalls: step.toolCalls.map((tc) => ({
|
|
13121
|
+
callId: tc.callId,
|
|
13122
|
+
toolName: tc.toolName,
|
|
13123
|
+
status: tc.status,
|
|
13124
|
+
...options.raw ? { input: tc.input, output: tc.output } : {},
|
|
13125
|
+
...tc.error ? { error: tc.error } : {}
|
|
13126
|
+
}))
|
|
13127
|
+
} : {}
|
|
13128
|
+
}));
|
|
12745
13129
|
}
|
|
12746
|
-
|
|
12747
|
-
|
|
12748
|
-
|
|
12749
|
-
|
|
12750
|
-
|
|
13130
|
+
}
|
|
13131
|
+
if (options.includeMessages && result.messages) {
|
|
13132
|
+
if (options.raw) {
|
|
13133
|
+
output3.messages = result.messages;
|
|
13134
|
+
} else {
|
|
13135
|
+
output3.messages = result.messages.map((msg) => ({
|
|
13136
|
+
messageId: msg.messageId,
|
|
13137
|
+
type: msg.type,
|
|
13138
|
+
contentPreview: msg.content?.substring(0, 200) + (msg.content && msg.content.length > 200 ? "..." : ""),
|
|
13139
|
+
createdAt: msg.createdAt
|
|
13140
|
+
}));
|
|
12751
13141
|
}
|
|
12752
|
-
|
|
12753
|
-
|
|
12754
|
-
|
|
13142
|
+
}
|
|
13143
|
+
return output3;
|
|
13144
|
+
}
|
|
13145
|
+
var workflowResultCommand = new Command("result").description("Get action result by resultId").argument("<resultId>", "Action result ID (ar-xxx)").option("--include-steps", "Include execution steps").option("--include-messages", "Include action messages").option("--include-tool-calls", "Include tool call details (requires --include-steps)").option("--raw", "Show full content without truncation").action(async (resultId, options) => {
|
|
13146
|
+
try {
|
|
13147
|
+
if (!resultId.startsWith("ar-") && !resultId.startsWith("start-")) {
|
|
13148
|
+
return fail(ErrorCodes.INVALID_INPUT, `Invalid resultId format: ${resultId}`, {
|
|
13149
|
+
hint: 'Result ID should start with "ar-" or "start-"',
|
|
12755
13150
|
suggestedFix: {
|
|
12756
|
-
field: "
|
|
12757
|
-
format: "
|
|
12758
|
-
example:
|
|
13151
|
+
field: "resultId",
|
|
13152
|
+
format: "ar-xxx or start-xxx",
|
|
13153
|
+
example: "ar-cq18zd4qr97nbla1tu1rqqmd"
|
|
12759
13154
|
}
|
|
12760
13155
|
});
|
|
12761
13156
|
}
|
|
12762
|
-
const
|
|
12763
|
-
|
|
12764
|
-
|
|
12765
|
-
|
|
12766
|
-
|
|
12767
|
-
|
|
12768
|
-
body
|
|
12769
|
-
});
|
|
12770
|
-
const plan = response.data ?? response;
|
|
12771
|
-
ok("workflow.edit", {
|
|
12772
|
-
planId,
|
|
12773
|
-
operationsApplied: operations.length,
|
|
12774
|
-
plan: {
|
|
12775
|
-
title: plan.title,
|
|
12776
|
-
taskCount: plan.tasks?.length ?? 0,
|
|
12777
|
-
variableCount: plan.variables?.length ?? 0,
|
|
12778
|
-
tasks: plan.tasks?.map((t) => ({
|
|
12779
|
-
id: t.id,
|
|
12780
|
-
title: t.title
|
|
12781
|
-
})),
|
|
12782
|
-
variables: plan.variables?.map((v) => ({
|
|
12783
|
-
variableId: v.variableId,
|
|
12784
|
-
name: v.name
|
|
12785
|
-
}))
|
|
12786
|
-
}
|
|
13157
|
+
const result = await apiGetActionResult(resultId);
|
|
13158
|
+
const formattedResult = formatResult(result, {
|
|
13159
|
+
includeSteps: options.includeSteps,
|
|
13160
|
+
includeMessages: options.includeMessages,
|
|
13161
|
+
includeToolCalls: options.includeToolCalls,
|
|
13162
|
+
raw: options.raw
|
|
12787
13163
|
});
|
|
13164
|
+
ok("workflow.result", formattedResult);
|
|
12788
13165
|
} catch (error) {
|
|
12789
13166
|
if (error instanceof CLIError) {
|
|
12790
13167
|
fail(error.code, error.message, {
|
|
@@ -12792,17 +13169,39 @@ Examples:
|
|
|
12792
13169
|
hint: error.hint,
|
|
12793
13170
|
suggestedFix: error.suggestedFix
|
|
12794
13171
|
});
|
|
12795
|
-
return;
|
|
12796
13172
|
}
|
|
12797
13173
|
fail(
|
|
12798
13174
|
ErrorCodes.INTERNAL_ERROR,
|
|
12799
|
-
error instanceof Error ? error.message : "Failed to
|
|
13175
|
+
error instanceof Error ? error.message : "Failed to get action result"
|
|
13176
|
+
);
|
|
13177
|
+
}
|
|
13178
|
+
});
|
|
13179
|
+
|
|
13180
|
+
// src/commands/workflow/session.ts
|
|
13181
|
+
init_cjs_shims();
|
|
13182
|
+
var workflowSessionCommand = new Command("session").description("Get the latest copilot session for a workflow").argument("<workflowId>", "Workflow ID (canvas ID)").action(async (workflowId) => {
|
|
13183
|
+
try {
|
|
13184
|
+
const result = await apiRequest(
|
|
13185
|
+
`/v1/cli/workflow/${workflowId}/session`
|
|
13186
|
+
);
|
|
13187
|
+
ok("workflow.session", result);
|
|
13188
|
+
} catch (error) {
|
|
13189
|
+
if (error instanceof CLIError) {
|
|
13190
|
+
fail(error.code, error.message, {
|
|
13191
|
+
details: error.details,
|
|
13192
|
+
hint: error.hint,
|
|
13193
|
+
suggestedFix: error.suggestedFix
|
|
13194
|
+
});
|
|
13195
|
+
}
|
|
13196
|
+
fail(
|
|
13197
|
+
ErrorCodes.INTERNAL_ERROR,
|
|
13198
|
+
error instanceof Error ? error.message : "Failed to get workflow session"
|
|
12800
13199
|
);
|
|
12801
13200
|
}
|
|
12802
13201
|
});
|
|
12803
13202
|
|
|
12804
13203
|
// src/commands/workflow/index.ts
|
|
12805
|
-
var workflowCommand = new Command("workflow").description("Manage and run workflows").addCommand(workflowCreateCommand).addCommand(workflowGenerateCommand).addCommand(workflowListCommand).addCommand(workflowGetCommand).addCommand(workflowDeleteCommand).addCommand(workflowRunCommand).addCommand(workflowRunsCommand).addCommand(workflowStatusCommand).addCommand(workflowDetailCommand).addCommand(workflowToolcallsCommand).addCommand(workflowAbortCommand).addCommand(workflowToolsetKeysCommand).addCommand(workflowLayoutCommand).addCommand(workflowNodesCommand).addCommand(workflowNodeGetCommand).addCommand(workflowNodeAddCommand).addCommand(workflowNodeUpdateCommand).addCommand(workflowNodeDeleteCommand).addCommand(workflowNodeOutputCommand).addCommand(workflowEditCommand);
|
|
13204
|
+
var workflowCommand = new Command("workflow").description("Manage and run workflows").addCommand(workflowCreateCommand).addCommand(workflowGenerateCommand).addCommand(workflowListCommand).addCommand(workflowGetCommand).addCommand(workflowDeleteCommand).addCommand(workflowRunCommand).addCommand(workflowRunsCommand).addCommand(workflowStatusCommand).addCommand(workflowDetailCommand).addCommand(workflowToolcallsCommand).addCommand(workflowAbortCommand).addCommand(workflowToolsetKeysCommand).addCommand(workflowLayoutCommand).addCommand(workflowNodesCommand).addCommand(workflowNodeGetCommand).addCommand(workflowNodeAddCommand).addCommand(workflowNodeUpdateCommand).addCommand(workflowNodeDeleteCommand).addCommand(workflowNodeOutputCommand).addCommand(workflowEditCommand).addCommand(workflowVariablesCommand).addCommand(workflowSessionCommand).addCommand(workflowResultCommand);
|
|
12806
13205
|
|
|
12807
13206
|
// src/commands/tool/index.ts
|
|
12808
13207
|
init_cjs_shims();
|
|
@@ -12982,7 +13381,7 @@ var fileGetCommand = new Command("get").description("Get file details").argument
|
|
|
12982
13381
|
|
|
12983
13382
|
// src/commands/file/download.ts
|
|
12984
13383
|
init_cjs_shims();
|
|
12985
|
-
var
|
|
13384
|
+
var fs14 = __toESM(require("fs"));
|
|
12986
13385
|
var path11 = __toESM(require("path"));
|
|
12987
13386
|
var fileDownloadCommand = new Command("download").description("Download file to local filesystem").argument("<fileId>", "File ID").option("-o, --output <path>", "Output file path (defaults to original filename)").action(async (fileId, options) => {
|
|
12988
13387
|
try {
|
|
@@ -12991,7 +13390,7 @@ var fileDownloadCommand = new Command("download").description("Download file to
|
|
|
12991
13390
|
);
|
|
12992
13391
|
const outputPath = options.output || filename || `${fileId}`;
|
|
12993
13392
|
const resolvedPath = path11.resolve(outputPath);
|
|
12994
|
-
|
|
13393
|
+
fs14.writeFileSync(resolvedPath, data);
|
|
12995
13394
|
ok("file.download", {
|
|
12996
13395
|
fileId,
|
|
12997
13396
|
path: resolvedPath,
|
|
@@ -13016,7 +13415,7 @@ var fileDownloadCommand = new Command("download").description("Download file to
|
|
|
13016
13415
|
|
|
13017
13416
|
// src/commands/file/upload.ts
|
|
13018
13417
|
init_cjs_shims();
|
|
13019
|
-
var
|
|
13418
|
+
var fs15 = __toESM(require("fs"));
|
|
13020
13419
|
var path12 = __toESM(require("path"));
|
|
13021
13420
|
var MAX_FILES = 10;
|
|
13022
13421
|
function formatSize(bytes) {
|
|
@@ -13028,7 +13427,7 @@ var fileUploadCommand = new Command("upload").description("Upload file(s) to a c
|
|
|
13028
13427
|
const formatter = getFormatter();
|
|
13029
13428
|
try {
|
|
13030
13429
|
const resolvedPath = path12.resolve(inputPath);
|
|
13031
|
-
if (!
|
|
13430
|
+
if (!fs15.existsSync(resolvedPath)) {
|
|
13032
13431
|
fail(ErrorCodes.NOT_FOUND, `Path not found: ${inputPath}`, {
|
|
13033
13432
|
hint: "Check if the file or directory exists"
|
|
13034
13433
|
});
|
|
@@ -13047,7 +13446,7 @@ var fileUploadCommand = new Command("upload").description("Upload file(s) to a c
|
|
|
13047
13446
|
for (let i = 0; i < files.length; i++) {
|
|
13048
13447
|
const filePath = files[i];
|
|
13049
13448
|
const filename = path12.basename(filePath);
|
|
13050
|
-
const fileStats =
|
|
13449
|
+
const fileStats = fs15.statSync(filePath);
|
|
13051
13450
|
const sizeStr = formatSize(fileStats.size);
|
|
13052
13451
|
let currentStage = "presign";
|
|
13053
13452
|
const updateProgress = () => {
|
|
@@ -13128,7 +13527,7 @@ var fileUploadCommand = new Command("upload").description("Upload file(s) to a c
|
|
|
13128
13527
|
}
|
|
13129
13528
|
});
|
|
13130
13529
|
function resolveFilesToUpload(inputPath, filter) {
|
|
13131
|
-
const stats =
|
|
13530
|
+
const stats = fs15.statSync(inputPath);
|
|
13132
13531
|
if (stats.isFile()) {
|
|
13133
13532
|
if (filter) {
|
|
13134
13533
|
const filterExts = filter.split(",").map((e) => e.trim().toLowerCase());
|
|
@@ -13140,11 +13539,11 @@ function resolveFilesToUpload(inputPath, filter) {
|
|
|
13140
13539
|
return [inputPath];
|
|
13141
13540
|
}
|
|
13142
13541
|
if (stats.isDirectory()) {
|
|
13143
|
-
const entries =
|
|
13542
|
+
const entries = fs15.readdirSync(inputPath);
|
|
13144
13543
|
const filterExts = filter?.split(",").map((e) => e.trim().toLowerCase());
|
|
13145
13544
|
const files = entries.map((e) => path12.join(inputPath, e)).filter((p) => {
|
|
13146
13545
|
try {
|
|
13147
|
-
return
|
|
13546
|
+
return fs15.statSync(p).isFile();
|
|
13148
13547
|
} catch {
|
|
13149
13548
|
return false;
|
|
13150
13549
|
}
|
|
@@ -13154,7 +13553,7 @@ function resolveFilesToUpload(inputPath, filter) {
|
|
|
13154
13553
|
return filterExts.includes(ext);
|
|
13155
13554
|
}).sort((a, b) => {
|
|
13156
13555
|
try {
|
|
13157
|
-
return
|
|
13556
|
+
return fs15.statSync(a).size - fs15.statSync(b).size;
|
|
13158
13557
|
} catch {
|
|
13159
13558
|
return 0;
|
|
13160
13559
|
}
|
|
@@ -13258,7 +13657,7 @@ var skillGetCommand = new Command("get").description("Get skill package details"
|
|
|
13258
13657
|
|
|
13259
13658
|
// src/commands/skill/create.ts
|
|
13260
13659
|
init_cjs_shims();
|
|
13261
|
-
var
|
|
13660
|
+
var fs16 = __toESM(require("fs"));
|
|
13262
13661
|
init_symlink();
|
|
13263
13662
|
init_paths();
|
|
13264
13663
|
init_logger();
|
|
@@ -13304,13 +13703,13 @@ var skillCreateCommand = new Command("create").description("Create a new skill p
|
|
|
13304
13703
|
});
|
|
13305
13704
|
const result = response.payload;
|
|
13306
13705
|
let localPath;
|
|
13307
|
-
let
|
|
13706
|
+
let _symlinkPath;
|
|
13308
13707
|
if (result.workflowId) {
|
|
13309
13708
|
try {
|
|
13310
13709
|
const localName = options.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
13311
13710
|
const skillDir = getReflyDomainSkillDir(localName);
|
|
13312
13711
|
const symlinkStatus = isSkillSymlinkValid(localName);
|
|
13313
|
-
if (
|
|
13712
|
+
if (fs16.existsSync(skillDir) || symlinkStatus.exists) {
|
|
13314
13713
|
logger.debug(`Local skill '${localName}' already exists, skipping sync`);
|
|
13315
13714
|
} else {
|
|
13316
13715
|
const skillMdContent = generateReflySkillMd({
|
|
@@ -13328,7 +13727,7 @@ var skillCreateCommand = new Command("create").description("Create a new skill p
|
|
|
13328
13727
|
const symlinkResult = createReflySkillWithSymlink(localName, skillMdContent);
|
|
13329
13728
|
if (symlinkResult.success) {
|
|
13330
13729
|
localPath = symlinkResult.reflyPath;
|
|
13331
|
-
|
|
13730
|
+
_symlinkPath = symlinkResult.claudePath;
|
|
13332
13731
|
logger.info(`Created local domain skill: ${localName}`);
|
|
13333
13732
|
} else {
|
|
13334
13733
|
logger.warn(`Failed to create local skill: ${symlinkResult.error}`);
|
|
@@ -13338,18 +13737,16 @@ var skillCreateCommand = new Command("create").description("Create a new skill p
|
|
|
13338
13737
|
logger.warn(`Failed to sync to local: ${syncError.message}`);
|
|
13339
13738
|
}
|
|
13340
13739
|
}
|
|
13740
|
+
const webUrl = getWebUrl();
|
|
13341
13741
|
const payload = {
|
|
13342
13742
|
skillId: result.skillId,
|
|
13343
13743
|
name: result.name,
|
|
13344
13744
|
status: result.status,
|
|
13345
13745
|
createdAt: result.createdAt,
|
|
13346
13746
|
workflowId: result.workflowId,
|
|
13347
|
-
|
|
13747
|
+
workflowUrl: result.workflowId ? `${webUrl}/workflow/${result.workflowId}` : void 0,
|
|
13748
|
+
localPath
|
|
13348
13749
|
};
|
|
13349
|
-
if (localPath) {
|
|
13350
|
-
payload.localPath = localPath;
|
|
13351
|
-
payload.symlinkPath = symlinkPath;
|
|
13352
|
-
}
|
|
13353
13750
|
if (options.verbose) {
|
|
13354
13751
|
payload.workflowIds = result.workflowIds;
|
|
13355
13752
|
payload.workflows = result.workflows;
|
|
@@ -13373,7 +13770,7 @@ var skillCreateCommand = new Command("create").description("Create a new skill p
|
|
|
13373
13770
|
|
|
13374
13771
|
// src/commands/skill/update.ts
|
|
13375
13772
|
init_cjs_shims();
|
|
13376
|
-
var
|
|
13773
|
+
var fs17 = __toESM(require("fs"));
|
|
13377
13774
|
var path13 = __toESM(require("path"));
|
|
13378
13775
|
init_paths();
|
|
13379
13776
|
init_symlink();
|
|
@@ -13405,7 +13802,7 @@ var skillUpdateCommand = new Command("update").description("Update skill install
|
|
|
13405
13802
|
const name = options.name;
|
|
13406
13803
|
const skillDir = getReflyDomainSkillDir(name);
|
|
13407
13804
|
const skillMdPath = path13.join(skillDir, "SKILL.md");
|
|
13408
|
-
if (!
|
|
13805
|
+
if (!fs17.existsSync(skillMdPath)) {
|
|
13409
13806
|
const skillsDir = getReflySkillsDir();
|
|
13410
13807
|
fail(ErrorCodes.NOT_FOUND, `SKILL.md not found at ${skillMdPath}`, {
|
|
13411
13808
|
hint: `Make sure the skill '${name}' exists in ${skillsDir}/
|
|
@@ -13414,7 +13811,7 @@ To see installed skills: refly skill list`
|
|
|
13414
13811
|
});
|
|
13415
13812
|
return;
|
|
13416
13813
|
}
|
|
13417
|
-
const skillContent =
|
|
13814
|
+
const skillContent = fs17.readFileSync(skillMdPath, "utf-8");
|
|
13418
13815
|
let meta;
|
|
13419
13816
|
try {
|
|
13420
13817
|
const parsed = parseReflySkillMd(skillContent);
|
|
@@ -13497,7 +13894,7 @@ To see installed skills: refly skill list`
|
|
|
13497
13894
|
|
|
13498
13895
|
// src/commands/skill/publish.ts
|
|
13499
13896
|
init_cjs_shims();
|
|
13500
|
-
var
|
|
13897
|
+
var fs18 = __toESM(require("fs"));
|
|
13501
13898
|
var path14 = __toESM(require("path"));
|
|
13502
13899
|
init_symlink();
|
|
13503
13900
|
init_paths();
|
|
@@ -13521,7 +13918,7 @@ To find your skill name:
|
|
|
13521
13918
|
const name = options.name;
|
|
13522
13919
|
const skillDir = getReflyDomainSkillDir(name);
|
|
13523
13920
|
const skillMdPath = path14.join(skillDir, "SKILL.md");
|
|
13524
|
-
if (!
|
|
13921
|
+
if (!fs18.existsSync(skillMdPath)) {
|
|
13525
13922
|
fail(ErrorCodes.NOT_FOUND, `SKILL.md not found at ${skillMdPath}`, {
|
|
13526
13923
|
hint: `Make sure the skill '${name}' exists in ${skillsDir}/
|
|
13527
13924
|
|
|
@@ -13530,7 +13927,7 @@ To create a new skill: refly skill create --name "${name}" --workflow-query "...
|
|
|
13530
13927
|
});
|
|
13531
13928
|
return;
|
|
13532
13929
|
}
|
|
13533
|
-
const skillContent =
|
|
13930
|
+
const skillContent = fs18.readFileSync(skillMdPath, "utf-8");
|
|
13534
13931
|
let parsedSkill;
|
|
13535
13932
|
try {
|
|
13536
13933
|
parsedSkill = parseReflySkillMd(skillContent);
|
|
@@ -13561,8 +13958,6 @@ To create a new skill: refly skill create --name "${name}" --workflow-query "...
|
|
|
13561
13958
|
version: result.version,
|
|
13562
13959
|
status: result.status,
|
|
13563
13960
|
isPublic: result.isPublic,
|
|
13564
|
-
shareId: result.shareId,
|
|
13565
|
-
shareUrl: result.shareId ? `https://refly.ai/skill/${result.shareId}` : void 0,
|
|
13566
13961
|
githubPrUrl: result.githubPrUrl,
|
|
13567
13962
|
githubPrNumber: result.githubPrNumber,
|
|
13568
13963
|
localPath: skillMdPath
|
|
@@ -13585,7 +13980,7 @@ To create a new skill: refly skill create --name "${name}" --workflow-query "...
|
|
|
13585
13980
|
|
|
13586
13981
|
// src/commands/skill/unpublish.ts
|
|
13587
13982
|
init_cjs_shims();
|
|
13588
|
-
var
|
|
13983
|
+
var fs19 = __toESM(require("fs"));
|
|
13589
13984
|
var path15 = __toESM(require("path"));
|
|
13590
13985
|
init_symlink();
|
|
13591
13986
|
init_paths();
|
|
@@ -13610,7 +14005,7 @@ To find your skill name:
|
|
|
13610
14005
|
name = options.name;
|
|
13611
14006
|
const skillDir = getReflyDomainSkillDir(name);
|
|
13612
14007
|
const skillMdPath = path15.join(skillDir, "SKILL.md");
|
|
13613
|
-
if (!
|
|
14008
|
+
if (!fs19.existsSync(skillMdPath)) {
|
|
13614
14009
|
fail(ErrorCodes.NOT_FOUND, `SKILL.md not found at ${skillMdPath}`, {
|
|
13615
14010
|
hint: `Make sure the skill '${name}' exists in ${skillsDir}/
|
|
13616
14011
|
|
|
@@ -13618,7 +14013,7 @@ To see installed skills: refly skill list`
|
|
|
13618
14013
|
});
|
|
13619
14014
|
return;
|
|
13620
14015
|
}
|
|
13621
|
-
const skillContent =
|
|
14016
|
+
const skillContent = fs19.readFileSync(skillMdPath, "utf-8");
|
|
13622
14017
|
try {
|
|
13623
14018
|
const { meta } = parseReflySkillMd(skillContent);
|
|
13624
14019
|
skillId = options.id || meta.skillId;
|
|
@@ -13662,11 +14057,11 @@ To see installed skills: refly skill list`
|
|
|
13662
14057
|
|
|
13663
14058
|
// src/commands/skill/run.ts
|
|
13664
14059
|
init_cjs_shims();
|
|
13665
|
-
var
|
|
14060
|
+
var fs20 = __toESM(require("fs"));
|
|
13666
14061
|
var path16 = __toESM(require("path"));
|
|
13667
14062
|
init_symlink();
|
|
13668
14063
|
init_paths();
|
|
13669
|
-
var skillRunCommand = new Command("run").description("Run an installed skill").option("--id <installationId>", "Installation ID (skpi-xxx)").option("--name <name>", "Local skill name (directory in ~/.refly/skills/)").option("--input <json>", "Input JSON for the skill").option("--workflow <skillWorkflowId>", "Run specific workflow only").option("--async", "Run asynchronously").action(async (options) => {
|
|
14064
|
+
var skillRunCommand = new Command("run").description("Run an installed skill").option("--id <installationId>", "Installation ID (skpi-xxx)").option("--name <name>", "Local skill name (directory in ~/.refly/skills/)").option("--input <json>", "Input JSON for the skill").option("--workflow <skillWorkflowId>", "Run specific workflow only").option("--async", "Run asynchronously").option("--no-prompt", "Disable interactive prompts (fail if required variables are missing)").action(async (options) => {
|
|
13670
14065
|
try {
|
|
13671
14066
|
const skillsDir = getReflySkillsDir();
|
|
13672
14067
|
if (!options.id && !options.name) {
|
|
@@ -13684,11 +14079,12 @@ To find your skill name:
|
|
|
13684
14079
|
let installationId;
|
|
13685
14080
|
let name;
|
|
13686
14081
|
let skillId;
|
|
14082
|
+
let workflowId;
|
|
13687
14083
|
if (options.name) {
|
|
13688
14084
|
name = options.name;
|
|
13689
|
-
const skillDir = getReflyDomainSkillDir(name);
|
|
14085
|
+
const skillDir = getReflyDomainSkillDir(options.name);
|
|
13690
14086
|
const skillMdPath = path16.join(skillDir, "SKILL.md");
|
|
13691
|
-
if (!
|
|
14087
|
+
if (!fs20.existsSync(skillMdPath)) {
|
|
13692
14088
|
fail(ErrorCodes.NOT_FOUND, `SKILL.md not found at ${skillMdPath}`, {
|
|
13693
14089
|
hint: `Make sure the skill '${name}' exists in ${skillsDir}/
|
|
13694
14090
|
|
|
@@ -13697,10 +14093,11 @@ To install a skill: refly skill install <skillId>`
|
|
|
13697
14093
|
});
|
|
13698
14094
|
return;
|
|
13699
14095
|
}
|
|
13700
|
-
const skillContent =
|
|
14096
|
+
const skillContent = fs20.readFileSync(skillMdPath, "utf-8");
|
|
13701
14097
|
try {
|
|
13702
14098
|
const { meta } = parseReflySkillMd(skillContent);
|
|
13703
14099
|
skillId = meta.skillId;
|
|
14100
|
+
workflowId = meta.workflowId;
|
|
13704
14101
|
if (options.id) {
|
|
13705
14102
|
installationId = options.id;
|
|
13706
14103
|
} else if (meta.installationId) {
|
|
@@ -13753,6 +14150,29 @@ To install: refly skill install ${meta.skillId}`
|
|
|
13753
14150
|
return;
|
|
13754
14151
|
}
|
|
13755
14152
|
}
|
|
14153
|
+
if (options.noPrompt && workflowId) {
|
|
14154
|
+
try {
|
|
14155
|
+
const workflow = await apiGetWorkflow(workflowId);
|
|
14156
|
+
if (workflow?.variables) {
|
|
14157
|
+
const checkResult = checkRequiredVariables(workflow.variables, input3);
|
|
14158
|
+
if (!checkResult.valid) {
|
|
14159
|
+
const errorPayload = buildMissingVariablesError(
|
|
14160
|
+
"skill",
|
|
14161
|
+
name || installationId,
|
|
14162
|
+
name,
|
|
14163
|
+
checkResult
|
|
14164
|
+
);
|
|
14165
|
+
fail(ErrorCodes.MISSING_VARIABLES, errorPayload.message, {
|
|
14166
|
+
details: errorPayload.details,
|
|
14167
|
+
hint: errorPayload.hint,
|
|
14168
|
+
suggestedFix: errorPayload.suggestedFix,
|
|
14169
|
+
recoverable: errorPayload.recoverable
|
|
14170
|
+
});
|
|
14171
|
+
}
|
|
14172
|
+
}
|
|
14173
|
+
} catch {
|
|
14174
|
+
}
|
|
14175
|
+
}
|
|
13756
14176
|
const body = { input: input3 };
|
|
13757
14177
|
if (options.workflow) body.workflowId = options.workflow;
|
|
13758
14178
|
if (options.async) body.async = true;
|
|
@@ -13789,6 +14209,87 @@ To install: refly skill install ${meta.skillId}`
|
|
|
13789
14209
|
}
|
|
13790
14210
|
});
|
|
13791
14211
|
|
|
14212
|
+
// src/commands/skill/stop.ts
|
|
14213
|
+
init_cjs_shims();
|
|
14214
|
+
var fs21 = __toESM(require("fs"));
|
|
14215
|
+
var path17 = __toESM(require("path"));
|
|
14216
|
+
init_symlink();
|
|
14217
|
+
init_paths();
|
|
14218
|
+
function getLocalSkillNames() {
|
|
14219
|
+
const skillsDir = getReflySkillsDir();
|
|
14220
|
+
if (!fs21.existsSync(skillsDir)) {
|
|
14221
|
+
return [];
|
|
14222
|
+
}
|
|
14223
|
+
return fs21.readdirSync(skillsDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
|
|
14224
|
+
}
|
|
14225
|
+
var skillStopCommand = new Command("stop").description("Stop running skill executions").requiredOption("--name <name>", "Local skill name (directory in ~/.refly/skills/)").action(async (options) => {
|
|
14226
|
+
try {
|
|
14227
|
+
const skillsDir = getReflySkillsDir();
|
|
14228
|
+
const name = options.name;
|
|
14229
|
+
const skillDir = getReflyDomainSkillDir(name);
|
|
14230
|
+
const skillMdPath = path17.join(skillDir, "SKILL.md");
|
|
14231
|
+
if (!fs21.existsSync(skillMdPath)) {
|
|
14232
|
+
const availableSkills = getLocalSkillNames();
|
|
14233
|
+
const skillList = availableSkills.length > 0 ? availableSkills.join(", ") : "(no skills installed)";
|
|
14234
|
+
fail(ErrorCodes.NOT_FOUND, `Skill "${name}" not found`, {
|
|
14235
|
+
hint: `Available skills: ${skillList}
|
|
14236
|
+
|
|
14237
|
+
Skills directory: ${skillsDir}`
|
|
14238
|
+
});
|
|
14239
|
+
}
|
|
14240
|
+
const skillContent = fs21.readFileSync(skillMdPath, "utf-8");
|
|
14241
|
+
let installationId;
|
|
14242
|
+
try {
|
|
14243
|
+
const { meta } = parseReflySkillMd(skillContent);
|
|
14244
|
+
if (!meta.installationId) {
|
|
14245
|
+
fail(ErrorCodes.INVALID_INPUT, `Skill "${name}" does not have an installationId`, {
|
|
14246
|
+
hint: `This skill may have been created locally but not installed.
|
|
14247
|
+
|
|
14248
|
+
To install: refly skill install ${meta.skillId}`
|
|
14249
|
+
});
|
|
14250
|
+
}
|
|
14251
|
+
installationId = meta.installationId;
|
|
14252
|
+
} catch (parseError) {
|
|
14253
|
+
fail(
|
|
14254
|
+
ErrorCodes.INVALID_INPUT,
|
|
14255
|
+
`Failed to parse SKILL.md: ${parseError.message}`,
|
|
14256
|
+
{
|
|
14257
|
+
hint: "Make sure SKILL.md has valid frontmatter with required fields"
|
|
14258
|
+
}
|
|
14259
|
+
);
|
|
14260
|
+
}
|
|
14261
|
+
const result = await apiRequest(
|
|
14262
|
+
`/v1/skill-installations/${installationId}/stop`,
|
|
14263
|
+
{
|
|
14264
|
+
method: "POST"
|
|
14265
|
+
}
|
|
14266
|
+
);
|
|
14267
|
+
ok("skill.stop", {
|
|
14268
|
+
name,
|
|
14269
|
+
installationId,
|
|
14270
|
+
message: result.message,
|
|
14271
|
+
stoppedExecutions: result.stoppedExecutions
|
|
14272
|
+
});
|
|
14273
|
+
} catch (error) {
|
|
14274
|
+
if (error instanceof CLIError) {
|
|
14275
|
+
if (error.code === "NOT_FOUND") {
|
|
14276
|
+
fail(ErrorCodes.NOT_FOUND, `No running executions for skill "${options.name}"`, {
|
|
14277
|
+
hint: "The skill is not currently running"
|
|
14278
|
+
});
|
|
14279
|
+
}
|
|
14280
|
+
fail(error.code, error.message, {
|
|
14281
|
+
details: error.details,
|
|
14282
|
+
hint: error.hint,
|
|
14283
|
+
suggestedFix: error.suggestedFix
|
|
14284
|
+
});
|
|
14285
|
+
}
|
|
14286
|
+
fail(
|
|
14287
|
+
ErrorCodes.INTERNAL_ERROR,
|
|
14288
|
+
error instanceof Error ? error.message : "Failed to stop skill"
|
|
14289
|
+
);
|
|
14290
|
+
}
|
|
14291
|
+
});
|
|
14292
|
+
|
|
13792
14293
|
// src/commands/skill/search.ts
|
|
13793
14294
|
init_cjs_shims();
|
|
13794
14295
|
var skillSearchCommand = new Command("search").description("Search public skill packages").argument("<query>", "Search query").option("--tags <tags>", "Filter by tags (comma-separated)").option("--page <number>", "Page number", "1").option("--page-size <number>", "Page size", "20").action(async (query, options) => {
|
|
@@ -13835,11 +14336,12 @@ var skillSearchCommand = new Command("search").description("Search public skill
|
|
|
13835
14336
|
init_cjs_shims();
|
|
13836
14337
|
init_symlink();
|
|
13837
14338
|
init_logger();
|
|
13838
|
-
var skillInstallCommand = new Command("install").description("Install a skill package").argument("<skillId>", "Skill package ID to install").option("--version <version>", "Specific version to install").option("--share-id <shareId>", "Share ID for private skills").option("--config <json>", "Installation config JSON").action(async (skillId, options) => {
|
|
14339
|
+
var skillInstallCommand = new Command("install").description("Install a skill package").argument("<skillId>", "Skill package ID to install").option("--version <version>", "Specific version to install").option("--share-id <shareId>", "Share ID for private skills").option("--config <json>", "Installation config JSON").option("--force", "Force reinstall if already installed").action(async (skillId, options) => {
|
|
13839
14340
|
try {
|
|
13840
14341
|
const body = { skillId };
|
|
13841
14342
|
if (options.version) body.version = options.version;
|
|
13842
14343
|
if (options.shareId) body.shareId = options.shareId;
|
|
14344
|
+
if (options.force) body.force = true;
|
|
13843
14345
|
if (options.config) {
|
|
13844
14346
|
try {
|
|
13845
14347
|
body.config = JSON.parse(options.config);
|
|
@@ -13881,7 +14383,9 @@ var skillInstallCommand = new Command("install").description("Install a skill pa
|
|
|
13881
14383
|
inputSchema: result.skillPackage?.inputSchema,
|
|
13882
14384
|
outputSchema: result.skillPackage?.outputSchema
|
|
13883
14385
|
});
|
|
13884
|
-
const symlinkResult = createReflySkillWithSymlink(skillName, skillMdContent
|
|
14386
|
+
const symlinkResult = createReflySkillWithSymlink(skillName, skillMdContent, {
|
|
14387
|
+
force: options.force
|
|
14388
|
+
});
|
|
13885
14389
|
if (symlinkResult.success) {
|
|
13886
14390
|
localPath = symlinkResult.reflyPath;
|
|
13887
14391
|
symlinkPath = symlinkResult.claudePath;
|
|
@@ -13923,7 +14427,7 @@ var skillInstallCommand = new Command("install").description("Install a skill pa
|
|
|
13923
14427
|
// src/commands/skill/uninstall.ts
|
|
13924
14428
|
init_cjs_shims();
|
|
13925
14429
|
var fs22 = __toESM(require("fs"));
|
|
13926
|
-
var
|
|
14430
|
+
var path18 = __toESM(require("path"));
|
|
13927
14431
|
init_symlink();
|
|
13928
14432
|
init_paths();
|
|
13929
14433
|
init_logger();
|
|
@@ -13948,7 +14452,7 @@ To find your skill name:
|
|
|
13948
14452
|
if (options.name) {
|
|
13949
14453
|
name = options.name;
|
|
13950
14454
|
const skillDir = getReflyDomainSkillDir(name);
|
|
13951
|
-
const skillMdPath =
|
|
14455
|
+
const skillMdPath = path18.join(skillDir, "SKILL.md");
|
|
13952
14456
|
if (!fs22.existsSync(skillMdPath)) {
|
|
13953
14457
|
fail(ErrorCodes.NOT_FOUND, `SKILL.md not found at ${skillMdPath}`, {
|
|
13954
14458
|
hint: `Make sure the skill '${name}' exists in ${skillsDir}/
|
|
@@ -14074,7 +14578,7 @@ init_cjs_shims();
|
|
|
14074
14578
|
// src/skill/loader.ts
|
|
14075
14579
|
init_cjs_shims();
|
|
14076
14580
|
var fs23 = __toESM(require("fs"));
|
|
14077
|
-
var
|
|
14581
|
+
var path19 = __toESM(require("path"));
|
|
14078
14582
|
var import_gray_matter = __toESM(require("gray-matter"));
|
|
14079
14583
|
init_logger();
|
|
14080
14584
|
|
|
@@ -14255,13 +14759,13 @@ function extractSkillMetadata(content) {
|
|
|
14255
14759
|
// src/commands/skill/validate.ts
|
|
14256
14760
|
init_paths();
|
|
14257
14761
|
var fs24 = __toESM(require("fs"));
|
|
14258
|
-
var
|
|
14762
|
+
var path20 = __toESM(require("path"));
|
|
14259
14763
|
var skillValidateCommand = new Command("validate").description("Validate local skill files").argument("[skillPath]", "Path to skill file or directory (defaults to ~/.refly/skills)").option("--fix", "Attempt to fix common issues").action(async (skillPath, _options) => {
|
|
14260
14764
|
try {
|
|
14261
14765
|
const results = [];
|
|
14262
14766
|
let targetPath;
|
|
14263
14767
|
if (skillPath) {
|
|
14264
|
-
targetPath =
|
|
14768
|
+
targetPath = path20.resolve(skillPath);
|
|
14265
14769
|
} else {
|
|
14266
14770
|
await ensureSkillsDir();
|
|
14267
14771
|
targetPath = getSkillsDir();
|
|
@@ -14331,7 +14835,7 @@ function validateSkillFile(filePath) {
|
|
|
14331
14835
|
function findSkillFiles(dir, files = []) {
|
|
14332
14836
|
const entries = fs24.readdirSync(dir, { withFileTypes: true });
|
|
14333
14837
|
for (const entry of entries) {
|
|
14334
|
-
const fullPath =
|
|
14838
|
+
const fullPath = path20.join(dir, entry.name);
|
|
14335
14839
|
if (entry.isDirectory()) {
|
|
14336
14840
|
if (!entry.name.startsWith(".")) {
|
|
14337
14841
|
findSkillFiles(fullPath, files);
|
|
@@ -14348,7 +14852,7 @@ init_cjs_shims();
|
|
|
14348
14852
|
init_symlink();
|
|
14349
14853
|
init_paths();
|
|
14350
14854
|
var fs25 = __toESM(require("fs"));
|
|
14351
|
-
var
|
|
14855
|
+
var path21 = __toESM(require("path"));
|
|
14352
14856
|
var skillSyncCommand = new Command("sync").description("Validate and repair skill symlinks").option("--dry-run", "Show issues without making changes").option("--fix", "Attempt to repair broken symlinks").option("--prune", "Remove orphan symlinks (symlinks without source directory)").action(async (options) => {
|
|
14353
14857
|
try {
|
|
14354
14858
|
const symlinks = listSkillSymlinks();
|
|
@@ -14382,7 +14886,7 @@ var skillSyncCommand = new Command("sync").description("Validate and repair skil
|
|
|
14382
14886
|
if (entry.isDirectory() && entry.name !== "base") {
|
|
14383
14887
|
if (!symlinkNames.has(entry.name)) {
|
|
14384
14888
|
orphans += 1;
|
|
14385
|
-
warnings.push(`Orphan directory (no symlink): ${
|
|
14889
|
+
warnings.push(`Orphan directory (no symlink): ${path21.join(skillsDir, entry.name)}`);
|
|
14386
14890
|
if (options.prune && !options.dryRun) {
|
|
14387
14891
|
const result = createSkillSymlink(entry.name);
|
|
14388
14892
|
if (result.success) {
|
|
@@ -14427,12 +14931,12 @@ var skillSyncCommand = new Command("sync").description("Validate and repair skil
|
|
|
14427
14931
|
});
|
|
14428
14932
|
|
|
14429
14933
|
// src/commands/skill/index.ts
|
|
14430
|
-
var skillCommand = new Command("skill").description("Manage skill packages and local skills").addCommand(skillListCommand).addCommand(skillGetCommand).addCommand(skillCreateCommand).addCommand(skillUpdateCommand).addCommand(skillPublishCommand).addCommand(skillUnpublishCommand).addCommand(skillSearchCommand).addCommand(skillInstallCommand).addCommand(skillUninstallCommand).addCommand(skillInstallationsCommand).addCommand(skillRunCommand).addCommand(skillValidateCommand).addCommand(skillSyncCommand);
|
|
14934
|
+
var skillCommand = new Command("skill").description("Manage skill packages and local skills").addCommand(skillListCommand).addCommand(skillGetCommand).addCommand(skillCreateCommand).addCommand(skillUpdateCommand).addCommand(skillPublishCommand).addCommand(skillUnpublishCommand).addCommand(skillSearchCommand).addCommand(skillInstallCommand).addCommand(skillUninstallCommand).addCommand(skillInstallationsCommand).addCommand(skillRunCommand).addCommand(skillStopCommand).addCommand(skillValidateCommand).addCommand(skillSyncCommand);
|
|
14431
14935
|
|
|
14432
14936
|
// src/bin/refly.ts
|
|
14433
14937
|
function getVersion() {
|
|
14434
14938
|
try {
|
|
14435
|
-
const pkgPath =
|
|
14939
|
+
const pkgPath = path22.join(__dirname, "..", "..", "package.json");
|
|
14436
14940
|
const pkg = JSON.parse(fs26.readFileSync(pkgPath, "utf-8"));
|
|
14437
14941
|
return pkg.version || "0.1.0";
|
|
14438
14942
|
} catch {
|