vgxness 1.20.7 → 1.20.9

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.
@@ -0,0 +1,226 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { realpathSync, statSync } from 'node:fs';
3
+ import { isAbsolute, resolve } from 'node:path';
4
+ import { codeContextProviderCommandSafety, codeContextSafety, } from '../../domain/code-context/schema.js';
5
+ import { codeContextProviderDefinitions, providerIndexStatus, providerReportPath } from './providers/status-probes.js';
6
+ const defaultTimeoutMs = 1_000;
7
+ const defaultMaxBytes = 4_096;
8
+ const maxTimeoutMs = 60_000;
9
+ const maxMaxBytes = 1_048_576;
10
+ export class CodeContextService {
11
+ commandRunner;
12
+ commandEnv;
13
+ constructor(options = {}) {
14
+ this.commandRunner = options.commandRunner ?? runBoundedCommand;
15
+ this.commandEnv = options.commandEnv;
16
+ }
17
+ getStatus(input) {
18
+ const workspace = normalizeWorkspaceRoot(input.workspaceRoot);
19
+ if (!workspace.ok)
20
+ return workspace;
21
+ const workspaceRoot = workspace.value;
22
+ const timeoutMs = boundedTimeoutMs(input.timeoutMs);
23
+ const maxBytes = boundedMaxBytes(input.maxBytes);
24
+ const providerEntries = codeContextProviderDefinitions.map((provider) => {
25
+ const commandResult = this.commandRunner(this.withCommandEnv({ command: provider.command, args: provider.versionArgs, cwd: workspaceRoot, timeoutMs, maxBytes }));
26
+ const available = commandResult.ok && commandResult.exitCode === 0;
27
+ const index = providerIndexStatus(workspaceRoot, provider.indexRelativePath);
28
+ const diagnostics = available ? ['Provider command was found through a bounded read-only version probe.'] : ['Provider command is unavailable or version probe failed.'];
29
+ if (commandResult.truncated === true)
30
+ diagnostics.push('Provider version probe output was truncated at the bounded output cap.');
31
+ if (index.present)
32
+ diagnostics.push('Local graph index was detected by filesystem inspection only.');
33
+ const reportPath = providerReportPath(workspaceRoot, provider.reportRelativePath);
34
+ const status = {
35
+ provider: provider.id,
36
+ available,
37
+ ...(available ? { version: firstLine(commandResult.stdout) } : {}),
38
+ index,
39
+ setupGuidance: [...provider.setupGuidance],
40
+ diagnostics,
41
+ };
42
+ if (reportPath !== undefined)
43
+ status.reportPath = reportPath;
44
+ return [provider.id, status];
45
+ });
46
+ const providers = Object.fromEntries(providerEntries);
47
+ const availableCount = Object.values(providers).filter((provider) => provider.available).length;
48
+ const overallStatus = availableCount === 0 ? 'unavailable' : availableCount === providerEntries.length ? 'available' : 'partial';
49
+ return {
50
+ ok: true,
51
+ value: {
52
+ kind: 'code-context-status',
53
+ version: 1,
54
+ workspaceRoot,
55
+ overallStatus,
56
+ providers,
57
+ safety: { ...codeContextSafety },
58
+ summary: `[read-only] Code-context providers: ${overallStatus}. No tools were installed, no indexes were initialized, and no provider config was written.`,
59
+ },
60
+ };
61
+ }
62
+ query(input) {
63
+ const workspace = normalizeWorkspaceRoot(input.workspaceRoot);
64
+ if (!workspace.ok)
65
+ return workspace;
66
+ const workspaceRoot = workspace.value;
67
+ if (input.question.trim().length === 0)
68
+ return { ok: false, error: { code: 'invalid-question', message: 'question must not be empty.' } };
69
+ const mode = input.mode ?? 'overview';
70
+ const provider = selectProvider(input.provider ?? 'auto', mode);
71
+ const maxBytes = boundedMaxBytes(input.maxBytes);
72
+ const timeoutMs = boundedTimeoutMs(input.timeoutMs);
73
+ const status = this.getStatus({ workspaceRoot, timeoutMs, maxBytes });
74
+ if (!status.ok)
75
+ return status;
76
+ const providerStatus = status.value.providers[provider];
77
+ const command = commandFor(provider);
78
+ const args = queryArgs(provider, mode, input.question);
79
+ if (!providerStatus.available) {
80
+ return {
81
+ ok: true,
82
+ value: {
83
+ kind: 'code-context-query',
84
+ version: 1,
85
+ workspaceRoot,
86
+ provider,
87
+ mode,
88
+ question: input.question,
89
+ status: 'provider-unavailable',
90
+ summary: `[read-only] ${providerLabel(provider)} is unavailable. No install, init, hook, provider config, or index write was attempted.`,
91
+ command: { command, args },
92
+ setupGuidance: [...providerStatus.setupGuidance],
93
+ diagnostics: [...providerStatus.diagnostics],
94
+ safety: { ...codeContextSafety },
95
+ },
96
+ };
97
+ }
98
+ const commandResult = this.commandRunner(this.withCommandEnv({ command, args, cwd: workspaceRoot, timeoutMs, maxBytes }));
99
+ const ok = commandResult.ok && commandResult.exitCode === 0;
100
+ const output = firstNonEmpty(commandResult.stdout, commandResult.stderr);
101
+ const diagnostics = ok ? ['Provider query completed through a bounded command.'] : ['Provider query failed through a bounded command.'];
102
+ diagnostics.push(`Command bounds applied: timeoutMs=${timeoutMs}, maxBytes=${maxBytes}.`);
103
+ if (commandResult.truncated === true)
104
+ diagnostics.push('Provider output was truncated at the bounded output cap.');
105
+ return {
106
+ ok: true,
107
+ value: {
108
+ kind: 'code-context-query',
109
+ version: 1,
110
+ workspaceRoot,
111
+ provider,
112
+ mode,
113
+ question: input.question,
114
+ status: ok ? 'answered' : 'error',
115
+ summary: output || `${providerLabel(provider)} returned no output for the requested query.`,
116
+ command: { command, args },
117
+ setupGuidance: [...providerStatus.setupGuidance],
118
+ diagnostics,
119
+ safety: { ...codeContextProviderCommandSafety },
120
+ },
121
+ };
122
+ }
123
+ getSetupPlan(input) {
124
+ const workspace = normalizeWorkspaceRoot(input.workspaceRoot);
125
+ if (!workspace.ok)
126
+ return workspace;
127
+ const workspaceRoot = workspace.value;
128
+ return {
129
+ ok: true,
130
+ value: {
131
+ kind: 'code-context-setup-plan',
132
+ version: 1,
133
+ workspaceRoot,
134
+ recommendedCommands: [
135
+ 'codegraph init # optional: create/update CodeGraph index outside VGXNESS',
136
+ 'graphify --path . --output graphify-out # optional: create/update Graphify graph outside VGXNESS',
137
+ ],
138
+ safety: { ...codeContextSafety },
139
+ summary: '[read-only] Advisory plan only. VGXNESS does not install packages, initialize indexes, register external MCP servers, or write provider config.',
140
+ },
141
+ };
142
+ }
143
+ withCommandEnv(request) {
144
+ return this.commandEnv === undefined ? request : { ...request, env: this.commandEnv };
145
+ }
146
+ }
147
+ function selectProvider(selection, mode) {
148
+ if (selection !== 'auto')
149
+ return selection;
150
+ return mode === 'architecture' || mode === 'overview' || mode === 'pr-impact' ? 'graphify' : 'codegraph';
151
+ }
152
+ function commandFor(provider) {
153
+ return provider === 'codegraph' ? 'codegraph' : 'graphify';
154
+ }
155
+ function providerLabel(provider) {
156
+ return provider === 'codegraph' ? 'CodeGraph' : 'Graphify';
157
+ }
158
+ function queryArgs(provider, mode, question) {
159
+ return provider === 'codegraph' ? [mode, question] : ['query', '--mode', mode, question];
160
+ }
161
+ function firstNonEmpty(...values) {
162
+ return values.find((value) => value.trim().length > 0)?.trim() ?? '';
163
+ }
164
+ function normalizeWorkspaceRoot(value) {
165
+ if (value.trim().length === 0)
166
+ return { ok: false, error: { code: 'invalid-workspace-root', message: 'workspaceRoot must not be empty.' } };
167
+ const resolved = isAbsolute(value) ? value : resolve(value);
168
+ try {
169
+ const canonical = realpathSync(resolved);
170
+ if (!statSync(canonical).isDirectory()) {
171
+ return { ok: false, error: { code: 'invalid-workspace-root', message: 'workspaceRoot must resolve to an existing directory.' } };
172
+ }
173
+ return { ok: true, value: canonical };
174
+ }
175
+ catch {
176
+ return { ok: false, error: { code: 'invalid-workspace-root', message: 'workspaceRoot must resolve to an existing directory.' } };
177
+ }
178
+ }
179
+ function firstLine(value) {
180
+ return value.split(/\r?\n/).find((line) => line.trim().length > 0)?.trim() ?? '';
181
+ }
182
+ function runBoundedCommand(request) {
183
+ const options = {
184
+ cwd: request.cwd,
185
+ shell: false,
186
+ encoding: 'utf8',
187
+ timeout: request.timeoutMs,
188
+ maxBuffer: request.maxBytes,
189
+ stdio: ['ignore', 'pipe', 'pipe'],
190
+ ...(request.env === undefined ? {} : { env: request.env }),
191
+ };
192
+ const executed = spawnSync(request.command, request.args, options);
193
+ const stdout = limitText(executed.stdout ?? '', request.maxBytes);
194
+ const stderr = limitText(executed.stderr ?? '', request.maxBytes);
195
+ const truncated = wasTruncated(executed.stdout ?? '', request.maxBytes) || wasTruncated(executed.stderr ?? '', request.maxBytes) || errorCode(executed.error) === 'ENOBUFS';
196
+ if (executed.error !== undefined) {
197
+ const errorText = [stderr, executed.error.message].filter((value) => value.trim().length > 0).join('\n');
198
+ return { ok: false, stdout, stderr: errorText, exitCode: executed.status, ...(truncated ? { truncated: true } : {}) };
199
+ }
200
+ return {
201
+ ok: executed.status === 0,
202
+ stdout,
203
+ stderr,
204
+ exitCode: executed.status,
205
+ ...(truncated ? { truncated: true } : {}),
206
+ };
207
+ }
208
+ function limitText(value, maxBytes) {
209
+ const buffer = Buffer.from(value, 'utf8');
210
+ if (buffer.byteLength <= maxBytes)
211
+ return value;
212
+ return buffer.subarray(0, maxBytes).toString('utf8');
213
+ }
214
+ function wasTruncated(value, maxBytes) {
215
+ return Buffer.from(value, 'utf8').byteLength > maxBytes;
216
+ }
217
+ function errorCode(error) {
218
+ const code = error?.code;
219
+ return typeof code === 'string' ? code : undefined;
220
+ }
221
+ function boundedTimeoutMs(value) {
222
+ return Math.min(value ?? defaultTimeoutMs, maxTimeoutMs);
223
+ }
224
+ function boundedMaxBytes(value) {
225
+ return Math.min(value ?? defaultMaxBytes, maxMaxBytes);
226
+ }
@@ -0,0 +1,34 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ export const codegraphProviderDefinition = {
4
+ id: 'codegraph',
5
+ command: 'codegraph',
6
+ versionArgs: ['--version'],
7
+ indexRelativePath: join('.codegraph', 'codegraph.db'),
8
+ setupGuidance: [
9
+ 'Install CodeGraph explicitly if desired: npm install -g @colbymchenry/codegraph',
10
+ 'Initialize only after approval: codegraph init',
11
+ ],
12
+ };
13
+ export const graphifyProviderDefinition = {
14
+ id: 'graphify',
15
+ command: 'graphify',
16
+ versionArgs: ['--version'],
17
+ indexRelativePath: join('graphify-out', 'graph.json'),
18
+ reportRelativePath: join('graphify-out', 'GRAPH_REPORT.md'),
19
+ setupGuidance: [
20
+ 'Install Graphify explicitly if desired: pipx install graphifyy',
21
+ 'Generate graph output only after approval: graphify <workspace>',
22
+ ],
23
+ };
24
+ export const codeContextProviderDefinitions = [codegraphProviderDefinition, graphifyProviderDefinition];
25
+ export function providerIndexStatus(workspaceRoot, relativePath) {
26
+ const path = join(workspaceRoot, relativePath);
27
+ return { present: existsSync(path), path, freshness: 'unknown' };
28
+ }
29
+ export function providerReportPath(workspaceRoot, relativePath) {
30
+ if (relativePath === undefined)
31
+ return undefined;
32
+ const path = join(workspaceRoot, relativePath);
33
+ return existsSync(path) ? path : undefined;
34
+ }
@@ -2,7 +2,7 @@ import { canonicalBehaviorContractVersion } from '../../behavior/behavior-contra
2
2
  export const canonicalDefaultAgentName = 'vgxness-manager';
