@ethlete/cli 2.1.0-next.9 → 3.0.0-next.16
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/CHANGELOG.md +78 -0
- package/README.md +22 -7
- package/design/define-call.ts +8 -8
- package/design/web/frame.ts +11 -5
- package/design/web/host.css +4 -4
- package/design/web/host.ts +68 -68
- package/package.json +3 -3
- package/src/index.d.ts +1 -0
- package/src/index.js +18 -4
- package/src/index.js.map +1 -1
- package/src/lib/api/clear.js +13 -3
- package/src/lib/api/clear.js.map +1 -1
- package/src/lib/api/compose.js +5 -1
- package/src/lib/api/compose.js.map +1 -1
- package/src/lib/api/git.d.ts +11 -4
- package/src/lib/api/git.js +35 -8
- package/src/lib/api/git.js.map +1 -1
- package/src/lib/api/load-definitions.js +10 -1
- package/src/lib/api/load-definitions.js.map +1 -1
- package/src/lib/api/ports.js +12 -3
- package/src/lib/api/ports.js.map +1 -1
- package/src/lib/api/run.js +8 -3
- package/src/lib/api/run.js.map +1 -1
- package/src/lib/api/setup.js +1 -1
- package/src/lib/api/setup.js.map +1 -1
- package/src/lib/api/state.js +7 -5
- package/src/lib/api/state.js.map +1 -1
- package/src/lib/auth/composer-auth.js +3 -2
- package/src/lib/auth/composer-auth.js.map +1 -1
- package/src/lib/auth/gitlab-token.js +1 -1
- package/src/lib/auth/gitlab-token.js.map +1 -1
- package/src/lib/config/diagnose.js +15 -9
- package/src/lib/config/diagnose.js.map +1 -1
- package/src/lib/config/local-config.d.ts +1 -1
- package/src/lib/design/check.js +27 -16
- package/src/lib/design/check.js.map +1 -1
- package/src/lib/design/serve.js +5 -5
- package/src/lib/design/serve.js.map +1 -1
- package/src/lib/design/vite-paths.d.ts +7 -0
- package/src/lib/design/vite-paths.js +15 -0
- package/src/lib/design/vite-paths.js.map +1 -0
- package/src/lib/doctor/doctor-command.js +18 -4
- package/src/lib/doctor/doctor-command.js.map +1 -1
- package/src/lib/release.d.ts +38 -1
- package/src/lib/release.js +150 -43
- package/src/lib/release.js.map +1 -1
- package/src/lib/update/agent-rules-sync.d.ts +37 -0
- package/src/lib/update/agent-rules-sync.js +40 -0
- package/src/lib/update/agent-rules-sync.js.map +1 -0
- package/src/lib/update/agent-setup.d.ts +33 -0
- package/src/lib/update/agent-setup.js +124 -0
- package/src/lib/update/agent-setup.js.map +1 -0
- package/src/lib/update/ai.d.ts +37 -8
- package/src/lib/update/ai.js +193 -24
- package/src/lib/update/ai.js.map +1 -1
- package/src/lib/update/args.d.ts +2 -0
- package/src/lib/update/args.js +22 -2
- package/src/lib/update/args.js.map +1 -1
- package/src/lib/update/available-migrations.d.ts +10 -0
- package/src/lib/update/available-migrations.js +23 -0
- package/src/lib/update/available-migrations.js.map +1 -0
- package/src/lib/update/commits.d.ts +63 -0
- package/src/lib/update/commits.js +146 -0
- package/src/lib/update/commits.js.map +1 -0
- package/src/lib/update/gitignore.d.ts +8 -0
- package/src/lib/update/gitignore.js +22 -0
- package/src/lib/update/gitignore.js.map +1 -0
- package/src/lib/update/index.d.ts +6 -0
- package/src/lib/update/index.js +6 -0
- package/src/lib/update/index.js.map +1 -1
- package/src/lib/update/migration-manifest.d.ts +10 -0
- package/src/lib/update/migration-manifest.js +15 -3
- package/src/lib/update/migration-manifest.js.map +1 -1
- package/src/lib/update/migration-record.d.ts +24 -0
- package/src/lib/update/migration-record.js +48 -0
- package/src/lib/update/migration-record.js.map +1 -0
- package/src/lib/update/migrations-command.d.ts +14 -0
- package/src/lib/update/migrations-command.js +212 -0
- package/src/lib/update/migrations-command.js.map +1 -0
- package/src/lib/update/package-manager.d.ts +20 -1
- package/src/lib/update/package-manager.js +34 -15
- package/src/lib/update/package-manager.js.map +1 -1
- package/src/lib/update/packages.js +31 -9
- package/src/lib/update/packages.js.map +1 -1
- package/src/lib/update/pending.d.ts +16 -0
- package/src/lib/update/pending.js +21 -5
- package/src/lib/update/pending.js.map +1 -1
- package/src/lib/update/plan.d.ts +28 -2
- package/src/lib/update/plan.js +54 -3
- package/src/lib/update/plan.js.map +1 -1
- package/src/lib/update/registry.d.ts +32 -4
- package/src/lib/update/registry.js +145 -8
- package/src/lib/update/registry.js.map +1 -1
- package/src/lib/update/run-migrations.d.ts +2 -0
- package/src/lib/update/run-migrations.js +20 -15
- package/src/lib/update/run-migrations.js.map +1 -1
- package/src/lib/update/scan.d.ts +14 -0
- package/src/lib/update/scan.js +57 -0
- package/src/lib/update/scan.js.map +1 -0
- package/src/lib/update/semver.js +2 -1
- package/src/lib/update/semver.js.map +1 -1
- package/src/lib/update/tasks.d.ts +18 -1
- package/src/lib/update/tasks.js +114 -43
- package/src/lib/update/tasks.js.map +1 -1
- package/src/lib/update/update-command.d.ts +7 -0
- package/src/lib/update/update-command.js +286 -64
- package/src/lib/update/update-command.js.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,83 @@
|
|
|
1
1
|
# @ethlete/cli
|
|
2
2
|
|
|
3
|
+
## 3.0.0-next.16
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- Breaking: `release()` takes `{ args, root?, invocation? }` and resolves to an exit code instead of exiting. `et release` tags after the release commit and takes `--message` and `--help`; `et update` names the `.npmrc` whose token was refused.
|
|
8
|
+
|
|
9
|
+
### Minor Changes
|
|
10
|
+
|
|
11
|
+
- New `et migrations` lists the recommended and optional migrations an app has not run, and `et migrations run <package>:<name>` runs one and records it in `.ethlete/migrations.json`.
|
|
12
|
+
- `et update` runs only `required` migrations and points at the recommended and optional ones it left.
|
|
13
|
+
- `et migrations` shows the number of affected files next to each migration whose manifest entry names a `scan` generator.
|
|
14
|
+
- Peer dependencies are ranges (`^22.1.0` for Angular, `^7.8.0` for RxJS, ...) instead of the workspace's exact versions. `et update` says when another dist tag holds a newer major, also when the repo is up to date.
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- `et release` and `et update` now reject values on boolean flags and empty `--tag=`/`--to=`, and version comparison ignores build metadata.
|
|
19
|
+
- `et update --from` rejects a version that is not one, such as `core@v5.0.0`, instead of running every migration of the package.
|
|
20
|
+
- The call title bar no longer covers the top of a drawing: the drawing starts below it, and it fades out while the drawing scrolls down and back in on scroll up.
|
|
21
|
+
|
|
22
|
+
## 2.1.0-next.15
|
|
23
|
+
|
|
24
|
+
### Minor Changes
|
|
25
|
+
|
|
26
|
+
- `et update --ai` ends an interactive agent session by itself once the agent writes the task's `.finished` file, then commits the task and starts the next one. `/exit` still works.
|
|
27
|
+
|
|
28
|
+
## 2.1.0-next.14
|
|
29
|
+
|
|
30
|
+
### Minor Changes
|
|
31
|
+
|
|
32
|
+
- `et update` commits each step by itself - the version bump, each codemod, the agent rules sync and each finished `--ai` task - and never a file that was dirty before the run; `--no-commit` turns this off.
|
|
33
|
+
- `et update --ai` without `updateAgentCommand` lists the agent CLIs on `PATH` and saves the one you pick, as an interactive session or a headless run.
|
|
34
|
+
|
|
35
|
+
### Patch Changes
|
|
36
|
+
|
|
37
|
+
- The Claude Code choices in `et update --ai` start the agent in auto mode, so it can run its checks without asking.
|
|
38
|
+
- `et update --ai` tells you, for each task and in the agent's last message, to type `/exit` so the next task starts.
|
|
39
|
+
|
|
40
|
+
## 2.1.0-next.13
|
|
41
|
+
|
|
42
|
+
### Patch Changes
|
|
43
|
+
|
|
44
|
+
- `et update` hands the migrations to the newly installed `et` when the update moves `@ethlete/cli`, so steps a newer CLI added, such as the agent rules sync, run in that same update.
|
|
45
|
+
- `et update` follows the dist tag that holds the newest version of the installed prerelease line, so a package that changesets published to `latest`, such as `@ethlete/agent-rules`, no longer stays on the older `next` version.
|
|
46
|
+
|
|
47
|
+
## 2.1.0-next.12
|
|
48
|
+
|
|
49
|
+
### Patch Changes
|
|
50
|
+
|
|
51
|
+
- `et api clear` keeps a checkout git cannot read, and `et api up` and `setup` no longer fail on output over 1 MB.
|
|
52
|
+
- `et api clear` also keeps a checkout with stashes or detached-HEAD commits, `checkout` never reads a branch as a flag or path, `-h` shows help, and a port held on loopback or IPv6 counts as taken.
|
|
53
|
+
- `ethlete api` no longer leaves an `ethlete-api-*` directory in the temp folder after each podman run.
|
|
54
|
+
- GitLab token checks refuse redirects, `auth.json` is narrowed before the token is written, `release` matches its flags exactly, and `doctor` reports a broken legacy config file.
|
|
55
|
+
- `et design check` closes the browser when the page fails, and `et design serve` resolves calls on Windows.
|
|
56
|
+
- `et doctor` reports an `ethlete.apis.js` that throws while it loads instead of crashing.
|
|
57
|
+
- `release --force` stages only the files `changeset version` changed instead of running `git add .`, so unrelated uncommitted changes stay out of the "Release versions" commit.
|
|
58
|
+
- `et update` passes the agent prompt through environment variables, sends `.npmrc` registry tokens, keeps CRLF line endings, skips git-ignored manifests, and rejects migration names or instructions outside the package.
|
|
59
|
+
- `et update` prefers the lockfile over the calling `npx`, runs package managers on Windows, and points every run to `--continue` while an update is unfinished.
|
|
60
|
+
|
|
61
|
+
## 2.1.0-next.11
|
|
62
|
+
|
|
63
|
+
### Minor Changes
|
|
64
|
+
|
|
65
|
+
- `et update` runs `ethlete-agents sync` after the install when it moved `@ethlete/agent-rules` and the repo has an `ethlete-agents.config.json`, so the regenerated rules and skills match the tasks the update writes.
|
|
66
|
+
|
|
67
|
+
### Patch Changes
|
|
68
|
+
|
|
69
|
+
- `et update --ai` stops before any change when `updateAgentCommand` is missing, hands the agent a real prompt, reports each task, and works on the tasks an earlier run left.
|
|
70
|
+
- `et update` gitignores its task list, so a later run no longer needs `--force`, and `--continue` keeps the `--from` versions and the codemods an earlier run applied.
|
|
71
|
+
- Fix `et update` for a real consumer: the `et` bin runs, `--continue` skips applied codemods, `--check` reports an unfinished run, lookups use the repo's registry, task links point at the right docs site, and failed syncs are reported.
|
|
72
|
+
- `yarn et update` on yarn 1 installs from the registry the repo's `.npmrc` or `.yarnrc` names, not the default registry yarn exports to scripts.
|
|
73
|
+
- `et update` drops deleted tasks from `tasks.md` even when nothing is pending, prints "none" for an empty dry-run migration list, and aligns the `--continue` plan.
|
|
74
|
+
|
|
75
|
+
## 2.1.0-next.10
|
|
76
|
+
|
|
77
|
+
### Patch Changes
|
|
78
|
+
|
|
79
|
+
- A design call now lists its drawings as `variants` in `variant-<key>.ts` files, and `et design check` takes `--variant`; the old `options` key and `--option` flag are gone.
|
|
80
|
+
|
|
3
81
|
## 2.1.0-next.9
|
|
4
82
|
|
|
5
83
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ Repo tooling - installs the `et` binary.
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
yarn add --dev @ethlete/cli
|
|
8
|
+
yarn add --dev @ethlete/cli@next
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
## `et release`
|
|
@@ -14,7 +14,9 @@ yarn add --dev @ethlete/cli
|
|
|
14
14
|
yarn et release
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
Turns pending changesets into a tagged, pushed release commit (version →
|
|
17
|
+
Turns pending changesets into a tagged, pushed release commit (version → commit → tag → push). A
|
|
18
|
+
failed commit stops the run before any tag exists. Pass `--message "chore(release): Release versions"`
|
|
19
|
+
when a commit-msg hook rejects the default `Release versions`; `et release --help` lists the flags.
|
|
18
20
|
|
|
19
21
|
## `et auth`
|
|
20
22
|
|
|
@@ -47,23 +49,36 @@ yarn et update --tag latest # leave the prerelease line
|
|
|
47
49
|
yarn et update core --to 5.0.0-next.55 # an exact version for the package you name
|
|
48
50
|
yarn et update --continue # finish a run that stopped
|
|
49
51
|
yarn et update --ai # hand every agent-assisted task to an agent
|
|
52
|
+
yarn et update --no-commit # leave every change uncommitted
|
|
50
53
|
```
|
|
51
54
|
|
|
52
55
|
The target follows the dist tag the installed version is on, so a repo on a `-next` prerelease stays
|
|
53
|
-
on `next
|
|
56
|
+
on `next`, and a repo on `latest` is told per package when a newer major waits on `next`. The working
|
|
57
|
+
tree must be clean, because the codemods rewrite files; `--force` skips that
|
|
54
58
|
check.
|
|
55
59
|
|
|
56
60
|
The install runs before the migrations are read, because the migrations of a version ship inside that
|
|
57
61
|
version. A run that stops leaves `.ethlete/update/pending.json` behind, and `--continue` picks it up -
|
|
58
62
|
starting over would skip every migration the stopped run had not reached.
|
|
59
63
|
|
|
64
|
+
When the update moved `@ethlete/agent-rules`, it runs `ethlete-agents sync` before the codemods, so the
|
|
65
|
+
rules and skills match the tasks it writes. `--continue` skips the codemods that already applied, and
|
|
66
|
+
every other run exits 1 and points to `--continue` while a stopped run is unfinished.
|
|
67
|
+
|
|
60
68
|
Everything a codemod cannot decide is written to `.ethlete/update`: `tasks.md` for you, `tasks.json`
|
|
61
69
|
for an agent, and one file per task holding the instructions the package ships. A task is `manual` (it
|
|
62
70
|
needs a decision), `assisted` (written as a prompt for an agent) or `unsupported` (a codemod this repo
|
|
63
71
|
has no Nx to run, with the command to run it by hand).
|
|
64
72
|
|
|
65
|
-
`--ai` hands each assisted task to the command in `updateAgentCommand` in
|
|
66
|
-
`ethlete.config.local.json
|
|
73
|
+
`--ai` hands each open assisted task to the command in `updateAgentCommand` in
|
|
74
|
+
`ethlete.config.local.json` (for example `claude --permission-mode auto`), one run per task,
|
|
75
|
+
and reports each run. It also works on the tasks an earlier run left. When the key is missing, `--ai`
|
|
76
|
+
lists the agent CLIs on `PATH` and saves the command you pick.
|
|
77
|
+
|
|
78
|
+
Each step is committed by itself: the version bump with the lockfile, each codemod that changed files,
|
|
79
|
+
the agent rules sync, and each agent task that ends done. A commit takes only the paths its step
|
|
80
|
+
changed, and a step that touched a file you had changed before the run is left uncommitted.
|
|
81
|
+
`--no-commit` commits nothing.
|
|
67
82
|
|
|
68
83
|
A package declares its migrations in `migrations.json` at its own root, pointed at from `package.json`
|
|
69
84
|
with `"ethlete": { "migrations": "./migrations.json" }`. The full format is on the docs site.
|
|
@@ -174,5 +189,5 @@ fallback with a warning. Add `ethlete.config.local.json` to your `.gitignore`.
|
|
|
174
189
|
|
|
175
190
|
Full command reference on the docs site:
|
|
176
191
|
|
|
177
|
-
- [Overview & usage](https://ethlete-sdk-docs.web.app/cli/)
|
|
178
|
-
- [Updating the SDK](https://ethlete-sdk-docs.web.app/cli/update)
|
|
192
|
+
- [Overview & usage](https://ethlete-sdk-docs-next.web.app/cli/)
|
|
193
|
+
- [Updating the SDK](https://ethlete-sdk-docs-next.web.app/cli/update)
|
package/design/define-call.ts
CHANGED
|
@@ -37,9 +37,9 @@ export const drawing = (drawn: Drawing): Drawing => drawn;
|
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
39
|
* One drawn answer to a call. `load` resolves the module whose default export is the
|
|
40
|
-
* drawing that answers it, so a broken
|
|
40
|
+
* drawing that answers it, so a broken variant breaks its own frame only.
|
|
41
41
|
*/
|
|
42
|
-
export type
|
|
42
|
+
export type CallVariant = {
|
|
43
43
|
key: string;
|
|
44
44
|
name: string;
|
|
45
45
|
/** Left out by a view: a single drawing answers no question, so it argues nothing. */
|
|
@@ -53,8 +53,8 @@ export type CallOption = {
|
|
|
53
53
|
};
|
|
54
54
|
|
|
55
55
|
/**
|
|
56
|
-
* One pass over a call: the
|
|
57
|
-
* whose
|
|
56
|
+
* One pass over a call: the variants drawn together, and what came out of them. A round
|
|
57
|
+
* whose variants all carry a verdict is settled, and the page folds it down to its winner.
|
|
58
58
|
*/
|
|
59
59
|
export type CallRound = {
|
|
60
60
|
key: string;
|
|
@@ -71,8 +71,8 @@ export type CallRound = {
|
|
|
71
71
|
export type CallMode = 'wireframe' | 'design';
|
|
72
72
|
|
|
73
73
|
/**
|
|
74
|
-
* One open question of an exploration, with every
|
|
75
|
-
* A call with one
|
|
74
|
+
* One open question of an exploration, with every variant drawn at the same geometry.
|
|
75
|
+
* A call with one variant and no claim is a view: one reference picture, drawn full width.
|
|
76
76
|
*/
|
|
77
77
|
export type Call = {
|
|
78
78
|
/** The feature this call belongs to, for example 'the hour strip'. Left out by a loose call. */
|
|
@@ -80,13 +80,13 @@ export type Call = {
|
|
|
80
80
|
eyebrow: string;
|
|
81
81
|
headline: string;
|
|
82
82
|
intro: string;
|
|
83
|
-
/** The width every
|
|
83
|
+
/** The width every variant frame gets, in px. The geometry the thing ships in. */
|
|
84
84
|
frameWidth: number;
|
|
85
85
|
/** Left out by a call that draws the real thing, which is what `design` means. */
|
|
86
86
|
mode?: CallMode;
|
|
87
87
|
/** Left out by a short call. With rounds, the intro says only what the call is about. */
|
|
88
88
|
rounds?: CallRound[];
|
|
89
|
-
|
|
89
|
+
variants: CallVariant[];
|
|
90
90
|
};
|
|
91
91
|
|
|
92
92
|
export const defineCall = (call: Call): Call => call;
|
package/design/web/frame.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { loadEnv } from 'virtual:design-explore/env';
|
|
|
3
3
|
|
|
4
4
|
const params = new URLSearchParams(location.search);
|
|
5
5
|
const slug = params.get('call') ?? '';
|
|
6
|
-
const key = params.get('
|
|
6
|
+
const key = params.get('variant') ?? '';
|
|
7
7
|
|
|
8
8
|
await loadEnv(slug.split('/')[0] ?? '');
|
|
9
9
|
|
|
@@ -17,10 +17,10 @@ const fail = (message: string) => {
|
|
|
17
17
|
const call = calls[slug];
|
|
18
18
|
if (!call) fail(`design-explore: no call "${slug}"`);
|
|
19
19
|
else {
|
|
20
|
-
const
|
|
21
|
-
if (!
|
|
20
|
+
const variant = (await call()).default.variants.find((o) => o.key === key);
|
|
21
|
+
if (!variant) fail(`design-explore: call "${slug}" has no variant "${key}"`);
|
|
22
22
|
else {
|
|
23
|
-
const loaded = (await
|
|
23
|
+
const loaded = (await variant.load()).default;
|
|
24
24
|
const style = document.createElement('style');
|
|
25
25
|
|
|
26
26
|
style.textContent = loaded.styles;
|
|
@@ -31,8 +31,14 @@ else {
|
|
|
31
31
|
|
|
32
32
|
const report = () => {
|
|
33
33
|
const height = Math.ceil(document.documentElement.getBoundingClientRect().height);
|
|
34
|
-
parent.postMessage({ type: 'design-explore:height',
|
|
34
|
+
parent.postMessage({ type: 'design-explore:height', variant: key, height }, '*');
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
new ResizeObserver(report).observe(document.documentElement);
|
|
38
38
|
report();
|
|
39
|
+
|
|
40
|
+
addEventListener(
|
|
41
|
+
'scroll',
|
|
42
|
+
() => parent.postMessage({ type: 'design-explore:scroll', variant: key, y: Math.round(scrollY) }, '*'),
|
|
43
|
+
{ passive: true },
|
|
44
|
+
);
|
package/design/web/host.css
CHANGED
|
@@ -203,7 +203,7 @@ main {
|
|
|
203
203
|
color: var(--h-ink);
|
|
204
204
|
}
|
|
205
205
|
|
|
206
|
-
/* A folded
|
|
206
|
+
/* A folded variant keeps its name on the page, so the thread of the round is still readable. */
|
|
207
207
|
.folded {
|
|
208
208
|
display: flex;
|
|
209
209
|
max-width: 68ch;
|
|
@@ -270,7 +270,7 @@ header p {
|
|
|
270
270
|
}
|
|
271
271
|
|
|
272
272
|
/*
|
|
273
|
-
* A track is as wide as the frame it holds, so the
|
|
273
|
+
* A track is as wide as the frame it holds, so the variants wrap to the next band when the window
|
|
274
274
|
* runs out of room. Row flow is what lets them wrap: each column takes four rows, so the next one
|
|
275
275
|
* starts beside it and only a full band pushes to a new line.
|
|
276
276
|
*/
|
|
@@ -386,7 +386,7 @@ header p {
|
|
|
386
386
|
transform-origin: top left;
|
|
387
387
|
}
|
|
388
388
|
|
|
389
|
-
/* The contact sheet draws every
|
|
389
|
+
/* The contact sheet draws every variant at once, so one screen holds the whole call. */
|
|
390
390
|
.grid.sheet {
|
|
391
391
|
--thumb-width: calc(var(--frame-width) * var(--de-scale));
|
|
392
392
|
|
|
@@ -441,7 +441,7 @@ header p {
|
|
|
441
441
|
outline-offset: 4px;
|
|
442
442
|
}
|
|
443
443
|
|
|
444
|
-
/* A rejected
|
|
444
|
+
/* A rejected variant stays readable, and comes back to full strength under the pointer. */
|
|
445
445
|
.column[data-verdict='rejected'] {
|
|
446
446
|
opacity: 0.45;
|
|
447
447
|
transition: opacity 0.15s;
|
package/design/web/host.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Call,
|
|
1
|
+
import type { Call, CallVariant, CallRound } from '@design-explore';
|
|
2
2
|
import { calls, defaultCall } from 'virtual:design-explore';
|
|
3
3
|
import './host.css';
|
|
4
4
|
|
|
@@ -33,21 +33,21 @@ const listLink = (name: string, list: string[], key: string) => {
|
|
|
33
33
|
const toggleOpen = (key: string) => listLink('open', [...opened], key);
|
|
34
34
|
const togglePick = (key: string) => listLink('pick', picked, key);
|
|
35
35
|
|
|
36
|
-
type Band = { key: string | null; number: number; round: CallRound | null;
|
|
36
|
+
type Band = { key: string | null; number: number; round: CallRound | null; variants: CallVariant[] };
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
|
-
* The
|
|
40
|
-
* declares it, so
|
|
39
|
+
* The variants are the call. A band exists because a variant names it, never because `rounds`
|
|
40
|
+
* declares it, so a variant added without its round entry still gets a band, a heading and a
|
|
41
41
|
* menu row - all three say the bare key until somebody writes the prose.
|
|
42
42
|
*/
|
|
43
43
|
const bandsOf = (call: Call): Band[] => {
|
|
44
44
|
const declared = new Map((call.rounds ?? []).map((round) => [round.key, round]));
|
|
45
45
|
const bands = new Map<string, Band>();
|
|
46
46
|
|
|
47
|
-
for (const
|
|
48
|
-
const key =
|
|
49
|
-
const band = bands.get(key) ?? { key: key || null, number: 0, round: declared.get(key) ?? null,
|
|
50
|
-
band.
|
|
47
|
+
for (const variant of call.variants) {
|
|
48
|
+
const key = variant.round ?? '';
|
|
49
|
+
const band = bands.get(key) ?? { key: key || null, number: 0, round: declared.get(key) ?? null, variants: [] };
|
|
50
|
+
band.variants.push(variant);
|
|
51
51
|
bands.set(key, band);
|
|
52
52
|
}
|
|
53
53
|
|
|
@@ -57,7 +57,7 @@ const bandsOf = (call: Call): Band[] => {
|
|
|
57
57
|
return [...bands.values()];
|
|
58
58
|
};
|
|
59
59
|
|
|
60
|
-
/** Prose that no
|
|
60
|
+
/** Prose that no variant claims is stale prose, and it is the one thing the variants cannot show. */
|
|
61
61
|
const problemsOf = (call: Call, bands: Band[]) => {
|
|
62
62
|
const keys = (call.rounds ?? []).map((round) => round.key);
|
|
63
63
|
const drawn = new Set(bands.map((band) => band.key));
|
|
@@ -66,7 +66,7 @@ const problemsOf = (call: Call, bands: Band[]) => {
|
|
|
66
66
|
...[...new Set(keys.filter((key, index) => keys.indexOf(key) !== index))].map(
|
|
67
67
|
(key) => `two rounds share the key "${key}"`,
|
|
68
68
|
),
|
|
69
|
-
...keys.filter((key) => !drawn.has(key)).map((key) => `round "${key}" has no
|
|
69
|
+
...keys.filter((key) => !drawn.has(key)).map((key) => `round "${key}" has no variants`),
|
|
70
70
|
];
|
|
71
71
|
};
|
|
72
72
|
|
|
@@ -77,10 +77,10 @@ const problemsOf = (call: Call, bands: Band[]) => {
|
|
|
77
77
|
*/
|
|
78
78
|
const chainOf = (bands: Band[]) => {
|
|
79
79
|
const named = bands.filter((band) => band.key);
|
|
80
|
-
const ruled = named.length > 1 && named.every((band) => band.
|
|
80
|
+
const ruled = named.length > 1 && named.every((band) => band.variants.every((variant) => variant.verdict));
|
|
81
81
|
const chain = named
|
|
82
|
-
.map((band) => band.
|
|
83
|
-
.filter((
|
|
82
|
+
.map((band) => band.variants.find((variant) => variant.verdict === 'chosen'))
|
|
83
|
+
.filter((variant): variant is CallVariant => !!variant);
|
|
84
84
|
|
|
85
85
|
return ruled && chain.length > 0 ? chain : [];
|
|
86
86
|
};
|
|
@@ -133,54 +133,54 @@ if (!load) {
|
|
|
133
133
|
const bands = bandsOf(call);
|
|
134
134
|
const chain = chainOf(bands);
|
|
135
135
|
const result = chain.at(-1);
|
|
136
|
-
const isView = call.
|
|
136
|
+
const isView = call.variants.length === 1 && !call.variants[0]?.claim;
|
|
137
137
|
const geometry = `--frame-width:${call.frameWidth}px`;
|
|
138
138
|
|
|
139
|
-
const frame = (
|
|
139
|
+
const frame = (variant: CallVariant) => `
|
|
140
140
|
<iframe
|
|
141
|
-
src="frame.html?call=${encodeURIComponent(slug)}&
|
|
142
|
-
data-
|
|
143
|
-
title="${esc(
|
|
141
|
+
src="frame.html?call=${encodeURIComponent(slug)}&variant=${encodeURIComponent(variant.key)}"
|
|
142
|
+
data-variant="${esc(variant.key)}"
|
|
143
|
+
title="${esc(variant.name)}"
|
|
144
144
|
style="width:${call.frameWidth}px"
|
|
145
145
|
></iframe>`;
|
|
146
146
|
|
|
147
|
-
const column = (
|
|
148
|
-
<div class="column" data-verdict="${
|
|
147
|
+
const column = (variant: CallVariant) => `
|
|
148
|
+
<div class="column" data-verdict="${variant.verdict ?? 'open'}" ${picked.includes(variant.key) ? 'data-picked' : ''}>
|
|
149
149
|
${
|
|
150
150
|
isView
|
|
151
151
|
? ''
|
|
152
152
|
: `<h3>
|
|
153
|
-
<a href="${togglePick(
|
|
154
|
-
<span class="tag">${
|
|
153
|
+
<a href="${togglePick(variant.key)}">${esc(variant.name)}</a>
|
|
154
|
+
<span class="tag">${variant.verdict ?? 'open'}</span>
|
|
155
155
|
</h3>`
|
|
156
156
|
}
|
|
157
|
-
<div class="stage">${frame(
|
|
158
|
-
${
|
|
159
|
-
${
|
|
157
|
+
<div class="stage">${frame(variant)}</div>
|
|
158
|
+
${variant.claim ? `<p class="claim">${esc(variant.claim)}</p>` : ''}
|
|
159
|
+
${variant.cost ? `<p class="cost">${esc(variant.cost)}</p>` : ''}
|
|
160
160
|
</div>`;
|
|
161
161
|
|
|
162
|
-
const grid = (
|
|
163
|
-
|
|
162
|
+
const grid = (variants: CallVariant[]) =>
|
|
163
|
+
variants.length === 0
|
|
164
164
|
? ''
|
|
165
|
-
: `<div class="grid" style="${geometry}" ${isView ? 'data-view' : ''}>${
|
|
165
|
+
: `<div class="grid" style="${geometry}" ${isView ? 'data-view' : ''}>${variants.map(column).join('')}</div>`;
|
|
166
166
|
|
|
167
|
-
const rows = (
|
|
168
|
-
|
|
167
|
+
const rows = (variants: CallVariant[]) =>
|
|
168
|
+
variants.length === 0
|
|
169
169
|
? ''
|
|
170
|
-
: `<ul class="folded">${
|
|
170
|
+
: `<ul class="folded">${variants
|
|
171
171
|
.map(
|
|
172
|
-
(
|
|
173
|
-
`<li data-verdict="${
|
|
174
|
-
|
|
175
|
-
)}</a><span class="tag">${
|
|
172
|
+
(variant) =>
|
|
173
|
+
`<li data-verdict="${variant.verdict ?? 'open'}"><a href="${togglePick(variant.key)}">${esc(
|
|
174
|
+
variant.name,
|
|
175
|
+
)}</a><span class="tag">${variant.verdict ?? 'open'}</span></li>`,
|
|
176
176
|
)
|
|
177
177
|
.join('')}</ul>`;
|
|
178
178
|
|
|
179
|
-
const band = ({ key, number, round,
|
|
180
|
-
const settled =
|
|
179
|
+
const band = ({ key, number, round, variants }: Band) => {
|
|
180
|
+
const settled = variants.every((variant) => variant.verdict);
|
|
181
181
|
const open = !key || !settled || opened.has(key);
|
|
182
|
-
const drawn = open ?
|
|
183
|
-
const folded =
|
|
182
|
+
const drawn = open ? variants : chain.length > 0 ? [] : variants.filter((variant) => variant.verdict === 'chosen');
|
|
183
|
+
const folded = variants.filter((variant) => !drawn.includes(variant));
|
|
184
184
|
|
|
185
185
|
const head = !key
|
|
186
186
|
? ''
|
|
@@ -191,7 +191,7 @@ if (!load) {
|
|
|
191
191
|
${
|
|
192
192
|
settled
|
|
193
193
|
? `<a class="fold" href="${toggleOpen(key)}">${
|
|
194
|
-
open ? `Fold ${
|
|
194
|
+
open ? `Fold ${variants.length} variants away` : `Show all ${variants.length} variants`
|
|
195
195
|
}</a>`
|
|
196
196
|
: ''
|
|
197
197
|
}
|
|
@@ -208,11 +208,11 @@ if (!load) {
|
|
|
208
208
|
/** Each step is the one before it plus a change, so the arrow is the order they were drawn in. */
|
|
209
209
|
const trail = () =>
|
|
210
210
|
chain
|
|
211
|
-
.map((
|
|
212
|
-
const band = bands.find((entry) => entry.
|
|
213
|
-
const target = band?.key ? `${toggleOpen(band.key)}#round-${band.key}` : togglePick(
|
|
214
|
-
return `<a href="${esc(target)}" ${
|
|
215
|
-
|
|
211
|
+
.map((variant) => {
|
|
212
|
+
const band = bands.find((entry) => entry.variants.includes(variant));
|
|
213
|
+
const target = band?.key ? `${toggleOpen(band.key)}#round-${band.key}` : togglePick(variant.key);
|
|
214
|
+
return `<a href="${esc(target)}" ${variant === result ? 'aria-current="step"' : ''}>${esc(
|
|
215
|
+
variant.key.toUpperCase(),
|
|
216
216
|
)}</a>`;
|
|
217
217
|
})
|
|
218
218
|
.join('<span class="arrow">→</span>');
|
|
@@ -236,21 +236,21 @@ if (!load) {
|
|
|
236
236
|
</section>`;
|
|
237
237
|
|
|
238
238
|
const tray = () => {
|
|
239
|
-
const
|
|
240
|
-
.map((key) => call.
|
|
241
|
-
.filter((
|
|
242
|
-
if (
|
|
239
|
+
const variants = picked
|
|
240
|
+
.map((key) => call.variants.find((variant) => variant.key === key))
|
|
241
|
+
.filter((variant): variant is CallVariant => !!variant);
|
|
242
|
+
if (variants.length === 0) return '';
|
|
243
243
|
|
|
244
|
-
const two =
|
|
244
|
+
const two = variants.length === 2;
|
|
245
245
|
|
|
246
246
|
return `
|
|
247
247
|
<section class="round tray">
|
|
248
248
|
<div class="round-head">
|
|
249
|
-
<span class="eyebrow">Compare · ${
|
|
250
|
-
<h2>${
|
|
249
|
+
<span class="eyebrow">Compare · ${variants.length}</span>
|
|
250
|
+
<h2>${variants.map((variant) => esc(variant.name)).join(' · ')}</h2>
|
|
251
251
|
<div class="switch">
|
|
252
|
-
${
|
|
253
|
-
.map((
|
|
252
|
+
${variants
|
|
253
|
+
.map((variant, index) => `<button data-step="${index}">${esc(variant.key.toUpperCase())}</button>`)
|
|
254
254
|
.join('')}
|
|
255
255
|
<span class="hint">${
|
|
256
256
|
two ? 'click or space to blink · arrows to wipe' : 'click or space for the next one'
|
|
@@ -259,7 +259,7 @@ if (!load) {
|
|
|
259
259
|
<a class="fold" href="${link({ pick: null })}">Clear the comparison</a>
|
|
260
260
|
</div>
|
|
261
261
|
<div class="overlay" data-two="${two}" style="width:${call.frameWidth}px">
|
|
262
|
-
${
|
|
262
|
+
${variants.map(frame).join('')}
|
|
263
263
|
<div class="seam"></div>
|
|
264
264
|
</div>
|
|
265
265
|
</section>`;
|
|
@@ -267,14 +267,14 @@ if (!load) {
|
|
|
267
267
|
|
|
268
268
|
const sheet = () => `
|
|
269
269
|
<div class="grid sheet" style="${geometry};--de-scale:${SHEET_SCALE}">
|
|
270
|
-
${call.
|
|
270
|
+
${call.variants
|
|
271
271
|
.map(
|
|
272
|
-
(
|
|
273
|
-
<a class="thumb" href="${togglePick(
|
|
274
|
-
picked.includes(
|
|
272
|
+
(variant) => `
|
|
273
|
+
<a class="thumb" href="${togglePick(variant.key)}" data-verdict="${variant.verdict ?? 'open'}" ${
|
|
274
|
+
picked.includes(variant.key) ? 'data-picked' : ''
|
|
275
275
|
}>
|
|
276
|
-
<div class="thumb-frame">${frame(
|
|
277
|
-
<span class="thumb-name">${esc(
|
|
276
|
+
<div class="thumb-frame">${frame(variant)}</div>
|
|
277
|
+
<span class="thumb-name">${esc(variant.name)}</span>
|
|
278
278
|
</a>`,
|
|
279
279
|
)
|
|
280
280
|
.join('')}
|
|
@@ -286,7 +286,7 @@ if (!load) {
|
|
|
286
286
|
: `<div class="views">
|
|
287
287
|
<a href="${link({ view: null })}" ${view === 'rounds' ? 'aria-current="page"' : ''}>rounds</a>
|
|
288
288
|
<a href="${link({ view: 'sheet' })}" ${view === 'sheet' ? 'aria-current="page"' : ''}>all ${
|
|
289
|
-
call.
|
|
289
|
+
call.variants.length
|
|
290
290
|
}</a>
|
|
291
291
|
</div>`;
|
|
292
292
|
|
|
@@ -345,8 +345,8 @@ const heights = new Map<string, number>();
|
|
|
345
345
|
|
|
346
346
|
/** The overlay is as tall as its tallest pick, so no frame is cut and none of them move. */
|
|
347
347
|
const size = () => {
|
|
348
|
-
for (const frame of document.querySelectorAll<HTMLIFrameElement>('iframe[data-
|
|
349
|
-
const height = heights.get(frame.dataset.
|
|
348
|
+
for (const frame of document.querySelectorAll<HTMLIFrameElement>('iframe[data-variant]')) {
|
|
349
|
+
const height = heights.get(frame.dataset.variant ?? '');
|
|
350
350
|
if (!height) continue;
|
|
351
351
|
|
|
352
352
|
frame.style.height = `${height}px`;
|
|
@@ -359,17 +359,17 @@ const size = () => {
|
|
|
359
359
|
if (!overlay) return;
|
|
360
360
|
|
|
361
361
|
const tallest = [...overlay.querySelectorAll<HTMLIFrameElement>('iframe')]
|
|
362
|
-
.map((frame) => heights.get(frame.dataset.
|
|
362
|
+
.map((frame) => heights.get(frame.dataset.variant ?? '') ?? 0)
|
|
363
363
|
.reduce((a, b) => Math.max(a, b), 0);
|
|
364
364
|
|
|
365
365
|
if (tallest > 0) overlay.style.height = `${tallest}px`;
|
|
366
366
|
};
|
|
367
367
|
|
|
368
368
|
addEventListener('message', (event) => {
|
|
369
|
-
const data = event.data as { type?: string;
|
|
370
|
-
if (data?.type !== 'design-explore:height' || !data.height || !data.
|
|
369
|
+
const data = event.data as { type?: string; variant?: string; height?: number };
|
|
370
|
+
if (data?.type !== 'design-explore:height' || !data.height || !data.variant) return;
|
|
371
371
|
|
|
372
|
-
heights.set(data.
|
|
372
|
+
heights.set(data.variant, data.height);
|
|
373
373
|
size();
|
|
374
374
|
|
|
375
375
|
if (restoring) scrollTo(0, target);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ethlete/cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-next.16",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
"vite": "8.1.5"
|
|
15
15
|
},
|
|
16
16
|
"peerDependencies": {
|
|
17
|
-
"playwright": "1.
|
|
18
|
-
"tslib": "2.
|
|
17
|
+
"playwright": "^1.50.0",
|
|
18
|
+
"tslib": "^2.3.0"
|
|
19
19
|
},
|
|
20
20
|
"peerDependenciesMeta": {
|
|
21
21
|
"playwright": {
|
package/src/index.d.ts
CHANGED
package/src/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
1
2
|
"use strict";
|
|
2
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
4
|
const tslib_1 = require("tslib");
|
|
@@ -38,6 +39,11 @@ const USAGE_ROWS = [
|
|
|
38
39
|
args: ' [packages...]',
|
|
39
40
|
lines: ['Move the @ethlete/* packages to a newer version and run the', 'migrations those versions ship'],
|
|
40
41
|
},
|
|
42
|
+
{
|
|
43
|
+
subcommand: 'migrations',
|
|
44
|
+
args: ' [run <package>:<name>]',
|
|
45
|
+
lines: ['List the recommended and optional migrations this repo has', 'not run yet, or run one of them'],
|
|
46
|
+
},
|
|
41
47
|
];
|
|
42
48
|
const usage = (root) => {
|
|
43
49
|
const rows = USAGE_ROWS.map((row) => (Object.assign(Object.assign({}, row), { command: `${(0, lib_1.repoInvocation)({ root, subcommand: row.subcommand })}${row.args}` })));
|
|
@@ -52,10 +58,11 @@ const usage = (root) => {
|
|
|
52
58
|
const cli = (args) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
53
59
|
switch (args[0]) {
|
|
54
60
|
case 'release':
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
61
|
+
return (0, lib_1.release)({
|
|
62
|
+
root: process.cwd(),
|
|
63
|
+
args: args.slice(1),
|
|
64
|
+
invocation: (0, lib_1.repoInvocation)({ root: process.cwd(), subcommand: 'release' }),
|
|
65
|
+
});
|
|
59
66
|
case 'api':
|
|
60
67
|
return (0, lib_1.apiCommand)({
|
|
61
68
|
root: process.cwd(),
|
|
@@ -80,6 +87,13 @@ const cli = (args) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
|
80
87
|
argv: args.slice(1),
|
|
81
88
|
invocation: (0, lib_1.repoInvocation)({ root: process.cwd(), subcommand: 'update' }),
|
|
82
89
|
});
|
|
90
|
+
case 'migrations':
|
|
91
|
+
return (0, lib_1.migrationsCommand)({
|
|
92
|
+
root: process.cwd(),
|
|
93
|
+
argv: args.slice(1),
|
|
94
|
+
invocation: (0, lib_1.repoInvocation)({ root: process.cwd(), subcommand: 'migrations' }),
|
|
95
|
+
updateInvocation: (0, lib_1.repoInvocation)({ root: process.cwd(), subcommand: 'update' }),
|
|
96
|
+
});
|
|
83
97
|
case 'doctor':
|
|
84
98
|
// Every fix it names is an `et api` command, so it needs that script rather than its own.
|
|
85
99
|
return (0, lib_1.doctorCommand)({
|
package/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/cli/src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/cli/src/index.ts"],"names":[],"mappings":"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"}
|