@piewf/cli 5.9.0 → 5.10.0
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/src/cli.d.ts +10 -0
- package/dist/src/cli.js +74 -9
- package/package.json +2 -2
package/dist/src/cli.d.ts
CHANGED
|
@@ -15,6 +15,15 @@ export interface CliOptions extends DoctorOptions {
|
|
|
15
15
|
}
|
|
16
16
|
export declare function formatWorkflowCliHelp(fn: WorkflowCatalogFunction, command?: string): string;
|
|
17
17
|
export declare function parseWorkflowCliArgs(schema: JsonSchema, rawArgs: readonly string[]): Record<string, JsonValue>;
|
|
18
|
+
type ScriptWorkflowCliArgs = {
|
|
19
|
+
help: true;
|
|
20
|
+
} | {
|
|
21
|
+
help: false;
|
|
22
|
+
scriptPath: string;
|
|
23
|
+
name: string;
|
|
24
|
+
args: JsonValue;
|
|
25
|
+
};
|
|
26
|
+
export declare function parseScriptWorkflowCliArgs(rawArgs: readonly string[]): ScriptWorkflowCliArgs;
|
|
18
27
|
export declare function parseDoctorArgs(rawArgs: readonly string[]): {
|
|
19
28
|
role?: string;
|
|
20
29
|
prompt?: string;
|
|
@@ -22,3 +31,4 @@ export declare function parseDoctorArgs(rawArgs: readonly string[]): {
|
|
|
22
31
|
};
|
|
23
32
|
export declare function parseDoctorCleanupArgs(rawArgs: readonly string[]): Required<Pick<DoctorCleanupOptions, "olderThanDays" | "yes">>;
|
|
24
33
|
export declare function runCli(args: readonly string[], options?: CliOptions, write?: (text: string) => void): Promise<number>;
|
|
34
|
+
export {};
|
package/dist/src/cli.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { chmodSync, linkSync, mkdirSync, mkdtempSync, realpathSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
|
-
import { dirname, join } from "node:path";
|
|
5
|
+
import { basename, dirname, extname, join } from "node:path";
|
|
6
6
|
import { pathToFileURL } from "node:url";
|
|
7
7
|
import { ProjectTrustStore, SessionManager, SettingsManager, createAgentSessionFromServices, createAgentSessionServices, getAgentDir, hasTrustRequiringProjectResources } from "@earendil-works/pi-coding-agent";
|
|
8
8
|
import { Value } from "typebox/value";
|
|
@@ -214,7 +214,53 @@ function launcherHelpLines() {
|
|
|
214
214
|
" --".padEnd(28) + "End launcher option parsing; pass later tokens to workflow input",
|
|
215
215
|
];
|
|
216
216
|
}
|
|
217
|
-
function workflowUsage() { return [`Usage: piewf run <workflow-name> [workflow arguments] | export <workflow-name> [--name <command>] [--output <path>] [--force]`, "", "Launcher options:", ...launcherHelpLines()].join("\n") + "\n"; }
|
|
217
|
+
function workflowUsage() { return [`Usage: piewf run <workflow-name> [workflow arguments] | run --script <path> [--name <workflow-name>] [--input <json>] | export <workflow-name> [--name <command>] [--output <path>] [--force]`, "", "Launcher options:", ...launcherHelpLines()].join("\n") + "\n"; }
|
|
218
|
+
function scriptWorkflowUsage() { return [`Usage: piewf run --script <path> [--name <workflow-name>] [--input <json>]`, "", "Options:", ...launcherHelpLines().slice(0, 2), " -h, --help".padEnd(28) + "Show this help"].join("\n") + "\n"; }
|
|
219
|
+
function scriptWorkflowName(scriptPath) {
|
|
220
|
+
const filename = basename(scriptPath);
|
|
221
|
+
const extension = extname(filename);
|
|
222
|
+
return extension ? filename.slice(0, -extension.length) : filename;
|
|
223
|
+
}
|
|
224
|
+
export function parseScriptWorkflowCliArgs(rawArgs) {
|
|
225
|
+
let scriptPath;
|
|
226
|
+
let name;
|
|
227
|
+
let input;
|
|
228
|
+
for (let index = 0; index < rawArgs.length; index += 1) {
|
|
229
|
+
const token = requiredArg(rawArgs, index);
|
|
230
|
+
if (token === "--help" || token === "-h")
|
|
231
|
+
return { help: true };
|
|
232
|
+
const equals = token.indexOf("=");
|
|
233
|
+
const option = equals >= 0 ? token.slice(0, equals) : token;
|
|
234
|
+
if (option === "--script" || option === "--name" || option === "--input") {
|
|
235
|
+
const value = equals >= 0 ? token.slice(equals + 1) : rawArgs[++index];
|
|
236
|
+
if (!value?.trim())
|
|
237
|
+
throw new Error(`Missing value for ${option}`);
|
|
238
|
+
if (option === "--script") {
|
|
239
|
+
if (scriptPath !== undefined)
|
|
240
|
+
throw new Error("--script may only be provided once");
|
|
241
|
+
scriptPath = value;
|
|
242
|
+
}
|
|
243
|
+
else if (option === "--name") {
|
|
244
|
+
if (name !== undefined)
|
|
245
|
+
throw new Error("--name may only be provided once");
|
|
246
|
+
name = value;
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
if (input !== undefined)
|
|
250
|
+
throw new Error("--input may only be provided once");
|
|
251
|
+
input = parseJsonInput(value);
|
|
252
|
+
}
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
throw new Error(`Unknown option: ${token}`);
|
|
256
|
+
}
|
|
257
|
+
if (scriptPath === undefined)
|
|
258
|
+
throw new Error("Missing required option: --script");
|
|
259
|
+
const workflowName = name === undefined ? scriptWorkflowName(scriptPath) : name.trim();
|
|
260
|
+
if (!workflowName)
|
|
261
|
+
throw new Error("Workflow name must be non-empty");
|
|
262
|
+
return { help: false, scriptPath, name: workflowName, args: input ?? null };
|
|
263
|
+
}
|
|
218
264
|
function exportUsage() { return [`Usage: piewf export <workflow-name> [--name <command>] [--output <path>] [--force] [--bundle]`, "", "Launcher options:", ...launcherHelpLines()].join("\n") + "\n"; }
|
|
219
265
|
function bundleUsage() { return [`Usage: piewf bundle <workflow-name> [--name <command>] [--output <directory>] [--force]`, "", "The bundle contains a launcher, manifest, workflow payload, and external-runtime setup instructions.", "Repeat --role, --alias, --tool, --command, or --environment to declare recipient requirements.", "Use --extension, --skill, --resource, and --dependency to copy selected payload resources."].join("\n") + "\n"; }
|
|
220
266
|
function parseInspectArgs(rawArgs) {
|
|
@@ -524,15 +570,20 @@ class CliProgress {
|
|
|
524
570
|
this.#run = undefined;
|
|
525
571
|
}
|
|
526
572
|
}
|
|
527
|
-
async function invokeWorkflow(
|
|
528
|
-
if (!Value.Check(fn.input, args))
|
|
529
|
-
throw new Error(`Invalid input for ${fn.name}`);
|
|
573
|
+
async function invokeWorkflow(launch, runtime, options, context) {
|
|
574
|
+
if (launch.fn && (!object(launch.args) || !Value.Check(launch.fn.input, launch.args)))
|
|
575
|
+
throw new Error(`Invalid input for ${launch.fn.name}`);
|
|
576
|
+
if (!launch.fn && launch.scriptPath === undefined)
|
|
577
|
+
throw new Error("Workflow launch has no source");
|
|
530
578
|
let announcedRunId;
|
|
531
579
|
const announceRunId = (runId) => { if (announcedRunId === runId)
|
|
532
580
|
return; announcedRunId = runId; options.stderr(`Run ID: ${runId}\n`); };
|
|
533
581
|
const progress = new CliProgress(options.stderr, options.isTTY ?? process.stderr.isTTY, announceRunId);
|
|
534
582
|
try {
|
|
535
|
-
const
|
|
583
|
+
const params = launch.scriptPath === undefined
|
|
584
|
+
? { name: launch.name, script: `return await ${launch.fn?.name ?? launch.name}(args);`, args: launch.args, foreground: true }
|
|
585
|
+
: { name: launch.name, scriptPath: launch.scriptPath, args: launch.args, foreground: true };
|
|
586
|
+
const result = await runtime.workflowTool.execute(randomUUID(), params, options.signal, (update) => { if (object(update) && object(update.details) && isPersistedRun(update.details.run))
|
|
536
587
|
progress.update(update.details.run); }, context);
|
|
537
588
|
if (!isHeadlessWorkflowResult(result))
|
|
538
589
|
throw new Error("Workflow returned an invalid result");
|
|
@@ -589,8 +640,22 @@ async function runWorkflowCli(rawArgs, options) {
|
|
|
589
640
|
options.write(workflowUsage());
|
|
590
641
|
return args.length ? 0 : 1;
|
|
591
642
|
}
|
|
643
|
+
const runtimeOptions = { ...options, ...(parsed.trustOverride !== undefined ? { trustOverride: parsed.trustOverride } : {}) };
|
|
644
|
+
const scriptMode = args[0] === "--script" || args[0]?.startsWith("--script=") || args[0]?.startsWith("--") && args.some((arg) => arg === "--script" || arg.startsWith("--script="));
|
|
645
|
+
if (scriptMode) {
|
|
646
|
+
const script = parseScriptWorkflowCliArgs(args);
|
|
647
|
+
if (script.help) {
|
|
648
|
+
options.write(scriptWorkflowUsage());
|
|
649
|
+
return 0;
|
|
650
|
+
}
|
|
651
|
+
return withWorkflowRuntime(runtimeOptions, async (runtime, context) => {
|
|
652
|
+
const result = await invokeWorkflow({ name: script.name, scriptPath: script.scriptPath, args: script.args }, runtime, options, context);
|
|
653
|
+
options.write(`${JSON.stringify(result.value)}\n`);
|
|
654
|
+
return 0;
|
|
655
|
+
});
|
|
656
|
+
}
|
|
592
657
|
const name = requiredArg(args, 0);
|
|
593
|
-
return withWorkflowRuntime(
|
|
658
|
+
return withWorkflowRuntime(runtimeOptions, async (runtime, context) => {
|
|
594
659
|
const help = args.slice(1).some((arg) => arg === "--help" || arg === "-h");
|
|
595
660
|
const fn = runtime.catalog.functions.find((candidate) => candidate.name === name);
|
|
596
661
|
if (!fn)
|
|
@@ -600,7 +665,7 @@ async function runWorkflowCli(rawArgs, options) {
|
|
|
600
665
|
return 0;
|
|
601
666
|
}
|
|
602
667
|
const input = parseWorkflowCliArgs(fn.input, args.slice(1));
|
|
603
|
-
const result = await invokeWorkflow(fn, input, runtime, options, context);
|
|
668
|
+
const result = await invokeWorkflow({ name: fn.name, fn, args: input }, runtime, options, context);
|
|
604
669
|
options.write(`${JSON.stringify(result.value)}\n`);
|
|
605
670
|
return 0;
|
|
606
671
|
});
|
|
@@ -842,7 +907,7 @@ export async function runCli(args, options = {}, write = (text) => { process.std
|
|
|
842
907
|
return 1;
|
|
843
908
|
}
|
|
844
909
|
}
|
|
845
|
-
write("Usage: piewf doctor [role] [--role <role>] [--prompt <text>] [--json] | inspect [session-id] [--json|--summary] [--failed] | transcript <session-file> | share <run-id> | bundle <workflow-name> [--name <command>] [--output <path>] [--force] | run <workflow-name> [workflow arguments] | export <workflow-name> [--name <command>] [--output <path>] [--force] [--bundle]\n");
|
|
910
|
+
write("Usage: piewf doctor [role] [--role <role>] [--prompt <text>] [--json] | inspect [session-id] [--json|--summary] [--failed] | transcript <session-file> | share <run-id> | bundle <workflow-name> [--name <command>] [--output <path>] [--force] | run <workflow-name> [workflow arguments] | run --script <path> [--name <workflow-name>] [--input <json>] | export <workflow-name> [--name <command>] [--output <path>] [--force] [--bundle]\n");
|
|
846
911
|
return 1;
|
|
847
912
|
}
|
|
848
913
|
if (process.argv[1] && import.meta.url === pathToFileURL(realpathSync(process.argv[1])).href) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@piewf/cli",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.10.0",
|
|
4
4
|
"description": "CLI for pi-extensible-workflows",
|
|
5
5
|
"homepage": "https://vekexasia.github.io/pi-extensible-workflows/",
|
|
6
6
|
"repository": {
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
},
|
|
47
47
|
"license": "MIT",
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"pi-extensible-workflows": "5.
|
|
49
|
+
"pi-extensible-workflows": "5.10.0"
|
|
50
50
|
},
|
|
51
51
|
"publishConfig": {
|
|
52
52
|
"access": "public"
|