import assert from "node:assert/strict" import { existsSync, mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs" import { tmpdir } from "node:os" import path from "node:path" import { test } from "node:test" import { agentsTarget, runInit } from "../src/init.ts" function fixturePkg() { const pkgRoot = mkdtempSync(path.join(tmpdir(), "init-pkg-")) mkdirSync(path.join(pkgRoot, "agents")) writeFileSync(path.join(pkgRoot, "package.json"), JSON.stringify({ version: "9.9.9" })) writeFileSync(path.join(pkgRoot, "agents", "pocock.md"), "---\nmode: primary\n---\nv1\n") writeFileSync(path.join(pkgRoot, "agents", "pocock-worker.md"), "---\nmode: subagent\n---\nv1\n") return pkgRoot } test("runInit copies agents, stamps version, targets project or global dir", () => { const pkgRoot = fixturePkg() const home = mkdtempSync(path.join(tmpdir(), "init-home-")) const cwd = mkdtempSync(path.join(tmpdir(), "init-cwd-")) try { const project = runInit({ argv: ["init"], cwd, pkgRoot, home }) assert.equal(project.target, path.join(cwd, ".opencode", "agents")) assert.deepEqual(project.copied, ["pocock-worker.md", "pocock.md"]) assert.deepEqual(project.skipped, []) assert.equal( readFileSync(path.join(project.target, "pocock.md"), "utf8"), "---\nmode: primary\n---\nv1\n", ) assert.equal(readFileSync(path.join(project.target, ".pocock-version"), "utf8"), "9.9.9\n") const global = runInit({ argv: ["init", "-g"], cwd, pkgRoot, home }) assert.equal(global.target, path.join(home, ".config", "opencode", "agents")) assert.ok(existsSync(path.join(global.target, "pocock.md"))) // identical files are refreshed silently; locally modified files are kept without --force writeFileSync(path.join(project.target, "pocock.md"), "---\nmode: primary\n---\nUSER EDIT\n") const again = runInit({ argv: ["init"], cwd, pkgRoot, home }) assert.deepEqual(again.skipped, ["pocock.md"]) assert.deepEqual(again.copied, ["pocock-worker.md"]) assert.match(readFileSync(path.join(project.target, "pocock.md"), "utf8"), /USER EDIT/) const forced = runInit({ argv: ["init", "--force"], cwd, pkgRoot, home }) assert.deepEqual(forced.skipped, []) assert.match(readFileSync(path.join(project.target, "pocock.md"), "utf8"), /v1/) assert.throws( () => runInit({ argv: ["init", "--wat"], cwd, pkgRoot, home }), /unknown argument --wat/, ) } finally { for (const dir of [pkgRoot, home, cwd]) rmSync(dir, { recursive: true, force: true }) } }) test("agentsTarget resolves global vs project locations", () => { assert.equal(agentsTarget(false, "/repo", "/home/u"), path.join("/repo", ".opencode", "agents")) assert.equal( agentsTarget(true, "/repo", "/home/u"), path.join("/home/u", ".config", "opencode", "agents"), ) }) test("runInit fails clearly when the package has no agents dir", () => { const empty = mkdtempSync(path.join(tmpdir(), "init-empty-")) try { writeFileSync(path.join(empty, "package.json"), "{}") assert.throws( () => runInit({ argv: ["init"], cwd: empty, pkgRoot: empty, home: empty }), /no agents\/ in package/, ) } finally { rmSync(empty, { recursive: true, force: true }) } })