@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/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 vymalo contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# @vymalo/opencode-devtools
|
|
2
|
+
|
|
3
|
+
> A belt of everyday, **deterministic, local** developer utilities for the model — maths, encoding,
|
|
4
|
+
> crypto, date/time, structured-data conversion, and an opt-in HTTP client.
|
|
5
|
+
|
|
6
|
+
[](https://www.npmjs.com/package/@vymalo/opencode-devtools)
|
|
7
|
+

|
|
8
|
+

|
|
9
|
+
|
|
10
|
+
An OpenCode plugin that registers a set of pure, in-process tools the model can call — no bridge, no
|
|
11
|
+
server, no auth. Tools are organised into **groups** (gated by the `groups` option, like the browser
|
|
12
|
+
plugin): `math`, `codec`, `crypto`, `datetime`, `convert` (on by default) and an opt-in, SSRF-guarded
|
|
13
|
+
`http` group. The same tool surface ships as an MCP server: [`@vymalo/opencode-devtools-mcp`](../opencode-devtools-mcp).
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
```jsonc
|
|
18
|
+
// opencode.json
|
|
19
|
+
{
|
|
20
|
+
"plugin": ["@vymalo/opencode-devtools"]
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Enable the `http` group (off by default — it performs network egress):
|
|
25
|
+
|
|
26
|
+
```jsonc
|
|
27
|
+
{
|
|
28
|
+
"plugin": [
|
|
29
|
+
["@vymalo/opencode-devtools", {
|
|
30
|
+
"groups": ["math", "codec", "crypto", "datetime", "convert", "http"],
|
|
31
|
+
"http": { "allowPrivateNetwork": false }
|
|
32
|
+
}]
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Tools at a glance
|
|
38
|
+
|
|
39
|
+
| Group | Tools |
|
|
40
|
+
| --- | --- |
|
|
41
|
+
| `math` | `math_eval` (64-digit), `math_convert_unit`, `math_stats`, `math_base` |
|
|
42
|
+
| `codec` | `codec_base64`, `codec_hex`, `codec_url`, `codec_jwt_decode`, `codec_gzip` |
|
|
43
|
+
| `crypto` | `crypto_hash`, `crypto_hmac`, `crypto_uuid` (v4/v7), `crypto_ulid`, `crypto_random`, `crypto_keypair` |
|
|
44
|
+
| `datetime` | `datetime_now`, `datetime_parse`, `datetime_format`, `datetime_diff`, `datetime_convert_tz`, `datetime_cron` |
|
|
45
|
+
| `convert` | `convert_data` (JSON/YAML/TOML/CSV), `convert_query` (JSONPath) |
|
|
46
|
+
| `http` *(opt-in)* | `http_request`, `http_graphql` |
|
|
47
|
+
|
|
48
|
+
Full reference, config, and the security model: [`docs/devtools.md`](../../docs/devtools.md).
|
|
49
|
+
|
|
50
|
+
## Why not memory / adb / database too?
|
|
51
|
+
|
|
52
|
+
Those already have mature MCP servers, so we **adopt** them rather than rebuild — see
|
|
53
|
+
[`docs/recommended-mcps.md`](../../docs/recommended-mcps.md). devtools fills only the gaps: the small
|
|
54
|
+
deterministic utilities nobody else maintains well.
|
|
55
|
+
|
|
56
|
+
## License
|
|
57
|
+
|
|
58
|
+
MIT
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ToolGroup } from "./schema.js";
|
|
2
|
+
import type { ToolSpec } from "./tool-spec.js";
|
|
3
|
+
export type { ToolGroup } from "./schema.js";
|
|
4
|
+
export type { NeutralResult, ToolContext, ToolSpec } from "./tool-spec.js";
|
|
5
|
+
export declare const TOOL_GROUPS: readonly ToolGroup[];
|
|
6
|
+
/**
|
|
7
|
+
* Groups registered when the operator doesn't specify. The five deterministic,
|
|
8
|
+
* offline groups are on; `http` performs network egress and is opt-in.
|
|
9
|
+
*/
|
|
10
|
+
export declare const DEFAULT_GROUPS: readonly ToolGroup[];
|
|
11
|
+
/**
|
|
12
|
+
* The single source of truth for the devtools tool surface, shared by the
|
|
13
|
+
* OpenCode plugin and the MCP server. Filter by `group` to gate what an agent
|
|
14
|
+
* sees.
|
|
15
|
+
*/
|
|
16
|
+
export declare const DEVTOOLS_TOOLS: readonly ToolSpec[];
|
|
17
|
+
/** The catalog tools enabled for the given groups. */
|
|
18
|
+
export declare function selectTools(groups: readonly ToolGroup[]): ToolSpec[];
|
package/dist/catalog.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { CODEC_TOOLS } from "./groups/codec.js";
|
|
2
|
+
import { CONVERT_TOOLS } from "./groups/convert.js";
|
|
3
|
+
import { CRYPTO_TOOLS } from "./groups/crypto.js";
|
|
4
|
+
import { DATETIME_TOOLS } from "./groups/datetime.js";
|
|
5
|
+
import { HTTP_TOOLS } from "./groups/http.js";
|
|
6
|
+
import { MATH_TOOLS } from "./groups/math.js";
|
|
7
|
+
export const TOOL_GROUPS = [
|
|
8
|
+
"math",
|
|
9
|
+
"codec",
|
|
10
|
+
"crypto",
|
|
11
|
+
"datetime",
|
|
12
|
+
"convert",
|
|
13
|
+
"http"
|
|
14
|
+
];
|
|
15
|
+
/**
|
|
16
|
+
* Groups registered when the operator doesn't specify. The five deterministic,
|
|
17
|
+
* offline groups are on; `http` performs network egress and is opt-in.
|
|
18
|
+
*/
|
|
19
|
+
export const DEFAULT_GROUPS = [
|
|
20
|
+
"math",
|
|
21
|
+
"codec",
|
|
22
|
+
"crypto",
|
|
23
|
+
"datetime",
|
|
24
|
+
"convert"
|
|
25
|
+
];
|
|
26
|
+
/**
|
|
27
|
+
* The single source of truth for the devtools tool surface, shared by the
|
|
28
|
+
* OpenCode plugin and the MCP server. Filter by `group` to gate what an agent
|
|
29
|
+
* sees.
|
|
30
|
+
*/
|
|
31
|
+
export const DEVTOOLS_TOOLS = [
|
|
32
|
+
...MATH_TOOLS,
|
|
33
|
+
...CODEC_TOOLS,
|
|
34
|
+
...CRYPTO_TOOLS,
|
|
35
|
+
...DATETIME_TOOLS,
|
|
36
|
+
...CONVERT_TOOLS,
|
|
37
|
+
...HTTP_TOOLS
|
|
38
|
+
];
|
|
39
|
+
/** The catalog tools enabled for the given groups. */
|
|
40
|
+
export function selectTools(groups) {
|
|
41
|
+
const enabled = new Set(groups);
|
|
42
|
+
return DEVTOOLS_TOOLS.filter((spec) => enabled.has(spec.group));
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAO9C,MAAM,CAAC,MAAM,WAAW,GAAyB;IAC/C,MAAM;IACN,OAAO;IACP,QAAQ;IACR,UAAU;IACV,SAAS;IACT,MAAM;CACE,CAAC;AAEX;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAyB;IAClD,MAAM;IACN,OAAO;IACP,QAAQ;IACR,UAAU;IACV,SAAS;CACD,CAAC;AAEX;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAwB;IACjD,GAAG,UAAU;IACb,GAAG,WAAW;IACd,GAAG,YAAY;IACf,GAAG,cAAc;IACjB,GAAG,aAAa;IAChB,GAAG,UAAU;CACd,CAAC;AAEF,sDAAsD;AACtD,MAAM,UAAU,WAAW,CAAC,MAA4B;IACtD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IAChC,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;AAClE,CAAC"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { deflateRawSync, gunzipSync, gzipSync, inflateRawSync } from "node:zlib";
|
|
2
|
+
import { json, reqString, text } from "../tool-spec.js";
|
|
3
|
+
// Cap decompressed output so a small gzip/deflate "bomb" can't exhaust memory.
|
|
4
|
+
const MAX_DECOMPRESSED_BYTES = 50_000_000; // 50 MB
|
|
5
|
+
export const CODEC_TOOLS = [
|
|
6
|
+
{
|
|
7
|
+
name: "codec_base64",
|
|
8
|
+
group: "codec",
|
|
9
|
+
description: "Base64 encode or decode text. Supports standard and URL-safe (base64url) alphabets.",
|
|
10
|
+
input: {
|
|
11
|
+
mode: { type: "string", enum: ["encode", "decode"], description: "Direction." },
|
|
12
|
+
input: { type: "string", description: "Text to encode, or base64 to decode." },
|
|
13
|
+
urlSafe: {
|
|
14
|
+
type: "boolean",
|
|
15
|
+
optional: true,
|
|
16
|
+
description: "Use the URL-safe base64url alphabet (default false)."
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
handler: (args) => {
|
|
20
|
+
const mode = reqString(args, "mode");
|
|
21
|
+
const input = reqString(args, "input");
|
|
22
|
+
const urlSafe = args.urlSafe === true;
|
|
23
|
+
const encoding = urlSafe ? "base64url" : "base64";
|
|
24
|
+
if (mode === "encode") {
|
|
25
|
+
return text(Buffer.from(input, "utf8").toString(encoding));
|
|
26
|
+
}
|
|
27
|
+
return text(Buffer.from(input, encoding).toString("utf8"));
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: "codec_hex",
|
|
32
|
+
group: "codec",
|
|
33
|
+
description: "Hex (base16) encode or decode text.",
|
|
34
|
+
input: {
|
|
35
|
+
mode: { type: "string", enum: ["encode", "decode"], description: "Direction." },
|
|
36
|
+
input: { type: "string", description: "Text to encode, or hex to decode." }
|
|
37
|
+
},
|
|
38
|
+
handler: (args) => {
|
|
39
|
+
const mode = reqString(args, "mode");
|
|
40
|
+
const input = reqString(args, "input");
|
|
41
|
+
if (mode === "encode") {
|
|
42
|
+
return text(Buffer.from(input, "utf8").toString("hex"));
|
|
43
|
+
}
|
|
44
|
+
// Buffer.from(…, "hex") silently truncates at the first bad nibble — reject
|
|
45
|
+
// odd-length or non-hex input instead of returning a corrupted result.
|
|
46
|
+
const cleaned = input.replace(/\s+/g, "");
|
|
47
|
+
if (cleaned.length % 2 !== 0 || !/^[0-9a-fA-F]*$/.test(cleaned)) {
|
|
48
|
+
throw new Error("invalid hex: expected an even number of [0-9a-f] digits");
|
|
49
|
+
}
|
|
50
|
+
return text(Buffer.from(cleaned, "hex").toString("utf8"));
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: "codec_url",
|
|
55
|
+
group: "codec",
|
|
56
|
+
description: "URL-encode or decode a string (percent-encoding). Use `component` for a query value, otherwise the whole URL is treated leniently.",
|
|
57
|
+
input: {
|
|
58
|
+
mode: { type: "string", enum: ["encode", "decode"], description: "Direction." },
|
|
59
|
+
input: { type: "string", description: "Text to encode or decode." },
|
|
60
|
+
component: {
|
|
61
|
+
type: "boolean",
|
|
62
|
+
optional: true,
|
|
63
|
+
description: "Encode as a single URI component (default true)."
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
handler: (args) => {
|
|
67
|
+
const mode = reqString(args, "mode");
|
|
68
|
+
const input = reqString(args, "input");
|
|
69
|
+
const component = args.component !== false;
|
|
70
|
+
if (mode === "encode") {
|
|
71
|
+
return text(component ? encodeURIComponent(input) : encodeURI(input));
|
|
72
|
+
}
|
|
73
|
+
return text(component ? decodeURIComponent(input) : decodeURI(input));
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: "codec_jwt_decode",
|
|
78
|
+
group: "codec",
|
|
79
|
+
description: "Decode a JWT into its header and payload claims WITHOUT verifying the signature. The result is explicitly unverified — never trust it for auth decisions.",
|
|
80
|
+
input: {
|
|
81
|
+
token: { type: "string", description: "The compact JWT (header.payload.signature)." }
|
|
82
|
+
},
|
|
83
|
+
handler: (args) => {
|
|
84
|
+
const token = reqString(args, "token").trim();
|
|
85
|
+
const parts = token.split(".");
|
|
86
|
+
if (parts.length < 2) {
|
|
87
|
+
throw new Error("not a JWT: expected at least header.payload");
|
|
88
|
+
}
|
|
89
|
+
const decode = (segment) => {
|
|
90
|
+
const decoded = Buffer.from(segment, "base64url").toString("utf8");
|
|
91
|
+
return JSON.parse(decoded);
|
|
92
|
+
};
|
|
93
|
+
const header = decode(parts[0]);
|
|
94
|
+
const payload = decode(parts[1]);
|
|
95
|
+
return json({
|
|
96
|
+
header,
|
|
97
|
+
payload,
|
|
98
|
+
signaturePresent: parts.length >= 3 && parts[2].length > 0,
|
|
99
|
+
verified: false
|
|
100
|
+
}, `Decoded JWT (UNVERIFIED):\nheader: ${JSON.stringify(header)}\npayload: ${JSON.stringify(payload, null, 2)}`);
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
name: "codec_gzip",
|
|
105
|
+
group: "codec",
|
|
106
|
+
description: "Compress or decompress text with gzip or raw deflate. Compressed output is returned as base64; to decompress, pass base64 input.",
|
|
107
|
+
input: {
|
|
108
|
+
mode: { type: "string", enum: ["compress", "decompress"], description: "Direction." },
|
|
109
|
+
input: {
|
|
110
|
+
type: "string",
|
|
111
|
+
description: "Text to compress, or base64 of compressed bytes to decompress."
|
|
112
|
+
},
|
|
113
|
+
algorithm: {
|
|
114
|
+
type: "string",
|
|
115
|
+
optional: true,
|
|
116
|
+
enum: ["gzip", "deflate"],
|
|
117
|
+
description: "Compression algorithm (default gzip)."
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
handler: (args) => {
|
|
121
|
+
const mode = reqString(args, "mode");
|
|
122
|
+
const input = reqString(args, "input");
|
|
123
|
+
const algorithm = args.algorithm === "deflate" ? "deflate" : "gzip";
|
|
124
|
+
if (mode === "compress") {
|
|
125
|
+
const raw = Buffer.from(input, "utf8");
|
|
126
|
+
const out = algorithm === "gzip" ? gzipSync(raw) : deflateRawSync(raw);
|
|
127
|
+
return json({
|
|
128
|
+
algorithm,
|
|
129
|
+
base64: out.toString("base64"),
|
|
130
|
+
originalBytes: raw.length,
|
|
131
|
+
compressedBytes: out.length
|
|
132
|
+
}, out.toString("base64"));
|
|
133
|
+
}
|
|
134
|
+
const compressed = Buffer.from(input, "base64");
|
|
135
|
+
const opts = { maxOutputLength: MAX_DECOMPRESSED_BYTES };
|
|
136
|
+
const out = algorithm === "gzip" ? gunzipSync(compressed, opts) : inflateRawSync(compressed, opts);
|
|
137
|
+
return text(out.toString("utf8"));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
];
|
|
141
|
+
//# sourceMappingURL=codec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codec.js","sourceRoot":"","sources":["../../src/groups/codec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import TOML from "@iarna/toml";
|
|
2
|
+
import { JSONPath } from "jsonpath-plus";
|
|
3
|
+
import Papa from "papaparse";
|
|
4
|
+
import YAML from "yaml";
|
|
5
|
+
import { json, reqString } from "../tool-spec.js";
|
|
6
|
+
const FORMATS = ["json", "yaml", "toml", "csv"];
|
|
7
|
+
function decode(input, format) {
|
|
8
|
+
switch (format) {
|
|
9
|
+
case "json":
|
|
10
|
+
return JSON.parse(input);
|
|
11
|
+
case "yaml":
|
|
12
|
+
return YAML.parse(input);
|
|
13
|
+
case "toml":
|
|
14
|
+
return TOML.parse(input);
|
|
15
|
+
case "csv": {
|
|
16
|
+
// dynamicTyping is intentionally OFF: it would coerce "00123" → 123 (losing
|
|
17
|
+
// leading zeros) and round 64-bit IDs, silently corrupting the data. Keep
|
|
18
|
+
// every field as a string for a faithful conversion.
|
|
19
|
+
const parsed = Papa.parse(input.trim(), {
|
|
20
|
+
header: true,
|
|
21
|
+
skipEmptyLines: true,
|
|
22
|
+
dynamicTyping: false
|
|
23
|
+
});
|
|
24
|
+
if (parsed.errors.length > 0) {
|
|
25
|
+
throw new Error(`CSV parse error: ${parsed.errors[0].message}`);
|
|
26
|
+
}
|
|
27
|
+
return parsed.data;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function encode(value, format) {
|
|
32
|
+
switch (format) {
|
|
33
|
+
case "json":
|
|
34
|
+
return JSON.stringify(value, null, 2);
|
|
35
|
+
case "yaml":
|
|
36
|
+
return YAML.stringify(value);
|
|
37
|
+
case "toml":
|
|
38
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
39
|
+
throw new Error("TOML output requires a top-level object (table)");
|
|
40
|
+
}
|
|
41
|
+
return TOML.stringify(value);
|
|
42
|
+
case "csv": {
|
|
43
|
+
const rows = Array.isArray(value) ? value : [value];
|
|
44
|
+
return Papa.unparse(rows);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export const CONVERT_TOOLS = [
|
|
49
|
+
{
|
|
50
|
+
name: "convert_data",
|
|
51
|
+
group: "convert",
|
|
52
|
+
description: "Convert structured data between JSON, YAML, TOML and CSV. CSV maps to/from an array of row objects; TOML output needs a top-level object.",
|
|
53
|
+
input: {
|
|
54
|
+
input: { type: "string", description: "The source document." },
|
|
55
|
+
from: { type: "string", enum: FORMATS, description: "Source format." },
|
|
56
|
+
to: { type: "string", enum: FORMATS, description: "Target format." }
|
|
57
|
+
},
|
|
58
|
+
handler: (args) => {
|
|
59
|
+
const input = reqString(args, "input");
|
|
60
|
+
const from = reqString(args, "from");
|
|
61
|
+
const to = reqString(args, "to");
|
|
62
|
+
const value = decode(input, from);
|
|
63
|
+
const out = encode(value, to);
|
|
64
|
+
return json({ from, to, result: out }, out);
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: "convert_query",
|
|
69
|
+
group: "convert",
|
|
70
|
+
description: 'Run a JSONPath query against a JSON, YAML or TOML document and return the matching values. Example path: "$.items[*].name".',
|
|
71
|
+
input: {
|
|
72
|
+
input: { type: "string", description: "The source document." },
|
|
73
|
+
path: { type: "string", description: 'JSONPath expression, e.g. "$.store.book[*].author".' },
|
|
74
|
+
from: {
|
|
75
|
+
type: "string",
|
|
76
|
+
optional: true,
|
|
77
|
+
enum: ["json", "yaml", "toml"],
|
|
78
|
+
description: "Source format (default json)."
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
handler: (args) => {
|
|
82
|
+
const input = reqString(args, "input");
|
|
83
|
+
const path = reqString(args, "path");
|
|
84
|
+
const from = (typeof args.from === "string" ? args.from : "json");
|
|
85
|
+
const value = decode(input, from);
|
|
86
|
+
// eval: false disables script/filter expressions (`[?(...)]`) — they run
|
|
87
|
+
// arbitrary JS via the engine. `path` is model-supplied, so this keeps the
|
|
88
|
+
// tool deterministic (no sandbox escape). Standard path queries still work.
|
|
89
|
+
const matches = JSONPath({
|
|
90
|
+
path,
|
|
91
|
+
json: value,
|
|
92
|
+
wrap: true,
|
|
93
|
+
eval: false
|
|
94
|
+
});
|
|
95
|
+
return json({ path, count: matches.length, matches }, matches.length === 0 ? "(no matches)" : JSON.stringify(matches, null, 2));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
];
|
|
99
|
+
//# sourceMappingURL=convert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convert.js","sourceRoot":"","sources":["../../src/groups/convert.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { createHash, createHmac, generateKeyPairSync } from "node:crypto";
|
|
2
|
+
import { json, reqNumber, reqString, text } from "../tool-spec.js";
|
|
3
|
+
const HASH_ALGORITHMS = ["md5", "sha1", "sha256", "sha512"];
|
|
4
|
+
const BYTE_ENCODINGS = ["utf8", "hex", "base64"];
|
|
5
|
+
const OUT_ENCODINGS = ["hex", "base64", "base64url"];
|
|
6
|
+
function asBuffer(value, encoding) {
|
|
7
|
+
return Buffer.from(value, encoding);
|
|
8
|
+
}
|
|
9
|
+
// ─── UUID (v4 / v7) over injected randomness + clock ─────────────────────────
|
|
10
|
+
function uuidV4(ctx) {
|
|
11
|
+
const b = Buffer.from(ctx.randomBytes(16));
|
|
12
|
+
b[6] = (b[6] & 0x0f) | 0x40;
|
|
13
|
+
b[8] = (b[8] & 0x3f) | 0x80;
|
|
14
|
+
const h = b.toString("hex");
|
|
15
|
+
return `${h.slice(0, 8)}-${h.slice(8, 12)}-${h.slice(12, 16)}-${h.slice(16, 20)}-${h.slice(20)}`;
|
|
16
|
+
}
|
|
17
|
+
function uuidV7(ctx) {
|
|
18
|
+
const ms = ctx.now().getTime();
|
|
19
|
+
const b = Buffer.from(ctx.randomBytes(16));
|
|
20
|
+
b.writeUIntBE(ms, 0, 6); // 48-bit big-endian unix-ms timestamp
|
|
21
|
+
b[6] = (b[6] & 0x0f) | 0x70; // version 7
|
|
22
|
+
b[8] = (b[8] & 0x3f) | 0x80; // RFC 4122 variant
|
|
23
|
+
const h = b.toString("hex");
|
|
24
|
+
return `${h.slice(0, 8)}-${h.slice(8, 12)}-${h.slice(12, 16)}-${h.slice(16, 20)}-${h.slice(20)}`;
|
|
25
|
+
}
|
|
26
|
+
// ─── ULID (Crockford base32, 48-bit time + 80-bit randomness) ────────────────
|
|
27
|
+
const MAX_COUNT = 1000;
|
|
28
|
+
/** Clamp a requested identifier count to [1, MAX_COUNT] so a caller can't ask for millions. */
|
|
29
|
+
function clampCount(raw) {
|
|
30
|
+
if (typeof raw !== "number" || Number.isNaN(raw)) {
|
|
31
|
+
return 1;
|
|
32
|
+
}
|
|
33
|
+
return Math.min(MAX_COUNT, Math.max(1, Math.floor(raw)));
|
|
34
|
+
}
|
|
35
|
+
const CROCKFORD = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
36
|
+
function ulid(ctx) {
|
|
37
|
+
let ms = ctx.now().getTime();
|
|
38
|
+
let time = "";
|
|
39
|
+
for (let i = 0; i < 10; i++) {
|
|
40
|
+
time = CROCKFORD[ms % 32] + time;
|
|
41
|
+
ms = Math.floor(ms / 32);
|
|
42
|
+
}
|
|
43
|
+
let bits = 0n;
|
|
44
|
+
for (const byte of ctx.randomBytes(10)) {
|
|
45
|
+
bits = (bits << 8n) | BigInt(byte);
|
|
46
|
+
}
|
|
47
|
+
let rand = "";
|
|
48
|
+
for (let i = 0; i < 16; i++) {
|
|
49
|
+
rand = CROCKFORD[Number(bits & 31n)] + rand;
|
|
50
|
+
bits >>= 5n;
|
|
51
|
+
}
|
|
52
|
+
return time + rand;
|
|
53
|
+
}
|
|
54
|
+
export const CRYPTO_TOOLS = [
|
|
55
|
+
{
|
|
56
|
+
name: "crypto_hash",
|
|
57
|
+
group: "crypto",
|
|
58
|
+
description: "Compute a cryptographic hash digest (md5, sha1, sha256, sha512) of some input.",
|
|
59
|
+
input: {
|
|
60
|
+
algorithm: { type: "string", enum: HASH_ALGORITHMS, description: "Digest algorithm." },
|
|
61
|
+
input: { type: "string", description: "Data to hash." },
|
|
62
|
+
inputEncoding: {
|
|
63
|
+
type: "string",
|
|
64
|
+
optional: true,
|
|
65
|
+
enum: BYTE_ENCODINGS,
|
|
66
|
+
description: "How to interpret `input` (default utf8)."
|
|
67
|
+
},
|
|
68
|
+
outputEncoding: {
|
|
69
|
+
type: "string",
|
|
70
|
+
optional: true,
|
|
71
|
+
enum: OUT_ENCODINGS,
|
|
72
|
+
description: "Digest encoding (default hex)."
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
handler: (args) => {
|
|
76
|
+
const algorithm = reqString(args, "algorithm");
|
|
77
|
+
const input = reqString(args, "input");
|
|
78
|
+
const inEnc = typeof args.inputEncoding === "string" ? args.inputEncoding : "utf8";
|
|
79
|
+
const outEnc = (typeof args.outputEncoding === "string" ? args.outputEncoding : "hex");
|
|
80
|
+
const digest = createHash(algorithm).update(asBuffer(input, inEnc)).digest(outEnc);
|
|
81
|
+
return text(digest);
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: "crypto_hmac",
|
|
86
|
+
group: "crypto",
|
|
87
|
+
description: "Compute a keyed HMAC (md5, sha1, sha256, sha512) over some input.",
|
|
88
|
+
input: {
|
|
89
|
+
algorithm: { type: "string", enum: HASH_ALGORITHMS, description: "Underlying hash." },
|
|
90
|
+
key: { type: "string", description: "Secret key (utf8)." },
|
|
91
|
+
input: { type: "string", description: "Data to authenticate (utf8)." },
|
|
92
|
+
outputEncoding: {
|
|
93
|
+
type: "string",
|
|
94
|
+
optional: true,
|
|
95
|
+
enum: OUT_ENCODINGS,
|
|
96
|
+
description: "Digest encoding (default hex)."
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
handler: (args) => {
|
|
100
|
+
const algorithm = reqString(args, "algorithm");
|
|
101
|
+
const key = reqString(args, "key");
|
|
102
|
+
const input = reqString(args, "input");
|
|
103
|
+
const outEnc = (typeof args.outputEncoding === "string" ? args.outputEncoding : "hex");
|
|
104
|
+
return text(createHmac(algorithm, key).update(input, "utf8").digest(outEnc));
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: "crypto_uuid",
|
|
109
|
+
group: "crypto",
|
|
110
|
+
description: "Generate a UUID. Version 4 is random; version 7 is time-ordered (sortable, good for database keys).",
|
|
111
|
+
input: {
|
|
112
|
+
version: {
|
|
113
|
+
type: "string",
|
|
114
|
+
optional: true,
|
|
115
|
+
enum: ["4", "7"],
|
|
116
|
+
description: "UUID version (default 4)."
|
|
117
|
+
},
|
|
118
|
+
count: { type: "number", optional: true, description: "How many to generate (default 1)." }
|
|
119
|
+
},
|
|
120
|
+
handler: (args, ctx) => {
|
|
121
|
+
const version = args.version === "7" ? "7" : "4";
|
|
122
|
+
const count = clampCount(args.count);
|
|
123
|
+
const gen = version === "7" ? () => uuidV7(ctx) : () => uuidV4(ctx);
|
|
124
|
+
const ids = Array.from({ length: count }, gen);
|
|
125
|
+
return count === 1 ? text(ids[0]) : json({ version, ids }, ids.join("\n"));
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
name: "crypto_ulid",
|
|
130
|
+
group: "crypto",
|
|
131
|
+
description: "Generate a ULID — a 26-char, lexicographically-sortable, Crockford-base32 identifier (48-bit timestamp + 80-bit randomness).",
|
|
132
|
+
input: {
|
|
133
|
+
count: { type: "number", optional: true, description: "How many to generate (default 1)." }
|
|
134
|
+
},
|
|
135
|
+
handler: (args, ctx) => {
|
|
136
|
+
const count = clampCount(args.count);
|
|
137
|
+
const ids = Array.from({ length: count }, () => ulid(ctx));
|
|
138
|
+
return count === 1 ? text(ids[0]) : json({ ids }, ids.join("\n"));
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: "crypto_random",
|
|
143
|
+
group: "crypto",
|
|
144
|
+
description: "Generate cryptographically-strong random bytes, encoded as hex, base64 or base64url.",
|
|
145
|
+
input: {
|
|
146
|
+
bytes: { type: "number", description: "Number of random bytes (1–4096)." },
|
|
147
|
+
encoding: {
|
|
148
|
+
type: "string",
|
|
149
|
+
optional: true,
|
|
150
|
+
enum: OUT_ENCODINGS,
|
|
151
|
+
description: "Output encoding (default hex)."
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
handler: (args, ctx) => {
|
|
155
|
+
const bytes = reqNumber(args, "bytes");
|
|
156
|
+
if (!Number.isInteger(bytes) || bytes < 1 || bytes > 4096) {
|
|
157
|
+
throw new Error('"bytes" must be an integer in 1–4096');
|
|
158
|
+
}
|
|
159
|
+
const encoding = (typeof args.encoding === "string" ? args.encoding : "hex");
|
|
160
|
+
return text(Buffer.from(ctx.randomBytes(bytes)).toString(encoding));
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
name: "crypto_keypair",
|
|
165
|
+
group: "crypto",
|
|
166
|
+
description: "Generate an asymmetric keypair (ed25519, rsa, or ec/P-256) and return the PEM-encoded public and private keys.",
|
|
167
|
+
input: {
|
|
168
|
+
type: {
|
|
169
|
+
type: "string",
|
|
170
|
+
optional: true,
|
|
171
|
+
enum: ["ed25519", "rsa", "ec"],
|
|
172
|
+
description: "Key type (default ed25519)."
|
|
173
|
+
},
|
|
174
|
+
modulusLength: {
|
|
175
|
+
type: "number",
|
|
176
|
+
optional: true,
|
|
177
|
+
description: "RSA modulus bits (default 2048; rsa only)."
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
handler: (args) => {
|
|
181
|
+
const type = typeof args.type === "string" ? args.type : "ed25519";
|
|
182
|
+
const enc = {
|
|
183
|
+
publicKeyEncoding: { type: "spki", format: "pem" },
|
|
184
|
+
privateKeyEncoding: { type: "pkcs8", format: "pem" }
|
|
185
|
+
};
|
|
186
|
+
let pair;
|
|
187
|
+
if (type === "rsa") {
|
|
188
|
+
const modulusLength = typeof args.modulusLength === "number" ? Math.floor(args.modulusLength) : 2048;
|
|
189
|
+
// generateKeyPairSync blocks the event loop; a huge modulus is a DoS.
|
|
190
|
+
if (modulusLength < 1024 || modulusLength > 4096) {
|
|
191
|
+
throw new Error('"modulusLength" must be between 1024 and 4096');
|
|
192
|
+
}
|
|
193
|
+
pair = generateKeyPairSync("rsa", { modulusLength, ...enc });
|
|
194
|
+
}
|
|
195
|
+
else if (type === "ec") {
|
|
196
|
+
pair = generateKeyPairSync("ec", { namedCurve: "P-256", ...enc });
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
pair = generateKeyPairSync("ed25519", enc);
|
|
200
|
+
}
|
|
201
|
+
return json({ type, publicKey: pair.publicKey, privateKey: pair.privateKey }, `${pair.publicKey}\n${pair.privateKey}`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
];
|
|
205
|
+
//# sourceMappingURL=crypto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/groups/crypto.ts"],"names":[],"mappings":"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"}
|