@twobirds/microcomponents 0.5.0 → 0.7.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/README.md CHANGED
@@ -46,6 +46,21 @@ An MCP (Model Context Protocol) server ships with the package so AI assistants c
46
46
  microcomponents-mcp # stdio server, straight from the installed package
47
47
  ```
48
48
 
49
+ `mc create` writes an `opencode.jsonc` into every scaffolded project, so opencode picks the server up as soon as you open the project — no config edit needed. opencode reads the project config from the repo root, and the server is started through `npx`, which resolves the version the project installed:
50
+
51
+ ```jsonc
52
+ {
53
+ "$schema": "https://opencode.ai/config.json",
54
+ "mcp": {
55
+ "microcomponents": {
56
+ "type": "local",
57
+ "command": ["npx", "-p", "@twobirds/microcomponents", "microcomponents-mcp"],
58
+ "enabled": true,
59
+ },
60
+ },
61
+ }
62
+ ```
63
+
49
64
  In a published package the server runs from `dist/mcp` and reads the prebuilt `api.json` and the concept essays that the build step emits next to it. During development it generates the index live from `src/` at startup, so it cannot drift away from the library it documents:
50
65
 
51
66
  ```bash
@@ -80,11 +95,12 @@ pnpm run cli -- new my-card --target-html --target-css --dry-run
80
95
  # would create src/my/card.target.css
81
96
  ```
82
97
 
83
- `mc create` scaffolds a complete dev environment for a namespace — a Vite dev server serving `src/` straight, a page shell that turns on `autoload(true)`, and a starter component with companion assets:
98
+ `mc create` scaffolds a complete dev environment for a namespace — a Vite dev server serving `src/` straight, a page shell that turns on `autoload(true)`, a starter component with companion assets, and an `opencode.jsonc` that registers the MCP server:
84
99
 
85
100
  ```bash
86
101
  pnpm run cli -- create --namespace mc --dir mc-app
87
102
  # created mc-app/package.json
103
+ # created mc-app/opencode.jsonc
88
104
  # created mc-app/src/index.html
89
105
  # created mc-app/src/mc/app.ts
90
106
  # created mc-app/src/mc/app.target.html
@@ -109,16 +125,31 @@ pnpm run cli -- create --namespace mc
109
125
  # rerun with --force to overwrite
110
126
  ```
111
127
 
112
- Once installed from npm the same command is available as `mc`:
128
+ Once installed from npm the same command is available as `mc` (and as `microcomponents`, the same executable under the package name):
113
129
 
114
130
  ```bash
115
131
  mc new my-card [--css] [--html] [--target-html] [--shadow-html] [--target-css] [--shadow-css] [--js] [--dir <path>] [--force] [--dry-run]
116
132
  mc create --namespace <ns> [--dir <path>] [--force] [--dry-run]
117
133
  mc clean
118
134
  mc check
135
+ mc --version
119
136
  ```
120
137
 
121
- `clean` and `check` are thin wrappers around the package.json scripts of the same name, so the scripts remain the single source of truth for what they do — `mc check` type-checks every project context (lib, cli, mcp, test, demo, node) and exits with the script's exit code.
138
+ `clean` and `check` are thin wrappers around the package.json scripts of the same name, so the scripts remain the single source of truth for what they do — `mc check` type-checks every project context (lib, cli, mcp, test, demo, node) and exits with the script's exit code. `mc --version` (`-v`) prints the version of the package the CLI ships in, read from its own package.json, so it reports the installed library, not the version of the project the command runs in.
139
+
140
+ Nothing has to be installed to run it once — `npx` fetches the package into its own cache and runs the bin from there:
141
+
142
+ ```bash
143
+ npx @twobirds/microcomponents mc --help
144
+ npx @twobirds/microcomponents new my-card --target-html --target-css --dry-run
145
+ ```
146
+
147
+ `npx <package>` alone has no bin name to run, so npm picks the bin whose key matches the unscoped package name — that is why `bin` lists `microcomponents` next to `mc`. With `-p` the package is named explicitly and the word after it is read as the bin name, so `mc` and the MCP server can be started by name:
148
+
149
+ ```bash
150
+ npx -p @twobirds/microcomponents mc new my-card --target-html --target-css
151
+ npx -p @twobirds/microcomponents microcomponents-mcp
152
+ ```
122
153
 
123
154
  The scaffold derives the file path from the tag using the same rule the runtime autoload loader uses (`my-card` → `my/card.ts`), names companion assets after the runtime's asset descriptors (`targetHtml` → `card.target.html`), and wires them into a `static assets` declaration. `--js` emits a plain JavaScript file for the rapid-prototyping path.
124
155
 
@@ -1 +1 @@
1
- {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/cli/create.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;EAkBE;AAUF;;;;;;;;;;EAUE;AACF,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,yCAAyC;AACzC,MAAM,WAAW,aAAa;IAC7B,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;EAYE;AACF,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,CAuBhE"}
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/cli/create.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;EAkBE;AAUF;;;;;;;;;;EAUE;AACF,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,yCAAyC;AACzC,MAAM,WAAW,aAAa;IAC7B,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;EAYE;AACF,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,CAwBhE"}
@@ -62,6 +62,7 @@ export function scaffoldProject(namespace) {
62
62
  files['tsconfig.vc.json'] = tsconfigVc();
63
63
  files['vite.config.ts'] = viteConfig(namespace);
64
64
  files['.gitignore'] = gitignore();
65
+ files['opencode.jsonc'] = opencodeConfig();
65
66
  files['README.md'] = readme(namespace, tag);
66
67
  files['src/index.html'] = shell(namespace, tag);
67
68
  files[`src/${base}.ts`] = appSource(namespace, tag);
@@ -81,7 +82,7 @@ function packageJson(namespace) {
81
82
  typecheck: 'tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.vc.json',
82
83
  },
83
84
  dependencies: {
84
- '@twobirds/microcomponents': '^0.5.0',
85
+ '@twobirds/microcomponents': '^0.7.0',
85
86
  },
86
87
  devDependencies: {
87
88
  vite: '^8.1.5',
@@ -126,6 +127,18 @@ function gitignore() {
126
127
  dist/
127
128
  `;
