viagen 0.0.55 → 0.0.57
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 +19 -0
- package/dist/cli.js +86 -88
- package/dist/index.d.ts +3 -0
- package/dist/index.js +31 -27
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -86,10 +86,29 @@ viagen({
|
|
|
86
86
|
sandboxFiles: [...], // copy files manually into sandbox
|
|
87
87
|
systemPrompt: '...', // custom system prompt (see below)
|
|
88
88
|
editable: ['src','conf'], // files/dirs editable in the UI
|
|
89
|
+
mcpServers: { ... }, // additional MCP servers for Claude
|
|
89
90
|
})
|
|
90
91
|
```
|
|
91
92
|
|
|
92
93
|
|
|
94
|
+
### Custom MCP Servers
|
|
95
|
+
|
|
96
|
+
Pass additional [MCP server](https://modelcontextprotocol.io) configurations to give Claude access to custom tools:
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
viagen({
|
|
100
|
+
mcpServers: {
|
|
101
|
+
'my-db': {
|
|
102
|
+
command: 'npx',
|
|
103
|
+
args: ['-y', '@my-org/db-mcp-server'],
|
|
104
|
+
env: { DATABASE_URL: process.env.DATABASE_URL },
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
})
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
These are merged with viagen's built-in platform tools (when connected). User-provided servers take precedence if names collide.
|
|
111
|
+
|
|
93
112
|
### Editable Files
|
|
94
113
|
|
|
95
114
|
Add a file editor panel to the chat UI:
|
package/dist/cli.js
CHANGED
|
@@ -1144,7 +1144,7 @@ async function sandbox(args, options) {
|
|
|
1144
1144
|
}
|
|
1145
1145
|
}
|
|
1146
1146
|
var SYNC_DENY_KEYS = /* @__PURE__ */ new Set([
|
|
1147
|
-
"
|
|
1147
|
+
"VIAGEN_ENVIRONMENT_ID",
|
|
1148
1148
|
"VIAGEN_PLATFORM_URL",
|
|
1149
1149
|
"INFISICAL_CLIENT_ID",
|
|
1150
1150
|
"INFISICAL_CLIENT_SECRET",
|
|
@@ -1165,45 +1165,45 @@ async function sync() {
|
|
|
1165
1165
|
const env = loadDotenv(cwd);
|
|
1166
1166
|
console.log("viagen sync");
|
|
1167
1167
|
console.log("");
|
|
1168
|
-
let
|
|
1169
|
-
let
|
|
1170
|
-
if (
|
|
1168
|
+
let environmentId = env["VIAGEN_ENVIRONMENT_ID"];
|
|
1169
|
+
let environmentName;
|
|
1170
|
+
if (environmentId) {
|
|
1171
1171
|
try {
|
|
1172
|
-
const existing = await client.
|
|
1173
|
-
|
|
1174
|
-
console.log(`
|
|
1172
|
+
const existing = await client.environments.get(environmentId);
|
|
1173
|
+
environmentName = existing.name;
|
|
1174
|
+
console.log(`Environment: ${environmentName}`);
|
|
1175
1175
|
} catch {
|
|
1176
|
-
console.log("Previously synced
|
|
1176
|
+
console.log("Previously synced environment not found. Choose an environment:");
|
|
1177
1177
|
console.log("");
|
|
1178
|
-
|
|
1178
|
+
environmentId = void 0;
|
|
1179
1179
|
}
|
|
1180
1180
|
}
|
|
1181
|
-
if (!
|
|
1182
|
-
const
|
|
1183
|
-
if (
|
|
1184
|
-
console.log("Your
|
|
1181
|
+
if (!environmentId) {
|
|
1182
|
+
const environments2 = await client.environments.list();
|
|
1183
|
+
if (environments2.length > 0) {
|
|
1184
|
+
console.log("Your environments:");
|
|
1185
1185
|
console.log("");
|
|
1186
|
-
for (let i = 0; i <
|
|
1187
|
-
const repo =
|
|
1188
|
-
console.log(` ${i + 1}) ${
|
|
1186
|
+
for (let i = 0; i < environments2.length; i++) {
|
|
1187
|
+
const repo = environments2[i].githubRepo ? ` (${environments2[i].githubRepo})` : "";
|
|
1188
|
+
console.log(` ${i + 1}) ${environments2[i].name}${repo}`);
|
|
1189
1189
|
}
|
|
1190
|
-
console.log(` ${
|
|
1190
|
+
console.log(` ${environments2.length + 1}) Create new environment`);
|
|
1191
1191
|
console.log("");
|
|
1192
1192
|
const choice = await promptUser("Choose: ");
|
|
1193
1193
|
const idx = parseInt(choice, 10) - 1;
|
|
1194
|
-
if (idx >= 0 && idx <
|
|
1195
|
-
|
|
1196
|
-
|
|
1194
|
+
if (idx >= 0 && idx < environments2.length) {
|
|
1195
|
+
environmentId = environments2[idx].id;
|
|
1196
|
+
environmentName = environments2[idx].name;
|
|
1197
1197
|
} else {
|
|
1198
|
-
|
|
1199
|
-
if (!
|
|
1198
|
+
environmentName = await promptUser("Environment name: ");
|
|
1199
|
+
if (!environmentName) {
|
|
1200
1200
|
console.log("Cancelled.");
|
|
1201
1201
|
return;
|
|
1202
1202
|
}
|
|
1203
1203
|
}
|
|
1204
1204
|
} else {
|
|
1205
|
-
|
|
1206
|
-
if (!
|
|
1205
|
+
environmentName = await promptUser("Environment name: ");
|
|
1206
|
+
if (!environmentName) {
|
|
1207
1207
|
console.log("Cancelled.");
|
|
1208
1208
|
return;
|
|
1209
1209
|
}
|
|
@@ -1249,23 +1249,21 @@ async function sync() {
|
|
|
1249
1249
|
const gitInfo = getGitInfo(cwd);
|
|
1250
1250
|
const gitRemote = env["GIT_REMOTE_URL"] || gitInfo?.remoteUrl;
|
|
1251
1251
|
const githubRepo = gitRemote ? repoNwo(gitRemote) : void 0;
|
|
1252
|
-
const gitBranch = env["GIT_BRANCH"] || gitInfo?.branch;
|
|
1253
1252
|
console.log("");
|
|
1254
1253
|
console.log("Syncing...");
|
|
1255
1254
|
const vercelProjectId = env["VERCEL_PROJECT_ID"];
|
|
1256
1255
|
const vercelOrgId = env["VERCEL_ORG_ID"];
|
|
1257
1256
|
const syncInput = {
|
|
1258
|
-
...
|
|
1259
|
-
name:
|
|
1257
|
+
...environmentId ? { id: environmentId } : {},
|
|
1258
|
+
name: environmentName,
|
|
1260
1259
|
...githubRepo ? { githubRepo } : {},
|
|
1261
|
-
...gitBranch ? { gitBranch } : {},
|
|
1262
1260
|
...vercelProjectId ? { vercelProjectId } : {},
|
|
1263
1261
|
...vercelOrgId ? { vercelOrgId } : {},
|
|
1264
1262
|
secrets
|
|
1265
1263
|
};
|
|
1266
1264
|
let result;
|
|
1267
1265
|
try {
|
|
1268
|
-
result = await client.
|
|
1266
|
+
result = await client.environments.sync(syncInput);
|
|
1269
1267
|
} catch (err) {
|
|
1270
1268
|
const logDir = join2(cwd, ".viagen");
|
|
1271
1269
|
const logFile = join2(logDir, "sync-error.log");
|
|
@@ -1288,11 +1286,11 @@ async function sync() {
|
|
|
1288
1286
|
console.error(` ${logFile}`);
|
|
1289
1287
|
process.exit(1);
|
|
1290
1288
|
}
|
|
1291
|
-
if (!env["
|
|
1292
|
-
writeEnvVars(cwd, {
|
|
1289
|
+
if (!env["VIAGEN_ENVIRONMENT_ID"]) {
|
|
1290
|
+
writeEnvVars(cwd, { VIAGEN_ENVIRONMENT_ID: result.app.id });
|
|
1293
1291
|
}
|
|
1294
1292
|
console.log(
|
|
1295
|
-
`Synced "${result.
|
|
1293
|
+
`Synced "${result.app.name}" \u2014 ${result.secrets.stored} secrets stored.`
|
|
1296
1294
|
);
|
|
1297
1295
|
if (result.secrets.failed && result.secrets.failed.length > 0) {
|
|
1298
1296
|
console.log(` Failed (${result.secrets.failed.length}): ${result.secrets.failed.join(", ")}`);
|
|
@@ -1389,42 +1387,42 @@ async function requireClient() {
|
|
|
1389
1387
|
}
|
|
1390
1388
|
return createViagen({ baseUrl: creds.baseUrl, token: creds.token, orgId: creds.orgId });
|
|
1391
1389
|
}
|
|
1392
|
-
async function
|
|
1390
|
+
async function requireEnvironmentId(client) {
|
|
1393
1391
|
const cwd = process.cwd();
|
|
1394
1392
|
const env = loadDotenv(cwd);
|
|
1395
|
-
let
|
|
1396
|
-
if (
|
|
1393
|
+
let environmentId = env["VIAGEN_ENVIRONMENT_ID"];
|
|
1394
|
+
if (environmentId) {
|
|
1397
1395
|
try {
|
|
1398
|
-
await client.
|
|
1399
|
-
return
|
|
1396
|
+
await client.environments.get(environmentId);
|
|
1397
|
+
return environmentId;
|
|
1400
1398
|
} catch {
|
|
1401
|
-
console.log("
|
|
1399
|
+
console.log("Environment from .env not found. Choose an environment:");
|
|
1402
1400
|
console.log("");
|
|
1403
|
-
|
|
1401
|
+
environmentId = void 0;
|
|
1404
1402
|
}
|
|
1405
1403
|
}
|
|
1406
|
-
const
|
|
1407
|
-
if (
|
|
1408
|
-
console.error("No
|
|
1404
|
+
const environments2 = await client.environments.list();
|
|
1405
|
+
if (environments2.length === 0) {
|
|
1406
|
+
console.error("No environments found. Create one with `viagen environments create <name>` or `viagen sync`.");
|
|
1409
1407
|
process.exit(1);
|
|
1410
1408
|
}
|
|
1411
|
-
if (
|
|
1412
|
-
return
|
|
1409
|
+
if (environments2.length === 1) {
|
|
1410
|
+
return environments2[0].id;
|
|
1413
1411
|
}
|
|
1414
|
-
console.log("Select
|
|
1412
|
+
console.log("Select an environment:");
|
|
1415
1413
|
console.log("");
|
|
1416
|
-
for (let i = 0; i <
|
|
1417
|
-
const repo =
|
|
1418
|
-
console.log(` ${i + 1}) ${
|
|
1414
|
+
for (let i = 0; i < environments2.length; i++) {
|
|
1415
|
+
const repo = environments2[i].githubRepo ? ` (${environments2[i].githubRepo})` : "";
|
|
1416
|
+
console.log(` ${i + 1}) ${environments2[i].name}${repo}`);
|
|
1419
1417
|
}
|
|
1420
1418
|
console.log("");
|
|
1421
1419
|
const choice = await promptUser("Choose: ");
|
|
1422
1420
|
const idx = parseInt(choice, 10) - 1;
|
|
1423
|
-
if (idx < 0 || idx >=
|
|
1421
|
+
if (idx < 0 || idx >= environments2.length) {
|
|
1424
1422
|
console.error("Invalid selection.");
|
|
1425
1423
|
process.exit(1);
|
|
1426
1424
|
}
|
|
1427
|
-
return
|
|
1425
|
+
return environments2[idx].id;
|
|
1428
1426
|
}
|
|
1429
1427
|
async function teams() {
|
|
1430
1428
|
const client = await requireClient();
|
|
@@ -1490,56 +1488,56 @@ async function orgs(args) {
|
|
|
1490
1488
|
console.log(` ${m.name}${role}`);
|
|
1491
1489
|
}
|
|
1492
1490
|
}
|
|
1493
|
-
async function
|
|
1491
|
+
async function environments(args) {
|
|
1494
1492
|
const sub = args[0];
|
|
1495
1493
|
if (sub === "create") {
|
|
1496
1494
|
const name = args.slice(1).join(" ");
|
|
1497
1495
|
if (!name) {
|
|
1498
|
-
console.error("Usage: viagen
|
|
1496
|
+
console.error("Usage: viagen environments create <name>");
|
|
1499
1497
|
process.exit(1);
|
|
1500
1498
|
}
|
|
1501
1499
|
const client2 = await requireClient();
|
|
1502
|
-
const
|
|
1503
|
-
console.log(`Created
|
|
1500
|
+
const environment = await client2.environments.create({ name });
|
|
1501
|
+
console.log(`Created environment "${environment.name}" (${environment.id})`);
|
|
1504
1502
|
return;
|
|
1505
1503
|
}
|
|
1506
1504
|
if (sub === "get") {
|
|
1507
1505
|
const id = args[1];
|
|
1508
1506
|
if (!id) {
|
|
1509
|
-
console.error("Usage: viagen
|
|
1507
|
+
console.error("Usage: viagen environments get <id>");
|
|
1510
1508
|
process.exit(1);
|
|
1511
1509
|
}
|
|
1512
1510
|
const client2 = await requireClient();
|
|
1513
|
-
const
|
|
1514
|
-
console.log(` Name: ${
|
|
1515
|
-
console.log(` ID: ${
|
|
1516
|
-
if (
|
|
1517
|
-
if (
|
|
1518
|
-
console.log(` Created: ${
|
|
1511
|
+
const environment = await client2.environments.get(id);
|
|
1512
|
+
console.log(` Name: ${environment.name}`);
|
|
1513
|
+
console.log(` ID: ${environment.id}`);
|
|
1514
|
+
if (environment.githubRepo) console.log(` GitHub: ${environment.githubRepo}`);
|
|
1515
|
+
if (environment.templateId) console.log(` Template: ${environment.templateId}`);
|
|
1516
|
+
console.log(` Created: ${environment.createdAt}`);
|
|
1519
1517
|
return;
|
|
1520
1518
|
}
|
|
1521
1519
|
if (sub === "delete") {
|
|
1522
1520
|
const id = args[1];
|
|
1523
1521
|
if (!id) {
|
|
1524
|
-
console.error("Usage: viagen
|
|
1522
|
+
console.error("Usage: viagen environments delete <id>");
|
|
1525
1523
|
process.exit(1);
|
|
1526
1524
|
}
|
|
1527
|
-
const answer = await promptUser(`Delete
|
|
1525
|
+
const answer = await promptUser(`Delete environment ${id}? [y/n]: `);
|
|
1528
1526
|
if (answer !== "y" && answer !== "yes") return;
|
|
1529
1527
|
const client2 = await requireClient();
|
|
1530
|
-
await client2.
|
|
1531
|
-
console.log("
|
|
1528
|
+
await client2.environments.delete(id);
|
|
1529
|
+
console.log("Environment deleted.");
|
|
1532
1530
|
return;
|
|
1533
1531
|
}
|
|
1534
1532
|
const client = await requireClient();
|
|
1535
|
-
const list = await client.
|
|
1533
|
+
const list = await client.environments.list() ?? [];
|
|
1536
1534
|
if (list.length === 0) {
|
|
1537
|
-
console.log("No
|
|
1535
|
+
console.log("No environments. Create one with `viagen environments create <name>`.");
|
|
1538
1536
|
return;
|
|
1539
1537
|
}
|
|
1540
|
-
for (const
|
|
1541
|
-
const repo =
|
|
1542
|
-
console.log(` ${
|
|
1538
|
+
for (const e of list) {
|
|
1539
|
+
const repo = e.githubRepo ? ` (${e.githubRepo})` : "";
|
|
1540
|
+
console.log(` ${e.name}${repo} ${e.id}`);
|
|
1543
1541
|
}
|
|
1544
1542
|
}
|
|
1545
1543
|
function formatTaskStatus(status) {
|
|
@@ -1554,9 +1552,9 @@ function formatTaskStatus(status) {
|
|
|
1554
1552
|
}
|
|
1555
1553
|
async function tasksList(args) {
|
|
1556
1554
|
const client = await requireClient();
|
|
1557
|
-
const
|
|
1555
|
+
const environmentId = await requireEnvironmentId(client);
|
|
1558
1556
|
const status = parseFlag(args, "--status") || parseFlag(args, "-s");
|
|
1559
|
-
const list = await client.tasks.list(
|
|
1557
|
+
const list = await client.tasks.list(environmentId, status);
|
|
1560
1558
|
if (list.length === 0) {
|
|
1561
1559
|
console.log(
|
|
1562
1560
|
status ? `No tasks with status "${status}".` : "No tasks. Create one with `viagen tasks create <prompt>`."
|
|
@@ -1602,11 +1600,11 @@ async function tasksCreate(args) {
|
|
|
1602
1600
|
}
|
|
1603
1601
|
}
|
|
1604
1602
|
const client = await requireClient();
|
|
1605
|
-
const
|
|
1603
|
+
const environmentId = await requireEnvironmentId(client);
|
|
1606
1604
|
const input = { prompt };
|
|
1607
1605
|
if (branch) input.branch = branch;
|
|
1608
1606
|
if (type) input.type = type;
|
|
1609
|
-
const task = await client.tasks.create(
|
|
1607
|
+
const task = await client.tasks.create(environmentId, input);
|
|
1610
1608
|
console.log(`Task created: ${task.id}`);
|
|
1611
1609
|
console.log(` Prompt: ${task.prompt}`);
|
|
1612
1610
|
console.log(` Type: ${task.type}`);
|
|
@@ -1622,8 +1620,8 @@ async function tasksGet(args) {
|
|
|
1622
1620
|
process.exit(1);
|
|
1623
1621
|
}
|
|
1624
1622
|
const client = await requireClient();
|
|
1625
|
-
const
|
|
1626
|
-
const task = await client.tasks.get(
|
|
1623
|
+
const environmentId = await requireEnvironmentId(client);
|
|
1624
|
+
const task = await client.tasks.get(environmentId, taskId);
|
|
1627
1625
|
console.log(` ID: ${task.id}`);
|
|
1628
1626
|
console.log(` Type: ${task.type}`);
|
|
1629
1627
|
console.log(` Status: ${formatTaskStatus(task.status)}`);
|
|
@@ -1654,13 +1652,13 @@ async function tasksRun(args) {
|
|
|
1654
1652
|
process.exit(1);
|
|
1655
1653
|
}
|
|
1656
1654
|
const client = await requireClient();
|
|
1657
|
-
const
|
|
1658
|
-
const task = await client.tasks.get(
|
|
1655
|
+
const environmentId = await requireEnvironmentId(client);
|
|
1656
|
+
const task = await client.tasks.get(environmentId, taskId);
|
|
1659
1657
|
console.log(`Running task: ${task.id}`);
|
|
1660
1658
|
console.log(` Prompt: ${task.prompt}`);
|
|
1661
1659
|
console.log(` Branch: ${task.branch}`);
|
|
1662
1660
|
console.log("");
|
|
1663
|
-
await client.tasks.update(
|
|
1661
|
+
await client.tasks.update(environmentId, taskId, { status: "running" });
|
|
1664
1662
|
const sandboxArgs = [];
|
|
1665
1663
|
if (task.branch) {
|
|
1666
1664
|
sandboxArgs.push("--branch", task.branch);
|
|
@@ -1674,12 +1672,12 @@ async function tasksRun(args) {
|
|
|
1674
1672
|
promptOverride: task.prompt,
|
|
1675
1673
|
extraEnvVars: {
|
|
1676
1674
|
VIAGEN_TASK_ID: task.id,
|
|
1677
|
-
|
|
1675
|
+
VIAGEN_ENVIRONMENT_ID: environmentId
|
|
1678
1676
|
}
|
|
1679
1677
|
});
|
|
1680
1678
|
} catch (err) {
|
|
1681
1679
|
console.error(`Sandbox deploy failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1682
|
-
await client.tasks.update(
|
|
1680
|
+
await client.tasks.update(environmentId, taskId, { status: "ready" }).catch(() => {
|
|
1683
1681
|
});
|
|
1684
1682
|
process.exit(1);
|
|
1685
1683
|
}
|
|
@@ -1714,11 +1712,11 @@ function help() {
|
|
|
1714
1712
|
console.log(" orgs List your organizations");
|
|
1715
1713
|
console.log(" orgs create <name> Create a new organization");
|
|
1716
1714
|
console.log(" orgs invite <email> Invite a member to the org");
|
|
1717
|
-
console.log("
|
|
1718
|
-
console.log("
|
|
1719
|
-
console.log("
|
|
1720
|
-
console.log("
|
|
1721
|
-
console.log(" tasks List tasks for current
|
|
1715
|
+
console.log(" environments List environments in current org");
|
|
1716
|
+
console.log(" environments create <name> Create a new environment");
|
|
1717
|
+
console.log(" environments get <id> Show environment details");
|
|
1718
|
+
console.log(" environments delete <id> Delete an environment");
|
|
1719
|
+
console.log(" tasks List tasks for current environment");
|
|
1722
1720
|
console.log(" tasks create <prompt> Create a new task");
|
|
1723
1721
|
console.log(" tasks get <id> Show task details");
|
|
1724
1722
|
console.log(" tasks run <id> Run a task in a sandbox");
|
|
@@ -1797,8 +1795,8 @@ async function main() {
|
|
|
1797
1795
|
await teams();
|
|
1798
1796
|
} else if (command === "orgs") {
|
|
1799
1797
|
await orgs(args.slice(1));
|
|
1800
|
-
} else if (command === "
|
|
1801
|
-
await
|
|
1798
|
+
} else if (command === "environments") {
|
|
1799
|
+
await environments(args.slice(1));
|
|
1802
1800
|
} else if (command === "tasks") {
|
|
1803
1801
|
await tasks(args.slice(1));
|
|
1804
1802
|
} else if (command === "dev") {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Plugin } from 'vite';
|
|
2
|
+
import { McpServerConfig } from '@anthropic-ai/claude-agent-sdk';
|
|
2
3
|
|
|
3
4
|
declare const DEFAULT_SYSTEM_PROMPT = "\n You are embedded in a Vite dev server as the \"viagen\" plugin.\n Your job is to help build and modify the app. Files you edit will trigger Vite HMR automatically.\n You can read .viagen/server.log to check recent Vite dev server output (compile errors, HMR updates, warnings).\n Be concise.\n\n You have agent-browser available for interacting with the running app in a real browser.\n Use it to visually verify your changes, test interactions, and catch UI issues.\n Key commands:\n agent-browser open <url> \u2014 open a page\n agent-browser snapshot \u2014 get accessibility tree with element refs (@e1, @e2, etc.)\n agent-browser click @e<N> \u2014 click an element by ref\n agent-browser fill @e<N> \"value\" \u2014 fill an input\n agent-browser screenshot <file> \u2014 capture a screenshot (you can view the image)\n agent-browser diff snapshot --baseline <file> \u2014 compare page state before/after\n agent-browser close \u2014 close the browser\n After making changes, consider using agent-browser to verify the result visually.\n";
|
|
4
5
|
|
|
@@ -97,6 +98,8 @@ interface ViagenOptions {
|
|
|
97
98
|
* @example ['src/components', '.env', 'vite.config.ts']
|
|
98
99
|
*/
|
|
99
100
|
editable?: string[];
|
|
101
|
+
/** Additional MCP servers to make available to Claude. Merged with built-in viagen tools. */
|
|
102
|
+
mcpServers?: Record<string, McpServerConfig>;
|
|
100
103
|
/** Enable verbose debug logging. Also enabled by VIAGEN_DEBUG=1 in .env. */
|
|
101
104
|
debug?: boolean;
|
|
102
105
|
}
|
package/dist/index.js
CHANGED
|
@@ -100,17 +100,17 @@ function registerHealthRoutes(server, env, errorRef) {
|
|
|
100
100
|
} : null;
|
|
101
101
|
const prompt = env["VIAGEN_PROMPT"] || null;
|
|
102
102
|
const taskId = env["VIAGEN_TASK_ID"] || null;
|
|
103
|
-
const
|
|
103
|
+
const environmentId = env["VIAGEN_ENVIRONMENT_ID"] || null;
|
|
104
104
|
res.setHeader("Content-Type", "application/json");
|
|
105
105
|
if (configured) {
|
|
106
|
-
res.end(JSON.stringify({ status: "ok", configured: true, git, vercel, branch, session, prompt, taskId,
|
|
106
|
+
res.end(JSON.stringify({ status: "ok", configured: true, git, vercel, branch, session, prompt, taskId, environmentId, missing }));
|
|
107
107
|
} else {
|
|
108
108
|
res.end(
|
|
109
|
-
JSON.stringify({ status: "error", configured: false, git, vercel, branch, session, prompt, taskId,
|
|
109
|
+
JSON.stringify({ status: "error", configured: false, git, vercel, branch, session, prompt, taskId, environmentId, missing })
|
|
110
110
|
);
|
|
111
111
|
}
|
|
112
112
|
});
|
|
113
|
-
const currentVersion = true ? "0.0.
|
|
113
|
+
const currentVersion = true ? "0.0.57" : "0.0.0";
|
|
114
114
|
debug("health", `version resolved: ${currentVersion}`);
|
|
115
115
|
let versionCache = null;
|
|
116
116
|
server.middlewares.use("/via/version", (_req, res) => {
|
|
@@ -770,10 +770,10 @@ data: ${JSON.stringify(doneData)}
|
|
|
770
770
|
`);
|
|
771
771
|
res.end();
|
|
772
772
|
}
|
|
773
|
-
if (opts.viagenClient && opts.
|
|
773
|
+
if (opts.viagenClient && opts.environmentId) {
|
|
774
774
|
const taskId = opts.env["VIAGEN_TASK_ID"];
|
|
775
775
|
if (taskId && (event.inputTokens || event.outputTokens)) {
|
|
776
|
-
opts.viagenClient.tasks.update(opts.
|
|
776
|
+
opts.viagenClient.tasks.update(opts.environmentId, taskId, {
|
|
777
777
|
...event.inputTokens != null && { inputTokens: event.inputTokens },
|
|
778
778
|
...event.outputTokens != null && { outputTokens: event.outputTokens }
|
|
779
779
|
}).catch((err) => {
|
|
@@ -3798,7 +3798,7 @@ function buildUiHtml(opts) {
|
|
|
3798
3798
|
|
|
3799
3799
|
// Store task context for history rendering
|
|
3800
3800
|
healthTaskId = data.taskId || null;
|
|
3801
|
-
healthProjectId = data.
|
|
3801
|
+
healthProjectId = data.environmentId || null;
|
|
3802
3802
|
|
|
3803
3803
|
// Load chat history from server (source of truth)
|
|
3804
3804
|
await loadHistory();
|
|
@@ -3892,7 +3892,7 @@ function buildUiHtml(opts) {
|
|
|
3892
3892
|
if (data.prompt && data.configured && chatLog.length === 0) {
|
|
3893
3893
|
if (data.taskId) {
|
|
3894
3894
|
// Task mode: show link instead of raw prompt
|
|
3895
|
-
var taskUrl = 'https://app.viagen.dev/
|
|
3895
|
+
var taskUrl = 'https://app.viagen.dev/environments/' + data.environmentId + '/tasks/' + data.taskId;
|
|
3896
3896
|
var div = document.createElement('div');
|
|
3897
3897
|
div.className = 'msg msg-user';
|
|
3898
3898
|
div.innerHTML = '<span class="label">Task</span><span class="text">Working on <a href="' + escapeHtml(taskUrl) + '" target="_blank" style="color:#2563eb;text-decoration:underline;">Via Task</a></span>';
|
|
@@ -18657,7 +18657,7 @@ import {
|
|
|
18657
18657
|
tool
|
|
18658
18658
|
} from "@anthropic-ai/claude-agent-sdk";
|
|
18659
18659
|
function createViagenTools(config2) {
|
|
18660
|
-
const { client,
|
|
18660
|
+
const { client, environmentId } = config2;
|
|
18661
18661
|
const taskId = process.env["VIAGEN_TASK_ID"];
|
|
18662
18662
|
const tools = [
|
|
18663
18663
|
tool(
|
|
@@ -18682,7 +18682,7 @@ function createViagenTools(config2) {
|
|
|
18682
18682
|
}
|
|
18683
18683
|
const internalStatus = args.status === "review" ? "validating" : args.status === "completed" ? "completed" : args.status;
|
|
18684
18684
|
try {
|
|
18685
|
-
await client.tasks.update(
|
|
18685
|
+
await client.tasks.update(environmentId, id, {
|
|
18686
18686
|
...internalStatus && { status: internalStatus },
|
|
18687
18687
|
...args.prUrl && { prUrl: args.prUrl },
|
|
18688
18688
|
result: args.result,
|
|
@@ -18703,12 +18703,12 @@ function createViagenTools(config2) {
|
|
|
18703
18703
|
),
|
|
18704
18704
|
tool(
|
|
18705
18705
|
"viagen_list_tasks",
|
|
18706
|
-
"List tasks in the current
|
|
18706
|
+
"List tasks in the current environment. Optionally filter by status.",
|
|
18707
18707
|
{
|
|
18708
18708
|
status: external_exports.enum(["ready", "running", "validating", "completed", "timed_out"]).optional().describe("Filter tasks by status.")
|
|
18709
18709
|
},
|
|
18710
18710
|
async (args) => {
|
|
18711
|
-
const tasks = await client.tasks.list(
|
|
18711
|
+
const tasks = await client.tasks.list(environmentId, args.status);
|
|
18712
18712
|
return {
|
|
18713
18713
|
content: [
|
|
18714
18714
|
{
|
|
@@ -18726,7 +18726,7 @@ function createViagenTools(config2) {
|
|
|
18726
18726
|
taskId: external_exports.string().describe("The task ID to retrieve.")
|
|
18727
18727
|
},
|
|
18728
18728
|
async (args) => {
|
|
18729
|
-
const task = await client.tasks.get(
|
|
18729
|
+
const task = await client.tasks.get(environmentId, args.taskId);
|
|
18730
18730
|
return {
|
|
18731
18731
|
content: [
|
|
18732
18732
|
{
|
|
@@ -18739,14 +18739,14 @@ function createViagenTools(config2) {
|
|
|
18739
18739
|
),
|
|
18740
18740
|
tool(
|
|
18741
18741
|
"viagen_create_task",
|
|
18742
|
-
"Create a new task in the current
|
|
18742
|
+
"Create a new task in the current environment. Use this to create follow-up work.",
|
|
18743
18743
|
{
|
|
18744
18744
|
prompt: external_exports.string().describe("The task prompt / instructions."),
|
|
18745
18745
|
branch: external_exports.string().optional().describe("Git branch name for the task."),
|
|
18746
18746
|
type: external_exports.enum(["task", "plan"]).optional().describe("Task type: 'task' for code changes, 'plan' for implementation plans.")
|
|
18747
18747
|
},
|
|
18748
18748
|
async (args) => {
|
|
18749
|
-
const task = await client.tasks.create(
|
|
18749
|
+
const task = await client.tasks.create(environmentId, {
|
|
18750
18750
|
prompt: args.prompt,
|
|
18751
18751
|
branch: args.branch,
|
|
18752
18752
|
type: args.type
|
|
@@ -18793,12 +18793,12 @@ Constraints:
|
|
|
18793
18793
|
`;
|
|
18794
18794
|
var TASK_TOOLS_PROMPT = `
|
|
18795
18795
|
You have access to viagen platform tools for task management:
|
|
18796
|
-
- viagen_list_tasks: List tasks in this
|
|
18796
|
+
- viagen_list_tasks: List tasks in this environment (optionally filter by status)
|
|
18797
18797
|
- viagen_get_task: Get full details of a specific task
|
|
18798
18798
|
- viagen_create_task: Create follow-up tasks for work you identify
|
|
18799
18799
|
- viagen_update_task: Update a task's status ('review' or 'completed'). Accepts an optional taskId \u2014 defaults to the current task if one is set.
|
|
18800
18800
|
|
|
18801
|
-
Use these to understand
|
|
18801
|
+
Use these to understand environment context and create follow-up work when appropriate.
|
|
18802
18802
|
`;
|
|
18803
18803
|
|
|
18804
18804
|
// src/index.ts
|
|
@@ -19182,7 +19182,7 @@ ${payload.err.frame || ""}`
|
|
|
19182
19182
|
}
|
|
19183
19183
|
const platformToken = env["VIAGEN_USER_TOKEN"] || env["VIAGEN_AUTH_TOKEN"];
|
|
19184
19184
|
const platformUrl = env["VIAGEN_PLATFORM_URL"] || "https://app.viagen.dev";
|
|
19185
|
-
const
|
|
19185
|
+
const environmentId = env["VIAGEN_ENVIRONMENT_ID"];
|
|
19186
19186
|
let viagenClient = null;
|
|
19187
19187
|
if (platformToken) {
|
|
19188
19188
|
viagenClient = createViagen({ token: platformToken, baseUrl: platformUrl });
|
|
@@ -19222,9 +19222,9 @@ ${payload.err.frame || ""}`
|
|
|
19222
19222
|
res.end(JSON.stringify({ error: "Method not allowed" }));
|
|
19223
19223
|
return;
|
|
19224
19224
|
}
|
|
19225
|
-
if (!viagenClient || !
|
|
19225
|
+
if (!viagenClient || !environmentId) {
|
|
19226
19226
|
res.writeHead(503, { "Content-Type": "application/json" });
|
|
19227
|
-
res.end(JSON.stringify({ error: "Task creation not configured: missing platform credentials or
|
|
19227
|
+
res.end(JSON.stringify({ error: "Task creation not configured: missing platform credentials or VIAGEN_ENVIRONMENT_ID" }));
|
|
19228
19228
|
return;
|
|
19229
19229
|
}
|
|
19230
19230
|
let body = "";
|
|
@@ -19246,7 +19246,7 @@ Page URL: ${pageUrl}`);
|
|
|
19246
19246
|
if (screenshot) parts.push("\n[Screenshot attached]");
|
|
19247
19247
|
parts.push("\n\n[Submitted via viagen preview feedback]");
|
|
19248
19248
|
const fullPrompt = parts.join("");
|
|
19249
|
-
const task = await viagenClient.tasks.create(
|
|
19249
|
+
const task = await viagenClient.tasks.create(environmentId, { prompt: fullPrompt, type: "task" });
|
|
19250
19250
|
if (screenshot && task.id) {
|
|
19251
19251
|
try {
|
|
19252
19252
|
const [header, b64] = screenshot.split(",");
|
|
@@ -19254,7 +19254,7 @@ Page URL: ${pageUrl}`);
|
|
|
19254
19254
|
const binary = Buffer.from(b64, "base64");
|
|
19255
19255
|
const blob = new Blob([binary], { type: mime });
|
|
19256
19256
|
const ext = mime === "image/png" ? "png" : "jpeg";
|
|
19257
|
-
await viagenClient.tasks.addAttachment(
|
|
19257
|
+
await viagenClient.tasks.addAttachment(environmentId, task.id, blob, `screenshot.${ext}`);
|
|
19258
19258
|
debug("preview", `screenshot attached to task ${task.id}`);
|
|
19259
19259
|
} catch (attachErr) {
|
|
19260
19260
|
debug("preview", `screenshot attachment failed (non-fatal): ${attachErr}`);
|
|
@@ -19277,15 +19277,19 @@ Page URL: ${pageUrl}`);
|
|
|
19277
19277
|
const resolvedModel = env["VIAGEN_MODEL"] || opts.model;
|
|
19278
19278
|
debug("server", `creating ChatSession (model: ${resolvedModel})`);
|
|
19279
19279
|
let mcpServers;
|
|
19280
|
-
const hasPlatformContext = !!(viagenClient &&
|
|
19280
|
+
const hasPlatformContext = !!(viagenClient && environmentId);
|
|
19281
19281
|
if (hasPlatformContext) {
|
|
19282
19282
|
debug("server", "creating viagen MCP tools (platform connected)");
|
|
19283
19283
|
const viagenMcp = createViagenTools({
|
|
19284
19284
|
client: viagenClient,
|
|
19285
|
-
|
|
19285
|
+
environmentId
|
|
19286
19286
|
});
|
|
19287
19287
|
mcpServers = { [viagenMcp.name]: viagenMcp };
|
|
19288
19288
|
}
|
|
19289
|
+
if (options?.mcpServers) {
|
|
19290
|
+
mcpServers = { ...mcpServers, ...options.mcpServers };
|
|
19291
|
+
debug("server", `merged ${Object.keys(options.mcpServers).length} user MCP server(s)`);
|
|
19292
|
+
}
|
|
19289
19293
|
const isPlanMode = env["VIAGEN_TASK_TYPE"] === "plan";
|
|
19290
19294
|
let systemPrompt = options?.systemPrompt;
|
|
19291
19295
|
if (isPlanMode) {
|
|
@@ -19310,7 +19314,7 @@ Page URL: ${pageUrl}`);
|
|
|
19310
19314
|
registerChatRoutes(server, chatSession, {
|
|
19311
19315
|
env,
|
|
19312
19316
|
viagenClient: viagenClient ?? void 0,
|
|
19313
|
-
|
|
19317
|
+
environmentId
|
|
19314
19318
|
});
|
|
19315
19319
|
if (hasEditor) {
|
|
19316
19320
|
registerFileRoutes(server, {
|
|
@@ -19330,8 +19334,8 @@ Page URL: ${pageUrl}`);
|
|
|
19330
19334
|
debug("server", "auto-prompt completed");
|
|
19331
19335
|
logBuffer.push("info", `[viagen] Prompt completed`);
|
|
19332
19336
|
const currentTaskId = env["VIAGEN_TASK_ID"];
|
|
19333
|
-
if (viagenClient &&
|
|
19334
|
-
viagenClient.tasks.update(
|
|
19337
|
+
if (viagenClient && environmentId && currentTaskId && (event.inputTokens || event.outputTokens)) {
|
|
19338
|
+
viagenClient.tasks.update(environmentId, currentTaskId, {
|
|
19335
19339
|
...event.inputTokens != null && { inputTokens: event.inputTokens },
|
|
19336
19340
|
...event.outputTokens != null && { outputTokens: event.outputTokens }
|
|
19337
19341
|
}).catch((err) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "viagen",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.57",
|
|
4
4
|
"description": "Vite dev server plugin that exposes endpoints for chatting with Claude Code SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"agent-browser": "^0.20.12",
|
|
46
46
|
"lucide-react": "^0.564.0",
|
|
47
47
|
"simple-git": "^3.31.1",
|
|
48
|
-
"viagen-sdk": "^0.0
|
|
48
|
+
"viagen-sdk": "^0.1.0"
|
|
49
49
|
},
|
|
50
50
|
"license": "MIT",
|
|
51
51
|
"repository": {
|