vigthoria-cli 1.10.37 → 1.10.47
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/agent-session-menu.d.ts +19 -0
- package/dist/commands/agent-session-menu.js +155 -0
- package/dist/commands/auth.js +68 -51
- package/dist/commands/bridge.js +19 -12
- package/dist/commands/cancel.js +22 -15
- package/dist/commands/chat.d.ts +0 -28
- package/dist/commands/chat.js +407 -1254
- package/dist/commands/config.js +73 -33
- package/dist/commands/deploy.js +123 -83
- package/dist/commands/device.js +61 -21
- package/dist/commands/edit.js +39 -32
- package/dist/commands/explain.js +25 -18
- package/dist/commands/generate.js +44 -37
- package/dist/commands/hub.js +102 -95
- package/dist/commands/index.js +46 -41
- package/dist/commands/legion.js +186 -146
- package/dist/commands/review.js +36 -29
- package/dist/commands/security.js +12 -5
- package/dist/commands/wallet.js +35 -28
- package/dist/commands/workflow.js +20 -13
- package/dist/utils/brain-hub-client.js +5 -1
- package/dist/utils/bridge-client.js +52 -11
- package/dist/utils/codebase-indexer.js +41 -4
- package/dist/utils/context-ranker.js +21 -15
- package/dist/utils/files.js +42 -5
- package/dist/utils/logger.js +50 -42
- package/dist/utils/persona.js +8 -3
- package/dist/utils/post-write-validator.js +29 -22
- package/dist/utils/project-memory.js +23 -16
- package/dist/utils/task-display.js +20 -13
- package/dist/utils/workspace-brain-service.js +45 -8
- package/dist/utils/workspace-cache.js +26 -18
- package/dist/utils/workspace-stream.js +63 -21
- package/package.json +3 -6
- package/dist/commands/fork.d.ts +0 -17
- package/dist/commands/fork.js +0 -164
- package/dist/commands/history.d.ts +0 -17
- package/dist/commands/history.js +0 -113
- package/dist/commands/preview.d.ts +0 -55
- package/dist/commands/preview.js +0 -467
- package/dist/commands/replay.d.ts +0 -18
- package/dist/commands/replay.js +0 -156
- package/dist/commands/repo.d.ts +0 -97
- package/dist/commands/repo.js +0 -773
- package/dist/commands/update.d.ts +0 -9
- package/dist/commands/update.js +0 -201
- package/dist/index.d.ts +0 -21
- package/dist/index.js +0 -1823
- package/dist/utils/api.d.ts +0 -572
- package/dist/utils/api.js +0 -6548
- package/dist/utils/cli-state.d.ts +0 -54
- package/dist/utils/cli-state.js +0 -185
- package/dist/utils/config.d.ts +0 -85
- package/dist/utils/config.js +0 -267
- package/dist/utils/session.d.ts +0 -118
- package/dist/utils/session.js +0 -423
- package/dist/utils/tools.d.ts +0 -276
- package/dist/utils/tools.js +0 -3516
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Vigthoria CLI — Multi-Step Terminal Task Display
|
|
3
4
|
*
|
|
@@ -6,22 +7,27 @@
|
|
|
6
7
|
*
|
|
7
8
|
* Only activates when stderr is a real TTY; JSON mode and piped output stay clean.
|
|
8
9
|
*/
|
|
9
|
-
|
|
10
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
11
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.TaskDisplay = void 0;
|
|
15
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
10
16
|
const ICONS = {
|
|
11
|
-
pending:
|
|
12
|
-
running:
|
|
13
|
-
done:
|
|
14
|
-
error:
|
|
15
|
-
skipped:
|
|
17
|
+
pending: chalk_1.default.gray('○'),
|
|
18
|
+
running: chalk_1.default.cyan('⟳'),
|
|
19
|
+
done: chalk_1.default.green('✓'),
|
|
20
|
+
error: chalk_1.default.red('✗'),
|
|
21
|
+
skipped: chalk_1.default.gray('\u2013'),
|
|
16
22
|
};
|
|
17
23
|
const LABEL_FN = {
|
|
18
|
-
pending: (s) =>
|
|
19
|
-
running: (s) =>
|
|
20
|
-
done: (s) =>
|
|
21
|
-
error: (s) =>
|
|
22
|
-
skipped: (s) =>
|
|
24
|
+
pending: (s) => chalk_1.default.gray(s),
|
|
25
|
+
running: (s) => chalk_1.default.cyan.bold(s),
|
|
26
|
+
done: (s) => chalk_1.default.gray(s),
|
|
27
|
+
error: (s) => chalk_1.default.red(s),
|
|
28
|
+
skipped: (s) => chalk_1.default.gray(s),
|
|
23
29
|
};
|
|
24
|
-
|
|
30
|
+
class TaskDisplay {
|
|
25
31
|
tasks = [];
|
|
26
32
|
linesRendered = 0;
|
|
27
33
|
enabled;
|
|
@@ -38,7 +44,7 @@ export class TaskDisplay {
|
|
|
38
44
|
return this.tasks.map((t) => {
|
|
39
45
|
const icon = ICONS[t.status];
|
|
40
46
|
const label = LABEL_FN[t.status](t.label);
|
|
41
|
-
const detail = t.detail ?
|
|
47
|
+
const detail = t.detail ? chalk_1.default.gray(` \u2014 ${t.detail.slice(0, 60)}`) : '';
|
|
42
48
|
return ` ${icon} ${label}${detail}`;
|
|
43
49
|
});
|
|
44
50
|
}
|
|
@@ -106,3 +112,4 @@ export class TaskDisplay {
|
|
|
106
112
|
return this.enabled;
|
|
107
113
|
}
|
|
108
114
|
}
|
|
115
|
+
exports.TaskDisplay = TaskDisplay;
|
|
@@ -1,10 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Workspace Brain — local codebase index + Brain Hub sync for CLI.
|
|
3
4
|
*/
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.WorkspaceBrainService = void 0;
|
|
40
|
+
const path = __importStar(require("path"));
|
|
41
|
+
const brain_hub_client_js_1 = require("./brain-hub-client.js");
|
|
42
|
+
const codebase_indexer_js_1 = require("./codebase-indexer.js");
|
|
43
|
+
class WorkspaceBrainService {
|
|
8
44
|
workspacePath;
|
|
9
45
|
indexer;
|
|
10
46
|
brainClient;
|
|
@@ -13,8 +49,8 @@ export class WorkspaceBrainService {
|
|
|
13
49
|
accountContextCache = null;
|
|
14
50
|
constructor(options) {
|
|
15
51
|
this.workspacePath = path.resolve(options.workspacePath);
|
|
16
|
-
this.indexer = new CodebaseIndexer(this.workspacePath);
|
|
17
|
-
this.brainClient = new BrainHubClient({
|
|
52
|
+
this.indexer = new codebase_indexer_js_1.CodebaseIndexer(this.workspacePath);
|
|
53
|
+
this.brainClient = new brain_hub_client_js_1.BrainHubClient({
|
|
18
54
|
apiBase: options.apiBase,
|
|
19
55
|
getAuthToken: options.getAuthToken,
|
|
20
56
|
});
|
|
@@ -31,7 +67,7 @@ export class WorkspaceBrainService {
|
|
|
31
67
|
indexedFileCount: status.indexedFileCount,
|
|
32
68
|
totalChunks: status.totalChunks,
|
|
33
69
|
isIndexing: status.isIndexing,
|
|
34
|
-
meta: CodebaseIndexer.loadMeta(this.workspacePath),
|
|
70
|
+
meta: codebase_indexer_js_1.CodebaseIndexer.loadMeta(this.workspacePath),
|
|
35
71
|
};
|
|
36
72
|
}
|
|
37
73
|
async ensureIndexed(options = {}) {
|
|
@@ -41,7 +77,7 @@ export class WorkspaceBrainService {
|
|
|
41
77
|
return { indexed: true, fileCount: meta.indexedFileCount, chunkCount: meta.totalChunks };
|
|
42
78
|
}
|
|
43
79
|
if (this.indexer.hasLocalIndex()) {
|
|
44
|
-
const meta = CodebaseIndexer.loadMeta(this.workspacePath);
|
|
80
|
+
const meta = codebase_indexer_js_1.CodebaseIndexer.loadMeta(this.workspacePath);
|
|
45
81
|
return {
|
|
46
82
|
indexed: true,
|
|
47
83
|
fileCount: meta?.indexedFileCount || this.indexer.getStatus().indexedFileCount,
|
|
@@ -119,3 +155,4 @@ export class WorkspaceBrainService {
|
|
|
119
155
|
}).catch(() => undefined);
|
|
120
156
|
}
|
|
121
157
|
}
|
|
158
|
+
exports.WorkspaceBrainService = WorkspaceBrainService;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Vigthoria CLI — Workspace Hash Cache
|
|
3
4
|
*
|
|
@@ -6,17 +7,24 @@
|
|
|
6
7
|
* - Changed/new files → sent first (highest budget priority)
|
|
7
8
|
* - Unchanged files → sent last (trimmed by budget if token limit reached)
|
|
8
9
|
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
11
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.getChangedFiles = getChangedFiles;
|
|
15
|
+
exports.updateWorkspaceCache = updateWorkspaceCache;
|
|
16
|
+
exports.summarizeChanges = summarizeChanges;
|
|
17
|
+
const node_crypto_1 = require("node:crypto");
|
|
18
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
19
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
12
20
|
const CACHE_SUBDIR = '.vigthoria';
|
|
13
21
|
const CACHE_FILENAME = 'file-hashes.json';
|
|
14
22
|
function getCachePath(workspacePath) {
|
|
15
|
-
return
|
|
23
|
+
return node_path_1.default.join(workspacePath, CACHE_SUBDIR, CACHE_FILENAME);
|
|
16
24
|
}
|
|
17
25
|
function hashFile(absPath) {
|
|
18
26
|
try {
|
|
19
|
-
return createHash('sha256').update(
|
|
27
|
+
return (0, node_crypto_1.createHash)('sha256').update(node_fs_1.default.readFileSync(absPath)).digest('hex');
|
|
20
28
|
}
|
|
21
29
|
catch {
|
|
22
30
|
return '';
|
|
@@ -24,7 +32,7 @@ function hashFile(absPath) {
|
|
|
24
32
|
}
|
|
25
33
|
function loadCache(workspacePath) {
|
|
26
34
|
try {
|
|
27
|
-
return JSON.parse(
|
|
35
|
+
return JSON.parse(node_fs_1.default.readFileSync(getCachePath(workspacePath), 'utf-8'));
|
|
28
36
|
}
|
|
29
37
|
catch {
|
|
30
38
|
return {};
|
|
@@ -32,10 +40,10 @@ function loadCache(workspacePath) {
|
|
|
32
40
|
}
|
|
33
41
|
function persistCache(workspacePath, hashes) {
|
|
34
42
|
try {
|
|
35
|
-
const cacheDir =
|
|
36
|
-
if (!
|
|
37
|
-
|
|
38
|
-
|
|
43
|
+
const cacheDir = node_path_1.default.join(workspacePath, CACHE_SUBDIR);
|
|
44
|
+
if (!node_fs_1.default.existsSync(cacheDir))
|
|
45
|
+
node_fs_1.default.mkdirSync(cacheDir, { recursive: true });
|
|
46
|
+
node_fs_1.default.writeFileSync(getCachePath(workspacePath), JSON.stringify(hashes, null, 2), 'utf-8');
|
|
39
47
|
}
|
|
40
48
|
catch { /* non-fatal */ }
|
|
41
49
|
}
|
|
@@ -45,13 +53,13 @@ function persistCache(workspacePath, hashes) {
|
|
|
45
53
|
* @param workspacePath Absolute project root.
|
|
46
54
|
* @param relativePaths Workspace-relative (or absolute) file paths to check.
|
|
47
55
|
*/
|
|
48
|
-
|
|
56
|
+
function getChangedFiles(workspacePath, relativePaths) {
|
|
49
57
|
const cache = loadCache(workspacePath);
|
|
50
58
|
const changed = [];
|
|
51
59
|
const unchanged = [];
|
|
52
60
|
for (const rel of relativePaths) {
|
|
53
|
-
const abs =
|
|
54
|
-
const key =
|
|
61
|
+
const abs = node_path_1.default.isAbsolute(rel) ? rel : node_path_1.default.join(workspacePath, rel);
|
|
62
|
+
const key = node_path_1.default.relative(workspacePath, abs).replace(/\\/g, '/');
|
|
55
63
|
const currentHash = hashFile(abs);
|
|
56
64
|
if (!currentHash || cache[key] !== currentHash) {
|
|
57
65
|
changed.push(rel);
|
|
@@ -66,13 +74,13 @@ export function getChangedFiles(workspacePath, relativePaths) {
|
|
|
66
74
|
* Write current hashes for the given files into the persistent cache.
|
|
67
75
|
* Call this after an agent run completes successfully.
|
|
68
76
|
*/
|
|
69
|
-
|
|
70
|
-
if (!workspacePath || !
|
|
77
|
+
function updateWorkspaceCache(workspacePath, relativePaths) {
|
|
78
|
+
if (!workspacePath || !node_fs_1.default.existsSync(workspacePath))
|
|
71
79
|
return;
|
|
72
80
|
const cache = loadCache(workspacePath);
|
|
73
81
|
for (const rel of relativePaths) {
|
|
74
|
-
const abs =
|
|
75
|
-
const key =
|
|
82
|
+
const abs = node_path_1.default.isAbsolute(rel) ? rel : node_path_1.default.join(workspacePath, rel);
|
|
83
|
+
const key = node_path_1.default.relative(workspacePath, abs).replace(/\\/g, '/');
|
|
76
84
|
const hash = hashFile(abs);
|
|
77
85
|
if (hash)
|
|
78
86
|
cache[key] = hash;
|
|
@@ -82,7 +90,7 @@ export function updateWorkspaceCache(workspacePath, relativePaths) {
|
|
|
82
90
|
/**
|
|
83
91
|
* Return a human-readable summary of changes since last cache update.
|
|
84
92
|
*/
|
|
85
|
-
|
|
93
|
+
function summarizeChanges(workspacePath, relativePaths) {
|
|
86
94
|
const { changed, unchanged, total } = getChangedFiles(workspacePath, relativePaths);
|
|
87
95
|
return `${changed.length} changed, ${unchanged.length} unchanged of ${total} files tracked`;
|
|
88
96
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Workspace Stream — Real-time bidirectional file sync between CLI and V3.
|
|
3
4
|
*
|
|
@@ -17,12 +18,51 @@
|
|
|
17
18
|
* {"type": "file_sync", "path": "rel/path", "content": "...", "action": "write"|"delete"}
|
|
18
19
|
* {"type": "file_batch", "files": [{path, content}, ...]}
|
|
19
20
|
*/
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
22
|
+
if (k2 === undefined) k2 = k;
|
|
23
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
24
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
25
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
26
|
+
}
|
|
27
|
+
Object.defineProperty(o, k2, desc);
|
|
28
|
+
}) : (function(o, m, k, k2) {
|
|
29
|
+
if (k2 === undefined) k2 = k;
|
|
30
|
+
o[k2] = m[k];
|
|
31
|
+
}));
|
|
32
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
33
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
34
|
+
}) : function(o, v) {
|
|
35
|
+
o["default"] = v;
|
|
36
|
+
});
|
|
37
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
38
|
+
var ownKeys = function(o) {
|
|
39
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
40
|
+
var ar = [];
|
|
41
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
42
|
+
return ar;
|
|
43
|
+
};
|
|
44
|
+
return ownKeys(o);
|
|
45
|
+
};
|
|
46
|
+
return function (mod) {
|
|
47
|
+
if (mod && mod.__esModule) return mod;
|
|
48
|
+
var result = {};
|
|
49
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
50
|
+
__setModuleDefault(result, mod);
|
|
51
|
+
return result;
|
|
52
|
+
};
|
|
53
|
+
})();
|
|
54
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
55
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
56
|
+
};
|
|
57
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
58
|
+
exports.WorkspaceWSClient = exports.WorkspaceWatcher = void 0;
|
|
59
|
+
exports.applyFileMutation = applyFileMutation;
|
|
60
|
+
const chokidar = __importStar(require("chokidar"));
|
|
61
|
+
const fs_1 = __importDefault(require("fs"));
|
|
62
|
+
const path_1 = __importDefault(require("path"));
|
|
63
|
+
const ws_1 = __importDefault(require("ws"));
|
|
64
|
+
const logger_js_1 = require("./logger.js");
|
|
65
|
+
const logger = new logger_js_1.Logger();
|
|
26
66
|
logger.setVerbose(!!process.env.VIGTHORIA_DEBUG);
|
|
27
67
|
// Files/dirs to ignore in the watcher
|
|
28
68
|
const IGNORE_PATTERNS = [
|
|
@@ -69,27 +109,27 @@ const _v3MuteTimeout = 2000; // 2s mute window after V3 writes a file
|
|
|
69
109
|
* Apply a file_mutation event from V3's SSE stream to the local workspace.
|
|
70
110
|
* Call this from the SSE event handler for real-time file application.
|
|
71
111
|
*/
|
|
72
|
-
|
|
112
|
+
function applyFileMutation(event, workspaceRoot) {
|
|
73
113
|
if (event.type !== 'file_mutation')
|
|
74
114
|
return false;
|
|
75
115
|
if (!event.path || !workspaceRoot)
|
|
76
116
|
return false;
|
|
77
|
-
const absPath =
|
|
117
|
+
const absPath = path_1.default.resolve(workspaceRoot, event.path);
|
|
78
118
|
// Safety: ensure the resolved path is within the workspace
|
|
79
|
-
if (!absPath.startsWith(
|
|
119
|
+
if (!absPath.startsWith(path_1.default.resolve(workspaceRoot) + path_1.default.sep) && absPath !== path_1.default.resolve(workspaceRoot)) {
|
|
80
120
|
logger.warn(`Refusing to apply mutation outside workspace: ${event.path}`);
|
|
81
121
|
return false;
|
|
82
122
|
}
|
|
83
123
|
try {
|
|
84
124
|
if (event.action === 'delete') {
|
|
85
|
-
if (
|
|
86
|
-
|
|
125
|
+
if (fs_1.default.existsSync(absPath)) {
|
|
126
|
+
fs_1.default.unlinkSync(absPath);
|
|
87
127
|
logger.debug(`Deleted: ${event.path}`);
|
|
88
128
|
}
|
|
89
129
|
}
|
|
90
130
|
else if (typeof event.content === 'string') {
|
|
91
|
-
|
|
92
|
-
|
|
131
|
+
fs_1.default.mkdirSync(path_1.default.dirname(absPath), { recursive: true });
|
|
132
|
+
fs_1.default.writeFileSync(absPath, event.content, 'utf8');
|
|
93
133
|
// Mute the watcher for this file to prevent echo
|
|
94
134
|
_v3MutatedFiles.add(absPath);
|
|
95
135
|
setTimeout(() => _v3MutatedFiles.delete(absPath), _v3MuteTimeout);
|
|
@@ -102,13 +142,13 @@ export function applyFileMutation(event, workspaceRoot) {
|
|
|
102
142
|
return false;
|
|
103
143
|
}
|
|
104
144
|
}
|
|
105
|
-
|
|
145
|
+
class WorkspaceWatcher {
|
|
106
146
|
watcher = null;
|
|
107
147
|
workspaceRoot;
|
|
108
148
|
onFileChange;
|
|
109
149
|
_ready = false;
|
|
110
150
|
constructor(options) {
|
|
111
|
-
this.workspaceRoot =
|
|
151
|
+
this.workspaceRoot = path_1.default.resolve(options.workspaceRoot);
|
|
112
152
|
this.onFileChange = options.onFileChange;
|
|
113
153
|
}
|
|
114
154
|
start() {
|
|
@@ -173,10 +213,10 @@ export class WorkspaceWatcher {
|
|
|
173
213
|
// Skip if this file was just written by V3 (echo prevention)
|
|
174
214
|
if (_v3MutatedFiles.has(filePath))
|
|
175
215
|
return;
|
|
176
|
-
const ext =
|
|
216
|
+
const ext = path_1.default.extname(filePath).toLowerCase();
|
|
177
217
|
if (BINARY_EXTENSIONS.has(ext))
|
|
178
218
|
return;
|
|
179
|
-
const relativePath =
|
|
219
|
+
const relativePath = path_1.default.relative(this.workspaceRoot, filePath);
|
|
180
220
|
if (relativePath.startsWith('..'))
|
|
181
221
|
return; // safety
|
|
182
222
|
if (action === 'delete') {
|
|
@@ -184,10 +224,10 @@ export class WorkspaceWatcher {
|
|
|
184
224
|
return;
|
|
185
225
|
}
|
|
186
226
|
try {
|
|
187
|
-
const stat =
|
|
227
|
+
const stat = fs_1.default.statSync(filePath);
|
|
188
228
|
if (stat.size > MAX_SYNC_FILE_BYTES)
|
|
189
229
|
return;
|
|
190
|
-
const content =
|
|
230
|
+
const content = fs_1.default.readFileSync(filePath, 'utf8');
|
|
191
231
|
this.onFileChange?.(relativePath, content, 'write');
|
|
192
232
|
}
|
|
193
233
|
catch {
|
|
@@ -195,7 +235,8 @@ export class WorkspaceWatcher {
|
|
|
195
235
|
}
|
|
196
236
|
}
|
|
197
237
|
}
|
|
198
|
-
|
|
238
|
+
exports.WorkspaceWatcher = WorkspaceWatcher;
|
|
239
|
+
class WorkspaceWSClient {
|
|
199
240
|
ws = null;
|
|
200
241
|
opts;
|
|
201
242
|
reconnectTimer = null;
|
|
@@ -209,7 +250,7 @@ export class WorkspaceWSClient {
|
|
|
209
250
|
if (this.ws)
|
|
210
251
|
return;
|
|
211
252
|
const url = `${this.opts.serverUrl}/ws/workspace`;
|
|
212
|
-
this.ws = new
|
|
253
|
+
this.ws = new ws_1.default(url);
|
|
213
254
|
this.ws.on('open', () => {
|
|
214
255
|
this._connected = true;
|
|
215
256
|
this._send({
|
|
@@ -302,3 +343,4 @@ export class WorkspaceWSClient {
|
|
|
302
343
|
}
|
|
303
344
|
}
|
|
304
345
|
}
|
|
346
|
+
exports.WorkspaceWSClient = WorkspaceWSClient;
|
package/package.json
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vigthoria-cli",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.47",
|
|
4
4
|
"description": "Vigthoria Coder CLI - AI-powered terminal coding assistant",
|
|
5
|
-
"type": "module",
|
|
6
5
|
"main": "dist/index.js",
|
|
7
6
|
"files": [
|
|
8
7
|
"dist",
|
|
@@ -65,9 +64,7 @@
|
|
|
65
64
|
"test:model:governance": "npm run build && node scripts/test-model-governance-no-agent.js",
|
|
66
65
|
"validate:no-go": "bash scripts/release/validate-no-go-gates.sh",
|
|
67
66
|
"test:legion:billing:e2e": "npm run build && node scripts/test-legion-godmode-billing-e2e.js",
|
|
68
|
-
"test:windows:v3-sync": "npm run build && node scripts/test-windows-v3-sync-recovery.js"
|
|
69
|
-
"test:persona": "npm run build && node scripts/test-persona-mode.mjs",
|
|
70
|
-
"test:error-wording": "npm run build && node scripts/test-error-wording.mjs"
|
|
67
|
+
"test:windows:v3-sync": "npm run build && node scripts/test-windows-v3-sync-recovery.js"
|
|
71
68
|
},
|
|
72
69
|
"keywords": [
|
|
73
70
|
"ai",
|
|
@@ -84,7 +81,7 @@
|
|
|
84
81
|
"archiver": "^6.0.1",
|
|
85
82
|
"axios": "^1.6.0",
|
|
86
83
|
"chalk": "^5.3.0",
|
|
87
|
-
"chokidar": "^
|
|
84
|
+
"chokidar": "^5.0.0",
|
|
88
85
|
"commander": "^11.1.0",
|
|
89
86
|
"conf": "^12.0.0",
|
|
90
87
|
"diff": "^5.1.0",
|
package/dist/commands/fork.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { Config } from '../utils/config.js';
|
|
2
|
-
import { Logger } from '../utils/logger.js';
|
|
3
|
-
interface ForkOptions {
|
|
4
|
-
eventIndex?: number;
|
|
5
|
-
project?: string;
|
|
6
|
-
json?: boolean;
|
|
7
|
-
}
|
|
8
|
-
export declare class ForkCommand {
|
|
9
|
-
private config;
|
|
10
|
-
private logger;
|
|
11
|
-
constructor(config: Config, logger: Logger);
|
|
12
|
-
private getHeaders;
|
|
13
|
-
private getBaseUrl;
|
|
14
|
-
private resolveWorkspaceRoot;
|
|
15
|
-
run(runId: string, message: string, options: ForkOptions): Promise<void>;
|
|
16
|
-
}
|
|
17
|
-
export {};
|
package/dist/commands/fork.js
DELETED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
import { isServerRuntime } from '../utils/api.js';
|
|
2
|
-
/**
|
|
3
|
-
* fork.ts — Fork from an existing V3 agent run and stream the result.
|
|
4
|
-
*/
|
|
5
|
-
import chalk from 'chalk';
|
|
6
|
-
import { createRequire } from 'node:module';
|
|
7
|
-
import { createSpinner, CH } from '../utils/logger.js';
|
|
8
|
-
const require = createRequire(import.meta.url);
|
|
9
|
-
export class ForkCommand {
|
|
10
|
-
config;
|
|
11
|
-
logger;
|
|
12
|
-
constructor(config, logger) {
|
|
13
|
-
this.config = config;
|
|
14
|
-
this.logger = logger;
|
|
15
|
-
}
|
|
16
|
-
getHeaders() {
|
|
17
|
-
const headers = { 'Content-Type': 'application/json' };
|
|
18
|
-
const token = process.env.VIGTHORIA_TOKEN ||
|
|
19
|
-
process.env.VIGTHORIA_AUTH_TOKEN ||
|
|
20
|
-
this.config.get('authToken');
|
|
21
|
-
if (token) {
|
|
22
|
-
headers['Authorization'] = `Bearer ${token}`;
|
|
23
|
-
headers['Cookie'] = `vigthoria-auth-token=${token}`;
|
|
24
|
-
}
|
|
25
|
-
const serviceKey = process.env.VIGTHORIA_V3_SERVICE_KEY;
|
|
26
|
-
if (serviceKey)
|
|
27
|
-
headers['X-Service-Key'] = serviceKey;
|
|
28
|
-
return headers;
|
|
29
|
-
}
|
|
30
|
-
getBaseUrl() {
|
|
31
|
-
const configuredApiUrl = String(this.config.get('apiUrl') || 'https://coder.vigthoria.io').replace(/\/$/, '');
|
|
32
|
-
const allowLocal = !isServerRuntime() || process.env.VIGTHORIA_ALLOW_LOCAL_V3_AGENT === '1';
|
|
33
|
-
return (process.env.VIGTHORIA_V3_AGENT_URL ||
|
|
34
|
-
process.env.V3_AGENT_URL ||
|
|
35
|
-
(allowLocal ? 'http://127.0.0.1:8030' : null) ||
|
|
36
|
-
configuredApiUrl);
|
|
37
|
-
}
|
|
38
|
-
resolveWorkspaceRoot(project) {
|
|
39
|
-
if (/^[a-zA-Z]:[\\/]/.test(project) || /^\\\\/.test(project))
|
|
40
|
-
return '';
|
|
41
|
-
if (typeof require !== 'undefined') {
|
|
42
|
-
try {
|
|
43
|
-
const path = require('path');
|
|
44
|
-
if (!path.isAbsolute(project))
|
|
45
|
-
return '';
|
|
46
|
-
}
|
|
47
|
-
catch { }
|
|
48
|
-
}
|
|
49
|
-
return project;
|
|
50
|
-
}
|
|
51
|
-
async run(runId, message, options) {
|
|
52
|
-
const project = options.project || process.cwd();
|
|
53
|
-
const workspace = this.resolveWorkspaceRoot(project);
|
|
54
|
-
const eventIndex = options.eventIndex || 0;
|
|
55
|
-
const spinner = createSpinner(`Forking run ${runId}...`).start();
|
|
56
|
-
try {
|
|
57
|
-
const baseUrl = this.getBaseUrl();
|
|
58
|
-
const body = {
|
|
59
|
-
workspace_root: workspace,
|
|
60
|
-
from_event_index: eventIndex,
|
|
61
|
-
new_request: message || '',
|
|
62
|
-
stream: true,
|
|
63
|
-
context: '',
|
|
64
|
-
};
|
|
65
|
-
const resp = await fetch(`${baseUrl}/api/runs/${encodeURIComponent(runId)}/fork`, {
|
|
66
|
-
method: 'POST',
|
|
67
|
-
headers: this.getHeaders(),
|
|
68
|
-
body: JSON.stringify(body),
|
|
69
|
-
});
|
|
70
|
-
if (!resp.ok) {
|
|
71
|
-
spinner.stop();
|
|
72
|
-
if (resp.status === 404) {
|
|
73
|
-
this.logger.error(`Run ${runId} not found or has no event log.`);
|
|
74
|
-
}
|
|
75
|
-
else if (resp.status === 502 || resp.status === 503) {
|
|
76
|
-
this.logger.error(`V3 run-history route is not available on ${baseUrl}. Backend may not expose /api/runs.`);
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
this.logger.error(`Fork failed: ${resp.status} ${resp.statusText}`);
|
|
80
|
-
}
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
spinner.stop();
|
|
84
|
-
console.log(chalk.bold(`\n${CH.success} Forked from ${chalk.cyan(runId)} at event ${eventIndex}\n`));
|
|
85
|
-
if (!resp.body) {
|
|
86
|
-
this.logger.error('No response body');
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
// Stream SSE events
|
|
90
|
-
const reader = resp.body.getReader();
|
|
91
|
-
const decoder = new TextDecoder();
|
|
92
|
-
let buffer = '';
|
|
93
|
-
let toolCallNum = 0;
|
|
94
|
-
while (true) {
|
|
95
|
-
const { done, value } = await reader.read();
|
|
96
|
-
if (done)
|
|
97
|
-
break;
|
|
98
|
-
buffer += decoder.decode(value, { stream: true });
|
|
99
|
-
const lines = buffer.split('\n');
|
|
100
|
-
buffer = lines.pop() || '';
|
|
101
|
-
for (const line of lines) {
|
|
102
|
-
if (!line.startsWith('data: '))
|
|
103
|
-
continue;
|
|
104
|
-
const payload = line.slice(6).trim();
|
|
105
|
-
if (payload === '[DONE]') {
|
|
106
|
-
console.log(chalk.bold(`\n${CH.success} Fork run complete\n`));
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
try {
|
|
110
|
-
const evt = JSON.parse(payload);
|
|
111
|
-
const type = evt.type || 'unknown';
|
|
112
|
-
if (options.json) {
|
|
113
|
-
console.log(JSON.stringify(evt));
|
|
114
|
-
continue;
|
|
115
|
-
}
|
|
116
|
-
switch (type) {
|
|
117
|
-
case 'context':
|
|
118
|
-
console.log(chalk.blue(` context: ${evt.context_id || '?'}`) +
|
|
119
|
-
(evt.forked_from ? chalk.dim(` (forked from ${evt.forked_from})`) : ''));
|
|
120
|
-
break;
|
|
121
|
-
case 'start':
|
|
122
|
-
console.log(chalk.green(` ▶ START`) + ` task=${evt.task_id || '?'}` +
|
|
123
|
-
(evt.forked_from ? chalk.dim(` forked_from=${evt.forked_from}`) : ''));
|
|
124
|
-
break;
|
|
125
|
-
case 'plan':
|
|
126
|
-
console.log(chalk.magenta(` 📋 PLAN`) + ` ${evt.tasks?.length || 0} tasks`);
|
|
127
|
-
break;
|
|
128
|
-
case 'tool_call':
|
|
129
|
-
toolCallNum++;
|
|
130
|
-
console.log(chalk.yellow(` 🔧 #${toolCallNum}`) + ` ${evt.name || '?'}(${JSON.stringify(evt.arguments || {}).substring(0, 60)})`);
|
|
131
|
-
break;
|
|
132
|
-
case 'tool_result': {
|
|
133
|
-
const icon = evt.success !== false ? chalk.green('✓') : chalk.red('✗');
|
|
134
|
-
console.log(` ${icon} ${evt.name || '?'}: ${chalk.dim((evt.output || '').substring(0, 100))}`);
|
|
135
|
-
break;
|
|
136
|
-
}
|
|
137
|
-
case 'message':
|
|
138
|
-
console.log(chalk.cyan(` 💬 `) + (evt.content || '').substring(0, 150));
|
|
139
|
-
break;
|
|
140
|
-
case 'complete': {
|
|
141
|
-
const seal = evt.seal_score ? `[${evt.seal_score.tier} ${evt.seal_score.overall}]` : '';
|
|
142
|
-
console.log(chalk.green(` ✅ COMPLETE `) + chalk.yellow(seal) +
|
|
143
|
-
` ${evt.iterations || '?'} iterations, ${evt.tool_calls || '?'} tool calls`);
|
|
144
|
-
break;
|
|
145
|
-
}
|
|
146
|
-
case 'error':
|
|
147
|
-
console.log(chalk.red(` ❌ ERROR: `) + (evt.message || '').substring(0, 200));
|
|
148
|
-
break;
|
|
149
|
-
default:
|
|
150
|
-
console.log(chalk.dim(` ${type}: ${JSON.stringify(evt).substring(0, 80)}`));
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
catch {
|
|
154
|
-
// skip unparseable lines
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
catch (err) {
|
|
160
|
-
spinner.stop();
|
|
161
|
-
this.logger.error(`Fork error: ${err.message}`);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { Config } from '../utils/config.js';
|
|
2
|
-
import { Logger } from '../utils/logger.js';
|
|
3
|
-
interface HistoryOptions {
|
|
4
|
-
limit?: number;
|
|
5
|
-
json?: boolean;
|
|
6
|
-
project?: string;
|
|
7
|
-
}
|
|
8
|
-
export declare class HistoryCommand {
|
|
9
|
-
private config;
|
|
10
|
-
private logger;
|
|
11
|
-
constructor(config: Config, logger: Logger);
|
|
12
|
-
private getHeaders;
|
|
13
|
-
private getBaseUrl;
|
|
14
|
-
private resolveWorkspaceRoot;
|
|
15
|
-
run(options: HistoryOptions): Promise<void>;
|
|
16
|
-
}
|
|
17
|
-
export {};
|