feat: expand api snapshots and schema tooling

This commit is contained in:
Nathan Flurry 2026-01-26 00:13:17 -08:00
parent ee014b0838
commit 011ca27287
72 changed files with 29480 additions and 1081 deletions

View file

@ -0,0 +1,153 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://sandbox-agent/schemas/amp.json",
"title": "AMP Code SDK Schema",
"definitions": {
"StreamJSONMessage": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"message",
"tool_call",
"tool_result",
"error",
"done"
]
},
"id": {
"type": "string"
},
"content": {
"type": "string"
},
"tool_call": {
"$ref": "#/definitions/ToolCall"
},
"error": {
"type": "string"
}
},
"required": [
"type"
]
},
"AmpOptions": {
"type": "object",
"properties": {
"model": {
"type": "string"
},
"apiKey": {
"type": "string"
},
"baseURL": {
"type": "string"
},
"maxTokens": {
"type": "number"
},
"temperature": {
"type": "number"
},
"systemPrompt": {
"type": "string"
},
"tools": {
"type": "array",
"items": {
"type": "object"
}
},
"workingDirectory": {
"type": "string"
},
"permissionRules": {
"type": "array",
"items": {
"$ref": "#/definitions/PermissionRule"
}
}
}
},
"PermissionRule": {
"type": "object",
"properties": {
"tool": {
"type": "string"
},
"action": {
"type": "string",
"enum": [
"allow",
"deny",
"ask"
]
},
"pattern": {
"type": "string"
},
"description": {
"type": "string"
}
},
"required": [
"tool",
"action"
]
},
"Message": {
"type": "object",
"properties": {
"role": {
"type": "string",
"enum": [
"user",
"assistant",
"system"
]
},
"content": {
"type": "string"
},
"tool_calls": {
"type": "array",
"items": {
"$ref": "#/definitions/ToolCall"
}
}
},
"required": [
"role",
"content"
]
},
"ToolCall": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"arguments": {
"oneOf": [
{
"type": "string"
},
{
"type": "object"
}
]
}
},
"required": [
"id",
"name",
"arguments"
]
}
}
}

View file

@ -0,0 +1,182 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://sandbox-agent/schemas/claude.json",
"title": "Claude Code SDK Schema",
"definitions": {
"SDKMessage": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"user",
"assistant",
"result"
]
},
"content": {
"type": "string"
},
"timestamp": {
"type": "string",
"format": "date-time"
}
},
"required": [
"type"
]
},
"SDKResultMessage": {
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "result"
},
"result": {
"type": "object"
},
"error": {
"type": "string"
},
"duration_ms": {
"type": "number"
}
},
"required": [
"type"
]
},
"Options": {
"type": "object",
"properties": {
"model": {
"type": "string"
},
"maxTokens": {
"type": "number"
},
"temperature": {
"type": "number"
},
"systemPrompt": {
"type": "string"
},
"tools": {
"type": "array",
"items": {
"type": "string"
}
},
"allowedTools": {
"type": "array",
"items": {
"type": "string"
}
},
"workingDirectory": {
"type": "string"
}
}
},
"BashInput": {
"type": "object",
"properties": {
"command": {
"type": "string"
},
"timeout": {
"type": "number"
},
"workingDirectory": {
"type": "string"
}
},
"required": [
"command"
]
},
"FileEditInput": {
"type": "object",
"properties": {
"path": {
"type": "string"
},
"oldText": {
"type": "string"
},
"newText": {
"type": "string"
}
},
"required": [
"path",
"oldText",
"newText"
]
},
"FileReadInput": {
"type": "object",
"properties": {
"path": {
"type": "string"
},
"startLine": {
"type": "number"
},
"endLine": {
"type": "number"
}
},
"required": [
"path"
]
},
"FileWriteInput": {
"type": "object",
"properties": {
"path": {
"type": "string"
},
"content": {
"type": "string"
}
},
"required": [
"path",
"content"
]
},
"GlobInput": {
"type": "object",
"properties": {
"pattern": {
"type": "string"
},
"path": {
"type": "string"
}
},
"required": [
"pattern"
]
},
"GrepInput": {
"type": "object",
"properties": {
"pattern": {
"type": "string"
},
"path": {
"type": "string"
},
"include": {
"type": "string"
}
},
"required": [
"pattern"
]
}
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

695
resources/agent-schemas/deno.lock generated Normal file
View file

