@neural-tools/create-json-plugin 0.1.7

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.md ADDED
@@ -0,0 +1,21 @@
1
+ # MIT License
2
+
3
+ Copyright (c) 2025 Luke Amy
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,40 @@
1
+ # @neural-tools/create-json-plugin
2
+
3
+ Scaffold Claude plugins that include:
4
+
5
+ - A JSON-output skill (`skills/<skill-name>/SKILL.md`)
6
+ - A custom JSON LSP config (`.lsp.json`)
7
+ - A local schema (`schemas/*.schema.json`)
8
+ - Hook scripts (`hooks/`) that enforce schema validation on writes/edits
9
+ - A starter config file validated against that schema
10
+
11
+ ## Usage
12
+
13
+ ```bash
14
+ pnpm --filter @neural-tools/create-json-plugin build
15
+ node packages/create-json-plugin/dist/index.js my-plugin
16
+ ```
17
+
18
+ Or after publishing:
19
+
20
+ ```bash
21
+ npx @neural-tools/create-json-plugin my-plugin
22
+ ```
23
+
24
+ ## Defaults
25
+
26
+ - Skill name: `generate-json-config`
27
+ - Output config file: `config.json`
28
+ - Schema file: `config.schema.json`
29
+ - Output directory: `./claude/plugins`
30
+
31
+ ## CLI options
32
+
33
+ - `-d, --description <desc>` Plugin description
34
+ - `-o, --output <dir>` Output directory for plugins
35
+ - `--skill <name>` Skill name to create
36
+ - `--file-name <name>` Target JSON config file name
37
+ - `--schema-name <name>` Schema file name
38
+ - `--version <version>` Plugin version
39
+ - `--author <name>` Plugin author
40
+ - `--dry-run` Preview without writing files
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ interface GenerateJsonPluginOptions {
3
+ description?: string;
4
+ output?: string;
5
+ skill?: string;
6
+ fileName?: string;
7
+ schemaName?: string;
8
+ version?: string;
9
+ author?: string;
10
+ dryRun?: boolean;
11
+ }
12
+ declare function createJsonPlugin(pluginName: string | undefined, options: GenerateJsonPluginOptions): Promise<void>;
13
+
14
+ export { createJsonPlugin };
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ interface GenerateJsonPluginOptions {
3
+ description?: string;
4
+ output?: string;
5
+ skill?: string;
6
+ fileName?: string;
7
+ schemaName?: string;
8
+ version?: string;
9
+ author?: string;
10
+ dryRun?: boolean;
11
+ }
12
+ declare function createJsonPlugin(pluginName: string | undefined, options: GenerateJsonPluginOptions): Promise<void>;
13
+
14
+ export { createJsonPlugin };
package/dist/index.js ADDED
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env node
2
+ "use strict";var T=Object.create;var f=Object.defineProperty;var U=Object.getOwnPropertyDescriptor;var q=Object.getOwnPropertyNames;var W=Object.getPrototypeOf,H=Object.prototype.hasOwnProperty;var K=(i,e)=>{for(var t in e)f(i,t,{get:e[t],enumerable:!0})},D=(i,e,t,p)=>{if(e&&typeof e=="object"||typeof e=="function")for(let c of q(e))!H.call(i,c)&&c!==t&&f(i,c,{get:()=>e[c],enumerable:!(p=U(e,c))||p.enumerable});return i};var P=(i,e,t)=>(t=i!=null?T(W(i)):{},D(e||!i||!i.__esModule?f(t,"default",{value:i,enumerable:!0}):t,i)),V=i=>D(f({},"__esModule",{value:!0}),i);var z={};K(z,{createJsonPlugin:()=>I});module.exports=V(z);var o=P(require("path")),n=P(require("fs-extra")),v=P(require("inquirer")),L=require("commander"),l=require("@neural-tools/core"),b=new L.Command;b.name("create-neural-json-plugin").description("Create a Claude plugin with a JSON-output skill and custom JSON LSP validation").argument("[plugin-name]","Name of the plugin").option("-d, --description <desc>","Description of the plugin").option("-o, --output <dir>","Output directory","./claude/plugins").option("--skill <name>","Skill name","generate-json-config").option("--file-name <name>","Name of the JSON config file","config.json").option("--schema-name <name>","Name of the JSON schema file","config.schema.json").option("--version <version>","Plugin version","0.1.0").option("--author <author>","Plugin author").option("--dry-run","Preview without creating files",!1).action(async(i,e)=>{await I(i,e)});async function I(i,e){l.logger.header("Create JSON Plugin");let t=i;if(t||(t=(await v.default.prompt([{type:"input",name:"pluginName",message:"Plugin name:",default:"json-config-plugin",validate:h=>!h||h.trim().length===0?"Plugin name is required":!0}])).pluginName),!t)throw new Error("Plugin name is required");let p=e.description;p||(p=(await v.default.prompt([{type:"input",name:"description",message:"Plugin description:",default:`${t} plugin with JSON skill + schema validation`}])).description);let c=p||`${t} plugin with JSON skill + schema validation`,u=e.skill||"generate-json-config",a=e.fileName||"config.json",d=e.schemaName||"config.schema.json",s=o.default.resolve(e.output||"./claude/plugins",t),k=o.default.join(s,".claude-plugin"),g=o.default.join(k,"plugin.json"),O=o.default.join(s,"schemas"),j=o.default.join(O,d),E=o.default.join(s,"skills",u),w=o.default.join(E,"SKILL.md"),S=o.default.join(s,"hooks"),_=o.default.join(S,"scripts"),N=o.default.join(S,"hooks.json"),m=o.default.join(_,"validate-json-config.py"),J=o.default.join(_,"ensure-json-lsp.sh"),C=o.default.join(s,"examples"),$=o.default.join(C,a),y=o.default.join(s,".lsp.json");if(e.dryRun){l.logger.section("Dry Run",[`Plugin directory: ${s}`,`Manifest: ${g}`,`LSP config: ${y}`,`Schema: ${j}`,`Skill: ${w}`,`Hooks config: ${N}`,`Validation hook: ${m}`,`Starter config: ${$}`]);return}if(await n.default.pathExists(g)){let{overwrite:r}=await v.default.prompt([{type:"confirm",name:"overwrite",message:`Plugin ${t} already exists at ${s}. Overwrite?`,default:!1}]);if(!r){l.logger.warn("Cancelled");return}await n.default.remove(s)}l.logger.startSpinner("Scaffolding plugin...");try{await n.default.ensureDir(k),await n.default.ensureDir(O),await n.default.ensureDir(E),await n.default.ensureDir(S),await n.default.ensureDir(_),await n.default.ensureDir(C);let r={name:t,version:e.version||"0.1.0",description:c};e.author&&(r.author=e.author),await n.default.writeJSON(g,r,{spaces:2});let h={json:{command:"vscode-json-languageserver",args:["--stdio"],extensionToLanguage:{".json":"json"},settings:{json:{schemas:[{fileMatch:[`**/${a}`],url:`file://\${CLAUDE_PLUGIN_ROOT}/schemas/${d}`}],validate:{enable:!0}}}}};await n.default.writeJSON(y,h,{spaces:2});let x={hooks:{SessionStart:[{hooks:[{type:"command",command:"bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/ensure-json-lsp.sh",timeout:60}]}],PreToolUse:[{matcher:"Edit|Write|MultiEdit",hooks:[{type:"command",command:"python3 ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/validate-json-config.py",timeout:15}]}]}};await n.default.writeJSON(N,x,{spaces:2});let R={$schema:"http://json-schema.org/draft-07/schema#",title:a,description:`Schema for ${a}`,type:"object",required:["version","settings"],properties:{version:{type:"string"},settings:{type:"object",minProperties:1,properties:{enabled:{type:"boolean"},mode:{type:"string"}},additionalProperties:!0},items:{type:"array",items:{type:"object",required:["name","value"],properties:{name:{type:"string"},value:{}},additionalProperties:!0}}},additionalProperties:!0};await n.default.writeJSON(j,R,{spaces:2});let G=`#!/usr/bin/env python3
3
+ import json
4
+ import os
5
+ import sys
6
+ from pathlib import Path
7
+
8
+ TARGET_FILE = "${a}"
9
+ SCHEMA_FILE = "${d}"
10
+
11
+ def load_schema(plugin_root: str) -> dict:
12
+ schema_path = Path(plugin_root) / "schemas" / SCHEMA_FILE
13
+ with open(schema_path, "r", encoding="utf-8") as f:
14
+ return json.load(f)
15
+
16
+ def validate_with_jsonschema(config: dict, plugin_root: str) -> list[str]:
17
+ import jsonschema
18
+
19
+ schema = load_schema(plugin_root)
20
+ validator = jsonschema.Draft7Validator(schema)
21
+ errors = []
22
+ for error in sorted(validator.iter_errors(config), key=lambda e: str(e.path)):
23
+ path = ".".join(str(p) for p in error.path) or "(root)"
24
+ errors.append(f" - {path}: {error.message}")
25
+ return errors
26
+
27
+ def validate_basic(config: dict) -> list[str]:
28
+ errors = []
29
+ if "version" not in config:
30
+ errors.append(" - Missing required field: version")
31
+ if "settings" not in config:
32
+ errors.append(" - Missing required field: settings")
33
+ if "settings" in config and not isinstance(config["settings"], dict):
34
+ errors.append(" - settings must be an object")
35
+ return errors
36
+
37
+ def main() -> None:
38
+ try:
39
+ hook_data = json.load(sys.stdin)
40
+ except (json.JSONDecodeError, EOFError):
41
+ sys.exit(0)
42
+
43
+ if hook_data.get("tool_name") not in ("Write", "Edit", "MultiEdit"):
44
+ sys.exit(0)
45
+
46
+ tool_input = hook_data.get("tool_input", {})
47
+ file_path = tool_input.get("file_path", "")
48
+ content = tool_input.get("content", "")
49
+
50
+ if not file_path.endswith(TARGET_FILE):
51
+ sys.exit(0)
52
+
53
+ try:
54
+ config = json.loads(content)
55
+ except json.JSONDecodeError as e:
56
+ print(json.dumps({"decision": "block", "reason": f"JSON parse error in {Path(file_path).name}: {e}"}))
57
+ sys.exit(0)
58
+
59
+ plugin_root = os.environ.get("CLAUDE_PLUGIN_ROOT", str(Path(__file__).parent.parent.parent))
60
+ try:
61
+ errors = validate_with_jsonschema(config, plugin_root)
62
+ except Exception:
63
+ errors = validate_basic(config)
64
+
65
+ if errors:
66
+ lines = [f"JSON config validation failed for {Path(file_path).name}:"]
67
+ lines.extend(errors)
68
+ lines.append(f"Fix validation errors to match schema: {SCHEMA_FILE}")
69
+ print(json.dumps({"decision": "block", "reason": "\\n".join(lines)}))
70
+
71
+ sys.exit(0)
72
+
73
+ if __name__ == "__main__":
74
+ main()
75
+ `;await n.default.writeFile(m,G,"utf-8"),await n.default.chmod(m,493),await n.default.writeFile(J,`#!/bin/bash
76
+ WARNINGS=()
77
+
78
+ if ! command -v vscode-json-languageserver &>/dev/null; then
79
+ if command -v npm &>/dev/null; then
80
+ echo "Installing vscode-json-languageserver..."
81
+ npm install -g vscode-json-languageserver --silent
82
+ echo "JSON language server installed. Restart Claude Code to activate schema validation."
83
+ else
84
+ WARNINGS+=("vscode-json-languageserver not found. Install Node.js then run: npm install -g vscode-json-languageserver")
85
+ fi
86
+ fi
87
+
88
+ if [[ \${#WARNINGS[@]} -gt 0 ]]; then
89
+ echo ""
90
+ echo "Plugin setup needed:"
91
+ for w in "\${WARNINGS[@]}"; do
92
+ echo " - $w"
93
+ done
94
+ echo ""
95
+ fi
96
+ `,"utf-8"),await n.default.chmod(J,493);let A=`---
97
+ name: ${u}
98
+ description: Generate ${a} JSON files that validate against ${d}
99
+ ---
100
+
101
+ # ${u}
102
+
103
+ Generate a valid \`${a}\` file.
104
+
105
+ ## Rules
106
+
107
+ 1. Output strict JSON only when producing the final config (no comments, no trailing commas).
108
+ 2. Ensure the output matches schema at \`${d}\`.
109
+ 3. Include required top-level keys: \`version\` and \`settings\`.
110
+ 4. Keep all values syntactically valid JSON and consistent with the schema.
111
+
112
+ ## Output
113
+
114
+ Return the JSON in a fenced block with \`json\` language and save it as \`${a}\`.
115
+ `;await n.default.writeFile(w,A,"utf-8");let F={version:"1.0.0",settings:{enabled:!0,mode:"standard"},items:[{name:"example",value:"demo"}]};await n.default.writeJSON($,F,{spaces:2});let M=`# ${t}
116
+
117
+ Generated by @neural-tools/create-json-plugin.
118
+
119
+ ## What this plugin includes
120
+
121
+ - \`.lsp.json\` using \`vscode-json-languageserver\`
122
+ - JSON schema at \`schemas/${d}\`
123
+ - Skill at \`skills/${u}/SKILL.md\` for generating \`${a}\`
124
+ - Hooks at \`hooks/hooks.json\` that enforce schema validation on edits/writes
125
+ - Starter config at \`examples/${a}\`
126
+
127
+ ## Notes
128
+
129
+ Install the JSON language server if needed:
130
+
131
+ \`npm install -g vscode-json-languageserver\`
132
+ `;await n.default.writeFile(o.default.join(s,"README.md"),M,"utf-8"),l.logger.succeedSpinner("Plugin created"),l.logger.section("Created",[`Plugin: ${s}`,`Manifest: ${g}`,`LSP config: ${y}`,`Schema: ${j}`,`Skill: ${w}`,`Hooks config: ${N}`,`Validation hook: ${m}`,`Starter config: ${$}`])}catch(r){throw l.logger.failSpinner("Failed to create plugin"),r}}b.parse();0&&(module.exports={createJsonPlugin});
package/dist/index.mjs ADDED
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env node
2
+ import n from"path";import e from"fs-extra";import N from"inquirer";import{Command as R}from"commander";import{logger as r}from"@neural-tools/core";var E=new R;E.name("create-neural-json-plugin").description("Create a Claude plugin with a JSON-output skill and custom JSON LSP validation").argument("[plugin-name]","Name of the plugin").option("-d, --description <desc>","Description of the plugin").option("-o, --output <dir>","Output directory","./claude/plugins").option("--skill <name>","Skill name","generate-json-config").option("--file-name <name>","Name of the JSON config file","config.json").option("--schema-name <name>","Name of the JSON schema file","config.schema.json").option("--version <version>","Plugin version","0.1.0").option("--author <author>","Plugin author").option("--dry-run","Preview without creating files",!1).action(async(g,i)=>{await G(g,i)});async function G(g,i){r.header("Create JSON Plugin");let s=g;if(s||(s=(await N.prompt([{type:"input",name:"pluginName",message:"Plugin name:",default:"json-config-plugin",validate:u=>!u||u.trim().length===0?"Plugin name is required":!0}])).pluginName),!s)throw new Error("Plugin name is required");let m=i.description;m||(m=(await N.prompt([{type:"input",name:"description",message:"Plugin description:",default:`${s} plugin with JSON skill + schema validation`}])).description);let J=m||`${s} plugin with JSON skill + schema validation`,c=i.skill||"generate-json-config",o=i.fileName||"config.json",l=i.schemaName||"config.schema.json",t=n.resolve(i.output||"./claude/plugins",s),$=n.join(t,".claude-plugin"),p=n.join($,"plugin.json"),y=n.join(t,"schemas"),h=n.join(y,l),P=n.join(t,"skills",c),f=n.join(P,"SKILL.md"),v=n.join(t,"hooks"),j=n.join(v,"scripts"),w=n.join(v,"hooks.json"),d=n.join(j,"validate-json-config.py"),k=n.join(j,"ensure-json-lsp.sh"),O=n.join(t,"examples"),S=n.join(O,o),_=n.join(t,".lsp.json");if(i.dryRun){r.section("Dry Run",[`Plugin directory: ${t}`,`Manifest: ${p}`,`LSP config: ${_}`,`Schema: ${h}`,`Skill: ${f}`,`Hooks config: ${w}`,`Validation hook: ${d}`,`Starter config: ${S}`]);return}if(await e.pathExists(p)){let{overwrite:a}=await N.prompt([{type:"confirm",name:"overwrite",message:`Plugin ${s} already exists at ${t}. Overwrite?`,default:!1}]);if(!a){r.warn("Cancelled");return}await e.remove(t)}r.startSpinner("Scaffolding plugin...");try{await e.ensureDir($),await e.ensureDir(y),await e.ensureDir(P),await e.ensureDir(v),await e.ensureDir(j),await e.ensureDir(O);let a={name:s,version:i.version||"0.1.0",description:J};i.author&&(a.author=i.author),await e.writeJSON(p,a,{spaces:2});let u={json:{command:"vscode-json-languageserver",args:["--stdio"],extensionToLanguage:{".json":"json"},settings:{json:{schemas:[{fileMatch:[`**/${o}`],url:`file://\${CLAUDE_PLUGIN_ROOT}/schemas/${l}`}],validate:{enable:!0}}}}};await e.writeJSON(_,u,{spaces:2});let C={hooks:{SessionStart:[{hooks:[{type:"command",command:"bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/ensure-json-lsp.sh",timeout:60}]}],PreToolUse:[{matcher:"Edit|Write|MultiEdit",hooks:[{type:"command",command:"python3 ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/validate-json-config.py",timeout:15}]}]}};await e.writeJSON(w,C,{spaces:2});let D={$schema:"http://json-schema.org/draft-07/schema#",title:o,description:`Schema for ${o}`,type:"object",required:["version","settings"],properties:{version:{type:"string"},settings:{type:"object",minProperties:1,properties:{enabled:{type:"boolean"},mode:{type:"string"}},additionalProperties:!0},items:{type:"array",items:{type:"object",required:["name","value"],properties:{name:{type:"string"},value:{}},additionalProperties:!0}}},additionalProperties:!0};await e.writeJSON(h,D,{spaces:2});let L=`#!/usr/bin/env python3
3
+ import json
4
+ import os
5
+ import sys
6
+ from pathlib import Path
7
+
8
+ TARGET_FILE = "${o}"
9
+ SCHEMA_FILE = "${l}"
10
+
11
+ def load_schema(plugin_root: str) -> dict:
12
+ schema_path = Path(plugin_root) / "schemas" / SCHEMA_FILE
13
+ with open(schema_path, "r", encoding="utf-8") as f:
14
+ return json.load(f)
15
+
16
+ def validate_with_jsonschema(config: dict, plugin_root: str) -> list[str]:
17
+ import jsonschema
18
+
19
+ schema = load_schema(plugin_root)
20
+ validator = jsonschema.Draft7Validator(schema)
21
+ errors = []
22
+ for error in sorted(validator.iter_errors(config), key=lambda e: str(e.path)):
23
+ path = ".".join(str(p) for p in error.path) or "(root)"
24
+ errors.append(f" - {path}: {error.message}")
25
+ return errors
26
+
27
+ def validate_basic(config: dict) -> list[str]:
28
+ errors = []
29
+ if "version" not in config:
30
+ errors.append(" - Missing required field: version")
31
+ if "settings" not in config:
32
+ errors.append(" - Missing required field: settings")
33
+ if "settings" in config and not isinstance(config["settings"], dict):
34
+ errors.append(" - settings must be an object")
35
+ return errors
36
+
37
+ def main() -> None:
38
+ try:
39
+ hook_data = json.load(sys.stdin)
40
+ except (json.JSONDecodeError, EOFError):
41
+ sys.exit(0)
42
+
43
+ if hook_data.get("tool_name") not in ("Write", "Edit", "MultiEdit"):
44
+ sys.exit(0)
45
+
46
+ tool_input = hook_data.get("tool_input", {})
47
+ file_path = tool_input.get("file_path", "")
48
+ content = tool_input.get("content", "")
49
+
50
+ if not file_path.endswith(TARGET_FILE):
51
+ sys.exit(0)
52
+
53
+ try:
54
+ config = json.loads(content)
55
+ except json.JSONDecodeError as e:
56
+ print(json.dumps({"decision": "block", "reason": f"JSON parse error in {Path(file_path).name}: {e}"}))
57
+ sys.exit(0)
58
+
59
+ plugin_root = os.environ.get("CLAUDE_PLUGIN_ROOT", str(Path(__file__).parent.parent.parent))
60
+ try:
61
+ errors = validate_with_jsonschema(config, plugin_root)
62
+ except Exception:
63
+ errors = validate_basic(config)
64
+
65
+ if errors:
66
+ lines = [f"JSON config validation failed for {Path(file_path).name}:"]
67
+ lines.extend(errors)
68
+ lines.append(f"Fix validation errors to match schema: {SCHEMA_FILE}")
69
+ print(json.dumps({"decision": "block", "reason": "\\n".join(lines)}))
70
+
71
+ sys.exit(0)
72
+
73
+ if __name__ == "__main__":
74
+ main()
75
+ `;await e.writeFile(d,L,"utf-8"),await e.chmod(d,493),await e.writeFile(k,`#!/bin/bash
76
+ WARNINGS=()
77
+
78
+ if ! command -v vscode-json-languageserver &>/dev/null; then
79
+ if command -v npm &>/dev/null; then
80
+ echo "Installing vscode-json-languageserver..."
81
+ npm install -g vscode-json-languageserver --silent
82
+ echo "JSON language server installed. Restart Claude Code to activate schema validation."
83
+ else
84
+ WARNINGS+=("vscode-json-languageserver not found. Install Node.js then run: npm install -g vscode-json-languageserver")
85
+ fi
86
+ fi
87
+
88
+ if [[ \${#WARNINGS[@]} -gt 0 ]]; then
89
+ echo ""
90
+ echo "Plugin setup needed:"
91
+ for w in "\${WARNINGS[@]}"; do
92
+ echo " - $w"
93
+ done
94
+ echo ""
95
+ fi
96
+ `,"utf-8"),await e.chmod(k,493);let b=`---
97
+ name: ${c}
98
+ description: Generate ${o} JSON files that validate against ${l}
99
+ ---
100
+
101
+ # ${c}
102
+
103
+ Generate a valid \`${o}\` file.
104
+
105
+ ## Rules
106
+
107
+ 1. Output strict JSON only when producing the final config (no comments, no trailing commas).
108
+ 2. Ensure the output matches schema at \`${l}\`.
109
+ 3. Include required top-level keys: \`version\` and \`settings\`.
110
+ 4. Keep all values syntactically valid JSON and consistent with the schema.
111
+
112
+ ## Output
113
+
114
+ Return the JSON in a fenced block with \`json\` language and save it as \`${o}\`.
115
+ `;await e.writeFile(f,b,"utf-8");let I={version:"1.0.0",settings:{enabled:!0,mode:"standard"},items:[{name:"example",value:"demo"}]};await e.writeJSON(S,I,{spaces:2});let x=`# ${s}
116
+
117
+ Generated by @neural-tools/create-json-plugin.
118
+
119
+ ## What this plugin includes
120
+
121
+ - \`.lsp.json\` using \`vscode-json-languageserver\`
122
+ - JSON schema at \`schemas/${l}\`
123
+ - Skill at \`skills/${c}/SKILL.md\` for generating \`${o}\`
124
+ - Hooks at \`hooks/hooks.json\` that enforce schema validation on edits/writes
125
+ - Starter config at \`examples/${o}\`
126
+
127
+ ## Notes
128
+
129
+ Install the JSON language server if needed:
130
+
131
+ \`npm install -g vscode-json-languageserver\`
132
+ `;await e.writeFile(n.join(t,"README.md"),x,"utf-8"),r.succeedSpinner("Plugin created"),r.section("Created",[`Plugin: ${t}`,`Manifest: ${p}`,`LSP config: ${_}`,`Schema: ${h}`,`Skill: ${f}`,`Hooks config: ${w}`,`Validation hook: ${d}`,`Starter config: ${S}`])}catch(a){throw r.failSpinner("Failed to create plugin"),a}}E.parse();export{G as createJsonPlugin};
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@neural-tools/create-json-plugin",
3
+ "version": "0.1.7",
4
+ "description": "Scaffold Claude plugins with JSON-output skills and custom JSON LSP validation",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "create-neural-json-plugin": "./dist/index.js"
9
+ },
10
+ "license": "SEE LICENSE IN ../../LICENSE.md",
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "https://github.com/MacLeanLuke/neural-tools.git",
17
+ "directory": "packages/create-json-plugin"
18
+ },
19
+ "homepage": "https://github.com/MacLeanLuke/neural-tools#readme",
20
+ "bugs": {
21
+ "url": "https://github.com/MacLeanLuke/neural-tools/issues"
22
+ },
23
+ "keywords": [
24
+ "neural-tools",
25
+ "claude",
26
+ "plugin",
27
+ "json",
28
+ "lsp",
29
+ "generator"
30
+ ],
31
+ "dependencies": {
32
+ "commander": "^12.0.0",
33
+ "fs-extra": "^11.2.0",
34
+ "inquirer": "^9.2.12",
35
+ "@neural-tools/core": "0.1.7"
36
+ },
37
+ "devDependencies": {
38
+ "@types/fs-extra": "^11.0.4",
39
+ "@types/inquirer": "^9.0.7",
40
+ "@types/node": "^20.11.5",
41
+ "typescript": "^5.3.3"
42
+ },
43
+ "files": [
44
+ "dist"
45
+ ],
46
+ "scripts": {
47
+ "build": "tsup && chmod +x dist/index.js",
48
+ "dev": "tsup --watch",
49
+ "clean": "rm -rf dist",
50
+ "test": "echo 'Tests coming soon'"
51
+ }
52
+ }