showpane 0.4.4 → 0.4.6
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.
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"generatedAt": "2026-04-
|
|
4
|
-
"scaffoldVersion": "0.2.
|
|
3
|
+
"generatedAt": "2026-04-09T14:26:32.270Z",
|
|
4
|
+
"scaffoldVersion": "0.2.3",
|
|
5
5
|
"files": {
|
|
6
6
|
".env.example": "0dd692f1c7e6bcabdf5dbdfe9abb73797d79d8e90da150d6098b63ddc695dc29",
|
|
7
7
|
".gitignore": "998e5f43865ea56ac79a05acfd5d4b0d696f310bd5325a1ed458c3d40154d437",
|
|
8
|
-
"VERSION": "
|
|
8
|
+
"VERSION": "3ab94c04d24986f3af288ba1cda2c0bbddbc5a89dff097182805f54578e1ea75",
|
|
9
9
|
"docker-compose.yml": "420fd123da019c22f03662933537e24779b4c2c91f90c23abfec5965cd0f35ce",
|
|
10
10
|
"docker/Caddyfile": "d9c58086986795f5b3e42ff9b5942e60b8df946a1a0c40351381616c0b4d2bed",
|
|
11
11
|
"docker/Dockerfile": "340470e3735ea53b2c03003a13a91361652291add33c40a2bf13e6af2a8cb73a",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"src/app/api/health/route.ts": "78fff55707372ce0cd6e9e49ef4f049622bc43cc42916d3f83e0162409d678b1",
|
|
48
48
|
"src/app/globals.css": "28dcda76006d0e6af01b6dcf1a315dc5b5b6931c880fc53fd6565ff09d5dd13a",
|
|
49
49
|
"src/app/layout.tsx": "c17aabeb2b486f023e777230343ace6cc06840f641a10b9dd9f65e092018f82f",
|
|
50
|
-
"src/app/page.tsx": "
|
|
50
|
+
"src/app/page.tsx": "732ea54f313386b65bce1170785379b27bb26b5da26b833b1e50c3713b87be1a",
|
|
51
51
|
"src/components/copy-button.tsx": "2f3d1d8a6a0a570c8d78e19c3c15519c44af17b5d8893ae5a5f57db5ecce7077",
|
|
52
52
|
"src/components/portal-login.tsx": "8b0d91bb28674e1102fd2e5b5ddcc3a93755dd806fbd3d1b2dbea2646cffca5e",
|
|
53
53
|
"src/components/portal-shell.tsx": "a4e16e118ef93f79e71fb69e80f1fac6e6fff90f0fbdacdf8deb821a57656877",
|
package/bundle/scaffold/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.2.
|
|
1
|
+
0.2.3
|
|
@@ -4,6 +4,7 @@ import { prisma } from "@/lib/db";
|
|
|
4
4
|
import { getRuntimeState, isRuntimeSnapshotMode } from "@/lib/runtime-state";
|
|
5
5
|
import { ArrowUpRight, BookOpen, Command, MessageSquareQuote } from "lucide-react";
|
|
6
6
|
import Link from "next/link";
|
|
7
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
7
8
|
import os from "node:os";
|
|
8
9
|
import path from "node:path";
|
|
9
10
|
|
|
@@ -16,9 +17,22 @@ const PROMPT_EXAMPLES = [
|
|
|
16
17
|
export default async function Home() {
|
|
17
18
|
let portalCount = 0;
|
|
18
19
|
const showpaneBinDir = path.join(os.homedir(), ".showpane", "bin");
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
const configPath = path.join(os.homedir(), ".showpane", "config.json");
|
|
21
|
+
const configShellPathConfigured = existsSync(configPath)
|
|
22
|
+
? (() => {
|
|
23
|
+
try {
|
|
24
|
+
const raw = readFileSync(configPath, "utf8");
|
|
25
|
+
return Boolean((JSON.parse(raw) as { shellPathConfigured?: boolean }).shellPathConfigured);
|
|
26
|
+
} catch {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
})()
|
|
30
|
+
: false;
|
|
31
|
+
const prefersCanonicalCommand =
|
|
32
|
+
configShellPathConfigured ||
|
|
33
|
+
(process.env.PATH ?? "").split(path.delimiter).includes(showpaneBinDir);
|
|
34
|
+
const primaryCommand = "showpane claude";
|
|
35
|
+
const fallbackCommand = "npx showpane claude";
|
|
22
36
|
try {
|
|
23
37
|
if (isRuntimeSnapshotMode()) {
|
|
24
38
|
const state = await getRuntimeState();
|
|
@@ -46,7 +60,7 @@ export default async function Home() {
|
|
|
46
60
|
Your Showpane workspace is ready
|
|
47
61
|
</h1>
|
|
48
62
|
<p className="mt-4 max-w-2xl text-base leading-7 text-white/82 sm:text-lg">
|
|
49
|
-
Open
|
|
63
|
+
Open a new terminal window, run Showpane with Claude, and create your first client portal.
|
|
50
64
|
</p>
|
|
51
65
|
</div>
|
|
52
66
|
</div>
|
|
@@ -61,15 +75,21 @@ export default async function Home() {
|
|
|
61
75
|
Start with Claude
|
|
62
76
|
</div>
|
|
63
77
|
<p className="mt-3 text-sm leading-6 text-white/72">
|
|
64
|
-
|
|
78
|
+
Open a new terminal window and run this command there. Your current terminal is running the local app, so this command belongs in a fresh one.
|
|
65
79
|
</p>
|
|
80
|
+
{!prefersCanonicalCommand && (
|
|
81
|
+
<p className="mt-2 text-xs leading-5 text-white/60">
|
|
82
|
+
If <code className="font-mono text-white">{primaryCommand}</code> isn't available in your shell yet, use{" "}
|
|
83
|
+
<code className="font-mono text-white">{fallbackCommand}</code>.
|
|
84
|
+
</p>
|
|
85
|
+
)}
|
|
66
86
|
</div>
|
|
67
|
-
<CopyButton text={
|
|
87
|
+
<CopyButton text={primaryCommand} invert />
|
|
68
88
|
</div>
|
|
69
89
|
|
|
70
90
|
<div className="mt-5 rounded-2xl border border-white/10 bg-white/5 p-4">
|
|
71
91
|
<code className="block overflow-x-auto font-mono text-sm text-white sm:text-[15px]">
|
|
72
|
-
{
|
|
92
|
+
{primaryCommand}
|
|
73
93
|
</code>
|
|
74
94
|
</div>
|
|
75
95
|
</section>
|
package/bundle/toolchain/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.1.
|
|
1
|
+
1.1.3 (requires app >= 0.2.3)
|
package/dist/index.js
CHANGED
|
@@ -243,35 +243,146 @@ function getResumeCommand() {
|
|
|
243
243
|
function getResumeHint() {
|
|
244
244
|
return isShowpaneShimOnPath() ? null : `Optional: add ${SHOWPANE_BIN_DIR} to your PATH to use ${BOLD}showpane${RESET} directly.`;
|
|
245
245
|
}
|
|
246
|
+
function shellPathExportLine() {
|
|
247
|
+
return `export PATH="$HOME/.showpane/bin:$PATH"`;
|
|
248
|
+
}
|
|
249
|
+
function detectShellProfile() {
|
|
250
|
+
if (process.platform === "win32") {
|
|
251
|
+
return null;
|
|
252
|
+
}
|
|
253
|
+
const shell = basename(process.env.SHELL || "");
|
|
254
|
+
if (shell === "zsh") {
|
|
255
|
+
return join(homedir(), ".zshrc");
|
|
256
|
+
}
|
|
257
|
+
if (shell === "bash") {
|
|
258
|
+
return process.platform === "darwin" ? join(homedir(), ".bash_profile") : join(homedir(), ".bashrc");
|
|
259
|
+
}
|
|
260
|
+
if (shell === "fish") {
|
|
261
|
+
return join(homedir(), ".config", "fish", "config.fish");
|
|
262
|
+
}
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
function ensureShellPathEntry(profilePath) {
|
|
266
|
+
ensureDir(dirname(profilePath));
|
|
267
|
+
const exportLine = shellPathExportLine();
|
|
268
|
+
const contents = existsSync(profilePath) ? readFileSync(profilePath, "utf8") : "";
|
|
269
|
+
if (contents.includes(exportLine) || contents.includes(SHOWPANE_BIN_DIR)) {
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
const prefix = contents.length > 0 && !contents.endsWith("\n") ? "\n" : "";
|
|
273
|
+
writeFileSync(profilePath, `${contents}${prefix}${exportLine}
|
|
274
|
+
`);
|
|
275
|
+
return true;
|
|
276
|
+
}
|
|
277
|
+
async function maybeConfigureShellPath(config, options) {
|
|
278
|
+
const configuredProfile = typeof config.shellPathConfiguredProfile === "string" ? config.shellPathConfiguredProfile : null;
|
|
279
|
+
if (isShowpaneShimOnPath()) {
|
|
280
|
+
config.shellPathConfigured = true;
|
|
281
|
+
config.shellPathPrompted = true;
|
|
282
|
+
return {
|
|
283
|
+
command: "showpane claude",
|
|
284
|
+
configured: true,
|
|
285
|
+
profilePath: configuredProfile
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
if (config.shellPathConfigured) {
|
|
289
|
+
return {
|
|
290
|
+
command: "showpane claude",
|
|
291
|
+
configured: true,
|
|
292
|
+
profilePath: configuredProfile
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
if (options.yes || !process.stdin.isTTY || !process.stdout.isTTY) {
|
|
296
|
+
config.shellPathPrompted = true;
|
|
297
|
+
config.shellPathConfigured = false;
|
|
298
|
+
return {
|
|
299
|
+
command: "npx showpane claude",
|
|
300
|
+
configured: false,
|
|
301
|
+
profilePath: configuredProfile
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
const profilePath = detectShellProfile();
|
|
305
|
+
if (!profilePath) {
|
|
306
|
+
config.shellPathPrompted = true;
|
|
307
|
+
config.shellPathConfigured = false;
|
|
308
|
+
return {
|
|
309
|
+
command: "npx showpane claude",
|
|
310
|
+
configured: false,
|
|
311
|
+
profilePath: null
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
const answer = await ask(
|
|
315
|
+
` ${BOLD}Add Showpane to your PATH so 'showpane' works in future terminals?${RESET} ${DIM}(recommended) [Y/n]${RESET} `
|
|
316
|
+
);
|
|
317
|
+
if (answer && !["y", "yes"].includes(answer.toLowerCase())) {
|
|
318
|
+
config.shellPathPrompted = true;
|
|
319
|
+
config.shellPathConfigured = false;
|
|
320
|
+
config.shellPathConfiguredProfile = profilePath;
|
|
321
|
+
return {
|
|
322
|
+
command: "npx showpane claude",
|
|
323
|
+
configured: false,
|
|
324
|
+
profilePath
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
ensureShellPathEntry(profilePath);
|
|
328
|
+
config.shellPathPrompted = true;
|
|
329
|
+
config.shellPathConfigured = true;
|
|
330
|
+
config.shellPathConfiguredProfile = profilePath;
|
|
331
|
+
console.log();
|
|
332
|
+
green(`Added Showpane to your PATH in ${DIM}${profilePath}${RESET}`);
|
|
333
|
+
return {
|
|
334
|
+
command: "showpane claude",
|
|
335
|
+
configured: true,
|
|
336
|
+
profilePath
|
|
337
|
+
};
|
|
338
|
+
}
|
|
246
339
|
function getCommandOutput(errorLike) {
|
|
247
340
|
const error2 = errorLike;
|
|
248
341
|
const stdout = typeof error2?.stdout === "string" ? error2.stdout : error2?.stdout?.toString() ?? "";
|
|
249
342
|
const stderr = typeof error2?.stderr === "string" ? error2.stderr : error2?.stderr?.toString() ?? "";
|
|
250
343
|
return [stdout, stderr].filter(Boolean).join("\n").trim();
|
|
251
344
|
}
|
|
252
|
-
function
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
345
|
+
async function runQuietAsync(command2, cwd, env) {
|
|
346
|
+
const child = spawn(command2, {
|
|
347
|
+
cwd,
|
|
348
|
+
env: env ? { ...process.env, ...env } : process.env,
|
|
349
|
+
shell: true,
|
|
350
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
351
|
+
});
|
|
352
|
+
let output = "";
|
|
353
|
+
const appendOutput = (chunk) => {
|
|
354
|
+
output += chunk.toString();
|
|
355
|
+
if (output.length > 20 * 1024 * 1024) {
|
|
356
|
+
output = output.slice(-20 * 1024 * 1024);
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
child.stdout?.on("data", appendOutput);
|
|
360
|
+
child.stderr?.on("data", appendOutput);
|
|
361
|
+
await new Promise((resolvePromise, rejectPromise) => {
|
|
362
|
+
child.on("error", (errorLike) => {
|
|
363
|
+
rejectPromise(
|
|
364
|
+
new StepCommandError(
|
|
365
|
+
errorLike instanceof Error ? errorLike.message : String(errorLike),
|
|
366
|
+
output.trim()
|
|
367
|
+
)
|
|
368
|
+
);
|
|
260
369
|
});
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
370
|
+
child.on("close", (code, signal) => {
|
|
371
|
+
if (code === 0) {
|
|
372
|
+
resolvePromise();
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
const reason = signal ? `Command terminated with signal ${signal}` : `Command exited with code ${code ?? "unknown"}`;
|
|
376
|
+
rejectPromise(new StepCommandError(reason, output.trim()));
|
|
377
|
+
});
|
|
378
|
+
});
|
|
268
379
|
}
|
|
269
|
-
function runInstallerCommand(command2, cwd, env, verbose) {
|
|
380
|
+
async function runInstallerCommand(command2, cwd, env, verbose) {
|
|
270
381
|
if (verbose) {
|
|
271
382
|
run(command2, cwd, env);
|
|
272
383
|
return;
|
|
273
384
|
}
|
|
274
|
-
|
|
385
|
+
await runQuietAsync(command2, cwd, env);
|
|
275
386
|
}
|
|
276
387
|
var activeSpinner = null;
|
|
277
388
|
function renderSpinner(label, frame, startedAt) {
|
|
@@ -331,6 +442,18 @@ function stepFailure(label, errorLike, hint) {
|
|
|
331
442
|
}
|
|
332
443
|
process.exit(1);
|
|
333
444
|
}
|
|
445
|
+
function shouldUseSpinner(verbose) {
|
|
446
|
+
return process.stdout.isTTY && !verbose;
|
|
447
|
+
}
|
|
448
|
+
function stepStartForCreate(label, options) {
|
|
449
|
+
stepStart(label, shouldUseSpinner(options.verbose));
|
|
450
|
+
}
|
|
451
|
+
function stepSuccessForCreate(label) {
|
|
452
|
+
stepSuccess(label);
|
|
453
|
+
}
|
|
454
|
+
function stepFailureForCreate(label, errorLike, hint) {
|
|
455
|
+
stepFailure(label, errorLike, hint);
|
|
456
|
+
}
|
|
334
457
|
function attachSpinnerCleanup() {
|
|
335
458
|
const cleanup = () => stopSpinner();
|
|
336
459
|
process.on("exit", cleanup);
|
|
@@ -679,39 +802,39 @@ function applyUpgradePlan(projectRoot, scaffoldSource, plan) {
|
|
|
679
802
|
cpSync(sourcePath, targetPath);
|
|
680
803
|
}
|
|
681
804
|
}
|
|
682
|
-
function installDependencies(projectRoot, verbose) {
|
|
805
|
+
async function installDependencies(projectRoot, verbose) {
|
|
683
806
|
if (existsSync(join(projectRoot, "package-lock.json"))) {
|
|
684
807
|
if (verbose === void 0) {
|
|
685
808
|
run("npm ci", projectRoot, getInstallerEnv());
|
|
686
809
|
} else {
|
|
687
|
-
runInstallerCommand("npm ci", projectRoot, getInstallerEnv(), verbose);
|
|
810
|
+
await runInstallerCommand("npm ci", projectRoot, getInstallerEnv(), verbose);
|
|
688
811
|
}
|
|
689
812
|
} else {
|
|
690
813
|
if (verbose === void 0) {
|
|
691
814
|
run("npm install", projectRoot, getInstallerEnv());
|
|
692
815
|
} else {
|
|
693
|
-
runInstallerCommand("npm install", projectRoot, getInstallerEnv(), verbose);
|
|
816
|
+
await runInstallerCommand("npm install", projectRoot, getInstallerEnv(), verbose);
|
|
694
817
|
}
|
|
695
818
|
}
|
|
696
819
|
}
|
|
697
|
-
function generateLocalDatabase(projectRoot, databaseUrl, verbose) {
|
|
820
|
+
async function generateLocalDatabase(projectRoot, databaseUrl, verbose) {
|
|
698
821
|
const env = getInstallerEnv({
|
|
699
822
|
DATABASE_URL: databaseUrl
|
|
700
823
|
});
|
|
701
824
|
if (verbose === void 0) {
|
|
702
825
|
run("npm run prisma:db-push", projectRoot, env);
|
|
703
826
|
} else {
|
|
704
|
-
runInstallerCommand("npm run prisma:db-push", projectRoot, env, verbose);
|
|
827
|
+
await runInstallerCommand("npm run prisma:db-push", projectRoot, env, verbose);
|
|
705
828
|
}
|
|
706
829
|
}
|
|
707
|
-
function seedProject(projectRoot, databaseUrl, verbose) {
|
|
830
|
+
async function seedProject(projectRoot, databaseUrl, verbose) {
|
|
708
831
|
const env = getInstallerEnv({
|
|
709
832
|
DATABASE_URL: databaseUrl
|
|
710
833
|
});
|
|
711
834
|
if (verbose === void 0) {
|
|
712
835
|
run("npx tsx prisma/seed.ts", projectRoot, env);
|
|
713
836
|
} else {
|
|
714
|
-
runInstallerCommand("npx tsx prisma/seed.ts", projectRoot, env, verbose);
|
|
837
|
+
await runInstallerCommand("npx tsx prisma/seed.ts", projectRoot, env, verbose);
|
|
715
838
|
}
|
|
716
839
|
}
|
|
717
840
|
function maybeRunPostUpgradeSteps(projectRoot, changedPaths) {
|
|
@@ -782,9 +905,8 @@ function installSharedSkillProjection(toolchainRoot) {
|
|
|
782
905
|
process.platform === "win32" ? "junction" : "dir"
|
|
783
906
|
);
|
|
784
907
|
}
|
|
785
|
-
function printCreateSuccessCard(projectRoot, url) {
|
|
786
|
-
const resumeCommand =
|
|
787
|
-
const resumeHint = getResumeHint();
|
|
908
|
+
function printCreateSuccessCard(projectRoot, url, pathSetup) {
|
|
909
|
+
const resumeCommand = pathSetup.command;
|
|
788
910
|
console.log();
|
|
789
911
|
console.log(` ${GREEN}Showpane is ready${RESET}`);
|
|
790
912
|
console.log();
|
|
@@ -792,14 +914,20 @@ function printCreateSuccessCard(projectRoot, url) {
|
|
|
792
914
|
console.log(` ${BOLD}App:${RESET} ${url}`);
|
|
793
915
|
console.log(` ${BOLD}Demo:${RESET} example / demo-only-password`);
|
|
794
916
|
console.log();
|
|
795
|
-
console.log(` ${BOLD}Next:${RESET}`);
|
|
917
|
+
console.log(` ${BOLD}Next (in a new terminal window):${RESET}`);
|
|
796
918
|
console.log(` ${DIM}${resumeCommand}${RESET}`);
|
|
797
919
|
console.log();
|
|
920
|
+
if (pathSetup.configured && pathSetup.profilePath) {
|
|
921
|
+
console.log(` ${DIM}Your current terminal is running the local app logs. Open a fresh terminal so ${BOLD}showpane${RESET}${DIM} is available from ${pathSetup.profilePath}.${RESET}`);
|
|
922
|
+
} else {
|
|
923
|
+
console.log(` ${DIM}Your current terminal is running the local app logs, so open a fresh terminal before you run that command.${RESET}`);
|
|
924
|
+
}
|
|
925
|
+
console.log();
|
|
798
926
|
console.log(` ${BOLD}Try:${RESET}`);
|
|
799
927
|
console.log(` ${DIM}Create a portal for my call with Acme Health${RESET}`);
|
|
800
|
-
if (
|
|
928
|
+
if (!pathSetup.configured) {
|
|
801
929
|
console.log();
|
|
802
|
-
console.log(` ${DIM}${
|
|
930
|
+
console.log(` ${DIM}${getResumeHint()}${RESET}`);
|
|
803
931
|
}
|
|
804
932
|
console.log();
|
|
805
933
|
}
|
|
@@ -1031,6 +1159,8 @@ async function createProject(args) {
|
|
|
1031
1159
|
}
|
|
1032
1160
|
printBanner();
|
|
1033
1161
|
ensureShowpaneShim();
|
|
1162
|
+
const config = readShowpaneConfig();
|
|
1163
|
+
const pathSetup = await maybeConfigureShellPath(config, options);
|
|
1034
1164
|
const companyName = options.companyName ?? await ask(` ${BOLD}What's your company name?${RESET} `);
|
|
1035
1165
|
if (!companyName) {
|
|
1036
1166
|
error("Company name is required.");
|
|
@@ -1046,20 +1176,20 @@ async function createProject(args) {
|
|
|
1046
1176
|
console.log();
|
|
1047
1177
|
blue(`Setting up ${BOLD}${companyName}${RESET} portal as ${DIM}${dirName}/${RESET}`);
|
|
1048
1178
|
console.log();
|
|
1049
|
-
|
|
1179
|
+
stepStartForCreate("Creating project", options);
|
|
1050
1180
|
try {
|
|
1051
1181
|
copyScaffoldFiles(join(bundleRoot, "scaffold"), projectRoot, scaffoldManifest);
|
|
1052
|
-
|
|
1182
|
+
stepSuccessForCreate("Project created");
|
|
1053
1183
|
} catch (errorLike) {
|
|
1054
|
-
|
|
1184
|
+
stepFailureForCreate("Creating project", errorLike);
|
|
1055
1185
|
}
|
|
1056
|
-
|
|
1186
|
+
stepStartForCreate("Installing dependencies", options);
|
|
1057
1187
|
try {
|
|
1058
|
-
installDependencies(projectRoot, options.verbose);
|
|
1059
|
-
|
|
1188
|
+
await installDependencies(projectRoot, options.verbose);
|
|
1189
|
+
stepSuccessForCreate("Dependencies installed");
|
|
1060
1190
|
} catch (errorLike) {
|
|
1061
|
-
|
|
1062
|
-
"
|
|
1191
|
+
stepFailureForCreate(
|
|
1192
|
+
"Installing dependencies",
|
|
1063
1193
|
errorLike,
|
|
1064
1194
|
"Check your Node.js version and network connection, then try again."
|
|
1065
1195
|
);
|
|
@@ -1072,23 +1202,22 @@ async function createProject(args) {
|
|
|
1072
1202
|
AUTH_SECRET="${authSecret}"
|
|
1073
1203
|
`
|
|
1074
1204
|
);
|
|
1075
|
-
|
|
1205
|
+
stepStartForCreate("Configuring database", options);
|
|
1076
1206
|
try {
|
|
1077
|
-
generateLocalDatabase(projectRoot, databaseUrl, options.verbose);
|
|
1078
|
-
seedProject(projectRoot, databaseUrl, options.verbose);
|
|
1079
|
-
|
|
1207
|
+
await generateLocalDatabase(projectRoot, databaseUrl, options.verbose);
|
|
1208
|
+
await seedProject(projectRoot, databaseUrl, options.verbose);
|
|
1209
|
+
stepSuccessForCreate("Database configured");
|
|
1080
1210
|
} catch (errorLike) {
|
|
1081
|
-
|
|
1082
|
-
"
|
|
1211
|
+
stepFailureForCreate(
|
|
1212
|
+
"Configuring database",
|
|
1083
1213
|
errorLike,
|
|
1084
1214
|
"Check Prisma setup and the generated .env file, then retry the install."
|
|
1085
1215
|
);
|
|
1086
1216
|
}
|
|
1087
|
-
|
|
1217
|
+
stepStartForCreate("Installing Claude skills", options);
|
|
1088
1218
|
let toolchainInfo;
|
|
1089
1219
|
try {
|
|
1090
1220
|
toolchainInfo = syncToolchain(bundleRoot, showpaneVersion, false);
|
|
1091
|
-
const config = readShowpaneConfig();
|
|
1092
1221
|
updateWorkspaceFromConfig(config, projectRoot, {
|
|
1093
1222
|
name: dirName,
|
|
1094
1223
|
deployMode: "local",
|
|
@@ -1102,15 +1231,15 @@ AUTH_SECRET="${authSecret}"
|
|
|
1102
1231
|
toolchainInfo.toolchainVersion
|
|
1103
1232
|
);
|
|
1104
1233
|
tryInitializeGitRepo(projectRoot, false);
|
|
1105
|
-
|
|
1234
|
+
stepSuccessForCreate("Claude skills installed");
|
|
1106
1235
|
} catch (errorLike) {
|
|
1107
|
-
|
|
1108
|
-
"
|
|
1236
|
+
stepFailureForCreate(
|
|
1237
|
+
"Installing Claude skills",
|
|
1109
1238
|
errorLike,
|
|
1110
1239
|
"Check permissions for ~/.showpane and ~/.claude/skills, then try again."
|
|
1111
1240
|
);
|
|
1112
1241
|
}
|
|
1113
|
-
|
|
1242
|
+
stepStartForCreate("Starting app", options);
|
|
1114
1243
|
let serverStart;
|
|
1115
1244
|
try {
|
|
1116
1245
|
serverStart = await startDevServer(
|
|
@@ -1120,13 +1249,13 @@ AUTH_SECRET="${authSecret}"
|
|
|
1120
1249
|
options.verbose
|
|
1121
1250
|
);
|
|
1122
1251
|
} catch (errorLike) {
|
|
1123
|
-
|
|
1124
|
-
"
|
|
1252
|
+
stepFailureForCreate(
|
|
1253
|
+
"Starting app",
|
|
1125
1254
|
errorLike,
|
|
1126
1255
|
`Run ${BOLD}cd ${dirName} && npm run dev${RESET} for more detail.`
|
|
1127
1256
|
);
|
|
1128
1257
|
}
|
|
1129
|
-
printCreateSuccessCard(projectRoot, serverStart.url);
|
|
1258
|
+
printCreateSuccessCard(projectRoot, serverStart.url, pathSetup);
|
|
1130
1259
|
serverStart.devServer.on("close", (code) => {
|
|
1131
1260
|
if (code !== 0) {
|
|
1132
1261
|
error(`Dev server exited with code ${code}`);
|