@ -0,0 +1,695 @@
{
"version": "5",
"specifiers": {
"npm:@anthropic-ai/claude-code@latest": "2.1.19",
"npm:@openai/codex@latest": "0.91.0",
"npm:@types/node@22": "22.19.7",
"npm:cheerio@1": "1.2.0",
"npm:ts-json-schema-generator@^2.4.0": "2.4.0",
"npm:tsx@^4.19.0": "4.21.0",
"npm:typescript@^5.7.0": "5.9.3"
},
"npm": {
"@anthropic-ai/claude-code@2.1.19": {
"integrity": "sha512-/bUlQuX/6nKr1Zqfi/9Q6xf7WonUBk72ZfKKENU4WVrIFWqTv/0JJsoW/dHol9QBNHvyfKIeBbYu4avHNRAnuQ==",
"optionalDependencies": [
"@img/sharp-darwin-arm64",
"@img/sharp-darwin-x64",
"@img/sharp-linux-arm",
"@img/sharp-linux-arm64",
"@img/sharp-linux-x64",
"@img/sharp-linuxmusl-arm64",
"@img/sharp-linuxmusl-x64",
"@img/sharp-win32-x64"
],
"bin": true
},
"@esbuild/aix-ppc64@0.27.2": {
"integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==",
"os": ["aix"],
"cpu": ["ppc64"]
},
"@esbuild/android-arm64@0.27.2": {
"integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==",
"os": ["android"],
"cpu": ["arm64"]
},
"@esbuild/android-arm@0.27.2": {
"integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==",
"os": ["android"],
"cpu": ["arm"]
},
"@esbuild/android-x64@0.27.2": {
"integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==",
"os": ["android"],
"cpu": ["x64"]
},
"@esbuild/darwin-arm64@0.27.2": {
"integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==",
"os": ["darwin"],
"cpu": ["arm64"]
},
"@esbuild/darwin-x64@0.27.2": {
"integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==",
"os": ["darwin"],
"cpu": ["x64"]
},
"@esbuild/freebsd-arm64@0.27.2": {
"integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==",
"os": ["freebsd"],
"cpu": ["arm64"]
},
"@esbuild/freebsd-x64@0.27.2": {
"integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==",
"os": ["freebsd"],
"cpu": ["x64"]
},
"@esbuild/linux-arm64@0.27.2": {
"integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==",
"os": ["linux"],
"cpu": ["arm64"]
},
"@esbuild/linux-arm@0.27.2": {
"integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==",
"os": ["linux"],
"cpu": ["arm"]
},
"@esbuild/linux-ia32@0.27.2": {
"integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==",
"os": ["linux"],
"cpu": ["ia32"]
},
"@esbuild/linux-loong64@0.27.2": {
"integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==",
"os": ["linux"],
"cpu": ["loong64"]
},
"@esbuild/linux-mips64el@0.27.2": {
"integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==",
"os": ["linux"],
"cpu": ["mips64el"]
},
"@esbuild/linux-ppc64@0.27.2": {
"integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==",
"os": ["linux"],
"cpu": ["ppc64"]
},
"@esbuild/linux-riscv64@0.27.2": {
"integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==",
"os": ["linux"],
"cpu": ["riscv64"]
},
"@esbuild/linux-s390x@0.27.2": {
"integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==",
"os": ["linux"],
"cpu": ["s390x"]
},
"@esbuild/linux-x64@0.27.2": {
"integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==",
"os": ["linux"],
"cpu": ["x64"]
},
"@esbuild/netbsd-arm64@0.27.2": {
"integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==",
"os": ["netbsd"],
"cpu": ["arm64"]
},
"@esbuild/netbsd-x64@0.27.2": {
"integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==",
"os": ["netbsd"],
"cpu": ["x64"]
},
"@esbuild/openbsd-arm64@0.27.2": {
"integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==",
"os": ["openbsd"],
"cpu": ["arm64"]
},
"@esbuild/openbsd-x64@0.27.2": {
"integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==",
"os": ["openbsd"],
"cpu": ["x64"]
},
"@esbuild/openharmony-arm64@0.27.2": {
"integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==",
"os": ["openharmony"],
"cpu": ["arm64"]
},
"@esbuild/sunos-x64@0.27.2": {
"integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==",
"os": ["sunos"],
"cpu": ["x64"]
},
"@esbuild/win32-arm64@0.27.2": {
"integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==",
"os": ["win32"],
"cpu": ["arm64"]
},
"@esbuild/win32-ia32@0.27.2": {
"integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==",
"os": ["win32"],
"cpu": ["ia32"]
},
"@esbuild/win32-x64@0.27.2": {
"integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==",
"os": ["win32"],
"cpu": ["x64"]
},
"@img/sharp-darwin-arm64@0.33.5": {
"integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==",
"optionalDependencies": [
"@img/sharp-libvips-darwin-arm64"
],
"os": ["darwin"],
"cpu": ["arm64"]
},
"@img/sharp-darwin-x64@0.33.5": {
"integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==",
"optionalDependencies": [
"@img/sharp-libvips-darwin-x64"
],
"os": ["darwin"],
"cpu": ["x64"]
},
"@img/sharp-libvips-darwin-arm64@1.0.4": {
"integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==",
"os": ["darwin"],
"cpu": ["arm64"]
},
"@img/sharp-libvips-darwin-x64@1.0.4": {
"integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==",
"os": ["darwin"],
"cpu": ["x64"]
},
"@img/sharp-libvips-linux-arm64@1.0.4": {
"integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==",
"os": ["linux"],
"cpu": ["arm64"]
},
"@img/sharp-libvips-linux-arm@1.0.5": {
"integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==",
"os": ["linux"],
"cpu": ["arm"]
},
"@img/sharp-libvips-linux-x64@1.0.4": {
"integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==",
"os": ["linux"],
"cpu": ["x64"]
},
"@img/sharp-libvips-linuxmusl-arm64@1.0.4": {
"integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==",
"os": ["linux"],
"cpu": ["arm64"]
},
"@img/sharp-libvips-linuxmusl-x64@1.0.4": {
"integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==",
"os": ["linux"],
"cpu": ["x64"]
},
"@img/sharp-linux-arm64@0.33.5": {
"integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==",
"optionalDependencies": [
"@img/sharp-libvips-linux-arm64"
],
"os": ["linux"],
"cpu": ["arm64"]
},
"@img/sharp-linux-arm@0.33.5": {
"integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==",
"optionalDependencies": [
"@img/sharp-libvips-linux-arm"
],
"os": ["linux"],
"cpu": ["arm"]
},
"@img/sharp-linux-x64@0.33.5": {
"integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==",
"optionalDependencies": [
"@img/sharp-libvips-linux-x64"
],
"os": ["linux"],
"cpu": ["x64"]
},
"@img/sharp-linuxmusl-arm64@0.33.5": {
"integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==",
"optionalDependencies": [
"@img/sharp-libvips-linuxmusl-arm64"
],
"os": ["linux"],
"cpu": ["arm64"]
},
"@img/sharp-linuxmusl-x64@0.33.5": {
"integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==",
"optionalDependencies": [
"@img/sharp-libvips-linuxmusl-x64"
],
"os": ["linux"],
"cpu": ["x64"]
},
"@img/sharp-win32-x64@0.33.5": {
"integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==",
"os": ["win32"],
"cpu": ["x64"]
},
"@isaacs/balanced-match@4.0.1": {
"integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ=="
},
"@isaacs/brace-expansion@5.0.0": {
"integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==",
"dependencies": [
"@isaacs/balanced-match"
]
},
"@isaacs/cliui@8.0.2": {
"integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
"dependencies": [
"string-width@5.1.2",
"string-width-cjs@npm:string-width@4.2.3",
"strip-ansi@7.1.2",
"strip-ansi-cjs@npm:strip-ansi@6.0.1",
"wrap-ansi@8.1.0",
"wrap-ansi-cjs@npm:wrap-ansi@7.0.0"
]
},
"@openai/codex@0.91.0": {
"integrity": "sha512-eRLRg0+uM0g0iW+Ca5VedBk+laslLcq93Hf6rbFtv+gLb4+aMib2UPdvlDlvvCVkBMbvE8ckY/cju+iOOuKCNA==",
"bin": true
},
"@types/json-schema@7.0.15": {
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="
},
"@types/node@22.19.7": {
"integrity": "sha512-MciR4AKGHWl7xwxkBa6xUGxQJ4VBOmPTF7sL+iGzuahOFaO0jHCsuEfS80pan1ef4gWId1oWOweIhrDEYLuaOw==",
"dependencies": [
"undici-types"
]
},
"ansi-regex@5.0.1": {
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
},
"ansi-regex@6.2.2": {
"integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="
},
"ansi-styles@4.3.0": {
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dependencies": [
"color-convert"
]
},
"ansi-styles@6.2.3": {
"integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="
},
"boolbase@1.0.0": {
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
},
"cheerio-select@2.1.0": {
"integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
"dependencies": [
"boolbase",
"css-select",
"css-what",
"domelementtype",
"domhandler",
"domutils"
]
},
"cheerio@1.2.0": {
"integrity": "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==",
"dependencies": [
"cheerio-select",
"dom-serializer",
"domhandler",
"domutils",
"encoding-sniffer",
"htmlparser2",
"parse5",
"parse5-htmlparser2-tree-adapter",
"parse5-parser-stream",
"undici",
"whatwg-mimetype"
]
},
"color-convert@2.0.1": {
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dependencies": [
"color-name"
]
},
"color-name@1.1.4": {
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"commander@13.1.0": {
"integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw=="
},
"cross-spawn@7.0.6": {
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dependencies": [
"path-key",
"shebang-command",
"which"
]
},
"css-select@5.2.2": {
"integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==",
"dependencies": [
"boolbase",
"css-what",
"domhandler",
"domutils",
"nth-check"
]
},
"css-what@6.2.2": {
"integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="
},
"dom-serializer@2.0.0": {
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"dependencies": [
"domelementtype",
"domhandler",
"entities@4.5.0"
]
},
"domelementtype@2.3.0": {
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="
},
"domhandler@5.0.3": {
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dependencies": [
"domelementtype"
]
},
"domutils@3.2.2": {
"integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
"dependencies": [
"dom-serializer",
"domelementtype",
"domhandler"
]
},
"eastasianwidth@0.2.0": {
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
},
"emoji-regex@8.0.0": {
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"emoji-regex@9.2.2": {
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
},
"encoding-sniffer@0.2.1": {
"integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==",
"dependencies": [
"iconv-lite",
"whatwg-encoding"
]
},
"entities@4.5.0": {
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="
},
"entities@6.0.1": {
"integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="
},
"entities@7.0.1": {
"integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="
},
"esbuild@0.27.2": {
"integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==",
"optionalDependencies": [
"@esbuild/aix-ppc64",
"@esbuild/android-arm",
"@esbuild/android-arm64",
"@esbuild/android-x64",
"@esbuild/darwin-arm64",
"@esbuild/darwin-x64",
"@esbuild/freebsd-arm64",
"@esbuild/freebsd-x64",
"@esbuild/linux-arm",
"@esbuild/linux-arm64",
"@esbuild/linux-ia32",
"@esbuild/linux-loong64",
"@esbuild/linux-mips64el",
"@esbuild/linux-ppc64",
"@esbuild/linux-riscv64",
"@esbuild/linux-s390x",
"@esbuild/linux-x64",
"@esbuild/netbsd-arm64",
"@esbuild/netbsd-x64",
"@esbuild/openbsd-arm64",
"@esbuild/openbsd-x64",
"@esbuild/openharmony-arm64",
"@esbuild/sunos-x64",
"@esbuild/win32-arm64",
"@esbuild/win32-ia32",
"@esbuild/win32-x64"
],
"scripts": true,
"bin": true
},
"foreground-child@3.3.1": {
"integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
"dependencies": [
"cross-spawn",
"signal-exit"
]
},
"fsevents@2.3.3": {
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"os": ["darwin"],
"scripts": true
},
"get-tsconfig@4.13.0": {
"integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==",
"dependencies": [
"resolve-pkg-maps"
]
},
"glob@11.1.0": {
"integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==",
"dependencies": [
"foreground-child",
"jackspeak",
"minimatch",
"minipass",
"package-json-from-dist",
"path-scurry"
],
"bin": true
},
"htmlparser2@10.1.0": {
"integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==",
"dependencies": [
"domelementtype",
"domhandler",
"domutils",
"entities@7.0.1"
]
},
"iconv-lite@0.6.3": {
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"dependencies": [
"safer-buffer"
]
},
"is-fullwidth-code-point@3.0.0": {
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
},
"isexe@2.0.0": {
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
},
"jackspeak@4.1.1": {
"integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==",
"dependencies": [
"@isaacs/cliui"
]
},
"json5@2.2.3": {
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"bin": true
},
"lru-cache@11.2.5": {
"integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw=="
},
"minimatch@10.1.1": {
"integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==",
"dependencies": [
"@isaacs/brace-expansion"
]
},
"minipass@7.1.2": {
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="
},
"normalize-path@3.0.0": {
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
},
"nth-check@2.1.1": {
"integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
"dependencies": [
"boolbase"
]
},
"package-json-from-dist@1.0.1": {
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="
},
"parse5-htmlparser2-tree-adapter@7.1.0": {
"integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==",
"dependencies": [
"domhandler",
"parse5"
]
},
"parse5-parser-stream@7.1.2": {
"integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==",
"dependencies": [
"parse5"
]
},
"parse5@7.3.0": {
"integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
"dependencies": [
"entities@6.0.1"
]
},
"path-key@3.1.1": {
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
},
"path-scurry@2.0.1": {
"integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==",
"dependencies": [
"lru-cache",
"minipass"
]
},
"resolve-pkg-maps@1.0.0": {
"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="
},
"safe-stable-stringify@2.5.0": {
"integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA=="
},
"safer-buffer@2.1.2": {
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"shebang-command@2.0.0": {
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dependencies": [
"shebang-regex"
]
},
"shebang-regex@3.0.0": {
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
},
"signal-exit@4.1.0": {
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="
},
"string-width@4.2.3": {
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dependencies": [
"emoji-regex@8.0.0",
"is-fullwidth-code-point",
"strip-ansi@6.0.1"
]
},
"string-width@5.1.2": {
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
"dependencies": [
"eastasianwidth",
"emoji-regex@9.2.2",
"strip-ansi@7.1.2"
]
},
"strip-ansi@6.0.1": {
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dependencies": [
"ansi-regex@5.0.1"
]
},
"strip-ansi@7.1.2": {
"integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
"dependencies": [
"ansi-regex@6.2.2"
]
},
"ts-json-schema-generator@2.4.0": {
"integrity": "sha512-HbmNsgs58CfdJq0gpteRTxPXG26zumezOs+SB9tgky6MpqiFgQwieCn2MW70+sxpHouZ/w9LW0V6L4ZQO4y1Ug==",
"dependencies": [
"@types/json-schema",
"commander",
"glob",
"json5",
"normalize-path",
"safe-stable-stringify",
"tslib",
"typescript"
],
"bin": true
},
"tslib@2.8.1": {
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
},
"tsx@4.21.0": {
"integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==",
"dependencies": [
"esbuild",
"get-tsconfig"
],
"optionalDependencies": [
"fsevents"
],
"bin": true
},
"typescript@5.9.3": {
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"bin": true
},
"undici-types@6.21.0": {
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="
},
"undici@7.19.1": {
"integrity": "sha512-Gpq0iNm5M6cQWlyHQv9MV+uOj1jWk7LpkoE5vSp/7zjb4zMdAcUD+VL5y0nH4p9EbUklq00eVIIX/XcDHzu5xg=="
},
"whatwg-encoding@3.1.1": {
"integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
"dependencies": [
"iconv-lite"
],
"deprecated": true
},
"whatwg-mimetype@4.0.0": {
"integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg=="
},
"which@2.0.2": {
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dependencies": [
"isexe"
],
"bin": true
},
"wrap-ansi@7.0.0": {
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dependencies": [
"ansi-styles@4.3.0",
"string-width@4.2.3",
"strip-ansi@6.0.1"
]
},
"wrap-ansi@8.1.0": {
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
"dependencies": [
"ansi-styles@6.2.3",
"string-width@5.1.2",
"strip-ansi@7.1.2"
]
}
},
"workspace": {
"packageJson": {
"dependencies": [
"npm:@anthropic-ai/claude-code@latest",
"npm:@openai/codex@latest",
"npm:@types/node@22",
"npm:cheerio@1",
"npm:ts-json-schema-generator@^2.4.0",
"npm:tsx@^4.19.0",
"npm:typescript@^5.7.0"
]
}
}
}

