@appshell/cli 1.0.0-alpha.10 → 1.0.0-alpha.101

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
@@ -41,51 +41,240 @@ pnpm add -D @appshell/cli
41
41
  appshell [command]
42
42
 
43
43
  Commands:
44
- appshell generate [target] Generates a resource
45
- appshell register Register one or more appshell manifests
46
- appshell start Start the appshell runtime environment
44
+ appshell generate [target] Generates a resource
45
+ appshell config [target] Configures the appshell cli
46
+ appshell app <target> Manage appshell applications
47
+ appshell dev Point an application at this package running
48
+ locally, for this browser only
49
+ appshell login Authenticate with an appshell registry
50
+ appshell logout Discard the stored credential for a registry
51
+ appshell publish Publish a package to the appshell registry
52
+ appshell unpublish <name> <version> Remove a published package version
53
+ appshell trust Trust CI workflows to publish into a scope
54
+ without a stored secret
55
+ appshell outdated Analyzes shared dependencies for outdated versions
47
56
  ```
48
57
 
49
- ### appshell generate
58
+ These global options apply to every command:
59
+
60
+ | Option | Default | Purpose |
61
+ | ------ | ------- | ------- |
62
+ | `-r, --registry` | `http://localhost:7070` | Registry to operate against |
63
+ | `-a, --application` | — | Application, as `name` or `scope/name` |
64
+ | `--scopeId` | `default` | Scope owning unqualified packages and applications |
65
+ | `-k, --apiKey` | `""` | Api key, when the registry expects one |
66
+ | `-v, --verbose` | `false` | Verbose output |
67
+
68
+ `--registry` and `--application` fall back to `APPSHELL_REGISTRY` /
69
+ `APPSHELL_APPLICATION`, then to `~/.appshell/config`. Set them once instead of
70
+ passing them every time:
50
71
 
51
72
  ```bash
52
- appshell generate [target]
73
+ appshell config set registry http://localhost:7070
74
+ appshell config set application storefront
75
+ appshell config list
76
+ ```
53
77
 
54
- Generates a resource
78
+ ## Vocabulary
55
79
 
56
- Commands:
57
- appshell generate manifest Generate the appshell manifest by processing the template specified by --template
58
- appshell generate env Generate the runtime environment js file that reflects the current process.env
59
- appshell generate global-config Generate the global appshell configuration file by merging sources specifed by --registry options
60
- appshell generate metadata Generate the appshell metadata file by merging sources specifed by --registry options
80
+ | Term | Identity | What it is |
81
+ | ---- | -------- | ---------- |
82
+ | **Scope** | `acme` | Namespace and permission boundary |
83
+ | **Package** | `acme/checkout@1.5.0` | What you publish. Immutable, digest-addressed |
84
+ | **Application** | `acme/storefront` | The composition the registry serves |
85
+ | **Remote** | `PingModule/Ping` | What the browser loads, over Module Federation |
86
+
87
+ ## Authenticating
88
+
89
+ ```bash
90
+ appshell login # device flow against the configured issuer
91
+ appshell login --clientSecret ... # client credentials, for CI
92
+ appshell logout
61
93
  ```
62
94
 
