@sentientui/cli 0.2.3 → 0.2.5
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/LICENSE +21 -0
- package/dist/index.cjs +103 -41
- package/dist/index.js +88 -41
- package/package.json +4 -2
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Carlos Sánchez Campos / SentientUI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.cjs
CHANGED
|
@@ -4,27 +4,17 @@ var __create = Object.create;
|
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
5
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
8
7
|
var __getProtoOf = Object.getPrototypeOf;
|
|
9
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
|
-
var
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
for (var prop in b || (b = {}))
|
|
14
|
-
if (__hasOwnProp.call(b, prop))
|
|
15
|
-
__defNormalProp(a, prop, b[prop]);
|
|
16
|
-
if (__getOwnPropSymbols)
|
|
17
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
18
|
-
if (__propIsEnum.call(b, prop))
|
|
19
|
-
__defNormalProp(a, prop, b[prop]);
|
|
20
|
-
}
|
|
21
|
-
return a;
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
22
12
|
};
|
|
23
13
|
var __copyProps = (to, from, except, desc) => {
|
|
24
14
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
25
|
-
for (let
|
|
26
|
-
if (!__hasOwnProp.call(to,
|
|
27
|
-
__defProp(to,
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
28
18
|
}
|
|
29
19
|
return to;
|
|
30
20
|
};
|
|
@@ -36,6 +26,17 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
36
26
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
37
27
|
mod
|
|
38
28
|
));
|
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
+
|
|
31
|
+
// src/index.ts
|
|
32
|
+
var index_exports = {};
|
|
33
|
+
__export(index_exports, {
|
|
34
|
+
main: () => main,
|
|
35
|
+
parseArgs: () => parseArgs
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(index_exports);
|
|
38
|
+
var import_node_fs4 = require("fs");
|
|
39
|
+
var import_node_url = require("url");
|
|
39
40
|
|
|
40
41
|
// src/init.ts
|
|
41
42
|
var import_node_child_process = require("child_process");
|
|
@@ -46,14 +47,14 @@ var import_node_path = __toESM(require("path"), 1);
|
|
|
46
47
|
function readPackageJson(cwd) {
|
|
47
48
|
try {
|
|
48
49
|
return JSON.parse((0, import_node_fs.readFileSync)(import_node_path.default.join(cwd, "package.json"), "utf-8"));
|
|
49
|
-
} catch
|
|
50
|
+
} catch {
|
|
50
51
|
return null;
|
|
51
52
|
}
|
|
52
53
|
}
|
|
53
54
|
function detectFramework(cwd) {
|
|
54
55
|
const pkg = readPackageJson(cwd);
|
|
55
56
|
if (!pkg) return "unknown";
|
|
56
|
-
const deps =
|
|
57
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
57
58
|
const has = (dir) => (0, import_node_fs.existsSync)(import_node_path.default.join(cwd, dir));
|
|
58
59
|
if (deps["next"]) {
|
|
59
60
|
if (has("app") || has(import_node_path.default.join("src", "app"))) return "next-app";
|
|
@@ -88,15 +89,25 @@ function installCommand(pm, pkgName) {
|
|
|
88
89
|
var import_node_fs2 = require("fs");
|
|
89
90
|
var import_node_path2 = __toESM(require("path"), 1);
|
|
90
91
|
function envVarName(framework) {
|
|
91
|
-
|
|
92
|
+
switch (framework) {
|
|
93
|
+
case "cra":
|
|
94
|
+
return "REACT_APP_SENTIENT_API_KEY";
|
|
95
|
+
case "vite":
|
|
96
|
+
case "remix":
|
|
97
|
+
return "VITE_SENTIENT_API_KEY";
|
|
98
|
+
case "next-app":
|
|
99
|
+
case "next-pages":
|
|
100
|
+
case "unknown":
|
|
101
|
+
return "NEXT_PUBLIC_SENTIENT_API_KEY";
|
|
102
|
+
}
|
|
92
103
|
}
|
|
93
|
-
function writeEnvFile(cwd, framework,
|
|
104
|
+
function writeEnvFile(cwd, framework, key) {
|
|
94
105
|
const varName = envVarName(framework);
|
|
95
106
|
const file = import_node_path2.default.join(cwd, ".env.local");
|
|
96
107
|
const block = [
|
|
97
108
|
"",
|
|
98
109
|
"# SentientUI \u2014 leave empty for local mode (decisions are simulated on-device; nothing is sent)",
|
|
99
|
-
`${varName}=${
|
|
110
|
+
`${varName}=${key ?? ""}`,
|
|
100
111
|
""
|
|
101
112
|
].join("\n");
|
|
102
113
|
if (!(0, import_node_fs2.existsSync)(file)) {
|
|
@@ -104,7 +115,7 @@ function writeEnvFile(cwd, framework, key2) {
|
|
|
104
115
|
return "created";
|
|
105
116
|
}
|
|
106
117
|
const existing = (0, import_node_fs2.readFileSync)(file, "utf-8");
|
|
107
|
-
const assigned = existing.split(/\r?\n/).some((line) => line.trim().startsWith(`${varName}=`));
|
|
118
|
+
const assigned = existing.split(/\r?\n/).some((line) => line.trim().replace(/^#+\s*/, "").startsWith(`${varName}=`));
|
|
108
119
|
if (assigned) return "kept";
|
|
109
120
|
(0, import_node_fs2.appendFileSync)(file, block, "utf-8");
|
|
110
121
|
return "appended";
|
|
@@ -205,7 +216,7 @@ createRoot(document.getElementById('root')!).render(
|
|
|
205
216
|
import { AdaptiveProvider } from '@sentientui/react';
|
|
206
217
|
|
|
207
218
|
// inside the Layout/App component body:
|
|
208
|
-
<AdaptiveProvider apiKey=
|
|
219
|
+
<AdaptiveProvider apiKey={import.meta.env.${envVar} ?? ''} context="landing">
|
|
209
220
|
<Outlet />
|
|
210
221
|
</AdaptiveProvider>`;
|
|
211
222
|
case "cra":
|
|
@@ -236,11 +247,39 @@ function finale(framework) {
|
|
|
236
247
|
return `open http://localhost:${port}?sentient_persona=buyer`;
|
|
237
248
|
}
|
|
238
249
|
|
|
250
|
+
// src/validate-key.ts
|
|
251
|
+
function isPublishableKey(key) {
|
|
252
|
+
return key.startsWith("pk_");
|
|
253
|
+
}
|
|
254
|
+
function warnIfNotPublishableKey(key, log = (line) => console.warn(line)) {
|
|
255
|
+
if (!key || isPublishableKey(key)) return false;
|
|
256
|
+
const looksSecret = key.startsWith("sk_");
|
|
257
|
+
log("");
|
|
258
|
+
log("\u26A0 ============================ SECURITY WARNING ============================");
|
|
259
|
+
log(`\u26A0 The key you passed ("${key.slice(0, 6)}\u2026") is NOT a publishable pk_ key.`);
|
|
260
|
+
if (looksSecret) {
|
|
261
|
+
log("\u26A0 It looks like a SECRET server key (sk_\u2026). Do NOT ship it to the browser.");
|
|
262
|
+
}
|
|
263
|
+
log("\u26A0 This CLI writes the key into a CLIENT-exposed env var, so it is bundled");
|
|
264
|
+
log("\u26A0 into your site and visible to every visitor. Only publishable pk_ keys");
|
|
265
|
+
log("\u26A0 belong in client env. Get your pk_ key from the SentientUI dashboard.");
|
|
266
|
+
log("\u26A0 =======================================================================");
|
|
267
|
+
log("");
|
|
268
|
+
return true;
|
|
269
|
+
}
|
|
270
|
+
function assertPublishableKey(key, log = (line) => console.error(line)) {
|
|
271
|
+
if (warnIfNotPublishableKey(key, log)) {
|
|
272
|
+
throw new Error(
|
|
273
|
+
"Refusing to write a non-publishable key into a client-exposed env var. Only publishable pk_ keys belong in the browser bundle \u2014 pass your pk_ key from the SentientUI dashboard, or omit --key for local mode."
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
239
278
|
// src/init.ts
|
|
240
279
|
function runInit(opts) {
|
|
241
|
-
|
|
242
|
-
const
|
|
243
|
-
|
|
280
|
+
const log = opts.log ?? ((line) => console.log(line));
|
|
281
|
+
const exec = opts.exec ?? ((command, cwd) => (0, import_node_child_process.execSync)(command, { cwd, stdio: "inherit" }));
|
|
282
|
+
assertPublishableKey(opts.key, log);
|
|
244
283
|
const framework = detectFramework(opts.cwd);
|
|
245
284
|
log(`[sentientui] detected framework: ${framework}`);
|
|
246
285
|
if (framework === "unknown") {
|
|
@@ -253,7 +292,7 @@ function runInit(opts) {
|
|
|
253
292
|
exec(install, opts.cwd);
|
|
254
293
|
const envResult = writeEnvFile(opts.cwd, framework, opts.key);
|
|
255
294
|
log(
|
|
256
|
-
`[sentientui] .env.local ${envResult}: ${envVarName(framework)}=${
|
|
295
|
+
`[sentientui] .env.local ${envResult}: ${envVarName(framework)}=${opts.key ?? "(empty \u2014 local mode)"}`
|
|
257
296
|
);
|
|
258
297
|
const scaffolded = scaffoldExample(opts.cwd);
|
|
259
298
|
log(
|
|
@@ -268,27 +307,50 @@ function runInit(opts) {
|
|
|
268
307
|
}
|
|
269
308
|
|
|
270
309
|
// src/index.ts
|
|
310
|
+
var import_meta = {};
|
|
271
311
|
function parseArgs(argv) {
|
|
272
312
|
const args = [...argv];
|
|
273
|
-
const
|
|
274
|
-
let
|
|
313
|
+
const command = args.shift();
|
|
314
|
+
let key;
|
|
275
315
|
for (let i = 0; i < args.length; i++) {
|
|
276
|
-
|
|
277
|
-
|
|
316
|
+
const arg = args[i];
|
|
317
|
+
if (arg === "--key") {
|
|
318
|
+
key = args[i + 1];
|
|
278
319
|
i++;
|
|
320
|
+
} else if (arg.startsWith("--key=")) {
|
|
321
|
+
key = arg.slice("--key=".length);
|
|
279
322
|
}
|
|
280
323
|
}
|
|
281
|
-
return { command
|
|
324
|
+
return { command, key };
|
|
282
325
|
}
|
|
283
|
-
|
|
284
|
-
|
|
326
|
+
function main(argv) {
|
|
327
|
+
const { command, key } = parseArgs(argv);
|
|
328
|
+
if (command === "init") {
|
|
329
|
+
try {
|
|
330
|
+
runInit({ cwd: process.cwd(), key });
|
|
331
|
+
} catch (err) {
|
|
332
|
+
console.error(`[sentientui] init failed: ${String(err)}`);
|
|
333
|
+
process.exit(1);
|
|
334
|
+
}
|
|
335
|
+
} else {
|
|
336
|
+
console.log("Usage: npx @sentientui/cli init [--key pk_...] [--yes]");
|
|
337
|
+
process.exit(command ? 1 : 0);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
function isRunAsScript() {
|
|
285
341
|
try {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
342
|
+
const entry = process.argv[1];
|
|
343
|
+
if (!entry) return false;
|
|
344
|
+
return (0, import_node_fs4.realpathSync)((0, import_node_url.fileURLToPath)(import_meta.url)) === (0, import_node_fs4.realpathSync)(entry);
|
|
345
|
+
} catch {
|
|
346
|
+
return false;
|
|
290
347
|
}
|
|
291
|
-
} else {
|
|
292
|
-
console.log("Usage: npx @sentientui/cli init [--key pk_...] [--yes]");
|
|
293
|
-
process.exit(command ? 1 : 0);
|
|
294
348
|
}
|
|
349
|
+
if (isRunAsScript()) {
|
|
350
|
+
main(process.argv.slice(2));
|
|
351
|
+
}
|
|
352
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
353
|
+
0 && (module.exports = {
|
|
354
|
+
main,
|
|
355
|
+
parseArgs
|
|
356
|
+
});
|
package/dist/index.js
CHANGED
|
@@ -1,20 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
var __defNormalProp = (obj, key2, value) => key2 in obj ? __defProp(obj, key2, { enumerable: true, configurable: true, writable: true, value }) : obj[key2] = value;
|
|
7
|
-
var __spreadValues = (a, b) => {
|
|
8
|
-
for (var prop in b || (b = {}))
|
|
9
|
-
if (__hasOwnProp.call(b, prop))
|
|
10
|
-
__defNormalProp(a, prop, b[prop]);
|
|
11
|
-
if (__getOwnPropSymbols)
|
|
12
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
13
|
-
if (__propIsEnum.call(b, prop))
|
|
14
|
-
__defNormalProp(a, prop, b[prop]);
|
|
15
|
-
}
|
|
16
|
-
return a;
|
|
17
|
-
};
|
|
2
|
+
|
|
3
|
+
// src/index.ts
|
|
4
|
+
import { realpathSync } from "fs";
|
|
5
|
+
import { fileURLToPath } from "url";
|
|
18
6
|
|
|
19
7
|
// src/init.ts
|
|
20
8
|
import { execSync } from "child_process";
|
|
@@ -25,14 +13,14 @@ import path from "path";
|
|
|
25
13
|
function readPackageJson(cwd) {
|
|
26
14
|
try {
|
|
27
15
|
return JSON.parse(readFileSync(path.join(cwd, "package.json"), "utf-8"));
|
|
28
|
-
} catch
|
|
16
|
+
} catch {
|
|
29
17
|
return null;
|
|
30
18
|
}
|
|
31
19
|
}
|
|
32
20
|
function detectFramework(cwd) {
|
|
33
21
|
const pkg = readPackageJson(cwd);
|
|
34
22
|
if (!pkg) return "unknown";
|
|
35
|
-
const deps =
|
|
23
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
36
24
|
const has = (dir) => existsSync(path.join(cwd, dir));
|
|
37
25
|
if (deps["next"]) {
|
|
38
26
|
if (has("app") || has(path.join("src", "app"))) return "next-app";
|
|
@@ -67,15 +55,25 @@ function installCommand(pm, pkgName) {
|
|
|
67
55
|
import { existsSync as existsSync2, readFileSync as readFileSync2, appendFileSync, writeFileSync } from "fs";
|
|
68
56
|
import path2 from "path";
|
|
69
57
|
function envVarName(framework) {
|
|
70
|
-
|
|
58
|
+
switch (framework) {
|
|
59
|
+
case "cra":
|
|
60
|
+
return "REACT_APP_SENTIENT_API_KEY";
|
|
61
|
+
case "vite":
|
|
62
|
+
case "remix":
|
|
63
|
+
return "VITE_SENTIENT_API_KEY";
|
|
64
|
+
case "next-app":
|
|
65
|
+
case "next-pages":
|
|
66
|
+
case "unknown":
|
|
67
|
+
return "NEXT_PUBLIC_SENTIENT_API_KEY";
|
|
68
|
+
}
|
|
71
69
|
}
|
|
72
|
-
function writeEnvFile(cwd, framework,
|
|
70
|
+
function writeEnvFile(cwd, framework, key) {
|
|
73
71
|
const varName = envVarName(framework);
|
|
74
72
|
const file = path2.join(cwd, ".env.local");
|
|
75
73
|
const block = [
|
|
76
74
|
"",
|
|
77
75
|
"# SentientUI \u2014 leave empty for local mode (decisions are simulated on-device; nothing is sent)",
|
|
78
|
-
`${varName}=${
|
|
76
|
+
`${varName}=${key ?? ""}`,
|
|
79
77
|
""
|
|
80
78
|
].join("\n");
|
|
81
79
|
if (!existsSync2(file)) {
|
|
@@ -83,7 +81,7 @@ function writeEnvFile(cwd, framework, key2) {
|
|
|
83
81
|
return "created";
|
|
84
82
|
}
|
|
85
83
|
const existing = readFileSync2(file, "utf-8");
|
|
86
|
-
const assigned = existing.split(/\r?\n/).some((line) => line.trim().startsWith(`${varName}=`));
|
|
84
|
+
const assigned = existing.split(/\r?\n/).some((line) => line.trim().replace(/^#+\s*/, "").startsWith(`${varName}=`));
|
|
87
85
|
if (assigned) return "kept";
|
|
88
86
|
appendFileSync(file, block, "utf-8");
|
|
89
87
|
return "appended";
|
|
@@ -184,7 +182,7 @@ createRoot(document.getElementById('root')!).render(
|
|
|
184
182
|
import { AdaptiveProvider } from '@sentientui/react';
|
|
185
183
|
|
|
186
184
|
// inside the Layout/App component body:
|
|
187
|
-
<AdaptiveProvider apiKey=
|
|
185
|
+
<AdaptiveProvider apiKey={import.meta.env.${envVar} ?? ''} context="landing">
|
|
188
186
|
<Outlet />
|
|
189
187
|
</AdaptiveProvider>`;
|
|
190
188
|
case "cra":
|
|
@@ -215,11 +213,39 @@ function finale(framework) {
|
|
|
215
213
|
return `open http://localhost:${port}?sentient_persona=buyer`;
|
|
216
214
|
}
|
|
217
215
|
|
|
216
|
+
// src/validate-key.ts
|
|
217
|
+
function isPublishableKey(key) {
|
|
218
|
+
return key.startsWith("pk_");
|
|
219
|
+
}
|
|
220
|
+
function warnIfNotPublishableKey(key, log = (line) => console.warn(line)) {
|
|
221
|
+
if (!key || isPublishableKey(key)) return false;
|
|
222
|
+
const looksSecret = key.startsWith("sk_");
|
|
223
|
+
log("");
|
|
224
|
+
log("\u26A0 ============================ SECURITY WARNING ============================");
|
|
225
|
+
log(`\u26A0 The key you passed ("${key.slice(0, 6)}\u2026") is NOT a publishable pk_ key.`);
|
|
226
|
+
if (looksSecret) {
|
|
227
|
+
log("\u26A0 It looks like a SECRET server key (sk_\u2026). Do NOT ship it to the browser.");
|
|
228
|
+
}
|
|
229
|
+
log("\u26A0 This CLI writes the key into a CLIENT-exposed env var, so it is bundled");
|
|
230
|
+
log("\u26A0 into your site and visible to every visitor. Only publishable pk_ keys");
|
|
231
|
+
log("\u26A0 belong in client env. Get your pk_ key from the SentientUI dashboard.");
|
|
232
|
+
log("\u26A0 =======================================================================");
|
|
233
|
+
log("");
|
|
234
|
+
return true;
|
|
235
|
+
}
|
|
236
|
+
function assertPublishableKey(key, log = (line) => console.error(line)) {
|
|
237
|
+
if (warnIfNotPublishableKey(key, log)) {
|
|
238
|
+
throw new Error(
|
|
239
|
+
"Refusing to write a non-publishable key into a client-exposed env var. Only publishable pk_ keys belong in the browser bundle \u2014 pass your pk_ key from the SentientUI dashboard, or omit --key for local mode."
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
218
244
|
// src/init.ts
|
|
219
245
|
function runInit(opts) {
|
|
220
|
-
|
|
221
|
-
const
|
|
222
|
-
|
|
246
|
+
const log = opts.log ?? ((line) => console.log(line));
|
|
247
|
+
const exec = opts.exec ?? ((command, cwd) => execSync(command, { cwd, stdio: "inherit" }));
|
|
248
|
+
assertPublishableKey(opts.key, log);
|
|
223
249
|
const framework = detectFramework(opts.cwd);
|
|
224
250
|
log(`[sentientui] detected framework: ${framework}`);
|
|
225
251
|
if (framework === "unknown") {
|
|
@@ -232,7 +258,7 @@ function runInit(opts) {
|
|
|
232
258
|
exec(install, opts.cwd);
|
|
233
259
|
const envResult = writeEnvFile(opts.cwd, framework, opts.key);
|
|
234
260
|
log(
|
|
235
|
-
`[sentientui] .env.local ${envResult}: ${envVarName(framework)}=${
|
|
261
|
+
`[sentientui] .env.local ${envResult}: ${envVarName(framework)}=${opts.key ?? "(empty \u2014 local mode)"}`
|
|
236
262
|
);
|
|
237
263
|
const scaffolded = scaffoldExample(opts.cwd);
|
|
238
264
|
log(
|
|
@@ -249,25 +275,46 @@ function runInit(opts) {
|
|
|
249
275
|
// src/index.ts
|
|
250
276
|
function parseArgs(argv) {
|
|
251
277
|
const args = [...argv];
|
|
252
|
-
const
|
|
253
|
-
let
|
|
278
|
+
const command = args.shift();
|
|
279
|
+
let key;
|
|
254
280
|
for (let i = 0; i < args.length; i++) {
|
|
255
|
-
|
|
256
|
-
|
|
281
|
+
const arg = args[i];
|
|
282
|
+
if (arg === "--key") {
|
|
283
|
+
key = args[i + 1];
|
|
257
284
|
i++;
|
|
285
|
+
} else if (arg.startsWith("--key=")) {
|
|
286
|
+
key = arg.slice("--key=".length);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return { command, key };
|
|
290
|
+
}
|
|
291
|
+
function main(argv) {
|
|
292
|
+
const { command, key } = parseArgs(argv);
|
|
293
|
+
if (command === "init") {
|
|
294
|
+
try {
|
|
295
|
+
runInit({ cwd: process.cwd(), key });
|
|
296
|
+
} catch (err) {
|
|
297
|
+
console.error(`[sentientui] init failed: ${String(err)}`);
|
|
298
|
+
process.exit(1);
|
|
258
299
|
}
|
|
300
|
+
} else {
|
|
301
|
+
console.log("Usage: npx @sentientui/cli init [--key pk_...] [--yes]");
|
|
302
|
+
process.exit(command ? 1 : 0);
|
|
259
303
|
}
|
|
260
|
-
return { command: command2, key: key2 };
|
|
261
304
|
}
|
|
262
|
-
|
|
263
|
-
if (command === "init") {
|
|
305
|
+
function isRunAsScript() {
|
|
264
306
|
try {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
307
|
+
const entry = process.argv[1];
|
|
308
|
+
if (!entry) return false;
|
|
309
|
+
return realpathSync(fileURLToPath(import.meta.url)) === realpathSync(entry);
|
|
310
|
+
} catch {
|
|
311
|
+
return false;
|
|
269
312
|
}
|
|
270
|
-
} else {
|
|
271
|
-
console.log("Usage: npx @sentientui/cli init [--key pk_...] [--yes]");
|
|
272
|
-
process.exit(command ? 1 : 0);
|
|
273
313
|
}
|
|
314
|
+
if (isRunAsScript()) {
|
|
315
|
+
main(process.argv.slice(2));
|
|
316
|
+
}
|
|
317
|
+
export {
|
|
318
|
+
main,
|
|
319
|
+
parseArgs
|
|
320
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentientui/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"description": "SentientUI CLI — `npx @sentientui/cli init` sets up adaptive UI in an existing React app (installs the SDK, writes env config, scaffolds an example, and prints the wrap instructions)",
|
|
5
|
+
"license": "MIT",
|
|
5
6
|
"homepage": "https://sentient-ui.com",
|
|
6
7
|
"repository": {
|
|
7
8
|
"type": "git",
|
|
@@ -40,6 +41,7 @@
|
|
|
40
41
|
"build": "tsup",
|
|
41
42
|
"test": "vitest run",
|
|
42
43
|
"typecheck": "tsc --noEmit",
|
|
43
|
-
"dev": "tsx src/index.ts"
|
|
44
|
+
"dev": "tsx src/index.ts",
|
|
45
|
+
"lint": "eslint src"
|
|
44
46
|
}
|
|
45
47
|
}
|