opencode-yul 0.0.12
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/index.d.ts +2 -0
- package/dist/index.js +89 -0
- package/package.json +43 -0
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// yul OpenCode plugin: keeps dependencies current by blocking `write`/`edit`
|
|
2
|
+
// tool calls that would pin a newly added/changed dependency to a version
|
|
3
|
+
// older than what's actually released.
|
|
4
|
+
//
|
|
5
|
+
// Distributed as the npm package "opencode-yul" — add it to the `plugin`
|
|
6
|
+
// array in your project's opencode.json/opencode.jsonc:
|
|
7
|
+
//
|
|
8
|
+
// { "plugin": ["opencode-yul"] }
|
|
9
|
+
//
|
|
10
|
+
// NOTE: `input.tool` values and `output.args` field names below were
|
|
11
|
+
// confirmed against the built-in write/edit tool schemas in opencode-ai@1.18.31
|
|
12
|
+
// (write: {content, filePath}; edit: {filePath, oldString, newString, replaceAll}).
|
|
13
|
+
// Re-check if the hook stops firing after an OpenCode upgrade changes these.
|
|
14
|
+
import { spawnSync } from "node:child_process";
|
|
15
|
+
import { existsSync, mkdirSync, readdirSync, rmSync } from "node:fs";
|
|
16
|
+
import { homedir } from "node:os";
|
|
17
|
+
import { join } from "node:path";
|
|
18
|
+
// Bumped in lockstep with .claude-plugin/plugin.json and this package's own
|
|
19
|
+
// package.json version by the release workflow — it's what pins which yul
|
|
20
|
+
// binary this plugin downloads and runs.
|
|
21
|
+
const YUL_VERSION = "0.0.12";
|
|
22
|
+
const CACHE_ROOT = join(process.env.XDG_CACHE_HOME ?? join(homedir(), ".cache"), "yul");
|
|
23
|
+
const CACHE_DIR = join(CACHE_ROOT, `v${YUL_VERSION}`);
|
|
24
|
+
const BIN_PATH = join(CACHE_DIR, "yul");
|
|
25
|
+
// ensureYul downloads the pinned yul release binary into the cache dir if
|
|
26
|
+
// it isn't already there, then prunes caches left behind by other versions.
|
|
27
|
+
// Mirrors scripts/ensure-yul.sh, minus the "newer release available"
|
|
28
|
+
// notice, which has no obvious OpenCode-side equivalent to print to.
|
|
29
|
+
function ensureYul() {
|
|
30
|
+
if (existsSync(BIN_PATH))
|
|
31
|
+
return;
|
|
32
|
+
mkdirSync(CACHE_DIR, { recursive: true });
|
|
33
|
+
const result = spawnSync("sh", ["-c", `curl -fsSL "https://raw.githubusercontent.com/chains-project/yul/v${YUL_VERSION}/install.sh" | sh`], {
|
|
34
|
+
env: { ...process.env, YUL_VERSION: `v${YUL_VERSION}`, YUL_INSTALL_DIR: CACHE_DIR },
|
|
35
|
+
stdio: "ignore",
|
|
36
|
+
timeout: 60_000, // matches the outer timeout Claude Code's hooks.json puts on the equivalent script
|
|
37
|
+
});
|
|
38
|
+
if (result.status !== 0 || !existsSync(BIN_PATH))
|
|
39
|
+
return; // fail open: hook below no-ops until the binary exists
|
|
40
|
+
if (existsSync(CACHE_ROOT)) {
|
|
41
|
+
for (const entry of readdirSync(CACHE_ROOT, { withFileTypes: true })) {
|
|
42
|
+
if (entry.isDirectory() && entry.name.startsWith("v") && entry.name !== `v${YUL_VERSION}`) {
|
|
43
|
+
rmSync(join(CACHE_ROOT, entry.name), { recursive: true, force: true });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function toHookInput(tool, args) {
|
|
49
|
+
if (tool === "write") {
|
|
50
|
+
return { tool_name: "Write", tool_input: { file_path: args.filePath, content: args.content } };
|
|
51
|
+
}
|
|
52
|
+
if (tool === "edit") {
|
|
53
|
+
return {
|
|
54
|
+
tool_name: "Edit",
|
|
55
|
+
tool_input: {
|
|
56
|
+
file_path: args.filePath,
|
|
57
|
+
old_string: args.oldString,
|
|
58
|
+
new_string: args.newString,
|
|
59
|
+
replace_all: args.replaceAll,
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
export const Yul = async () => {
|
|
66
|
+
try {
|
|
67
|
+
ensureYul();
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// fail open: cache setup errors must not disable OpenCode
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
"tool.execute.before": async (input, output) => {
|
|
74
|
+
if (!existsSync(BIN_PATH))
|
|
75
|
+
return; // fail open: still downloading, or offline install
|
|
76
|
+
const hookInput = toHookInput(input.tool, output.args);
|
|
77
|
+
if (!hookInput)
|
|
78
|
+
return;
|
|
79
|
+
const result = spawnSync(BIN_PATH, [], {
|
|
80
|
+
input: JSON.stringify(hookInput),
|
|
81
|
+
encoding: "utf8",
|
|
82
|
+
});
|
|
83
|
+
if (result.status === 2) {
|
|
84
|
+
throw new Error(result.stderr || "yul: dependency pin is outdated");
|
|
85
|
+
}
|
|
86
|
+
// any other exit code (0, or a resolver/plumbing error) fails open
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/package.json",
|
|
3
|
+
"name": "opencode-yul",
|
|
4
|
+
"version": "0.0.12",
|
|
5
|
+
"description": "Forces models to use the latest versions of dependencies instead of outdated versions from model training data.",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/chains-project/yul.git",
|
|
9
|
+
"directory": "opencode-yul"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/chains-project/yul",
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "dist/index.js",
|
|
15
|
+
"types": "dist/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"import": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsc",
|
|
27
|
+
"typecheck": "tsc --noEmit",
|
|
28
|
+
"prepublishOnly": "npm run build"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"opencode",
|
|
32
|
+
"opencode-plugin",
|
|
33
|
+
"dependencies"
|
|
34
|
+
],
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"@opencode-ai/plugin": ">=1.0.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@opencode-ai/plugin": "^1.0.0",
|
|
40
|
+
"@types/node": "^26.6.2",
|
|
41
|
+
"typescript": "^7.0.2"
|
|
42
|
+
}
|
|
43
|
+
}
|