vigthoria-cli 1.13.13 → 1.13.20
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/auth.js +21 -7
- package/dist/commands/background.d.ts +3 -0
- package/dist/commands/background.js +58 -1
- package/dist/commands/chat.d.ts +2 -0
- package/dist/commands/chat.js +121 -1
- package/dist/commands/config.js +10 -14
- package/dist/commands/legion.js +48 -13
- package/dist/index.js +107 -6
- package/dist/utils/api.d.ts +7 -0
- package/dist/utils/api.js +236 -55
- package/dist/utils/clientManifest.d.ts +9 -0
- package/dist/utils/clientManifest.js +11 -1
- package/dist/utils/command-menu.js +6 -0
- package/dist/utils/config.js +7 -5
- package/dist/utils/contextBudget.d.ts +5 -1
- package/dist/utils/contextBudget.js +7 -4
- package/dist/utils/fastAgentRouter.d.ts +2 -2
- package/dist/utils/fastAgentRouter.js +4 -5
- package/dist/utils/requestIntent.js +5 -4
- package/dist/utils/session.d.ts +18 -0
- package/dist/utils/v3-workspace-path.js +22 -2
- package/install.ps1 +1 -1
- package/install.sh +1 -1
- package/package.json +3 -1
- package/scripts/release/validate-no-go-gates.sh +45 -7
|
@@ -56,8 +56,18 @@ export function resolveClientOsSlug() {
|
|
|
56
56
|
}
|
|
57
57
|
export function buildClientManifest(overrides = {}) {
|
|
58
58
|
const ios = isIOSEnvironment() && !overrides.os;
|
|
59
|
+
const productId = overrides.product_id || process.env.VIGTHORIA_SOURCE_PRODUCT_ID || 'vigthoria-cli';
|
|
59
60
|
return {
|
|
60
|
-
product_id:
|
|
61
|
+
product_id: productId,
|
|
62
|
+
context_contract_version: overrides.context_contract_version || '2.0',
|
|
63
|
+
source_product_id: overrides.source_product_id || process.env.VIGTHORIA_SOURCE_PRODUCT_ID || productId,
|
|
64
|
+
active_application_id: overrides.active_application_id || process.env.VIGTHORIA_ACTIVE_APPLICATION_ID || 'cli-agent-chat',
|
|
65
|
+
active_surface_id: overrides.active_surface_id || process.env.VIGTHORIA_ACTIVE_SURFACE_ID || 'agent-session',
|
|
66
|
+
target_product_id: overrides.target_product_id || 'none',
|
|
67
|
+
workspace_kind: overrides.workspace_kind || process.env.VIGTHORIA_WORKSPACE_KIND || 'local-development-workspace',
|
|
68
|
+
selected_engine_id: overrides.selected_engine_id || 'none',
|
|
69
|
+
capability_catalog_version: overrides.capability_catalog_version || process.env.VIGTHORIA_CAPABILITY_CATALOG_VERSION || '2026.08.03.1',
|
|
70
|
+
capability_scope_id: overrides.capability_scope_id || process.env.VIGTHORIA_CAPABILITY_SCOPE_ID || 'cli.ecosystem-user',
|
|
61
71
|
version: overrides.version || readPackageVersion(),
|
|
62
72
|
os: overrides.os || resolveClientOsSlug(),
|
|
63
73
|
execution_mode: overrides.execution_mode || (ios ? 'mobile-terminal-sandbox' : 'local-user-machine'),
|
|
@@ -3,6 +3,10 @@ const AGENT_COMMANDS = new Set([
|
|
|
3
3
|
'agent', 'chat', 'chat-resume', 'operator', 'legion', 'workflow',
|
|
4
4
|
'history', 'replay', 'fork', 'cancel',
|
|
5
5
|
]);
|
|
6
|
+
// Subprocess protocols are not user-facing commands. Presenting one in the
|
|
7
|
+
// root picker caused `v4-menu` to be launched without its required output
|
|
8
|
+
// file, which is exactly the failure reported from CLI 1.13.13.
|
|
9
|
+
const INTERNAL_COMMANDS = new Set(['v4-menu']);
|
|
6
10
|
function familyFor(commandPath) {
|
|
7
11
|
const root = commandPath.split(' ')[0];
|
|
8
12
|
if (root === 'repo')
|
|
@@ -15,6 +19,8 @@ export function buildCommandCatalog(program) {
|
|
|
15
19
|
const entries = [];
|
|
16
20
|
const visit = (command, parents) => {
|
|
17
21
|
const commandPath = [...parents, command.name()].join(' ');
|
|
22
|
+
if (parents.length === 0 && INTERNAL_COMMANDS.has(commandPath))
|
|
23
|
+
return;
|
|
18
24
|
entries.push({
|
|
19
25
|
path: commandPath,
|
|
20
26
|
description: command.description() || '',
|
package/dist/utils/config.js
CHANGED
|
@@ -195,11 +195,13 @@ export class Config {
|
|
|
195
195
|
// Vigthoria server infrastructure operational models
|
|
196
196
|
// ═══════════════════════════════════════════════════════════════
|
|
197
197
|
const models = [
|
|
198
|
-
{ id: '
|
|
199
|
-
{ id: 'code
|
|
200
|
-
{ id: '
|
|
201
|
-
{ id: '
|
|
202
|
-
{ id: '
|
|
198
|
+
{ id: 'architect', name: 'Vigthoria v4 Creative 27B', description: 'Architect, planning, deep reasoning, and creative systems work', tier: 'local', backendModel: 'Vigthoria-v4-Creative-27B' },
|
|
199
|
+
{ id: 'code', name: 'Vigthoria v4 Code 27B', description: 'Dense production executor for coding, debugging, and repository changes', tier: 'local', backendModel: 'Vigthoria-v4-Code-27B' },
|
|
200
|
+
{ id: 'assistant', name: 'Vigthoria v4 Assistant 9B', description: 'Low-latency FIM, completion, voice, and diagnostic model', tier: 'local', backendModel: 'Vigthoria-v4-Assistant-9B' },
|
|
201
|
+
{ id: 'code-35b', name: 'Vigthoria v4 Code 27B', description: 'Legacy selector mapped to the V4 executor', tier: 'local', backendModel: 'Vigthoria-v4-Code-27B' },
|
|
202
|
+
{ id: 'code-9b', name: 'Vigthoria v4 Assistant 9B', description: 'Legacy selector mapped to the V4 assistant', tier: 'local', backendModel: 'Vigthoria-v4-Assistant-9B' },
|
|
203
|
+
{ id: 'balanced', name: 'Vigthoria v4 Assistant 9B', description: 'Legacy selector mapped to the V4 assistant', tier: 'local', backendModel: 'Vigthoria-v4-Assistant-9B' },
|
|
204
|
+
{ id: 'balanced-4b', name: 'Vigthoria v4 Assistant 9B', description: 'Legacy selector mapped to the V4 assistant', tier: 'local', backendModel: 'Vigthoria-v4-Assistant-9B' },
|
|
203
205
|
];
|
|
204
206
|
if (this.hasCloudAccess()) {
|
|
205
207
|
models.push({ id: 'cloud-fast', name: 'Vigthoria Cloud Fast', description: 'Fast cloud responses for lighter work', tier: 'cloud', backendModel: 'vigthoria-cloud-fast' }, { id: 'cloud-balanced', name: 'Vigthoria Cloud Balanced', description: 'Default quality/cost balance for chat and coding', tier: 'cloud', backendModel: 'vigthoria-cloud-balanced' }, { id: 'cloud-code', name: 'Vigthoria Cloud Code', description: 'Economical cloud coding and completion', tier: 'cloud', backendModel: 'vigthoria-cloud-code' }, { id: 'cloud-power', name: 'Vigthoria Cloud Power', description: 'Premium general intelligence for demanding work', tier: 'cloud', backendModel: 'vigthoria-cloud-power' }, { id: 'cloud-maximum', name: 'Vigthoria Cloud Maximum', description: 'Maximum power for complex architecture and reviews', tier: 'cloud', backendModel: 'vigthoria-cloud-maximum' },
|
|
@@ -15,7 +15,11 @@ export declare function estimateJsonTokens(value: unknown): number;
|
|
|
15
15
|
export declare function resolveInputBudget(runtimeNctx?: number, maxOutput?: number): number;
|
|
16
16
|
/**
|
|
17
17
|
* Char limit for the initial V3 context JSON payload.
|
|
18
|
-
*
|
|
18
|
+
* The hydration payload is transport-only: the server writes workspaceFiles
|
|
19
|
+
* to an isolated directory and exposes only a compact filename summary to the
|
|
20
|
+
* model. It can therefore use the full calculated input envelope without
|
|
21
|
+
* consuming system/tool framing tokens. Clamp at 180k, far below the gateway
|
|
22
|
+
* body limit, while preserving compaction for genuinely large workspaces.
|
|
19
23
|
*/
|
|
20
24
|
export declare function resolveV3ContextCharLimit(runtimeNctx?: number): number;
|
|
21
25
|
export declare function compactToolListingOutput(name: string, output: string, charCap: number): string;
|
|
@@ -29,13 +29,16 @@ export function resolveInputBudget(runtimeNctx = DEFAULT_CODE_RUNTIME_CTX, maxOu
|
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
31
|
* Char limit for the initial V3 context JSON payload.
|
|
32
|
-
*
|
|
32
|
+
* The hydration payload is transport-only: the server writes workspaceFiles
|
|
33
|
+
* to an isolated directory and exposes only a compact filename summary to the
|
|
34
|
+
* model. It can therefore use the full calculated input envelope without
|
|
35
|
+
* consuming system/tool framing tokens. Clamp at 180k, far below the gateway
|
|
36
|
+
* body limit, while preserving compaction for genuinely large workspaces.
|
|
33
37
|
*/
|
|
34
38
|
export function resolveV3ContextCharLimit(runtimeNctx = DEFAULT_CODE_RUNTIME_CTX) {
|
|
35
39
|
const inputBudget = resolveInputBudget(runtimeNctx);
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
return Math.min(100_000, Math.max(32_000, charLimit));
|
|
40
|
+
const hydrationChars = inputBudget * CHARS_PER_TOKEN_EST;
|
|
41
|
+
return Math.min(180_000, Math.max(32_000, hydrationChars));
|
|
39
42
|
}
|
|
40
43
|
export function compactToolListingOutput(name, output, charCap) {
|
|
41
44
|
const text = String(output || '');
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Vigthoria
|
|
2
|
+
* Vigthoria v4 Assistant 9B — fast agent path classifier through the governed router.
|
|
3
3
|
* Regex/trivial detection always wins; LLM router refines ambiguous build prompts only.
|
|
4
4
|
*/
|
|
5
5
|
export type AgentRoutePath = 'template-instant' | 'v3-agent' | 'analysis-only';
|
|
@@ -23,7 +23,7 @@ export interface BalancedRouterResult {
|
|
|
23
23
|
}
|
|
24
24
|
export declare function parseBalancedRouterJson(raw: string): BalancedRouterJson | null;
|
|
25
25
|
/**
|
|
26
|
-
* Inference bases for
|
|
26
|
+
* Inference bases for the V4 Assistant routing lane only.
|
|
27
27
|
* Local developer machines must opt in (env) — avoids ~1.5s localhost probe on every Windows turn.
|
|
28
28
|
*/
|
|
29
29
|
export declare function getInferenceRouterBaseUrls(selfHostedUrl: string | null): string[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Vigthoria
|
|
2
|
+
* Vigthoria v4 Assistant 9B — fast agent path classifier through the governed router.
|
|
3
3
|
* Regex/trivial detection always wins; LLM router refines ambiguous build prompts only.
|
|
4
4
|
*/
|
|
5
5
|
const ROUTER_SYSTEM = `You are Vigthoria Agent Router. Reply with ONE JSON object only. No markdown, no HTML, no code fences.
|
|
@@ -14,8 +14,7 @@ fast_path: "template-instant" or null
|
|
|
14
14
|
|
|
15
15
|
Example: {"path":"template-instant","task_kind":"web-build","fast_path":"template-instant","confidence":0.95,"reason":"trivial html popup page"}`;
|
|
16
16
|
const INFERENCE_MODEL_IDS = [
|
|
17
|
-
'
|
|
18
|
-
'vigthoria-v3-balanced-4b',
|
|
17
|
+
'Vigthoria-v4-Assistant-9B',
|
|
19
18
|
];
|
|
20
19
|
function normalizePath(value) {
|
|
21
20
|
const p = String(value || '').trim().toLowerCase();
|
|
@@ -56,7 +55,7 @@ export function parseBalancedRouterJson(raw) {
|
|
|
56
55
|
return null;
|
|
57
56
|
}
|
|
58
57
|
/**
|
|
59
|
-
* Inference bases for
|
|
58
|
+
* Inference bases for the V4 Assistant routing lane only.
|
|
60
59
|
* Local developer machines must opt in (env) — avoids ~1.5s localhost probe on every Windows turn.
|
|
61
60
|
*/
|
|
62
61
|
export function getInferenceRouterBaseUrls(selfHostedUrl) {
|
|
@@ -69,7 +68,7 @@ export function getInferenceRouterBaseUrls(selfHostedUrl) {
|
|
|
69
68
|
|| process.env.VIGTHORIA_AGENT_LLM_ROUTER === '1'
|
|
70
69
|
|| process.platform === 'linux';
|
|
71
70
|
if (allowLocalhost) {
|
|
72
|
-
urls.push('http://127.0.0.1:
|
|
71
|
+
urls.push('http://127.0.0.1:4009');
|
|
73
72
|
}
|
|
74
73
|
return [...new Set(urls)];
|
|
75
74
|
}
|
|
@@ -4,14 +4,15 @@
|
|
|
4
4
|
*/
|
|
5
5
|
const CLI_SHAPING_BLOCK = /(?:^|\n\n)Platform:\s*(?:Windows|macOS|Linux)\.[\s\S]*?(?=\n\n[A-Z][^\n]{0,40}:|\s*$)/i;
|
|
6
6
|
const READONLY_SHAPING_BLOCK = /(?:^|\n\n)(?:Read-only analysis mode is active\.|Diagnostic mode is active\.)[\s\S]*?(?=\n\n[A-Z][^\n]{0,40}:|\s*$)/i;
|
|
7
|
-
const BUILD_VERBS = /\b(build|create|make|implement|complete|fix|repair|edit|modify|write|generate|add|finish|scaffold|develop|update|change|refactor|want|need|require|looking for|let's|let us|we need|we should|erstelle|erstellen|schreib|schreibe|bearbeite)\b/i;
|
|
8
|
-
const ARTIFACT_NOUNS = /\b(file|files|project|game|spiel|app|website|html5|frontend|component|feature|code|workspace|repo|clone|replica|remake|page|site|screen|button|popup|modal|alert|canvas|sprite|level|levels|enemy|enemies|character|npc|world|scene|script|module|api|database|config|landing|dashboard|platformer|arcade|playable|collectible|scoreboard|leaderboard|pitfall|pacman|rogue|html|css|javascript|typescript)\b/i;
|
|
7
|
+
const BUILD_VERBS = /\b(build|create|make|implement|complete|redesign|overhaul|rebuild|transform|polish|art-direct|fix|repair|edit|modify|write|generate|add|finish|scaffold|develop|update|change|refactor|want|need|require|looking for|let's|let us|we need|we should|erstelle|erstellen|schreib|schreibe|bearbeite)\b/i;
|
|
8
|
+
const ARTIFACT_NOUNS = /\b(file|files|project|game|spiel|app|website|html5|frontend|component|feature|code|workspace|repo|clone|replica|remake|page|site|design|showcase|screen|button|popup|modal|alert|canvas|sprite|level|levels|enemy|enemies|character|npc|world|scene|script|module|api|database|config|landing|dashboard|platformer|arcade|playable|collectible|scoreboard|leaderboard|pitfall|pacman|rogue|html|css|javascript|typescript)\b/i;
|
|
9
9
|
/** Canvas/playable games only — bare "html5" or "website" must NOT match. */
|
|
10
10
|
const GAME_INTENT = /\b(game|spiel|playable|babylon(?:\.js|js)?|vge|webgl|3d\s+(?:game|runner|prototype|world|experience)|html5\s+(?:game|canvas)|html5\s+game|canvas\s+game|game\s+canvas|arcade|platformer|side[- ]?scroller|pitfall|pac[- ]?man|tetris|snake|breakout|pong|roguelike|metroidvania|tower\s+defense|clone\s+of\s+(?:a\s+)?(?:game|pitfall|pac|mario|zelda|arcade)|gameplay|collectible|boss\s+fight|level\s+design|sprite\s+sheet|wild\s+(?:boar|pig|forest)|forest\s+pig)\b/i;
|
|
11
11
|
const WEB_PAGE_INTENT = /\b(website|web\s*site|webpage|web\s*page|landing\s+page|home\s*page|index\.html|html\s+page|static\s+page|single\s+page|popup|alert|modal|hello\s+world)\b/i;
|
|
12
|
+
const WEB_SHOWCASE_INTENT = /\b(web[- ]?design\s+showcase|frontend|marketing\s+site|dashboard|saas)\b/i;
|
|
12
13
|
const CLONE_BUILD = /\bclone\s+of\b|\b(build|create|make)\s+(?:a|an|the|us|me)?\s*(?:clone|replica|remake|port)\b/i;
|
|
13
14
|
const READ_ONLY_INTENT = /\b(analy[sz]e|analyse|analysis|audit|review|inspect|proof|understand|summari[sz]e|scan|read[\s-]?only|where we left|what is|how does|show me|tell me|identify\s+gaps?|gap\s+analysis|production\s+blockers?)\b/i;
|
|
14
|
-
const EXPLICIT_WRITE_VERBS = /\b(implement|write|edit|modify|update|fix|repair|create|build|generate|scaffold|deploy|refactor|develop|integrate|correct|apply|patch)\b/i;
|
|
15
|
+
const EXPLICIT_WRITE_VERBS = /\b(implement|write|edit|modify|update|redesign|overhaul|rebuild|transform|polish|art-direct|fix|repair|create|build|generate|scaffold|deploy|refactor|develop|integrate|correct|apply|patch)\b/i;
|
|
15
16
|
const TRIVIAL_HTML_PAGE = /\b(hello\s*world|simple\s+(?:html|web|page|site)|html5\s+website|html\s+5\s+website|popup|alert\s*\(|show\s+a\s+popup|one\s+page|single\s+html)\b/i;
|
|
16
17
|
/** User explicitly grants write permission after an analysis or confirmation gate. */
|
|
17
18
|
const WRITE_PERMISSION_GRANT = /\b(?:hereby\s+confirm|i\s+confirm|confirm(?:ed)?\s+that|give\s+(?:you|permission)|granting\s+permission|allow\s+(?:you|me\s+to)|you\s+(?:may|can|have\s+permission\s+to)|permission\s+to|authorized?\s+to|approve(?:d)?\s+(?:the\s+)?(?:changes?|writes?|edits?)|go\s+ahead\s+and(?:\s+write|\s+apply|\s+make|\s+do)?|do\s+all\s+the\s+changes|apply\s+(?:the\s+)?(?:changes?|fixes?|fix)|proceed\s+with\s+(?:the\s+)?(?:changes?|fixes?|implementation|writes?)|make\s+(?:the\s+)?changes|please\s+write)\b/i;
|
|
@@ -111,7 +112,7 @@ export function isContinueOrRetryPrompt(prompt) {
|
|
|
111
112
|
}
|
|
112
113
|
export function hasWebPageIntent(prompt) {
|
|
113
114
|
const text = stripExecutionShaping(prompt);
|
|
114
|
-
return WEB_PAGE_INTENT.test(text) || /\bhtml5\s+website\b/i.test(text);
|
|
115
|
+
return WEB_PAGE_INTENT.test(text) || WEB_SHOWCASE_INTENT.test(text) || /\bhtml5\s+website\b/i.test(text);
|
|
115
116
|
}
|
|
116
117
|
export function isTrivialHtmlPageRequest(prompt) {
|
|
117
118
|
const text = stripExecutionShaping(prompt);
|
package/dist/utils/session.d.ts
CHANGED
|
@@ -47,6 +47,24 @@ export interface Session {
|
|
|
47
47
|
agentMode: boolean;
|
|
48
48
|
operatorMode?: boolean;
|
|
49
49
|
lastAgentRunOutcome?: Record<string, unknown> | null;
|
|
50
|
+
activeAgentRun?: AgentExecutionCheckpoint | null;
|
|
51
|
+
}
|
|
52
|
+
export interface AgentExecutionCheckpoint {
|
|
53
|
+
executionId: string;
|
|
54
|
+
parentExecutionId?: string | null;
|
|
55
|
+
contextId: string;
|
|
56
|
+
prompt: string;
|
|
57
|
+
originalPrompt: string;
|
|
58
|
+
workspacePath: string;
|
|
59
|
+
userTier: string | null;
|
|
60
|
+
taskType: string;
|
|
61
|
+
workflowType: string;
|
|
62
|
+
status: 'submitted' | 'running' | 'completed' | 'failed';
|
|
63
|
+
submittedAt: string;
|
|
64
|
+
updatedAt: string;
|
|
65
|
+
failedTaskIds: string[];
|
|
66
|
+
unfinishedTaskIds: string[];
|
|
67
|
+
error?: string | null;
|
|
50
68
|
}
|
|
51
69
|
export declare class SessionManager {
|
|
52
70
|
private sessionsDir;
|
|
@@ -4,7 +4,7 @@ function stripInlineWorkspacePlaceholders(value) {
|
|
|
4
4
|
// Only strip placeholders when they were appended to a segment (e.g. pitfall[Vigthoria service]).
|
|
5
5
|
// Keep canonical scrubbed segments like /[internal]/ intact for dedicated mapping logic.
|
|
6
6
|
return String(value || '')
|
|
7
|
-
.replace(/(
|
|
7
|
+
.replace(/([^/])\[(?:internal|Vigthoria service|Vigthoria Agent|Vigthoria storage|temp|home|workspace)\](?=(?:\/|$))/ig, '$1')
|
|
8
8
|
.replace(/\/+$/g, '');
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
@@ -16,6 +16,9 @@ export function normalizeV3WorkspaceRelativePath(rawPath, rootPath) {
|
|
|
16
16
|
if (!input) {
|
|
17
17
|
return '';
|
|
18
18
|
}
|
|
19
|
+
input = input
|
|
20
|
+
.replace(/^var\/?\[internal\]/i, '[internal]')
|
|
21
|
+
.replace(/^varwww\[internal\]/i, '[internal]');
|
|
19
22
|
input = stripInlineWorkspacePlaceholders(input);
|
|
20
23
|
const safeRelative = (candidate) => {
|
|
21
24
|
const stripped = String(candidate || '').replace(/^\/+/, '');
|
|
@@ -64,6 +67,8 @@ export function normalizeV3WorkspaceRelativePath(rawPath, rootPath) {
|
|
|
64
67
|
}
|
|
65
68
|
const placeholderPatterns = [
|
|
66
69
|
[/^(?:var\/)?www\/\[internal\](?:\/(.*))?$/i, 1],
|
|
70
|
+
[/^var\/?\[internal\](?:\/(.*))?$/i, 1],
|
|
71
|
+
[/^varwww\[internal\](?:\/(.*))?$/i, 1],
|
|
67
72
|
[/^\[internal\](?:\/(.*))?$/i, 1],
|
|
68
73
|
[/^\[Vigthoria service\](?:\/(.*))?$/i, 1],
|
|
69
74
|
[/^\[Vigthoria Agent\](?:\/(.*))?$/i, 1],
|
|
@@ -134,6 +139,9 @@ export function normalizeV3WorkspaceRelativePath(rawPath, rootPath) {
|
|
|
134
139
|
}
|
|
135
140
|
const rootNoLeadingSlash = normalizedRoot.replace(/^\//, '');
|
|
136
141
|
const rootBase = path.posix.basename(normalizedRoot);
|
|
142
|
+
if (input.replace(/\/+$/g, '').toLowerCase() === normalizedRoot.toLowerCase()) {
|
|
143
|
+
return '';
|
|
144
|
+
}
|
|
137
145
|
const prefixes = [
|
|
138
146
|
`${normalizedRoot}/`,
|
|
139
147
|
`${rootNoLeadingSlash}/`,
|
|
@@ -150,6 +158,11 @@ export function normalizeV3WorkspaceRelativePath(rawPath, rootPath) {
|
|
|
150
158
|
return safeRelative(input.slice(embeddedIndex + embeddedRoot.length));
|
|
151
159
|
}
|
|
152
160
|
}
|
|
161
|
+
// An unmatched POSIX absolute path belongs to another filesystem boundary.
|
|
162
|
+
// Never reinterpret it as a workspace-relative path by merely trimming '/'.
|
|
163
|
+
if (input.startsWith('/')) {
|
|
164
|
+
return '';
|
|
165
|
+
}
|
|
153
166
|
const relative = safeRelative(input);
|
|
154
167
|
if (relative === 'workspace') {
|
|
155
168
|
return '';
|
|
@@ -167,7 +180,11 @@ export function isV3WorkspaceRootAliasPath(rawPath, rootPath) {
|
|
|
167
180
|
if (!original || original === '.') {
|
|
168
181
|
return true;
|
|
169
182
|
}
|
|
170
|
-
const
|
|
183
|
+
const compactCanonical = original
|
|
184
|
+
.replace(/\\/g, '/')
|
|
185
|
+
.replace(/^var\/?\[internal\]/i, '[internal]')
|
|
186
|
+
.replace(/^varwww\[internal\]/i, '[internal]');
|
|
187
|
+
const sanitized = stripInlineWorkspacePlaceholders(compactCanonical).trim();
|
|
171
188
|
if (!sanitized || sanitized === '.' || sanitized === '/') {
|
|
172
189
|
return true;
|
|
173
190
|
}
|
|
@@ -181,6 +198,9 @@ export function isV3WorkspaceRootAliasPath(rawPath, rootPath) {
|
|
|
181
198
|
|| lowered === '[internal]'
|
|
182
199
|
|| lowered === 'www/[internal]'
|
|
183
200
|
|| lowered === 'var/www/[internal]'
|
|
201
|
+
|| lowered === 'var[internal]'
|
|
202
|
+
|| lowered === 'var/[internal]'
|
|
203
|
+
|| lowered === 'varwww[internal]'
|
|
184
204
|
|| lowered === '[vigthoria service]'
|
|
185
205
|
|| lowered === 'var/www/[vigthoria service]') {
|
|
186
206
|
return true;
|
package/install.ps1
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
$ErrorActionPreference = "Stop"
|
|
6
6
|
|
|
7
7
|
# Configuration
|
|
8
|
-
$CLI_VERSION = "1.13.
|
|
8
|
+
$CLI_VERSION = "1.13.20"
|
|
9
9
|
$INSTALL_DIR = "$env:USERPROFILE\.vigthoria"
|
|
10
10
|
$NPM_PACKAGE = "vigthoria-cli"
|
|
11
11
|
$GIT_PACKAGE_URL = "git+https://market.vigthoria.io/vigthoria/vigthoria-cli.git"
|
package/install.sh
CHANGED
|
@@ -26,7 +26,7 @@ else
|
|
|
26
26
|
fi
|
|
27
27
|
|
|
28
28
|
# Configuration
|
|
29
|
-
CLI_VERSION="1.13.
|
|
29
|
+
CLI_VERSION="1.13.20"
|
|
30
30
|
INSTALL_DIR="$HOME/.vigthoria"
|
|
31
31
|
REPO_URL="https://market.vigthoria.io/vigthoria/vigthoria-cli"
|
|
32
32
|
GIT_PACKAGE_URL="git+https://market.vigthoria.io/vigthoria/vigthoria-cli.git"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vigthoria-cli",
|
|
3
|
-
"version": "1.13.
|
|
3
|
+
"version": "1.13.20",
|
|
4
4
|
"description": "Vigthoria Coder CLI - AI-powered terminal coding assistant",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -72,7 +72,9 @@
|
|
|
72
72
|
"test:legion:billing:e2e": "npm run build && node scripts/test-legion-godmode-billing-e2e.js",
|
|
73
73
|
"test:windows:v3-sync": "npm run build && node scripts/test-windows-v3-sync-recovery.js",
|
|
74
74
|
"test:v3-workspace-path": "npm run build && node scripts/test-v3-workspace-path.js",
|
|
75
|
+
"test:v3-server-tool-execution": "npm run build && node scripts/test-v3-server-tool-execution.js",
|
|
75
76
|
"test:session:project-match": "npm run build && node scripts/test-session-project-match.mjs",
|
|
77
|
+
"test:external-client-resume": "npm run build && node scripts/test-external-client-resume.mjs",
|
|
76
78
|
"test:v3-stream-mutation": "npm run build && node scripts/test-v3-stream-mutation.js",
|
|
77
79
|
"test:context:budget": "npm run build && node scripts/test-context-budget.js",
|
|
78
80
|
"test:v3-client-tool-quality": "npm run build && node scripts/test-v3-client-tool-quality.mjs",
|
|
@@ -5,6 +5,7 @@ ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
|
5
5
|
cd "$ROOT"
|
|
6
6
|
|
|
7
7
|
CLI="node dist/index.js"
|
|
8
|
+
SERVICE_IDENTITY_MODE="${VIGTHORIA_TEST_SERVICE_IDENTITY:-0}"
|
|
8
9
|
unset V3_SERVICE_KEY
|
|
9
10
|
unset HYPERLOOP_SERVICE_KEY
|
|
10
11
|
# Release validation runs against local model-router in this environment
|
|
@@ -27,6 +28,7 @@ printf '%s
|
|
|
27
28
|
' "$AUTH_JSON" > /tmp/vig-auth-preflight.json
|
|
28
29
|
python3 - << 'PY'
|
|
29
30
|
import json
|
|
31
|
+
import re
|
|
30
32
|
with open('/tmp/vig-auth-preflight.json','r',encoding='utf-8') as f:
|
|
31
33
|
j=json.load(f)
|
|
32
34
|
msg='Vigthoria Gate way user authentification failed. Please log out and login again.'
|
|
@@ -35,6 +37,15 @@ assert j.get('error') == msg, f"unexpected auth message: {j.get('error')}"
|
|
|
35
37
|
print('[pass] auth preflight message')
|
|
36
38
|
PY
|
|
37
39
|
|
|
40
|
+
if [[ "$SERVICE_IDENTITY_MODE" == "1" ]]; then
|
|
41
|
+
# From this point onward the no-go suite exercises server-local model and
|
|
42
|
+
# tool routes without borrowing a human account session. The invalid-token
|
|
43
|
+
# gateway assertion above always runs against the canonical public boundary.
|
|
44
|
+
export VIGTHORIA_LOCAL_TEST_MODE=1
|
|
45
|
+
export VIGTHORIA_LOCAL_TEST_TOKEN="vigthoria-release-service-identity"
|
|
46
|
+
export VIGTHORIA_AUTH_TOKEN="$VIGTHORIA_LOCAL_TEST_TOKEN"
|
|
47
|
+
fi
|
|
48
|
+
|
|
38
49
|
echo "[1.1] ranker includes agent.py top10 for SSE prompt"
|
|
39
50
|
node - << 'EOF2'
|
|
40
51
|
import('./dist/utils/context-ranker.js').then((m)=>{
|
|
@@ -62,12 +73,22 @@ if (!tsc || !tsc.ran || !tsc.passed) process.exit(1);
|
|
|
62
73
|
EOF2
|
|
63
74
|
|
|
64
75
|
echo "[6.2] balanced-4b no-agent path"
|
|
65
|
-
|
|
76
|
+
for attempt in 1 2 3; do
|
|
77
|
+
if $CLI chat --no-agent --model balanced-4b --prompt "reply exactly: ok" --json >/tmp/vig-balanced.json; then
|
|
78
|
+
break
|
|
79
|
+
fi
|
|
80
|
+
if [[ "$attempt" == "3" ]]; then
|
|
81
|
+
echo "[fail] balanced-4b remained unavailable after 3 attempts"
|
|
82
|
+
exit 1
|
|
83
|
+
fi
|
|
84
|
+
echo "[retry] balanced-4b transient failure ($attempt/3)"
|
|
85
|
+
sleep 2
|
|
86
|
+
done
|
|
66
87
|
python3 - << 'PY'
|
|
67
88
|
import json
|
|
68
89
|
j=json.load(open('/tmp/vig-balanced.json'))
|
|
69
90
|
assert j.get('success') is True
|
|
70
|
-
assert j.get('model') in ('vigthoria-balanced-4b', 'vigthoria-v3-balanced-4b'), j
|
|
91
|
+
assert j.get('model') in ('Vigthoria-v4-Assistant-9B', 'vigthoria-balanced-4b', 'vigthoria-v3-balanced-4b'), j
|
|
71
92
|
print('[pass] balanced-4b')
|
|
72
93
|
PY
|
|
73
94
|
|
|
@@ -76,13 +97,17 @@ $CLI hyper-loop status >/tmp/vig-hyperloop.txt
|
|
|
76
97
|
$CLI devtools connect >/tmp/vig-devtools.txt
|
|
77
98
|
|
|
78
99
|
echo "[6.11] operator flow"
|
|
79
|
-
|
|
80
|
-
|
|
100
|
+
if [[ "$SERVICE_IDENTITY_MODE" == "1" ]]; then
|
|
101
|
+
echo "[skip] paid-user operator probe (isolated release service identity)"
|
|
102
|
+
else
|
|
103
|
+
$CLI operator --prompt "reply with exactly: OK" --json >/tmp/vig-operator.json
|
|
104
|
+
python3 - << 'PY'
|
|
81
105
|
import json
|
|
82
106
|
j=json.load(open('/tmp/vig-operator.json'))
|
|
83
107
|
assert j.get('success') is True, j
|
|
84
108
|
print('[pass] operator flow')
|
|
85
109
|
PY
|
|
110
|
+
fi
|
|
86
111
|
|
|
87
112
|
echo "[7.1/7.3/7.4] local service health"
|
|
88
113
|
for u in http://localhost:8030/health http://localhost:4009/health http://localhost:4011/health; do
|
|
@@ -95,10 +120,12 @@ echo "[7.2/7.8/12.3] models inventory"
|
|
|
95
120
|
curl -s http://localhost:4009/v1/models >/tmp/vig-models.json
|
|
96
121
|
python3 - << 'PY'
|
|
97
122
|
import json
|
|
123
|
+
import re
|
|
98
124
|
ids={m.get('id','') for m in json.load(open('/tmp/vig-models.json')).get('data',[])}
|
|
99
125
|
if ids:
|
|
100
126
|
has_router = any(
|
|
101
127
|
m in ids for m in (
|
|
128
|
+
'Vigthoria-v4-Assistant-9B',
|
|
102
129
|
'vigthoria-balanced-4b', 'vigthoria-balanced-4b:latest',
|
|
103
130
|
'vigthoria-v3-balanced-4b', 'vigthoria-v3-balanced-4b:latest',
|
|
104
131
|
'vigthoria-fast-9b', 'vigthoria-fast-9b:latest',
|
|
@@ -106,11 +133,12 @@ if ids:
|
|
|
106
133
|
)
|
|
107
134
|
has_creative = any(
|
|
108
135
|
m in ids for m in (
|
|
136
|
+
'Vigthoria-v4-Creative-27B',
|
|
109
137
|
'vigthoria-creative-9b-v4', 'vigthoria-creative-9b-v4:latest',
|
|
110
138
|
'vigthoria-fast-9b', 'vigthoria-fast-9b:latest',
|
|
111
139
|
)
|
|
112
140
|
)
|
|
113
|
-
has_code = any('vigthoria-v3
|
|
141
|
+
has_code = 'Vigthoria-v4-Code-27B' in ids or any(re.search(r'^vigthoria-v3(?:\.\d+)?-code-35b(?:-|:|$)', i) for i in ids)
|
|
114
142
|
assert has_router, f'missing router model in inventory: {sorted(ids)}'
|
|
115
143
|
assert has_creative, f'missing creative/fast model in inventory: {sorted(ids)}'
|
|
116
144
|
assert has_code, f'missing code model in inventory: {sorted(ids)}'
|
|
@@ -136,12 +164,22 @@ rg -n "coder.vigthoria.io/releases" install.ps1 install.sh README.md >/tmp/vig-r
|
|
|
136
164
|
cat /tmp/vig-release-urls.txt
|
|
137
165
|
|
|
138
166
|
echo "[12.1] no-agent governance fallback"
|
|
139
|
-
|
|
167
|
+
for attempt in 1 2 3; do
|
|
168
|
+
if $CLI chat --no-agent --model creative-v4 --prompt "say ok" --json >/tmp/vig-creative.json; then
|
|
169
|
+
break
|
|
170
|
+
fi
|
|
171
|
+
if [[ "$attempt" == "3" ]]; then
|
|
172
|
+
echo "[fail] governance fallback remained unavailable after 3 attempts"
|
|
173
|
+
exit 1
|
|
174
|
+
fi
|
|
175
|
+
echo "[retry] governance fallback transient failure ($attempt/3)"
|
|
176
|
+
sleep 2
|
|
177
|
+
done
|
|
140
178
|
python3 - << 'PY'
|
|
141
179
|
import json
|
|
142
180
|
j=json.load(open('/tmp/vig-creative.json'))
|
|
143
181
|
assert j.get('success') is True
|
|
144
|
-
assert j.get('model') == '
|
|
182
|
+
assert j.get('model') == 'Vigthoria-v4-Code-27B', j
|
|
145
183
|
md=j.get('metadata') or {}
|
|
146
184
|
fb=md.get('modelFallback') or {}
|
|
147
185
|
assert fb.get('reason') == 'governance-blocked-model', j
|