View file

@ -8,7 +8,11 @@
"extract:opencode": "tsx src/index.ts --agent=opencode",
"extract:claude": "tsx src/index.ts --agent=claude",
"extract:codex": "tsx src/index.ts --agent=codex",
"extract:amp": "tsx src/index.ts --agent=amp"
"extract:amp": "tsx src/index.ts --agent=amp",
"extract:claude-events": "tsx src/claude-event-types.ts",
"extract:claude-events:sdk": "tsx src/claude-event-types-sdk.ts",
"extract:claude-events:cli": "tsx src/claude-event-types-cli.ts",
"extract:claude-events:docs": "tsx src/claude-event-types-docs.ts"
},
"dependencies": {
"ts-json-schema-generator": "^2.4.0",

View file

@ -3,7 +3,7 @@ import { fetchWithCache } from "./cache.js";
import { createNormalizedSchema, type NormalizedSchema } from "./normalize.js";
import type { JSONSchema7 } from "json-schema";
const AMP_DOCS_URL = "https://ampcode.com/manual/appendix";
const AMP_DOCS_URL = "https://ampcode.com/manual/appendix?preview#message-schema";
// Key types we want to extract
const TARGET_TYPES = ["StreamJSONMessage", "AmpOptions", "PermissionRule", "Message", "ToolCall"];

View file

@ -0,0 +1,11 @@
import { collectFromCli } from "./claude-event-types.js";
const promptArg = process.argv.slice(2).find((arg) => arg.startsWith("--prompt="));
const timeoutArg = process.argv.slice(2).find((arg) => arg.startsWith("--timeoutMs="));
const prompt = promptArg?.split("=")[1] ?? "Reply with exactly OK.";
const timeoutMs = timeoutArg ? Number(timeoutArg.split("=")[1]) : 20000;
collectFromCli(prompt, timeoutMs).then((result) => {
console.log(JSON.stringify(result, null, 2));
});

View file

@ -0,0 +1,8 @@
import { collectFromDocs } from "./claude-event-types.js";
const urlsArg = process.argv.slice(2).find((arg) => arg.startsWith("--urls="));
const urls = urlsArg ? urlsArg.split("=")[1]!.split(",") : undefined;
collectFromDocs(urls ?? []).then((result) => {
console.log(JSON.stringify(result, null, 2));
});

View file

@ -0,0 +1,4 @@
import { collectFromSdkTypes } from "./claude-event-types.js";
const result = collectFromSdkTypes();
console.log(JSON.stringify(result, null, 2));

View file

@ -0,0 +1,338 @@
import { readFileSync, existsSync } from "node:fs";
import { join, dirname } from "node:path";
import { fileURLToPath } from "node:url";
import { spawn } from "node:child_process";
import ts from "typescript";
import { load } from "cheerio";
type SourceResult = {
source: string;
types: string[];
details?: Record<string, string[]>;
error?: string;
};
const SDK_POSSIBLE_PATHS = [
"node_modules/@anthropic-ai/claude-code/sdk-tools.d.ts",
"node_modules/@anthropic-ai/claude-code/dist/index.d.ts",
"node_modules/@anthropic-ai/claude-code/dist/types.d.ts",
"node_modules/@anthropic-ai/claude-code/index.d.ts",
];
const DEFAULT_DOC_URLS = [
"https://platform.claude.com/docs/en/messages-streaming",
"https://platform.claude.com/docs/en/api/messages-streaming",
"https://docs.anthropic.com/claude/reference/messages-streaming",
"https://docs.anthropic.com/claude/reference/messages-streaming#events",
"https://docs.anthropic.com/claude/docs/messages-streaming",
];
function moduleDir(): string {
const metaDir = (import.meta as { dirname?: string }).dirname;
if (typeof metaDir === "string") {
return metaDir;
}
return dirname(fileURLToPath(import.meta.url));
}
function findSdkTypesPath(): string | null {
const resourceDir = join(moduleDir(), "..");
const repoRoot = join(moduleDir(), "..", "..", "..");
const searchRoots = [resourceDir, repoRoot];
for (const root of searchRoots) {
for (const relativePath of SDK_POSSIBLE_PATHS) {
const fullPath = join(root, relativePath);
if (existsSync(fullPath)) {
return fullPath;
}
}
}
return null;
}
function extractStringLiterals(node: ts.TypeNode): string[] {
if (ts.isLiteralTypeNode(node) && ts.isStringLiteral(node.literal)) {
return [node.literal.text];
}
if (ts.isUnionTypeNode(node)) {
return node.types.flatMap((typeNode) => extractStringLiterals(typeNode));
}
return [];
}
function containerName(node: ts.Node): string | null {
let current: ts.Node | undefined = node;
while (current) {
if (ts.isInterfaceDeclaration(current) && current.name) {
return current.name.text;
}
if (ts.isTypeAliasDeclaration(current) && current.name) {
return current.name.text;
}
current = current.parent;
}
return null;
}
function collectFromSdkTypes(): SourceResult {
const path = findSdkTypesPath();
if (!path) {
return { source: "sdk", types: [], error: "Claude SDK types not found" };
}
const content = readFileSync(path, "utf8");
const sourceFile = ts.createSourceFile(path, content, ts.ScriptTarget.Latest, true);
const types = new Set<string>();
const details: Record<string, string[]> = {};
function visit(node: ts.Node): void {
if (ts.isPropertySignature(node)) {
const name = node.name && ts.isIdentifier(node.name) ? node.name.text : null;
if (name === "type" && node.type) {
const literals = extractStringLiterals(node.type);
if (literals.length > 0) {
const parentName = containerName(node) ?? "anonymous";
if (/Event|Stream|Message/i.test(parentName)) {
literals.forEach((value) => types.add(value));
details[parentName] = (details[parentName] ?? []).concat(literals);
}
}
}
}
ts.forEachChild(node, visit);
}
visit(sourceFile);
return { source: "sdk", types: Array.from(types).sort(), details };
}
function collectFromCli(prompt: string, timeoutMs: number): Promise<SourceResult> {
return new Promise((resolve) => {
const result: SourceResult = { source: "cli", types: [] };
const types = new Set<string>();
const denoGlobal = (globalThis as {
Deno?: {
which?: (cmd: string) => string | null;
Command?: new (
cmd: string,
options: { args: string[]; stdout: "piped"; stderr: "piped" },
) => { output: () => Promise<{ stdout: Uint8Array; stderr: Uint8Array; code: number }> };
};
}).Deno;
if (denoGlobal?.which && !denoGlobal.which("claude")) {
result.error = "claude binary not found in PATH";
resolve(result);
return;
}
if (denoGlobal?.Command) {
const command = new denoGlobal.Command("claude", {
args: ["--print", "--output-format", "stream-json", "--verbose", prompt],
stdout: "piped",
stderr: "piped",
});
try {
command
.output()
.then(({ stdout, stderr, code }) => {
const text = new TextDecoder().decode(stdout);
for (const line of text.split("\n")) {
const trimmed = line.trim();
if (!trimmed) continue;
try {
const value = JSON.parse(trimmed);
if (value && typeof value.type === "string") {
types.add(value.type);
}
} catch {
// ignore non-json
}
}
result.types = Array.from(types).sort();
if (code !== 0) {
result.error =
new TextDecoder().decode(stderr).trim() ||
`claude exited with code ${code}`;
}
resolve(result);
})
.catch((error) => {
result.error = error instanceof Error ? error.message : String(error);
resolve(result);
});
} catch (error) {
result.error = error instanceof Error ? error.message : String(error);
resolve(result);
}
return;
}
let child;
try {
child = spawn(
"claude",
["--print", "--output-format", "stream-json", "--verbose", prompt],
{ stdio: ["ignore", "pipe", "pipe"] },
);
} catch (error) {
result.error = error instanceof Error ? error.message : String(error);
resolve(result);
return;
}
if (!child.stdout || !child.stderr) {
result.error = "claude stdout/stderr not available";
resolve(result);
return;
}
let stderr = "";
const timer = setTimeout(() => {
child.kill("SIGKILL");
}, timeoutMs);
child.stdout.on("data", (chunk) => {
const text = chunk.toString("utf8");
for (const line of text.split("\n")) {
const trimmed = line.trim();
if (!trimmed) continue;
try {
const value = JSON.parse(trimmed);
if (value && typeof value.type === "string") {
types.add(value.type);
}
} catch {
// ignore non-json
}
}
});
child.stderr.on("data", (chunk) => {
stderr += chunk.toString("utf8");
});
child.on("close", (code) => {
clearTimeout(timer);
result.types = Array.from(types).sort();
if (code !== 0) {
result.error = stderr.trim() || `claude exited with code ${code}`;
}
resolve(result);
});
});
}
async function collectFromDocs(urls: string[]): Promise<SourceResult> {
if (typeof fetch !== "function") {
return { source: "docs", types: [], error: "fetch is not available in this runtime" };
}
const effectiveUrls = urls.length > 0 ? urls : DEFAULT_DOC_URLS;
const types = new Set<string>();
const extractFromText = (text: string) => {
const typeMatches = text.match(/\"type\"\\s*:\\s*\"([^\"]+)\"/g) ?? [];
for (const match of typeMatches) {
const value = match.split(":")[1]?.trim().replace(/^\"|\"$/g, "");
if (value) types.add(value);
}
const eventMatches = text.match(/event\\s*:\\s*([a-z_]+)/gi) ?? [];
for (const match of eventMatches) {
const value = match.split(":")[1]?.trim();
if (value) types.add(value);
}
};
for (const url of effectiveUrls) {
try {
const res = await fetch(url);
if (!res.ok) {
continue;
}
const html = await res.text();
const $ = load(html);
const blocks = $("pre, code")
.map((_, el) => $(el).text())
.get();
for (const block of blocks) {
extractFromText(block);
}
const nextData = $("#__NEXT_DATA__").text();
if (nextData) {
extractFromText(nextData);
}
extractFromText(html);
} catch {
// ignore per-url errors
}
}
return { source: "docs", types: Array.from(types).sort() };
}
type Args = {
source: "all" | "sdk" | "cli" | "docs";
prompt: string;
timeoutMs: number;
urls: string[];
json: boolean;
};
function parseArgs(): Args {
const args = process.argv.slice(2);
const sourceArg = args.find((arg) => arg.startsWith("--source="));
const promptArg = args.find((arg) => arg.startsWith("--prompt="));
const timeoutArg = args.find((arg) => arg.startsWith("--timeoutMs="));
const urlsArg = args.find((arg) => arg.startsWith("--urls="));
const json = args.includes("--json");
return {
source: (sourceArg?.split("=")[1] as Args["source"]) ?? "all",
prompt: promptArg?.split("=")[1] ?? "Reply with exactly OK.",
timeoutMs: timeoutArg ? Number(timeoutArg.split("=")[1]) : 20000,
urls: urlsArg ? urlsArg.split("=")[1]!.split(",") : DEFAULT_DOC_URLS,
json,
};
}
function summarize(results: SourceResult[]): void {
const counts = results.map((r) => ({ source: r.source, count: r.types.length }));
const max = Math.max(...counts.map((c) => c.count), 0);
const best = counts.filter((c) => c.count === max).map((c) => c.source);
const union = Array.from(
new Set(results.flatMap((r) => r.types))
).sort();
console.log("Claude event type extraction");
console.log("============================");
for (const result of results) {
console.log(`- ${result.source}: ${result.types.length} types${result.error ? " (error)" : ""}`);
}
console.log(`\nMost comprehensive: ${best.join(", ") || "none"}`);
console.log(`Union (${union.length}): ${union.join(", ")}`);
}
async function main(): Promise<void> {
const args = parseArgs();
const results: SourceResult[] = [];
if (args.source === "all" || args.source === "sdk") {
results.push(collectFromSdkTypes());
}
if (args.source === "all" || args.source === "cli") {
results.push(await collectFromCli(args.prompt, args.timeoutMs));
}
if (args.source === "all" || args.source === "docs") {
results.push(await collectFromDocs(args.urls));
}
if (args.json) {
console.log(JSON.stringify({ results }, null, 2));
return;
}
summarize(results);
}
main().catch((error) => {
console.error("Fatal error:", error);
process.exit(1);
});
export { collectFromCli, collectFromDocs, collectFromSdkTypes };

View file

@ -1,92 +1,43 @@
import { createGenerator, type Config } from "ts-json-schema-generator";
import { existsSync, readFileSync } from "fs";
import { join, dirname } from "path";
import { execSync } from "child_process";
import { createNormalizedSchema, type NormalizedSchema } from "./normalize.js";
import type { JSONSchema7 } from "json-schema";
// Try multiple possible paths for the SDK types
const POSSIBLE_PATHS = [
"node_modules/@anthropic-ai/claude-code/sdk-tools.d.ts",
"node_modules/@anthropic-ai/claude-code/dist/index.d.ts",
"node_modules/@anthropic-ai/claude-code/dist/types.d.ts",
"node_modules/@anthropic-ai/claude-code/index.d.ts",
];
// Key types we want to extract
const TARGET_TYPES = [
"ToolInputSchemas",
"AgentInput",
"BashInput",
"FileEditInput",
"FileReadInput",
"FileWriteInput",
"GlobInput",
"GrepInput",
"WebFetchInput",
"WebSearchInput",
"AskUserQuestionInput",
];
function findTypesPath(): string | null {
const baseDir = join(import.meta.dirname, "..", "..", "resources", "agent-schemas");
for (const relativePath of POSSIBLE_PATHS) {
const fullPath = join(baseDir, relativePath);
if (existsSync(fullPath)) {
return fullPath;
}
}
return null;
}
export async function extractClaudeSchema(): Promise<NormalizedSchema> {
console.log("Extracting Claude Code SDK schema...");
const typesPath = findTypesPath();
if (!typesPath) {
console.log(" [warn] Claude Code SDK types not found, using fallback schema");
return createFallbackSchema();
}
console.log(` [found] ${typesPath}`);
const config: Config = {
path: typesPath,
tsconfig: join(import.meta.dirname, "..", "..", "resources", "agent-schemas", "tsconfig.json"),
type: "*",
skipTypeCheck: true,
topRef: false,
expose: "export",
jsDoc: "extended",
};
console.log("Extracting Claude Code schema via CLI...");
try {
const generator = createGenerator(config);
const schema = generator.createSchema(config.type);
// Run claude CLI with --json-schema flag to get the schema
const output = execSync("claude --output-format json --json-schema", {
encoding: "utf-8",
timeout: 30000,
stdio: ["pipe", "pipe", "pipe"],
});
// Parse the JSON output
const parsed = JSON.parse(output);
// Extract definitions from the schema
const definitions: Record<string, JSONSchema7> = {};
if (schema.definitions) {
for (const [name, def] of Object.entries(schema.definitions)) {
if (parsed.definitions) {
for (const [name, def] of Object.entries(parsed.definitions)) {
definitions[name] = def as JSONSchema7;
}
} else if (parsed.$defs) {
for (const [name, def] of Object.entries(parsed.$defs)) {
definitions[name] = def as JSONSchema7;
}
} else {
// The output might be a single schema, use it as the root
definitions["Schema"] = parsed as JSONSchema7;
}
// Verify target types exist
const found = TARGET_TYPES.filter((name) => definitions[name]);
const missing = TARGET_TYPES.filter((name) => !definitions[name]);
if (missing.length > 0) {
console.log(` [warn] Missing expected types: ${missing.join(", ")}`);
}
console.log(` [ok] Extracted ${Object.keys(definitions).length} types (${found.length} target types)`);
console.log(` [ok] Extracted ${Object.keys(definitions).length} types from CLI`);
return createNormalizedSchema("claude", "Claude Code SDK Schema", definitions);
} catch (error) {
console.log(` [error] Schema generation failed: ${error}`);
const errorMessage = error instanceof Error ? error.message : String(error);
console.log(` [warn] CLI extraction failed: ${errorMessage}`);
console.log(" [fallback] Using embedded schema definitions");
return createFallbackSchema();
}

View file

@ -1,88 +1,69 @@
import { createGenerator, type Config } from "ts-json-schema-generator";
import { existsSync } from "fs";
import { execSync } from "child_process";
import { existsSync, readFileSync, rmSync, readdirSync } from "fs";
import { join } from "path";
import { createNormalizedSchema, type NormalizedSchema } from "./normalize.js";
import type { JSONSchema7 } from "json-schema";
// Try multiple possible paths for the SDK types
const POSSIBLE_PATHS = [
"node_modules/@openai/codex/dist/index.d.ts",
"node_modules/@openai/codex/dist/types.d.ts",
"node_modules/@openai/codex/index.d.ts",
];
// Key types we want to extract
const TARGET_TYPES = [
"ThreadEvent",
"ThreadItem",
"CodexOptions",
"ThreadOptions",
"Input",
"ResponseItem",
"FunctionCall",
"Message",
];
function findTypesPath(): string | null {
const baseDir = join(import.meta.dirname, "..", "..", "resources", "agent-schemas");
for (const relativePath of POSSIBLE_PATHS) {
const fullPath = join(baseDir, relativePath);
if (existsSync(fullPath)) {
return fullPath;
}
}
return null;
}
export async function extractCodexSchema(): Promise<NormalizedSchema> {
console.log("Extracting Codex SDK schema...");
console.log("Extracting Codex schema via CLI...");
const typesPath = findTypesPath();
if (!typesPath) {
console.log(" [warn] Codex SDK types not found, using fallback schema");
return createFallbackSchema();
}
console.log(` [found] ${typesPath}`);
const config: Config = {
path: typesPath,
tsconfig: join(import.meta.dirname, "..", "..", "resources", "agent-schemas", "tsconfig.json"),
type: "*",
skipTypeCheck: true,
topRef: false,
expose: "export",
jsDoc: "extended",
};
const tempDir = join(import.meta.dirname, "..", ".temp-codex-schemas");
try {
const generator = createGenerator(config);
const schema = generator.createSchema(config.type);
// Run codex CLI to generate JSON schema
execSync(`codex app-server generate-json-schema --out "${tempDir}"`, {
encoding: "utf-8",
timeout: 30000,
stdio: ["pipe", "pipe", "pipe"],
});
// Read generated schema files from temp directory
const definitions: Record<string, JSONSchema7> = {};
if (schema.definitions) {
for (const [name, def] of Object.entries(schema.definitions)) {
definitions[name] = def as JSONSchema7;
if (existsSync(tempDir)) {
const files = readdirSync(tempDir).filter((f) => f.endsWith(".json"));
for (const file of files) {
const filePath = join(tempDir, file);
const content = readFileSync(filePath, "utf-8");
const schema = JSON.parse(content);
// Extract the name from the file (e.g., "ThreadEvent.json" -> "ThreadEvent")
const name = file.replace(".json", "");
if (schema.definitions) {
for (const [defName, def] of Object.entries(schema.definitions)) {
definitions[defName] = def as JSONSchema7;
}
} else if (schema.$defs) {
for (const [defName, def] of Object.entries(schema.$defs)) {
definitions[defName] = def as JSONSchema7;
}
} else {
definitions[name] = schema as JSONSchema7;
}
}
// Clean up temp directory
rmSync(tempDir, { recursive: true, force: true });
}
// Verify target types exist
const found = TARGET_TYPES.filter((name) => definitions[name]);
const missing = TARGET_TYPES.filter((name) => !definitions[name]);
if (missing.length > 0) {
console.log(` [warn] Missing expected types: ${missing.join(", ")}`);
if (Object.keys(definitions).length === 0) {
console.log(" [warn] No schemas extracted from CLI, using fallback");
return createFallbackSchema();
}
console.log(` [ok] Extracted ${Object.keys(definitions).length} types (${found.length} target types)`);
console.log(` [ok] Extracted ${Object.keys(definitions).length} types from CLI`);
return createNormalizedSchema("codex", "Codex SDK Schema", definitions);
} catch (error) {
console.log(` [error] Schema generation failed: ${error}`);
// Clean up temp directory on error
if (existsSync(tempDir)) {
rmSync(tempDir, { recursive: true, force: true });
}
const errorMessage = error instanceof Error ? error.message : String(error);
console.log(` [warn] CLI extraction failed: ${errorMessage}`);
console.log(" [fallback] Using embedded schema definitions");
return createFallbackSchema();
}

View file

@ -6,8 +6,8 @@ import { extractCodexSchema } from "./codex.js";
import { extractAmpSchema } from "./amp.js";
import { validateSchema, type NormalizedSchema } from "./normalize.js";
const RESOURCE_DIR = join(import.meta.dirname, "..", "..", "resources", "agent-schemas");
const DIST_DIR = join(RESOURCE_DIR, "dist");
const RESOURCE_DIR = join(import.meta.dirname, "..");
const DIST_DIR = join(RESOURCE_DIR, "artifacts", "json-schema");
type AgentName = "opencode" | "claude" | "codex" | "amp";