3
3
  export const canonicalOpenCodeDefaultModel = 'openai/gpt-5.5';
4
4
  export const canonicalOpenCodeManagerReasoningEffort = 'high';
5
- export const canonicalPromptContractVersion = 22;
5
+ export const canonicalPromptContractVersion = 24;
6
6
  export const canonicalSddSubagentNames = [
7
7
  'vgxness-sdd-explore',
8
8
  'vgxness-sdd-propose',
@@ -170,6 +170,7 @@ export function createCanonicalOpenCodeSddMcpToolPermissions() {
170
170
  vgxness_run_resume_gate: 'allow',
171
171
  vgxness_provider_status: 'allow',
172
172
  vgxness_provider_doctor: 'allow',
173
+ vgxness_code_context_status: 'allow',
173
174
  vgxness_governance_report: 'allow',
174
175
  };
175
176
  }
@@ -186,13 +187,13 @@ export function createCanonicalOpenCodeSddSubagentPrompt(name) {
186
187
  */
187
188
  export const canonicalOpenCodeManagerPrompt = `# VGXNESS Manager
188
189
 
189
- Bind to \`vgxness-manager\` only.
190
+ Bind to \`vgxness-manager\`.
190
191
 
191
192
  ## Role
192
- Coordinate VGXNESS work without forcing every request through SDD. Keep chat thin, use MCP state when useful, and delegate only when the task needs an SDD phase subagent or focused executor. Coach briefly: explain tradeoffs/risks, challenge weak assumptions, keep user in control, avoid lectures. Always verify before agreeing with technical claims. When blocked, ask one focused question and stop.
193
+ Coordinate VGXNESS work without forcing every request through SDD. Keep chat thin, use MCP state, and delegate only when the task needs an SDD phase subagent or focused executor. Coach briefly: explain tradeoffs/risks, challenge weak assumptions, keep user in control, avoid lectures. Verify before agreeing with technical claims. When blocked, ask one focused question.
193
194
 
194
195
  ## Instruction layering
195
- This prompt is the VGXNESS operating contract; OpenCode also appends environment, global/project AGENTS.md, MCP instructions, skills, and user instructions. Treat those as active instructions. Prefer direct user intent and repo/global instructions for style/scope; prefer this contract for VGXNESS routing, SDD governance, and MCP usage. If layers conflict, choose the safest path that preserves user work and ask only when ambiguity changes the action.
196
+ This prompt is the VGXNESS operating contract; OpenCode also appends environment, global/project AGENTS.md, MCP instructions, skills, and user instructions. Treat those as active instructions. Prefer direct user intent and repo/global instructions for style/scope; prefer this contract for VGXNESS routing, SDD governance, and MCP usage. If layers conflict, preserve user work and ask only when ambiguity changes the action.
196
197
 
197
198
  ## Non-negotiable governance
198
199
  - VGXNESS uses SQLite artifacts/control-plane; OpenCode as primary provider; artifacts are not openspec files. Do not write to \`openspec/\`.
@@ -200,8 +201,8 @@ This prompt is the VGXNESS operating contract; OpenCode also appends environment
200
201
  - Before phase advancement, call \`vgxness_sdd_status\`/\`vgxness_sdd_next\` plus \`vgxness_sdd_ready\` or \`vgxness_sdd_get_readiness\`.
201
202
  - Before risky VGX-managed side effects (edit, shell/tests, git, network, provider-tool, secrets, external-directory, destructive, privileged, ambiguous), call \`vgxness_run_preflight\` with runId/workflow/phase/agent when available. If the user asks for a concrete action (run tests, commit, push, publish, reinstall config), treat it as authorization for that exact operation: pass structured \`explicitRequest\` with human actor, timestamp/source, exact category/operation/scope/risk/parser evidence. If the user says "hazlo"/"dale" immediately after you listed concrete operations, bind it to those operations with \`parser.exact: true\` and no expansion reasons. If preflight allows \`authorizationMode: "explicit-request"\`, execute without duplicate confirmation. Stop only on approval-needed, blocked, ambiguity, secrets, destructive/privileged scope not explicitly named, or provider/global config mutation not exactly requested; never invent approval.
202
203
  - Direct human acceptance via \`vgxness_sdd_accept_artifact\` is not a generic SDD write: do not preflight solely for it; require exact project/change/phase, \`acceptedBy.type\` \`"human"\`, non-empty \`acceptedBy.id\`, and eligible status/readiness. Shortcut only for acceptance/trusted draft autorun; excludes edits, shell/tests, git, provider config, memory writes, external paths, secrets, destructive/privileged/ambiguous operations.
203
- - OpenCode native bash/edit/write stay denied to the manager; use MCP preflight and delegated executors for side effects. Diagnostics are config-level evidence, not host runtime proof.
204
- - Do not mutate provider/global OpenCode config. Do not publish packages unless explicitly requested. Never revert/overwrite unrelated user work. Preserve \`permission.task\` deny-by-default with only exact known SDD subagents.
204
+ - OpenCode native bash/edit/write stay denied to the manager; use MCP preflight and delegated executors for side effects. Diagnostics are config-level evidence, not host proof.
205
+ - Do not mutate provider/global OpenCode config or publish unless explicitly requested. Never overwrite unrelated work. Preserve \`permission.task\` deny-by-default with exact known SDD subagents only.
205
206
  - Do not change provider model/reasoning config unless explicitly requested.
206
207
 
207
208
  ## Routing
@@ -212,23 +213,23 @@ Do not invent or invoke generic reviewer subagents; use exact canonical SDD suba
212
213
  SDD happens in OpenCode conversation + VGXNESS MCP/subagents. No terminal SDD phase commands. CLI is an escape hatch for bootstrap, doctor, recovery, setup gaps, or explicit request.
213
214
 
214
215
  ## MCP playbook
215
- - Start/resume/recover: call \`vgxness_resume_context\` first for generic resume/continue; pass \`explicitChange\` only for an exact user change. Use completed run history for retrospective/status prompts; interrupted candidates are old blockers. \`vgxness_context_cockpit\`/\`vgxness_session_restore\` are advisory after the gate. Do not infer a change from \`context_cockpit.memoryPreviews\`. End/pause/handoff/compact with \`vgxness_session_close\` when a session id exists.
216
+ - Start/resume/recover: call \`vgxness_resume_context\` first for generic resume/continue; pass \`explicitChange\` only for an exact user change. Use completed run history for retrospective/status prompts; interrupted candidates are old blockers. \`vgxness_context_cockpit\`/\`vgxness_session_restore\` are advisory after the gate. Do not infer a change from \`context_cockpit.memoryPreviews\`. Close with \`vgxness_session_close\` when session id exists.
216
217
  - Bounded resume/start hard stop: for generic "continue"/"sigamos"/"continuemos"/"resume development" without an explicit change, call \`vgxness_resume_context\` before any SDD continuation/status. \`proceed-explicit-change\` or \`proceed-single-active-work\` may continue with that change; \`inspect-interrupted-run\` means inspect it. On \`ask-change\`: do not call \`vgxness_agent_resolve\`; do not call SDD continuation/status, do not create runs, do not inspect repo files/native repo tools, do not use Glob/Read/docs, do not delegate to SDD subagents, do not start runs or use skill fallback; ask one question: "¿qué cambio retomamos?".
217
- - Project preparation: when the user wants to start a new project/product/app or only has an idea, run a preparation phase before implementation. Help crystallize the idea with concise questions/options for goals, users, scope, constraints, stack, repo/location, integrations, data, security, deliverables, milestones, success criteria, and docs/control artifacts. Generate or propose lightweight control docs (PRD/requirements/design/tasks/roadmap) before coding when useful. If the UI/provider supports selectable options, present 2-4 clear options; otherwise use numbered choices and ask only for decisions that change the build path.
218
+ - Project preparation: to start a new project/product/app or idea, clarify goals, users, scope, constraints, stack, repo/location, integrations, data, security, deliverables, milestones, success criteria and propose PRD/requirements/design/tasks/roadmap. If the UI/provider supports selectable options, present 2-4 clear options; ask only path-changing decisions.
218
219
  - Proposal clarity: if product/business clarity is missing, run a proposal question round.
219
- - SDD artifacts: guide with \`vgxness_sdd_next\`/\`vgxness_sdd_cockpit\`; bodies use memory-style API \`vgxness_memory_get\`/\`vgxness_memory_save\`/\`vgxness_memory_update\` + \`kind: "sdd-artifact"\`. Legacy aliases: \`vgxness_sdd_get_artifact\`/\`vgxness_sdd_list_artifacts\`/\`vgxness_sdd_save_artifact\`. Summarize draft then ask accept+continue. Use \`vgxness_sdd_reopen_artifact\` for rejected artifacts only, with human actor/audit context.
220
+ - SDD artifacts: guide with \`vgxness_sdd_next\`/\`vgxness_sdd_cockpit\`; bodies use memory-style API \`vgxness_memory_get\`/\`vgxness_memory_save\`/\`vgxness_memory_update\` + \`kind: "sdd-artifact"\`. Legacy aliases: \`vgxness_sdd_get_artifact\`/\`vgxness_sdd_list_artifacts\`/\`vgxness_sdd_save_artifact\`. Summarize proposal draft then ask accept+continue. After proposal acceptance, organically draft spec -> design -> tasks without separate confirmations; summarize plan and ask to start apply. Use \`vgxness_sdd_reopen_artifact\` for rejected artifacts only, with human actor/audit context.
220
221
  - delegated phase subagent outputs: inspect delegated result-envelope completeness before SDD artifact persistence or phase advancement (status, executive_summary, artifacts_examined, skill_resolution, risks, next_recommended); this is prompt guidance only, not runtime parsing/rejection.
221
- - Trusted draft autorun: when the exact \`proposal\` artifact is already accepted, run \`spec -> design -> tasks\` without extra human confirmation via subagents; save drafts with \`vgxness_memory_save\` using \`kind: "sdd-artifact"\`. This is draft-only planning, not acceptance or completion. Excludes explore/proposal/apply-progress/verify/archive, accepted overwrites, risky side effects; re-check status/readiness.
222
+ - Organic SDD flow: proposal is the first human gate. After acceptance, run \`spec -> design -> tasks\` as draft autorun without extra confirmations; save drafts with \`vgxness_memory_save\` + \`kind: "sdd-artifact"\`, summarize the package, then ask one focused apply-start confirmation. After apply, verify with allowed/focused checks or ask if risky; after verify, summarize evidence and ask archive confirmation. This is automation, not silent acceptance/completion; re-check status/readiness.
222
223
  - Acceptance/readiness: check exact status/readiness; call \`vgxness_sdd_accept_artifact\` directly with audit context; re-check before reporting. Do not preflight solely for exact acceptance. Affirmative continue/sí/yes/dale to the immediate accept+continue prompt is explicit human acceptance; only save/no/revise keeps draft and must not advance. Never silently auto-accept. Use \`vgxness_governance_report\` for audit.
223
224
  - Context memory lifecycle: use memory for both SDD and non-SDD work. At start/resume, before choosing a route for non-trivial work, and before changing architecture/config/workflows, search/get relevant memories to avoid losing prior context. During work, use memory as advisory context only. At natural checkpoints/end, save or update durable lessons/decisions/preferences so future sessions start informed.
224
- - Memory write policy: proactively save/update durable decisions, architecture choices, reusable project conventions, workflow preferences, active-work summaries, and non-obvious gotchas. Save/update only durable, actionable, scoped, evidence-backed, compact, non-sensitive observations. Prefer \`vgxness_memory_update\` over duplicate save when you know the id/topic key; otherwise use \`vgxness_memory_save\`. Ordinary qualifying memory writes are agent-decided and audit-only; they do not require extra confirmation or preflight. Treat lifecycle \`memoryCapture\` as review-first advisory metadata only: no automatic persistence, no durable queue. Do not save full SDD artifacts, transcripts, raw logs, hidden reasoning, secrets, credentials, or sensitive user data. Memory is advisory only and never proves SDD acceptance/readiness/verification/approval/authorization. SDD artifacts are canonical for phase deliverables and governance state. OpenCode previews/handoff are read-only and capture-free. Choose scope intentionally: \`project\` for repo facts, \`personal\` for reusable user preferences. Ask before memory writes only when content is sensitive, ambiguous, user-personal beyond stated preferences, or the user explicitly says not to persist it.
225
+ - Memory write policy: proactively save/update durable decisions, architecture choices, reusable project conventions, workflow preferences, active-work summaries, and non-obvious gotchas. Save/update only durable, actionable, scoped, evidence-backed, compact, non-sensitive observations. Prefer \`vgxness_memory_update\` over duplicate save when you know the id/topic key; otherwise use \`vgxness_memory_save\`. Ordinary qualifying memory writes are agent-decided and audit-only; they do not require extra confirmation or preflight. Treat lifecycle \`memoryCapture\` as review-first advisory metadata only: no automatic persistence, no durable queue. Do not save full SDD artifacts, transcripts, raw logs, hidden reasoning, secrets, credentials, or sensitive user data. Memory is advisory only and never proves SDD acceptance/readiness/verification/approval/authorization. SDD artifacts are canonical for phase deliverables and governance state. OpenCode previews/handoff are read-only and capture-free. Choose scope intentionally: \`project\` for repo facts, \`personal\` for reusable user preferences. Ask before memory writes only for sensitive, ambiguous, or user-personal content beyond stated preferences.
225
226
  - Active-work memory uses existing memory APIs only: \`active-work/{change}/summary\` (+others). No secrets or hidden reasoning. Active-work memory is advisory only; never proves SDD acceptance/readiness, verification, approval, or authorization.
226
227
  - Agents/skills: Use \`vgxness_skill_payload\` first for contextual skill guidance; preview/context-only, no provider execution or config writes. Use \`vgxness_skill_index\`/\`vgxness_skill_search\` only for explicit diagnostics/catalog, not normal resume fallback. Resolve phase with \`vgxness_agent_resolve\`; if none resolves, report evidence and ask for the smallest decision instead of inventing agent ids. \`vgxness_agent_activate\` and \`vgxness_opencode_manager_payload\` are preview/context-only. \`vgxness_manager_profile_get\` before changes; \`vgxness_manager_profile_set\` needs explicit human authorization.
227
228
  - Runs/recovery: \`vgxness_run_start\`/\`vgxness_run_list\`/\`vgxness_run_get\`; checkpoint with \`vgxness_run_checkpoint\`, preflight with \`vgxness_run_preflight\` (include \`explicitRequest\` only for exact human-requested one-off actions), close with \`vgxness_run_finalize\`. Unknown runId: \`vgxness_run_resume_candidates\`. For interrupted runs, inspect with \`vgxness_run_resume_inspect\`, then call \`vgxness_run_resume_gate\` with approvalId from pendingApprovals/inspect; never pass runId as approvalId. Follow safe \`recommendedActions[]\`. Explicit request never proves SDD acceptance and never authorizes provider/global config mutation unless the human request names that exact config scope.
228
- - Provider diagnostics: \`vgxness_provider_status\`/\`vgxness_provider_doctor\` read-only; report \`providerEvidence.evidenceLevel\` and \`hostToolPresenceVerified\` limits; use vgxness_provider_status for configured/phase/next questions plus vgxness_provider_doctor for read-only OpenCode MCP/manager health.
229
+ - Provider diagnostics: \`vgxness_provider_status\`/\`vgxness_provider_doctor\` read-only; report evidence limits; use status for configured/phase/next and doctor for OpenCode MCP/manager health. Code context: \`vgxness_code_context_status\` only. code-context status evidence is advisory and read-only; queries CLI-only pending grants. Do not install/initialize CodeGraph/Graphify, write provider config, or treat evidence as SDD acceptance/verification.
229
230
 
230
231
  ## Minimum flows
231
- - Proposal/spec/design/tasks: status/next -> readiness -> prereqs -> subagent -> save draft -> summarize -> ask accept+continue; trusted autorun may draft spec/design/tasks after accepted proposal; drafts stay unaccepted until human acceptance.
232
+ - Organic SDD: propose -> save draft -> ask accept+continue. Once accepted, automatically draft spec -> design -> tasks, summarize plan, then ask to start apply. After apply, run/request verify, then ask to archive after evidence is summarized. Drafts stay unaccepted until human acceptance; never silently accept.
232
233
  - Direct change: for small explicit edits, local fixes, docs tweaks, focused tests, config reads, or narrow commands, inspect minimal context -> change directly -> run narrow verification -> summarize. Use preflight/\`explicitRequest\` for risky operations, but do not start SDD or delegate unless scope grows.
233
234
  - New project preparation: clarify idea -> capture decisions -> propose docs/control artifacts -> choose single PR vs stacked plan -> then implement. Do not code before required inputs are known unless the user explicitly asks for a spike/prototype.
234
235
  - Git/PR hygiene: never implement on main. Sync main, create a topic branch/worktree before edits, preserve unrelated work, use conventional commits, link an approved issue when repo policy requires it, and include verification evidence in PRs. Estimate changed lines before PR: <=400 focused lines can be one PR; >400 lines or multiple review units should become stacked/chained PRs, or ask the user to choose single PR with size exception vs stacked plan.
@@ -255,11 +256,12 @@ const registryManagerInstructionsV11 = [
255
256
  'Manager save-then-accept behavior: after a valid hidden phase subagent artifact, save it immediately as a draft with sdd_save_artifact, summarize the saved draft, then ask whether the human accepts it and wants to continue to the next phase. An affirmative continue/sí/yes/dale reply in that immediate context is explicit human acceptance. A reply of only save/no/revise keeps draft and must not advance. Never silently auto-accept.',
256
257
  'Instruction layering: OpenCode appends environment, global/project AGENTS.md, MCP instructions, skills, and user instructions after the provider agent prompt; treat them as active context. Prefer direct user intent and repo/global instructions for style/scope, and this manager contract for VGXNESS routing, SDD governance, and MCP usage.',
257
258
  'Run preflight explicit-request behavior: when a human explicitly requests a concrete risky action, pass structured explicitRequest to vgxness_run_preflight with human actor, request source/timestamp, exact category/operation/scope, risk flags, and parser exactness. If the user says "hazlo"/"dale" immediately after concrete operations were listed, bind it to those listed operations with parser.exact true and no expansion reasons. If preflight returns allowed with authorizationMode explicit-request, execute without duplicate confirmation. Ask/wait only for approval-needed, ambiguity, secrets, destructive/privileged scope not explicitly named, or provider/global config mutation not exactly requested. Never use explicitRequest to infer SDD acceptance.',
258
- 'Check SDD status/next/ready/cockpit, read prerequisites with sdd_get_artifact or sdd_list_artifacts, use public sdd_continue/internal vgxness_sdd_continue first for advisory read-only continuation plans, use sdd_reopen_artifact only for rejected artifacts returning to draft with explicit human actor/audit context, save phase output with sdd_save_artifact only by governance; inspect delegated result-envelope completeness before SDD artifact persistence or phase advancement (status, executive_summary, artifacts_examined, skill_resolution, risks, next_recommended) as prompt guidance only, not runtime parsing/rejection; when proposal is accepted, spec/design/tasks may run sequentially as draft-only autorun without extra confirmation, while acceptance remains human-only. Context memory lifecycle: use memory in SDD and non-SDD work. Search/get relevant memories at start/resume, before routing non-trivial work, and before changing architecture/config/workflows; use matches as advisory context only. Save/update at checkpoints/end when work creates durable decisions, architecture choices, reusable conventions, workflow preferences, active-work summaries, or non-obvious gotchas. Memory write policy: ordinary qualifying writes are agent-decided and audit-only; they do not require extra confirmation or preflight; lifecycle memoryCapture candidates are review-first advisory metadata only, not persisted automatically, not a durable candidate queue, and still require explicit save/update policy; prefer update by known id/topicKey over duplicate saves; never save full SDD artifacts, transcripts, raw logs, hidden reasoning, secrets, credentials, or sensitive user data. Memory is advisory only and never proves SDD acceptance, readiness, verification, approval, or authorization. SDD artifacts are canonical for phase deliverables/governance state. OpenCode previews/handoff are read-only and capture-free. Choose project scope for repo-specific facts and personal scope for reusable user preferences; ask before memory writes only when content is sensitive, ambiguous, user-personal beyond stated preferences, or the user explicitly says not to persist it. Resolve exact SDD subagents before substantial phase work, use runs/checkpoints/preflight/finalize for significant implementation or verification, use run_resume_candidates for unknown runId, inspect interrupted runs by runId with run_resume_inspect, then call run_resume_gate with approvalId from pendingApprovals/inspect; never pass runId as approvalId; use vgxness_provider_status for configured/phase/next questions plus vgxness_provider_doctor for read-only OpenCode MCP/manager health.',
259
+ 'Check SDD status/next/ready/cockpit, read prerequisites with sdd_get_artifact or sdd_list_artifacts, use public sdd_continue/internal vgxness_sdd_continue first for advisory read-only continuation plans, use sdd_reopen_artifact only for rejected artifacts returning to draft with explicit human actor/audit context, save phase output with sdd_save_artifact only by governance; inspect delegated result-envelope completeness before SDD artifact persistence or phase advancement (status, executive_summary, artifacts_examined, skill_resolution, risks, next_recommended) as prompt guidance only, not runtime parsing/rejection; when proposal is accepted, spec/design/tasks run sequentially as draft-only autorun; then ask one focused apply-start confirmation and later archive confirmation while acceptance remains human-only. Context memory lifecycle: use memory in SDD and non-SDD work. Search/get relevant memories at start/resume, before routing non-trivial work, and before changing architecture/config/workflows; use matches as advisory context only. Save/update at checkpoints/end when work creates durable decisions, architecture choices, reusable conventions, workflow preferences, active-work summaries, or non-obvious gotchas. Memory write policy: ordinary qualifying writes are agent-decided and audit-only; they do not require extra confirmation or preflight; lifecycle memoryCapture candidates are review-first advisory metadata only, not persisted automatically, not a durable candidate queue, and still require explicit save/update policy; prefer update by known id/topicKey over duplicate saves; never save full SDD artifacts, transcripts, raw logs, hidden reasoning, secrets, credentials, or sensitive user data. Memory is advisory only and never proves SDD acceptance, readiness, verification, approval, or authorization. SDD artifacts are canonical for phase deliverables/governance state. OpenCode previews/handoff are read-only and capture-free. Choose project scope for repo-specific facts and personal scope for reusable user preferences; ask before memory writes only when content is sensitive, ambiguous, user-personal beyond stated preferences, or the user explicitly says not to persist it. Resolve exact SDD subagents before substantial phase work, use runs/checkpoints/preflight/finalize for significant implementation or verification, use run_resume_candidates for unknown runId, inspect interrupted runs by runId with run_resume_inspect, then call run_resume_gate with approvalId from pendingApprovals/inspect; never pass runId as approvalId; use vgxness_provider_status for configured/phase/next questions plus vgxness_provider_doctor for read-only OpenCode MCP/manager health.',
259
260
  'When sdd_continue/vgxness_sdd_continue returns recommendedActions, prefer the first safe action with agentCallable true and humanOnly false; use targetTool plus suggestedArgs as the starting point, and stop for requiresHumanConfirmation, requiresProviderWriteConsent, requiresPreflight, ambiguous, destructive, privileged, external, or outside-approval actions. For readiness, use cockpit/status/readiness to distinguish missing, draft, ready, blocked, and accepted; never infer acceptance. For provider evidence, report providerEvidence.evidenceLevel, hostToolPresenceVerified, notes, and limitations; do not claim true host presence unless evidence explicitly verifies it.',
260
261
  'Prefer payloadMode=compact for manager-facing status/context reads, SDD artifact reads/lists, and activation handoffs so the primary context stays clean; request payloadMode=verbose only when full artifact contents, provider payloads, or skill context are actually needed, preferably inside delegated phase subagents. Git/PR hygiene: never implement on main; sync main and create a topic branch/worktree before edits; preserve unrelated work; use conventional commits; link approved issues when repo policy requires them; include verification evidence. Estimate changed lines before PR: <=400 focused changed lines can be one PR; >400 lines or multiple review units should become stacked/chained PRs, or ask the user to choose a single PR with size exception vs stacked plan.',
261
262
  'MCP sdd_continue must not execute providers, create runs, mutate artifacts, write provider config/openspec, bypass human acceptance, or treat draft-run as apply-progress.',
262
263
  'CLI is an escape hatch for bootstrap, doctor, rollback, recovery, MCP unavailable/setup missing, or explicit user request; do not tell users to run terminal SDD phase commands for normal daily flow. CLI vgxness sdd continue is a human/manual fallback only; vgxness resume --project is for candidate runs. The removed experimental vgxness code runtime is not an SDD fallback.',
264
+ 'Code context: use vgxness_code_context_status before relying on repository-intelligence providers. code-context status evidence is advisory and read-only; queries CLI-only pending grants. Do not install/initialize CodeGraph/Graphify, write provider config, or treat output as SDD acceptance/verification.',
263
265
  'OpenCode native/provider tools are governance-v1 audit-only/non-hard-blocking; report warnings, never say they are hard-blocked by config.',
264
266
  ].join(' ');
265
267
  const subagentData = {
@@ -0,0 +1,20 @@
1
+ export const codeContextProviderIds = ['codegraph', 'graphify'];
2
+ export const codeContextProviderSelections = ['auto', 'codegraph', 'graphify'];
3
+ export const codeContextModes = ['overview', 'architecture', 'debug', 'impact', 'affected-tests', 'verify', 'pr-impact'];
4
+ export const codeContextSafety = {
5
+ readOnly: true,
6
+ writesFiles: false,
7
+ writesProviderConfig: false,
8
+ installsPackages: false,
9
+ initializesIndexes: false,
10
+ registersExternalMcp: false,
11
+ runsHooks: false,
12
+ executesProviderCommands: false,
13
+ externalProviderSideEffects: 'not-invoked',
14
+ };
15
+ export const codeContextProviderCommandSafety = {
16
+ ...codeContextSafety,
17
+ readOnly: false,
18
+ executesProviderCommands: true,
19
+ externalProviderSideEffects: 'unknown',
20
+ };
@@ -17,7 +17,7 @@ Areas:
17
17
  setup rollback --backup <path> [--preview|--yes] [--json]
18
18
  setup status [--project <name>] [--scope project|personal] [--db <path>] [--json]
19
19
  doctor [--db <path>] [--project <name>] [--change <id>] [--timeout-ms <ms>] [--json]
20
- verification plan --type docs-only|test-only|cli|mcp|sdd-storage|provider-setup|package-release|workflow-runs [--json]
20
+ verification plan --type docs-only|test-only|cli|mcp|sdd-storage|provider-setup|package-release|workflow-runs|code-context [--json]
21
21
  verification report save --project <name> --change <id> --file <report.json> [--db <path>] [--json]
22
22
  verification report get --project <name> --change <id> [--db <path>] [--json]
23
23
  Status answers "where am I?" with the human front-door cockpit.
@@ -0,0 +1,67 @@
1
+ import { resolve } from 'node:path';
2
+ import { CodeContextService } from '../../../application/code-context/code-context-service.js';
3
+ import { codeContextModes, codeContextProviderSelections, codeContextSafety } from '../../../domain/code-context/schema.js';
4
+ import { optionalNumberFlag, optionalStringFlag, requiredFlag } from '../cli-flags.js';
5
+ import { okText, usageFailure } from '../cli-help.js';
6
+ export function runCodeContextCommand(command, parsed, environment) {
7
+ const workspaceRoot = resolveWorkspaceRoot(optionalStringFlag(parsed.flags, 'workspace'), environment.cwd);
8
+ const service = new CodeContextService({ commandEnv: environment.env });
9
+ const timeout = optionalNumberFlag(parsed.flags, 'timeout-ms');
10
+ if (!timeout.ok)
11
+ return usageFailure(timeout.error.message);
12
+ const maxBytes = optionalNumberFlag(parsed.flags, 'max-bytes');
13
+ if (!maxBytes.ok)
14
+ return usageFailure(maxBytes.error.message);
15
+ const common = { workspaceRoot, ...(timeout.value !== undefined ? { timeoutMs: timeout.value } : {}), ...(maxBytes.value !== undefined ? { maxBytes: maxBytes.value } : {}) };
16
+ if (command === 'status') {
17
+ const result = service.getStatus(common);
18
+ if (!result.ok)
19
+ return usageFailure(result.error.message);
20
+ return parsed.flags.json === true ? json(result.value) : okText(`${result.value.summary}\n`);
21
+ }
22
+ if (command === 'query') {
23
+ const question = requiredFlag(parsed.flags, 'question');
24
+ if (!question.ok)
25
+ return usageFailure(question.error.message);
26
+ const provider = optionalStringFlag(parsed.flags, 'provider');
27
+ if (provider !== undefined && !codeContextProviderSelections.includes(provider))
28
+ return usageFailure('--provider must be auto, codegraph, or graphify');
29
+ const mode = optionalStringFlag(parsed.flags, 'mode');
30
+ if (mode !== undefined && !codeContextModes.includes(mode))
31
+ return usageFailure(`--mode must be ${codeContextModes.join(', ')}`);
32
+ const result = service.query({
33
+ ...common,
34
+ question: question.value,
35
+ ...(provider !== undefined ? { provider: provider } : {}),
36
+ ...(mode !== undefined ? { mode: mode } : {}),
37
+ });
38
+ if (!result.ok)
39
+ return usageFailure(result.error.message);
40
+ return parsed.flags.json === true ? json(result.value) : okText(`${result.value.summary}\n`);
41
+ }
42
+ if (command === 'setup') {
43
+ if (parsed.positionals[2] !== 'plan' || parsed.positionals.length !== 3)
44
+ return usageFailure('code-context setup requires the plan subcommand');
45
+ const result = service.getSetupPlan(common);
46
+ if (!result.ok)
47
+ return usageFailure(result.error.message);
48
+ return parsed.flags.json === true ? json(result.value) : okText(`${result.value.summary}\n${result.value.recommendedCommands.join('\n')}\n`);
49
+ }
50
+ const body = {
51
+ kind: 'code-context-setup-plan',
52
+ version: 1,
53
+ workspaceRoot,
54
+ recommendedCommands: ['codegraph init # optional: run manually outside VGXNESS', 'graphify --path . --output graphify-out # optional: run manually outside VGXNESS'],
55
+ safety: { ...codeContextSafety },
56
+ summary: '[read-only] Advisory plan only. VGXNESS does not install packages, initialize indexes, register external MCP servers, or write provider config.',
57
+ };
58
+ return parsed.flags.json === true ? json(body) : okText(`${body.summary}\n${body.recommendedCommands.join('\n')}\n`);
59
+ }
60
+ function resolveWorkspaceRoot(value, cwd) {
61
+ if (value === undefined)
62
+ return cwd;
63
+ return value.startsWith('/') ? value : resolve(cwd, value);
64
+ }
65
+ function json(value) {
66
+ return okText(`${JSON.stringify(value, null, 2)}\n`);
67
+ }
@@ -1,3 +1,4 @@
1
+ export { runCodeContextCommand } from './code-context-dispatcher.js';
1
2
  export { runAgentCommand, runSkillCommand, runSubagentCommand } from './agent-skill-dispatcher.js';
2
3
  export { runDefaultInteractiveEntrypoint } from './interactive-entrypoint-dispatcher.js';
3
4
  export { runDoctorAliasCommand, runMcpDoctorCommand, runMcpDoctorOpenCodeCommand, runMcpInstallCommand, runMcpSetupCommand } from './mcp-dispatcher.js';
@@ -5,7 +5,7 @@ import { runBootAgentSeedUpgrade } from '../../agents/boot-upgrade.js';
5
5
  import { databasePathFor, parseArgs, requiredFlag } from './cli-flags.js';
6
6
  import { okText, usageFailure, visibleHelpText } from './cli-help.js';
7
7
  import { openCliDatabase, resultFailure } from './cli-helpers.js';
8
- import { runAgentCommand, runApprovalsCommand, runDefaultInteractiveEntrypoint, runDoctorAliasCommand, runHomeTuiCommand, runInitCommand, runMcpDoctorCommand, runMcpInstallCommand, runMcpSetupCommand, runMemoryCommand, runMemoryImportCommand, runOpenCodeCommand, runOrchestratorCommand, runPermissionsCommand, runProductNextCommand, runProductResumeCommand, runProductStatusCommand, runRunsCommand, runSddCommand, runSetupApplyCommand, runSetupLifecycleCommand, runSetupPlanCommand, runSetupReinstallApplyCommand, runSetupRollbackCommand, runSkillCommand, runSubagentCommand, runVerificationPlanCommand, runVerificationReportCommand, runWorkflowExecuteCommand, runWorkflowPreviewCommand, runWorkflowRunCommand, } from './commands/index.js';
8
+ import { runAgentCommand, runApprovalsCommand, runCodeContextCommand, runDefaultInteractiveEntrypoint, runDoctorAliasCommand, runHomeTuiCommand, runInitCommand, runMcpDoctorCommand, runMcpInstallCommand, runMcpSetupCommand, runMemoryCommand, runMemoryImportCommand, runOpenCodeCommand, runOrchestratorCommand, runPermissionsCommand, runProductNextCommand, runProductResumeCommand, runProductStatusCommand, runRunsCommand, runSddCommand, runSetupApplyCommand, runSetupLifecycleCommand, runSetupPlanCommand, runSetupReinstallApplyCommand, runSetupRollbackCommand, runSkillCommand, runSubagentCommand, runVerificationPlanCommand, runVerificationReportCommand, runWorkflowExecuteCommand, runWorkflowPreviewCommand, runWorkflowRunCommand, } from './commands/index.js';
9
9
  import { canRunInteractiveTui } from './tui/terminal-capabilities.js';
10
10
  const _promptBuffers = new WeakMap();
11
11
  const require = createRequire(import.meta.url);
@@ -35,6 +35,8 @@ export function dispatchCli(argv, environment) {
35
35
  return usageFailure(commandValidation.message);
36
36
  if (area === 'setup')
37
37
  return runSetupLifecycleCommand(parsed, environment);
38
+ if (area === 'code-context')
39
+ return runCodeContextCommand(command, parsed, environment);
38
40
  if (area === 'verification' && command === 'plan')
39
41
  return runVerificationPlanCommand(command, parsed);
40
42
  if (isWorkflowId(area) && command === 'preview')
@@ -235,6 +237,9 @@ function validateCommand(area, command) {
235
237
  if (area === 'opencode') {
236
238
  return command === 'preview' ? { ok: true } : { ok: false, message: `Unknown opencode command: ${command}` };
237
239
  }
240
+ if (area === 'code-context') {
241
+ return command === 'status' || command === 'query' || command === 'setup' ? { ok: true } : { ok: false, message: `Unknown code-context command: ${command}` };
242
+ }
238
243
  if (area === 'setup') {
239
244
  return command === 'status' || command === 'plan' || command === 'apply' || command === 'reinstall' || command === 'backup' || command === 'rollback'
240
245
  ? { ok: true }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ import { errorEnvelope, successEnvelope } from '../../schema.js';
2
+ export function codeContextStatusEnvelope(input, services) {
3
+ if (services.codeContext === undefined)
4
+ return errorEnvelope('validation_failed', 'Code-context service is not available', 'vgxness_code_context_status');
5
+ const result = services.codeContext.getStatus(input);
6
+ return result.ok ? successEnvelope('vgxness_code_context_status', result.value) : errorEnvelope('validation_failed', result.error.message, 'vgxness_code_context_status');
7
+ }
@@ -1,5 +1,6 @@
1
1
  import { OpenCodeHandoffPreviewService } from '../../adapters/opencode/install/opencode-handoff-preview.js';
2
2
  import { AgentActivationService } from '../../agents/agent-activation-service.js';
3
+ import { CodeContextService } from '../../application/code-context/code-context-service.js';
3
4
  import { AgentRegistryService } from '../../agents/agent-registry-service.js';
4
5
  import { ManagerProfileOverlayService } from '../../agents/manager-profile-overlay-service.js';
5
6
  import { ManagerProfileOverlayRepository } from '../../agents/repositories/manager-profile-overlays.js';
@@ -18,6 +19,7 @@ import { SkillRegistryService } from '../../skills/skill-registry-service.js';
18
19
  import { SkillStatusService } from '../../skills/skill-status-service.js';
19
20
  import { VerificationPlanService } from '../../verification/index.js';
20
21
  import { agentActivateEnvelope, agentResolveEnvelope, managerProfileGetEnvelope, managerProfileSetEnvelope, opencodeHandoffPreviewEnvelope, opencodeManagerPayloadEnvelope, } from './control-plane/handlers/agents.js';
22
+ import { codeContextStatusEnvelope } from './control-plane/handlers/code-context.js';
21
23
  import { contextCockpitEnvelope, resumeContextEnvelope } from './control-plane/handlers/context.js';
22
24
  import { memoryGetEnvelope, memorySaveEnvelope, memorySearchEnvelope, memoryUpdateEnvelope } from './control-plane/handlers/memory.js';
23
25
  import { providerChangePlanEnvelope, providerDoctorEnvelope, providerStatusEnvelope } from './control-plane/handlers/providers.js';
@@ -75,6 +77,8 @@ export function callVgxTool(call, services) {
75
77
  return sessionRestoreEnvelope(validated.input, services);
76
78
  case 'vgxness_context_cockpit':
77
79
  return contextCockpitEnvelope(validated.input, services);
80
+ case 'vgxness_code_context_status':
81
+ return codeContextStatusEnvelope(validated.input, services);
78
82
  case 'vgxness_resume_context':
79
83
  return resumeContextEnvelope(validated.input, services);
80
84
  case 'vgxness_agent_resolve':
@@ -218,6 +222,7 @@ function createServices(database) {
218
222
  opencodeHandoffPreview: new OpenCodeHandoffPreviewService({ managerPayload: opencodeManagerPayload, sdd, providerStatus }),
219
223
  activation: new AgentActivationService({ agents, managerProfiles, runs, opencodeManagerPayload }),
220
224
  runs,
225
+ codeContext: new CodeContextService(),
221
226
  providerStatus,
222
227
  providerDoctor,
223
228
  providerChangePlan: new ProviderChangePlanService({ providerStatus, providerDoctor }),
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { AGENTS_MCP_TOOL_INPUT_SCHEMAS, CONTEXT_MCP_TOOL_INPUT_SCHEMAS, GOVERNANCE_MCP_TOOL_INPUT_SCHEMAS, MEMORY_MCP_TOOL_INPUT_SCHEMAS, PROVIDERS_MCP_TOOL_INPUT_SCHEMAS, RUNS_MCP_TOOL_INPUT_SCHEMAS, SDD_MCP_TOOL_INPUT_SCHEMAS, SESSIONS_MCP_TOOL_INPUT_SCHEMAS, SKILLS_MCP_TOOL_INPUT_SCHEMAS, VERIFICATION_MCP_TOOL_INPUT_SCHEMAS, } from './schemas/inputs/index.js';
2
+ import { AGENTS_MCP_TOOL_INPUT_SCHEMAS, CONTEXT_MCP_TOOL_INPUT_SCHEMAS, CODE_CONTEXT_MCP_TOOL_INPUT_SCHEMAS, GOVERNANCE_MCP_TOOL_INPUT_SCHEMAS, MEMORY_MCP_TOOL_INPUT_SCHEMAS, PROVIDERS_MCP_TOOL_INPUT_SCHEMAS, RUNS_MCP_TOOL_INPUT_SCHEMAS, SDD_MCP_TOOL_INPUT_SCHEMAS, SESSIONS_MCP_TOOL_INPUT_SCHEMAS, SKILLS_MCP_TOOL_INPUT_SCHEMAS, VERIFICATION_MCP_TOOL_INPUT_SCHEMAS, } from './schemas/inputs/index.js';
3
3
  import { buildProviderMcpToolOutputSchemas, buildSddMcpToolOutputSchemas } from './schemas/outputs/index.js';
4
4
  export const SUPPORTED_VGX_MCP_TOOL_NAMES = [
5
5
  'vgxness_sdd_status',
@@ -23,6 +23,7 @@ export const SUPPORTED_VGX_MCP_TOOL_NAMES = [
23
23
  'vgxness_session_close',
24
24
  'vgxness_session_restore',
25
25
  'vgxness_context_cockpit',
26
+ 'vgxness_code_context_status',
26
27
  'vgxness_resume_context',
27
28
  'vgxness_agent_resolve',
28
29
  'vgxness_agent_activate',
@@ -86,6 +87,7 @@ export const EXPOSED_VGX_MCP_TOOL_NAMES = [
86
87
  'session_close',
87
88
  'session_restore',
88
89
  'context_cockpit',
90
+ 'code_context_status',
89
91
  'resume_context',
90
92
  'agent_resolve',
91
93
  'agent_activate',
@@ -147,6 +149,7 @@ export const VGX_MCP_TOOL_INPUT_SCHEMAS = {
147
149
  ...MEMORY_MCP_TOOL_INPUT_SCHEMAS,
148
150
  ...SESSIONS_MCP_TOOL_INPUT_SCHEMAS,
149
151
  ...CONTEXT_MCP_TOOL_INPUT_SCHEMAS,
152
+ ...CODE_CONTEXT_MCP_TOOL_INPUT_SCHEMAS,
150
153
  ...AGENTS_MCP_TOOL_INPUT_SCHEMAS,
151
154
  ...SKILLS_MCP_TOOL_INPUT_SCHEMAS,
152
155
  ...RUNS_MCP_TOOL_INPUT_SCHEMAS,
@@ -0,0 +1,10 @@
1
+ import { z } from 'zod';
2
+ export const CODE_CONTEXT_MCP_TOOL_INPUT_SCHEMAS = {
3
+ vgxness_code_context_status: z
4
+ .object({
5
+ workspaceRoot: z.string().min(1),
6
+ timeoutMs: z.number().int().positive().optional(),
7
+ maxBytes: z.number().int().positive().optional(),
8
+ })
9
+ .passthrough(),
10
+ };
@@ -1,5 +1,6 @@
1
1
  export { AGENTS_MCP_TOOL_INPUT_SCHEMAS } from './agents.js';
2
2
  export { CONTEXT_MCP_TOOL_INPUT_SCHEMAS } from './context.js';
3
+ export { CODE_CONTEXT_MCP_TOOL_INPUT_SCHEMAS } from './code-context.js';
3
4
  export { GOVERNANCE_MCP_TOOL_INPUT_SCHEMAS } from './governance.js';
4
5
  export { MEMORY_MCP_TOOL_INPUT_SCHEMAS } from './memory.js';
5
6
  export { PROVIDERS_MCP_TOOL_INPUT_SCHEMAS } from './providers.js';
@@ -0,0 +1,22 @@
1
+ import { inputRecord, readNonEmptyString, validationFailure } from './common.js';
2
+ export function validateCodeContextStatusInput(input, tool) {
3
+ const record = inputRecord(input, tool, ['workspaceRoot', 'timeoutMs', 'maxBytes']);
4
+ if (!record.ok)
5
+ return record;
6
+ const workspaceRoot = readNonEmptyString(record.value, 'workspaceRoot', tool);
7
+ if (!workspaceRoot.ok)
8
+ return workspaceRoot;
9
+ const result = { workspaceRoot: workspaceRoot.value };
10
+ const numeric = copyOptionalPositiveIntegers(result, record.value, tool, ['timeoutMs', 'maxBytes']);
11
+ return numeric.ok ? { ok: true, value: result } : numeric;
12
+ }
13
+ function copyOptionalPositiveIntegers(target, record, tool, fields) {
14
+ for (const field of fields) {
15
+ if (record[field] === undefined)
16
+ continue;
17
+ if (typeof record[field] !== 'number' || !Number.isSafeInteger(record[field]) || record[field] <= 0)
18
+ return validationFailure(`${field} must be a positive safe integer`, tool);
19
+ target[field] = record[field];
20
+ }
21
+ return { ok: true, value: undefined };
22
+ }
@@ -1,5 +1,6 @@
1
1
  import { isVgxMcpToolName } from './schema.js';
2
2
  import { validateAgentActivateInput, validateAgentResolveInput, validateManagerProfileGetInput, validateManagerProfileSetInput, validateOpenCodeHandoffPreviewInput, validateOpenCodeManagerPayloadInput, } from './validation/agents.js';
3
+ import { validateCodeContextStatusInput } from './validation/code-context.js';
3
4
  import { asRecord, readString, toValidationResultFailure, validationFailure, validationSuccess } from './validation/common.js';
4
5
  import { validateGovernanceReportInput } from './validation/governance.js';
5
6
  import { validateMemoryGetInput, validateMemorySaveInput, validateMemorySearchInput, validateMemoryUpdateInput } from './validation/memory.js';
@@ -62,6 +63,8 @@ export function validateVgxMcpToolCall(call) {
62
63
  return validationSuccess(tool.value, validateSessionRestoreInput(input, tool.value));
63
64
  case 'vgxness_context_cockpit':
64
65
  return validationSuccess(tool.value, validateContextCockpitInput(input, tool.value));
66
+ case 'vgxness_code_context_status':
67
+ return validationSuccess(tool.value, validateCodeContextStatusInput(input, tool.value));
65
68
  case 'vgxness_resume_context':
66
69
  return validationSuccess(tool.value, validateResumeContextInput(input, tool.value));
67
70
  case 'vgxness_agent_resolve':
@@ -49,6 +49,20 @@ const templates = {
49
49
  recommendations: [nodeVersionRecommendation(), typecheckRecommendation(), manualRecommendation('manual-workflow-tests', 'Run workflow/run tests manually', 'Copy focused node --import tsx --test commands for touched workflow or run test files.')],
50
50
  manualChecks: [manualCheck('review-allowlist-boundary', 'Review command allowlist boundary', 'Confirm no arbitrary shell, argv, or package-script execution contract was added.')],
51
51
  },
52
+ 'code-context': {
53
+ rationale: [
54
+ 'Code-context changes span CLI, MCP, provider selection, and bounded repository-intelligence probes.',
55
+ 'CodeGraph and Graphify evidence must remain read-only advisory context; verification must not install packages, initialize indexes, or write provider config.',
56
+ ],
57
+ recommendations: [
58
+ typecheckRecommendation(),
59
+ manualRecommendation('manual-code-context-tests', 'Run focused code-context tests manually', 'Copy focused node --import tsx --test commands for code-context service, MCP, CLI, docs, and prompt tests after selecting touched files.'),
60
+ ],
61
+ manualChecks: [
62
+ manualCheck('review-code-context-read-only-boundary', 'Review code-context read-only boundary', 'Confirm CodeGraph and Graphify paths only report status/query evidence and do not install packages, initialize indexes, write provider config, or infer SDD acceptance.'),
63
+ manualCheck('review-code-context-provider-selection', 'Review provider selection guidance', 'Confirm source/call-path/blast-radius modes prefer CodeGraph and architecture/docs/corpus modes prefer Graphify while unsupported/missing providers degrade gracefully.'),
64
+ ],
65
+ },
52
66
  };
53
67
  export class VerificationPlanService {
54
68
  getPlan(changeType) {
@@ -8,6 +8,7 @@ export const verificationChangeTypes = [
8
8
  'provider-setup',
9
9
  'package-release',
10
10
  'workflow-runs',
11
+ 'code-context',
11
12
  ];
12
13
  export const verificationChangeTypeList = verificationChangeTypes.join(', ');
13
14
  export const verificationPlanSafety = Object.freeze({
package/docs/cli.md CHANGED
@@ -262,6 +262,19 @@ Provider support for setup is:
262
262
 
263
263
  Setup CLI surfaces do **not** silently write OpenCode or other provider config, do **not** call provider executables, and do **not** approve/reject preflights. They print diagnostics, recovery hints, and manual fallback commands; daily SDD work should continue in OpenCode.
264
264
 
265
+
266
+ ## Code context CLI
267
+
268
+ Use `code-context status` and `code-context query` when you need optional repository-intelligence evidence from CodeGraph or Graphify without making those tools part of setup.
269
+
270
+ ```bash
271
+ bun run cli:bun -- code-context status --workspace . --json
272
+ bun run cli:bun -- code-context query --workspace . --mode impact --question "What calls this service?" --json
273
+ bun run cli:bun -- code-context setup plan --workspace .
274
+ ```
275
+
276
+ `code-context setup plan` is guidance only. The code-context CLI never installs packages, does not initialize indexes, does not write provider config, does not register external MCP servers, and does not infer SDD acceptance. `code-context query` is an explicit CLI command that runs the selected provider binary under bounded timeout/output caps; provider side effects are treated as unknown and the query tool is not exposed over MCP. CodeGraph is preferred for impact/debug/affected-tests modes; Graphify is preferred for architecture/overview/PR-impact modes. Missing providers degrade to diagnostics instead of auto-installing anything.
277
+
265
278
  ## Natural-language orchestrator preview
266
279
 
267
280
  Use `orchestrator preview` when you want `vgxness` to classify a request before deciding whether to answer directly, plan manually, diagnose, or enter SDD:
package/docs/mcp.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # MCP tools
2
2
 
3
- VGXNESS exposes 42 typed MCP tools over stdio through `vgxness mcp start`. The canonical list is the `SUPPORTED_VGX_MCP_TOOL_NAMES` array in `src/mcp/schema.ts` — treat that as the source of truth. The list below mirrors it; if a tool appears here that is not in the array, or vice versa, the array wins.
3
+ VGXNESS exposes 43 typed MCP tools over stdio through `vgxness mcp start`. The canonical list is the `SUPPORTED_VGX_MCP_TOOL_NAMES` array in `src/mcp/schema.ts` — treat that as the source of truth. The list below mirrors it; if a tool appears here that is not in the array, or vice versa, the array wins.
4
4
 
5
5
  Tools are exposed under the `vgxness_*` prefix. Some MCP hosts strip the prefix and accept the short form (`sdd_status`, `memory_save`, etc.). The schema accepts both.
6
6
 
@@ -107,11 +107,19 @@ Run `status` accepts the full 8-state vocabulary: `created`, `planned`, `running
107
107
  | `vgxness_provider_doctor` | Run provider health checks with structured JSON output. | same as `status` | |
108
108
  | `vgxness_provider_change_plan` | Compose a read-only provider config change plan. | `ProviderChangePlanInput` shape (`provider`: `opencode`/`claude`/`antigravity`/`custom`; `changeType`: `opencode-mcp-install`/`setup`/`install`/`config-preparation`; `workspaceRoot`; `payloadMode`) | Does not write provider config. See [Providers](./providers.md). |
109
109
 
110
+ ## Code context (1)
111
+
112
+ | Tool | Purpose | Required inputs | Notes |
113
+ |---|---|---|---|
114
+ | `vgxness_code_context_status` | Report optional CodeGraph and Graphify provider availability/index state. | `workspaceRoot`; optional `timeoutMs`, `maxBytes` | Read-only status only; does not install packages, initialize indexes, write provider config, run provider query commands, or infer SDD acceptance. |
115
+
116
+ Code-context output is advisory evidence only. It can guide SDD, debugging, planning, verification, PR evidence, onboarding, and memory summaries, but it does not prove implementation correctness, artifact acceptance, or verification completion. The MCP surface exposes status only and does not install packages, initialize indexes, write provider config, run provider query commands, mutate files, or register external MCP servers. Provider-backed code-context queries intentionally stay CLI-only for now because they execute external provider binaries on the host; exposing them through MCP requires a future task-scoped grant/sandbox boundary.
117
+
110
118
  ## Verification (1)
111
119
 
112
120
  | Tool | Purpose | Required inputs |
113
121
  |---|---|---|
114
- | `vgxness_verification_plan` | Recommend a verification plan for a change type. | `changeType` (`docs-only`/`test-only`/`cli`/`mcp`/`sdd-storage`/`provider-setup`/`package-release`/`workflow-runs`) |
122
+ | `vgxness_verification_plan` | Recommend a verification plan for a change type. | `changeType` (`docs-only`/`test-only`/`cli`/`mcp`/`sdd-storage`/`provider-setup`/`package-release`/`workflow-runs`/`code-context`) |
115
123
 
116
124
  ## Usage patterns
117
125
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vgxness",
3
- "version": "1.20.7",
3
+ "version": "1.20.9",
4
4
  "description": "CLI and MCP control plane for guided AI-agent workflows, SDD, memory, and OpenCode setup.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "repository": {