fix: resolve installed OpenCode skill paths consistently

Carry forward PR #3115 ef475c79 and 780dfb78 onto current main. Preserve the newer hook-consent transforms during install and repair. Main already includes the source import fix from #3167.
This commit is contained in:
Yusuf Efe
2026-10-09 15:40:12 -04:00
committed by haelyra
parent ef648e0189
commit 0f34fdcc14
11 changed files with 342 additions and 41 deletions
+84
View File
@@ -7,7 +7,57 @@ const fs = require("fs")
const os = require("os")
const path = require("path")
const { spawnSync } = require("child_process")
const { pathToFileURL } = require("url")
const { getNpmPackEntry } = require("../lib/npm-pack-output")
const { createManifestInstallPlan, applyInstallPlan } = require("../../scripts/lib/install-executor")
const { withHookConsent } = require("../../scripts/lib/install/hook-consent")
function checkRuntime(runtimeRoot, extension, loader) {
const check = `
const assert = require("node:assert/strict")
const path = require("node:path")
const { pathToFileURL } = require("node:url")
const [root, extension] = process.argv.slice(1)
const load = (name) => import(pathToFileURL(path.join(root, name + extension)).href)
async function main() {
const tools = await load("tools/index")
assert.deepEqual(Object.keys(tools).sort(), [
"changedFiles", "checkCoverage", "dependencyAnalyzer", "formatCode",
"gitSummary", "lintCheck", "runTests", "securityAudit",
])
for (const tool of Object.values(tools)) {
assert.equal(typeof tool.description, "string")
assert.equal(typeof tool.execute, "function")
}
const plugins = await load("plugins/index")
const entry = await load("index")
assert.deepEqual(Object.keys(entry), ["default"])
assert.equal(entry.default, plugins.default)
const logs = []
const plugin = await entry.default({
client: { app: { log: (event) => logs.push(event.body) } },
$: () => { throw new Error("Unexpected shell execution") },
directory: process.cwd(),
worktree: process.cwd(),
})
assert.equal(typeof plugin["session.created"], "function")
await plugin["file.edited"]({ path: path.join(process.cwd(), "example.txt") })
const changed = JSON.parse(await tools.changedFiles.execute({ format: "json" }, {}))
assert.equal(changed.changed, true)
assert.deepEqual(changed.files, [{ path: "example.txt", changeType: "modified" }])
assert.ok(!logs.some((log) => log.message.includes("tracking disabled")))
}
main().catch((error) => { console.error(error); process.exit(1) })
`
const args = loader ? ["--loader", pathToFileURL(loader).href] : []
const result = spawnSync(process.execPath, [...args, "-e", check, runtimeRoot, extension], {
cwd: path.join(__dirname, "..", ".."),
encoding: "utf8",
})
assert.strictEqual(result.status, 0, result.error?.message || result.stderr || result.stdout)
}
function runTest(name, fn) {
try {
@@ -183,6 +233,40 @@ function main() {
})
assert.strictEqual(result.status, 0, result.stderr)
}],
["compiled barrels load and share the lazy changed-files store", () => {
checkRuntime(path.dirname(distEntry), ".js")
}],
["full home install loads TypeScript barrels and the lazy changed-files store", () => {
// Keep the fixture beneath the repo so the installed tools can resolve
// the real SDK dependency without installing packages in the user's home.
const fixture = fs.mkdtempSync(path.join(repoRoot, "tests", ".opencode-home-"))
try {
const homeDir = path.join(fixture, "home")
const projectRoot = path.join(fixture, "project")
fs.mkdirSync(homeDir)
fs.mkdirSync(projectRoot)
const plan = withHookConsent(createManifestInstallPlan({
sourceRoot: repoRoot,
homeDir,
projectRoot,
env: {},
target: "opencode",
profileId: "full",
}), "enabled")
applyInstallPlan(plan)
const config = JSON.parse(fs.readFileSync(path.join(plan.targetRoot, "opencode.json"), "utf8"))
assert.deepStrictEqual(config.skills.paths, ["./skills"])
assert.ok(fs.existsSync(path.join(plan.targetRoot, config.skills.paths[0], "tdd-workflow", "SKILL.md")))
assert.ok(!fs.existsSync(path.join(plan.targetRoot, "tools", "run-tests.js")))
checkRuntime(
plan.targetRoot,
".ts",
path.join(repoRoot, "tests", "fixtures", "opencode-ts-loader.mjs"),
)
} finally {
fs.rmSync(fixture, { recursive: true, force: true })
}
}],
["npm pack includes the compiled OpenCode dist payload", () => {
fs.rmSync(path.dirname(distEntry), { recursive: true, force: true })
const result = spawnSync("npm", ["pack", "--dry-run", "--json", "--ignore-scripts=false"], {