128
129
  }
130
+ function opencodeConfig() {
131
+ return JSON.stringify({
132
+ $schema: 'https://opencode.ai/config.json',
133
+ mcp: {
134
+ microcomponents: {
135
+ type: 'local',
136
+ command: ['npx', '-p', '@twobirds/microcomponents', 'microcomponents-mcp'],
137
+ enabled: true,
138
+ },
139
+ },
140
+ }, null, '\t');
141
+ }
129
142
  function readme(namespace, tag) {
130
143
  return `# ${namespace} App
131
144
 
@@ -38,6 +38,10 @@ const code = await main(['clean'], async (script) => {
38
38
  return 0;
39
39
  });
40
40
  ```
41
+ @example
42
+ ```ts
43
+ const code = await main(['--version']);
44
+ ```
41
45
  */
42
46
  export declare function main(argv: string[], run?: Runner): Promise<number>;
43
47
  //# sourceMappingURL=dispatch.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../src/cli/dispatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;EAYE;AAsDF,MAAM,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAqGzD;;;;;;;;;;;;EAYE;AACF,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ/D;AAED;;;;;;;;;;;;EAYE;AACF,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,GAAE,MAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAwGnF"}
1
+ {"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../src/cli/dispatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;EAYE;AA0DF,MAAM,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAwHzD;;;;;;;;;;;;EAYE;AACF,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ/D;AAED;;;;;;;;;;;;;;;;EAgBE;AACF,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,GAAE,MAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CA8GnF"}
@@ -26,6 +26,8 @@ Usage:
26
26
  mc create --namespace <ns> [--dir <path>] [--force] [--dry-run]
27
27
  mc clean
28
28
  mc check
29
+ mc --version
30
+ mc --help
29
31
 
30
32
  Commands:
31
33
  new <tag> Scaffold a micro component (e.g. mc new my-card --target-html --target-css)
@@ -46,6 +48,8 @@ Other options:
46
48
  --dir <path> scaffold root (default: src)
47
49
  --force overwrite files that already exist
48
50
  --dry-run print what would be written; touch nothing on disk
51
+ --version print the version of the package the CLI ships in (-v)
52
+ --help print this text (-h)
49
53
 
50
54
  Created paths are printed as they appear from the current directory. mc create writes
51
55
  a whole project into a folder of its own (default: the namespace), so its files show
@@ -153,6 +157,22 @@ async function checkSelf(cwd = process.cwd()) {
153
157
  return spawnProcess('pnpm', ['exec', 'tsc', '--noEmit', '-p', 'tsconfig.json'], cwd);
154
158
  }
155
159
  /**
160
+ The version of the package the CLI ships in, read from its package.json. Two
161
+ levels above `dist/cli` (and above `src/cli` when tsx runs the source) is the
162
+ package root, so the CLI reports the version it was installed with, not the
163
+ version of the project it is run in.
164
+
165
+ @example
166
+ ```ts
167
+ const version = await readVersion();
168
+ ```
169
+ @param pkgPath - package.json to read (defaults to the package root of this CLI).
170
+ */
171
+ async function readVersion(pkgPath = path.join(import.meta.dirname, '..', '..', 'package.json')) {
172
+ const { version } = JSON.parse(await readFile(pkgPath, 'utf8'));
173
+ return version;
174
+ }
175
+ /**
156
176
  Runs a package.json script through pnpm and resolves with its exit code.
157
177
 
158
178
  Thin wrappers like `clean` and `check` delegate here so the script — not the
@@ -188,6 +208,10 @@ const code = await main(['clean'], async (script) => {
188
208
  return 0;
189
209
  });
190
210
  ```
211
+ @example
212
+ ```ts
213
+ const code = await main(['--version']);
214
+ ```
191
215
  */
192
216
  export async function main(argv, run = runScript) {
193
217
  const { values, positionals } = parseArgs({
@@ -206,9 +230,14 @@ export async function main(argv, run = runScript) {
206
230
  force: { type: 'boolean' },
207
231
  'dry-run': { type: 'boolean' },
208
232
  help: { type: 'boolean', short: 'h' },
233
+ version: { type: 'boolean', short: 'v' },
209
234
  },
210
235
  });
211
236
  const command = positionals[0];
237
+ if (values.version) {
238
+ console.log(await readVersion());
239
+ return 0;
240
+ }
212
241
  if (values.help || !command) {
213
242
  console.log(USAGE);
214
243
  return 0;
package/dist/mcp/api.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "libraryVersion": "0.5.0",
2
+ "libraryVersion": "0.7.0",
3
3
  "exportedCount": 41,
4
4
  "entries": {
5
5
  "MC": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twobirds/microcomponents",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "Micro Components",
5
5
  "keywords": [
6
6
  "PWA",
@@ -34,6 +34,7 @@
34
34
  },
35
35
  "bin": {
36
36
  "mc": "./dist/cli/index.js",
37
+ "microcomponents": "./dist/cli/index.js",
37
38
  "microcomponents-mcp": "./dist/mcp/index.js"
38
39
  },
39
40
  "files": [