63
- ## Generate manifest
95
+ The token is stored per registry. A registry running `AUTH_MODE=none` needs none —
96
+ commands only fail when the registry says so, and a 401 tells you to log in.
97
+ `APPSHELL_TOKEN` overrides the stored credential. A GitHub Actions job can publish with
98
+ neither — see [Trusted publishing](#trusted-publishing).
99
+
100
+ ## Publishing a package
101
+
102
+ ```bash
103
+ appshell publish --template dist/appshell.template.json
104
+ ```
105
+
106
+ Publishing is idempotent: the same content under the same version is a no-op.
107
+ Different content under an existing version is rejected unless the registry allows
108
+ forcing. When `--application` resolves, publish also **activates** the version there.
109
+
110
+ | Option | When omitted | Purpose |
111
+ | ------ | ------------ | ------- |
112
+ | `-t, --template` | `appshell.template.json` | Template to process |
113
+ | `--name` | the unscoped `package.json` name | Package name |
114
+ | `--package-version` | the `package.json` version | Version to publish as |
115
+ | `--visibility` | the registry defaults to `private` | Whether other scopes may activate it |
116
+ | `-w, --watch` | `false` | Republish whenever the template changes |
117
+
118
+ ```bash
119
+ appshell unpublish checkout 1.5.0
120
+ ```
121
+
122
+ ## Trusted publishing
123
+
124
+ A GitHub Actions workflow can publish into a scope with its own OIDC identity, so no
125
+ secret is stored anywhere. The scope's owner — or an organization admin, for a scope an
126
+ organization owns — records which workflow may:
127
+
128
+ ```bash
129
+ appshell trust add acme --github acme/widgets --workflow pipeline.yml --environment production
130
+ appshell trust list acme
131
+ appshell trust remove acme 1b2c3d4e # the id as `list` shows it
132
+ ```
133
+
134
+ `trust add` looks the repository up on GitHub and records it by its immutable ids, so a
135
+ renamed or transferred repository, or a new one taking the old name, does not inherit the
136
+ trust. Set `GITHUB_TOKEN` (or `GH_TOKEN`) to look up a private repository; `--github-api
137
+ https://<host>/api/v3` and `--issuer` cover GitHub Enterprise Server. Naming an
138
+ `--environment` is recommended: its protection rules then decide which branches and
139
+ reviewers can publish.
140
+
141
+ The workflow needs `id-token: write` and the registry's address, nothing else:
142
+
143
+ ```yaml
144
+ permissions: { id-token: write, contents: read }
145
+ env: { APPSHELL_REGISTRY: https://registry.appshell.org }
146
+ jobs:
147
+ publish:
148
+ runs-on: ubuntu-latest
149
+ environment: production
150
+ steps:
151
+ - uses: actions/checkout@v4
152
+ # ...build...
153
+ - run: npx appshell publish
154
+ ```
155
+
156
+ With no `APPSHELL_TOKEN` and no stored login for the registry, `appshell publish` asks the
157
+ runner for a token whose audience is the registry url as configured, without a trailing
158
+ slash — the registry's `TRUSTED_PUBLISHING_AUDIENCE` must be exactly that — and presents
159
+ it for that one request. Each publish mints its own and none is stored. An explicit
160
+ `APPSHELL_TOKEN` or stored login wins, so a job that sets one publishes as that account.
161
+
162
+ The package must name its scope, as `@acme/widgets`: a workflow has no namespace of its
163
+ own. A refusal says what to check — `appshell trust list <scope>` and the job's
164
+ environment, or that the registry does not have trusted publishing enabled, in which case
165
+ publish retries once without a token for a registry that needs none (`AUTH_MODE=none`).
166
+
167
+ ## Declaring an application
168
+
169
+ `appshell app apply` reconciles an application against a declared resource, creating
170
+ it when absent. It is the declarative counterpart to `app create` plus `publish
171
+ --application`, and the same file works against any registry via `--registry`.
172
+
173
+ **appshell.app.yaml**
174
+
175
+ ```yaml
176
+ apiVersion: registry.appshell.org/v1
177
+ kind: Application
178
+ name: storefront
179
+ spec:
180
+ shell:
181
+ root: ContainerModule/Container
182
+ title: Storefront
183
+ packages:
184
+ - acme/checkout@1.5.0
185
+ - acme/cart@2.0.1
186
+ ```
187
+
188
+ ```bash
189
+ appshell app apply -f appshell.app.yaml
190
+ ```
191
+
192
+ `spec.packages` is the **full desired set** — anything activated but absent from it is
193
+ deactivated, and the command prints what moved:
194
+
195
+ ```
196
+ Updated acme/storefront
197
+ activated acme/cart@2.0.1
198
+ deactivated acme/search
199
+ ```
200
+
201
+ Omit `spec.packages` entirely and package state is left alone, which is what you want
202
+ locally where the webpack plugin already publishes and activates on every build.
203
+ `${VAR}` placeholders expand from the environment exactly as they do in
204
+ `appshell.config.yaml`.
205
+
206
+ ## Inspecting an application
207
+
208
+ ```bash
209
+ appshell app list # every application in the scope
210
+ appshell app get storefront # packages, revision, visibility
211
+ appshell app composition storefront # the resolved payload the shell receives
212
+ appshell app revisions storefront # revision history
213
+ appshell app rollback storefront --to 3
214
+ appshell app open storefront # print the shell url
215
+ ```
216
+
217
+ Every mutation produces a revision, so `revisions` is the audit trail and `rollback`
218
+ is how you undo one.
219
+
220
+ ```bash
221
+ appshell app create storefront # imperative equivalent of a bare apply
222
+ appshell app delete storefront
223
+ appshell app deactivate acme/checkout
224
+ appshell app clone --from prod --to my-sandbox
225
+ appshell app sync --from prod --to staging --include packages
226
+ ```
227
+
228
+ ## Developing against a deployed application
64
229
 
65
- Generates the appshell global runtime manifest.
230
+ `appshell dev` opens an **overlay**: a per-developer, per-browser redirect that points
231
+ some of an application's remotes at your machine. It is resolved per request, expires
232
+ on its own, and never reaches the application's composition or its revision history.
66
233
 
67
234
  ```bash
68
- appshell generate manifest
235
+ appshell dev --port 3002 # redirect this package's remotes at localhost:3002
236
+ appshell dev status # what is open on the application
237
+ appshell dev stop --package # stop redirecting just this package
238
+ appshell dev stop <id> # close one, or --all
239
+ ```
69
240
 
70
- Generate the appshell global runtime manifest
241
+ An overlay can only redirect remote keys the application already publishes — adding
242
+ one outright would be a way to run code the application was never composed with. For a
243
+ new package, publish and activate it first, or work in a clone.
71
244
 
72
- Options:
73
- --help Show help [boolean]
74
- --version Show version number [boolean]
75
- -t, --template Path to the appshell config template to process [string] [default: "appshell.template.json"]
76
- -o, --outDir Output location for the appshell manifest [string] [default: "dist"]
77
- -f, --outFile Output filename for the appshell manifest [string] [default: "appshell.manifest.json"]
245
+ `--shell dev` additionally serves the development shell build, which is what supports
246
+ hot reloading remotes in place.
247
+
248
+ ## Analyzing shared dependencies
249
+
250
+ ```bash
251
+ appshell outdated
78
252
  ```
79
253
 
80
- ### Sample usage
254
+ Compares this package's dependencies against the shared-dependency baselines the
255
+ application declares, and reports conflicts, missing entries and matches.
256
+
257
+ ## Generate manifest
258
+
259
+ Processes a template into an appshell manifest. `appshell publish` does this for you;
260
+ run it directly when you want the manifest as a build artifact.
81
261
 
82
262
  ```bash
83
263
  appshell generate manifest --template dist/appshell.template.json
84
264
  ```
85
265
 
86
- **Where does the content of APPSHELL_REGISTRY come from?**
266
+ | Option | Default | Purpose |
267
+ | ------ | ------- | ------- |
268
+ | `-t, --template` | `appshell.template.json` | Template to process |
269
+ | `-o, --outDir` | `dist` | Output location |
270
+ | `-f, --outFile` | `appshell.manifest.json` | Output filename |
87
271
 
88
- > Each micro-frontend configured to use [@appshell/webpack-plugin](https://www.npmjs.com/package/@appshell/webpack-plugin) emits a manifest template, which is subsequently used to generate a manifest for the remote module. This manifest is then registered with the APPSHELL_REGISTRY.
272
+ **Where does the template come from?**
273
+
274
+ > Each micro-frontend configured with
275
+ > [@appshell/webpack-plugin](https://www.npmjs.com/package/@appshell/webpack-plugin)
276
+ > emits `appshell.template.json` at build time. `appshell publish` turns that into a
277
+ > manifest and publishes it as a package version.
89
278
 
90
279
  Sample config template `appshell.template.json`:
91
280
 
@@ -121,7 +310,7 @@ Sample config template `appshell.template.json`:
121
310
  }
122
311
  }
123
312
  },
