pi-extensible-workflows 1.0.1 → 3.0.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/README.md +9 -2
- package/dist/src/agent-execution.d.ts +13 -14
- package/dist/src/agent-execution.js +110 -197
- package/dist/src/budget.d.ts +38 -0
- package/dist/src/budget.js +160 -0
- package/dist/src/cli.d.ts +9 -0
- package/dist/src/cli.js +536 -6
- package/dist/src/doctor.d.ts +4 -4
- package/dist/src/doctor.js +9 -29
- package/dist/src/execution.d.ts +17 -0
- package/dist/src/execution.js +630 -0
- package/dist/src/herdr.d.ts +12 -0
- package/dist/src/herdr.js +74 -0
- package/dist/src/host.d.ts +62 -0
- package/dist/src/host.js +2696 -0
- package/dist/src/index.d.ts +11 -557
- package/dist/src/index.js +8 -3974
- package/dist/src/persistence.d.ts +32 -19
- package/dist/src/persistence.js +310 -70
- package/dist/src/registry.d.ts +31 -0
- package/dist/src/registry.js +169 -0
- package/dist/src/session-inspector.d.ts +1 -0
- package/dist/src/session-inspector.js +4 -1
- package/dist/src/types.d.ts +565 -0
- package/dist/src/types.js +27 -0
- package/dist/src/utils.d.ts +26 -0
- package/dist/src/utils.js +128 -0
- package/dist/src/validation.d.ts +24 -0
- package/dist/src/validation.js +740 -0
- package/dist/src/workflow-evals.js +2 -1
- package/package.json +4 -3
- package/skills/pi-extensible-workflows/SKILL.md +52 -67
- package/src/agent-execution.ts +84 -147
- package/src/budget.ts +75 -0
- package/src/cli.ts +427 -6
- package/src/doctor.ts +13 -32
- package/src/execution.ts +540 -0
- package/src/herdr.ts +73 -0
- package/src/host.ts +2265 -0
- package/src/index.ts +11 -3453
- package/src/persistence.ts +255 -47
- package/src/registry.ts +157 -0
- package/src/session-inspector.ts +5 -1
- package/src/types.ts +113 -0
- package/src/utils.ts +108 -0
- package/src/validation.ts +616 -0
- package/src/workflow-evals.ts +2 -1
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type HerdrPaneAction = "inspect" | "transcript" | "fork";
|
|
2
|
+
export interface HerdrPaneRequest {
|
|
3
|
+
action: HerdrPaneAction;
|
|
4
|
+
cwd: string;
|
|
5
|
+
sessionId?: string;
|
|
6
|
+
original?: string;
|
|
7
|
+
readOnly?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export type HerdrCommandRunner = (args: readonly string[]) => Promise<string>;
|
|
10
|
+
export declare function herdrPaneId(env?: NodeJS.ProcessEnv): string | undefined;
|
|
11
|
+
export declare function herdrPaneCommand(request: HerdrPaneRequest): string;
|
|
12
|
+
export declare function openHerdrPane(request: HerdrPaneRequest, runner?: HerdrCommandRunner): Promise<string>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
const runHerdr = (args) => new Promise((resolve, reject) => {
|
|
4
|
+
execFile("herdr", [...args], { encoding: "utf8", maxBuffer: 1024 * 1024 }, (error, stdout) => {
|
|
5
|
+
if (error) {
|
|
6
|
+
reject(new Error(error.message));
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
resolve(stdout);
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
export function herdrPaneId(env = process.env) {
|
|
13
|
+
if (env.HERDR_ENV !== "1")
|
|
14
|
+
return undefined;
|
|
15
|
+
const paneId = env.HERDR_PANE_ID?.trim();
|
|
16
|
+
return paneId || undefined;
|
|
17
|
+
}
|
|
18
|
+
function shellQuote(value) { return `'${value.replace(/'/g, `'\\''`)}'`; }
|
|
19
|
+
function json(value) { return JSON.parse(value); }
|
|
20
|
+
function record(value) { return typeof value === "object" && value !== null && !Array.isArray(value) ? value : undefined; }
|
|
21
|
+
function paneLayout(value, targetPane) {
|
|
22
|
+
const root = record(value);
|
|
23
|
+
const result = record(root?.result);
|
|
24
|
+
const layout = record(result?.layout);
|
|
25
|
+
const rawPanes = layout?.panes;
|
|
26
|
+
if (!Array.isArray(rawPanes))
|
|
27
|
+
throw new Error("Herdr returned an invalid pane layout.");
|
|
28
|
+
const panes = rawPanes;
|
|
29
|
+
const pane = panes.find((candidate) => record(candidate)?.pane_id === targetPane);
|
|
30
|
+
const rect = record(record(pane)?.rect);
|
|
31
|
+
const width = rect?.width;
|
|
32
|
+
const height = rect?.height;
|
|
33
|
+
if (width === undefined || height === undefined || typeof width !== "number" || typeof height !== "number")
|
|
34
|
+
throw new Error("Herdr returned an invalid target pane geometry.");
|
|
35
|
+
return { width, height };
|
|
36
|
+
}
|
|
37
|
+
function splitPaneId(value) {
|
|
38
|
+
const pane = record(record(record(value)?.result)?.pane);
|
|
39
|
+
const paneId = pane?.pane_id;
|
|
40
|
+
if (typeof paneId !== "string" || !paneId)
|
|
41
|
+
throw new Error("Herdr returned an invalid created pane ID.");
|
|
42
|
+
return paneId;
|
|
43
|
+
}
|
|
44
|
+
function commandFor(request) {
|
|
45
|
+
const cliPath = fileURLToPath(new URL("./cli.js", import.meta.resolve("pi-extensible-workflows")));
|
|
46
|
+
const environment = ["PI_CODING_AGENT_DIR", "PI_CODING_AGENT_SESSION_DIR"].flatMap((name) => process.env[name] === undefined ? [] : [`${name}=${shellQuote(process.env[name] ?? "")}`]);
|
|
47
|
+
const command = request.action === "inspect"
|
|
48
|
+
? [shellQuote(process.execPath), shellQuote(cliPath), "inspect", shellQuote(request.sessionId ?? "")]
|
|
49
|
+
: request.action === "transcript"
|
|
50
|
+
? [shellQuote(process.execPath), shellQuote(cliPath), "transcript", shellQuote(request.original ?? "")]
|
|
51
|
+
: ["pi", "--fork", shellQuote(request.original ?? ""), ...(request.readOnly ? ["--tools", shellQuote("read,grep,find,ls")] : [])];
|
|
52
|
+
return `cd ${shellQuote(request.cwd)} && ${environment.length ? `${environment.join(" ")} ` : ""}${command.join(" ")}`;
|
|
53
|
+
}
|
|
54
|
+
export function herdrPaneCommand(request) { return commandFor(request); }
|
|
55
|
+
export async function openHerdrPane(request, runner = runHerdr) {
|
|
56
|
+
const targetPane = herdrPaneId();
|
|
57
|
+
if (!targetPane)
|
|
58
|
+
throw new Error("Pane actions require a Herdr-managed session with HERDR_PANE_ID.");
|
|
59
|
+
if (!request.cwd)
|
|
60
|
+
throw new Error("Pane actions require a working directory.");
|
|
61
|
+
if ((request.action === "inspect" && !request.sessionId) || (request.action !== "inspect" && !request.original))
|
|
62
|
+
throw new Error("Pane action is missing its session source.");
|
|
63
|
+
const layout = paneLayout(json(await runner(["pane", "layout", "--pane", targetPane])), targetPane);
|
|
64
|
+
const direction = layout.width > layout.height ? "right" : "down";
|
|
65
|
+
const paneId = splitPaneId(json(await runner(["pane", "split", targetPane, "--direction", direction, "--no-focus"])));
|
|
66
|
+
try {
|
|
67
|
+
await runner(["pane", "run", paneId, commandFor(request)]);
|
|
68
|
+
return paneId;
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
await runner(["pane", "close", paneId]).catch(() => undefined);
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Type } from "@earendil-works/pi-ai";
|
|
2
|
+
import { copyToClipboard, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
3
|
+
import { type SessionFactory } from "./agent-execution.js";
|
|
4
|
+
import type { AwaitingCheckpoint, PersistedRun, WorktreeReference } from "./persistence.js";
|
|
5
|
+
import { type LaunchSnapshot, type RunState, type WorkflowFailureDiagnostics } from "./types.js";
|
|
6
|
+
export interface WorkflowProgressStyles {
|
|
7
|
+
accent(text: string): string;
|
|
8
|
+
success(text: string): string;
|
|
9
|
+
error(text: string): string;
|
|
10
|
+
warning(text: string): string;
|
|
11
|
+
muted(text: string): string;
|
|
12
|
+
dim(text: string): string;
|
|
13
|
+
bold(text: string): string;
|
|
14
|
+
}
|
|
15
|
+
export declare function formatWorkflowFailure(error: unknown): string;
|
|
16
|
+
export declare class RunLifecycle {
|
|
17
|
+
#private;
|
|
18
|
+
private readonly changed?;
|
|
19
|
+
constructor(state?: RunState, changed?: ((state: RunState, previousState: RunState, reason?: string) => void | Promise<void>) | undefined);
|
|
20
|
+
get state(): RunState;
|
|
21
|
+
enter(): Promise<void>;
|
|
22
|
+
leave(): Promise<void>;
|
|
23
|
+
enterAwaitingInput(): Promise<void>;
|
|
24
|
+
resolveAwaitingInput(): Promise<void>;
|
|
25
|
+
pause(): Promise<void>;
|
|
26
|
+
resume(): Promise<void>;
|
|
27
|
+
providerPause(): Promise<void>;
|
|
28
|
+
terminal(state: "completed" | "failed" | "stopped" | "interrupted" | "budget_exhausted", reason?: string): Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
export declare function formatWorkflowPreview(args: {
|
|
31
|
+
script?: unknown;
|
|
32
|
+
workflow?: unknown;
|
|
33
|
+
name?: unknown;
|
|
34
|
+
description?: unknown;
|
|
35
|
+
}): string;
|
|
36
|
+
export declare const WORKFLOW_TOOL_LABEL = "Workflow";
|
|
37
|
+
export declare const WORKFLOW_TOOL_DESCRIPTION = "Run a deterministic JavaScript workflow";
|
|
38
|
+
export declare const WORKFLOW_TOOL_PROMPT_SNIPPET = "Run a deterministic, resumable JavaScript workflow that orchestrates subagents. Inline launches require an explicit non-empty name; registered function launches reject name and use workflow as the run name. Runs in the background by default; completion arrives as a follow-up message. Foreground results include the completed run ID. Use workflow_retry with an explicit failed run ID to replay completed structural operations; parentRunId only reuses named worktrees.";
|
|
39
|
+
export declare const WORKFLOW_TOOL_PARAMETERS: Type.TObject<{
|
|
40
|
+
name: Type.TOptional<Type.TString>;
|
|
41
|
+
description: Type.TOptional<Type.TString>;
|
|
42
|
+
script: Type.TOptional<Type.TString>;
|
|
43
|
+
workflow: Type.TOptional<Type.TString>;
|
|
44
|
+
args: Type.TOptional<Type.TUnknown>;
|
|
45
|
+
foreground: Type.TOptional<Type.TBoolean>;
|
|
46
|
+
concurrency: Type.TOptional<Type.TInteger>;
|
|
47
|
+
budget: Type.TOptional<Type.TUnknown>;
|
|
48
|
+
parentRunId: Type.TOptional<Type.TString>;
|
|
49
|
+
}>;
|
|
50
|
+
export declare const WORKFLOW_RETRY_PARAMETERS: Type.TObject<{
|
|
51
|
+
runId: Type.TString;
|
|
52
|
+
}>;
|
|
53
|
+
export declare function formatWorkflowProgress(run: PersistedRun, spinner?: string, styles?: WorkflowProgressStyles): string;
|
|
54
|
+
export declare function truncateWorkflowProgress(text: string, width: number): string[];
|
|
55
|
+
export declare function formatBudgetStatus(run: Pick<PersistedRun, "budget" | "budgetVersion" | "usage" | "budgetEvents">): string[];
|
|
56
|
+
export declare function formatNavigatorDashboard(run: PersistedRun, checkpoints: readonly AwaitingCheckpoint[], worktrees: readonly WorktreeReference[]): string;
|
|
57
|
+
export declare function formatNavigatorRun(loaded: {
|
|
58
|
+
run: PersistedRun;
|
|
59
|
+
snapshot: Readonly<LaunchSnapshot>;
|
|
60
|
+
}, checkpoints: readonly AwaitingCheckpoint[], _worktrees: readonly WorktreeReference[]): string;
|
|
61
|
+
export declare function formatWorkflowFailureDiagnostics(diagnostic: WorkflowFailureDiagnostics): string;
|
|
62
|
+
export default function workflowExtension(pi: ExtensionAPI, home?: string, clipboard?: typeof copyToClipboard, createSession?: SessionFactory, agentDir?: string): void;
|