@glasshome/widget-cli 0.4.5 → 0.4.7
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/bin/cli.ts +14 -2
- package/package.json +5 -5
- package/src/commands/publish.ts +72 -37
- package/template/README.md.template +1 -1
package/bin/cli.ts
CHANGED
|
@@ -43,6 +43,8 @@ Examples:
|
|
|
43
43
|
glasshome-widget info
|
|
44
44
|
glasshome-widget info clock
|
|
45
45
|
glasshome-widget publish
|
|
46
|
+
glasshome-widget publish --name light --bump patch
|
|
47
|
+
glasshome-widget publish --name light --bump minor --scope glasshome
|
|
46
48
|
glasshome-widget login
|
|
47
49
|
glasshome-widget login https://my-hub.example.com
|
|
48
50
|
glasshome-widget upgrade
|
|
@@ -130,9 +132,19 @@ switch (effectiveCommand) {
|
|
|
130
132
|
}
|
|
131
133
|
|
|
132
134
|
case "publish": {
|
|
133
|
-
const hubUrlArg = args
|
|
135
|
+
const hubUrlArg = args.find((a) => !a.startsWith("--"));
|
|
136
|
+
const nameIdx = rawArgs.indexOf("--name");
|
|
137
|
+
const bumpIdx = rawArgs.indexOf("--bump");
|
|
138
|
+
const scopeIdx = rawArgs.indexOf("--scope");
|
|
139
|
+
const pubName = nameIdx !== -1 ? rawArgs[nameIdx + 1] : undefined;
|
|
140
|
+
const pubBump = bumpIdx !== -1 ? rawArgs[bumpIdx + 1] : undefined;
|
|
141
|
+
const pubScope = scopeIdx !== -1 ? rawArgs[scopeIdx + 1] : undefined;
|
|
134
142
|
const { runPublish } = await import("../src/commands/publish");
|
|
135
|
-
await runPublish(resolveWidgetDir(), hubUrlArg
|
|
143
|
+
await runPublish(resolveWidgetDir(), hubUrlArg, {
|
|
144
|
+
name: pubName,
|
|
145
|
+
bump: pubBump as "keep" | "patch" | "minor" | "major" | undefined,
|
|
146
|
+
scope: pubScope,
|
|
147
|
+
});
|
|
136
148
|
outro("Done");
|
|
137
149
|
break;
|
|
138
150
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glasshome/widget-cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.7",
|
|
4
4
|
"description": "CLI for creating and managing GlassHome widgets",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -17,14 +17,14 @@
|
|
|
17
17
|
],
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"@types/bun": "latest",
|
|
20
|
-
"@types/semver": "^7.0.0"
|
|
21
|
-
"vite-plugin-solid": "^2.11.0"
|
|
20
|
+
"@types/semver": "^7.0.0"
|
|
22
21
|
},
|
|
23
22
|
"dependencies": {
|
|
24
23
|
"@clack/prompts": "^0.10.0",
|
|
25
|
-
"@glasshome/widget-sdk": "0.2.
|
|
24
|
+
"@glasshome/widget-sdk": "0.2.5",
|
|
26
25
|
"open": "^11.0.0",
|
|
27
|
-
"semver": "^7.6.0"
|
|
26
|
+
"semver": "^7.6.0",
|
|
27
|
+
"vite-plugin-solid": "^2.11.0"
|
|
28
28
|
},
|
|
29
29
|
"repository": {
|
|
30
30
|
"type": "git",
|
package/src/commands/publish.ts
CHANGED
|
@@ -14,7 +14,17 @@ import {
|
|
|
14
14
|
} from "../utils/manifest";
|
|
15
15
|
import { runLogin } from "./login";
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
interface PublishOptions {
|
|
18
|
+
name?: string;
|
|
19
|
+
bump?: "keep" | "patch" | "minor" | "major";
|
|
20
|
+
scope?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function runPublish(
|
|
24
|
+
cwd: string,
|
|
25
|
+
hubUrlOverride?: string,
|
|
26
|
+
options?: PublishOptions,
|
|
27
|
+
): Promise<void> {
|
|
18
28
|
const s = spinner();
|
|
19
29
|
|
|
20
30
|
// Step 1: Validate (quiet)
|
|
@@ -53,7 +63,15 @@ export async function runPublish(cwd: string, hubUrlOverride?: string): Promise<
|
|
|
53
63
|
}
|
|
54
64
|
|
|
55
65
|
let scope: string;
|
|
56
|
-
if (
|
|
66
|
+
if (options?.scope) {
|
|
67
|
+
const match = scopes.find((s) => s.name === options.scope);
|
|
68
|
+
if (!match) {
|
|
69
|
+
log.error(`Scope @${options.scope} not found. Available: ${scopes.map((s) => s.name).join(", ")}`);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
scope = match.name;
|
|
73
|
+
log.info(`Publishing as @${scope} (${match.type})`);
|
|
74
|
+
} else if (scopes.length === 1) {
|
|
57
75
|
const only = scopes[0]!;
|
|
58
76
|
scope = only.name;
|
|
59
77
|
log.info(`Publishing as @${scope} (${only.type})`);
|
|
@@ -76,48 +94,65 @@ export async function runPublish(cwd: string, hubUrlOverride?: string): Promise<
|
|
|
76
94
|
|
|
77
95
|
// Step 4: Select widget
|
|
78
96
|
const widgets = discoverWidgets(cwd);
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
|
|
98
|
+
let widgetName: string;
|
|
99
|
+
if (options?.name) {
|
|
100
|
+
if (!widgets.includes(options.name)) {
|
|
101
|
+
log.error(`Widget "${options.name}" not found. Available: ${widgets.join(", ")}`);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
widgetName = options.name;
|
|
105
|
+
} else {
|
|
106
|
+
const widgetOptions = widgets.map((name) => {
|
|
107
|
+
const manifest = readManifest(cwd, name);
|
|
108
|
+
let sizeInfo = "";
|
|
109
|
+
try {
|
|
110
|
+
const info = getWidgetBundleInfo(cwd, name);
|
|
111
|
+
sizeInfo = ` — ${formatBytes(info.raw)}`;
|
|
112
|
+
} catch {}
|
|
113
|
+
return {
|
|
114
|
+
value: name,
|
|
115
|
+
label: `${manifest.name}${sizeInfo}`,
|
|
116
|
+
};
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const selected = await select({
|
|
120
|
+
message: "Select widget to publish:",
|
|
121
|
+
options: widgetOptions,
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
if (isCancel(selected)) {
|
|
125
|
+
cancel("Publish cancelled.");
|
|
126
|
+
process.exit(0);
|
|
127
|
+
}
|
|
128
|
+
widgetName = selected as string;
|
|
100
129
|
}
|
|
101
130
|
|
|
102
|
-
const widgetName = selected as string;
|
|
103
131
|
const manifest = readManifest(cwd, widgetName);
|
|
104
132
|
|
|
105
133
|
// Step 5: Version bump (per-widget, from manifest)
|
|
106
134
|
const currentVersion = manifest.version ?? "0.0.0";
|
|
107
135
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
options
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
136
|
+
let bump: string;
|
|
137
|
+
if (options?.bump) {
|
|
138
|
+
bump = options.bump;
|
|
139
|
+
log.info(`Version: ${currentVersion} → ${bump === "keep" ? currentVersion : semver.inc(currentVersion, bump as semver.ReleaseType) ?? currentVersion}`);
|
|
140
|
+
} else {
|
|
141
|
+
const choice = await select({
|
|
142
|
+
message: `${manifest.name} version: ${currentVersion}. Bump?`,
|
|
143
|
+
options: [
|
|
144
|
+
{ value: "keep", label: `Keep ${currentVersion}`, hint: "fails if already published" },
|
|
145
|
+
{ value: "patch", label: `Patch (${semver.inc(currentVersion, "patch")})` },
|
|
146
|
+
{ value: "minor", label: `Minor (${semver.inc(currentVersion, "minor")})` },
|
|
147
|
+
{ value: "major", label: `Major (${semver.inc(currentVersion, "major")})` },
|
|
148
|
+
],
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
if (isCancel(choice)) {
|
|
152
|
+
cancel("Publish cancelled.");
|
|
153
|
+
process.exit(0);
|
|
154
|
+
}
|
|
155
|
+
bump = choice as string;
|
|
121
156
|
}
|
|
122
157
|
|
|
123
158
|
let version = currentVersion;
|
|
@@ -35,7 +35,7 @@ This creates `src/{widget-name}/index.tsx` and `src/{widget-name}/manifest.json`
|
|
|
35
35
|
Connect your widgets to a running GlassHome instance:
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
|
-
bun widget connect http
|
|
38
|
+
bun widget connect http://homeassistant.local:3123
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
This builds all widgets, serves them on your LAN IP, registers them with the dashboard, and watches for file changes. Widgets hot-reload as you edit.
|