vigthoria-cli 1.8.6 → 1.8.8
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/commands/chat.js +27 -12
- package/dist/commands/preview.js +6 -4
- package/dist/utils/api.js +39 -18
- package/package.json +1 -1
package/dist/commands/chat.js
CHANGED
|
@@ -49,9 +49,28 @@ const session_js_1 = require("../utils/session.js");
|
|
|
49
49
|
const bridge_client_js_1 = require("../utils/bridge-client.js");
|
|
50
50
|
const workspace_stream_js_1 = require("../utils/workspace-stream.js");
|
|
51
51
|
const DEFAULT_V3_AGENT_TIMEOUT_MS = (() => {
|
|
52
|
-
const rawValue = process.env.VIGTHORIA_AGENT_TIMEOUT_MS || process.env.V3_AGENT_TIMEOUT_MS
|
|
52
|
+
const rawValue = process.env.VIGTHORIA_AGENT_TIMEOUT_MS || process.env.V3_AGENT_TIMEOUT_MS;
|
|
53
|
+
if (!rawValue) {
|
|
54
|
+
return 0;
|
|
55
|
+
}
|
|
56
|
+
const parsed = Number.parseInt(rawValue, 10);
|
|
57
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : 0;
|
|
58
|
+
})();
|
|
59
|
+
const DEFAULT_V3_AGENT_IDLE_TIMEOUT_MS = (() => {
|
|
60
|
+
const rawValue = process.env.VIGTHORIA_AGENT_IDLE_TIMEOUT_MS || process.env.V3_AGENT_IDLE_TIMEOUT_MS;
|
|
61
|
+
if (!rawValue) {
|
|
62
|
+
return 0;
|
|
63
|
+
}
|
|
64
|
+
const parsed = Number.parseInt(rawValue, 10);
|
|
65
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : 0;
|
|
66
|
+
})();
|
|
67
|
+
const DEFAULT_V3_AGENT_SOFT_TIMEOUT_MS = (() => {
|
|
68
|
+
const rawValue = process.env.VIGTHORIA_AGENT_SOFT_TIMEOUT_MS || process.env.V3_AGENT_SOFT_TIMEOUT_MS;
|
|
69
|
+
if (!rawValue) {
|
|
70
|
+
return 0;
|
|
71
|
+
}
|
|
53
72
|
const parsed = Number.parseInt(rawValue, 10);
|
|
54
|
-
return Number.isFinite(parsed) && parsed
|
|
73
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : 0;
|
|
55
74
|
})();
|
|
56
75
|
class ChatCommand {
|
|
57
76
|
config;
|
|
@@ -122,13 +141,9 @@ class ChatCommand {
|
|
|
122
141
|
return this.getDefaultChatModel();
|
|
123
142
|
}
|
|
124
143
|
isLegacyAgentFallbackAllowed() {
|
|
125
|
-
//
|
|
126
|
-
//
|
|
127
|
-
|
|
128
|
-
if (process.env.VIGTHORIA_ALLOW_LEGACY_AGENT_FALLBACK === '0') {
|
|
129
|
-
return false;
|
|
130
|
-
}
|
|
131
|
-
return true;
|
|
144
|
+
// Hosted V3 Agent Mode must fail loudly by default so clients do not silently drop into legacy mode.
|
|
145
|
+
// Operators can still opt in during emergency local debugging.
|
|
146
|
+
return process.env.VIGTHORIA_ALLOW_LEGACY_AGENT_FALLBACK === '1';
|
|
132
147
|
}
|
|
133
148
|
resolveAgentExecutionPolicy(prompt) {
|
|
134
149
|
const explicitModel = this.modelExplicitlySelected;
|
|
@@ -1624,7 +1639,7 @@ class ChatCommand {
|
|
|
1624
1639
|
clientSurface: 'cli',
|
|
1625
1640
|
localMachineCapable: true,
|
|
1626
1641
|
agentTimeoutMs: DEFAULT_V3_AGENT_TIMEOUT_MS,
|
|
1627
|
-
agentIdleTimeoutMs:
|
|
1642
|
+
agentIdleTimeoutMs: DEFAULT_V3_AGENT_IDLE_TIMEOUT_MS,
|
|
1628
1643
|
model: routingPolicy.selectedModel,
|
|
1629
1644
|
requestedModel: this.currentModel,
|
|
1630
1645
|
agentExecutionPolicy: routingPolicy,
|
|
@@ -1634,11 +1649,11 @@ class ChatCommand {
|
|
|
1634
1649
|
...runtimeContext,
|
|
1635
1650
|
onStreamEvent: spinner ? (event) => this.updateV3AgentSpinner(spinner, event) : undefined,
|
|
1636
1651
|
});
|
|
1637
|
-
const response = await (rescueEligible
|
|
1652
|
+
const response = await (rescueEligible && DEFAULT_V3_AGENT_SOFT_TIMEOUT_MS > 0
|
|
1638
1653
|
? Promise.race([
|
|
1639
1654
|
workflowPromise,
|
|
1640
1655
|
new Promise((_, reject) => {
|
|
1641
|
-
setTimeout(() => reject(new Error('V3_SAAS_SOFT_TIMEOUT')),
|
|
1656
|
+
setTimeout(() => reject(new Error('V3_SAAS_SOFT_TIMEOUT')), DEFAULT_V3_AGENT_SOFT_TIMEOUT_MS);
|
|
1642
1657
|
}),
|
|
1643
1658
|
])
|
|
1644
1659
|
: workflowPromise);
|
package/dist/commands/preview.js
CHANGED
|
@@ -112,10 +112,12 @@ class PreviewCommand {
|
|
|
112
112
|
if (options.proof) {
|
|
113
113
|
await this.runProofGate(projectPath, options.screenshot);
|
|
114
114
|
}
|
|
115
|
-
// If only --diff or --proof
|
|
116
|
-
if (
|
|
117
|
-
|
|
118
|
-
|
|
115
|
+
// If only --diff or --proof was requested (no explicit entry/port), just exit
|
|
116
|
+
if (options.diff || options.proof) {
|
|
117
|
+
if (!options.entry && !options.port) {
|
|
118
|
+
this.api.destroy();
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
119
121
|
}
|
|
120
122
|
// Detect entry file
|
|
121
123
|
const entryFile = this.detectEntryFile(projectPath, options.entry);
|
package/dist/utils/api.js
CHANGED
|
@@ -90,19 +90,31 @@ function formatCLIError(err) {
|
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
const DEFAULT_V3_AGENT_TIMEOUT_MS = (() => {
|
|
93
|
-
const rawValue = process.env.VIGTHORIA_AGENT_TIMEOUT_MS || process.env.V3_AGENT_TIMEOUT_MS
|
|
93
|
+
const rawValue = process.env.VIGTHORIA_AGENT_TIMEOUT_MS || process.env.V3_AGENT_TIMEOUT_MS;
|
|
94
|
+
if (!rawValue) {
|
|
95
|
+
// No total timeout by default for long-running SSE agent workflows.
|
|
96
|
+
return 0;
|
|
97
|
+
}
|
|
94
98
|
const parsed = Number.parseInt(rawValue, 10);
|
|
95
|
-
return Number.isFinite(parsed) && parsed
|
|
99
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : 0;
|
|
96
100
|
})();
|
|
97
101
|
const DEFAULT_V3_AGENT_IDLE_TIMEOUT_MS = (() => {
|
|
98
|
-
const rawValue = process.env.VIGTHORIA_AGENT_IDLE_TIMEOUT_MS || process.env.V3_AGENT_IDLE_TIMEOUT_MS
|
|
102
|
+
const rawValue = process.env.VIGTHORIA_AGENT_IDLE_TIMEOUT_MS || process.env.V3_AGENT_IDLE_TIMEOUT_MS;
|
|
103
|
+
if (!rawValue) {
|
|
104
|
+
// Keep stream open indefinitely unless user configures an idle limit.
|
|
105
|
+
return 0;
|
|
106
|
+
}
|
|
99
107
|
const parsed = Number.parseInt(rawValue, 10);
|
|
100
|
-
return Number.isFinite(parsed) && parsed
|
|
108
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : 0;
|
|
101
109
|
})();
|
|
102
110
|
const DEFAULT_OPERATOR_TIMEOUT_MS = (() => {
|
|
103
|
-
const rawValue = process.env.VIGTHORIA_OPERATOR_TIMEOUT_MS || process.env.OPERATOR_TIMEOUT_MS
|
|
111
|
+
const rawValue = process.env.VIGTHORIA_OPERATOR_TIMEOUT_MS || process.env.OPERATOR_TIMEOUT_MS;
|
|
112
|
+
if (!rawValue) {
|
|
113
|
+
// BMAD/operator flows can be long-running; do not cap by default.
|
|
114
|
+
return 0;
|
|
115
|
+
}
|
|
104
116
|
const parsed = Number.parseInt(rawValue, 10);
|
|
105
|
-
return Number.isFinite(parsed) && parsed
|
|
117
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : 0;
|
|
106
118
|
})();
|
|
107
119
|
class APIClient {
|
|
108
120
|
client;
|
|
@@ -2122,6 +2134,11 @@ menu {
|
|
|
2122
2134
|
if (!looksLikeFrontendTask) {
|
|
2123
2135
|
return;
|
|
2124
2136
|
}
|
|
2137
|
+
// Skip motion/scroll enhancements for games — they use canvas, not section-based layouts
|
|
2138
|
+
const looksLikeGame = /\bgame\b|arcade|pac.?man|tetris|platformer|roguelike|breakout|pong|snake\s+game|tower\s+defense|playable/i.test(prompt);
|
|
2139
|
+
if (looksLikeGame) {
|
|
2140
|
+
return;
|
|
2141
|
+
}
|
|
2125
2142
|
const htmlPath = path_1.default.join(rootPath, 'index.html');
|
|
2126
2143
|
if (!fs_1.default.existsSync(htmlPath)) {
|
|
2127
2144
|
return;
|
|
@@ -2568,7 +2585,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
2568
2585
|
let contextId = response.headers.get('x-context-id') || String(context.contextId || '').trim() || null;
|
|
2569
2586
|
let serverWorkspaceRoot = null;
|
|
2570
2587
|
const streamedFiles = {};
|
|
2571
|
-
const idleTimeoutMs = context.agentIdleTimeoutMs
|
|
2588
|
+
const idleTimeoutMs = context.agentIdleTimeoutMs ?? DEFAULT_V3_AGENT_IDLE_TIMEOUT_MS;
|
|
2572
2589
|
while (true) {
|
|
2573
2590
|
let chunk;
|
|
2574
2591
|
try {
|
|
@@ -2724,15 +2741,13 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
2724
2741
|
}
|
|
2725
2742
|
async runV3AgentWorkflow(message, context = {}) {
|
|
2726
2743
|
const executionContext = await this.bindExecutionContext(context);
|
|
2727
|
-
const baseTimeoutMs = executionContext.agentTimeoutMs
|
|
2744
|
+
const baseTimeoutMs = executionContext.agentTimeoutMs ?? DEFAULT_V3_AGENT_TIMEOUT_MS;
|
|
2728
2745
|
const expectedFiles = this.extractExpectedWorkspaceFiles(message, executionContext);
|
|
2729
2746
|
const requestedModel = String(executionContext.model || executionContext.requestedModel || 'agent');
|
|
2730
2747
|
const resolvedModel = this.resolvePermittedModelId(requestedModel);
|
|
2731
2748
|
const preferLocalV3 = /(premium|polished|landing|site|page|dashboard|saas|frontend|ui|responsive|animated|create the required project files and write them to the workspace)/i.test(message)
|
|
2732
2749
|
&& context.localMachineCapable !== false;
|
|
2733
|
-
const
|
|
2734
|
-
&& /(saas|dashboard|analytics|billing|team management|activity feed|login screen)/i.test(message);
|
|
2735
|
-
const timeoutMs = rescueEligibleSaaS ? Math.min(baseTimeoutMs, 210000) : baseTimeoutMs;
|
|
2750
|
+
const timeoutMs = baseTimeoutMs;
|
|
2736
2751
|
const maxAttempts = preferLocalV3 ? 2 : 1;
|
|
2737
2752
|
let lastErrors = [];
|
|
2738
2753
|
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
@@ -2766,7 +2781,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
2766
2781
|
};
|
|
2767
2782
|
for (const baseUrl of this.getV3AgentBaseUrls(preferLocalV3)) {
|
|
2768
2783
|
const controller = new AbortController();
|
|
2769
|
-
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
2784
|
+
const timeoutId = timeoutMs > 0 ? setTimeout(() => controller.abort(), timeoutMs) : null;
|
|
2770
2785
|
try {
|
|
2771
2786
|
const response = await this.executeV3AgentRunRequest(baseUrl, requestBody, requestExecutionContext, controller.signal);
|
|
2772
2787
|
if (!response.ok) {
|
|
@@ -2798,7 +2813,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
2798
2813
|
stream: true,
|
|
2799
2814
|
};
|
|
2800
2815
|
const continueController = new AbortController();
|
|
2801
|
-
const continueTimeoutId = setTimeout(() => continueController.abort(), timeoutMs);
|
|
2816
|
+
const continueTimeoutId = timeoutMs > 0 ? setTimeout(() => continueController.abort(), timeoutMs) : null;
|
|
2802
2817
|
try {
|
|
2803
2818
|
const continueHeaders = await this.getV3AgentHeaders();
|
|
2804
2819
|
const continueResponse = await fetch(this.getV3AgentContinueUrl(baseUrl), {
|
|
@@ -2816,7 +2831,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
2816
2831
|
break; // Fall through to normal completion with partial data
|
|
2817
2832
|
}
|
|
2818
2833
|
finally {
|
|
2819
|
-
|
|
2834
|
+
if (continueTimeoutId) {
|
|
2835
|
+
clearTimeout(continueTimeoutId);
|
|
2836
|
+
}
|
|
2820
2837
|
}
|
|
2821
2838
|
}
|
|
2822
2839
|
// Use the final continuation data for workspace recovery
|
|
@@ -2873,7 +2890,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
2873
2890
|
errors.push(`${baseUrl}: ${error?.message || String(error)}`);
|
|
2874
2891
|
}
|
|
2875
2892
|
finally {
|
|
2876
|
-
|
|
2893
|
+
if (timeoutId) {
|
|
2894
|
+
clearTimeout(timeoutId);
|
|
2895
|
+
}
|
|
2877
2896
|
}
|
|
2878
2897
|
}
|
|
2879
2898
|
lastErrors = errors;
|
|
@@ -2940,7 +2959,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
2940
2959
|
}
|
|
2941
2960
|
async runOperatorWorkflow(message, context = {}) {
|
|
2942
2961
|
const executionContext = await this.bindExecutionContext(context);
|
|
2943
|
-
const timeoutMs = context.operatorTimeoutMs
|
|
2962
|
+
const timeoutMs = context.operatorTimeoutMs ?? DEFAULT_OPERATOR_TIMEOUT_MS;
|
|
2944
2963
|
const errors = [];
|
|
2945
2964
|
const authToken = this.config.get('authToken');
|
|
2946
2965
|
// Collect a lightweight workspace file listing so the operator can
|
|
@@ -2949,7 +2968,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
2949
2968
|
const workspaceSummary = this.buildLocalWorkspaceSummary(workspacePath);
|
|
2950
2969
|
for (const baseUrl of this.getOperatorBaseUrls()) {
|
|
2951
2970
|
const controller = new AbortController();
|
|
2952
|
-
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
2971
|
+
const timeoutId = timeoutMs > 0 ? setTimeout(() => controller.abort(), timeoutMs) : null;
|
|
2953
2972
|
try {
|
|
2954
2973
|
const response = await fetch(this.getOperatorStreamUrl(baseUrl), {
|
|
2955
2974
|
method: 'POST',
|
|
@@ -3096,7 +3115,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
3096
3115
|
errors.push(`${baseUrl}: ${error?.message || String(error)}`);
|
|
3097
3116
|
}
|
|
3098
3117
|
finally {
|
|
3099
|
-
|
|
3118
|
+
if (timeoutId) {
|
|
3119
|
+
clearTimeout(timeoutId);
|
|
3120
|
+
}
|
|
3100
3121
|
}
|
|
3101
3122
|
}
|
|
3102
3123
|
throw new CLIError(`Operator workflow failed on all endpoints: ${errors.join(' | ')}`, 'model_backend');
|