@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 +30 -7
- package/dist/cli/create.js +1 -1
- package/dist/cli/dispatch.d.ts +4 -0
- package/dist/cli/dispatch.d.ts.map +1 -1
- package/dist/cli/dispatch.js +29 -0
- package/dist/mcp/api.json +601 -0
- package/dist/mcp/concepts/custom-element-registry.md +92 -0
- package/dist/mcp/concepts/event-system.md +45 -0
- package/dist/mcp/concepts/implementation-priority.md +10 -0
- package/dist/mcp/concepts/mc-types.md +349 -0
- package/dist/mcp/concepts/microcomponent-architecture.md +31 -0
- package/dist/mcp/concepts/state-management.md +18 -0
- package/dist/mcp/index.d.ts +3 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +264 -0
- package/package.json +18 -9
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
|
|
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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
|
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
|
|
package/dist/cli/create.js
CHANGED
|
@@ -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.
|
|
84
|
+
'@twobirds/microcomponents': '^0.6.0',
|
|
85
85
|
},
|
|
86
86
|
devDependencies: {
|
|
87
87
|
vite: '^8.1.5',
|
package/dist/cli/dispatch.d.ts
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/cli/dispatch.js
CHANGED
|
@@ -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;
|