@fkqfkq123/opencode-autopilot 0.1.2 → 0.1.3
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/packages/runtime/src/plugin/workflow-plugin-entry.js +9 -8
- package/dist/packages/runtime/src/shared/json-file.js +7 -1
- package/dist/packages/runtime/src/state/file-system-human-action-store.js +3 -1
- package/dist/packages/runtime/src/state/file-system-workflow-state-store.js +3 -1
- package/dist/packages/runtime/src/workspace/workflow-workspace.d.ts +1 -0
- package/dist/packages/runtime/src/workspace/workflow-workspace.js +8 -1
- package/package.json +1 -1
|
@@ -9,6 +9,7 @@ import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
|
9
9
|
import { homedir } from "node:os";
|
|
10
10
|
import { join } from "node:path";
|
|
11
11
|
import { z } from "zod";
|
|
12
|
+
const workflowIdSchema = z.string().min(1).describe("Workflow identifier");
|
|
12
13
|
const WORKFLOW_PRIMARY_AGENT_PROMPT = `You are the workflow execution agent.
|
|
13
14
|
|
|
14
15
|
Responsibilities:
|
|
@@ -252,7 +253,7 @@ export async function workflowPlugin(input) {
|
|
|
252
253
|
args: {
|
|
253
254
|
command: z.enum(commandNames)
|
|
254
255
|
.describe("Workflow channel command to execute"),
|
|
255
|
-
workflowId:
|
|
256
|
+
workflowId: workflowIdSchema,
|
|
256
257
|
payload: z.string().optional().describe("Optional JSON/string payload for answer-like commands"),
|
|
257
258
|
},
|
|
258
259
|
execute: async (args, context) => {
|
|
@@ -262,7 +263,7 @@ export async function workflowPlugin(input) {
|
|
|
262
263
|
workflow_open: {
|
|
263
264
|
description: "Open or initialize a workflow channel and attach to it.",
|
|
264
265
|
args: {
|
|
265
|
-
workflowId:
|
|
266
|
+
workflowId: workflowIdSchema,
|
|
266
267
|
payload: z.string().optional().describe("Initial request. Supports plain text or JSON: { prompt, docPaths[], projectContext }"),
|
|
267
268
|
},
|
|
268
269
|
execute: async (args, context) => invokeCommand("workflow-open", args.workflowId, args.payload, context?.sessionID),
|
|
@@ -270,21 +271,21 @@ export async function workflowPlugin(input) {
|
|
|
270
271
|
workflow_attach: {
|
|
271
272
|
description: "Attach to an existing workflow channel.",
|
|
272
273
|
args: {
|
|
273
|
-
workflowId:
|
|
274
|
+
workflowId: workflowIdSchema,
|
|
274
275
|
},
|
|
275
276
|
execute: async (args, context) => invokeCommand("workflow-attach", args.workflowId, undefined, context?.sessionID),
|
|
276
277
|
},
|
|
277
278
|
workflow_status: {
|
|
278
279
|
description: "Render the current workflow status block.",
|
|
279
280
|
args: {
|
|
280
|
-
workflowId:
|
|
281
|
+
workflowId: workflowIdSchema,
|
|
281
282
|
},
|
|
282
283
|
execute: async (args, context) => invokeCommand("workflow-status", args.workflowId, undefined, context?.sessionID),
|
|
283
284
|
},
|
|
284
285
|
workflow_answer: {
|
|
285
286
|
description: "Answer workflow clarification questions.",
|
|
286
287
|
args: {
|
|
287
|
-
workflowId:
|
|
288
|
+
workflowId: workflowIdSchema,
|
|
288
289
|
payload: z.string().describe("JSON string payload for question answers"),
|
|
289
290
|
},
|
|
290
291
|
execute: async (args, context) => invokeCommand("workflow-answer", args.workflowId, args.payload, context?.sessionID),
|
|
@@ -292,21 +293,21 @@ export async function workflowPlugin(input) {
|
|
|
292
293
|
workflow_approve: {
|
|
293
294
|
description: "Approve the current workflow plan or decision.",
|
|
294
295
|
args: {
|
|
295
|
-
workflowId:
|
|
296
|
+
workflowId: workflowIdSchema,
|
|
296
297
|
},
|
|
297
298
|
execute: async (args, context) => invokeCommand("workflow-approve", args.workflowId, undefined, context?.sessionID),
|
|
298
299
|
},
|
|
299
300
|
workflow_resume: {
|
|
300
301
|
description: "Resume a blocked workflow.",
|
|
301
302
|
args: {
|
|
302
|
-
workflowId:
|
|
303
|
+
workflowId: workflowIdSchema,
|
|
303
304
|
},
|
|
304
305
|
execute: async (args, context) => invokeCommand("workflow-resume", args.workflowId, undefined, context?.sessionID),
|
|
305
306
|
},
|
|
306
307
|
workflow_back: {
|
|
307
308
|
description: "Leave the workflow channel without stopping the workflow.",
|
|
308
309
|
args: {
|
|
309
|
-
workflowId:
|
|
310
|
+
workflowId: workflowIdSchema,
|
|
310
311
|
},
|
|
311
312
|
execute: async (args, context) => invokeCommand("workflow-back", args.workflowId, undefined, context?.sessionID),
|
|
312
313
|
},
|
|
@@ -3,11 +3,17 @@ import { dirname } from "node:path";
|
|
|
3
3
|
export async function readJsonFile(filePath) {
|
|
4
4
|
try {
|
|
5
5
|
const raw = await readFile(filePath, "utf8");
|
|
6
|
+
if (!raw.trim()) {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
6
9
|
return JSON.parse(raw);
|
|
7
10
|
}
|
|
8
11
|
catch (error) {
|
|
9
12
|
const message = error instanceof Error ? error.message : String(error);
|
|
10
|
-
if (message.includes("ENOENT")) {
|
|
13
|
+
if (message.includes("ENOENT") || message.includes("ENOTDIR") || message.includes("EINVAL")) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
if (error instanceof SyntaxError) {
|
|
11
17
|
return null;
|
|
12
18
|
}
|
|
13
19
|
throw error;
|
|
@@ -50,7 +50,9 @@ export class FileSystemHumanActionStore {
|
|
|
50
50
|
const workflowsDir = this.workspace.workflowsRoot();
|
|
51
51
|
let workflowIds = [];
|
|
52
52
|
try {
|
|
53
|
-
workflowIds = await readdir(workflowsDir)
|
|
53
|
+
workflowIds = (await readdir(workflowsDir, { withFileTypes: true }))
|
|
54
|
+
.filter((entry) => entry.isDirectory())
|
|
55
|
+
.map((entry) => entry.name);
|
|
54
56
|
}
|
|
55
57
|
catch (error) {
|
|
56
58
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -7,7 +7,9 @@ export class FileSystemWorkflowStateStore {
|
|
|
7
7
|
}
|
|
8
8
|
async listWorkflows() {
|
|
9
9
|
try {
|
|
10
|
-
const workflowIds = await readdir(this.workspace.workflowsRoot())
|
|
10
|
+
const workflowIds = (await readdir(this.workspace.workflowsRoot(), { withFileTypes: true }))
|
|
11
|
+
.filter((entry) => entry.isDirectory())
|
|
12
|
+
.map((entry) => entry.name);
|
|
11
13
|
const items = await Promise.all(workflowIds.map((workflowId) => this.getWorkflow(workflowId)));
|
|
12
14
|
return items.filter((item) => item !== null);
|
|
13
15
|
}
|
|
@@ -16,6 +16,7 @@ export interface WorkflowWorkspace {
|
|
|
16
16
|
export declare class DefaultWorkflowWorkspace implements WorkflowWorkspace {
|
|
17
17
|
private readonly root;
|
|
18
18
|
constructor(root: string);
|
|
19
|
+
private normalizeWorkflowId;
|
|
19
20
|
baseDir(): string;
|
|
20
21
|
workflowsRoot(): string;
|
|
21
22
|
workflowConfigFile(): string;
|
|
@@ -4,6 +4,13 @@ export class DefaultWorkflowWorkspace {
|
|
|
4
4
|
constructor(root) {
|
|
5
5
|
this.root = root;
|
|
6
6
|
}
|
|
7
|
+
normalizeWorkflowId(workflowId) {
|
|
8
|
+
const normalized = workflowId.trim();
|
|
9
|
+
if (!normalized) {
|
|
10
|
+
throw new Error("workflowId must be a non-empty string");
|
|
11
|
+
}
|
|
12
|
+
return normalized;
|
|
13
|
+
}
|
|
7
14
|
baseDir() {
|
|
8
15
|
return this.root;
|
|
9
16
|
}
|
|
@@ -14,7 +21,7 @@ export class DefaultWorkflowWorkspace {
|
|
|
14
21
|
return join(this.root, "workflow.json");
|
|
15
22
|
}
|
|
16
23
|
workflowDir(workflowId) {
|
|
17
|
-
return join(this.workflowsRoot(), workflowId);
|
|
24
|
+
return join(this.workflowsRoot(), this.normalizeWorkflowId(workflowId));
|
|
18
25
|
}
|
|
19
26
|
artifactStateFile(workflowId) {
|
|
20
27
|
return join(this.workflowDir(workflowId), "artifact-state.json");
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fkqfkq123/opencode-autopilot",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.3",
|
|
5
5
|
"description": "An OpenCode plugin for attached-session workflow execution with refinement, planning, development, review, and test phases.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"packageManager": "bun@1.3.5",
|