vigthoria-cli 1.9.2 → 1.9.5
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 +15 -5
- package/dist/commands/auth.d.ts +28 -38
- package/dist/commands/auth.js +389 -320
- package/dist/commands/chat.d.ts +3 -0
- package/dist/commands/chat.js +66 -15
- package/dist/commands/index.js +1 -1
- package/dist/commands/legion.d.ts +22 -19
- package/dist/commands/legion.js +550 -132
- package/dist/commands/preview.js +32 -7
- package/dist/commands/repo.js +19 -13
- package/dist/commands/update.d.ts +9 -0
- package/dist/commands/update.js +235 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +114 -33
- package/dist/utils/api.d.ts +25 -70
- package/dist/utils/api.js +784 -695
- package/dist/utils/tools.d.ts +11 -0
- package/dist/utils/tools.js +222 -0
- package/package.json +7 -1
package/dist/utils/tools.d.ts
CHANGED
|
@@ -14,6 +14,17 @@
|
|
|
14
14
|
* @author Vigthoria Labs
|
|
15
15
|
*/
|
|
16
16
|
import { Logger } from './logger.js';
|
|
17
|
+
export type StreamChunk = {
|
|
18
|
+
type: 'text' | 'delta' | 'error';
|
|
19
|
+
content: string;
|
|
20
|
+
};
|
|
21
|
+
export type UpdateInstallerResult = {
|
|
22
|
+
success: boolean;
|
|
23
|
+
platform: string;
|
|
24
|
+
error?: string;
|
|
25
|
+
};
|
|
26
|
+
export declare function installUpdateWindows(): Promise<UpdateInstallerResult>;
|
|
27
|
+
export declare function robustifyStreamResponse(res: any): AsyncIterable<StreamChunk>;
|
|
17
28
|
export type RiskLevel = 'low' | 'medium' | 'high' | 'critical';
|
|
18
29
|
export type SearchStatus = 'search_matches_found' | 'search_no_matches' | 'search_failed';
|
|
19
30
|
export interface ToolResult {
|
package/dist/utils/tools.js
CHANGED
|
@@ -52,12 +52,234 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
52
52
|
};
|
|
53
53
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
54
54
|
exports.AgenticTools = exports.ToolErrorType = void 0;
|
|
55
|
+
exports.installUpdateWindows = installUpdateWindows;
|
|
56
|
+
exports.robustifyStreamResponse = robustifyStreamResponse;
|
|
55
57
|
const fs = __importStar(require("fs"));
|
|
56
58
|
const path = __importStar(require("path"));
|
|
57
59
|
const child_process_1 = require("child_process");
|
|
58
60
|
const chalk_1 = __importDefault(require("chalk"));
|
|
59
61
|
const logger_js_1 = require("./logger.js");
|
|
60
62
|
const api_js_1 = require("./api.js");
|
|
63
|
+
const STREAM_RESPONSE_MAX_YIELD_CHARS = 32 * 1024;
|
|
64
|
+
function isNodeError(error) {
|
|
65
|
+
return error instanceof Error && 'code' in error;
|
|
66
|
+
}
|
|
67
|
+
function resolveWindowsInstallerPath() {
|
|
68
|
+
const configuredPath = process.env.VIGTHORIA_WINDOWS_INSTALLER || process.env.VIGTHORIA_UPDATE_INSTALLER;
|
|
69
|
+
if (configuredPath && configuredPath.trim().length > 0) {
|
|
70
|
+
return path.resolve(configuredPath);
|
|
71
|
+
}
|
|
72
|
+
const executableDir = path.dirname(process.execPath);
|
|
73
|
+
const cwd = process.cwd();
|
|
74
|
+
const candidates = [
|
|
75
|
+
path.resolve(cwd, 'dist', 'VigthoriaSetup.exe'),
|
|
76
|
+
path.resolve(cwd, 'release', 'VigthoriaSetup.exe'),
|
|
77
|
+
path.resolve(cwd, 'VigthoriaSetup.exe'),
|
|
78
|
+
path.resolve(executableDir, 'VigthoriaSetup.exe'),
|
|
79
|
+
path.resolve(executableDir, '..', 'VigthoriaSetup.exe'),
|
|
80
|
+
];
|
|
81
|
+
return candidates.find((candidate) => fs.existsSync(candidate)) ?? candidates[0];
|
|
82
|
+
}
|
|
83
|
+
async function installUpdateWindows() {
|
|
84
|
+
const installerPath = resolveWindowsInstallerPath();
|
|
85
|
+
try {
|
|
86
|
+
if (!fs.existsSync(installerPath)) {
|
|
87
|
+
return { success: false, platform: 'windows', error: 'ENOENT' };
|
|
88
|
+
}
|
|
89
|
+
await fs.promises.access(installerPath, fs.constants.F_OK);
|
|
90
|
+
await new Promise((resolve, reject) => {
|
|
91
|
+
const child = (0, child_process_1.spawn)(installerPath, [], {
|
|
92
|
+
cwd: path.dirname(installerPath),
|
|
93
|
+
detached: true,
|
|
94
|
+
stdio: 'ignore',
|
|
95
|
+
windowsHide: false,
|
|
96
|
+
});
|
|
97
|
+
child.once('error', reject);
|
|
98
|
+
child.once('spawn', () => {
|
|
99
|
+
child.unref();
|
|
100
|
+
resolve();
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
return { success: true, platform: 'windows' };
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
if (isNodeError(error) && error.code === 'ENOENT') {
|
|
107
|
+
return { success: false, platform: 'windows', error: 'ENOENT' };
|
|
108
|
+
}
|
|
109
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
110
|
+
return { success: false, platform: 'windows', error: message };
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async function* robustifyStreamResponse(res) {
|
|
114
|
+
const MAX_YIELD_CHARS = STREAM_RESPONSE_MAX_YIELD_CHARS;
|
|
115
|
+
const MAX_BUFFER_CHARS = 256 * 1024;
|
|
116
|
+
const body = res?.body ?? res;
|
|
117
|
+
const decoder = new TextDecoder('utf-8');
|
|
118
|
+
let reader = null;
|
|
119
|
+
let lineBuffer = '';
|
|
120
|
+
const emitContent = async function* (type, content) {
|
|
121
|
+
for (let offset = 0; offset < content.length; offset += MAX_YIELD_CHARS) {
|
|
122
|
+
const part = content.slice(offset, offset + MAX_YIELD_CHARS);
|
|
123
|
+
if (part.length > 0) {
|
|
124
|
+
yield { type, content: part };
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
const textFromObject = (value) => {
|
|
129
|
+
if (!value || typeof value !== 'object')
|
|
130
|
+
return '';
|
|
131
|
+
if (typeof value.content === 'string')
|
|
132
|
+
return value.content;
|
|
133
|
+
if (typeof value.text === 'string')
|
|
134
|
+
return value.text;
|
|
135
|
+
if (typeof value.delta === 'string')
|
|
136
|
+
return value.delta;
|
|
137
|
+
if (typeof value.delta?.text === 'string')
|
|
138
|
+
return value.delta.text;
|
|
139
|
+
if (typeof value.message?.content === 'string')
|
|
140
|
+
return value.message.content;
|
|
141
|
+
if (typeof value.choices?.[0]?.delta?.content === 'string')
|
|
142
|
+
return value.choices[0].delta.content;
|
|
143
|
+
if (typeof value.choices?.[0]?.message?.content === 'string')
|
|
144
|
+
return value.choices[0].message.content;
|
|
145
|
+
if (typeof value.error === 'string')
|
|
146
|
+
return value.error;
|
|
147
|
+
if (typeof value.error?.message === 'string')
|
|
148
|
+
return value.error.message;
|
|
149
|
+
return '';
|
|
150
|
+
};
|
|
151
|
+
const stringifyChunk = (chunk) => {
|
|
152
|
+
if (typeof chunk === 'string')
|
|
153
|
+
return chunk;
|
|
154
|
+
if (Buffer.isBuffer(chunk))
|
|
155
|
+
return chunk.toString('utf8');
|
|
156
|
+
if (chunk instanceof Uint8Array)
|
|
157
|
+
return Buffer.from(chunk).toString('utf8');
|
|
158
|
+
if (chunk instanceof ArrayBuffer)
|
|
159
|
+
return Buffer.from(chunk).toString('utf8');
|
|
160
|
+
if (chunk === null || chunk === undefined)
|
|
161
|
+
return '';
|
|
162
|
+
const objectText = textFromObject(chunk);
|
|
163
|
+
return objectText || String(chunk);
|
|
164
|
+
};
|
|
165
|
+
const decodeLine = (line) => {
|
|
166
|
+
const trimmed = line.trim();
|
|
167
|
+
if (!trimmed || trimmed === 'event: ping' || trimmed === ':' || trimmed === 'data: [DONE]' || trimmed === '[DONE]') {
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
const payload = trimmed.startsWith('data:') ? trimmed.slice(5).trimStart() : trimmed;
|
|
171
|
+
if (!payload || payload === '[DONE]')
|
|
172
|
+
return null;
|
|
173
|
+
if ((payload.startsWith('{') && payload.endsWith('}')) || (payload.startsWith('[') && payload.endsWith(']'))) {
|
|
174
|
+
try {
|
|
175
|
+
const parsed = JSON.parse(payload);
|
|
176
|
+
const parsedText = textFromObject(parsed);
|
|
177
|
+
if (parsedText) {
|
|
178
|
+
const type = parsed.error ? 'error' : 'delta';
|
|
179
|
+
return { type, content: parsedText };
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
console.debug(`Stream JSON fragment preserved as text: ${error instanceof Error ? error.message : String(error)}`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
if (payload.startsWith('event:') || payload.startsWith('id:') || payload.startsWith('retry:')) {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
return { type: 'delta', content: payload };
|
|
190
|
+
};
|
|
191
|
+
const consumeText = async function* (text, flush = false) {
|
|
192
|
+
if (text) {
|
|
193
|
+
lineBuffer += text;
|
|
194
|
+
}
|
|
195
|
+
while (lineBuffer.length > MAX_BUFFER_CHARS) {
|
|
196
|
+
const newlineIndex = lineBuffer.indexOf('\n', Math.max(0, MAX_BUFFER_CHARS - MAX_YIELD_CHARS));
|
|
197
|
+
const cutIndex = newlineIndex >= 0 ? newlineIndex + 1 : MAX_BUFFER_CHARS;
|
|
198
|
+
const overflow = lineBuffer.slice(0, cutIndex);
|
|
199
|
+
lineBuffer = lineBuffer.slice(cutIndex);
|
|
200
|
+
const decoded = decodeLine(overflow);
|
|
201
|
+
if (decoded) {
|
|
202
|
+
yield* emitContent(decoded.type, decoded.content);
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
yield* emitContent('delta', overflow);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
const lines = lineBuffer.split(/\r?\n/);
|
|
209
|
+
const partialLine = lines.pop() ?? '';
|
|
210
|
+
for (const line of lines) {
|
|
211
|
+
const decoded = decodeLine(line);
|
|
212
|
+
if (decoded) {
|
|
213
|
+
yield* emitContent(decoded.type, decoded.content);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if (flush) {
|
|
217
|
+
lineBuffer = '';
|
|
218
|
+
if (partialLine) {
|
|
219
|
+
const decoded = decodeLine(partialLine);
|
|
220
|
+
if (decoded) {
|
|
221
|
+
yield* emitContent(decoded.type, decoded.content);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
lineBuffer = partialLine;
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
try {
|
|
230
|
+
if (!body) {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
if (typeof body.getReader === 'function') {
|
|
234
|
+
reader = body.getReader();
|
|
235
|
+
const streamReader = reader;
|
|
236
|
+
const decoder = new TextDecoder();
|
|
237
|
+
while (true) {
|
|
238
|
+
const { done, value } = await streamReader.read();
|
|
239
|
+
if (done)
|
|
240
|
+
break;
|
|
241
|
+
const content = decoder.decode(value, { stream: true });
|
|
242
|
+
if (content.length > 0) {
|
|
243
|
+
yield* consumeText(content);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
const tail = decoder.decode();
|
|
247
|
+
if (tail.length > 0) {
|
|
248
|
+
yield* consumeText(tail);
|
|
249
|
+
}
|
|
250
|
+
yield* consumeText('', true);
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
if (typeof body[Symbol.asyncIterator] === 'function') {
|
|
254
|
+
for await (const chunk of body) {
|
|
255
|
+
const content = stringifyChunk(chunk);
|
|
256
|
+
if (content.length > 0) {
|
|
257
|
+
yield* consumeText(content);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
yield* consumeText('', true);
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
const content = stringifyChunk(body);
|
|
264
|
+
if (content.length > 0) {
|
|
265
|
+
yield* emitContent('text', content);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
catch (error) {
|
|
269
|
+
const content = error instanceof Error ? error.message : String(error);
|
|
270
|
+
yield { type: 'error', content };
|
|
271
|
+
}
|
|
272
|
+
finally {
|
|
273
|
+
lineBuffer = '';
|
|
274
|
+
try {
|
|
275
|
+
reader?.releaseLock();
|
|
276
|
+
}
|
|
277
|
+
catch (error) {
|
|
278
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
279
|
+
console.debug(`Stream reader release failed: ${message}`);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
61
283
|
const TOOL_ARG_ALIASES = {
|
|
62
284
|
read_file: {
|
|
63
285
|
path: ['file', 'filePath', 'filepath', 'target', 'targetPath'],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vigthoria-cli",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.5",
|
|
4
4
|
"description": "Vigthoria Coder CLI - AI-powered terminal coding assistant",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"files": [
|
|
@@ -9,6 +9,12 @@
|
|
|
9
9
|
"SECURITY_HARDENING.md",
|
|
10
10
|
"CLI_DIRECT_API_ARCHITECTURE.md"
|
|
11
11
|
],
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"files": [
|
|
14
|
+
"dist/",
|
|
15
|
+
"package.json"
|
|
16
|
+
]
|
|
17
|
+
},
|
|
12
18
|
"bin": {
|
|
13
19
|
"vigthoria": "dist/index.js",
|
|
14
20
|
"vig": "dist/index.js",
|