Files
stanp-opencode/tests/fixtures/native-host-plugin.ts
T
StanPonomarev f527778b29
CI / verify (pull_request) Failing after 8s
feat: split plugins and cleanup
2026-10-04 12:49:41 +02:00

94 lines
4.0 KiB
TypeScript

import { Plugin, Agent } from "@opencode/plugin/effect";
import { Rpc } from "@opencode/plugin/rpc";
import { Session } from "@opencode/schema/session";
import { SessionMessage } from "@opencode/schema/session-message";
import { Tool } from "@opencode/schema/tool";
import { Cause, Effect } from "effect";
import { z } from "zod";
import { appendFile } from "node:fs/promises";
import multiWork from "../../src/multi-work.js";
const probe = Rpc.define({
id: "multi-work-test",
events: {},
methods: {
delegate: {
input: z.object({
parent: z.string(),
child: z.string().optional(),
background: z.boolean(),
}),
output: z.string(),
},
},
});
export default Plugin.define({
id: multiWork.id,
effect: (context) =>
Effect.gen(function* () {
yield* multiWork.effect(context);
let delegate: Tool.Info | undefined;
yield* context.tool.transform((editor) => {
delegate = editor.get("subagent");
});
yield* context.session.hook("prompt", (event) =>
Effect.gen(function* () {
const child = yield* context.session.get({ sessionID: event.sessionID });
yield* Effect.promise(() =>
appendFile(
process.env.FIXTURE_TRACE!,
JSON.stringify({
id: child.id,
parent: child.parentID,
agent: child.agent,
directory: child.location.directory,
}) + "\n",
),
);
}).pipe(Effect.orDie),
);
yield* context.rpc
.register(probe, {
delegate: (input) =>
Effect.gen(function* () {
if (!delegate) throw new Error("Native subagent missing");
const result = yield* delegate.execute(
{
agent: "coordinate",
description: "native host proof",
prompt: "Reply with FIXTURE_COMPLETE",
background: input.background,
...(input.child
? { sessionID: input.child }
: {
worktree: {
base: "main",
branch: "fix/native-host",
label: "Fix native host",
},
}),
},
{
sessionID: Session.ID.make(input.parent),
agent: Agent.ID.make("multi-work"),
messageID: SessionMessage.ID.create(),
id: Tool.CallID.make(`call_${crypto.randomUUID()}`),
progress: () => Effect.void,
},
);
return JSON.stringify(result);
}).pipe(
Effect.catchCause((cause) =>
Cause.hasInterrupts(cause)
? Effect.interrupt
: Effect.succeed(
JSON.stringify({ failure: Cause.pretty(cause) }),
),
),
),
})
.pipe(Effect.orDie);
}),
});