@miakapp/cli 4.0.0-alpha.0 → 4.0.0-alpha.10
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 +151 -35
- package/assets/agent-guide.md +232 -79
- package/assets/design/OFL-Manrope.txt +93 -0
- package/assets/design/components.css +139 -0
- package/assets/design/fonts.css +9 -0
- package/assets/design/gallery.html +667 -0
- package/assets/design/guide.md +77 -0
- package/assets/design/tokens.css +185 -0
- package/assets/starter/app/app/README.md +74 -0
- package/assets/starter/app/app/main.ts +124 -0
- package/assets/starter/app/app/miakapp.ts +156 -0
- package/assets/starter/app/app/theme.ts +8 -0
- package/assets/starter/app/tsconfig.json +23 -0
- package/bin/miakapp.js +5 -1
- package/dist/agent-pack.d.ts +11 -3
- package/dist/agent-pack.d.ts.map +1 -1
- package/dist/agent-pack.js +26 -10
- package/dist/agent-pack.js.map +1 -1
- package/dist/contexts.d.ts +59 -0
- package/dist/contexts.d.ts.map +1 -0
- package/dist/contexts.js +388 -0
- package/dist/contexts.js.map +1 -0
- package/dist/control-plane.d.ts +14 -0
- package/dist/control-plane.d.ts.map +1 -1
- package/dist/control-plane.js +33 -1
- package/dist/control-plane.js.map +1 -1
- package/dist/internal/names.d.ts +5 -0
- package/dist/internal/names.d.ts.map +1 -1
- package/dist/internal/names.js +6 -0
- package/dist/internal/names.js.map +1 -1
- package/dist/main.d.ts +22 -5
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +673 -60
- package/dist/main.js.map +1 -1
- package/dist/mcp.d.ts +7 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +195 -26
- package/dist/mcp.js.map +1 -1
- package/dist/pairing.d.ts +27 -0
- package/dist/pairing.d.ts.map +1 -0
- package/dist/pairing.js +148 -0
- package/dist/pairing.js.map +1 -0
- package/dist/project.d.ts +3 -1
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +33 -6
- package/dist/project.js.map +1 -1
- package/dist/publication.d.ts +20 -5
- package/dist/publication.d.ts.map +1 -1
- package/dist/publication.js +58 -16
- package/dist/publication.js.map +1 -1
- package/dist/starter.d.ts +17 -0
- package/dist/starter.d.ts.map +1 -0
- package/dist/starter.js +72 -0
- package/dist/starter.js.map +1 -0
- package/dist/terminal.d.ts +10 -0
- package/dist/terminal.d.ts.map +1 -0
- package/dist/terminal.js +70 -0
- package/dist/terminal.js.map +1 -0
- package/dist/version.d.ts +15 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +15 -0
- package/dist/version.js.map +1 -0
- package/package.json +6 -4
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @miakapp/cli
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Pair, build, validate, publish and roll back independent Miakapp house applications.
|
|
4
4
|
|
|
5
5
|
The CLI is the deployment mechanism, not the source of truth. **Git belongs to
|
|
6
6
|
you**: this tool never commits, never rewrites sources it did not generate and
|
|
@@ -12,11 +12,60 @@ stable exit code and one stable failure kind, and `--json` prints exactly one
|
|
|
12
12
|
object on stdout.
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
bunx @miakapp/cli
|
|
16
|
-
bunx @miakapp/cli
|
|
17
|
-
|
|
15
|
+
printf '%s\n' "$CODE" | bunx @miakapp/cli pair --issuer "$MIAKAPP_ISSUER"
|
|
16
|
+
bunx @miakapp/cli init --starter app # manifest + app to edit; home and issuer from the context
|
|
17
|
+
bun run build && bun run check # after the inventory and adapting app/main.ts
|
|
18
|
+
bunx @miakapp/cli publish
|
|
19
|
+
bunx @miakapp/cli status # verify what is live
|
|
18
20
|
```
|
|
19
21
|
|
|
22
|
+
Use the exact issuer command shown by your deployment's `/pair` page; do not
|
|
23
|
+
guess a staging issuer. Open and verify the returned `home_url` as a resident
|
|
24
|
+
before handing it over.
|
|
25
|
+
|
|
26
|
+
## The app starter
|
|
27
|
+
|
|
28
|
+
`miakapp init --starter app` writes, beside `miakapp.yaml`, everything needed to
|
|
29
|
+
build a whole-house application with nothing but this package and Bun:
|
|
30
|
+
|
|
31
|
+
| File | |
|
|
32
|
+
| --- | --- |
|
|
33
|
+
| `app/main.ts` | the interface to edit: shows what the home shares, grouped, with stale and empty states |
|
|
34
|
+
| `app/miakapp.ts` | the bridge to `window.miakapp` — byte for byte the `@miakapp/app` SDK source, which is not on npm yet |
|
|
35
|
+
| `app/theme.ts` | Miakapp design tokens, themes (Minuit in dark mode, Lumière in light) and recipes, with Manrope embedded |
|
|
36
|
+
| `package.json` | `build` (Bun IIFE to the manifest's artifact), `typecheck`, `check`; pins this CLI and TypeScript |
|
|
37
|
+
| `tsconfig.json` | strict TypeScript for `app/` |
|
|
38
|
+
| `app/README.md` | the loop, the prerequisites and what to do before publishing |
|
|
39
|
+
|
|
40
|
+
Prerequisites: Node.js ≥ 22.9 for the CLI, Bun ≥ 1.2.23 for `bun run build`
|
|
41
|
+
(TypeScript, from `bun install`, only for `typecheck`). The starter accepts
|
|
42
|
+
`--artifact` (a plain relative `.js` path), `--release`, `--home`,
|
|
43
|
+
`--control-plane` and `--context`; it cannot be combined with
|
|
44
|
+
`--kind component`.
|
|
45
|
+
|
|
46
|
+
It never overwrites anything: every target is checked first, and if any one
|
|
47
|
+
exists the command fails with exit 2 and writes nothing. Without `--starter`,
|
|
48
|
+
`init` writes `miakapp.yaml` alone, as before.
|
|
49
|
+
|
|
50
|
+
The starter invents no value and offers no control. `app.requires` starts
|
|
51
|
+
empty, so a fresh build shows only an empty state: inventory the house, declare
|
|
52
|
+
the paths and calls, give them resident-facing names and a real layout, then
|
|
53
|
+
publish.
|
|
54
|
+
|
|
55
|
+
## Design
|
|
56
|
+
|
|
57
|
+
`miakapp docs design` prints a short design guide and the directory of the
|
|
58
|
+
files it describes: `tokens.css` (four themes: Minuit, Lumière, Miel, Craie),
|
|
59
|
+
`components.css` (glass, device tile, scene, switch, level slider, stale
|
|
60
|
+
banner), `fonts.css` (Manrope as a `data:` URL, since the frame has no network)
|
|
61
|
+
and `gallery.html`, example screens to open in a browser. They are a starting
|
|
62
|
+
point, not a framework: copy, change or ignore them.
|
|
63
|
+
|
|
64
|
+
Maintainers: the generated files (`fonts.css`, `gallery.html`, the starter's
|
|
65
|
+
`app/theme.ts`) come from `packages/cli/design/`; run `bun design/build.ts` in
|
|
66
|
+
`packages/cli` after editing `tokens.css`, `components.css` or the gallery
|
|
67
|
+
template. A test fails when they drift.
|
|
68
|
+
|
|
20
69
|
## The project file
|
|
21
70
|
|
|
22
71
|
`miakapp.yaml` sits at the root of your repository:
|
|
@@ -24,24 +73,25 @@ bunx @miakapp/cli publish --expected-generation 0
|
|
|
24
73
|
```yaml
|
|
25
74
|
schema: miakapp.project/1
|
|
26
75
|
home: my-home
|
|
27
|
-
control_plane: https://control.
|
|
76
|
+
control_plane: https://control.example.test
|
|
28
77
|
|
|
29
|
-
|
|
30
|
-
artifact: dist/
|
|
31
|
-
release: 2026-
|
|
78
|
+
app:
|
|
79
|
+
artifact: dist/app.js
|
|
80
|
+
release: 2026-10-03.1
|
|
32
81
|
requires:
|
|
33
82
|
state_read:
|
|
34
83
|
- climate.living_room.temperature
|
|
35
|
-
event_subscribe: []
|
|
36
|
-
event_publish: []
|
|
37
84
|
call:
|
|
38
85
|
- lighting.set
|
|
39
|
-
presentation: []
|
|
40
86
|
|
|
41
87
|
coordinator:
|
|
42
88
|
entry: coordinator/main.ts
|
|
43
89
|
```
|
|
44
90
|
|
|
91
|
+
`app` declares only `state_read` and `call`; events, media and reserved
|
|
92
|
+
`miakapp.*` calls are unavailable. Use `miakapp init --kind component` for the
|
|
93
|
+
semantic component ABI instead. Choose exactly one of `app` and `component`.
|
|
94
|
+
|
|
45
95
|
`requires` is the closed RFC 0002 capability object. Lists are de-duplicated and
|
|
46
96
|
sorted before they are bound into an upload capability, so the value the CLI
|
|
47
97
|
sends is byte-identical on every later reconciliation read.
|
|
@@ -55,10 +105,13 @@ duplicate keys — is rejected with the offending line rather than guessed at.
|
|
|
55
105
|
|
|
56
106
|
| Command | What it does |
|
|
57
107
|
| --- | --- |
|
|
58
|
-
| `
|
|
108
|
+
| `pair` | Redeems a one-time pairing code into a new stored context. |
|
|
109
|
+
| `context list\|show\|use\|remove` | Manages stored contexts. Never prints a key. |
|
|
110
|
+
| `init` | Writes `miakapp.yaml`; with `--starter app`, also a buildable app. Never overwrites. |
|
|
59
111
|
| `agent-pack` | Offline. Installs the guide and the MCP wiring into a repository. |
|
|
60
112
|
| `discover` | Offline. Inventories a Node-RED installation from its flows export. |
|
|
61
113
|
| `check` | Offline. Parses the project, verifies the artifact, prints the digest. |
|
|
114
|
+
| `status` | Reads the live generation, release and digest of the home. |
|
|
62
115
|
| `publish` | Capability → delivery → finalization → activation, in one run. |
|
|
63
116
|
| `activate` | Activates an already finalized digest at a new generation. |
|
|
64
117
|
| `rollback` | Alias of `activate`, for returning to a known-good digest. |
|
|
@@ -111,9 +164,9 @@ place instead of appending another copy. `.mcp.json` is merged as a structure
|
|
|
111
164
|
one key, by name — so every other server in it survives, and a file that does
|
|
112
165
|
not parse is refused rather than replaced with a valid one.
|
|
113
166
|
|
|
114
|
-
The server
|
|
115
|
-
|
|
116
|
-
|
|
167
|
+
The generated server entry uses `npx -y @miakapp/cli@<installed-version> mcp`,
|
|
168
|
+
so a new machine gets the same executable as the bundled guide without relying
|
|
169
|
+
on a global binary or this machine's directory layout.
|
|
117
170
|
|
|
118
171
|
Run it again whenever the CLI is upgraded: an unchanged file is reported
|
|
119
172
|
`unchanged`, and a guide that moved on is reported `updated`.
|
|
@@ -129,8 +182,7 @@ tools over newline-delimited JSON-RPC on stdio.
|
|
|
129
182
|
"mcpServers": {
|
|
130
183
|
"miakapp": {
|
|
131
184
|
"command": "bunx",
|
|
132
|
-
"args": ["@miakapp/cli", "mcp"]
|
|
133
|
-
"env": { "MIAKAPP_HOME_KEY": "${MIAKAPP_HOME_KEY}" }
|
|
185
|
+
"args": ["@miakapp/cli", "mcp"]
|
|
134
186
|
}
|
|
135
187
|
}
|
|
136
188
|
}
|
|
@@ -138,11 +190,17 @@ tools over newline-delimited JSON-RPC on stdio.
|
|
|
138
190
|
|
|
139
191
|
| Tool | Command | |
|
|
140
192
|
| --- | --- | --- |
|
|
193
|
+
| `miakapp_pair` | `pair` | stores a new context; the code is a tool argument |
|
|
194
|
+
| `miakapp_context_list` | `context list` | read-only, offline |
|
|
195
|
+
| `miakapp_context_show` | `context show` | read-only, offline |
|
|
196
|
+
| `miakapp_context_use` | `context use` | offline, changes the current context |
|
|
197
|
+
| `miakapp_context_remove` | `context remove` | **deletes a stored key — needs `confirm: true`** |
|
|
198
|
+
| `miakapp_status` | `status` | read-only |
|
|
141
199
|
| `miakapp_discover` | `discover` | read-only, offline |
|
|
142
200
|
| `miakapp_check` | `check` | read-only, offline |
|
|
143
201
|
| `miakapp_release` | `release` | read-only |
|
|
144
202
|
| `miakapp_upload` | `upload` | read-only |
|
|
145
|
-
| `miakapp_init` | `init` | writes `miakapp.yaml
|
|
203
|
+
| `miakapp_init` | `init` | writes `miakapp.yaml` (and the app starter with `starter: "app"`), never overwrites |
|
|
146
204
|
| `miakapp_agent_pack` | `agent-pack` | offline, writes the pack into a repository |
|
|
147
205
|
| `miakapp_publish` | `publish` | **moves the pointer — needs `confirm: true`** |
|
|
148
206
|
| `miakapp_activate` | `activate` | **moves the pointer — needs `confirm: true`** |
|
|
@@ -154,7 +212,8 @@ drift apart. A tool argument is the option name with `_` for `-`
|
|
|
154
212
|
(`expected_generation` → `--expected-generation`); an argument the tool does not
|
|
155
213
|
declare is refused rather than ignored.
|
|
156
214
|
|
|
157
|
-
The three pointer-moving tools
|
|
215
|
+
The three pointer-moving tools and `miakapp_context_remove` additionally
|
|
216
|
+
require `confirm: true`. It is
|
|
158
217
|
checked before anything else and never reaches the command line, so a model that
|
|
159
218
|
hallucinated a publication spends the mistake on an argument check instead of on
|
|
160
219
|
a generation.
|
|
@@ -165,20 +224,69 @@ remedy — not as a JSON-RPC error. That distinction matters: a protocol error
|
|
|
165
224
|
means the call never happened, while a publication that reached the control
|
|
166
225
|
plane and failed did happen, and only `kind` says whether to reconcile.
|
|
167
226
|
|
|
168
|
-
##
|
|
227
|
+
## Access: pairing and contexts
|
|
228
|
+
|
|
229
|
+
The owner grants access in their own browser; the agent never signs in. They
|
|
230
|
+
open `https://miakapp.com/pair`, choose the home, confirm, and send the
|
|
231
|
+
one-time code, which `pair` trades for a **new, separately revocable** Home Key:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
printf '%s\n' "$CODE" | miakapp pair # or run it in a terminal: hidden prompt
|
|
235
|
+
miakapp pair --code "$CODE" # allowed, but lands in shell history
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
| Option | Default |
|
|
239
|
+
| --- | --- |
|
|
240
|
+
| `--issuer <https url>` | `https://control.miakapp.com` |
|
|
241
|
+
| `--label <label>` | `miakapp-cli@<host name>`, shown in the owner's key list |
|
|
242
|
+
| `--name <context>` | the paired home ID (`-2`, `-3`… if taken) |
|
|
243
|
+
|
|
244
|
+
Before the code is sent, the issuer must serve a discovery document naming
|
|
245
|
+
exactly itself; redirects are refused. The redeem response —
|
|
246
|
+
`POST {issuer}/v1/pairing/redeem` with `{code, label}`, answered with
|
|
247
|
+
`{home_key, home_id, key_id, issuer}` and `Cache-Control: no-store` — must name
|
|
248
|
+
the same issuer and a key whose ID is embedded in the key. The code is sent
|
|
249
|
+
once and never retried: a lost response is exit 7, because a key may exist.
|
|
250
|
+
`pair` then exchanges the key for a publication token, reported as
|
|
251
|
+
`publish_access`, so a key without the publish scope is caught now rather than
|
|
252
|
+
at the first publication.
|
|
253
|
+
|
|
254
|
+
Contexts live in `~/.miakapp` (or `$MIAKAPP_CONFIG_DIR`, absolute):
|
|
255
|
+
|
|
256
|
+
| File | Holds | Mode |
|
|
257
|
+
| --- | --- | --- |
|
|
258
|
+
| `config.json` | context names, home IDs, issuers, key IDs, labels, current context | 0600 |
|
|
259
|
+
| `credentials.json` | the Home Keys, nothing else | 0600 |
|
|
169
260
|
|
|
170
|
-
The
|
|
171
|
-
|
|
172
|
-
|
|
261
|
+
The directory is 0700. Both files are replaced through a temporary file, an
|
|
262
|
+
fsync and a rename, under a lock file, so concurrent runs never lose a context
|
|
263
|
+
and a crash never leaves half a file. A credentials file readable by another
|
|
264
|
+
account, a symbolic link, a foreign owner or a key that is not the one the
|
|
265
|
+
context was paired with is refused rather than used.
|
|
173
266
|
|
|
174
267
|
```bash
|
|
175
|
-
|
|
176
|
-
|
|
268
|
+
miakapp context list
|
|
269
|
+
miakapp context show [name] # credential: stored (never printed)
|
|
270
|
+
miakapp context use <name>
|
|
271
|
+
miakapp context remove <name> # local only: the owner revokes the key server-side
|
|
177
272
|
```
|
|
178
273
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
274
|
+
Which Home Key a command uses, highest precedence first:
|
|
275
|
+
|
|
276
|
+
1. `--context <name>`, then `MIAKAPP_CONTEXT=<name>`;
|
|
277
|
+
2. `MIAKAPP_HOME_KEY` — a raw key, kept for CI and compatibility;
|
|
278
|
+
3. the stored context whose home and issuer match `miakapp.yaml`, the current
|
|
279
|
+
context breaking a tie between keys for that same home.
|
|
280
|
+
|
|
281
|
+
A selected context for another home — or a `MIAKAPP_HOME_KEY` this machine
|
|
282
|
+
knows was paired with another home — is refused before any request, so a key
|
|
283
|
+
can never publish into the wrong house. Every networked result reports
|
|
284
|
+
`credential_source` and `context`, never the key.
|
|
285
|
+
|
|
286
|
+
No command accepts a Home Key as an argument: an argument lands in shell
|
|
287
|
+
history, in a process listing and in most CI logs. The key is exchanged for a
|
|
288
|
+
five-minute `components:publish` token before every run, and publication
|
|
289
|
+
endpoints never see the Home Key itself.
|
|
182
290
|
|
|
183
291
|
## Generations
|
|
184
292
|
|
|
@@ -187,11 +295,11 @@ believe the pointer holds, and `--generation` (default: expected + 1) is the one
|
|
|
187
295
|
you are publishing. A stale expectation fails with `generation_conflict` and
|
|
188
296
|
exit code 6 rather than last-write-wins.
|
|
189
297
|
|
|
190
|
-
`--expected-generation`
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
298
|
+
Without `--expected-generation`, `publish` and `activate` read the live pointer
|
|
299
|
+
first (`GET /v1/homes/{homeId}/component-pointer`, RFC 0004 §13.2) and use its
|
|
300
|
+
generation. That read takes no lock, so the activation is still a
|
|
301
|
+
compare-and-set: a publication that lands in between makes this one fail with
|
|
302
|
+
exit 6, never overwrites it. `miakapp status` prints the same read.
|
|
195
303
|
|
|
196
304
|
## Exit codes
|
|
197
305
|
|
|
@@ -213,14 +321,14 @@ committed, so the next step is a read — `miakapp upload <id>` or
|
|
|
213
321
|
## Failure output
|
|
214
322
|
|
|
215
323
|
```console
|
|
216
|
-
$ miakapp publish
|
|
324
|
+
$ miakapp publish
|
|
217
325
|
miakapp: conflict: Activation failed with HTTP 409 generation_conflict (request Zq1...)
|
|
218
326
|
Another publication advanced the pointer. Read the active generation and retry
|
|
219
327
|
the activation with the observed expected_generation.
|
|
220
328
|
```
|
|
221
329
|
|
|
222
330
|
```console
|
|
223
|
-
$ miakapp publish --
|
|
331
|
+
$ miakapp publish --json
|
|
224
332
|
{"ok":false,"kind":"conflict","exit_code":6,"message":"...","remedy":"..."}
|
|
225
333
|
```
|
|
226
334
|
|
|
@@ -228,3 +336,11 @@ $ miakapp publish --expected-generation 0 --json
|
|
|
228
336
|
|
|
229
337
|
Alpha, tracking Miakapp 4. The package is `private` until the control plane it
|
|
230
338
|
talks to is deployed; publishing it to npm is a deliberate, separate step.
|
|
339
|
+
|
|
340
|
+
### Command help
|
|
341
|
+
|
|
342
|
+
Run `miakapp help` or append `--help` / `-h` to any command, including
|
|
343
|
+
`miakapp pair --help`. Help never prompts for a code or executes the command.
|
|
344
|
+
`miakapp init` defaults to a whole-house app at `dist/app.js`; add
|
|
345
|
+
`--starter app` for the buildable starter, or use `--kind component` for a
|
|
346
|
+
semantic component at `dist/component.js`.
|