vigthoria-cli 1.12.2 → 1.13.6
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.d.ts +3 -1
- package/dist/commands/chat.js +43 -43
- package/dist/commands/game.d.ts +26 -0
- package/dist/commands/game.js +113 -0
- package/dist/commands/repo.d.ts +9 -1
- package/dist/commands/repo.js +178 -29
- package/dist/commands/v4.d.ts +3 -0
- package/dist/commands/v4.js +12 -0
- package/dist/index.js +123 -59
- package/dist/utils/api.d.ts +1 -0
- package/dist/utils/api.js +83 -27
- package/dist/utils/brain-hub-client.js +42 -14
- package/dist/utils/codebase-indexer.js +29 -6
- package/dist/utils/command-menu.d.ts +11 -0
- package/dist/utils/command-menu.js +97 -0
- package/dist/utils/deckEvents.js +7 -1
- package/dist/utils/logger.js +6 -1
- package/dist/utils/requestIntent.d.ts +4 -0
- package/dist/utils/requestIntent.js +16 -1
- package/dist/utils/tools.js +18 -0
- package/package.json +6 -3
package/dist/commands/repo.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Vigthoria CLI - Repo Commands
|
|
3
3
|
*
|
|
4
|
-
* Push and pull projects to/from Vigthoria Repository
|
|
4
|
+
* Push and pull projects to/from Vigthoria Community Repository
|
|
5
5
|
* Enables version control and project sharing through the Vigthoria platform
|
|
6
6
|
*
|
|
7
7
|
* Usage:
|
|
@@ -21,6 +21,32 @@ const require = createRequire(import.meta.url);
|
|
|
21
21
|
import inquirer from 'inquirer';
|
|
22
22
|
import archiver from 'archiver';
|
|
23
23
|
import { createWriteStream } from 'fs';
|
|
24
|
+
const MAX_REPOSITORY_CONTENT_BYTES = 100 * 1024 * 1024;
|
|
25
|
+
const MAX_REPOSITORY_REQUEST_BYTES = 120 * 1024 * 1024;
|
|
26
|
+
class RepositoryApiError extends Error {
|
|
27
|
+
status;
|
|
28
|
+
payload;
|
|
29
|
+
constructor(status, payload, fallback) {
|
|
30
|
+
super(payload?.error || payload?.message || fallback);
|
|
31
|
+
this.name = 'RepositoryApiError';
|
|
32
|
+
this.status = status;
|
|
33
|
+
this.payload = payload || {};
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function formatBytes(bytes) {
|
|
37
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MiB`;
|
|
38
|
+
}
|
|
39
|
+
async function readResponsePayload(response) {
|
|
40
|
+
const rawBody = await response.text();
|
|
41
|
+
if (!rawBody)
|
|
42
|
+
return {};
|
|
43
|
+
try {
|
|
44
|
+
return JSON.parse(rawBody);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return { error: rawBody };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
24
50
|
export class RepoCommand {
|
|
25
51
|
config;
|
|
26
52
|
logger;
|
|
@@ -73,7 +99,11 @@ export class RepoCommand {
|
|
|
73
99
|
...(init.headers || {})
|
|
74
100
|
}
|
|
75
101
|
});
|
|
76
|
-
|
|
102
|
+
// Both 401 (missing/expired credentials) and 403 (a valid Coder
|
|
103
|
+
// token that Community cannot accept) must activate the explicit
|
|
104
|
+
// Community credential fallback. Previously a stale/incompatible
|
|
105
|
+
// Coder token made configured Community credentials unreachable.
|
|
106
|
+
if ([401, 403].includes(response.status) && allowCommunityAuthRetry && !this.communityToken) {
|
|
77
107
|
await this.ensureCommunityAuth();
|
|
78
108
|
if (this.communityToken) {
|
|
79
109
|
return attempt(url, false);
|
|
@@ -83,9 +113,16 @@ export class RepoCommand {
|
|
|
83
113
|
};
|
|
84
114
|
try {
|
|
85
115
|
const proxyResponse = await attempt(proxyPath, true);
|
|
86
|
-
|
|
116
|
+
// A large repository payload can exceed the Coder API's general
|
|
117
|
+
// 50 MiB parser while remaining valid under Community's 100 MiB
|
|
118
|
+
// repository contract. Retry that one status directly.
|
|
119
|
+
const shouldTryDirectCommunity = [401, 403, 404, 413].includes(proxyResponse.status);
|
|
120
|
+
if (proxyResponse.ok || (proxyResponse.status < 500 && !shouldTryDirectCommunity)) {
|
|
87
121
|
return proxyResponse;
|
|
88
122
|
}
|
|
123
|
+
if (shouldTryDirectCommunity) {
|
|
124
|
+
await proxyResponse.body?.cancel();
|
|
125
|
+
}
|
|
89
126
|
}
|
|
90
127
|
catch {
|
|
91
128
|
// fall through to direct community endpoint
|
|
@@ -111,13 +148,32 @@ export class RepoCommand {
|
|
|
111
148
|
continue;
|
|
112
149
|
}
|
|
113
150
|
try {
|
|
151
|
+
const raw = fs.readFileSync(fullPath);
|
|
152
|
+
let content;
|
|
153
|
+
let encoding;
|
|
154
|
+
try {
|
|
155
|
+
const sample = new TextDecoder('utf-8', { fatal: true }).decode(raw.subarray(0, Math.min(raw.length, 64 * 1024)));
|
|
156
|
+
const controlCharacters = sample.match(/[\u0000-\u0008\u000B\u000C\u000E-\u001F]/g)?.length || 0;
|
|
157
|
+
const looksBinary = sample.includes('\u0000')
|
|
158
|
+
|| (sample.length > 0 && controlCharacters / sample.length > 0.01);
|
|
159
|
+
if (looksBinary)
|
|
160
|
+
throw new Error('binary content');
|
|
161
|
+
content = new TextDecoder('utf-8', { fatal: true }).decode(raw);
|
|
162
|
+
encoding = 'utf8';
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
content = raw.toString('base64');
|
|
166
|
+
encoding = 'base64';
|
|
167
|
+
}
|
|
114
168
|
files.push({
|
|
115
169
|
path: relativePath,
|
|
116
|
-
content
|
|
170
|
+
content,
|
|
171
|
+
encoding,
|
|
172
|
+
size: raw.length,
|
|
117
173
|
});
|
|
118
174
|
}
|
|
119
175
|
catch {
|
|
120
|
-
// Skip
|
|
176
|
+
// Skip unreadable files. Binary files are transported as base64.
|
|
121
177
|
}
|
|
122
178
|
}
|
|
123
179
|
};
|
|
@@ -129,7 +185,7 @@ export class RepoCommand {
|
|
|
129
185
|
method: 'GET'
|
|
130
186
|
});
|
|
131
187
|
if (!response.ok) {
|
|
132
|
-
const error = await
|
|
188
|
+
const error = await readResponsePayload(response);
|
|
133
189
|
throw new Error(error.error || error.message || 'Failed to fetch repositories');
|
|
134
190
|
}
|
|
135
191
|
const data = await response.json();
|
|
@@ -152,6 +208,9 @@ export class RepoCommand {
|
|
|
152
208
|
return match;
|
|
153
209
|
}
|
|
154
210
|
formatRepoError(error) {
|
|
211
|
+
if (error instanceof RepositoryApiError && error.payload?.code === 'REPOSITORY_SECURITY_REVIEW') {
|
|
212
|
+
return 'Repository is isolated pending security review. See the review details above.';
|
|
213
|
+
}
|
|
155
214
|
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
156
215
|
if (/invalid or expired session/i.test(message)) {
|
|
157
216
|
return 'Repo memory service is not deployed or not reachable. Check `vigthoria status` for details.';
|
|
@@ -159,8 +218,37 @@ export class RepoCommand {
|
|
|
159
218
|
if (/ECONNREFUSED|ENOTFOUND|ETIMEDOUT|socket hang up/i.test(message)) {
|
|
160
219
|
return 'Repo memory service is not reachable. Check `vigthoria status` for details.';
|
|
161
220
|
}
|
|
221
|
+
if (/PayloadTooLargeError|request entity too large|PAYLOAD_TOO_LARGE|REPOSITORY_CONTENT_TOO_LARGE|exceeds the .*MiB/i.test(message)) {
|
|
222
|
+
return 'Project is too large for a single Community repository push. The limit is 100 MiB of readable project content and 120 MiB for the encoded request. Exclude generated output or split large assets, then retry.';
|
|
223
|
+
}
|
|
162
224
|
return message;
|
|
163
225
|
}
|
|
226
|
+
printSecurityReview(review) {
|
|
227
|
+
console.log(chalk.yellow('\n🛡 Repository security review required'));
|
|
228
|
+
console.log(chalk.gray(` Review ID: ${review.reviewId}`));
|
|
229
|
+
console.log(chalk.gray(` Status: ${review.status}`));
|
|
230
|
+
if (review.projectName)
|
|
231
|
+
console.log(chalk.gray(` Project: ${review.projectName}`));
|
|
232
|
+
if (review.riskScore !== undefined)
|
|
233
|
+
console.log(chalk.gray(` Risk score: ${review.riskScore}/100`));
|
|
234
|
+
if (review.reviewerFeedback) {
|
|
235
|
+
console.log(chalk.white(`\n Reviewer feedback: ${review.reviewerFeedback}`));
|
|
236
|
+
}
|
|
237
|
+
for (const entry of review.findings || []) {
|
|
238
|
+
for (const finding of entry.findings || []) {
|
|
239
|
+
const location = entry.path ? `${entry.path}: ` : '';
|
|
240
|
+
console.log(chalk.yellow(` • ${location}${finding.message || finding.type || 'Review required'}`));
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
if ((review.actionItems || []).length > 0) {
|
|
244
|
+
console.log(chalk.cyan('\n What to fix:'));
|
|
245
|
+
for (const item of review.actionItems || []) {
|
|
246
|
+
console.log(chalk.gray(` - ${item}`));
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
console.log(chalk.cyan(`\n Check status: vigthoria repo review ${review.reviewId}`));
|
|
250
|
+
console.log(chalk.cyan(` Retry fixed content: ${review.retryCommand || `vigthoria repo push --retry ${review.reviewId}`}\n`));
|
|
251
|
+
}
|
|
164
252
|
isAuthenticated() {
|
|
165
253
|
const token = this.config.get('authToken');
|
|
166
254
|
return !!token;
|
|
@@ -321,7 +409,7 @@ export class RepoCommand {
|
|
|
321
409
|
{
|
|
322
410
|
type: 'confirm',
|
|
323
411
|
name: 'confirm',
|
|
324
|
-
message: 'Push project to Vigthoria
|
|
412
|
+
message: 'Push project to Vigthoria Community Repository?',
|
|
325
413
|
default: true
|
|
326
414
|
}
|
|
327
415
|
]);
|
|
@@ -332,24 +420,35 @@ export class RepoCommand {
|
|
|
332
420
|
const uploadSpinner = createSpinner('Preparing project files...').start();
|
|
333
421
|
const files = this.collectProjectFiles(projectPath);
|
|
334
422
|
if (files.length === 0) {
|
|
335
|
-
throw new Error('No readable
|
|
423
|
+
throw new Error('No readable project files found to push');
|
|
336
424
|
}
|
|
337
|
-
|
|
425
|
+
const contentBytes = files.reduce((sum, file) => sum + file.size, 0);
|
|
426
|
+
if (contentBytes > MAX_REPOSITORY_CONTENT_BYTES) {
|
|
427
|
+
throw new Error(`Repository content is ${formatBytes(contentBytes)} and exceeds the ${formatBytes(MAX_REPOSITORY_CONTENT_BYTES)} limit`);
|
|
428
|
+
}
|
|
429
|
+
const pushPayload = JSON.stringify({
|
|
430
|
+
projectName: answers.name,
|
|
431
|
+
description: answers.description,
|
|
432
|
+
techStack: projectInfo.techStack.join(', '),
|
|
433
|
+
visibility: answers.visibility,
|
|
434
|
+
force: options.force || false,
|
|
435
|
+
files,
|
|
436
|
+
retryOf: options.retry || undefined,
|
|
437
|
+
clientSource: process.env.VIGTHORIA_CLIENT_SOURCE || 'community-cli',
|
|
438
|
+
commitMessage: `Push from Vigthoria CLI: ${files.length} file(s)`
|
|
439
|
+
});
|
|
440
|
+
const requestBytes = Buffer.byteLength(pushPayload, 'utf8');
|
|
441
|
+
if (requestBytes > MAX_REPOSITORY_REQUEST_BYTES) {
|
|
442
|
+
throw new Error(`Encoded repository request is ${formatBytes(requestBytes)} and exceeds the ${formatBytes(MAX_REPOSITORY_REQUEST_BYTES)} limit`);
|
|
443
|
+
}
|
|
444
|
+
uploadSpinner.text = `Uploading ${files.length} file(s), ${formatBytes(contentBytes)} to Vigthoria Community...`;
|
|
338
445
|
const registerResponse = await this.repoFetch('/api/repo/push', {
|
|
339
446
|
method: 'POST',
|
|
340
|
-
body:
|
|
341
|
-
projectName: answers.name,
|
|
342
|
-
description: answers.description,
|
|
343
|
-
techStack: projectInfo.techStack.join(', '),
|
|
344
|
-
visibility: answers.visibility,
|
|
345
|
-
force: options.force || false,
|
|
346
|
-
files,
|
|
347
|
-
commitMessage: `Push from Vigthoria CLI: ${files.length} file(s)`
|
|
348
|
-
})
|
|
447
|
+
body: pushPayload
|
|
349
448
|
});
|
|
350
449
|
if (!registerResponse.ok) {
|
|
351
|
-
const error = await
|
|
352
|
-
throw new
|
|
450
|
+
const error = await readResponsePayload(registerResponse);
|
|
451
|
+
throw new RepositoryApiError(registerResponse.status, error, 'Failed to push project');
|
|
353
452
|
}
|
|
354
453
|
const registerData = await registerResponse.json();
|
|
355
454
|
uploadSpinner.succeed(chalk.green('Project pushed successfully!'));
|
|
@@ -362,15 +461,65 @@ export class RepoCommand {
|
|
|
362
461
|
if ((registerData.project?.visibility || answers.visibility) === 'public') {
|
|
363
462
|
console.log(chalk.cyan(`\n🔗 Public URL: ${registerData.url || `https://community.vigthoria.io/showcase/${registerData.project?.id || registerData.projectId}`}`));
|
|
364
463
|
}
|
|
365
|
-
console.log(chalk.gray('\
|
|
464
|
+
console.log(chalk.gray('\nStored in Vigthoria Community. Use `vigthoria repo pull <name>` to restore this project anywhere.\n'));
|
|
366
465
|
}
|
|
367
466
|
catch (error) {
|
|
368
467
|
spinner.stop();
|
|
369
468
|
this.logger.error('Push failed');
|
|
469
|
+
if (error instanceof RepositoryApiError && error.payload?.code === 'REPOSITORY_SECURITY_REVIEW') {
|
|
470
|
+
this.printSecurityReview({
|
|
471
|
+
reviewId: error.payload.reviewId,
|
|
472
|
+
status: error.payload.status || 'pending_review',
|
|
473
|
+
riskScore: error.payload.riskScore,
|
|
474
|
+
findings: error.payload.findings,
|
|
475
|
+
actionItems: error.payload.actionItems,
|
|
476
|
+
retryCommand: error.payload.retryCommand,
|
|
477
|
+
});
|
|
478
|
+
}
|
|
370
479
|
const errMsg = this.formatRepoError(error);
|
|
371
480
|
console.log(chalk.red(`\n❌ Error: ${errMsg}\n`));
|
|
372
481
|
}
|
|
373
482
|
}
|
|
483
|
+
/**
|
|
484
|
+
* Show the current user's repository security review queue or one review.
|
|
485
|
+
*/
|
|
486
|
+
async review(reviewId, options = {}) {
|
|
487
|
+
this.requireAuth();
|
|
488
|
+
const spinner = createSpinner(reviewId ? 'Loading security review...' : 'Loading security reviews...').start();
|
|
489
|
+
try {
|
|
490
|
+
const apiPath = reviewId
|
|
491
|
+
? `/api/repo/security-reviews/${encodeURIComponent(reviewId)}`
|
|
492
|
+
: '/api/repo/security-reviews?mine=true';
|
|
493
|
+
const response = await this.repoFetch(apiPath, { method: 'GET' });
|
|
494
|
+
const payload = await readResponsePayload(response);
|
|
495
|
+
if (!response.ok) {
|
|
496
|
+
throw new RepositoryApiError(response.status, payload, 'Failed to load repository security review');
|
|
497
|
+
}
|
|
498
|
+
spinner.stop();
|
|
499
|
+
if (options.json) {
|
|
500
|
+
console.log(JSON.stringify(reviewId ? payload.review : payload.reviews, null, 2));
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
if (reviewId) {
|
|
504
|
+
this.printSecurityReview(payload.review);
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
const reviews = (payload.reviews || []);
|
|
508
|
+
if (reviews.length === 0) {
|
|
509
|
+
console.log(chalk.green('\n✓ No repository security reviews found.\n'));
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
console.log(chalk.cyan(`\nRepository security reviews (${reviews.length})`));
|
|
513
|
+
for (const review of reviews) {
|
|
514
|
+
console.log(chalk.gray(` ${review.reviewId} ${review.status} ${review.projectName || 'repository'}`));
|
|
515
|
+
}
|
|
516
|
+
console.log(chalk.gray('\nUse `vigthoria repo review <review-id>` for findings and repair steps.\n'));
|
|
517
|
+
}
|
|
518
|
+
catch (error) {
|
|
519
|
+
spinner.stop();
|
|
520
|
+
console.log(chalk.red(`\n❌ Error: ${this.formatRepoError(error)}\n`));
|
|
521
|
+
}
|
|
522
|
+
}
|
|
374
523
|
/**
|
|
375
524
|
* Pull a project from Vigthoria Repository
|
|
376
525
|
*/
|
|
@@ -384,7 +533,7 @@ export class RepoCommand {
|
|
|
384
533
|
body: JSON.stringify({ projectId: repo.id })
|
|
385
534
|
});
|
|
386
535
|
if (!response.ok) {
|
|
387
|
-
const error = await
|
|
536
|
+
const error = await readResponsePayload(response);
|
|
388
537
|
throw new Error(error.error || error.message || 'Project not found');
|
|
389
538
|
}
|
|
390
539
|
const data = await response.json();
|
|
@@ -478,14 +627,14 @@ export class RepoCommand {
|
|
|
478
627
|
};
|
|
479
628
|
spinner.stop();
|
|
480
629
|
if (data.projects.length === 0) {
|
|
481
|
-
console.log(chalk.yellow('\n📦 No projects in your Vigthoria
|
|
630
|
+
console.log(chalk.yellow('\n📦 No projects in your Vigthoria Community Repository yet.\n'));
|
|
482
631
|
console.log(chalk.gray('Use `vigthoria repo push` to upload your first project.\n'));
|
|
483
632
|
return;
|
|
484
633
|
}
|
|
485
634
|
// Separate owned and shared projects
|
|
486
635
|
const ownedProjects = data.owned || data.projects.filter((p) => p.access_level === 'owner');
|
|
487
636
|
const sharedProjects = data.shared || data.projects.filter((p) => p.access_level !== 'owner');
|
|
488
|
-
console.log(chalk.cyan(`\n📦 Your Vigthoria Repository (${data.total} project${data.total !== 1 ? 's' : ''})\n`));
|
|
637
|
+
console.log(chalk.cyan(`\n📦 Your Vigthoria Community Repository (${data.total} project${data.total !== 1 ? 's' : ''})\n`));
|
|
489
638
|
// Display owned projects grouped by visibility
|
|
490
639
|
if (ownedProjects.length > 0) {
|
|
491
640
|
console.log(chalk.bold.cyan(' 📁 YOUR PROJECTS'));
|
|
@@ -572,8 +721,8 @@ export class RepoCommand {
|
|
|
572
721
|
headers: this.getAuthHeaders()
|
|
573
722
|
});
|
|
574
723
|
if (!response.ok) {
|
|
575
|
-
spinner.succeed('Project not tracked in Vigthoria
|
|
576
|
-
console.log(chalk.yellow('\n📦 Current project is not synced with Vigthoria
|
|
724
|
+
spinner.succeed('Project not tracked in Vigthoria Community Repository');
|
|
725
|
+
console.log(chalk.yellow('\n📦 Current project is not synced with Vigthoria Community Repository.\n'));
|
|
577
726
|
console.log(chalk.gray('Use `vigthoria repo push` to upload it.\n'));
|
|
578
727
|
return;
|
|
579
728
|
}
|
|
@@ -650,7 +799,7 @@ export class RepoCommand {
|
|
|
650
799
|
const { confirm } = await inquirer.prompt([{
|
|
651
800
|
type: 'confirm',
|
|
652
801
|
name: 'confirm',
|
|
653
|
-
message: chalk.red(`Are you sure you want to delete "${projectName}" from Vigthoria
|
|
802
|
+
message: chalk.red(`Are you sure you want to delete "${projectName}" from Vigthoria Community Repository?`),
|
|
654
803
|
default: false
|
|
655
804
|
}]);
|
|
656
805
|
if (!confirm) {
|
|
@@ -667,7 +816,7 @@ export class RepoCommand {
|
|
|
667
816
|
const error = await response.json();
|
|
668
817
|
throw new Error(error.error || 'Failed to delete project');
|
|
669
818
|
}
|
|
670
|
-
spinner.succeed(chalk.green('Project deleted from Vigthoria
|
|
819
|
+
spinner.succeed(chalk.green('Project deleted from Vigthoria Community Repository'));
|
|
671
820
|
console.log(chalk.gray('\nNote: Your local files are not affected.\n'));
|
|
672
821
|
}
|
|
673
822
|
catch (error) {
|
|
@@ -704,7 +853,7 @@ export class RepoCommand {
|
|
|
704
853
|
})
|
|
705
854
|
});
|
|
706
855
|
if (!response.ok) {
|
|
707
|
-
const err = await
|
|
856
|
+
const err = await readResponsePayload(response);
|
|
708
857
|
throw new Error(err.error || `Engine import failed (${response.status})`);
|
|
709
858
|
}
|
|
710
859
|
const data = await response.json();
|
package/dist/commands/v4.d.ts
CHANGED
package/dist/commands/v4.js
CHANGED
|
@@ -38,6 +38,9 @@ export class V4Command {
|
|
|
38
38
|
.option('--transport <mode>', 'Bridge transport: auto | ws | sse', 'auto')
|
|
39
39
|
.option('--harness-stream-url <url>', 'Override harness stream URL')
|
|
40
40
|
.option('--harness-control-url <url>', 'Override harness control URL')
|
|
41
|
+
.option('--gateway-url <url>', 'DeerFlow Gateway URL')
|
|
42
|
+
.option('--prompt <text>', 'Task prompt to execute')
|
|
43
|
+
.option('--workspace <path>', 'Workspace path', process.cwd())
|
|
41
44
|
.option('--session-id <id>', 'Explicit V4 session id')
|
|
42
45
|
.option('--non-interactive', 'Disable interactive menu and use CLI options', false)
|
|
43
46
|
.option('--python <bin>', 'Python binary to use', defaultV4PythonBin())
|
|
@@ -82,6 +85,15 @@ export class V4Command {
|
|
|
82
85
|
if (options.harnessControlUrl) {
|
|
83
86
|
args.push('--harness-control-url', String(options.harnessControlUrl));
|
|
84
87
|
}
|
|
88
|
+
if (options.gatewayUrl) {
|
|
89
|
+
args.push('--gateway-url', String(options.gatewayUrl));
|
|
90
|
+
}
|
|
91
|
+
if (options.prompt) {
|
|
92
|
+
args.push('--prompt', String(options.prompt));
|
|
93
|
+
}
|
|
94
|
+
if (options.workspace) {
|
|
95
|
+
args.push('--workspace', path.resolve(String(options.workspace)));
|
|
96
|
+
}
|
|
85
97
|
if (options.sessionId) {
|
|
86
98
|
args.push('--session-id', String(options.sessionId));
|
|
87
99
|
}
|