add config schema generation for IDE autocomplete
- scripts/gen-config-schema.ts: generates JSON schema + TypeScript types from ClawdbotSchema - `pnpm schema:gen` - allow $schema key in config for IDE integration - Users can now add "$schema": "./schemas/clawdbot.schema.json" to their clawdbot.json for autocomplete without validation errors. - Document schema generation in configuration and scripts docs
This commit is contained in:
parent
28f8d00e9f
commit
34f193c657
2
.gitignore
vendored
2
.gitignore
vendored
@ -71,3 +71,5 @@ USER.md
|
||||
|
||||
# local tooling
|
||||
.serena/
|
||||
schemas/*.d.ts
|
||||
schemas/*.schema.json
|
||||
|
||||
@ -41,6 +41,27 @@ stay schema-driven across apps without hard-coded forms.
|
||||
Hints (labels, grouping, sensitive fields) ship alongside the schema so clients can render
|
||||
better forms without hard-coding config knowledge.
|
||||
|
||||
### IDE autocomplete
|
||||
|
||||
Get full autocomplete and validation for `openclaw.json` in VS Code, Cursor, and other
|
||||
JSON-Schema-aware editors by pointing to the generated schema:
|
||||
|
||||
```json5
|
||||
{
|
||||
"$schema": "./schemas/moltbot.schema.json",
|
||||
// ... rest of your config
|
||||
}
|
||||
```
|
||||
|
||||
Generate the schema (and a companion `.d.ts`) with:
|
||||
|
||||
```bash
|
||||
pnpm schema:gen
|
||||
```
|
||||
|
||||
This writes `schemas/moltbot.schema.json` and `schemas/moltbot.d.ts` from the Zod source schema.
|
||||
Both files are git-ignored; regenerate after pulling config schema changes.
|
||||
|
||||
## Apply + restart (RPC)
|
||||
|
||||
Use `config.apply` to validate + write the full config and restart the Gateway in one step.
|
||||
|
||||
@ -25,6 +25,12 @@ Use these when a task is clearly tied to a script; otherwise prefer the CLI.
|
||||
Auth monitoring scripts are documented here:
|
||||
[/automation/auth-monitoring](/automation/auth-monitoring)
|
||||
|
||||
## Config schema generation
|
||||
|
||||
- `scripts/gen-config-schema.ts`: generates `schemas/moltbot.schema.json` (JSON Schema) and `schemas/moltbot.d.ts` (TypeScript types) from the Zod config schema.
|
||||
- Run via `pnpm schema:gen`. Both output files are git-ignored.
|
||||
- See [IDE autocomplete](/gateway/configuration#ide-autocomplete) for usage.
|
||||
|
||||
## When adding scripts
|
||||
|
||||
- Keep scripts focused and documented.
|
||||
|
||||
@ -143,6 +143,7 @@
|
||||
"protocol:gen": "node --import tsx scripts/protocol-gen.ts",
|
||||
"protocol:gen:swift": "node --import tsx scripts/protocol-gen-swift.ts",
|
||||
"protocol:check": "pnpm protocol:gen && pnpm protocol:gen:swift && git diff --exit-code -- dist/protocol.schema.json apps/macos/Sources/OpenClawProtocol/GatewayModels.swift",
|
||||
"schema:gen": "node --import tsx scripts/gen-config-schema.ts",
|
||||
"canvas:a2ui:bundle": "bash scripts/bundle-a2ui.sh",
|
||||
"check:loc": "node --import tsx scripts/check-ts-max-loc.ts --max 500"
|
||||
},
|
||||
@ -227,6 +228,7 @@
|
||||
"@typescript/native-preview": "7.0.0-dev.20260124.1",
|
||||
"@vitest/coverage-v8": "^4.0.18",
|
||||
"docx-preview": "^0.3.7",
|
||||
"json-schema-to-typescript": "^15.0.4",
|
||||
"lit": "^3.3.2",
|
||||
"lucide": "^0.563.0",
|
||||
"ollama": "^0.6.3",
|
||||
|
||||
63
pnpm-lock.yaml
generated
63
pnpm-lock.yaml
generated
@ -215,6 +215,9 @@ importers:
|
||||
docx-preview:
|
||||
specifier: ^0.3.7
|
||||
version: 0.3.7
|
||||
json-schema-to-typescript:
|
||||
specifier: ^15.0.4
|
||||
version: 15.0.4
|
||||
lit:
|
||||
specifier: ^3.3.2
|
||||
version: 3.3.2
|
||||
@ -534,6 +537,10 @@ packages:
|
||||
zod:
|
||||
optional: true
|
||||
|
||||
'@apidevtools/json-schema-ref-parser@11.9.3':
|
||||
resolution: {integrity: sha512-60vepv88RwcJtSHrD6MjIL6Ta3SOYbgfnkHb+ppAVK+o9mXprRtulx7VlRl3lN3bbvysAfCS7WMVfhUYemB0IQ==}
|
||||
engines: {node: '>= 16'}
|
||||
|
||||
'@aws-crypto/crc32@5.2.0':
|
||||
resolution: {integrity: sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==}
|
||||
engines: {node: '>=16.0.0'}
|
||||
@ -1268,6 +1275,9 @@ packages:
|
||||
'@js-sdsl/ordered-map@4.4.2':
|
||||
resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==}
|
||||
|
||||
'@jsdevtools/ono@7.1.3':
|
||||
resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==}
|
||||
|
||||
'@keyv/bigmap@1.3.1':
|
||||
resolution: {integrity: sha512-WbzE9sdmQtKy8vrNPa9BRnwZh5UF4s1KTmSK0KUVLo3eff5BlQNNWDnFOouNpKfPKDnms9xynJjsMYjMaT/aFQ==}
|
||||
engines: {node: '>= 18'}
|
||||
@ -2716,12 +2726,18 @@ packages:
|
||||
'@types/http-errors@2.0.5':
|
||||
resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==}
|
||||
|
||||
'@types/json-schema@7.0.15':
|
||||
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
|
||||
|
||||
'@types/jsonwebtoken@9.0.10':
|
||||
resolution: {integrity: sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==}
|
||||
|
||||
'@types/linkify-it@5.0.0':
|
||||
resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==}
|
||||
|
||||
'@types/lodash@4.17.23':
|
||||
resolution: {integrity: sha512-RDvF6wTulMPjrNdCoYRC8gNR880JNGT8uB+REUpC2Ns4pRqQJhGz90wh7rgdXDPpCczF3VGktDuFGVnz8zP7HA==}
|
||||
|
||||
'@types/long@4.0.2':
|
||||
resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==}
|
||||
|
||||
@ -3982,6 +3998,10 @@ packages:
|
||||
js-tokens@9.0.1:
|
||||
resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==}
|
||||
|
||||
js-yaml@4.1.1:
|
||||
resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
|
||||
hasBin: true
|
||||
|
||||
jsbn@0.1.1:
|
||||
resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==}
|
||||
|
||||
@ -3996,6 +4016,11 @@ packages:
|
||||
resolution: {integrity: sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==}
|
||||
engines: {node: '>=16'}
|
||||
|
||||
json-schema-to-typescript@15.0.4:
|
||||
resolution: {integrity: sha512-Su9oK8DR4xCmDsLlyvadkXzX6+GGXJpbhwoLtOGArAG61dvbW4YQmSEno2y66ahpIdmLMg6YUf/QHLgiwvkrHQ==}
|
||||
engines: {node: '>=16.0.0'}
|
||||
hasBin: true
|
||||
|
||||
json-schema-traverse@0.4.1:
|
||||
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
|
||||
|
||||
@ -4723,6 +4748,11 @@ packages:
|
||||
resolution: {integrity: sha512-d+JFcLM17njZaOLkv6SCev7uoLaBtfK86vMUXhW1Z4glPWh4jozno9APvW/XKFJ3CCxVoC7OL38BqRydtu5nGg==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
prettier@3.8.1:
|
||||
resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==}
|
||||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
|
||||
pretty-bytes@6.1.1:
|
||||
resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==}
|
||||
engines: {node: ^14.13.1 || >=16.0.0}
|
||||
@ -5589,6 +5619,12 @@ snapshots:
|
||||
optionalDependencies:
|
||||
zod: 4.3.6
|
||||
|
||||
'@apidevtools/json-schema-ref-parser@11.9.3':
|
||||
dependencies:
|
||||
'@jsdevtools/ono': 7.1.3
|
||||
'@types/json-schema': 7.0.15
|
||||
js-yaml: 4.1.1
|
||||
|
||||
'@aws-crypto/crc32@5.2.0':
|
||||
dependencies:
|
||||
'@aws-crypto/util': 5.2.0
|
||||
@ -6831,6 +6867,8 @@ snapshots:
|
||||
|
||||
'@js-sdsl/ordered-map@4.4.2': {}
|
||||
|
||||
'@jsdevtools/ono@7.1.3': {}
|
||||
|
||||
'@keyv/bigmap@1.3.1(keyv@5.6.0)':
|
||||
dependencies:
|
||||
hashery: 1.4.0
|
||||
@ -8493,6 +8531,8 @@ snapshots:
|
||||
|
||||
'@types/http-errors@2.0.5': {}
|
||||
|
||||
'@types/json-schema@7.0.15': {}
|
||||
|
||||
'@types/jsonwebtoken@9.0.10':
|
||||
dependencies:
|
||||
'@types/ms': 2.1.0
|
||||
@ -8500,6 +8540,8 @@ snapshots:
|
||||
|
||||
'@types/linkify-it@5.0.0': {}
|
||||
|
||||
'@types/lodash@4.17.23': {}
|
||||
|
||||
'@types/long@4.0.2': {}
|
||||
|
||||
'@types/markdown-it@14.1.2':
|
||||
@ -9985,6 +10027,10 @@ snapshots:
|
||||
|
||||
js-tokens@9.0.1: {}
|
||||
|
||||
js-yaml@4.1.1:
|
||||
dependencies:
|
||||
argparse: 2.0.1
|
||||
|
||||
jsbn@0.1.1: {}
|
||||
|
||||
json-bigint@1.0.0:
|
||||
@ -9998,6 +10044,18 @@ snapshots:
|
||||
'@babel/runtime': 7.28.6
|
||||
ts-algebra: 2.0.0
|
||||
|
||||
json-schema-to-typescript@15.0.4:
|
||||
dependencies:
|
||||
'@apidevtools/json-schema-ref-parser': 11.9.3
|
||||
'@types/json-schema': 7.0.15
|
||||
'@types/lodash': 4.17.23
|
||||
is-glob: 4.0.3
|
||||
js-yaml: 4.1.1
|
||||
lodash: 4.17.23
|
||||
minimist: 1.2.8
|
||||
prettier: 3.8.1
|
||||
tinyglobby: 0.2.15
|
||||
|
||||
json-schema-traverse@0.4.1: {}
|
||||
|
||||
json-schema-traverse@1.0.0: {}
|
||||
@ -10318,8 +10376,7 @@ snapshots:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.2
|
||||
|
||||
minimist@1.2.8:
|
||||
optional: true
|
||||
minimist@1.2.8: {}
|
||||
|
||||
minipass@7.1.2: {}
|
||||
|
||||
@ -10749,6 +10806,8 @@ snapshots:
|
||||
|
||||
postgres@3.4.8: {}
|
||||
|
||||
prettier@3.8.1: {}
|
||||
|
||||
pretty-bytes@6.1.1:
|
||||
optional: true
|
||||
|
||||
|
||||
50
scripts/gen-config-schema.ts
Normal file
50
scripts/gen-config-schema.ts
Normal file
@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env bun
|
||||
/**
|
||||
* Generates schemas/clawdbot.schema.json and schemas/clawdbot.d.ts
|
||||
* from the zod schema source.
|
||||
*
|
||||
* Usage: bun scripts/gen-config-schema.ts
|
||||
*/
|
||||
import { writeFile, mkdir } from "node:fs/promises";
|
||||
import { dirname, join } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { compile } from "json-schema-to-typescript";
|
||||
import { OpenClawSchema } from "../src/config/zod-schema.js";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const rootDir = join(__dirname, "..");
|
||||
const schemasDir = join(rootDir, "schemas");
|
||||
|
||||
async function main() {
|
||||
await mkdir(schemasDir, { recursive: true });
|
||||
|
||||
// Generate JSON schema from zod
|
||||
const jsonSchema = OpenClawSchema.toJSONSchema({
|
||||
target: "draft-07",
|
||||
unrepresentable: "any",
|
||||
});
|
||||
|
||||
const schemaPath = join(schemasDir, "openclaw.schema.json");
|
||||
await writeFile(schemaPath, JSON.stringify(jsonSchema, null, 2));
|
||||
console.log(`Wrote ${schemaPath}`);
|
||||
|
||||
// Generate TypeScript types from JSON schema
|
||||
const dts = await compile(jsonSchema as Record<string, unknown>, "OpenClawConfig", {
|
||||
bannerComment: `/* eslint-disable */
|
||||
/**
|
||||
* This file was automatically generated by json-schema-to-typescript.
|
||||
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
|
||||
* and run json-schema-to-typescript to regenerate this file.
|
||||
*/`,
|
||||
additionalProperties: false,
|
||||
});
|
||||
|
||||
const dtsPath = join(schemasDir, "openclaw.d.ts");
|
||||
await writeFile(dtsPath, dts);
|
||||
console.log(`Wrote ${dtsPath}`);
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
@ -29,6 +29,7 @@ const NodeHostSchema = z
|
||||
|
||||
export const OpenClawSchema = z
|
||||
.object({
|
||||
$schema: z.string().optional(),
|
||||
meta: z
|
||||
.object({
|
||||
lastTouchedVersion: z.string().optional(),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user