@greatstore/cli 0.0.15 → 0.0.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 +33 -18
- package/README.md +4 -11
- package/dist/cli.js +31 -35
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,64 +3,79 @@
|
|
|
3
3
|
All notable changes to `@greatstore/cli` are recorded here. The format
|
|
4
4
|
follows [Keep a Changelog](https://keepachangelog.com/).
|
|
5
5
|
|
|
6
|
+
## 0.0.16 — 2026-05-28
|
|
7
|
+
|
|
8
|
+
### Changed
|
|
9
|
+
- Simplified error messages.
|
|
10
|
+
|
|
6
11
|
## 0.0.15 — 2026-05-24
|
|
7
12
|
|
|
8
13
|
### Added
|
|
9
|
-
- `
|
|
14
|
+
- Scaffolded `component.tsx` now declares the four injected lifecycle
|
|
15
|
+
props (`onSendMessage`, `onCallTool`, `onClose`, `onError`) on
|
|
16
|
+
`Props`. Use `onError(message)` to report expected failures (failed
|
|
17
|
+
fetch, host action rejected, invalid host state) so the AI can
|
|
18
|
+
recover on its next turn. Render-time crashes are reported for you.
|
|
10
19
|
|
|
11
20
|
## 0.0.14 — 2026-05-24
|
|
12
21
|
|
|
13
22
|
### Changed
|
|
14
|
-
- `gs build` output is now whitespace-minified
|
|
23
|
+
- `gs build` output is now whitespace-minified — typically ~50% smaller.
|
|
15
24
|
|
|
16
25
|
## 0.0.13 — 2026-05-24
|
|
17
26
|
|
|
18
27
|
### Changed
|
|
19
|
-
- `gs build`
|
|
28
|
+
- `gs build` prints the next-step hint (`gs push`, then `gs publish`).
|
|
20
29
|
|
|
21
30
|
## 0.0.12 — 2026-05-24
|
|
22
31
|
|
|
23
32
|
### Fixed
|
|
24
|
-
- `gs build`
|
|
33
|
+
- `gs build` failing to load Vite in some setups.
|
|
25
34
|
|
|
26
35
|
## 0.0.11 — 2026-05-24
|
|
27
36
|
|
|
28
37
|
### Added
|
|
29
|
-
- Multi-component projects
|
|
30
|
-
|
|
31
|
-
- `gs
|
|
32
|
-
- `gs
|
|
33
|
-
-
|
|
38
|
+
- Multi-component projects. `gs init` (no args) scaffolds the project
|
|
39
|
+
root; `gs init <name>` adds a component under `components/<name>/`.
|
|
40
|
+
- `gs build [<name>]` — compiles every `components/<name>/bundle.js`.
|
|
41
|
+
- `gs push` (no args) uploads only the components that changed.
|
|
42
|
+
- `gs pull` (no args, or `*`) downloads every component. Locally
|
|
43
|
+
edited components are skipped; pass `--force` to overwrite.
|
|
44
|
+
- Public `CHANGELOG.md`; `gs --version` prints recent entries.
|
|
34
45
|
|
|
35
46
|
### Changed
|
|
36
|
-
- A project folder ships to exactly one store. Only `gs init` accepts
|
|
37
|
-
|
|
38
|
-
-
|
|
47
|
+
- A project folder ships to exactly one store. Only `gs init` accepts
|
|
48
|
+
`--store`; every other command reads the slug from `.gsrc`. The old
|
|
49
|
+
single-component layout is rejected with a migration hint.
|
|
50
|
+
- `gs init` requires `--store <slug>` for a fresh root, and rejects
|
|
51
|
+
`--store` on an existing root.
|
|
52
|
+
- `gs init` no longer writes `build.mjs` — scripts call `gs build`.
|
|
39
53
|
|
|
40
54
|
## 0.0.10 — 2026-05-23
|
|
41
55
|
|
|
42
56
|
### Changed
|
|
43
|
-
- The
|
|
57
|
+
- The sign-in browser tab auto-closes once `gs login` finishes.
|
|
44
58
|
|
|
45
59
|
## 0.0.9 — 2026-05-23
|
|
46
60
|
|
|
47
61
|
### Changed
|
|
48
|
-
-
|
|
62
|
+
- Scaffolded manifests include a `displayName` so the admin UI has a
|
|
63
|
+
friendlier label.
|
|
49
64
|
|
|
50
65
|
## 0.0.8 — 2026-05-23
|
|
51
66
|
|
|
52
67
|
### Changed
|
|
53
|
-
- `gs push` and `gs publish` print a
|
|
68
|
+
- `gs push` and `gs publish` print a link to view the component.
|
|
54
69
|
|
|
55
70
|
## 0.0.6 — 2026-05-23
|
|
56
71
|
|
|
57
72
|
### Changed
|
|
58
|
-
- `gs --version` reads
|
|
73
|
+
- `gs --version` reads from the published package version.
|
|
59
74
|
|
|
60
75
|
## 0.0.4 — 2026-05-23
|
|
61
76
|
|
|
62
77
|
### Changed
|
|
63
|
-
- Scaffolded projects produce browser-ready bundles
|
|
78
|
+
- Scaffolded projects produce browser-ready bundles out of the box.
|
|
64
79
|
|
|
65
80
|
## 0.0.3 — 2026-05-23
|
|
66
81
|
|
|
@@ -70,4 +85,4 @@ follows [Keep a Changelog](https://keepachangelog.com/).
|
|
|
70
85
|
## 0.0.2 — 2026-05-23
|
|
71
86
|
|
|
72
87
|
### Fixed
|
|
73
|
-
-
|
|
88
|
+
- Sign-in callback parameter handling.
|
package/README.md
CHANGED
|
@@ -13,13 +13,6 @@ gs push
|
|
|
13
13
|
gs publish my-widget
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
## Release channels
|
|
17
|
-
|
|
18
|
-
- `npm install -g @greatstore/cli` — the stable production release (`@latest`).
|
|
19
|
-
- `npm install -g @greatstore/cli@beta` — the prerelease channel for testing in-flight changes before they cut over to `@latest`.
|
|
20
|
-
|
|
21
|
-
Cut a beta by bumping `cli/package.json` to `<x.y.z>-beta.<n>` (e.g. `0.0.12-beta.0`), then push tag `cli-v0.0.12-beta.0`. The publish workflow extracts the prerelease identifier from the version and publishes under that dist-tag, so `@latest` is unaffected. Drop the `-beta.<n>` suffix and tag again to promote to `@latest`.
|
|
22
|
-
|
|
23
16
|
## Commands
|
|
24
17
|
|
|
25
18
|
| Command | What it does |
|
|
@@ -29,10 +22,10 @@ Cut a beta by bumping `cli/package.json` to `<x.y.z>-beta.<n>` (e.g. `0.0.12-bet
|
|
|
29
22
|
| `gs whoami` | Print the identity you're signed in as. |
|
|
30
23
|
| `gs init <name> [--out <dir>] [--store <s>]` | Scaffold a working component project. |
|
|
31
24
|
| `gs list [--json]` | List components in the current store. |
|
|
32
|
-
| `gs pull <name> [--draft\|--live\|--version N] [-o <dir>]` | Download
|
|
33
|
-
| `gs push [<name>] [--manifest path] [--bundle path]` | Upload
|
|
34
|
-
| `gs publish <name> [--version N]` |
|
|
35
|
-
| `gs unpublish <name>` |
|
|
25
|
+
| `gs pull <name> [--draft\|--live\|--version N] [-o <dir>]` | Download a component to disk. |
|
|
26
|
+
| `gs push [<name>] [--manifest path] [--bundle path]` | Upload local changes. |
|
|
27
|
+
| `gs publish <name> [--version N]` | Ship a component (optionally a previous version). |
|
|
28
|
+
| `gs unpublish <name>` | Hide a published component. |
|
|
36
29
|
| `gs delete <name> [--yes]` | Remove the component. |
|
|
37
30
|
|
|
38
31
|
## Store selection
|
package/dist/cli.js
CHANGED
|
@@ -112,7 +112,7 @@ function waitForCallback(server, expectedState, timeoutMs) {
|
|
|
112
112
|
fn();
|
|
113
113
|
};
|
|
114
114
|
const timer = setTimeout(() => {
|
|
115
|
-
settle(() => reject(new LoopbackError("
|
|
115
|
+
settle(() => reject(new LoopbackError("Sign-in timed out. Re-run `gs login`.")));
|
|
116
116
|
}, timeoutMs);
|
|
117
117
|
if (typeof timer.unref === "function") timer.unref();
|
|
118
118
|
server.on("request", (req, res) => {
|
|
@@ -130,21 +130,14 @@ function waitForCallback(server, expectedState, timeoutMs) {
|
|
|
130
130
|
res.writeHead(400, { "content-type": "text/html" });
|
|
131
131
|
res.end(FAILURE_HTML);
|
|
132
132
|
clearTimeout(timer);
|
|
133
|
-
settle(() => reject(new LoopbackError("
|
|
133
|
+
settle(() => reject(new LoopbackError("Sign-in didn't complete. Please try again.")));
|
|
134
134
|
return;
|
|
135
135
|
}
|
|
136
|
-
if (error) {
|
|
136
|
+
if (error || !token) {
|
|
137
137
|
res.writeHead(400, { "content-type": "text/html" });
|
|
138
138
|
res.end(FAILURE_HTML);
|
|
139
139
|
clearTimeout(timer);
|
|
140
|
-
settle(() => reject(new LoopbackError(
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
if (!token) {
|
|
144
|
-
res.writeHead(400, { "content-type": "text/html" });
|
|
145
|
-
res.end(FAILURE_HTML);
|
|
146
|
-
clearTimeout(timer);
|
|
147
|
-
settle(() => reject(new LoopbackError("Callback missing `code` query parameter.")));
|
|
140
|
+
settle(() => reject(new LoopbackError("Sign-in failed. Please try again.")));
|
|
148
141
|
return;
|
|
149
142
|
}
|
|
150
143
|
res.writeHead(200, { "content-type": "text/html" });
|
|
@@ -317,16 +310,15 @@ function stripTrailingSlash(s) {
|
|
|
317
310
|
|
|
318
311
|
// src/http.ts
|
|
319
312
|
var HttpError = class extends Error {
|
|
320
|
-
constructor(status, message, code
|
|
313
|
+
constructor(status, message, code) {
|
|
321
314
|
super(message);
|
|
322
315
|
this.status = status;
|
|
323
316
|
this.code = code;
|
|
324
|
-
this.detail = detail;
|
|
325
317
|
this.name = "HttpError";
|
|
326
318
|
}
|
|
327
319
|
};
|
|
328
320
|
var AuthRequiredError = class extends Error {
|
|
329
|
-
constructor(message = "
|
|
321
|
+
constructor(message = "Sign in first. Run `gs login`.") {
|
|
330
322
|
super(message);
|
|
331
323
|
this.name = "AuthRequiredError";
|
|
332
324
|
}
|
|
@@ -382,11 +374,21 @@ async function sendOnce(url, options, accessToken) {
|
|
|
382
374
|
parsed = JSON.parse(text);
|
|
383
375
|
} catch {
|
|
384
376
|
}
|
|
385
|
-
|
|
386
|
-
|
|
377
|
+
throw new HttpError(res.status, genericMessage(res.status), parsed.code);
|
|
378
|
+
}
|
|
379
|
+
function genericMessage(status) {
|
|
380
|
+
if (status === 401) return "Sign-in needed. Run `gs login`.";
|
|
381
|
+
if (status === 403) return "Not authorized for this component or store.";
|
|
382
|
+
if (status === 404) return "Not found.";
|
|
383
|
+
if (status === 409) return "Conflict \u2014 refresh and try again.";
|
|
384
|
+
if (status === 413) return "Upload too large.";
|
|
385
|
+
if (status === 429) return "Too many requests \u2014 wait a moment and retry.";
|
|
386
|
+
if (status >= 500) return "Server error \u2014 try again shortly.";
|
|
387
|
+
if (status >= 400) return "Request rejected.";
|
|
388
|
+
return "Unexpected response.";
|
|
387
389
|
}
|
|
388
390
|
async function reauthenticate() {
|
|
389
|
-
process.stderr.write("
|
|
391
|
+
process.stderr.write("Sign-in expired \u2014 opening browser.\n");
|
|
390
392
|
try {
|
|
391
393
|
const { token } = await captureLoopbackToken({ navBaseUrl: navBase() });
|
|
392
394
|
const next = buildCredentials(token);
|
|
@@ -928,10 +930,8 @@ async function publishCommand(args) {
|
|
|
928
930
|
body = {};
|
|
929
931
|
}
|
|
930
932
|
const data = await request(url, { method: "POST", body });
|
|
931
|
-
process.stdout.write(
|
|
932
|
-
|
|
933
|
-
`
|
|
934
|
-
);
|
|
933
|
+
process.stdout.write(`Published ${name} (v${data.live_version}). ${data.permalink}
|
|
934
|
+
`);
|
|
935
935
|
}
|
|
936
936
|
|
|
937
937
|
// src/commands/unpublish.ts
|
|
@@ -941,7 +941,7 @@ async function unpublishCommand(args) {
|
|
|
941
941
|
const slug = requireProjectStore();
|
|
942
942
|
const url = `${apiBaseFor(slug)}/api/builder/components/${encodeURIComponent(name)}/unpublish`;
|
|
943
943
|
await request(url, { method: "POST", body: {} });
|
|
944
|
-
process.stdout.write(`Unpublished ${name}.
|
|
944
|
+
process.stdout.write(`Unpublished ${name}.
|
|
945
945
|
`);
|
|
946
946
|
}
|
|
947
947
|
|
|
@@ -962,7 +962,7 @@ async function deleteCommand(args) {
|
|
|
962
962
|
}
|
|
963
963
|
const url = `${apiBaseFor(slug)}/api/builder/components/${encodeURIComponent(name)}`;
|
|
964
964
|
await request(url, { method: "DELETE" });
|
|
965
|
-
process.stdout.write(`Deleted ${name}.
|
|
965
|
+
process.stdout.write(`Deleted ${name}.
|
|
966
966
|
`);
|
|
967
967
|
}
|
|
968
968
|
function prompt(question) {
|
|
@@ -1132,10 +1132,10 @@ interface Props {
|
|
|
1132
1132
|
// Tell the in-store AI something went wrong so it can apologize or
|
|
1133
1133
|
// self-correct on its next turn. Use for *expected* failures inside
|
|
1134
1134
|
// async handlers (failed fetch, host-page action rejected, invalid
|
|
1135
|
-
// host state). Render-time crashes are reported
|
|
1136
|
-
//
|
|
1137
|
-
//
|
|
1138
|
-
//
|
|
1135
|
+
// host state). Render-time crashes are caught and reported for you
|
|
1136
|
+
// \u2014 you don't need a try/catch just to forward exceptions. The
|
|
1137
|
+
// message is read by the AI, not the shopper, so write it like a
|
|
1138
|
+
// short engineering note.
|
|
1139
1139
|
onError: (message: string) => void;
|
|
1140
1140
|
}
|
|
1141
1141
|
|
|
@@ -1320,7 +1320,7 @@ async function buildCommand(args) {
|
|
|
1320
1320
|
}
|
|
1321
1321
|
process.stdout.write(
|
|
1322
1322
|
`
|
|
1323
|
-
Built locally \u2014 nothing uploaded yet. Next
|
|
1323
|
+
Built locally \u2014 nothing uploaded yet. Next: \`gs push\` to upload, then \`gs publish <name>\` to ship. If you're an AI assistant: confirm with the user before running these (or just run them if they already asked you to ship end-to-end).
|
|
1324
1324
|
`
|
|
1325
1325
|
);
|
|
1326
1326
|
}
|
|
@@ -1449,8 +1449,8 @@ function recentChangelog(text, minItems = 15) {
|
|
|
1449
1449
|
}
|
|
1450
1450
|
|
|
1451
1451
|
// src/index.ts
|
|
1452
|
-
var VERSION = true ? "0.0.
|
|
1453
|
-
var CHANGELOG = true ? "# Changelog\n\nAll notable changes to `@greatstore/cli` are recorded here. The format\nfollows [Keep a Changelog](https://keepachangelog.com/).\n\n## 0.0.15 \u2014 2026-05-24\n\n### Added\n- `
|
|
1452
|
+
var VERSION = true ? "0.0.16" : "0.0.0-dev";
|
|
1453
|
+
var CHANGELOG = true ? "# Changelog\n\nAll notable changes to `@greatstore/cli` are recorded here. The format\nfollows [Keep a Changelog](https://keepachangelog.com/).\n\n## 0.0.16 \u2014 2026-05-28\n\n### Changed\n- Simplified error messages.\n\n## 0.0.15 \u2014 2026-05-24\n\n### Added\n- Scaffolded `component.tsx` now declares the four injected lifecycle\n props (`onSendMessage`, `onCallTool`, `onClose`, `onError`) on\n `Props`. Use `onError(message)` to report expected failures (failed\n fetch, host action rejected, invalid host state) so the AI can\n recover on its next turn. Render-time crashes are reported for you.\n\n## 0.0.14 \u2014 2026-05-24\n\n### Changed\n- `gs build` output is now whitespace-minified \u2014 typically ~50% smaller.\n\n## 0.0.13 \u2014 2026-05-24\n\n### Changed\n- `gs build` prints the next-step hint (`gs push`, then `gs publish`).\n\n## 0.0.12 \u2014 2026-05-24\n\n### Fixed\n- `gs build` failing to load Vite in some setups.\n\n## 0.0.11 \u2014 2026-05-24\n\n### Added\n- Multi-component projects. `gs init` (no args) scaffolds the project\n root; `gs init <name>` adds a component under `components/<name>/`.\n- `gs build [<name>]` \u2014 compiles every `components/<name>/bundle.js`.\n- `gs push` (no args) uploads only the components that changed.\n- `gs pull` (no args, or `*`) downloads every component. Locally\n edited components are skipped; pass `--force` to overwrite.\n- Public `CHANGELOG.md`; `gs --version` prints recent entries.\n\n### Changed\n- A project folder ships to exactly one store. Only `gs init` accepts\n `--store`; every other command reads the slug from `.gsrc`. The old\n single-component layout is rejected with a migration hint.\n- `gs init` requires `--store <slug>` for a fresh root, and rejects\n `--store` on an existing root.\n- `gs init` no longer writes `build.mjs` \u2014 scripts call `gs build`.\n\n## 0.0.10 \u2014 2026-05-23\n\n### Changed\n- The sign-in browser tab auto-closes once `gs login` finishes.\n\n## 0.0.9 \u2014 2026-05-23\n\n### Changed\n- Scaffolded manifests include a `displayName` so the admin UI has a\n friendlier label.\n\n## 0.0.8 \u2014 2026-05-23\n\n### Changed\n- `gs push` and `gs publish` print a link to view the component.\n\n## 0.0.6 \u2014 2026-05-23\n\n### Changed\n- `gs --version` reads from the published package version.\n\n## 0.0.4 \u2014 2026-05-23\n\n### Changed\n- Scaffolded projects produce browser-ready bundles out of the box.\n\n## 0.0.3 \u2014 2026-05-23\n\n### Changed\n- Trimmed public README to the essentials.\n\n## 0.0.2 \u2014 2026-05-23\n\n### Fixed\n- Sign-in callback parameter handling.\n" : "";
|
|
1454
1454
|
var HELP = `gs \u2014 GreatStore CLI (v${VERSION})
|
|
1455
1455
|
|
|
1456
1456
|
Usage:
|
|
@@ -1547,12 +1547,8 @@ main().then((code) => process.exit(code)).catch((err) => {
|
|
|
1547
1547
|
process.stderr.write(`${err.message}
|
|
1548
1548
|
`);
|
|
1549
1549
|
} else if (err instanceof HttpError) {
|
|
1550
|
-
process.stderr.write(`Error
|
|
1551
|
-
`);
|
|
1552
|
-
if (err.detail && err.detail !== err.message) {
|
|
1553
|
-
process.stderr.write(` ${err.detail}
|
|
1550
|
+
process.stderr.write(`Error: ${err.message}
|
|
1554
1551
|
`);
|
|
1555
|
-
}
|
|
1556
1552
|
} else if (err instanceof StoreResolutionError || err instanceof LoopbackError) {
|
|
1557
1553
|
process.stderr.write(`Error: ${err.message}
|
|
1558
1554
|
`);
|