@kohryan/moodui 0.0.8 → 0.0.9
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/dist/cli.js +598 -24
- package/dist/cli.mjs +580 -6
- package/dist/ui/assets/index-BKsInBa3.js +7 -0
- package/dist/ui/assets/index-CMk6XQXy.js +58 -0
- package/dist/ui/index.html +12 -0
- package/package.json +12 -7
- package/src/ui/index.html +12 -0
- package/src/ui/main.tsx +11 -0
- package/src/ui/vite.config.ts +17 -0
package/dist/cli.mjs
CHANGED
|
@@ -3,8 +3,527 @@ import {
|
|
|
3
3
|
} from "./chunk-5D6KNM5J.mjs";
|
|
4
4
|
|
|
5
5
|
// src/cli.ts
|
|
6
|
-
import
|
|
6
|
+
import fs6 from "fs/promises";
|
|
7
|
+
import path2 from "path";
|
|
8
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
9
|
+
import http from "http";
|
|
10
|
+
|
|
11
|
+
// node_modules/open/index.js
|
|
12
|
+
import process7 from "process";
|
|
13
|
+
import { Buffer } from "buffer";
|
|
7
14
|
import path from "path";
|
|
15
|
+
import { fileURLToPath } from "url";
|
|
16
|
+
import { promisify as promisify5 } from "util";
|
|
17
|
+
import childProcess from "child_process";
|
|
18
|
+
import fs5, { constants as fsConstants2 } from "fs/promises";
|
|
19
|
+
|
|
20
|
+
// node_modules/wsl-utils/index.js
|
|
21
|
+
import process3 from "process";
|
|
22
|
+
import fs4, { constants as fsConstants } from "fs/promises";
|
|
23
|
+
|
|
24
|
+
// node_modules/is-wsl/index.js
|
|
25
|
+
import process2 from "process";
|
|
26
|
+
import os from "os";
|
|
27
|
+
import fs3 from "fs";
|
|
28
|
+
|
|
29
|
+
// node_modules/is-inside-container/index.js
|
|
30
|
+
import fs2 from "fs";
|
|
31
|
+
|
|
32
|
+
// node_modules/is-docker/index.js
|
|
33
|
+
import fs from "fs";
|
|
34
|
+
var isDockerCached;
|
|
35
|
+
function hasDockerEnv() {
|
|
36
|
+
try {
|
|
37
|
+
fs.statSync("/.dockerenv");
|
|
38
|
+
return true;
|
|
39
|
+
} catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function hasDockerCGroup() {
|
|
44
|
+
try {
|
|
45
|
+
return fs.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
|
|
46
|
+
} catch {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function isDocker() {
|
|
51
|
+
if (isDockerCached === void 0) {
|
|
52
|
+
isDockerCached = hasDockerEnv() || hasDockerCGroup();
|
|
53
|
+
}
|
|
54
|
+
return isDockerCached;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// node_modules/is-inside-container/index.js
|
|
58
|
+
var cachedResult;
|
|
59
|
+
var hasContainerEnv = () => {
|
|
60
|
+
try {
|
|
61
|
+
fs2.statSync("/run/.containerenv");
|
|
62
|
+
return true;
|
|
63
|
+
} catch {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
function isInsideContainer() {
|
|
68
|
+
if (cachedResult === void 0) {
|
|
69
|
+
cachedResult = hasContainerEnv() || isDocker();
|
|
70
|
+
}
|
|
71
|
+
return cachedResult;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// node_modules/is-wsl/index.js
|
|
75
|
+
var isWsl = () => {
|
|
76
|
+
if (process2.platform !== "linux") {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
if (os.release().toLowerCase().includes("microsoft")) {
|
|
80
|
+
if (isInsideContainer()) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
if (fs3.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft")) {
|
|
87
|
+
return !isInsideContainer();
|
|
88
|
+
}
|
|
89
|
+
} catch {
|
|
90
|
+
}
|
|
91
|
+
if (fs3.existsSync("/proc/sys/fs/binfmt_misc/WSLInterop") || fs3.existsSync("/run/WSL")) {
|
|
92
|
+
return !isInsideContainer();
|
|
93
|
+
}
|
|
94
|
+
return false;
|
|
95
|
+
};
|
|
96
|
+
var is_wsl_default = process2.env.__IS_WSL_TEST__ ? isWsl : isWsl();
|
|
97
|
+
|
|
98
|
+
// node_modules/wsl-utils/index.js
|
|
99
|
+
var wslDrivesMountPoint = /* @__PURE__ */ (() => {
|
|
100
|
+
const defaultMountPoint = "/mnt/";
|
|
101
|
+
let mountPoint;
|
|
102
|
+
return async function() {
|
|
103
|
+
if (mountPoint) {
|
|
104
|
+
return mountPoint;
|
|
105
|
+
}
|
|
106
|
+
const configFilePath = "/etc/wsl.conf";
|
|
107
|
+
let isConfigFileExists = false;
|
|
108
|
+
try {
|
|
109
|
+
await fs4.access(configFilePath, fsConstants.F_OK);
|
|
110
|
+
isConfigFileExists = true;
|
|
111
|
+
} catch {
|
|
112
|
+
}
|
|
113
|
+
if (!isConfigFileExists) {
|
|
114
|
+
return defaultMountPoint;
|
|
115
|
+
}
|
|
116
|
+
const configContent = await fs4.readFile(configFilePath, { encoding: "utf8" });
|
|
117
|
+
const configMountPoint = /(?<!#.*)root\s*=\s*(?<mountPoint>.*)/g.exec(configContent);
|
|
118
|
+
if (!configMountPoint) {
|
|
119
|
+
return defaultMountPoint;
|
|
120
|
+
}
|
|
121
|
+
mountPoint = configMountPoint.groups.mountPoint.trim();
|
|
122
|
+
mountPoint = mountPoint.endsWith("/") ? mountPoint : `${mountPoint}/`;
|
|
123
|
+
return mountPoint;
|
|
124
|
+
};
|
|
125
|
+
})();
|
|
126
|
+
var powerShellPathFromWsl = async () => {
|
|
127
|
+
const mountPoint = await wslDrivesMountPoint();
|
|
128
|
+
return `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`;
|
|
129
|
+
};
|
|
130
|
+
var powerShellPath = async () => {
|
|
131
|
+
if (is_wsl_default) {
|
|
132
|
+
return powerShellPathFromWsl();
|
|
133
|
+
}
|
|
134
|
+
return `${process3.env.SYSTEMROOT || process3.env.windir || String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
// node_modules/define-lazy-prop/index.js
|
|
138
|
+
function defineLazyProperty(object, propertyName, valueGetter) {
|
|
139
|
+
const define = (value) => Object.defineProperty(object, propertyName, { value, enumerable: true, writable: true });
|
|
140
|
+
Object.defineProperty(object, propertyName, {
|
|
141
|
+
configurable: true,
|
|
142
|
+
enumerable: true,
|
|
143
|
+
get() {
|
|
144
|
+
const result = valueGetter();
|
|
145
|
+
define(result);
|
|
146
|
+
return result;
|
|
147
|
+
},
|
|
148
|
+
set(value) {
|
|
149
|
+
define(value);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
return object;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// node_modules/default-browser/index.js
|
|
156
|
+
import { promisify as promisify4 } from "util";
|
|
157
|
+
import process6 from "process";
|
|
158
|
+
import { execFile as execFile4 } from "child_process";
|
|
159
|
+
|
|
160
|
+
// node_modules/default-browser-id/index.js
|
|
161
|
+
import { promisify } from "util";
|
|
162
|
+
import process4 from "process";
|
|
163
|
+
import { execFile } from "child_process";
|
|
164
|
+
var execFileAsync = promisify(execFile);
|
|
165
|
+
async function defaultBrowserId() {
|
|
166
|
+
if (process4.platform !== "darwin") {
|
|
167
|
+
throw new Error("macOS only");
|
|
168
|
+
}
|
|
169
|
+
const { stdout } = await execFileAsync("defaults", ["read", "com.apple.LaunchServices/com.apple.launchservices.secure", "LSHandlers"]);
|
|
170
|
+
const match = /LSHandlerRoleAll = "(?!-)(?<id>[^"]+?)";\s+?LSHandlerURLScheme = (?:http|https);/.exec(stdout);
|
|
171
|
+
const browserId = match?.groups.id ?? "com.apple.Safari";
|
|
172
|
+
if (browserId === "com.apple.safari") {
|
|
173
|
+
return "com.apple.Safari";
|
|
174
|
+
}
|
|
175
|
+
return browserId;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// node_modules/run-applescript/index.js
|
|
179
|
+
import process5 from "process";
|
|
180
|
+
import { promisify as promisify2 } from "util";
|
|
181
|
+
import { execFile as execFile2, execFileSync } from "child_process";
|
|
182
|
+
var execFileAsync2 = promisify2(execFile2);
|
|
183
|
+
async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
|
|
184
|
+
if (process5.platform !== "darwin") {
|
|
185
|
+
throw new Error("macOS only");
|
|
186
|
+
}
|
|
187
|
+
const outputArguments = humanReadableOutput ? [] : ["-ss"];
|
|
188
|
+
const execOptions = {};
|
|
189
|
+
if (signal) {
|
|
190
|
+
execOptions.signal = signal;
|
|
191
|
+
}
|
|
192
|
+
const { stdout } = await execFileAsync2("osascript", ["-e", script, outputArguments], execOptions);
|
|
193
|
+
return stdout.trim();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// node_modules/bundle-name/index.js
|
|
197
|
+
async function bundleName(bundleId) {
|
|
198
|
+
return runAppleScript(`tell application "Finder" to set app_path to application file id "${bundleId}" as string
|
|
199
|
+
tell application "System Events" to get value of property list item "CFBundleName" of property list file (app_path & ":Contents:Info.plist")`);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// node_modules/default-browser/windows.js
|
|
203
|
+
import { promisify as promisify3 } from "util";
|
|
204
|
+
import { execFile as execFile3 } from "child_process";
|
|
205
|
+
var execFileAsync3 = promisify3(execFile3);
|
|
206
|
+
var windowsBrowserProgIds = {
|
|
207
|
+
MSEdgeHTM: { name: "Edge", id: "com.microsoft.edge" },
|
|
208
|
+
// The missing `L` is correct.
|
|
209
|
+
MSEdgeBHTML: { name: "Edge Beta", id: "com.microsoft.edge.beta" },
|
|
210
|
+
MSEdgeDHTML: { name: "Edge Dev", id: "com.microsoft.edge.dev" },
|
|
211
|
+
AppXq0fevzme2pys62n3e0fbqa7peapykr8v: { name: "Edge", id: "com.microsoft.edge.old" },
|
|
212
|
+
ChromeHTML: { name: "Chrome", id: "com.google.chrome" },
|
|
213
|
+
ChromeBHTML: { name: "Chrome Beta", id: "com.google.chrome.beta" },
|
|
214
|
+
ChromeDHTML: { name: "Chrome Dev", id: "com.google.chrome.dev" },
|
|
215
|
+
ChromiumHTM: { name: "Chromium", id: "org.chromium.Chromium" },
|
|
216
|
+
BraveHTML: { name: "Brave", id: "com.brave.Browser" },
|
|
217
|
+
BraveBHTML: { name: "Brave Beta", id: "com.brave.Browser.beta" },
|
|
218
|
+
BraveDHTML: { name: "Brave Dev", id: "com.brave.Browser.dev" },
|
|
219
|
+
BraveSSHTM: { name: "Brave Nightly", id: "com.brave.Browser.nightly" },
|
|
220
|
+
FirefoxURL: { name: "Firefox", id: "org.mozilla.firefox" },
|
|
221
|
+
OperaStable: { name: "Opera", id: "com.operasoftware.Opera" },
|
|
222
|
+
VivaldiHTM: { name: "Vivaldi", id: "com.vivaldi.Vivaldi" },
|
|
223
|
+
"IE.HTTP": { name: "Internet Explorer", id: "com.microsoft.ie" }
|
|
224
|
+
};
|
|
225
|
+
var _windowsBrowserProgIdMap = new Map(Object.entries(windowsBrowserProgIds));
|
|
226
|
+
var UnknownBrowserError = class extends Error {
|
|
227
|
+
};
|
|
228
|
+
async function defaultBrowser(_execFileAsync = execFileAsync3) {
|
|
229
|
+
const { stdout } = await _execFileAsync("reg", [
|
|
230
|
+
"QUERY",
|
|
231
|
+
" HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice",
|
|
232
|
+
"/v",
|
|
233
|
+
"ProgId"
|
|
234
|
+
]);
|
|
235
|
+
const match = /ProgId\s*REG_SZ\s*(?<id>\S+)/.exec(stdout);
|
|
236
|
+
if (!match) {
|
|
237
|
+
throw new UnknownBrowserError(`Cannot find Windows browser in stdout: ${JSON.stringify(stdout)}`);
|
|
238
|
+
}
|
|
239
|
+
const { id } = match.groups;
|
|
240
|
+
const dotIndex = id.lastIndexOf(".");
|
|
241
|
+
const hyphenIndex = id.lastIndexOf("-");
|
|
242
|
+
const baseIdByDot = dotIndex === -1 ? void 0 : id.slice(0, dotIndex);
|
|
243
|
+
const baseIdByHyphen = hyphenIndex === -1 ? void 0 : id.slice(0, hyphenIndex);
|
|
244
|
+
return windowsBrowserProgIds[id] ?? windowsBrowserProgIds[baseIdByDot] ?? windowsBrowserProgIds[baseIdByHyphen] ?? { name: id, id };
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// node_modules/default-browser/index.js
|
|
248
|
+
var execFileAsync4 = promisify4(execFile4);
|
|
249
|
+
var titleize = (string) => string.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x) => x.toUpperCase());
|
|
250
|
+
async function defaultBrowser2() {
|
|
251
|
+
if (process6.platform === "darwin") {
|
|
252
|
+
const id = await defaultBrowserId();
|
|
253
|
+
const name = await bundleName(id);
|
|
254
|
+
return { name, id };
|
|
255
|
+
}
|
|
256
|
+
if (process6.platform === "linux") {
|
|
257
|
+
const { stdout } = await execFileAsync4("xdg-mime", ["query", "default", "x-scheme-handler/http"]);
|
|
258
|
+
const id = stdout.trim();
|
|
259
|
+
const name = titleize(id.replace(/.desktop$/, "").replace("-", " "));
|
|
260
|
+
return { name, id };
|
|
261
|
+
}
|
|
262
|
+
if (process6.platform === "win32") {
|
|
263
|
+
return defaultBrowser();
|
|
264
|
+
}
|
|
265
|
+
throw new Error("Only macOS, Linux, and Windows are supported");
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// node_modules/open/index.js
|
|
269
|
+
var execFile5 = promisify5(childProcess.execFile);
|
|
270
|
+
var __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
271
|
+
var localXdgOpenPath = path.join(__dirname, "xdg-open");
|
|
272
|
+
var { platform, arch } = process7;
|
|
273
|
+
async function getWindowsDefaultBrowserFromWsl() {
|
|
274
|
+
const powershellPath = await powerShellPath();
|
|
275
|
+
const rawCommand = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
|
|
276
|
+
const encodedCommand = Buffer.from(rawCommand, "utf16le").toString("base64");
|
|
277
|
+
const { stdout } = await execFile5(
|
|
278
|
+
powershellPath,
|
|
279
|
+
[
|
|
280
|
+
"-NoProfile",
|
|
281
|
+
"-NonInteractive",
|
|
282
|
+
"-ExecutionPolicy",
|
|
283
|
+
"Bypass",
|
|
284
|
+
"-EncodedCommand",
|
|
285
|
+
encodedCommand
|
|
286
|
+
],
|
|
287
|
+
{ encoding: "utf8" }
|
|
288
|
+
);
|
|
289
|
+
const progId = stdout.trim();
|
|
290
|
+
const browserMap = {
|
|
291
|
+
ChromeHTML: "com.google.chrome",
|
|
292
|
+
BraveHTML: "com.brave.Browser",
|
|
293
|
+
MSEdgeHTM: "com.microsoft.edge",
|
|
294
|
+
FirefoxURL: "org.mozilla.firefox"
|
|
295
|
+
};
|
|
296
|
+
return browserMap[progId] ? { id: browserMap[progId] } : {};
|
|
297
|
+
}
|
|
298
|
+
var pTryEach = async (array, mapper) => {
|
|
299
|
+
let latestError;
|
|
300
|
+
for (const item of array) {
|
|
301
|
+
try {
|
|
302
|
+
return await mapper(item);
|
|
303
|
+
} catch (error) {
|
|
304
|
+
latestError = error;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
throw latestError;
|
|
308
|
+
};
|
|
309
|
+
var baseOpen = async (options) => {
|
|
310
|
+
options = {
|
|
311
|
+
wait: false,
|
|
312
|
+
background: false,
|
|
313
|
+
newInstance: false,
|
|
314
|
+
allowNonzeroExitCode: false,
|
|
315
|
+
...options
|
|
316
|
+
};
|
|
317
|
+
if (Array.isArray(options.app)) {
|
|
318
|
+
return pTryEach(options.app, (singleApp) => baseOpen({
|
|
319
|
+
...options,
|
|
320
|
+
app: singleApp
|
|
321
|
+
}));
|
|
322
|
+
}
|
|
323
|
+
let { name: app, arguments: appArguments = [] } = options.app ?? {};
|
|
324
|
+
appArguments = [...appArguments];
|
|
325
|
+
if (Array.isArray(app)) {
|
|
326
|
+
return pTryEach(app, (appName) => baseOpen({
|
|
327
|
+
...options,
|
|
328
|
+
app: {
|
|
329
|
+
name: appName,
|
|
330
|
+
arguments: appArguments
|
|
331
|
+
}
|
|
332
|
+
}));
|
|
333
|
+
}
|
|
334
|
+
if (app === "browser" || app === "browserPrivate") {
|
|
335
|
+
const ids = {
|
|
336
|
+
"com.google.chrome": "chrome",
|
|
337
|
+
"google-chrome.desktop": "chrome",
|
|
338
|
+
"com.brave.Browser": "brave",
|
|
339
|
+
"org.mozilla.firefox": "firefox",
|
|
340
|
+
"firefox.desktop": "firefox",
|
|
341
|
+
"com.microsoft.msedge": "edge",
|
|
342
|
+
"com.microsoft.edge": "edge",
|
|
343
|
+
"com.microsoft.edgemac": "edge",
|
|
344
|
+
"microsoft-edge.desktop": "edge"
|
|
345
|
+
};
|
|
346
|
+
const flags = {
|
|
347
|
+
chrome: "--incognito",
|
|
348
|
+
brave: "--incognito",
|
|
349
|
+
firefox: "--private-window",
|
|
350
|
+
edge: "--inPrivate"
|
|
351
|
+
};
|
|
352
|
+
const browser = is_wsl_default ? await getWindowsDefaultBrowserFromWsl() : await defaultBrowser2();
|
|
353
|
+
if (browser.id in ids) {
|
|
354
|
+
const browserName = ids[browser.id];
|
|
355
|
+
if (app === "browserPrivate") {
|
|
356
|
+
appArguments.push(flags[browserName]);
|
|
357
|
+
}
|
|
358
|
+
return baseOpen({
|
|
359
|
+
...options,
|
|
360
|
+
app: {
|
|
361
|
+
name: apps[browserName],
|
|
362
|
+
arguments: appArguments
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
throw new Error(`${browser.name} is not supported as a default browser`);
|
|
367
|
+
}
|
|
368
|
+
let command;
|
|
369
|
+
const cliArguments = [];
|
|
370
|
+
const childProcessOptions = {};
|
|
371
|
+
if (platform === "darwin") {
|
|
372
|
+
command = "open";
|
|
373
|
+
if (options.wait) {
|
|
374
|
+
cliArguments.push("--wait-apps");
|
|
375
|
+
}
|
|
376
|
+
if (options.background) {
|
|
377
|
+
cliArguments.push("--background");
|
|
378
|
+
}
|
|
379
|
+
if (options.newInstance) {
|
|
380
|
+
cliArguments.push("--new");
|
|
381
|
+
}
|
|
382
|
+
if (app) {
|
|
383
|
+
cliArguments.push("-a", app);
|
|
384
|
+
}
|
|
385
|
+
} else if (platform === "win32" || is_wsl_default && !isInsideContainer() && !app) {
|
|
386
|
+
command = await powerShellPath();
|
|
387
|
+
cliArguments.push(
|
|
388
|
+
"-NoProfile",
|
|
389
|
+
"-NonInteractive",
|
|
390
|
+
"-ExecutionPolicy",
|
|
391
|
+
"Bypass",
|
|
392
|
+
"-EncodedCommand"
|
|
393
|
+
);
|
|
394
|
+
if (!is_wsl_default) {
|
|
395
|
+
childProcessOptions.windowsVerbatimArguments = true;
|
|
396
|
+
}
|
|
397
|
+
const encodedArguments = ["Start"];
|
|
398
|
+
if (options.wait) {
|
|
399
|
+
encodedArguments.push("-Wait");
|
|
400
|
+
}
|
|
401
|
+
if (app) {
|
|
402
|
+
encodedArguments.push(`"\`"${app}\`""`);
|
|
403
|
+
if (options.target) {
|
|
404
|
+
appArguments.push(options.target);
|
|
405
|
+
}
|
|
406
|
+
} else if (options.target) {
|
|
407
|
+
encodedArguments.push(`"${options.target}"`);
|
|
408
|
+
}
|
|
409
|
+
if (appArguments.length > 0) {
|
|
410
|
+
appArguments = appArguments.map((argument) => `"\`"${argument}\`""`);
|
|
411
|
+
encodedArguments.push("-ArgumentList", appArguments.join(","));
|
|
412
|
+
}
|
|
413
|
+
options.target = Buffer.from(encodedArguments.join(" "), "utf16le").toString("base64");
|
|
414
|
+
} else {
|
|
415
|
+
if (app) {
|
|
416
|
+
command = app;
|
|
417
|
+
} else {
|
|
418
|
+
const isBundled = !__dirname || __dirname === "/";
|
|
419
|
+
let exeLocalXdgOpen = false;
|
|
420
|
+
try {
|
|
421
|
+
await fs5.access(localXdgOpenPath, fsConstants2.X_OK);
|
|
422
|
+
exeLocalXdgOpen = true;
|
|
423
|
+
} catch {
|
|
424
|
+
}
|
|
425
|
+
const useSystemXdgOpen = process7.versions.electron ?? (platform === "android" || isBundled || !exeLocalXdgOpen);
|
|
426
|
+
command = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath;
|
|
427
|
+
}
|
|
428
|
+
if (appArguments.length > 0) {
|
|
429
|
+
cliArguments.push(...appArguments);
|
|
430
|
+
}
|
|
431
|
+
if (!options.wait) {
|
|
432
|
+
childProcessOptions.stdio = "ignore";
|
|
433
|
+
childProcessOptions.detached = true;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
if (platform === "darwin" && appArguments.length > 0) {
|
|
437
|
+
cliArguments.push("--args", ...appArguments);
|
|
438
|
+
}
|
|
439
|
+
if (options.target) {
|
|
440
|
+
cliArguments.push(options.target);
|
|
441
|
+
}
|
|
442
|
+
const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
|
|
443
|
+
if (options.wait) {
|
|
444
|
+
return new Promise((resolve, reject) => {
|
|
445
|
+
subprocess.once("error", reject);
|
|
446
|
+
subprocess.once("close", (exitCode) => {
|
|
447
|
+
if (!options.allowNonzeroExitCode && exitCode > 0) {
|
|
448
|
+
reject(new Error(`Exited with code ${exitCode}`));
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
resolve(subprocess);
|
|
452
|
+
});
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
subprocess.unref();
|
|
456
|
+
return subprocess;
|
|
457
|
+
};
|
|
458
|
+
var open = (target, options) => {
|
|
459
|
+
if (typeof target !== "string") {
|
|
460
|
+
throw new TypeError("Expected a `target`");
|
|
461
|
+
}
|
|
462
|
+
return baseOpen({
|
|
463
|
+
...options,
|
|
464
|
+
target
|
|
465
|
+
});
|
|
466
|
+
};
|
|
467
|
+
function detectArchBinary(binary) {
|
|
468
|
+
if (typeof binary === "string" || Array.isArray(binary)) {
|
|
469
|
+
return binary;
|
|
470
|
+
}
|
|
471
|
+
const { [arch]: archBinary } = binary;
|
|
472
|
+
if (!archBinary) {
|
|
473
|
+
throw new Error(`${arch} is not supported`);
|
|
474
|
+
}
|
|
475
|
+
return archBinary;
|
|
476
|
+
}
|
|
477
|
+
function detectPlatformBinary({ [platform]: platformBinary }, { wsl }) {
|
|
478
|
+
if (wsl && is_wsl_default) {
|
|
479
|
+
return detectArchBinary(wsl);
|
|
480
|
+
}
|
|
481
|
+
if (!platformBinary) {
|
|
482
|
+
throw new Error(`${platform} is not supported`);
|
|
483
|
+
}
|
|
484
|
+
return detectArchBinary(platformBinary);
|
|
485
|
+
}
|
|
486
|
+
var apps = {};
|
|
487
|
+
defineLazyProperty(apps, "chrome", () => detectPlatformBinary({
|
|
488
|
+
darwin: "google chrome",
|
|
489
|
+
win32: "chrome",
|
|
490
|
+
linux: ["google-chrome", "google-chrome-stable", "chromium"]
|
|
491
|
+
}, {
|
|
492
|
+
wsl: {
|
|
493
|
+
ia32: "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",
|
|
494
|
+
x64: ["/mnt/c/Program Files/Google/Chrome/Application/chrome.exe", "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"]
|
|
495
|
+
}
|
|
496
|
+
}));
|
|
497
|
+
defineLazyProperty(apps, "brave", () => detectPlatformBinary({
|
|
498
|
+
darwin: "brave browser",
|
|
499
|
+
win32: "brave",
|
|
500
|
+
linux: ["brave-browser", "brave"]
|
|
501
|
+
}, {
|
|
502
|
+
wsl: {
|
|
503
|
+
ia32: "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe",
|
|
504
|
+
x64: ["/mnt/c/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe", "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe"]
|
|
505
|
+
}
|
|
506
|
+
}));
|
|
507
|
+
defineLazyProperty(apps, "firefox", () => detectPlatformBinary({
|
|
508
|
+
darwin: "firefox",
|
|
509
|
+
win32: String.raw`C:\Program Files\Mozilla Firefox\firefox.exe`,
|
|
510
|
+
linux: "firefox"
|
|
511
|
+
}, {
|
|
512
|
+
wsl: "/mnt/c/Program Files/Mozilla Firefox/firefox.exe"
|
|
513
|
+
}));
|
|
514
|
+
defineLazyProperty(apps, "edge", () => detectPlatformBinary({
|
|
515
|
+
darwin: "microsoft edge",
|
|
516
|
+
win32: "msedge",
|
|
517
|
+
linux: ["microsoft-edge", "microsoft-edge-dev"]
|
|
518
|
+
}, {
|
|
519
|
+
wsl: "/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"
|
|
520
|
+
}));
|
|
521
|
+
defineLazyProperty(apps, "browser", () => "browser");
|
|
522
|
+
defineLazyProperty(apps, "browserPrivate", () => "browserPrivate");
|
|
523
|
+
var open_default = open;
|
|
524
|
+
|
|
525
|
+
// src/cli.ts
|
|
526
|
+
var __dirname2 = path2.dirname(fileURLToPath2(import.meta.url));
|
|
8
527
|
async function main() {
|
|
9
528
|
const argv = process.argv.slice(2);
|
|
10
529
|
const command = argv[0] ?? "help";
|
|
@@ -12,6 +531,10 @@ async function main() {
|
|
|
12
531
|
printHelp();
|
|
13
532
|
return;
|
|
14
533
|
}
|
|
534
|
+
if (command === "ui") {
|
|
535
|
+
await runUI();
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
15
538
|
if (command !== "generate") {
|
|
16
539
|
console.error(`Unknown command: ${command}`);
|
|
17
540
|
printHelp();
|
|
@@ -74,17 +597,65 @@ async function main() {
|
|
|
74
597
|
temperature,
|
|
75
598
|
maxAttempts
|
|
76
599
|
});
|
|
77
|
-
const resolvedOut =
|
|
78
|
-
await
|
|
79
|
-
await
|
|
600
|
+
const resolvedOut = path2.resolve(process.cwd(), outFile);
|
|
601
|
+
await fs6.mkdir(path2.dirname(resolvedOut), { recursive: true });
|
|
602
|
+
await fs6.writeFile(resolvedOut, result.code, "utf8");
|
|
80
603
|
console.log(`OK: wrote ${resolvedOut}`);
|
|
81
604
|
}
|
|
605
|
+
async function runUI() {
|
|
606
|
+
let uiDir = path2.join(__dirname2, "ui");
|
|
607
|
+
try {
|
|
608
|
+
await fs6.access(uiDir);
|
|
609
|
+
} catch {
|
|
610
|
+
uiDir = path2.join(__dirname2, "..", "dist", "ui");
|
|
611
|
+
}
|
|
612
|
+
const PORT = 3e3;
|
|
613
|
+
console.log(`Starting MoodUI UI...`);
|
|
614
|
+
const server = http.createServer(async (req, res) => {
|
|
615
|
+
let filePath = path2.join(uiDir, req.url === "/" ? "index.html" : req.url);
|
|
616
|
+
const extname = String(path2.extname(filePath)).toLowerCase();
|
|
617
|
+
const mimeTypes = {
|
|
618
|
+
".html": "text/html",
|
|
619
|
+
".js": "text/javascript",
|
|
620
|
+
".css": "text/css",
|
|
621
|
+
".json": "application/json",
|
|
622
|
+
".png": "image/png",
|
|
623
|
+
".jpg": "image/jpg",
|
|
624
|
+
".gif": "image/gif",
|
|
625
|
+
".svg": "image/svg+xml",
|
|
626
|
+
".ico": "image/x-icon"
|
|
627
|
+
};
|
|
628
|
+
const contentType = mimeTypes[extname] || "application/octet-stream";
|
|
629
|
+
try {
|
|
630
|
+
const content = await fs6.readFile(filePath);
|
|
631
|
+
res.writeHead(200, { "Content-Type": contentType });
|
|
632
|
+
res.end(content, "utf-8");
|
|
633
|
+
} catch (err) {
|
|
634
|
+
res.writeHead(404);
|
|
635
|
+
res.end("Not Found", "utf-8");
|
|
636
|
+
}
|
|
637
|
+
});
|
|
638
|
+
server.listen(PORT, () => {
|
|
639
|
+
const url = `http://localhost:${PORT}`;
|
|
640
|
+
console.log(`MoodUI UI running at ${url}`);
|
|
641
|
+
open_default(url);
|
|
642
|
+
});
|
|
643
|
+
process.on("SIGINT", () => {
|
|
644
|
+
server.close();
|
|
645
|
+
process.exit(0);
|
|
646
|
+
});
|
|
647
|
+
}
|
|
82
648
|
function printHelp() {
|
|
83
649
|
console.log(
|
|
84
650
|
[
|
|
85
|
-
"moodui
|
|
651
|
+
"moodui <command>",
|
|
652
|
+
"",
|
|
653
|
+
"Commands:",
|
|
654
|
+
" generate [options] <prompt...> Generate component via CLI",
|
|
655
|
+
" ui Launch Web UI for generating components",
|
|
656
|
+
" help, --help, -h Show this help message",
|
|
86
657
|
"",
|
|
87
|
-
"Options:",
|
|
658
|
+
"Generate Options:",
|
|
88
659
|
" --provider gemini|ollama|openai-compatible default: gemini",
|
|
89
660
|
" --model <name> required (default for gemini: gemini-3-flash-preview)",
|
|
90
661
|
" --out <path> path lengkap ke file output (termasuk direktori), default: src/generated/MoodScreen.tsx",
|
|
@@ -100,6 +671,9 @@ function printHelp() {
|
|
|
100
671
|
" OPENAI_COMPATIBLE_API_KEY",
|
|
101
672
|
"",
|
|
102
673
|
"Examples:",
|
|
674
|
+
" # Launch Web UI",
|
|
675
|
+
" npx @kohryan/moodui ui",
|
|
676
|
+
"",
|
|
103
677
|
" # Generate ke src/generated/MoodScreen.tsx (default)",
|
|
104
678
|
' GEMINI_API_KEY=... npx @kohryan/moodui generate --model gemini-3-flash-preview "Buat UI login sederhana"',
|
|
105
679
|
"",
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{createRoot as e}from"react-dom/client";var t=Object.create,n=Object.defineProperty,r=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,a=Object.getPrototypeOf,o=Object.prototype.hasOwnProperty,s=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),c=(e,t,a,s)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var c=i(t),l=0,u=c.length,d;l<u;l++)d=c[l],!o.call(e,d)&&d!==a&&n(e,d,{get:(e=>t[e]).bind(null,d),enumerable:!(s=r(t,d))||s.enumerable});return e},l=(e,r,i)=>(i=e==null?{}:t(a(e)),c(r||!e||!e.__esModule?n(i,`default`,{value:e,enumerable:!0}):i,e));(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var u=s((e=>{var t=Symbol.for(`react.fragment`),n={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},r=Object.assign,i={};function a(e,t,r){this.props=e,this.context=t,this.refs=i,this.updater=r||n}a.prototype.isReactComponent={},a.prototype.setState=function(e,t){if(typeof e!=`object`&&typeof e!=`function`&&e!=null)throw Error(`takes an object of state variables to update or a function which returns an object of state variables.`);this.updater.enqueueSetState(this,e,t,`setState`)},a.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,`forceUpdate`)};function o(){}o.prototype=a.prototype;function s(e,t,r){this.props=e,this.context=t,this.refs=i,this.updater=r||n}var c=s.prototype=new o;c.constructor=s,r(c,a.prototype),c.isPureReactComponent=!0,Array.isArray;var l={H:null,A:null,T:null,S:null};e.Fragment=t,e.useCallback=function(e,t){return l.H.useCallback(e,t)},e.useState=function(e){return l.H.useState(e)}})),d=s(((e,t)=>{t.exports=u()}));function f(e){let t=[];if(!h(e))return{ok:!1,errors:[`spec must be an object`]};e.version!==1&&t.push(`spec.version must be 1`);let n=e.root,r=m(n,`spec.root`);return r.ok||t.push(...r.errors),t.length>0?{ok:!1,errors:t}:{ok:!0,value:e}}function p(e){let t=f(e);if(!t.ok){let e=[`Invalid MoodUI spec:`,...t.errors.map(e=>`- ${e}`)].join(`
|
|
2
|
+
`);throw Error(e)}return t.value}function m(e,t){let n=[];if(!h(e))return{ok:!1,errors:[`${t} must be an object`]};let r=e.type;if(!g(r))return{ok:!1,errors:[`${t}.type must be a string`]};switch(r){case`box`:{let r=e.children;if(r!=null)if(!Array.isArray(r))n.push(`${t}.children must be an array`);else for(let e=0;e<r.length;e+=1){let i=r[e],a=m(i,`${t}.children[${e}]`);a.ok||n.push(...a.errors)}break}case`text`:{let r=e.props;h(r)?g(r.value)||n.push(`${t}.props.value must be a string`):n.push(`${t}.props must be an object`);break}case`button`:{let r=e.props;h(r)?g(r.label)||n.push(`${t}.props.label must be a string`):n.push(`${t}.props must be an object`);break}case`input`:{let r=e.props;r!=null&&!h(r)&&n.push(`${t}.props must be an object if provided`);break}case`image`:{let r=e.props;h(r)?g(r.src)||n.push(`${t}.props.src must be a string`):n.push(`${t}.props must be an object`);break}case`spacer`:{let r=e.props;r!=null&&!h(r)&&n.push(`${t}.props must be an object if provided`);break}default:n.push(`${t}.type must be one of: box | text | button | input | image | spacer`)}return n.length>0?{ok:!1,errors:n}:{ok:!0,value:e}}function h(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function g(e){return typeof e==`string`}function _(e,t={}){let n=p(e),r=t.componentName??`MoodUIScreen`,i=v(n.root,{indent:2,onActionProp:`onAction`});return[`import * as React from "react";`,``,`export type MoodUIScreenActionHandler = (actionId: string) => void;`,``,`export type MoodUIScreenProps = {`,` onAction?: MoodUIScreenActionHandler;`,`};`,``,`export function ${r}(props: MoodUIScreenProps) {`,` const { onAction } = props;`,` return (`,i,` );`,`}`,``].join(`
|
|
3
|
+
`)}function v(e,t){switch(e.type){case`box`:return y(`div`,e,t,()=>{let n=e.children??[];return n.length===0?[]:n.map(e=>v(e,{...t,indent:t.indent+2}))});case`text`:{let n=e.props?.as??`p`,r=A(e.props?.value??``);return y(n,e,t,()=>[j(t.indent+2)+r])}case`button`:{let n=A(e.props?.label??``),r=e.props?.actionId;return y(`button`,e,t,()=>[j(t.indent+2)+n],r?{onClick:`() => ${t.onActionProp}?.(${O(r)})`}:void 0)}case`input`:return b(`input`,e,t);case`image`:return b(`img`,e,t);case`spacer`:{let n=e.props?.size??8;return y(`div`,{type:`box`,props:{style:{width:T(n),height:T(n)}},children:[]},t,()=>[])}}}function y(e,t,n,r,i){let a=r(),o=x(e,t,i),s=`<${e}${o.length?` `+o.join(` `):``}>`,c=`</${e}>`;return a.length===0?j(n.indent)+s+c:[j(n.indent)+s,...a,j(n.indent)+c].join(`
|
|
4
|
+
`)}function b(e,t,n){let r=x(e,t);return j(n.indent)+`<${e}${r.length?` `+r.join(` `):``} />`}function x(e,t,n){let r=t.props??{},i=[];r.id&&i.push(`id=${D(r.id)}`),r.testId&&i.push(`data-testid=${D(r.testId)}`),r.className&&i.push(`className=${D(r.className)}`);let a=w(S(e,t),r.style)??{};if(e===`input`&&(r.name&&i.push(`name=${D(r.name)}`),r.placeholder&&i.push(`placeholder=${D(r.placeholder)}`),r.defaultValue&&i.push(`defaultValue=${D(r.defaultValue)}`)),e===`img`&&(r.src&&i.push(`src=${D(r.src)}`),r.alt&&i.push(`alt=${D(r.alt)}`),r.fit&&(a.objectFit=r.fit)),Object.keys(a).length>0&&i.push(`style={(${O(a)} as React.CSSProperties)}`),n)for(let[e,t]of Object.entries(n))i.push(`${e}={${t}}`);return i}function S(e,t){let n=t.props??{},r={};if(n.width!=null&&(r.width=T(n.width)),n.height!=null&&(r.height=T(n.height)),n.background!=null&&(r.background=n.background),n.borderRadius!=null&&(r.borderRadius=T(n.borderRadius)),C(r,`margin`,n.margin),C(r,`padding`,n.padding),t.type===`box`&&(r.display=`flex`,r.flexDirection=E(n.direction)??`column`,n.gap!=null&&(r.gap=T(n.gap)),n.align!=null&&(r.alignItems=n.align),n.justify!=null&&(r.justifyContent=n.justify),n.wrap!=null&&(r.flexWrap=n.wrap)),t.type===`text`&&(n.color!=null&&(r.color=n.color),n.fontSize!=null&&(r.fontSize=T(n.fontSize)),n.fontWeight!=null&&(r.fontWeight=n.fontWeight),n.textAlign!=null&&(r.textAlign=n.textAlign),e.startsWith(`h`)&&(r.margin=0)),t.type===`button`){r.cursor=`pointer`,r.border=`none`,r.padding=`10px 14px`,r.borderRadius=10;let e=n.variant??`primary`;e===`primary`?(r.background=`#111827`,r.color=`#ffffff`):e===`secondary`?(r.background=`#e5e7eb`,r.color=`#111827`):(r.background=`transparent`,r.color=`#111827`),n.disabled&&(r.opacity=.6,r.cursor=`not-allowed`)}return t.type===`input`&&(r.padding=`10px 12px`,r.borderRadius=10,r.border=`1px solid #d1d5db`,r.outline=`none`),t.type===`image`&&(n.fit!=null&&(r.objectFit=n.fit),r.maxWidth=`100%`),r}function C(e,t,n){if(n==null)return;if(typeof n==`number`||typeof n==`string`){e[t]=T(n);return}if(typeof n!=`object`||Array.isArray(n))return;let r=n,i=r.all,a=r.x,o=r.y;i!=null&&(e[t]=T(i)),a!=null&&(e[`${t}Left`]=T(a),e[`${t}Right`]=T(a)),o!=null&&(e[`${t}Top`]=T(o),e[`${t}Bottom`]=T(o)),r.top!=null&&(e[`${t}Top`]=T(r.top)),r.right!=null&&(e[`${t}Right`]=T(r.right)),r.bottom!=null&&(e[`${t}Bottom`]=T(r.bottom)),r.left!=null&&(e[`${t}Left`]=T(r.left))}function w(e,t){if(!(!e&&!t))return e?t?{...e,...t}:e:t}function T(e){return e}function E(e){if(e===`row`||e===`column`)return e;if(e===`horizontal`)return`row`;if(e===`vertical`)return`column`}function D(e){return`{${O(e)}}`}function O(e){return e===null?`null`:e===void 0?`undefined`:typeof e==`string`?JSON.stringify(e):typeof e==`number`||typeof e==`boolean`?String(e):Array.isArray(e)?`[${e.map(O).join(`, `)}]`:typeof e==`object`?`{ ${Object.entries(e).filter(([,e])=>e!==void 0).map(([e,t])=>`${k(e)}: ${O(t)}`).join(`, `)} }`:`undefined`}function k(e){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)?e:JSON.stringify(e)}function A(e){return e.replace(/&/g,`&`).replace(/</g,`<`).replace(/>/g,`>`)}function j(e){return` `.repeat(e)}var M=s((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),N=s(((e,t)=>{t.exports=M()})),P=l(d()),F=N();function I(e){return(0,F.jsx)(F.Fragment,{children:L(e.spec.root,e.onAction)})}function L(e,t){switch(e.type){case`box`:{let n=z(e),r=e.children?.map((e,n)=>(0,F.jsx)(P.Fragment,{children:L(e,t)},n));return(0,F.jsx)(`div`,{...R(e),style:n,children:r})}case`text`:{let t=e.props?.as??`p`,n=z(e);return(0,F.jsx)(t,{...R(e),style:n,children:e.props?.value??``})}case`button`:{let n=z(e),r=e.props?.actionId;return(0,F.jsx)(`button`,{...R(e),style:n,disabled:e.props?.disabled??!1,onClick:r?()=>t?.(r):void 0,children:e.props?.label??``})}case`input`:{let t=z(e);return(0,F.jsx)(`input`,{...R(e),style:t,name:e.props?.name,placeholder:e.props?.placeholder,defaultValue:e.props?.defaultValue})}case`image`:{let t=z(e);return(0,F.jsx)(`img`,{...R(e),style:t,src:e.props?.src,alt:e.props?.alt??``})}case`spacer`:{let t=e.props?.size??8;return(0,F.jsx)(`div`,{style:{width:t,height:t}})}}}function R(e){let t=e.props??{};return{id:typeof t.id==`string`?t.id:void 0,className:typeof t.className==`string`?t.className:void 0,"data-testid":typeof t.testId==`string`?t.testId:void 0}}function z(e){let t=e.props??{},n={},r=V(t.width),i=V(t.height),a=V(t.borderRadius);if(r!=null&&(n.width=r),i!=null&&(n.height=i),typeof t.background==`string`&&(n.background=t.background),a!=null&&(n.borderRadius=a),B(n,`margin`,t.margin),B(n,`padding`,t.padding),e.type===`box`){n.display=`flex`,t.direction===`row`||t.direction===`column`?n.flexDirection=t.direction:n.flexDirection=`column`;let e=V(t.gap);e!=null&&(n.gap=e),typeof t.align==`string`&&(n.alignItems=t.align),typeof t.justify==`string`&&(n.justifyContent=t.justify),(t.wrap===`nowrap`||t.wrap===`wrap`)&&(n.flexWrap=t.wrap)}if(e.type===`text`){typeof t.color==`string`&&(n.color=t.color);let r=V(t.fontSize);r!=null&&(n.fontSize=r),(typeof t.fontWeight==`string`||typeof t.fontWeight==`number`)&&(n.fontWeight=t.fontWeight),typeof t.textAlign==`string`&&(n.textAlign=t.textAlign);let i=e.props?.as;typeof i==`string`&&i.startsWith(`h`)&&(n.margin=0)}if(e.type===`button`){n.cursor=e.props?.disabled?`not-allowed`:`pointer`,n.border=`none`,n.padding??=`10px 14px`,n.borderRadius??=10;let t=e.props?.variant??`primary`;t===`primary`?(n.background??=`#111827`,n.color??=`#ffffff`):t===`secondary`?(n.background??=`#e5e7eb`,n.color??=`#111827`):(n.background??=`transparent`,n.color??=`#111827`),e.props?.disabled&&(n.opacity=.6)}if(e.type===`input`&&(n.padding??=`10px 12px`,n.borderRadius??=10,n.border??=`1px solid #d1d5db`,n.outline??=`none`),e.type===`image`){n.maxWidth??=`100%`;let t=e.props?.fit;t!=null&&(n.objectFit=t)}return t.style&&typeof t.style==`object`&&!Array.isArray(t.style)&&Object.assign(n,t.style),n}function B(e,t,n){if(n==null)return;let r=e;if(typeof n==`number`||typeof n==`string`){r[t]=V(n);return}if(typeof n!=`object`||Array.isArray(n))return;let i=n,a=i.all,o=i.x,s=i.y;a!=null&&(r[t]=V(a)),o!=null&&(r[`${t}Left`]=V(o),r[`${t}Right`]=V(o)),s!=null&&(r[`${t}Top`]=V(s),r[`${t}Bottom`]=V(s)),i.top!=null&&(r[`${t}Top`]=V(i.top)),i.right!=null&&(r[`${t}Right`]=V(i.right)),i.bottom!=null&&(r[`${t}Bottom`]=V(i.bottom)),i.left!=null&&(r[`${t}Left`]=V(i.left))}function V(e){if(typeof e==`number`||typeof e==`string`)return e}async function H(e,t){let n=t.maxAttempts??2;if(n<1)throw Error(`maxAttempts must be >= 1`);let r=U(),i=W(t.prompt),a=``,o;for(let s=1;s<=n;s+=1){let n=[{role:`system`,content:r},{role:`user`,content:i}];s>1&&n.push({role:`user`,content:`Perbaiki output kamu supaya valid JSON dan valid MoodUISpec. Output hanya JSON.`});let c=await e.chat({model:t.model,temperature:t.temperature,messages:n});a=c;try{return{spec:p(G(c)),raw:c}}catch(e){o=e}}let s=o instanceof Error?o.message:String(o);throw Error(`Failed to generate valid MoodUISpec. Last error: ${s}\n\nRaw:\n${a}`)}function U(){return[`Kamu adalah generator JSON untuk MoodUI.`,`TUGAS: keluarkan 1 objek JSON yang valid, sesuai schema MoodUISpec versi 1.`,`JANGAN keluarkan markdown, JANGAN ada penjelasan, JANGAN pakai backticks.`,``,`MoodUISpec shape:`,`{`,` "version": 1,`,` "root": MoodUINode`,`}`,``,`MoodUINode union:`,`- box: { type:'box', props?: { direction?, gap?, align?, justify?, wrap?, ...common }, children?: MoodUINode[] }`,`- text: { type:'text', props: { value: string, as?, color?, fontSize?, fontWeight?, textAlign?, ...common } }`,`- button: { type:'button', props: { label: string, variant?, actionId?, disabled?, ...common } }`,`- input: { type:'input', props?: { name?, placeholder?, defaultValue?, ...common } }`,`- image: { type:'image', props: { src: string, alt?, fit?, ...common } }`,`- spacer: { type:'spacer', props?: { size? } }`,``,`common props:`,`- id, testId, className, style(object), padding, margin, background, borderRadius, width, height`,``,`Rules:`,`- root wajib ada`,`- minimal pakai box sebagai container utama`,`- semua string pakai double quotes (JSON standard)`,`- jangan pakai function / JS expression apa pun`].join(`
|
|
5
|
+
`)}function W(e){return[`Buat UI dari request ini:`,e].join(`
|
|
6
|
+
`)}function G(e){let t=e.indexOf(`{`);if(t<0)throw Error(`No JSON object found`);let n=0,r=!1,i=!1;for(let a=t;a<e.length;a+=1){let o=e[a];if(r){i?i=!1:o===`\\`?i=!0:o===`"`&&(r=!1);continue}if(o===`"`){r=!0;continue}if(o===`{`?n+=1:o===`}`&&--n,n===0){let n=e.slice(t,a+1);return JSON.parse(n)}}throw Error(`Unterminated JSON object`)}function K(e){let t=(e.baseUrl??`https://generativelanguage.googleapis.com`).replace(/\/+$/,``),n=e.fetchFn??fetch,r=e.apiKey;return{async chat(e){let{systemInstruction:i,contents:a}=q(e.messages),o=await n(`${t}/v1beta/models/${encodeURIComponent(e.model)}:generateContent?key=${encodeURIComponent(r)}`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({...i?{systemInstruction:i}:{},contents:a,generationConfig:e.temperature==null?void 0:{temperature:e.temperature}})});if(!o.ok){let e=await J(o);throw Error(`Gemini generateContent failed (${o.status}): ${e}`)}let s=(await o.json())?.candidates?.[0]?.content?.parts,c=Array.isArray(s)?s.map(e=>typeof e?.text==`string`?e.text:``).join(``):void 0;if(typeof c!=`string`||c.length===0)throw Error(`Gemini response missing candidates[0].content.parts[].text`);return c}}}function q(e){let t=e.filter(e=>e.role===`system`).map(e=>e.content).filter(e=>e.trim().length>0),n=t.length>0?{role:`system`,parts:[{text:t.join(`
|
|
7
|
+
`)}]}:void 0,r=e.filter(e=>e.role!==`system`).map(e=>({role:e.role===`assistant`?`model`:`user`,parts:[{text:e.content}]}));return r.length===0&&r.push({role:`user`,parts:[{text:``}]}),{systemInstruction:n,contents:r}}async function J(e){try{return await e.text()}catch{return``}}function Y(e={}){let t=e.baseUrl??`http://localhost:11434`,n=e.fetchFn??fetch;return{async chat(e){let r=await n(`${t}/api/chat`,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({model:e.model,messages:e.messages,stream:!1,options:e.temperature==null?void 0:{temperature:e.temperature}})});if(!r.ok){let e=await X(r);throw Error(`Ollama chat failed (${r.status}): ${e}`)}let i=(await r.json())?.message?.content;if(typeof i!=`string`)throw Error(`Ollama response missing message.content`);return i}}}async function X(e){try{return await e.text()}catch{return``}}function Z(e){let t=e.fetchFn??fetch,n=e.baseUrl.replace(/\/+$/,``),r=e.apiKey,i=e.defaultHeaders??{};return{async chat(e){let a=await t(`${n}/v1/chat/completions`,{method:`POST`,headers:{"content-type":`application/json`,authorization:`Bearer ${r}`,...i},body:JSON.stringify({model:e.model,messages:e.messages,temperature:e.temperature})});if(!a.ok){let e=await Q(a);throw Error(`Chat completion failed (${a.status}): ${e}`)}let o=(await a.json())?.choices?.[0]?.message?.content;if(typeof o!=`string`)throw Error(`Response missing choices[0].message.content`);return o}}}async function Q(e){try{return await e.text()}catch{return``}}async function $(e){let{spec:t,raw:n}=await H(e.provider===`gemini`?K({apiKey:e.apiKey,baseUrl:e.baseUrl}):e.provider===`ollama`?Y({baseUrl:e.baseUrl}):Z({apiKey:e.apiKey,baseUrl:e.baseUrl}),{model:e.model,prompt:e.prompt,temperature:e.temperature,maxAttempts:e.maxAttempts});return{spec:t,raw:n,code:_(t,{componentName:e.componentName})}}function ee(e){let t=e.provider??`gemini`,[n,r]=P.useState(e.model??`gemini-3-flash-preview`),[i,a]=P.useState(e.apiKey??``),[o,s]=P.useState(e.baseUrl??``),[c,l]=P.useState(e.defaultPrompt??`Buat UI mood tracker: judul, input mood, tombol Simpan (actionId save_mood), dan section riwayat.`),[u,d]=P.useState(!1),[f,p]=P.useState(null),[m,h]=P.useState(null),[g,_]=P.useState(``),[v,y]=P.useState(!1),b=P.useCallback(async()=>{d(!0),p(null),y(!1);try{let r=t===`ollama`?await $({provider:`ollama`,model:n,baseUrl:o||void 0,prompt:c,componentName:e.componentName}):t===`openai-compatible`?await $({provider:`openai-compatible`,model:n,baseUrl:o||``,apiKey:i,prompt:c,componentName:e.componentName}):await $({provider:`gemini`,model:n,apiKey:i,baseUrl:o||void 0,prompt:c,componentName:e.componentName});h(r.spec),_(r.code)}catch(e){p(e instanceof Error?e.message:String(e))}finally{d(!1)}},[i,o,n,c,e.componentName,t]),x=e.componentName??`MoodScreen`,S=P.useCallback(async()=>{if(g)try{await navigator.clipboard.writeText(g),y(!0),setTimeout(()=>y(!1),2e3)}catch(e){console.error(`Failed to copy:`,e)}},[g]),C=P.useCallback(()=>{if(!g)return;let e=new Blob([g],{type:`text/plain`}),t=URL.createObjectURL(e),n=document.createElement(`a`);n.href=t,n.download=`${x}.tsx`,document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(t)},[g,x]),w=P.useCallback(async()=>{if(g)try{let e=await(await window.showSaveFilePicker({suggestedName:`${x}.tsx`,types:[{description:`TypeScript Files`,accept:{"text/plain":[`.tsx`]}}]})).createWritable();await e.write(g),await e.close()}catch(e){e.name?.includes(`AbortError`)||console.error(`Failed to save file:`,e)}},[g,x]);return(0,F.jsxs)(`div`,{style:{display:`grid`,gridTemplateColumns:`1fr 1fr`,gap:16},children:[(0,F.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:12},children:[(0,F.jsx)(`div`,{style:{fontWeight:700,fontSize:16},children:`MoodUI Prompt`}),(0,F.jsxs)(`div`,{style:{display:`flex`,gap:8,flexWrap:`wrap`},children:[(0,F.jsx)(`input`,{value:t,readOnly:!0,style:{padding:`10px 12px`,borderRadius:10,border:`1px solid #d1d5db`,background:`#f3f4f6`,width:200}}),(0,F.jsx)(`input`,{value:n,onChange:e=>r(e.target.value),placeholder:`model`,style:{padding:`10px 12px`,borderRadius:10,border:`1px solid #d1d5db`,flex:`1 1 220px`}})]}),t===`ollama`?null:(0,F.jsx)(`input`,{value:i,onChange:e=>a(e.target.value),placeholder:`API key`,type:`password`,style:{padding:`10px 12px`,borderRadius:10,border:`1px solid #d1d5db`}}),(0,F.jsx)(`input`,{value:o,onChange:e=>s(e.target.value),placeholder:t===`ollama`?`baseUrl (optional) e.g. http://localhost:11434`:`baseUrl (optional)`,style:{padding:`10px 12px`,borderRadius:10,border:`1px solid #d1d5db`}}),(0,F.jsx)(`textarea`,{value:c,onChange:e=>l(e.target.value),rows:10,style:{padding:12,borderRadius:12,border:`1px solid #d1d5db`,fontFamily:`ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace`,fontSize:12}}),(0,F.jsx)(`button`,{type:`button`,onClick:b,disabled:u,style:{padding:`10px 12px`,borderRadius:10,border:`1px solid #111827`,background:`#111827`,color:`#ffffff`,cursor:u?`not-allowed`:`pointer`},children:u?`Generating...`:`Generate`}),f?(0,F.jsx)(`pre`,{style:{margin:0,padding:12,borderRadius:12,border:`1px solid #7f1d1d`,background:`#fef2f2`,color:`#7f1d1d`,whiteSpace:`pre-wrap`},children:f}):null]}),(0,F.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:12},children:[(0,F.jsx)(`div`,{style:{fontWeight:700,fontSize:16},children:`Preview`}),(0,F.jsx)(`div`,{style:{minHeight:240,padding:16,borderRadius:16,background:`#ffffff`,border:`1px solid #e5e7eb`},children:m?(0,F.jsx)(I,{spec:m}):(0,F.jsx)(`div`,{style:{color:`#6b7280`},children:`Belum ada hasil`})}),(0,F.jsxs)(`div`,{style:{display:`flex`,justifyContent:`space-between`,alignItems:`center`},children:[(0,F.jsx)(`div`,{style:{fontWeight:700,fontSize:16},children:`React Code`}),(0,F.jsxs)(`div`,{style:{display:`flex`,gap:8},children:[(0,F.jsx)(`button`,{type:`button`,onClick:S,disabled:!g,style:{padding:`6px 12px`,borderRadius:8,border:v?`1px solid #16a34a`:`1px solid #6b7280`,background:v?`#dcfce7`:`#ffffff`,color:v?`#16a34a`:`#374151`,cursor:g?`pointer`:`not-allowed`,fontSize:12},children:v?`Copied!`:`Copy`}),(0,F.jsx)(`button`,{type:`button`,onClick:w,disabled:!g,style:{padding:`6px 12px`,borderRadius:8,border:`1px solid #059669`,background:`#059669`,color:`#ffffff`,cursor:g?`pointer`:`not-allowed`,fontSize:12},children:`Save to File`}),(0,F.jsx)(`button`,{type:`button`,onClick:C,disabled:!g,style:{padding:`6px 12px`,borderRadius:8,border:`1px solid #111827`,background:`#111827`,color:`#ffffff`,cursor:g?`pointer`:`not-allowed`,fontSize:12},children:`Download`})]})]}),(0,F.jsx)(`textarea`,{value:g,readOnly:!0,rows:12,style:{padding:12,borderRadius:12,border:`1px solid #d1d5db`,fontFamily:`ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace`,fontSize:12}})]})]})}e(document.getElementById(`root`)).render((0,F.jsx)(`div`,{style:{minHeight:`100vh`,padding:24,background:`#0b1220`},children:(0,F.jsx)(`div`,{style:{maxWidth:1100,margin:`0 auto`,background:`#fff`,padding:16,borderRadius:16},children:(0,F.jsx)(ee,{provider:`gemini`,model:`gemini-3-flash-preview`})})}));
|