| import { spawn } from "node:child_process"; |
| import { existsSync } from "node:fs"; |
| import { mkdir, writeFile } from "node:fs/promises"; |
| import { homedir, platform } from "node:os"; |
| import path from "node:path"; |
| import { tool } from "@opencode-ai/plugin"; |
|
|
| const TASK_KINDS = ["auto", "website", "business_document", "business_suite", "app", "code_project", "repo_patch", "coding"]; |
| const defaultRuntimeScript = () => |
| path.join(homedir(), ".config", "opencode", "kaiju-coder-7-runtime", "scripts", "run_kaiju_router.py"); |
|
|
| const resolveSafeFile = (directory, filePath) => { |
| const base = path.resolve(directory || process.cwd()); |
| const resolved = path.resolve(base, filePath); |
| if (resolved !== base && !resolved.startsWith(`${base}${path.sep}`)) { |
| throw new Error(`Refusing to write outside the OpenCode directory: ${filePath}`); |
| } |
| return resolved; |
| }; |
|
|
| const runProcess = (command, args, options = {}) => |
| new Promise((resolve, reject) => { |
| const child = spawn(command, args, { |
| ...options, |
| env: { |
| ...process.env, |
| ...(options.env || {}), |
| }, |
| }); |
| let stdout = ""; |
| let stderr = ""; |
| child.stdout?.on("data", (chunk) => { |
| stdout += chunk.toString(); |
| }); |
| child.stderr?.on("data", (chunk) => { |
| stderr += chunk.toString(); |
| }); |
| child.on("error", reject); |
| child.on("close", (code) => { |
| if (code === 0) { |
| resolve({ stdout, stderr }); |
| return; |
| } |
| reject(new Error([`Command failed with exit ${code}: ${command}`, stdout, stderr].filter(Boolean).join("\n"))); |
| }); |
| }); |
|
|
| const shouldOpenArtifact = (text) => |
| /\b(open it|open the (?:html|file|site|website|page)|launch it|show it)\b/i.test(text || ""); |
|
|
| const extractArtifactPath = (stdout) => { |
| const artifact = stdout.match(/^Artifact:\s*(.+)$/m); |
| if (artifact) { |
| return artifact[1].trim(); |
| } |
| const project = stdout.match(/^Project\/repo:\s*(.+)$/m); |
| return project ? project[1].trim() : ""; |
| }; |
|
|
| const openArtifact = async (artifactPath) => { |
| if (!artifactPath || !existsSync(artifactPath)) { |
| return ""; |
| } |
| const system = platform(); |
| if (system === "darwin") { |
| await runProcess("open", [artifactPath]); |
| } else if (system === "win32") { |
| await runProcess("cmd", ["/c", "start", "", artifactPath]); |
| } else { |
| await runProcess("xdg-open", [artifactPath]); |
| } |
| return `Opened artifact: ${artifactPath}`; |
| }; |
|
|
| export const KaijuCoder7NoAutocontinuePlugin = async () => { |
| const isKaijuCoder7 = (input) => { |
| const payload = JSON.stringify({ |
| agent: input?.agent, |
| model: input?.model, |
| provider: input?.provider, |
| session: input?.session, |
| }); |
|
|
| return ( |
| payload.includes("kaiju-coder-7") || |
| payload.includes("Kaiju Coder 7") || |
| payload.includes("kaiju/kaiju-coder-7") |
| ); |
| }; |
|
|
| return { |
| tool: { |
| kaiju_write_file: tool({ |
| description: |
| "Write one exact small file in the current OpenCode directory. Use for exact one-file creation requests, not large generated websites or projects.", |
| args: { |
| file_path: tool.schema.string().describe("Relative path to write inside the current OpenCode directory."), |
| content: tool.schema.string().describe("Exact file content to write."), |
| }, |
| async execute(args, context) { |
| const target = resolveSafeFile(context.directory, args.file_path); |
| await mkdir(path.dirname(target), { recursive: true }); |
| await writeFile(target, args.content, "utf8"); |
| return { |
| output: `Wrote file: ${target}`, |
| metadata: { file_path: target, bytes: Buffer.byteLength(args.content, "utf8") }, |
| }; |
| }, |
| }), |
|
|
| kaiju_artifact: tool({ |
| description: |
| "Create fast Kaiju Coder 7 websites, owner packs, apps, business documents, or code artifacts with the packaged local router. Use this instead of bash/write for large generated artifact tasks.", |
| args: { |
| prompt: tool.schema.string().describe("The full user request to build."), |
| out_dir: tool.schema |
| .string() |
| .optional() |
| .describe("Absolute output directory. For Desktop requests, use /Users/<user>/Desktop/<clear-folder-name>."), |
| kind: tool.schema |
| .enum(TASK_KINDS) |
| .optional() |
| .describe("Artifact type. Use website for sites and business_suite for owner operating packs."), |
| no_planner: tool.schema |
| .boolean() |
| .optional() |
| .describe("Use deterministic rendering without a second model-planning call. Defaults to true."), |
| }, |
| async execute(args, context) { |
| const runtimeScript = process.env.KAIJU_ROUTER_SCRIPT || defaultRuntimeScript(); |
| if (!existsSync(runtimeScript)) { |
| throw new Error(`Kaiju router runtime is missing: ${runtimeScript}`); |
| } |
| const outDir = |
| args.out_dir || |
| path.join(homedir(), "Desktop", "Kaiju-Coder-7-Artifacts"); |
| const kind = args.kind || "auto"; |
| const noPlanner = args.no_planner !== false; |
| const procArgs = [runtimeScript, "--kind", kind, "--out-dir", outDir, "--prompt", args.prompt]; |
| if (noPlanner) { |
| procArgs.splice(1, 0, "--no-planner"); |
| } |
|
|
| context.metadata({ |
| title: `Kaiju artifact: ${kind}`, |
| metadata: { out_dir: outDir, kind, no_planner: noPlanner }, |
| }); |
|
|
| const result = await runProcess(process.env.KAIJU_PYTHON || "python3", procArgs, { |
| cwd: context.directory || process.cwd(), |
| }); |
| let output = result.stdout.trim() || "Kaiju artifact command completed."; |
| if (shouldOpenArtifact(args.prompt)) { |
| const artifactPath = extractArtifactPath(output); |
| try { |
| const opened = await openArtifact(artifactPath); |
| output += opened |
| ? `\n${opened}` |
| : "\nOpen requested, but no generated artifact path was available to open."; |
| } catch (error) { |
| output += `\nOpen requested, but could not open artifact: ${error.message}`; |
| } |
| } |
| return { |
| output, |
| metadata: { stderr: result.stderr.trim(), out_dir: outDir, kind, no_planner: noPlanner }, |
| }; |
| }, |
| }), |
| }, |
|
|
| async "chat.params"(input, output) { |
| if (!isKaijuCoder7(input)) { |
| return; |
| } |
| output.temperature = 0; |
| output.maxOutputTokens = Math.min(output.maxOutputTokens || 768, 768); |
| }, |
|
|
| async "experimental.compaction.autocontinue"(input, output) { |
| if (isKaijuCoder7(input)) { |
| output.enabled = false; |
| } |
| }, |
|
|
| async "experimental.session.compacting"(input, output) { |
| if (!isKaijuCoder7(input)) { |
| return; |
| } |
|
|
| output.context.push( |
| [ |
| "For Kaiju Coder 7 sessions, summarize only facts proven by tool output.", |
| "Do not say a file was created unless a write/edit/bash/read result confirms it exists.", |
| "If work is incomplete or unverified, mark it incomplete instead of complete.", |
| "Never convert a maximum-step, compaction, or length-limit stop into a successful completion claim.", |
| ].join("\n"), |
| ); |
| }, |
| }; |
| }; |
|
|
| export default KaijuCoder7NoAutocontinuePlugin; |
|
|