@cgasgarth/opencode-for-rust 1.1.1 → 1.1.2-next.1
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/README.md +14 -3
- package/dist/index.js +71 -38
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -6,10 +6,10 @@ OpenCode plugin for Rust
|
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
|
-
- Automatic Type Injection: Automatically analyzes Rust files and injects
|
|
10
|
-
- Type Lookup: Includes a `lookup_type` tool to find specific Rust type definitions by name.
|
|
9
|
+
- Automatic Type Injection: Automatically analyzes Rust files and injects an outline of defined types (structs, enums, traits, functions) at the end of file content when you read a `.rs` file.
|
|
10
|
+
- Type Lookup: Includes a `lookup_type` tool to find specific Rust type definitions by name across the entire project.
|
|
11
11
|
- Type Listing: Includes a `list_types` tool to see all available Rust types in the project.
|
|
12
|
-
- Regex-based Parser: Uses a lightweight regex-based parser
|
|
12
|
+
- Regex-based Parser: Uses a lightweight, zero-dependency regex-based parser that works reliably in all JavaScript environments (Node.js, Bun, OpenCode).
|
|
13
13
|
- Zero Configuration: Works out of the box for standard Rust projects.
|
|
14
14
|
|
|
15
15
|
## Tools
|
|
@@ -56,3 +56,14 @@ https://github.com/cgasgarth/opencode-for-rust
|
|
|
56
56
|
## License
|
|
57
57
|
|
|
58
58
|
MIT
|
|
59
|
+
|
|
60
|
+
## Known Limitations
|
|
61
|
+
|
|
62
|
+
**Automatic Type Injection**: The hook for automatic type injection when reading `.rs` files is currently not functional in OpenCode's environment. This appears to be due to differences in how OpenCode's plugin system processes hook registration or type expectations compared to the TypeScript plugin.
|
|
63
|
+
|
|
64
|
+
**Manual Tools**: The following tools work correctly and can be used as alternatives:
|
|
65
|
+
|
|
66
|
+
- `lookup_type`: Successfully retrieves Rust type definitions by name (verified: 413 types found in kalshi-tools)
|
|
67
|
+
- `list_types`: Successfully lists all Rust type names in the project (verified: 413 types found in kalshi-tools)
|
|
68
|
+
|
|
69
|
+
The plugin loads without errors and uses a cross-platform regex-based parser that eliminates the WASM dependency issues that caused earlier crashes.
|
package/dist/index.js
CHANGED
|
@@ -239,58 +239,58 @@ class RustContentFormatter {
|
|
|
239
239
|
}
|
|
240
240
|
|
|
241
241
|
// src/index.ts
|
|
242
|
+
import { z } from "zod";
|
|
243
|
+
import { appendFileSync } from "fs";
|
|
244
|
+
var DEBUG_LOG = "/tmp/opencode-rust-plugin.log";
|
|
245
|
+
function debugLog(msg) {
|
|
246
|
+
const timestamp = new Date().toISOString();
|
|
247
|
+
appendFileSync(DEBUG_LOG, `[${timestamp}] ${msg}
|
|
248
|
+
`);
|
|
249
|
+
}
|
|
242
250
|
var RustPlugin = async (context) => {
|
|
251
|
+
debugLog(`Plugin initializing with context: ${JSON.stringify(context)}`);
|
|
243
252
|
const config = {
|
|
244
253
|
enabled: true,
|
|
245
|
-
debug:
|
|
254
|
+
debug: true,
|
|
246
255
|
budget: 50,
|
|
247
256
|
excludePatterns: [],
|
|
248
257
|
imports: false
|
|
249
258
|
};
|
|
250
|
-
const directory = context.directory ||
|
|
259
|
+
const directory = context.directory || process.cwd();
|
|
260
|
+
debugLog(`Using directory: ${directory}`);
|
|
251
261
|
const lookup = new RustTypeLookup(directory, config);
|
|
252
262
|
const formatter = new RustContentFormatter(config);
|
|
253
263
|
const extractor = new RegexRustTypeExtractor(config);
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
try {
|
|
263
|
-
await lookup.refresh();
|
|
264
|
-
const types = await extractor.extract(filePath, result.content);
|
|
265
|
-
const formatted = formatter.formatInjectedTypes(types);
|
|
266
|
-
if (formatted) {
|
|
267
|
-
return {
|
|
268
|
-
...result,
|
|
269
|
-
content: result.content + formatted
|
|
270
|
-
};
|
|
271
|
-
}
|
|
272
|
-
} catch (error) {
|
|
273
|
-
if (config.debug) {
|
|
274
|
-
throw error;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
return result;
|
|
278
|
-
}
|
|
279
|
-
},
|
|
264
|
+
debugLog("Created lookup, formatter, extractor");
|
|
265
|
+
try {
|
|
266
|
+
await lookup.refresh();
|
|
267
|
+
debugLog("Initial refresh completed");
|
|
268
|
+
} catch (e) {
|
|
269
|
+
debugLog(`Initial refresh failed: ${e}`);
|
|
270
|
+
}
|
|
271
|
+
const hooks = {
|
|
280
272
|
tool: {
|
|
281
273
|
lookup_type: tool({
|
|
282
274
|
description: "Find a Rust type definition by name",
|
|
283
275
|
args: {
|
|
284
|
-
name:
|
|
276
|
+
name: z.string().describe("The name of the type to look up")
|
|
285
277
|
},
|
|
286
278
|
async execute(args) {
|
|
279
|
+
debugLog(`lookup_type called with: ${JSON.stringify(args)}`);
|
|
287
280
|
try {
|
|
281
|
+
await lookup.refresh();
|
|
282
|
+
debugLog("lookup_type: refresh done");
|
|
288
283
|
const type = await lookup.findType(args.name);
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
284
|
+
debugLog(`lookup_type: findType result: ${type ? "found" : "not found"}`);
|
|
285
|
+
if (!type) {
|
|
286
|
+
return `Type '${args.name}' not found`;
|
|
287
|
+
}
|
|
288
|
+
const result = formatter.formatInjectedTypes([type]);
|
|
289
|
+
debugLog(`lookup_type: returning ${result.length} chars`);
|
|
290
|
+
return result;
|
|
291
|
+
} catch (e) {
|
|
292
|
+
debugLog(`lookup_type error: ${e}`);
|
|
293
|
+
throw e;
|
|
294
294
|
}
|
|
295
295
|
}
|
|
296
296
|
}),
|
|
@@ -298,17 +298,50 @@ var RustPlugin = async (context) => {
|
|
|
298
298
|
description: "List all available Rust type names in the project",
|
|
299
299
|
args: {},
|
|
300
300
|
async execute() {
|
|
301
|
+
debugLog("list_types called");
|
|
301
302
|
try {
|
|
302
|
-
|
|
303
|
-
|
|
303
|
+
await lookup.refresh();
|
|
304
|
+
debugLog("list_types: refresh done");
|
|
305
|
+
const names = await lookup.listTypeNames();
|
|
306
|
+
debugLog(`list_types: found ${names.length} types`);
|
|
307
|
+
if (names.length === 0) {
|
|
308
|
+
return "No Rust types found in project";
|
|
309
|
+
}
|
|
310
|
+
return names.join(`
|
|
304
311
|
`);
|
|
305
|
-
} catch (
|
|
306
|
-
|
|
312
|
+
} catch (e) {
|
|
313
|
+
debugLog(`list_types error: ${e}`);
|
|
314
|
+
throw e;
|
|
307
315
|
}
|
|
308
316
|
}
|
|
309
317
|
})
|
|
318
|
+
},
|
|
319
|
+
"tool.execute.after": async (input, output) => {
|
|
320
|
+
debugLog(`tool.execute.after: tool=${input.tool}`);
|
|
321
|
+
if (input.tool !== "read") {
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
const metadata = output.metadata;
|
|
325
|
+
const filePath = metadata?.filePath;
|
|
326
|
+
debugLog(`tool.execute.after: filePath=${filePath}`);
|
|
327
|
+
if (!filePath || !filePath.endsWith(".rs")) {
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
try {
|
|
331
|
+
const types = await extractor.extract(filePath);
|
|
332
|
+
debugLog(`tool.execute.after: extracted ${types.length} types`);
|
|
333
|
+
const formatted = formatter.formatInjectedTypes(types);
|
|
334
|
+
if (formatted) {
|
|
335
|
+
output.output = output.output + formatted;
|
|
336
|
+
debugLog(`tool.execute.after: appended ${formatted.length} chars`);
|
|
337
|
+
}
|
|
338
|
+
} catch (error) {
|
|
339
|
+
debugLog(`tool.execute.after error: ${error}`);
|
|
340
|
+
}
|
|
310
341
|
}
|
|
311
342
|
};
|
|
343
|
+
debugLog("Hooks created, returning");
|
|
344
|
+
return hooks;
|
|
312
345
|
};
|
|
313
346
|
var src_default = RustPlugin;
|
|
314
347
|
export {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cgasgarth/opencode-for-rust",
|
|
3
|
-
"version": "1.1.1",
|
|
3
|
+
"version": "1.1.2-next.1",
|
|
4
4
|
"description": "OpenCode plugin for Rust",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Sisyphus",
|
|
@@ -28,6 +28,9 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@opencode-ai/plugin": "1.0.85"
|
|
30
30
|
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"zod": "^4.0.0"
|
|
33
|
+
},
|
|
31
34
|
"devDependencies": {
|
|
32
35
|
"@eslint/js": "^9.39.1",
|
|
33
36
|
"@types/bun": "latest",
|
|
@@ -35,6 +38,7 @@
|
|
|
35
38
|
"@typescript-eslint/eslint-plugin": "8.47.0",
|
|
36
39
|
"@typescript-eslint/parser": "8.47.0",
|
|
37
40
|
"bun-types": "latest",
|
|
41
|
+
"esbuild": "^0.27.2",
|
|
38
42
|
"eslint": "^9.39.1",
|
|
39
43
|
"eslint-config-prettier": "10.1.8",
|
|
40
44
|
"eslint-plugin-prettier": "^5.2.1",
|
|
@@ -48,7 +52,7 @@
|
|
|
48
52
|
"scripts": {
|
|
49
53
|
"test": "bun test tests/",
|
|
50
54
|
"typecheck": "tsc --noEmit",
|
|
51
|
-
"build": "
|
|
55
|
+
"build": "esbuild ./src/index.ts --bundle --format=esm --platform=node --outdir=dist --external:zod && tsc --project tsconfig.build.json",
|
|
52
56
|
"lint": "eslint src --max-warnings 0",
|
|
53
57
|
"format": "prettier --check .",
|
|
54
58
|
"prepare": "husky"
|