viagen 0.0.53 → 0.0.55
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/index.d.ts +1 -1
- package/dist/index.js +433 -151
- package/package.json +3 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Plugin } from 'vite';
|
|
2
2
|
|
|
3
|
-
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";
|
|
3
|
+
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
4
|
|
|
5
5
|
interface GitInfo {
|
|
6
6
|
/** HTTPS remote URL (transformed from SSH if needed). */
|
package/dist/index.js
CHANGED
|
@@ -110,7 +110,7 @@ function registerHealthRoutes(server, env, errorRef) {
|
|
|
110
110
|
);
|
|
111
111
|
}
|
|
112
112
|
});
|
|
113
|
-
const currentVersion = true ? "0.0.
|
|
113
|
+
const currentVersion = true ? "0.0.55" : "0.0.0";
|
|
114
114
|
debug("health", `version resolved: ${currentVersion}`);
|
|
115
115
|
let versionCache = null;
|
|
116
116
|
server.middlewares.use("/via/version", (_req, res) => {
|
|
@@ -241,6 +241,18 @@ var DEFAULT_SYSTEM_PROMPT = `
|
|
|
241
241
|
Your job is to help build and modify the app. Files you edit will trigger Vite HMR automatically.
|
|
242
242
|
You can read .viagen/server.log to check recent Vite dev server output (compile errors, HMR updates, warnings).
|
|
243
243
|
Be concise.
|
|
244
|
+
|
|
245
|
+
You have agent-browser available for interacting with the running app in a real browser.
|
|
246
|
+
Use it to visually verify your changes, test interactions, and catch UI issues.
|
|
247
|
+
Key commands:
|
|
248
|
+
agent-browser open <url> \u2014 open a page
|
|
249
|
+
agent-browser snapshot \u2014 get accessibility tree with element refs (@e1, @e2, etc.)
|
|
250
|
+
agent-browser click @e<N> \u2014 click an element by ref
|
|
251
|
+
agent-browser fill @e<N> "value" \u2014 fill an input
|
|
252
|
+
agent-browser screenshot <file> \u2014 capture a screenshot (you can view the image)
|
|
253
|
+
agent-browser diff snapshot --baseline <file> \u2014 compare page state before/after
|
|
254
|
+
agent-browser close \u2014 close the browser
|
|
255
|
+
After making changes, consider using agent-browser to verify the result visually.
|
|
244
256
|
`;
|
|
245
257
|
var ChatSession = class {
|
|
246
258
|
sessionId;
|
|
@@ -758,23 +770,14 @@ data: ${JSON.stringify(doneData)}
|
|
|
758
770
|
`);
|
|
759
771
|
res.end();
|
|
760
772
|
}
|
|
761
|
-
if (opts.
|
|
773
|
+
if (opts.viagenClient && opts.projectId) {
|
|
762
774
|
const taskId = opts.env["VIAGEN_TASK_ID"];
|
|
763
|
-
if (taskId && (event.inputTokens || event.outputTokens
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
"Content-Type": "application/json",
|
|
768
|
-
Authorization: `Bearer ${opts.env["VIAGEN_AUTH_TOKEN"]}`
|
|
769
|
-
},
|
|
770
|
-
body: JSON.stringify({
|
|
771
|
-
taskId,
|
|
772
|
-
...event.inputTokens != null && { inputTokens: event.inputTokens },
|
|
773
|
-
...event.outputTokens != null && { outputTokens: event.outputTokens },
|
|
774
|
-
...event.costUsd != null && { costUsd: event.costUsd }
|
|
775
|
-
})
|
|
775
|
+
if (taskId && (event.inputTokens || event.outputTokens)) {
|
|
776
|
+
opts.viagenClient.tasks.update(opts.projectId, taskId, {
|
|
777
|
+
...event.inputTokens != null && { inputTokens: event.inputTokens },
|
|
778
|
+
...event.outputTokens != null && { outputTokens: event.outputTokens }
|
|
776
779
|
}).catch((err) => {
|
|
777
|
-
debug("chat", `usage
|
|
780
|
+
debug("chat", `usage report failed: ${err}`);
|
|
778
781
|
});
|
|
779
782
|
}
|
|
780
783
|
}
|
|
@@ -797,6 +800,213 @@ data: ${JSON.stringify(doneData)}
|
|
|
797
800
|
}
|
|
798
801
|
|
|
799
802
|
// src/overlay.ts
|
|
803
|
+
function buildPreviewScript() {
|
|
804
|
+
return (
|
|
805
|
+
/* js */
|
|
806
|
+
`
|
|
807
|
+
(function() {
|
|
808
|
+
if (document.getElementById('viagen-preview-btn')) return;
|
|
809
|
+
|
|
810
|
+
var btn = document.createElement('button');
|
|
811
|
+
btn.id = 'viagen-preview-btn';
|
|
812
|
+
btn.innerHTML = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display:inline-block;vertical-align:middle;margin-right:5px;"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path></svg><span style="vertical-align:middle;">Feedback</span>';
|
|
813
|
+
btn.style.cssText = 'position:fixed;bottom:16px;left:16px;z-index:99998;padding:8px 14px;background:#ffffff;color:#525252;border:1px solid #e5e5e5;border-radius:20px;font-size:12px;font-weight:500;font-family:Geist,-apple-system,BlinkMacSystemFont,sans-serif;cursor:pointer;letter-spacing:-0.01em;transition:border-color 0.15s,color 0.15s,box-shadow 0.15s;box-shadow:0 1px 3px rgba(0,0,0,0.08),0 1px 2px rgba(0,0,0,0.04);display:flex;align-items:center;';
|
|
814
|
+
btn.onmouseenter = function() { btn.style.borderColor = '#d4d4d4'; btn.style.color = '#171717'; btn.style.boxShadow = '0 2px 6px rgba(0,0,0,0.1),0 1px 3px rgba(0,0,0,0.06)'; };
|
|
815
|
+
btn.onmouseleave = function() { btn.style.borderColor = '#e5e5e5'; btn.style.color = '#525252'; btn.style.boxShadow = '0 1px 3px rgba(0,0,0,0.08),0 1px 2px rgba(0,0,0,0.04)'; };
|
|
816
|
+
|
|
817
|
+
btn.addEventListener('click', function() { openFeedback(); });
|
|
818
|
+
document.body.appendChild(btn);
|
|
819
|
+
|
|
820
|
+
function loadHtml2Canvas() {
|
|
821
|
+
return new Promise(function(resolve, reject) {
|
|
822
|
+
if (typeof window.html2canvas !== 'undefined') { resolve(window.html2canvas); return; }
|
|
823
|
+
var s = document.createElement('script');
|
|
824
|
+
s.src = 'https://unpkg.com/html2canvas@1.4.1/dist/html2canvas.min.js';
|
|
825
|
+
s.onload = function() { resolve(window.html2canvas); };
|
|
826
|
+
s.onerror = function() { reject(new Error('Failed to load html2canvas')); };
|
|
827
|
+
document.head.appendChild(s);
|
|
828
|
+
});
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
function openFeedback() {
|
|
832
|
+
btn.disabled = true;
|
|
833
|
+
var origHTML = btn.innerHTML;
|
|
834
|
+
btn.innerHTML = '<span style="vertical-align:middle;">Capturing\u2026</span>';
|
|
835
|
+
|
|
836
|
+
loadHtml2Canvas().then(function(h2c) {
|
|
837
|
+
return h2c(document.documentElement, {
|
|
838
|
+
useCORS: true,
|
|
839
|
+
allowTaint: true,
|
|
840
|
+
logging: false,
|
|
841
|
+
scale: Math.min(window.devicePixelRatio || 1, 2),
|
|
842
|
+
});
|
|
843
|
+
}).then(function(canvas) {
|
|
844
|
+
var dataUrl = canvas.toDataURL('image/jpeg', 0.82);
|
|
845
|
+
btn.disabled = false;
|
|
846
|
+
btn.innerHTML = origHTML;
|
|
847
|
+
showModal(dataUrl);
|
|
848
|
+
}).catch(function(e) {
|
|
849
|
+
console.warn('[viagen-preview] Screenshot failed:', e);
|
|
850
|
+
btn.disabled = false;
|
|
851
|
+
btn.innerHTML = origHTML;
|
|
852
|
+
showModal(null);
|
|
853
|
+
});
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
function showModal(screenshotDataUrl) {
|
|
857
|
+
var overlay = document.createElement('div');
|
|
858
|
+
overlay.id = 'viagen-preview-modal';
|
|
859
|
+
overlay.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.5);z-index:99999;display:flex;align-items:center;justify-content:center;font-family:Geist,-apple-system,BlinkMacSystemFont,sans-serif;';
|
|
860
|
+
|
|
861
|
+
var modal = document.createElement('div');
|
|
862
|
+
modal.style.cssText = 'background:#fff;border-radius:16px;padding:24px;max-width:560px;width:calc(100% - 32px);max-height:90vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,0.2);box-sizing:border-box;';
|
|
863
|
+
|
|
864
|
+
/* Header */
|
|
865
|
+
var header = document.createElement('div');
|
|
866
|
+
header.style.cssText = 'display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;';
|
|
867
|
+
var title = document.createElement('h2');
|
|
868
|
+
title.textContent = 'Send Feedback';
|
|
869
|
+
title.style.cssText = 'margin:0;font-size:16px;font-weight:600;color:#171717;';
|
|
870
|
+
var closeBtn = document.createElement('button');
|
|
871
|
+
closeBtn.innerHTML = '×';
|
|
872
|
+
closeBtn.style.cssText = 'background:none;border:none;font-size:22px;cursor:pointer;color:#a3a3a3;padding:0;line-height:1;transition:color 0.15s;';
|
|
873
|
+
closeBtn.onmouseenter = function() { closeBtn.style.color = '#171717'; };
|
|
874
|
+
closeBtn.onmouseleave = function() { closeBtn.style.color = '#a3a3a3'; };
|
|
875
|
+
closeBtn.onclick = function() { overlay.remove(); };
|
|
876
|
+
header.appendChild(title);
|
|
877
|
+
header.appendChild(closeBtn);
|
|
878
|
+
modal.appendChild(header);
|
|
879
|
+
|
|
880
|
+
/* Screenshot preview */
|
|
881
|
+
if (screenshotDataUrl) {
|
|
882
|
+
var imgWrap = document.createElement('div');
|
|
883
|
+
imgWrap.style.cssText = 'margin-bottom:16px;border-radius:8px;overflow:hidden;border:1px solid #e5e5e5;background:#f5f5f5;';
|
|
884
|
+
var img = document.createElement('img');
|
|
885
|
+
img.src = screenshotDataUrl;
|
|
886
|
+
img.style.cssText = 'width:100%;display:block;max-height:220px;object-fit:cover;object-position:top;';
|
|
887
|
+
imgWrap.appendChild(img);
|
|
888
|
+
modal.appendChild(imgWrap);
|
|
889
|
+
} else {
|
|
890
|
+
var pageRef = document.createElement('div');
|
|
891
|
+
pageRef.textContent = 'Page: ' + window.location.href;
|
|
892
|
+
pageRef.style.cssText = 'margin-bottom:16px;padding:10px 12px;background:#f5f5f5;border-radius:8px;font-size:12px;color:#737373;word-break:break-all;';
|
|
893
|
+
modal.appendChild(pageRef);
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
/* Textarea */
|
|
897
|
+
var label = document.createElement('label');
|
|
898
|
+
label.textContent = 'Describe your feedback';
|
|
899
|
+
label.style.cssText = 'display:block;font-size:13px;font-weight:500;color:#525252;margin-bottom:8px;';
|
|
900
|
+
modal.appendChild(label);
|
|
901
|
+
|
|
902
|
+
var textarea = document.createElement('textarea');
|
|
903
|
+
textarea.placeholder = 'e.g. The button color looks off, the layout breaks on mobile\u2026';
|
|
904
|
+
textarea.style.cssText = 'width:100%;min-height:96px;border:1px solid #e5e5e5;border-radius:8px;padding:12px;font-size:14px;font-family:inherit;resize:vertical;box-sizing:border-box;outline:none;transition:border-color 0.15s;color:#171717;';
|
|
905
|
+
textarea.onfocus = function() { textarea.style.borderColor = '#a3a3a3'; };
|
|
906
|
+
textarea.onblur = function() { textarea.style.borderColor = '#e5e5e5'; };
|
|
907
|
+
modal.appendChild(textarea);
|
|
908
|
+
|
|
909
|
+
/* Status */
|
|
910
|
+
var statusEl = document.createElement('div');
|
|
911
|
+
statusEl.style.cssText = 'margin-top:10px;font-size:13px;color:#737373;display:none;min-height:20px;';
|
|
912
|
+
modal.appendChild(statusEl);
|
|
913
|
+
|
|
914
|
+
/* Buttons */
|
|
915
|
+
var btnRow = document.createElement('div');
|
|
916
|
+
btnRow.style.cssText = 'display:flex;gap:8px;margin-top:16px;justify-content:flex-end;';
|
|
917
|
+
var cancelBtn = document.createElement('button');
|
|
918
|
+
cancelBtn.textContent = 'Cancel';
|
|
919
|
+
cancelBtn.style.cssText = 'padding:9px 16px;background:#f5f5f5;color:#525252;border:none;border-radius:8px;font-size:14px;font-weight:500;cursor:pointer;font-family:inherit;transition:background 0.15s;';
|
|
920
|
+
cancelBtn.onmouseenter = function() { cancelBtn.style.background = '#e5e5e5'; };
|
|
921
|
+
cancelBtn.onmouseleave = function() { cancelBtn.style.background = '#f5f5f5'; };
|
|
922
|
+
cancelBtn.onclick = function() { overlay.remove(); };
|
|
923
|
+
var submitBtn = document.createElement('button');
|
|
924
|
+
submitBtn.textContent = 'Create Task';
|
|
925
|
+
submitBtn.style.cssText = 'padding:9px 16px;background:#171717;color:#fff;border:none;border-radius:8px;font-size:14px;font-weight:500;cursor:pointer;font-family:inherit;transition:background 0.15s;';
|
|
926
|
+
submitBtn.onmouseenter = function() { if (!submitBtn.disabled) submitBtn.style.background = '#404040'; };
|
|
927
|
+
submitBtn.onmouseleave = function() { if (!submitBtn.disabled) submitBtn.style.background = '#171717'; };
|
|
928
|
+
|
|
929
|
+
submitBtn.addEventListener('click', function() {
|
|
930
|
+
var feedback = textarea.value.trim();
|
|
931
|
+
if (!feedback) {
|
|
932
|
+
textarea.style.borderColor = '#ef4444';
|
|
933
|
+
textarea.focus();
|
|
934
|
+
return;
|
|
935
|
+
}
|
|
936
|
+
submitBtn.disabled = true;
|
|
937
|
+
cancelBtn.disabled = true;
|
|
938
|
+
submitBtn.textContent = 'Creating\u2026';
|
|
939
|
+
submitBtn.style.opacity = '0.7';
|
|
940
|
+
statusEl.style.display = 'block';
|
|
941
|
+
statusEl.style.color = '#737373';
|
|
942
|
+
statusEl.textContent = 'Submitting your feedback\u2026';
|
|
943
|
+
|
|
944
|
+
var payload = {
|
|
945
|
+
prompt: feedback,
|
|
946
|
+
pageUrl: window.location.href,
|
|
947
|
+
screenshot: screenshotDataUrl || undefined,
|
|
948
|
+
};
|
|
949
|
+
|
|
950
|
+
fetch('/via/preview/task', {
|
|
951
|
+
method: 'POST',
|
|
952
|
+
headers: { 'Content-Type': 'application/json' },
|
|
953
|
+
body: JSON.stringify(payload),
|
|
954
|
+
}).then(function(res) {
|
|
955
|
+
if (!res.ok) {
|
|
956
|
+
return res.json().catch(function() { return {}; }).then(function(e) {
|
|
957
|
+
throw new Error(e.error || 'HTTP ' + res.status);
|
|
958
|
+
});
|
|
959
|
+
}
|
|
960
|
+
return res.json();
|
|
961
|
+
}).then(function() {
|
|
962
|
+
/* Success state */
|
|
963
|
+
modal.innerHTML = '';
|
|
964
|
+
var successDiv = document.createElement('div');
|
|
965
|
+
successDiv.style.cssText = 'text-align:center;padding:32px 24px;';
|
|
966
|
+
var check = document.createElement('div');
|
|
967
|
+
check.style.cssText = 'width:48px;height:48px;background:#22c55e;border-radius:50%;display:flex;align-items:center;justify-content:center;margin:0 auto 16px;color:#fff;font-size:22px;font-weight:700;';
|
|
968
|
+
check.textContent = '\\u2713';
|
|
969
|
+
var h3 = document.createElement('h3');
|
|
970
|
+
h3.textContent = 'Task Created!';
|
|
971
|
+
h3.style.cssText = 'margin:0 0 8px;font-size:16px;font-weight:600;color:#171717;font-family:Geist,-apple-system,BlinkMacSystemFont,sans-serif;';
|
|
972
|
+
var p = document.createElement('p');
|
|
973
|
+
p.textContent = 'Your feedback has been submitted successfully.';
|
|
974
|
+
p.style.cssText = 'margin:0;color:#737373;font-size:14px;font-family:Geist,-apple-system,BlinkMacSystemFont,sans-serif;';
|
|
975
|
+
successDiv.appendChild(check);
|
|
976
|
+
successDiv.appendChild(h3);
|
|
977
|
+
successDiv.appendChild(p);
|
|
978
|
+
modal.appendChild(successDiv);
|
|
979
|
+
setTimeout(function() { overlay.remove(); }, 2500);
|
|
980
|
+
}).catch(function(err) {
|
|
981
|
+
submitBtn.disabled = false;
|
|
982
|
+
cancelBtn.disabled = false;
|
|
983
|
+
submitBtn.textContent = 'Create Task';
|
|
984
|
+
submitBtn.style.opacity = '1';
|
|
985
|
+
statusEl.style.color = '#ef4444';
|
|
986
|
+
statusEl.textContent = 'Error: ' + (err.message || 'Failed to submit. Please try again.');
|
|
987
|
+
});
|
|
988
|
+
});
|
|
989
|
+
|
|
990
|
+
btnRow.appendChild(cancelBtn);
|
|
991
|
+
btnRow.appendChild(submitBtn);
|
|
992
|
+
modal.appendChild(btnRow);
|
|
993
|
+
overlay.appendChild(modal);
|
|
994
|
+
|
|
995
|
+
overlay.addEventListener('click', function(e) {
|
|
996
|
+
if (e.target === overlay) overlay.remove();
|
|
997
|
+
});
|
|
998
|
+
var escHandler = function(e) {
|
|
999
|
+
if (e.key === 'Escape') { overlay.remove(); document.removeEventListener('keydown', escHandler); }
|
|
1000
|
+
};
|
|
1001
|
+
document.addEventListener('keydown', escHandler);
|
|
1002
|
+
|
|
1003
|
+
document.body.appendChild(overlay);
|
|
1004
|
+
setTimeout(function() { textarea.focus(); }, 50);
|
|
1005
|
+
}
|
|
1006
|
+
})();
|
|
1007
|
+
`
|
|
1008
|
+
);
|
|
1009
|
+
}
|
|
800
1010
|
function buildClientScript(opts) {
|
|
801
1011
|
const pos = opts.position;
|
|
802
1012
|
const pw = opts.panelWidth;
|
|
@@ -4334,7 +4544,9 @@ function registerFileRoutes(server, opts) {
|
|
|
4334
4544
|
// src/inject.ts
|
|
4335
4545
|
var SCRIPT_TAG = '<script src="/via/client.js" defer></script>';
|
|
4336
4546
|
var MARKER = "viagen-toggle";
|
|
4337
|
-
|
|
4547
|
+
var PREVIEW_SCRIPT_TAG = '<script src="/via/preview.js" defer></script>';
|
|
4548
|
+
var PREVIEW_MARKER = "viagen-preview-btn";
|
|
4549
|
+
function createScriptInjectionMiddleware(scriptTag, marker) {
|
|
4338
4550
|
return function injectMiddleware(req, res, next) {
|
|
4339
4551
|
if (req.method !== "GET" && req.method !== "HEAD") {
|
|
4340
4552
|
return next();
|
|
@@ -4359,7 +4571,7 @@ function createInjectionMiddleware() {
|
|
|
4359
4571
|
if (!isHtmlResponse()) return chunk;
|
|
4360
4572
|
const str = typeof chunk === "string" ? chunk : Buffer.isBuffer(chunk) ? chunk.toString("utf-8") : null;
|
|
4361
4573
|
if (!str) return chunk;
|
|
4362
|
-
if (str.includes(
|
|
4574
|
+
if (str.includes(marker) || str.includes(scriptTag)) {
|
|
4363
4575
|
injected = true;
|
|
4364
4576
|
return chunk;
|
|
4365
4577
|
}
|
|
@@ -4370,7 +4582,7 @@ function createInjectionMiddleware() {
|
|
|
4370
4582
|
if (!res.headersSent) {
|
|
4371
4583
|
res.removeHeader("content-length");
|
|
4372
4584
|
}
|
|
4373
|
-
const result = str.slice(0, idx) +
|
|
4585
|
+
const result = str.slice(0, idx) + scriptTag + str.slice(idx);
|
|
4374
4586
|
return typeof chunk === "string" ? result : Buffer.from(result, "utf-8");
|
|
4375
4587
|
}
|
|
4376
4588
|
res.write = function(chunk, ...args) {
|
|
@@ -4390,6 +4602,12 @@ function createInjectionMiddleware() {
|
|
|
4390
4602
|
next();
|
|
4391
4603
|
};
|
|
4392
4604
|
}
|
|
4605
|
+
function createInjectionMiddleware() {
|
|
4606
|
+
return createScriptInjectionMiddleware(SCRIPT_TAG, MARKER);
|
|
4607
|
+
}
|
|
4608
|
+
function createPreviewInjectionMiddleware() {
|
|
4609
|
+
return createScriptInjectionMiddleware(PREVIEW_SCRIPT_TAG, PREVIEW_MARKER);
|
|
4610
|
+
}
|
|
4393
4611
|
|
|
4394
4612
|
// src/git.ts
|
|
4395
4613
|
import { readFileSync as readFileSync3 } from "fs";
|
|
@@ -18433,17 +18651,14 @@ function date4(params) {
|
|
|
18433
18651
|
// node_modules/zod/v4/classic/external.js
|
|
18434
18652
|
config(en_default());
|
|
18435
18653
|
|
|
18436
|
-
// src/
|
|
18654
|
+
// src/tools.ts
|
|
18437
18655
|
import {
|
|
18438
18656
|
createSdkMcpServer,
|
|
18439
18657
|
tool
|
|
18440
18658
|
} from "@anthropic-ai/claude-agent-sdk";
|
|
18441
|
-
import {
|
|
18442
|
-
listTasks,
|
|
18443
|
-
getTask,
|
|
18444
|
-
createTask
|
|
18445
|
-
} from "viagen-sdk/sandbox";
|
|
18446
18659
|
function createViagenTools(config2) {
|
|
18660
|
+
const { client, projectId } = config2;
|
|
18661
|
+
const taskId = process.env["VIAGEN_TASK_ID"];
|
|
18447
18662
|
const tools = [
|
|
18448
18663
|
tool(
|
|
18449
18664
|
"viagen_update_task",
|
|
@@ -18459,112 +18674,94 @@ function createViagenTools(config2) {
|
|
|
18459
18674
|
prReviewStatus: external_exports.string().optional().describe("PR review outcome \u2014 e.g. 'pass', 'flag', or 'fail'.")
|
|
18460
18675
|
},
|
|
18461
18676
|
async (args) => {
|
|
18462
|
-
const
|
|
18463
|
-
if (!
|
|
18677
|
+
const id = args.taskId || taskId;
|
|
18678
|
+
if (!id) {
|
|
18464
18679
|
return {
|
|
18465
18680
|
content: [{ type: "text", text: "Error: No taskId provided and VIAGEN_TASK_ID is not set." }]
|
|
18466
18681
|
};
|
|
18467
18682
|
}
|
|
18468
|
-
const callbackUrl = process.env["VIAGEN_CALLBACK_URL"];
|
|
18469
|
-
const authToken = process.env["VIAGEN_AUTH_TOKEN"];
|
|
18470
18683
|
const internalStatus = args.status === "review" ? "validating" : args.status === "completed" ? "completed" : args.status;
|
|
18471
|
-
|
|
18472
|
-
|
|
18473
|
-
headers: {
|
|
18474
|
-
"Content-Type": "application/json",
|
|
18475
|
-
Authorization: `Bearer ${authToken}`
|
|
18476
|
-
},
|
|
18477
|
-
body: JSON.stringify({
|
|
18478
|
-
taskId,
|
|
18684
|
+
try {
|
|
18685
|
+
await client.tasks.update(projectId, id, {
|
|
18479
18686
|
...internalStatus && { status: internalStatus },
|
|
18480
18687
|
...args.prUrl && { prUrl: args.prUrl },
|
|
18481
18688
|
result: args.result,
|
|
18482
18689
|
...args.inputTokens != null && { inputTokens: args.inputTokens },
|
|
18483
18690
|
...args.outputTokens != null && { outputTokens: args.outputTokens },
|
|
18484
|
-
...args.costUsd != null && { costUsd: args.costUsd },
|
|
18485
18691
|
...args.prReviewStatus && { prReviewStatus: args.prReviewStatus }
|
|
18486
|
-
})
|
|
18487
|
-
});
|
|
18488
|
-
if (!res.ok) {
|
|
18489
|
-
const text = await res.text().catch(() => "");
|
|
18692
|
+
});
|
|
18490
18693
|
return {
|
|
18491
|
-
content: [{ type: "text", text: `
|
|
18694
|
+
content: [{ type: "text", text: `Task ${id} updated.${args.status ? ` Status: '${args.status}'.` : ""}${args.prReviewStatus ? ` PR review: '${args.prReviewStatus}'.` : ""}` }]
|
|
18695
|
+
};
|
|
18696
|
+
} catch (err) {
|
|
18697
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
18698
|
+
return {
|
|
18699
|
+
content: [{ type: "text", text: `Error updating task: ${message}` }]
|
|
18492
18700
|
};
|
|
18493
18701
|
}
|
|
18702
|
+
}
|
|
18703
|
+
),
|
|
18704
|
+
tool(
|
|
18705
|
+
"viagen_list_tasks",
|
|
18706
|
+
"List tasks in the current project. Optionally filter by status.",
|
|
18707
|
+
{
|
|
18708
|
+
status: external_exports.enum(["ready", "running", "validating", "completed", "timed_out"]).optional().describe("Filter tasks by status.")
|
|
18709
|
+
},
|
|
18710
|
+
async (args) => {
|
|
18711
|
+
const tasks = await client.tasks.list(projectId, args.status);
|
|
18494
18712
|
return {
|
|
18495
|
-
content: [
|
|
18713
|
+
content: [
|
|
18714
|
+
{
|
|
18715
|
+
type: "text",
|
|
18716
|
+
text: JSON.stringify(tasks, null, 2)
|
|
18717
|
+
}
|
|
18718
|
+
]
|
|
18719
|
+
};
|
|
18720
|
+
}
|
|
18721
|
+
),
|
|
18722
|
+
tool(
|
|
18723
|
+
"viagen_get_task",
|
|
18724
|
+
"Get full details of a specific task by ID.",
|
|
18725
|
+
{
|
|
18726
|
+
taskId: external_exports.string().describe("The task ID to retrieve.")
|
|
18727
|
+
},
|
|
18728
|
+
async (args) => {
|
|
18729
|
+
const task = await client.tasks.get(projectId, args.taskId);
|
|
18730
|
+
return {
|
|
18731
|
+
content: [
|
|
18732
|
+
{
|
|
18733
|
+
type: "text",
|
|
18734
|
+
text: JSON.stringify(task, null, 2)
|
|
18735
|
+
}
|
|
18736
|
+
]
|
|
18737
|
+
};
|
|
18738
|
+
}
|
|
18739
|
+
),
|
|
18740
|
+
tool(
|
|
18741
|
+
"viagen_create_task",
|
|
18742
|
+
"Create a new task in the current project. Use this to create follow-up work.",
|
|
18743
|
+
{
|
|
18744
|
+
prompt: external_exports.string().describe("The task prompt / instructions."),
|
|
18745
|
+
branch: external_exports.string().optional().describe("Git branch name for the task."),
|
|
18746
|
+
type: external_exports.enum(["task", "plan"]).optional().describe("Task type: 'task' for code changes, 'plan' for implementation plans.")
|
|
18747
|
+
},
|
|
18748
|
+
async (args) => {
|
|
18749
|
+
const task = await client.tasks.create(projectId, {
|
|
18750
|
+
prompt: args.prompt,
|
|
18751
|
+
branch: args.branch,
|
|
18752
|
+
type: args.type
|
|
18753
|
+
});
|
|
18754
|
+
return {
|
|
18755
|
+
content: [
|
|
18756
|
+
{
|
|
18757
|
+
type: "text",
|
|
18758
|
+
text: JSON.stringify(task, null, 2)
|
|
18759
|
+
}
|
|
18760
|
+
]
|
|
18496
18761
|
};
|
|
18497
18762
|
}
|
|
18498
18763
|
)
|
|
18499
18764
|
];
|
|
18500
|
-
if (config2?.projectId) {
|
|
18501
|
-
tools.push(
|
|
18502
|
-
tool(
|
|
18503
|
-
"viagen_list_tasks",
|
|
18504
|
-
"List tasks in the current project. Optionally filter by status.",
|
|
18505
|
-
{
|
|
18506
|
-
status: external_exports.enum(["ready", "running", "validating", "completed", "timed_out"]).optional().describe("Filter tasks by status.")
|
|
18507
|
-
},
|
|
18508
|
-
async (args) => {
|
|
18509
|
-
const tasks = await listTasks({ status: args.status });
|
|
18510
|
-
return {
|
|
18511
|
-
content: [
|
|
18512
|
-
{
|
|
18513
|
-
type: "text",
|
|
18514
|
-
text: JSON.stringify(tasks, null, 2)
|
|
18515
|
-
}
|
|
18516
|
-
]
|
|
18517
|
-
};
|
|
18518
|
-
}
|
|
18519
|
-
)
|
|
18520
|
-
);
|
|
18521
|
-
tools.push(
|
|
18522
|
-
tool(
|
|
18523
|
-
"viagen_get_task",
|
|
18524
|
-
"Get full details of a specific task by ID.",
|
|
18525
|
-
{
|
|
18526
|
-
taskId: external_exports.string().describe("The task ID to retrieve.")
|
|
18527
|
-
},
|
|
18528
|
-
async (args) => {
|
|
18529
|
-
const task = await getTask(args.taskId);
|
|
18530
|
-
return {
|
|
18531
|
-
content: [
|
|
18532
|
-
{
|
|
18533
|
-
type: "text",
|
|
18534
|
-
text: JSON.stringify(task, null, 2)
|
|
18535
|
-
}
|
|
18536
|
-
]
|
|
18537
|
-
};
|
|
18538
|
-
}
|
|
18539
|
-
)
|
|
18540
|
-
);
|
|
18541
|
-
tools.push(
|
|
18542
|
-
tool(
|
|
18543
|
-
"viagen_create_task",
|
|
18544
|
-
"Create a new task in the current project. Use this to create follow-up work.",
|
|
18545
|
-
{
|
|
18546
|
-
prompt: external_exports.string().describe("The task prompt / instructions."),
|
|
18547
|
-
branch: external_exports.string().optional().describe("Git branch name for the task."),
|
|
18548
|
-
type: external_exports.enum(["task", "plan"]).optional().describe("Task type: 'task' for code changes, 'plan' for implementation plans.")
|
|
18549
|
-
},
|
|
18550
|
-
async (args) => {
|
|
18551
|
-
const task = await createTask({
|
|
18552
|
-
prompt: args.prompt,
|
|
18553
|
-
branch: args.branch,
|
|
18554
|
-
type: args.type
|
|
18555
|
-
});
|
|
18556
|
-
return {
|
|
18557
|
-
content: [
|
|
18558
|
-
{
|
|
18559
|
-
type: "text",
|
|
18560
|
-
text: JSON.stringify(task, null, 2)
|
|
18561
|
-
}
|
|
18562
|
-
]
|
|
18563
|
-
};
|
|
18564
|
-
}
|
|
18565
|
-
)
|
|
18566
|
-
);
|
|
18567
|
-
}
|
|
18568
18765
|
return createSdkMcpServer({ name: "viagen", tools });
|
|
18569
18766
|
}
|
|
18570
18767
|
var PLAN_MODE_DISALLOWED_TOOLS = ["Edit", "NotebookEdit"];
|
|
@@ -18604,6 +18801,9 @@ You have access to viagen platform tools for task management:
|
|
|
18604
18801
|
Use these to understand project context and create follow-up work when appropriate.
|
|
18605
18802
|
`;
|
|
18606
18803
|
|
|
18804
|
+
// src/index.ts
|
|
18805
|
+
import { createViagen } from "viagen-sdk";
|
|
18806
|
+
|
|
18607
18807
|
// src/sandbox.ts
|
|
18608
18808
|
import { randomUUID } from "crypto";
|
|
18609
18809
|
import { readFileSync as readFileSync4, readdirSync as readdirSync2 } from "fs";
|
|
@@ -18868,6 +19068,7 @@ function viagen(options) {
|
|
|
18868
19068
|
ui: options?.ui ?? true
|
|
18869
19069
|
};
|
|
18870
19070
|
let env;
|
|
19071
|
+
let previewEnabled = false;
|
|
18871
19072
|
let projectRoot;
|
|
18872
19073
|
let lastError = null;
|
|
18873
19074
|
let promptSent = false;
|
|
@@ -18877,12 +19078,13 @@ function viagen(options) {
|
|
|
18877
19078
|
name: "viagen",
|
|
18878
19079
|
config(_, { mode }) {
|
|
18879
19080
|
const e = loadEnv(mode, process.cwd(), "");
|
|
18880
|
-
if (e["VIAGEN_AUTH_TOKEN"]) {
|
|
19081
|
+
if (e["VIAGEN_AUTH_TOKEN"] || e["VIAGEN_USER_TOKEN"]) {
|
|
18881
19082
|
return { server: { host: true, allowedHosts: true } };
|
|
18882
19083
|
}
|
|
18883
19084
|
},
|
|
18884
19085
|
configResolved(config2) {
|
|
18885
19086
|
env = loadEnv(config2.mode, config2.envDir ?? config2.root, "");
|
|
19087
|
+
previewEnabled = env["VIAGEN_PREVIEW"] === "true";
|
|
18886
19088
|
projectRoot = config2.root;
|
|
18887
19089
|
const debugEnabled = options?.debug ?? env["VIAGEN_DEBUG"] === "1";
|
|
18888
19090
|
setDebug(debugEnabled);
|
|
@@ -18893,6 +19095,7 @@ function viagen(options) {
|
|
|
18893
19095
|
debug("init", `CLAUDE_ACCESS_TOKEN: ${env["CLAUDE_ACCESS_TOKEN"] ? "set" : "NOT SET"}`);
|
|
18894
19096
|
debug("init", `GITHUB_TOKEN: ${env["GITHUB_TOKEN"] ? "set" : "NOT SET"}`);
|
|
18895
19097
|
debug("init", `VIAGEN_AUTH_TOKEN: ${env["VIAGEN_AUTH_TOKEN"] ? "set" : "NOT SET"}`);
|
|
19098
|
+
debug("init", `VIAGEN_USER_TOKEN: ${env["VIAGEN_USER_TOKEN"] ? "set" : "NOT SET"}`);
|
|
18896
19099
|
debug("init", `VIAGEN_MODEL: ${env["VIAGEN_MODEL"] || "(not set)"}`);
|
|
18897
19100
|
debug("init", `VIAGEN_PROMPT: ${env["VIAGEN_PROMPT"] ? `"${env["VIAGEN_PROMPT"].slice(0, 80)}..."` : "(not set)"}`);
|
|
18898
19101
|
debug("init", `VIAGEN_TASK_ID: ${env["VIAGEN_TASK_ID"] || "(not set)"}`);
|
|
@@ -18911,21 +19114,30 @@ function viagen(options) {
|
|
|
18911
19114
|
);
|
|
18912
19115
|
},
|
|
18913
19116
|
transformIndexHtml(_html, ctx) {
|
|
18914
|
-
|
|
18915
|
-
|
|
18916
|
-
|
|
18917
|
-
|
|
18918
|
-
|
|
18919
|
-
|
|
19117
|
+
const tags = [];
|
|
19118
|
+
if (opts.ui) {
|
|
19119
|
+
const url2 = new URL(ctx.originalUrl || ctx.path, "http://localhost");
|
|
19120
|
+
const isEmbed = url2.searchParams.has("_viagen_embed");
|
|
19121
|
+
if (!isEmbed || opts.overlay) {
|
|
19122
|
+
tags.push({
|
|
19123
|
+
tag: "script",
|
|
19124
|
+
children: buildClientScript({
|
|
19125
|
+
position: opts.position,
|
|
19126
|
+
panelWidth: opts.panelWidth,
|
|
19127
|
+
overlay: opts.overlay
|
|
19128
|
+
}),
|
|
19129
|
+
injectTo: "body"
|
|
19130
|
+
});
|
|
19131
|
+
}
|
|
19132
|
+
}
|
|
19133
|
+
if (previewEnabled) {
|
|
19134
|
+
tags.push({
|
|
18920
19135
|
tag: "script",
|
|
18921
|
-
children:
|
|
18922
|
-
position: opts.position,
|
|
18923
|
-
panelWidth: opts.panelWidth,
|
|
18924
|
-
overlay: opts.overlay
|
|
18925
|
-
}),
|
|
19136
|
+
children: buildPreviewScript(),
|
|
18926
19137
|
injectTo: "body"
|
|
18927
|
-
}
|
|
18928
|
-
|
|
19138
|
+
});
|
|
19139
|
+
}
|
|
19140
|
+
return tags;
|
|
18929
19141
|
},
|
|
18930
19142
|
configureServer(server) {
|
|
18931
19143
|
debug("server", "configureServer starting");
|
|
@@ -18968,6 +19180,14 @@ ${payload.err.frame || ""}`
|
|
|
18968
19180
|
} else {
|
|
18969
19181
|
debug("server", "auth middleware DISABLED (no VIAGEN_AUTH_TOKEN)");
|
|
18970
19182
|
}
|
|
19183
|
+
const platformToken = env["VIAGEN_USER_TOKEN"] || env["VIAGEN_AUTH_TOKEN"];
|
|
19184
|
+
const platformUrl = env["VIAGEN_PLATFORM_URL"] || "https://app.viagen.dev";
|
|
19185
|
+
const projectId = env["VIAGEN_PROJECT_ID"];
|
|
19186
|
+
let viagenClient = null;
|
|
19187
|
+
if (platformToken) {
|
|
19188
|
+
viagenClient = createViagen({ token: platformToken, baseUrl: platformUrl });
|
|
19189
|
+
debug("server", `platform client created (baseUrl: ${platformUrl})`);
|
|
19190
|
+
}
|
|
18971
19191
|
const hasEditor = !!(options?.editable && options.editable.length > 0);
|
|
18972
19192
|
const clientJs = buildClientScript({
|
|
18973
19193
|
position: opts.position,
|
|
@@ -18990,18 +19210,80 @@ ${payload.err.frame || ""}`
|
|
|
18990
19210
|
res.setHeader("Content-Type", "text/html");
|
|
18991
19211
|
res.end(buildIframeHtml({ panelWidth: opts.panelWidth }));
|
|
18992
19212
|
});
|
|
19213
|
+
if (previewEnabled) {
|
|
19214
|
+
const previewJs = buildPreviewScript();
|
|
19215
|
+
server.middlewares.use("/via/preview.js", (_req, res) => {
|
|
19216
|
+
res.setHeader("Content-Type", "application/javascript");
|
|
19217
|
+
res.end(previewJs);
|
|
19218
|
+
});
|
|
19219
|
+
server.middlewares.use("/via/preview/task", (req, res) => {
|
|
19220
|
+
if (req.method !== "POST") {
|
|
19221
|
+
res.writeHead(405, { "Content-Type": "application/json" });
|
|
19222
|
+
res.end(JSON.stringify({ error: "Method not allowed" }));
|
|
19223
|
+
return;
|
|
19224
|
+
}
|
|
19225
|
+
if (!viagenClient || !projectId) {
|
|
19226
|
+
res.writeHead(503, { "Content-Type": "application/json" });
|
|
19227
|
+
res.end(JSON.stringify({ error: "Task creation not configured: missing platform credentials or VIAGEN_PROJECT_ID" }));
|
|
19228
|
+
return;
|
|
19229
|
+
}
|
|
19230
|
+
let body = "";
|
|
19231
|
+
req.on("data", (chunk) => {
|
|
19232
|
+
body += chunk.toString();
|
|
19233
|
+
});
|
|
19234
|
+
req.on("end", async () => {
|
|
19235
|
+
try {
|
|
19236
|
+
const data = JSON.parse(body);
|
|
19237
|
+
const { prompt, pageUrl, screenshot } = data;
|
|
19238
|
+
if (!prompt || typeof prompt !== "string") {
|
|
19239
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
19240
|
+
res.end(JSON.stringify({ error: "prompt is required" }));
|
|
19241
|
+
return;
|
|
19242
|
+
}
|
|
19243
|
+
const parts = [prompt.trim()];
|
|
19244
|
+
if (pageUrl) parts.push(`
|
|
19245
|
+
Page URL: ${pageUrl}`);
|
|
19246
|
+
if (screenshot) parts.push("\n[Screenshot attached]");
|
|
19247
|
+
parts.push("\n\n[Submitted via viagen preview feedback]");
|
|
19248
|
+
const fullPrompt = parts.join("");
|
|
19249
|
+
const task = await viagenClient.tasks.create(projectId, { prompt: fullPrompt, type: "task" });
|
|
19250
|
+
if (screenshot && task.id) {
|
|
19251
|
+
try {
|
|
19252
|
+
const [header, b64] = screenshot.split(",");
|
|
19253
|
+
const mime = header.match(/:(.*?);/)?.[1] || "image/jpeg";
|
|
19254
|
+
const binary = Buffer.from(b64, "base64");
|
|
19255
|
+
const blob = new Blob([binary], { type: mime });
|
|
19256
|
+
const ext = mime === "image/png" ? "png" : "jpeg";
|
|
19257
|
+
await viagenClient.tasks.addAttachment(projectId, task.id, blob, `screenshot.${ext}`);
|
|
19258
|
+
debug("preview", `screenshot attached to task ${task.id}`);
|
|
19259
|
+
} catch (attachErr) {
|
|
19260
|
+
debug("preview", `screenshot attachment failed (non-fatal): ${attachErr}`);
|
|
19261
|
+
}
|
|
19262
|
+
}
|
|
19263
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
19264
|
+
res.end(JSON.stringify({ task }));
|
|
19265
|
+
} catch (err) {
|
|
19266
|
+
const message = err instanceof Error ? err.message : "Internal error";
|
|
19267
|
+
debug("preview", `preview/task error: ${message}`);
|
|
19268
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
19269
|
+
res.end(JSON.stringify({ error: message }));
|
|
19270
|
+
}
|
|
19271
|
+
});
|
|
19272
|
+
});
|
|
19273
|
+
}
|
|
18993
19274
|
registerHealthRoutes(server, env, {
|
|
18994
19275
|
get: () => lastError
|
|
18995
19276
|
});
|
|
18996
19277
|
const resolvedModel = env["VIAGEN_MODEL"] || opts.model;
|
|
18997
19278
|
debug("server", `creating ChatSession (model: ${resolvedModel})`);
|
|
18998
19279
|
let mcpServers;
|
|
18999
|
-
const
|
|
19000
|
-
if (
|
|
19001
|
-
debug("server", "creating viagen MCP tools (
|
|
19002
|
-
const viagenMcp = createViagenTools(
|
|
19003
|
-
|
|
19004
|
-
|
|
19280
|
+
const hasPlatformContext = !!(viagenClient && projectId);
|
|
19281
|
+
if (hasPlatformContext) {
|
|
19282
|
+
debug("server", "creating viagen MCP tools (platform connected)");
|
|
19283
|
+
const viagenMcp = createViagenTools({
|
|
19284
|
+
client: viagenClient,
|
|
19285
|
+
projectId
|
|
19286
|
+
});
|
|
19005
19287
|
mcpServers = { [viagenMcp.name]: viagenMcp };
|
|
19006
19288
|
}
|
|
19007
19289
|
const isPlanMode = env["VIAGEN_TASK_TYPE"] === "plan";
|
|
@@ -19009,7 +19291,7 @@ ${payload.err.frame || ""}`
|
|
|
19009
19291
|
if (isPlanMode) {
|
|
19010
19292
|
debug("server", "plan mode active \u2014 restricting tools");
|
|
19011
19293
|
systemPrompt = PLAN_SYSTEM_PROMPT;
|
|
19012
|
-
} else if (
|
|
19294
|
+
} else if (hasPlatformContext) {
|
|
19013
19295
|
systemPrompt = (systemPrompt || "") + TASK_TOOLS_PROMPT;
|
|
19014
19296
|
}
|
|
19015
19297
|
const chatSession = new ChatSession({
|
|
@@ -19025,7 +19307,11 @@ ${payload.err.frame || ""}`
|
|
|
19025
19307
|
} : {}
|
|
19026
19308
|
});
|
|
19027
19309
|
debug("server", "registering chat routes");
|
|
19028
|
-
registerChatRoutes(server, chatSession, {
|
|
19310
|
+
registerChatRoutes(server, chatSession, {
|
|
19311
|
+
env,
|
|
19312
|
+
viagenClient: viagenClient ?? void 0,
|
|
19313
|
+
projectId
|
|
19314
|
+
});
|
|
19029
19315
|
if (hasEditor) {
|
|
19030
19316
|
registerFileRoutes(server, {
|
|
19031
19317
|
editable: options.editable,
|
|
@@ -19043,30 +19329,26 @@ ${payload.err.frame || ""}`
|
|
|
19043
19329
|
if (event.type === "done") {
|
|
19044
19330
|
debug("server", "auto-prompt completed");
|
|
19045
19331
|
logBuffer.push("info", `[viagen] Prompt completed`);
|
|
19046
|
-
const
|
|
19047
|
-
if (
|
|
19048
|
-
|
|
19049
|
-
|
|
19050
|
-
|
|
19051
|
-
"Content-Type": "application/json",
|
|
19052
|
-
Authorization: `Bearer ${env["VIAGEN_AUTH_TOKEN"]}`
|
|
19053
|
-
},
|
|
19054
|
-
body: JSON.stringify({
|
|
19055
|
-
taskId,
|
|
19056
|
-
...event.inputTokens != null && { inputTokens: event.inputTokens },
|
|
19057
|
-
...event.outputTokens != null && { outputTokens: event.outputTokens },
|
|
19058
|
-
...event.costUsd != null && { costUsd: event.costUsd }
|
|
19059
|
-
})
|
|
19332
|
+
const currentTaskId = env["VIAGEN_TASK_ID"];
|
|
19333
|
+
if (viagenClient && projectId && currentTaskId && (event.inputTokens || event.outputTokens)) {
|
|
19334
|
+
viagenClient.tasks.update(projectId, currentTaskId, {
|
|
19335
|
+
...event.inputTokens != null && { inputTokens: event.inputTokens },
|
|
19336
|
+
...event.outputTokens != null && { outputTokens: event.outputTokens }
|
|
19060
19337
|
}).catch((err) => {
|
|
19061
|
-
debug("server", `usage
|
|
19338
|
+
debug("server", `usage report failed: ${err}`);
|
|
19062
19339
|
});
|
|
19063
19340
|
}
|
|
19064
19341
|
}
|
|
19065
19342
|
});
|
|
19066
19343
|
}
|
|
19067
|
-
if (opts.ui) {
|
|
19344
|
+
if (opts.ui || previewEnabled) {
|
|
19068
19345
|
return () => {
|
|
19069
|
-
|
|
19346
|
+
if (opts.ui) {
|
|
19347
|
+
server.middlewares.use(createInjectionMiddleware());
|
|
19348
|
+
}
|
|
19349
|
+
if (previewEnabled) {
|
|
19350
|
+
server.middlewares.use(createPreviewInjectionMiddleware());
|
|
19351
|
+
}
|
|
19070
19352
|
};
|
|
19071
19353
|
}
|
|
19072
19354
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "viagen",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.55",
|
|
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",
|
|
@@ -42,9 +42,10 @@
|
|
|
42
42
|
"@anthropic-ai/claude-agent-sdk": "^0.2.50",
|
|
43
43
|
"@anthropic-ai/claude-code": "^2.1.42",
|
|
44
44
|
"@vercel/sandbox": "^1",
|
|
45
|
+
"agent-browser": "^0.20.12",
|
|
45
46
|
"lucide-react": "^0.564.0",
|
|
46
47
|
"simple-git": "^3.31.1",
|
|
47
|
-
"viagen-sdk": "^0.0.
|
|
48
|
+
"viagen-sdk": "^0.0.12"
|
|
48
49
|
},
|
|
49
50
|
"license": "MIT",
|
|
50
51
|
"repository": {
|