@vymalo/opencode-devtools 0.9.0
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/LICENSE +21 -0
- package/README.md +58 -0
- package/dist/catalog.d.ts +18 -0
- package/dist/catalog.js +44 -0
- package/dist/catalog.js.map +1 -0
- package/dist/groups/codec.d.ts +2 -0
- package/dist/groups/codec.js +141 -0
- package/dist/groups/codec.js.map +1 -0
- package/dist/groups/convert.d.ts +2 -0
- package/dist/groups/convert.js +99 -0
- package/dist/groups/convert.js.map +1 -0
- package/dist/groups/crypto.d.ts +2 -0
- package/dist/groups/crypto.js +205 -0
- package/dist/groups/crypto.js.map +1 -0
- package/dist/groups/datetime.d.ts +2 -0
- package/dist/groups/datetime.js +229 -0
- package/dist/groups/datetime.js.map +1 -0
- package/dist/groups/http.d.ts +10 -0
- package/dist/groups/http.js +269 -0
- package/dist/groups/http.js.map +1 -0
- package/dist/groups/math.d.ts +2 -0
- package/dist/groups/math.js +139 -0
- package/dist/groups/math.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/lib.d.ts +7 -0
- package/dist/lib.js +7 -0
- package/dist/lib.js.map +1 -0
- package/dist/logging.d.ts +16 -0
- package/dist/logging.js +72 -0
- package/dist/logging.js.map +1 -0
- package/dist/opencode.d.ts +14 -0
- package/dist/opencode.js +91 -0
- package/dist/opencode.js.map +1 -0
- package/dist/schema.d.ts +63 -0
- package/dist/schema.js +54 -0
- package/dist/schema.js.map +1 -0
- package/dist/tool-spec.d.ts +44 -0
- package/dist/tool-spec.js +27 -0
- package/dist/tool-spec.js.map +1 -0
- package/dist/tools.d.ts +18 -0
- package/dist/tools.js +91 -0
- package/dist/tools.js.map +1 -0
- package/dist/types.d.ts +38 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +81 -0
package/dist/tools.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { randomBytes as nodeRandomBytes } from "node:crypto";
|
|
2
|
+
import { tool } from "@opencode-ai/plugin";
|
|
3
|
+
import { selectTools } from "./catalog.js";
|
|
4
|
+
const z = tool.schema;
|
|
5
|
+
/** Build the full execution context, applying DI overrides. */
|
|
6
|
+
export function buildContext(options, overrides) {
|
|
7
|
+
return {
|
|
8
|
+
options,
|
|
9
|
+
now: overrides?.now ?? (() => new Date()),
|
|
10
|
+
randomBytes: overrides?.randomBytes ?? ((size) => nodeRandomBytes(size)),
|
|
11
|
+
fetchImpl: overrides?.fetchImpl ?? ((...a) => fetch(...a))
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function fieldToZod(field) {
|
|
15
|
+
let schema;
|
|
16
|
+
switch (field.type) {
|
|
17
|
+
case "string":
|
|
18
|
+
schema = (field.enum
|
|
19
|
+
? z.enum(field.enum)
|
|
20
|
+
: z.string());
|
|
21
|
+
break;
|
|
22
|
+
case "number":
|
|
23
|
+
schema = z.number();
|
|
24
|
+
break;
|
|
25
|
+
case "boolean":
|
|
26
|
+
schema = z.boolean();
|
|
27
|
+
break;
|
|
28
|
+
case "array":
|
|
29
|
+
schema = z.array(fieldToZod(field.items));
|
|
30
|
+
break;
|
|
31
|
+
case "object":
|
|
32
|
+
schema = z.object(buildShape(field.properties));
|
|
33
|
+
break;
|
|
34
|
+
case "record":
|
|
35
|
+
schema = z.record(z.string(), field.valueType === "any" ? z.any() : z.string());
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
if (field.description) {
|
|
39
|
+
schema = schema.describe(field.description);
|
|
40
|
+
}
|
|
41
|
+
if (field.optional) {
|
|
42
|
+
schema = schema.optional();
|
|
43
|
+
}
|
|
44
|
+
return schema;
|
|
45
|
+
}
|
|
46
|
+
function buildShape(input) {
|
|
47
|
+
const shape = {};
|
|
48
|
+
for (const [key, field] of Object.entries(input)) {
|
|
49
|
+
shape[key] = fieldToZod(field);
|
|
50
|
+
}
|
|
51
|
+
return shape;
|
|
52
|
+
}
|
|
53
|
+
/** Render an adapter-neutral result into OpenCode's text-only ToolResult. */
|
|
54
|
+
function renderOpenCode(result) {
|
|
55
|
+
if (result.kind === "text") {
|
|
56
|
+
return result.text;
|
|
57
|
+
}
|
|
58
|
+
const metadata = typeof result.data === "object" && result.data !== null ? result.data : { value: result.data };
|
|
59
|
+
return { output: result.text, metadata };
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Build the devtools tool map registered under `Hooks.tool`, filtered to the
|
|
63
|
+
* enabled groups. Each tool is a thin adapter over the shared catalog: validate
|
|
64
|
+
* args (zod), run the handler with the execution context, render the result.
|
|
65
|
+
*/
|
|
66
|
+
export function createDevtoolsTools(deps) {
|
|
67
|
+
const ctx = buildContext(deps.options, deps.context);
|
|
68
|
+
const tools = {};
|
|
69
|
+
for (const spec of selectTools(deps.options.groups)) {
|
|
70
|
+
const definition = {
|
|
71
|
+
description: spec.description,
|
|
72
|
+
args: buildShape(spec.input),
|
|
73
|
+
async execute(args) {
|
|
74
|
+
deps.logger.trace("devtools_tool_invoked", { tool: spec.name, group: spec.group });
|
|
75
|
+
try {
|
|
76
|
+
const result = await spec.handler(args, ctx);
|
|
77
|
+
deps.logger.trace("devtools_tool_completed", { tool: spec.name });
|
|
78
|
+
return renderOpenCode(result);
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
82
|
+
deps.logger.warn("devtools_tool_failed", { tool: spec.name, error: message });
|
|
83
|
+
throw err;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
tools[spec.name] = definition;
|
|
88
|
+
}
|
|
89
|
+
return tools;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ToolGroup } from "./schema.js";
|
|
2
|
+
export type LogLevel = "trace" | "debug" | "info" | "warn" | "error";
|
|
3
|
+
export type { ToolGroup } from "./schema.js";
|
|
4
|
+
/**
|
|
5
|
+
* Per-plugin configuration, supplied as the second argument to the plugin
|
|
6
|
+
* factory by OpenCode (the `[name, options]` tuple form in `plugin`). All
|
|
7
|
+
* fields are optional; see DEFAULTS in opencode.ts for the resolved values.
|
|
8
|
+
*/
|
|
9
|
+
export interface DevtoolsPluginOptions {
|
|
10
|
+
/** Master switch. When false no tools are registered. */
|
|
11
|
+
enabled?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Which tool groups to register. The five deterministic, offline groups
|
|
14
|
+
* (`math`, `codec`, `crypto`, `datetime`, `convert`) are on by default;
|
|
15
|
+
* `http` performs network egress and is **opt-in** — add it explicitly to
|
|
16
|
+
* enable it. Per-agent control is also possible via OpenCode's tool
|
|
17
|
+
* allow/deny on the `math_* / codec_* / …` names.
|
|
18
|
+
*/
|
|
19
|
+
groups?: ToolGroup[];
|
|
20
|
+
/** Options for the opt-in `http` group. */
|
|
21
|
+
http?: HttpOptions;
|
|
22
|
+
}
|
|
23
|
+
export interface HttpOptions {
|
|
24
|
+
/**
|
|
25
|
+
* Allow requests to loopback / private / link-local hosts (incl. the cloud
|
|
26
|
+
* metadata IP `169.254.169.254`). Default `false` — the SSRF guard rejects
|
|
27
|
+
* them. Turn on only when you intend the model to reach internal services.
|
|
28
|
+
*/
|
|
29
|
+
allowPrivateNetwork?: boolean;
|
|
30
|
+
/** Per-request timeout in ms before the call aborts. Default 30000. */
|
|
31
|
+
timeoutMs?: number;
|
|
32
|
+
}
|
|
33
|
+
/** Fully-resolved options with defaults applied. */
|
|
34
|
+
export interface ResolvedDevtoolsOptions {
|
|
35
|
+
enabled: boolean;
|
|
36
|
+
groups: ToolGroup[];
|
|
37
|
+
http: Required<HttpOptions>;
|
|
38
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vymalo/opencode-devtools",
|
|
3
|
+
"version": "0.9.0",
|
|
4
|
+
"description": "OpenCode plugin of everyday developer utilities the model can call locally: math (precise arithmetic, unit & base conversion, stats), codec (base64/hex/url, JWT decode, gzip), crypto (hash/hmac, uuid/ulid, random, keypairs), datetime (parse/format/diff, timezones, cron explain), convert (JSON/YAML/TOML/CSV + JSONPath), and an opt-in http client. Deterministic, zero-auth, no server — tools gated into named groups.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "vymalo contributors",
|
|
7
|
+
"homepage": "https://github.com/vymalo/opencode-oauth2#readme",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/vymalo/opencode-oauth2.git",
|
|
11
|
+
"directory": "packages/opencode-devtools"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/vymalo/opencode-oauth2/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"opencode",
|
|
18
|
+
"opencode-plugin",
|
|
19
|
+
"utilities",
|
|
20
|
+
"math",
|
|
21
|
+
"crypto",
|
|
22
|
+
"base64",
|
|
23
|
+
"jwt",
|
|
24
|
+
"datetime",
|
|
25
|
+
"cron",
|
|
26
|
+
"yaml",
|
|
27
|
+
"csv",
|
|
28
|
+
"http",
|
|
29
|
+
"ai-sdk"
|
|
30
|
+
],
|
|
31
|
+
"type": "module",
|
|
32
|
+
"main": "dist/index.js",
|
|
33
|
+
"types": "dist/index.d.ts",
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
37
|
+
"import": "./dist/index.js"
|
|
38
|
+
},
|
|
39
|
+
"./lib": {
|
|
40
|
+
"types": "./dist/lib.d.ts",
|
|
41
|
+
"import": "./dist/lib.js"
|
|
42
|
+
},
|
|
43
|
+
"./package.json": "./package.json"
|
|
44
|
+
},
|
|
45
|
+
"sideEffects": false,
|
|
46
|
+
"files": [
|
|
47
|
+
"dist"
|
|
48
|
+
],
|
|
49
|
+
"engines": {
|
|
50
|
+
"node": ">=22"
|
|
51
|
+
},
|
|
52
|
+
"publishConfig": {
|
|
53
|
+
"access": "public"
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"@iarna/toml": "^2.2.5",
|
|
57
|
+
"@opencode-ai/plugin": "1.15.10",
|
|
58
|
+
"cron-parser": "^5.5.0",
|
|
59
|
+
"cronstrue": "^3.20.0",
|
|
60
|
+
"jsonpath-plus": "^10.4.0",
|
|
61
|
+
"luxon": "^3.7.2",
|
|
62
|
+
"mathjs": "^15.2.0",
|
|
63
|
+
"papaparse": "^5.5.3",
|
|
64
|
+
"yaml": "^2.9.0"
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@types/luxon": "^3.7.1",
|
|
68
|
+
"@types/papaparse": "^5.5.2",
|
|
69
|
+
"vite": "^8.0.14",
|
|
70
|
+
"vitest": "^4.1.7"
|
|
71
|
+
},
|
|
72
|
+
"scripts": {
|
|
73
|
+
"build": "tsc -p tsconfig.json",
|
|
74
|
+
"lint": "biome lint .",
|
|
75
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
76
|
+
"test": "vitest run",
|
|
77
|
+
"coverage": "vitest run --coverage",
|
|
78
|
+
"format": "biome format --write .",
|
|
79
|
+
"format:check": "biome format ."
|
|
80
|
+
}
|
|
81
|
+
}
|