@twobirds/microcomponents 0.4.1 → 0.6.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
@@ -40,17 +40,25 @@ The progress of coding is occasionally being streamed on [twitch](https://twitch
40
40
 
41
41
  ## MCP Server
42
42
 
43
- An MCP (Model Context Protocol) server ships with this repo so AI assistants can look the library up instead of answering from memory: `microcomponents-mcp-server.ts` at the repo root.
43
+ An MCP (Model Context Protocol) server ships with the package so AI assistants can look the library up instead of answering from memory. The source is `src/mcp/index.ts`, compiled by `tsconfig.mcp.json` to `dist/mcp/index.js` and published with the package, so installing it gives you the executable bin:
44
44
 
45
45
  ```bash
46
- pnpm run mcp:run # start the server on stdio
47
- pnpm run mcp:dev # restart it whenever src/ changes
48
- pnpm run mcp:docs # regenerate docs/api.json and report undocumented exports
46
+ microcomponents-mcp # stdio server, straight from the installed package
47
+ ```
48
+
49
+ 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
+
51
+ ```bash
52
+ pnpm run mcp:dev # restart it whenever src/ changes
53
+ pnpm run mcp:run # start it from source on stdio
54
+ pnpm run mcp:docs # regenerate dist/mcp/api.json and report undocumented exports
49
55
  ```
50
56
 
51
57
  Tools: `list-components`, `get-component-docs`, `search-components`, `get-core-concept`, `get-source-file`, `list-undocumented`.
52
58
 
53
- There is no hand-written API list in the server. The whole index is extracted at startup from the JSDoc blocks of the public exports (the names re-exported by each `src/*/index.ts`), so it can never drift away from the code it documents — and `list-undocumented` tells you when a source file still lacks a doc block. Concept essays are hand-authored markdown, one file per concept under `docs/concepts/`, which is also where the tool's list of available concepts comes from.
59
+ There is no hand-written API list in the server. The whole index is extracted from the JSDoc blocks of the public exports (the names re-exported by each `src/*/index.ts`), so it can never drift away from the code it documents — and `list-undocumented` tells you when a source file still lacks a doc block. Concept essays are hand-authored markdown, one file per concept under `docs/concepts/`, copied into `dist/mcp/concepts` by the build, which is where the tool's list of available concepts comes from.
60
+
61
+ `get-source-file` reads package-root relative paths (`dist/core/MC.d.ts`, `dist/mcp/concepts/event-system.md`) and refuses any path outside the package sources.
54
62
 
55
63
  ## CLI
56
64
 
@@ -101,16 +109,31 @@ pnpm run cli -- create --namespace mc
101
109
  # rerun with --force to overwrite
102
110
  ```
103
111
 
104
- Once installed from npm the same command is available as `mc`:
112
+ Once installed from npm the same command is available as `mc` (and as `microcomponents`, the same executable under the package name):
105
113
 
106
114
  ```bash
107
115
  mc new my-card [--css] [--html] [--target-html] [--shadow-html] [--target-css] [--shadow-css] [--js] [--dir <path>] [--force] [--dry-run]
108
116
  mc create --namespace <ns> [--dir <path>] [--force] [--dry-run]
109
117
  mc clean
110
118
  mc check
119
+ mc --version
111
120
  ```
112
121
 
113
- `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, test, demo, node) and exits with the script's exit code.
122
+ `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.
123
+
124
+ Nothing has to be installed to run it once — `npx` fetches the package into its own cache and runs the bin from there:
125
+
126
+ ```bash
127
+ npx @twobirds/microcomponents mc --help
128
+ npx @twobirds/microcomponents new my-card --target-html --target-css --dry-run
129
+ ```
130
+
131
+ `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:
132
+
133
+ ```bash
134
+ npx -p @twobirds/microcomponents mc new my-card --target-html --target-css
135
+ npx -p @twobirds/microcomponents microcomponents-mcp
136
+ ```
114
137
 
115
138
  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.
116
139
 
@@ -81,7 +81,7 @@ function packageJson(namespace) {
81
81
  typecheck: 'tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.vc.json',
82
82
  },
83
83
  dependencies: {
84
- '@twobirds/microcomponents': '^0.4.1',
84
+ '@twobirds/microcomponents': '^0.6.0',
85
85
  },
86
86
  devDependencies: {
87
87
  vite: '^8.1.5',
@@ -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;