viagen 0.0.21 → 0.0.23
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/README.md +20 -15
- package/dist/cli.js +9 -9
- package/dist/index.js +37 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,7 +8,24 @@ A Vite dev server plugin and CLI tool that enables you to use Claude Code in a s
|
|
|
8
8
|
- [Vercel](https://vercel.com/signup) — Free plan works. Sandboxes last 45 min on Hobby, 5 hours on Pro.
|
|
9
9
|
- [GitHub CLI](https://cli.github.com) — Enables git clone and push from sandboxes.
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Quick Setup (Claude Code Plugin)
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
/plugin marketplace add viagen-dev/viagen-claude-plugin
|
|
15
|
+
/plugin install viagen@viagen-marketplace
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**Restart Claude Code to load the plugin.**
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
/viagen-install
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The plugin will handle npm installation, vite config updates, and run the setup wizard for you.
|
|
25
|
+
|
|
26
|
+
## Manual Setup
|
|
27
|
+
|
|
28
|
+
### Step 1 — Add viagen to your app
|
|
12
29
|
|
|
13
30
|
```bash
|
|
14
31
|
npm install --save-dev viagen
|
|
@@ -24,7 +41,7 @@ export default defineConfig({
|
|
|
24
41
|
})
|
|
25
42
|
```
|
|
26
43
|
|
|
27
|
-
|
|
44
|
+
### Step 2 — Setup
|
|
28
45
|
|
|
29
46
|
```bash
|
|
30
47
|
npx viagen setup
|
|
@@ -34,7 +51,7 @@ The setup wizard authenticates with Claude, detects your GitHub and Vercel crede
|
|
|
34
51
|
|
|
35
52
|
You can now run `npm run dev` to start the local dev server. At this point you can launch viagen and chat with Claude to make changes to your app.
|
|
36
53
|
|
|
37
|
-
|
|
54
|
+
### Step 3 — Sandbox
|
|
38
55
|
|
|
39
56
|
```bash
|
|
40
57
|
npx viagen sandbox
|
|
@@ -56,18 +73,6 @@ npx viagen sandbox --prompt "build me a landing page"
|
|
|
56
73
|
npx viagen sandbox stop <sandboxId>
|
|
57
74
|
```
|
|
58
75
|
|
|
59
|
-
## Step 4 — Sync
|
|
60
|
-
|
|
61
|
-
```bash
|
|
62
|
-
npx viagen sync
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
Pushes your local `.env` credentials (Claude Max tokens, GitHub token, Vercel config) to a platform project. This lets you launch sandboxes from the web — use your Max subscription from any device without needing a browser redirect.
|
|
66
|
-
|
|
67
|
-
The first run prompts you to pick or create a project. After that, subsequent syncs target the same project automatically (stored as `VIAGEN_PROJECT_ID` in `.env`).
|
|
68
|
-
|
|
69
|
-
Claude tokens are refreshed automatically if expired before syncing. Requires `viagen login` first.
|
|
70
|
-
|
|
71
76
|
## Plugin Options
|
|
72
77
|
|
|
73
78
|
```ts
|
package/dist/cli.js
CHANGED
|
@@ -677,7 +677,7 @@ async function setup() {
|
|
|
677
677
|
}
|
|
678
678
|
}
|
|
679
679
|
console.log("");
|
|
680
|
-
const hasVercel = existing["VERCEL_TOKEN"] && existing["
|
|
680
|
+
const hasVercel = existing["VERCEL_TOKEN"] && existing["VERCEL_ORG_ID"] && existing["VERCEL_PROJECT_ID"];
|
|
681
681
|
if (hasVercel) {
|
|
682
682
|
console.log("Vercel ... already configured");
|
|
683
683
|
} else if (!shellOk("which vercel")) {
|
|
@@ -709,8 +709,8 @@ async function setup() {
|
|
|
709
709
|
}
|
|
710
710
|
if (existsSync(projectJsonPath)) {
|
|
711
711
|
const project = JSON.parse(readFileSync2(projectJsonPath, "utf-8"));
|
|
712
|
-
if (!existing["
|
|
713
|
-
newVars["
|
|
712
|
+
if (!existing["VERCEL_ORG_ID"]) {
|
|
713
|
+
newVars["VERCEL_ORG_ID"] = project.orgId;
|
|
714
714
|
}
|
|
715
715
|
if (!existing["VERCEL_PROJECT_ID"]) {
|
|
716
716
|
newVars["VERCEL_PROJECT_ID"] = project.projectId;
|
|
@@ -744,7 +744,7 @@ async function setup() {
|
|
|
744
744
|
}
|
|
745
745
|
if (existsSync(projectJsonPath2)) {
|
|
746
746
|
const project = JSON.parse(readFileSync2(projectJsonPath2, "utf-8"));
|
|
747
|
-
if (!existing["
|
|
747
|
+
if (!existing["VERCEL_ORG_ID"]) newVars["VERCEL_ORG_ID"] = project.orgId;
|
|
748
748
|
if (!existing["VERCEL_PROJECT_ID"]) newVars["VERCEL_PROJECT_ID"] = project.projectId;
|
|
749
749
|
}
|
|
750
750
|
if (!existing["VERCEL_TOKEN"]) {
|
|
@@ -873,7 +873,7 @@ async function sandbox(args) {
|
|
|
873
873
|
}
|
|
874
874
|
}
|
|
875
875
|
const hasOidc = !!env["VERCEL_OIDC_TOKEN"];
|
|
876
|
-
const hasToken = !!env["VERCEL_TOKEN"] && !!env["
|
|
876
|
+
const hasToken = !!env["VERCEL_TOKEN"] && !!env["VERCEL_ORG_ID"] && !!env["VERCEL_PROJECT_ID"];
|
|
877
877
|
if (!hasOidc && !hasToken) {
|
|
878
878
|
console.error(
|
|
879
879
|
"Error: Vercel not configured. Run `npx viagen setup` first."
|
|
@@ -1002,9 +1002,9 @@ async function sandbox(args) {
|
|
|
1002
1002
|
git: deployGit,
|
|
1003
1003
|
overlayFiles,
|
|
1004
1004
|
envVars: dotenv,
|
|
1005
|
-
vercel: env["VERCEL_TOKEN"] && env["
|
|
1005
|
+
vercel: env["VERCEL_TOKEN"] && env["VERCEL_ORG_ID"] && env["VERCEL_PROJECT_ID"] ? {
|
|
1006
1006
|
token: env["VERCEL_TOKEN"],
|
|
1007
|
-
teamId: env["
|
|
1007
|
+
teamId: env["VERCEL_ORG_ID"],
|
|
1008
1008
|
projectId: env["VERCEL_PROJECT_ID"]
|
|
1009
1009
|
} : void 0,
|
|
1010
1010
|
timeoutMinutes,
|
|
@@ -1035,7 +1035,7 @@ var SYNC_KEYS = [
|
|
|
1035
1035
|
"ANTHROPIC_API_KEY",
|
|
1036
1036
|
"GITHUB_TOKEN",
|
|
1037
1037
|
"VERCEL_TOKEN",
|
|
1038
|
-
"
|
|
1038
|
+
"VERCEL_ORG_ID",
|
|
1039
1039
|
"VERCEL_PROJECT_ID",
|
|
1040
1040
|
"GIT_USER_NAME",
|
|
1041
1041
|
"GIT_USER_EMAIL"
|
|
@@ -1421,7 +1421,7 @@ function help() {
|
|
|
1421
1421
|
" VERCEL_TOKEN Vercel access token (for sandbox)."
|
|
1422
1422
|
);
|
|
1423
1423
|
console.log(
|
|
1424
|
-
"
|
|
1424
|
+
" VERCEL_ORG_ID Vercel org/team ID (for sandbox)."
|
|
1425
1425
|
);
|
|
1426
1426
|
console.log(
|
|
1427
1427
|
" VERCEL_PROJECT_ID Vercel project ID (for sandbox)."
|
package/dist/index.js
CHANGED
|
@@ -416,7 +416,6 @@ function buildClientScript(opts) {
|
|
|
416
416
|
const toggleSideKey = pos.includes("left") ? "left" : "right";
|
|
417
417
|
const toggleVerticalKey = pos.includes("top") ? "top" : "bottom";
|
|
418
418
|
const toggleClosedVal = "16px";
|
|
419
|
-
const toggleOpenVal = `${pw + 14}px`;
|
|
420
419
|
return (
|
|
421
420
|
/* js */
|
|
422
421
|
`
|
|
@@ -519,10 +518,45 @@ function buildClientScript(opts) {
|
|
|
519
518
|
var PANEL_KEY = 'viagen_panel_open';
|
|
520
519
|
var panel = document.createElement('div');
|
|
521
520
|
panel.id = 'viagen-panel';
|
|
522
|
-
|
|
521
|
+
var PANEL_WIDTH_KEY = 'viagen_panel_width';
|
|
522
|
+
var panelWidth = ${pw};
|
|
523
|
+
try { var saved = parseInt(sessionStorage.getItem(PANEL_WIDTH_KEY)); if (saved >= 280) panelWidth = saved; } catch(e) {}
|
|
524
|
+
panel.style.cssText = 'position:fixed;top:0;${panelSide}bottom:0;width:' + panelWidth + 'px;z-index:99997;display:none;border-${pos.includes("left") ? "right" : "left"}:1px solid #27272a;box-shadow:${pos.includes("left") ? "4" : "-4"}px 0 24px rgba(0,0,0,0.5);';
|
|
523
525
|
var iframe = document.createElement('iframe');
|
|
524
526
|
iframe.src = '/via/ui';
|
|
525
527
|
iframe.style.cssText = 'width:100%;height:100%;border:none;background:#09090b;';
|
|
528
|
+
|
|
529
|
+
/* ---- Drag-resize handle ---- */
|
|
530
|
+
var handle = document.createElement('div');
|
|
531
|
+
handle.style.cssText = 'position:absolute;top:0;${pos.includes("left") ? "right" : "left"}:-3px;width:6px;height:100%;cursor:col-resize;z-index:1;background:transparent;transition:background 0.15s;';
|
|
532
|
+
handle.onmouseenter = function() { handle.style.background = '#3f3f46'; };
|
|
533
|
+
handle.onmouseleave = function() { if (!resizing) handle.style.background = 'transparent'; };
|
|
534
|
+
var resizing = false;
|
|
535
|
+
|
|
536
|
+
handle.addEventListener('mousedown', function(e) {
|
|
537
|
+
e.preventDefault();
|
|
538
|
+
resizing = true;
|
|
539
|
+
handle.style.background = '#3f3f46';
|
|
540
|
+
iframe.style.pointerEvents = 'none';
|
|
541
|
+
});
|
|
542
|
+
document.addEventListener('mousemove', function(e) {
|
|
543
|
+
if (!resizing) return;
|
|
544
|
+
var w = ${pos.includes("left") ? "e.clientX" : "window.innerWidth - e.clientX"};
|
|
545
|
+
if (w < 280) w = 280;
|
|
546
|
+
if (w > window.innerWidth - 100) w = window.innerWidth - 100;
|
|
547
|
+
panelWidth = w;
|
|
548
|
+
panel.style.width = w + 'px';
|
|
549
|
+
toggle.style.${toggleSideKey} = (w + 14) + 'px';
|
|
550
|
+
});
|
|
551
|
+
document.addEventListener('mouseup', function() {
|
|
552
|
+
if (!resizing) return;
|
|
553
|
+
resizing = false;
|
|
554
|
+
handle.style.background = 'transparent';
|
|
555
|
+
iframe.style.pointerEvents = '';
|
|
556
|
+
try { sessionStorage.setItem(PANEL_WIDTH_KEY, String(panelWidth)); } catch(e) {}
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
panel.appendChild(handle);
|
|
526
560
|
panel.appendChild(iframe);
|
|
527
561
|
document.body.appendChild(panel);
|
|
528
562
|
|
|
@@ -547,7 +581,7 @@ function buildClientScript(opts) {
|
|
|
547
581
|
function setPanelOpen(open) {
|
|
548
582
|
panel.style.display = open ? 'block' : 'none';
|
|
549
583
|
toggle.innerHTML = open ? 'close' : dotHtml() + 'via';
|
|
550
|
-
toggle.style.${toggleSideKey} = open ? '
|
|
584
|
+
toggle.style.${toggleSideKey} = open ? (panelWidth + 14) + 'px' : '${toggleClosedVal}';
|
|
551
585
|
toggle.style.${toggleVerticalKey} = open ? '${pos.includes("top") ? "16" : "11"}px' : '12px';
|
|
552
586
|
toggle.style.borderColor = open ? '#71717a' : '#3f3f46';
|
|
553
587
|
toggle.style.color = open ? '#a1a1aa' : '#a1a1aa';
|