124
- "environment": {
313
+ "vars": {
125
314
  "RUNTIME_ARG_1": "${RUNTIME_ARG_1}",
126
315
  "RUNTIME_ARG_2": "${RUNTIME_ARG_2}"
127
316
  }
@@ -132,7 +321,7 @@ Sample config template `appshell.template.json`:
132
321
 
133
322
  > Note the variable expansion syntax `${CRA_MFE_URL}`. When `appshell generate manifest` is called the actual runtime environment values are injected in order to produce the remote module's appshell manifest.
134
323
 
135
- > **Note** the `environment` section defines runtime environment variables that are injected into the global namesapce `window.__appshell_env__[module_name]` when an Appshell component is loaded. See the examples for a use case.
324
+ > **Note** the `vars` section defines runtime configuration values a package reads with `getVars()` from [`@appshell/runtime/vars`](../runtime/README.md) once it is loaded. The package must share `@appshell/runtime` as a singleton to receive them. See the examples for a use case.
136
325
 
137
326
  Sample appshell manifest produced by the `appshell generate manifest` function:
138
327
 
@@ -215,7 +404,7 @@ Sample appshell manifest produced by the `appshell generate manifest` function:
215
404
  }
216
405
  }
217
406
  },
218
- "environment": {
407
+ "vars": {
219
408
  "CraModule": {
220
409
  "RUNTIME_ARG_1": "Foo",
221
410
  "RUNTIME_ARG_2": "Biz"
@@ -227,76 +416,5 @@ Sample appshell manifest produced by the `appshell generate manifest` function:
227
416
  }
228
417
  ```
229
418
 
230
- This appshell manifest is registered with `APPSHELL_REGISTRY` and subsequently consumed by the Appshell host.
231
-
232
- ## Register a manifest
233
-
234
- Register one or more appshell manifests with the global registry.
235
-
236
- ```bash
237
- appshell register
238
-
239
- Register one or more appshell manifests
240
-
241
- Options:
242
- --help Show help [boolean]
243
- --version Show version number [boolean]
244
- -m, --manifest One or more manifests to register [array]
245
- -r, --registry Registry path for the appshell manifests
246
- [string] [default: "appshell_registry"]
247
- ```
248
-
249
- ## Generate runtime env
250
-
251
- Generates a runtime env js file that can be consumed by the application at runtime.
252
-
253
- ```bash
254
- appshell generate env
255
-
256
- Generate the runtime environment js file that reflects the current process.env
257
-
258
- Options:
259
- --help Show help [boolean]
260
- --version Show version number [boolean]
261
- -o, --outDir Output location for the appshell environment js [string] [default: "."]
262
- -f, --outFile Output filename for the appshell environment js [string] [default: "appshell.env.js"]
263
- -p, --prefix Only capture environment variables that start with prefix or regex [string] [default: ""]
264
- -g, --globalName Global variable name window[globalName] used in the output js [string] [default: "__appshell_env__"]
265
- ```
266
-
267
- ### Sample usage
268
-
269
- ```bash
270
- appshell generate env --prefix APPSHELL_ --outDir dist
271
- ```
272
-
273
- Sample output `appshell.env.js`
274
-
275
- ```js
276
- window.__appshell_env__ = {
277
- APPSHELL_VAR_1 = 'val 1',
278
- APPSHELL_VAR_2 = 'val 2'
279
- };
280
- ```
281
-
282
- ### Using regex to match prefix
283
-
284
- ```bash
285
- appshell generate env --prefix '^(APPSHELL_|FOO_).*' --outDir dist
286
- ```
287
-
288
- Sample output `appshell.env.js`
289
-
290
- ```js
291
- window.__appshell_env__ = {
292
- APPSHELL_VAR_1 = 'val 1',
293
- APPSHELL_VAR_2 = 'val 2',
294
- FOO_VAR = 'some value'
295
- };
296
- ```
297
-
298
- Include in the public html
299
-
300
- ```html
301
- <script src="appshell.env.js"></script>
302
- ```
419
+ `appshell publish` sends this manifest to the registry as a package version. The
420
+ registry composes every activated package into the payload it serves to the shell.