vgxness 1.5.1 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -2
- package/dist/agents/agent-seed-service.js +10 -0
- package/dist/agents/canonical-agent-manifest.js +177 -0
- package/dist/agents/canonical-agent-projection.js +146 -0
- package/dist/agents/renderers/claude-renderer.js +30 -52
- package/dist/cli/bun-bin.js +6 -0
- package/dist/cli/cli-help.js +3 -0
- package/dist/cli/commands/agent-skill-dispatcher.js +6 -5
- package/dist/cli/commands/mcp-dispatcher.js +65 -3
- package/dist/cli/index.js +1 -1
- package/dist/governance/governance-report-builder.js +45 -26
- package/dist/mcp/claude-code-agent-config.js +79 -0
- package/dist/mcp/claude-code-config.js +84 -0
- package/dist/mcp/client-install-claude-code-contract.js +86 -0
- package/dist/mcp/client-install-claude-code.js +85 -0
- package/dist/mcp/index.js +5 -0
- package/dist/mcp/opencode-default-agent-config.js +7 -113
- package/dist/mcp/provider-canonical-agent-manifest.js +39 -0
- package/dist/mcp/provider-change-plan.js +57 -1
- package/dist/mcp/provider-doctor.js +54 -0
- package/dist/mcp/provider-status.js +82 -2
- package/dist/mcp/schema.js +2 -2
- package/dist/mcp/validation.js +1 -1
- package/dist/memory/memory-service.js +4 -0
- package/dist/sdd/sdd-workflow-service.js +129 -59
- package/dist/setup/providers/claude-setup-adapter.js +7 -4
- package/docs/architecture.md +54 -112
- package/docs/cli.md +53 -0
- package/docs/code-runtime.md +218 -0
- package/docs/contributing.md +120 -0
- package/docs/glossary.md +211 -0
- package/docs/mcp.md +144 -0
- package/docs/prd.md +23 -26
- package/docs/providers.md +123 -0
- package/docs/roadmap.md +88 -0
- package/docs/safety.md +147 -0
- package/docs/storage.md +93 -0
- package/package.json +1 -1
- package/docs/funcionamiento-del-sistema.md +0 -865
- package/docs/harness-gap-analysis.md +0 -243
- package/docs/vgxcode.md +0 -87
- package/docs/vgxness-code.md +0 -48
|
@@ -21,7 +21,9 @@ export class SddWorkflowService {
|
|
|
21
21
|
if (!validated.ok)
|
|
22
22
|
return validated;
|
|
23
23
|
const phases = this.getPhaseStatuses(validated.value.project, validated.value.change);
|
|
24
|
-
|
|
24
|
+
if (!phases.ok)
|
|
25
|
+
return phases;
|
|
26
|
+
const readiness = getReadinessFromStatuses(validated.value.change, validated.value.phase, phases.value);
|
|
25
27
|
return {
|
|
26
28
|
ok: true,
|
|
27
29
|
value: {
|
|
@@ -36,20 +38,27 @@ export class SddWorkflowService {
|
|
|
36
38
|
if (!validated.ok)
|
|
37
39
|
return validated;
|
|
38
40
|
const phases = this.getPhaseStatuses(validated.value.project, validated.value.change);
|
|
39
|
-
|
|
41
|
+
if (!phases.ok)
|
|
42
|
+
return phases;
|
|
43
|
+
return statusFromPhases(validated.value.change, phases.value);
|
|
40
44
|
}
|
|
41
45
|
getNext(input) {
|
|
42
46
|
const validated = validateProjectAndChange(input.project, input.change);
|
|
43
47
|
if (!validated.ok)
|
|
44
48
|
return validated;
|
|
45
49
|
const phases = this.getPhaseStatuses(validated.value.project, validated.value.change);
|
|
46
|
-
|
|
50
|
+
if (!phases.ok)
|
|
51
|
+
return phases;
|
|
52
|
+
return ok(nextDecisionFromStatuses(validated.value.change, phases.value));
|
|
47
53
|
}
|
|
48
54
|
getCockpit(input) {
|
|
49
55
|
const validated = validateProjectAndChange(input.project, input.change);
|
|
50
56
|
if (!validated.ok)
|
|
51
57
|
return validated;
|
|
52
|
-
const
|
|
58
|
+
const snapshot = this.loadPhaseSnapshot(validated.value.project, validated.value.change);
|
|
59
|
+
if (!snapshot.ok)
|
|
60
|
+
return snapshot;
|
|
61
|
+
const phases = snapshot.value.phases;
|
|
53
62
|
const next = nextDecisionFromStatuses(validated.value.change, phases);
|
|
54
63
|
const cockpitPhases = phases.map((phaseStatus) => {
|
|
55
64
|
const readiness = {
|
|
@@ -57,9 +66,7 @@ export class SddWorkflowService {
|
|
|
57
66
|
phase: phaseStatus.phase,
|
|
58
67
|
...getReadinessFromStatuses(validated.value.change, phaseStatus.phase, phases),
|
|
59
68
|
};
|
|
60
|
-
const artifact = phaseStatus.present
|
|
61
|
-
? this.artifactSummaryForPhase(validated.value.project, validated.value.change, phaseStatus.phase, phaseStatus.topicKey)
|
|
62
|
-
: undefined;
|
|
69
|
+
const artifact = phaseStatus.present ? cockpitArtifactSummaryFromSnapshotItem(phaseStatus) : undefined;
|
|
63
70
|
const blockers = cockpitBlockersForPhase(phaseStatus, readiness);
|
|
64
71
|
return {
|
|
65
72
|
phase: phaseStatus.phase,
|
|
@@ -100,6 +107,39 @@ export class SddWorkflowService {
|
|
|
100
107
|
};
|
|
101
108
|
return ok(cockpit);
|
|
102
109
|
}
|
|
110
|
+
getGovernanceSnapshot(input) {
|
|
111
|
+
const validated = validateProjectAndChange(input.project, input.change);
|
|
112
|
+
if (!validated.ok)
|
|
113
|
+
return validated;
|
|
114
|
+
const snapshot = this.loadPhaseSnapshot(validated.value.project, validated.value.change);
|
|
115
|
+
if (!snapshot.ok)
|
|
116
|
+
return snapshot;
|
|
117
|
+
const phases = snapshot.value.phases;
|
|
118
|
+
const status = statusFromPhases(validated.value.change, phases);
|
|
119
|
+
if (!status.ok)
|
|
120
|
+
return status;
|
|
121
|
+
const warnings = [];
|
|
122
|
+
const artifacts = phases.flatMap((phase) => {
|
|
123
|
+
if (phase.artifact === undefined)
|
|
124
|
+
return [];
|
|
125
|
+
const envelope = normalizeSddArtifact(phase.artifact);
|
|
126
|
+
warnings.push(...envelope.warnings);
|
|
127
|
+
if ((input.payloadMode ?? 'compact') === 'compact') {
|
|
128
|
+
const compactArtifact = compactGovernanceArtifact(envelope.artifact);
|
|
129
|
+
return [
|
|
130
|
+
{
|
|
131
|
+
phase: phase.phase,
|
|
132
|
+
topicKey: phase.topicKey,
|
|
133
|
+
artifact: compactArtifact,
|
|
134
|
+
envelope: { ...envelope, artifact: compactArtifact },
|
|
135
|
+
},
|
|
136
|
+
];
|
|
137
|
+
}
|
|
138
|
+
return [{ phase: phase.phase, topicKey: phase.topicKey, artifact: phase.artifact, envelope }];
|
|
139
|
+
});
|
|
140
|
+
const readiness = input.phase === undefined ? undefined : { change: validated.value.change, phase: input.phase, ...getReadinessFromStatuses(validated.value.change, input.phase, phases) };
|
|
141
|
+
return ok({ status: status.value, artifacts, ...(readiness === undefined ? {} : { readiness }), warnings });
|
|
142
|
+
}
|
|
103
143
|
saveArtifact(input) {
|
|
104
144
|
const validated = this.validatePhaseInput(input);
|
|
105
145
|
if (!validated.ok)
|
|
@@ -161,12 +201,33 @@ export class SddWorkflowService {
|
|
|
161
201
|
if (input.payloadMode !== 'compact')
|
|
162
202
|
return artifact;
|
|
163
203
|
const statuses = this.getPhaseStatuses(validated.value.project, validated.value.change);
|
|
164
|
-
|
|
204
|
+
if (!statuses.ok)
|
|
205
|
+
return statuses;
|
|
206
|
+
return ok(compactArtifactProjection(artifact.value, validated.value.change, validated.value.phase, getReadinessFromStatuses(validated.value.change, validated.value.phase, statuses.value)));
|
|
165
207
|
}
|
|
166
208
|
listArtifacts(input) {
|
|
167
209
|
const validated = validateProjectAndChange(input.project, input.change);
|
|
168
210
|
if (!validated.ok)
|
|
169
211
|
return validated;
|
|
212
|
+
if (input.payloadMode === 'compact') {
|
|
213
|
+
const snapshot = this.loadPhaseSnapshot(validated.value.project, validated.value.change);
|
|
214
|
+
if (!snapshot.ok)
|
|
215
|
+
return snapshot;
|
|
216
|
+
return ok({
|
|
217
|
+
project: validated.value.project,
|
|
218
|
+
change: validated.value.change,
|
|
219
|
+
artifacts: snapshot.value.phases.flatMap((phase) => {
|
|
220
|
+
if (phase.artifact === undefined)
|
|
221
|
+
return [];
|
|
222
|
+
return [compactArtifactProjection(phase.artifact, validated.value.change, phase.phase, getReadinessFromStatuses(validated.value.change, phase.phase, snapshot.value.phases))];
|
|
223
|
+
}),
|
|
224
|
+
fullRetrieval: {
|
|
225
|
+
tool: 'vgxness_sdd_list_artifacts',
|
|
226
|
+
payloadMode: 'verbose',
|
|
227
|
+
input: { project: validated.value.project, change: validated.value.change },
|
|
228
|
+
},
|
|
229
|
+
});
|
|
230
|
+
}
|
|
170
231
|
const listed = this.memory.listArtifactsByTopicPrefix(validated.value.project, `sdd/${validated.value.change}/`, this.context);
|
|
171
232
|
if (!listed.ok)
|
|
172
233
|
return listed;
|
|
@@ -174,22 +235,7 @@ export class SddWorkflowService {
|
|
|
174
235
|
const artifacts = sddPhases
|
|
175
236
|
.map((phase) => artifactsByTopicKey.get(sddTopicKey(validated.value.change, phase)))
|
|
176
237
|
.filter((artifact) => artifact !== undefined);
|
|
177
|
-
|
|
178
|
-
return ok({ project: validated.value.project, change: validated.value.change, artifacts });
|
|
179
|
-
const statuses = this.getPhaseStatuses(validated.value.project, validated.value.change);
|
|
180
|
-
return ok({
|
|
181
|
-
project: validated.value.project,
|
|
182
|
-
change: validated.value.change,
|
|
183
|
-
artifacts: artifacts.map((artifact) => {
|
|
184
|
-
const phase = isSddPhase(artifact.phase) ? artifact.phase : phaseFromTopicKey(validated.value.change, artifact.topicKey);
|
|
185
|
-
return compactArtifactProjection(artifact, validated.value.change, phase, getReadinessFromStatuses(validated.value.change, phase, statuses));
|
|
186
|
-
}),
|
|
187
|
-
fullRetrieval: {
|
|
188
|
-
tool: 'vgxness_sdd_list_artifacts',
|
|
189
|
-
payloadMode: 'verbose',
|
|
190
|
-
input: { project: validated.value.project, change: validated.value.change },
|
|
191
|
-
},
|
|
192
|
-
});
|
|
238
|
+
return ok({ project: validated.value.project, change: validated.value.change, artifacts });
|
|
193
239
|
}
|
|
194
240
|
validatePhaseInput(input) {
|
|
195
241
|
const validated = validateProjectAndChange(input.project, input.change);
|
|
@@ -200,31 +246,38 @@ export class SddWorkflowService {
|
|
|
200
246
|
return { ok: true, value: { ...validated.value, phase: input.phase } };
|
|
201
247
|
}
|
|
202
248
|
getPhaseStatuses(project, change) {
|
|
203
|
-
|
|
249
|
+
const snapshot = this.loadPhaseSnapshot(project, change);
|
|
250
|
+
if (!snapshot.ok)
|
|
251
|
+
return snapshot;
|
|
252
|
+
return ok(snapshot.value.phases.map(({ artifact, acceptance, createdAt, updatedAt, warnings, ...status }) => status));
|
|
253
|
+
}
|
|
254
|
+
loadPhaseSnapshot(project, change) {
|
|
255
|
+
const listed = this.memory.listArtifactsByTopicPrefixNoTrace(project, `sdd/${change}/`);
|
|
256
|
+
if (!listed.ok)
|
|
257
|
+
return listed;
|
|
258
|
+
const artifactsByTopicKey = new Map(listed.value.map((artifact) => [artifact.topicKey, artifact]));
|
|
259
|
+
const phases = sddPhases.map((phase) => {
|
|
204
260
|
const topicKey = sddTopicKey(change, phase);
|
|
205
|
-
const artifact =
|
|
206
|
-
if (
|
|
207
|
-
return { phase, topicKey, present: false, state: 'missing', accepted: false, legacy: false };
|
|
208
|
-
|
|
261
|
+
const artifact = artifactsByTopicKey.get(topicKey);
|
|
262
|
+
if (artifact === undefined)
|
|
263
|
+
return { phase, topicKey, present: false, state: 'missing', accepted: false, legacy: false, warnings: [] };
|
|
264
|
+
const envelope = normalizeSddArtifact(artifact);
|
|
265
|
+
return {
|
|
266
|
+
phase,
|
|
267
|
+
topicKey,
|
|
268
|
+
present: true,
|
|
269
|
+
state: envelope.metadata.status,
|
|
270
|
+
accepted: envelope.metadata.status === 'accepted',
|
|
271
|
+
legacy: envelope.warnings.includes('legacy-artifact-defaulted-to-draft'),
|
|
272
|
+
artifactId: artifact.id,
|
|
273
|
+
artifact,
|
|
274
|
+
...(envelope.metadata.acceptance === undefined ? {} : { acceptance: envelope.metadata.acceptance }),
|
|
275
|
+
createdAt: artifact.createdAt,
|
|
276
|
+
updatedAt: artifact.updatedAt,
|
|
277
|
+
warnings: envelope.warnings,
|
|
278
|
+
};
|
|
209
279
|
});
|
|
210
|
-
|
|
211
|
-
artifactSummaryForPhase(project, change, phase, topicKey) {
|
|
212
|
-
const artifact = this.memory.getArtifact(project, topicKey, this.context);
|
|
213
|
-
if (!artifact.ok)
|
|
214
|
-
return undefined;
|
|
215
|
-
const envelope = normalizeSddArtifact(artifact.value);
|
|
216
|
-
return {
|
|
217
|
-
phase,
|
|
218
|
-
topicKey,
|
|
219
|
-
present: true,
|
|
220
|
-
accepted: envelope.metadata.status === 'accepted',
|
|
221
|
-
legacy: envelope.warnings.includes('legacy-artifact-defaulted-to-draft'),
|
|
222
|
-
state: envelope.metadata.status,
|
|
223
|
-
artifactId: artifact.value.id,
|
|
224
|
-
...(envelope.metadata.acceptance === undefined ? {} : { acceptance: envelope.metadata.acceptance }),
|
|
225
|
-
createdAt: artifact.value.createdAt,
|
|
226
|
-
updatedAt: artifact.value.updatedAt,
|
|
227
|
-
};
|
|
280
|
+
return ok({ project, change, phases });
|
|
228
281
|
}
|
|
229
282
|
}
|
|
230
283
|
export function nextDecisionFromStatuses(change, phases) {
|
|
@@ -336,18 +389,6 @@ function getReadinessFromStatuses(change, phase, phases) {
|
|
|
336
389
|
blockedPrerequisites,
|
|
337
390
|
};
|
|
338
391
|
}
|
|
339
|
-
function phaseStatusFromArtifact(phase, topicKey, artifact) {
|
|
340
|
-
const envelope = normalizeSddArtifact(artifact);
|
|
341
|
-
return {
|
|
342
|
-
phase,
|
|
343
|
-
topicKey,
|
|
344
|
-
present: true,
|
|
345
|
-
state: envelope.metadata.status,
|
|
346
|
-
accepted: envelope.metadata.status === 'accepted',
|
|
347
|
-
legacy: envelope.warnings.includes('legacy-artifact-defaulted-to-draft'),
|
|
348
|
-
artifactId: artifact.id,
|
|
349
|
-
};
|
|
350
|
-
}
|
|
351
392
|
function compactArtifactProjection(artifact, change, phase, readiness) {
|
|
352
393
|
const envelope = normalizeSddArtifact(artifact);
|
|
353
394
|
const summary = summarizePayloadContent(artifact.content);
|
|
@@ -370,6 +411,35 @@ function compactArtifactProjection(artifact, change, phase, readiness) {
|
|
|
370
411
|
updatedAt: artifact.updatedAt,
|
|
371
412
|
};
|
|
372
413
|
}
|
|
414
|
+
function cockpitArtifactSummaryFromSnapshotItem(item) {
|
|
415
|
+
if (item.artifact === undefined || item.artifactId === undefined || item.createdAt === undefined || item.updatedAt === undefined)
|
|
416
|
+
return undefined;
|
|
417
|
+
return {
|
|
418
|
+
phase: item.phase,
|
|
419
|
+
topicKey: item.topicKey,
|
|
420
|
+
present: true,
|
|
421
|
+
accepted: item.accepted === true,
|
|
422
|
+
legacy: item.legacy === true,
|
|
423
|
+
state: item.state ?? 'draft',
|
|
424
|
+
artifactId: item.artifactId,
|
|
425
|
+
...(item.acceptance === undefined ? {} : { acceptance: item.acceptance }),
|
|
426
|
+
createdAt: item.createdAt,
|
|
427
|
+
updatedAt: item.updatedAt,
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
function compactGovernanceArtifact(artifact) {
|
|
431
|
+
return {
|
|
432
|
+
id: artifact.id,
|
|
433
|
+
project: artifact.project,
|
|
434
|
+
topicKey: artifact.topicKey,
|
|
435
|
+
phase: artifact.phase,
|
|
436
|
+
observationId: artifact.observationId,
|
|
437
|
+
createdAt: artifact.createdAt,
|
|
438
|
+
updatedAt: artifact.updatedAt,
|
|
439
|
+
contentLength: artifact.content.length,
|
|
440
|
+
contentOmitted: true,
|
|
441
|
+
};
|
|
442
|
+
}
|
|
373
443
|
function cockpitBlockersForPhase(status, readiness) {
|
|
374
444
|
const blockers = [];
|
|
375
445
|
if (!status.present)
|
|
@@ -4,17 +4,20 @@ export const claudeSetupAdapter = {
|
|
|
4
4
|
id: 'claude',
|
|
5
5
|
displayName: 'Claude',
|
|
6
6
|
supportLevel: 'preview-only',
|
|
7
|
-
capabilities: ['mcp-preview', 'manual-guidance'],
|
|
8
|
-
targets: [
|
|
7
|
+
capabilities: ['mcp-preview', 'mcp-install-plan', 'agent-preview', 'doctor', 'manual-guidance'],
|
|
8
|
+
targets: [
|
|
9
|
+
{ kind: 'project-config', label: 'Project .mcp.json', path: '.mcp.json', writableBySetup: false },
|
|
10
|
+
{ kind: 'project-config', label: 'Project Claude agents', path: '.claude/agents/*.md', writableBySetup: false },
|
|
11
|
+
],
|
|
9
12
|
getStatus(context) {
|
|
10
13
|
return {
|
|
11
14
|
providerId: 'claude',
|
|
12
15
|
status: 'preview-only',
|
|
13
|
-
summary: 'Claude setup
|
|
16
|
+
summary: 'Claude setup supports project-local read-only planning for .mcp.json and .claude/agents/*.md; confirmed writes are handled by guarded install flows.',
|
|
14
17
|
evidence: context.databasePath !== undefined
|
|
15
18
|
? ['Claude MCP preview can be generated from the selected database path.']
|
|
16
19
|
: ['Claude MCP preview uses a placeholder until a database path is selected.'],
|
|
17
|
-
guidance: ['
|
|
20
|
+
guidance: ['Review the Claude plan before any write. VGXNESS never writes ~/.claude.json, CLAUDE.md, or .claude/CLAUDE.md and does not execute/install Claude Code.'],
|
|
18
21
|
actions: [
|
|
19
22
|
{
|
|
20
23
|
id: 'claude-manual-guidance',
|
package/docs/architecture.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# vgxness Architecture
|
|
2
2
|
|
|
3
|
+
> **Scope:** this document describes the v1.5.1 architecture as it is actually built. It is the source of truth for how the product works today. Planned work that is not yet shipped lives in [Roadmap](./roadmap.md); historical planning context that no longer reflects reality has been retired. Where this doc disagrees with code, code wins — file a doc-sync task against the relevant module.
|
|
4
|
+
|
|
3
5
|
`vgxness` is a local-first, provider-agnostic, Gentle-AI-like harness for agentic development. Its core architecture separates the product domain from provider-specific tooling so agents, skills, memory, SDD workflows, runs, and traces can work across OpenCode, Claude Code, and future adapters such as Pi.
|
|
4
6
|
|
|
5
|
-
The architectural goal is not only to install better prompts or agent configs. `vgxness`
|
|
7
|
+
The architectural goal is not only to install better prompts or agent configs. `vgxness` combines an ecosystem configurator with a runtime control plane and a native code runtime: configured agents may execute the work, the control plane keeps explicit state for phase readiness, artifacts, runs, approvals, checkpoints, and audit evidence, and the code runtime performs bounded agentic work in the local workspace with explicit permission decisions.
|
|
6
8
|
|
|
7
|
-
The user-facing shape is deliberately
|
|
9
|
+
The user-facing shape is deliberately four-surface: **MCP for agents**, **CLI for scriptable operator control**, **TUI for guided setup and visual local operations**, and **code runtime (`vgxness code`)** for bounded agentic work in the workspace. All four call the same core services instead of reimplementing workflow rules.
|
|
8
10
|
|
|
9
11
|
## Architecture decision summary
|
|
10
12
|
|
|
@@ -14,9 +16,9 @@ The user-facing shape is deliberately three-surface: **MCP for agents**, **CLI f
|
|
|
14
16
|
| Reference model | Similar product surface to Gentle-AI/`gentle-pi`: agent setup, SDD orchestration, memory wiring, skills, profiles, permissions, verification. |
|
|
15
17
|
| Differentiator | Verifiable runtime state engine: SDD phases, artifacts, runs, approvals, checkpoints, and audit trails are queryable product state, not prompt-only convention. |
|
|
16
18
|
| Core workflow | SDD-first canonical state: explore → proposal → spec → design → tasks → apply-progress → verify → archive. |
|
|
17
|
-
| Interfaces | MCP server for AI tools, CLI for automation/power users, TUI for guided install/status/profile/SDD workflows. |
|
|
19
|
+
| Interfaces | MCP server for AI tools, CLI for automation/power users, TUI for guided install/status/profile/SDD workflows, and `vgxness code` runtime for bounded workspace work. |
|
|
18
20
|
| Installation UX | Step-based guided setup with doctor checks, dry-run support, and no manual provider JSON editing on the happy path. |
|
|
19
|
-
| Provider strategy | Provider-agnostic domain model with OpenCode
|
|
21
|
+
| Provider strategy | Provider-agnostic domain model with OpenCode as the primary supported provider; Claude Code is preview/manual only and VGXNESS does not install Claude or write `.claude/` or `CLAUDE.md`. Pi/`gentle-pi` compatibility is a future adapter/reference target. The code runtime speaks to any OpenAI-compatible endpoint through `src/code/providers/openai-compatible-provider-adapter.ts`. |
|
|
20
22
|
| Memory | Project memory plus personal/global memory, backed locally. |
|
|
21
23
|
| Agents | Agents/subagents are registered in a neutral schema, then rendered into provider-specific config. |
|
|
22
24
|
| Skills | Skills are first-class, versioned, attachable to agents/workflows/adapters, and improved through reviewable proposals. |
|
|
@@ -98,7 +100,7 @@ Gentle-AI/`gentle-pi` are strong references for the configurator and agent-behav
|
|
|
98
100
|
| Project | Repo-specific memory, SDD artifacts, run history, adapter config, project agents/skills. | `.vgx/` or project-local SQLite store. |
|
|
99
101
|
| Personal/global | User preferences, reusable skills, cross-project patterns, global agents. | User-level config/data directory. |
|
|
100
102
|
|
|
101
|
-
The exact path format is still open, but the architectural rule is fixed: **project data and personal data must not be collapsed into one scope**.
|
|
103
|
+
The exact path format is still open, but the architectural rule is fixed: **project data and personal data must not be collapsed into one scope**. See [Storage](./storage.md) for schema, migration layout, and lifecycle.
|
|
102
104
|
|
|
103
105
|
## SDD workflow engine
|
|
104
106
|
|
|
@@ -116,18 +118,20 @@ Current phase artifacts use one canonical topic key each:
|
|
|
116
118
|
sdd/{change}/{phase}
|
|
117
119
|
```
|
|
118
120
|
|
|
119
|
-
Readiness is
|
|
121
|
+
Readiness is a combination of prerequisite phase artifacts, explicit human acceptance, and aggregate blockers — artifact presence alone is not enough:
|
|
120
122
|
|
|
121
|
-
| Phase | Required
|
|
122
|
-
|
|
123
|
-
| `explore` | none |
|
|
124
|
-
| `proposal` | `explore` |
|
|
125
|
-
| `spec` | `proposal` |
|
|
126
|
-
| `design` | `proposal`, `spec` |
|
|
127
|
-
| `tasks` | `proposal`, `spec`, `design` |
|
|
128
|
-
| `apply-progress` | `tasks` |
|
|
129
|
-
| `verify` | `apply-progress` |
|
|
130
|
-
| `archive` | `verify` |
|
|
123
|
+
| Phase | Required prerequisites | Acceptance required |
|
|
124
|
+
|---|---|---|
|
|
125
|
+
| `explore` | none | no |
|
|
126
|
+
| `proposal` | `explore` | yes (on `explore`) |
|
|
127
|
+
| `spec` | `proposal` | yes (on `proposal`) |
|
|
128
|
+
| `design` | `proposal`, `spec` | yes (on `proposal`, `spec`) |
|
|
129
|
+
| `tasks` | `proposal`, `spec`, `design` | yes (on `proposal`, `spec`, `design`) |
|
|
130
|
+
| `apply-progress` | `tasks` | yes (on `tasks`) |
|
|
131
|
+
| `verify` | `apply-progress` | yes (on `apply-progress`) |
|
|
132
|
+
| `archive` | `verify` | yes (on `verify`) |
|
|
133
|
+
|
|
134
|
+
`SddWorkflowService.getReady(...)` returns a structured `SddReadiness` with `blockedPrerequisites`, while `getCockpit(...)` aggregates `SddCockpitBlocker`s of kind `missing-topic-key`, `unaccepted-phase`, `legacy-artifact`, or `readiness`. Acceptance is recorded only by a human actor (`acceptedBy.type === 'human'`); the runtime rejects agent or anonymous acceptance.
|
|
131
135
|
|
|
132
136
|
Current service API:
|
|
133
137
|
|
|
@@ -409,7 +413,7 @@ NO silent mutation of active skills. Eso es una línea roja.
|
|
|
409
413
|
|
|
410
414
|
## Provider adapter contract
|
|
411
415
|
|
|
412
|
-
Adapters render registry definitions into provider artifacts without changing the registry model.
|
|
416
|
+
Adapters render registry definitions into provider artifacts without changing the registry model. The full adapter contract, render API, and how to add a new provider live in [Providers](./providers.md); this section is a high-level map.
|
|
413
417
|
|
|
414
418
|
Current contract:
|
|
415
419
|
|
|
@@ -462,15 +466,15 @@ The checked-in OpenCode default config and `seeds/agents/agent-seed-v1.json` def
|
|
|
462
466
|
|
|
463
467
|
## Run lifecycle
|
|
464
468
|
|
|
465
|
-
A run is the core unit of execution.
|
|
466
|
-
|
|
467
|
-
Current terminal lifecycle rules:
|
|
469
|
+
A run is the core unit of execution. Run records are stored locally in SQLite and stay provider-neutral. The lifecycle is complete in v1.5.1:
|
|
468
470
|
|
|
469
471
|
```text
|
|
470
|
-
created →
|
|
472
|
+
created → planned → running → needs-human
|
|
473
|
+
↓
|
|
474
|
+
completed | failed | blocked | cancelled
|
|
471
475
|
```
|
|
472
476
|
|
|
473
|
-
The
|
|
477
|
+
All eight statuses are first-class on `RunStatus` (`src/runs/schema.ts:1`). The control plane exposes lifecycle operations through `vgxness_run_start`, `vgxness_run_checkpoint`, `vgxness_run_finalize`, and the read-only `vgxness_run_resume_inspect` and `vgxness_run_resume_gate` tools. Finalize is safe by default: terminal runs cannot be finalized again, and the final `outcome` must match the terminal `status` (`success`/`partial`/`failure`/`blocked`/`cancelled`).
|
|
474
478
|
|
|
475
479
|
Current run fields:
|
|
476
480
|
|
|
@@ -556,14 +560,13 @@ runService.appendCheckpoint({
|
|
|
556
560
|
});
|
|
557
561
|
```
|
|
558
562
|
|
|
559
|
-
|
|
563
|
+
Open follow-up for run execution lives in [Roadmap](./roadmap.md). The remaining work is:
|
|
564
|
+
|
|
565
|
+
- real provider/tool invocation behind sandboxed executors (the lifecycle and policy recording are stable; the actual executor is still test-only)
|
|
566
|
+
- CLI/MCP orchestration for `resume-after-approval` once a safe executor exists outside tests
|
|
567
|
+
- richer verification evidence summaries that link runs, tasks, and verifications
|
|
560
568
|
|
|
561
|
-
|
|
562
|
-
- real provider/tool invocation behind sandboxed executors
|
|
563
|
-
- CLI or adapter orchestration for resume-after-approval once a safe executor exists outside tests
|
|
564
|
-
- operator UX for retry admission and retry execution, with clear separation between reservation and actual execution
|
|
565
|
-
- sandbox/worktree execution strategies after decision recording is stable
|
|
566
|
-
- richer verification evidence summaries
|
|
569
|
+
What is already shipped: 8-state lifecycle, approval records, reserved attempts, retry policy evaluation with `never`/`after-abandoned`/`after-failure`/`after-failure-or-abandoned`, run insights with debug summary, run snapshot export (`RunSnapshotPackageV1`), and a `runs retry-check --approval <id> [--policy <json>]` operator command.
|
|
567
570
|
|
|
568
571
|
## Trace model
|
|
569
572
|
|
|
@@ -584,9 +587,7 @@ Minimum trace events:
|
|
|
584
587
|
|
|
585
588
|
## Permission model
|
|
586
589
|
|
|
587
|
-
Permissions
|
|
588
|
-
|
|
589
|
-
Minimum categories:
|
|
590
|
+
Permissions are defined in `vgxness` first, then mapped to adapters through the neutral `permissions` field on agents and subagents. The full safety model, including approval flow, redactors, and runtime gates, is in [Safety model](./safety.md). Categories:
|
|
590
591
|
|
|
591
592
|
| Category | Examples |
|
|
592
593
|
|---|---|
|
|
@@ -600,15 +601,9 @@ Minimum categories:
|
|
|
600
601
|
| `provider-tool` | opaque adapter/provider tool calls |
|
|
601
602
|
| `secrets` | environment variables, credentials, tokens |
|
|
602
603
|
|
|
603
|
-
Operations
|
|
604
|
-
|
|
605
|
-
- `allow`
|
|
606
|
-
- `ask`
|
|
607
|
-
- `deny`
|
|
608
|
-
|
|
609
|
-
Default stance for destructive or external operations: **ask or deny**, never implicit allow.
|
|
604
|
+
Operations resolve to `allow`, `ask`, or `deny`. Destructive or external operations default to **ask or deny**, never implicit allow.
|
|
610
605
|
|
|
611
|
-
Current foundation API: `evaluatePermission(request)` in `src/permissions
|
|
606
|
+
Current foundation API: `evaluatePermission(request)` in `src/permissions/policy-evaluator.ts` returns `allow`, `ask`, or `deny` with a reason. Defaults are intentionally conservative:
|
|
612
607
|
|
|
613
608
|
- workspace reads are allowed only when the target path stays inside `workspaceRoot`
|
|
614
609
|
- edits, shell, git, network, memory writes/searches, and provider-specific tools ask by default
|
|
@@ -616,84 +611,31 @@ Current foundation API: `evaluatePermission(request)` in `src/permissions/` retu
|
|
|
616
611
|
- destructive, external, privileged, or ambiguous requests require ask even when an agent override would otherwise allow the category
|
|
617
612
|
- workspace boundary denials cannot be relaxed by agent/subagent overrides
|
|
618
613
|
|
|
619
|
-
|
|
614
|
+
The code runtime layers a second, finer-grained decision on top of the policy evaluator: per-tool definitions declare whether a tool is `read`, `confirm`, or `restricted`; `PolicyApprovalBroker`, `StdioApprovalBroker`, and `ConservativePermissionGateway` (in `src/code/runtime/approval-coordinator.ts`) wire approval prompts to the runtime event stream. See [Code runtime](./code-runtime.md) for the workspace-side contract.
|
|
620
615
|
|
|
621
|
-
##
|
|
616
|
+
## Interface surface (current)
|
|
622
617
|
|
|
623
|
-
|
|
618
|
+
CLI surface groups are documented in [CLI reference](./cli.md). The plural form is canonical — singular shortcuts are not added.
|
|
624
619
|
|
|
625
|
-
|
|
626
|
-
vgxness init
|
|
627
|
-
vgxness memory search|get|save|update
|
|
628
|
-
vgxness agents list|register|get|resolve|render
|
|
629
|
-
vgxness skills list|register|propose|approve-proposal|apply-proposal
|
|
630
|
-
vgxness sdd status|next|ready|save-artifact|accept-artifact|list-artifacts
|
|
631
|
-
vgxness runs list|get|timeline|debug|resume-inspect|resume-gate
|
|
632
|
-
vgxness mcp doctor|install
|
|
633
|
-
vgxness opencode preview
|
|
634
|
-
```
|
|
635
|
-
|
|
636
|
-
Representative MCP tools mirror the same core services for agent use. For the current exact tool names, use `SUPPORTED_VGX_MCP_TOOL_NAMES`:
|
|
637
|
-
|
|
638
|
-
```text
|
|
639
|
-
vgxness_sdd_status
|
|
640
|
-
vgxness_sdd_next
|
|
641
|
-
vgxness_sdd_ready
|
|
642
|
-
vgxness_sdd_save_artifact
|
|
643
|
-
vgxness_sdd_get_artifact
|
|
644
|
-
vgxness_sdd_list_artifacts
|
|
645
|
-
vgxness_memory_search
|
|
646
|
-
vgxness_memory_get
|
|
647
|
-
vgxness_memory_save
|
|
648
|
-
vgxness_memory_update
|
|
649
|
-
vgxness_run_start
|
|
650
|
-
vgxness_run_list
|
|
651
|
-
vgxness_run_get
|
|
652
|
-
vgxness_run_preflight
|
|
653
|
-
vgxness_run_checkpoint
|
|
654
|
-
vgxness_run_finalize
|
|
655
|
-
vgxness_agent_resolve
|
|
656
|
-
vgxness_agent_activate
|
|
657
|
-
vgxness_manager_profile_get
|
|
658
|
-
vgxness_manager_profile_set
|
|
659
|
-
vgxness_skill_payload
|
|
660
|
-
vgxness_opencode_manager_payload
|
|
661
|
-
```
|
|
662
|
-
|
|
663
|
-
The CLI and TUI are human/operator control surfaces. MCP is the agent-facing control surface. Provider integrations are the execution/configuration plane.
|
|
620
|
+
MCP tools mirror the same core services for agent use. The full, current list of 38 tools is in [MCP tools](./mcp.md) and `SUPPORTED_VGX_MCP_TOOL_NAMES` (`src/mcp/schema.ts`); treat that array as the source of truth. The CLI and TUI are human/operator control surfaces. MCP is the agent-facing control surface. Provider integrations and the code runtime sit on the execution plane.
|
|
664
621
|
|
|
665
622
|
## Evaluation strategy
|
|
666
623
|
|
|
667
|
-
Minimum eval/test targets:
|
|
668
|
-
|
|
669
|
-
- Agent resolution selects the expected agent.
|
|
670
|
-
- Skill resolution injects the expected skill.
|
|
671
|
-
- Adapter rendering produces valid provider config.
|
|
672
|
-
- Permission rules block unsafe operations.
|
|
673
|
-
- SDD artifact chains remain complete.
|
|
674
|
-
- Memory upserts preserve revisions.
|
|
675
|
-
- Run resume restores expected state.
|
|
676
|
-
- Skill improvement proposals are versioned and require approval.
|
|
677
|
-
- MCP tools call the same core services as CLI/TUI and return actionable blocked states.
|
|
678
|
-
-
|
|
624
|
+
Minimum eval/test targets (asserted through `node:test` files under `test/`, totaling 95 files as of v1.5.1):
|
|
625
|
+
|
|
626
|
+
- Agent resolution selects the expected agent (`test/agents/agent-resolver.test.ts`).
|
|
627
|
+
- Skill resolution injects the expected skill (`test/skills/`).
|
|
628
|
+
- Adapter rendering produces valid provider config (`test/agents/provider-renderer.test.ts`).
|
|
629
|
+
- Permission rules block unsafe operations (`test/permissions/policy-evaluator.test.ts`).
|
|
630
|
+
- SDD artifact chains remain complete and human acceptance is enforced (`test/sdd/sdd-workflow-service.test.ts`).
|
|
631
|
+
- Memory upserts preserve revisions (`test/memory/`).
|
|
632
|
+
- Run resume restores expected run state and respects retry policies (`test/runs/`).
|
|
633
|
+
- Skill improvement proposals are versioned and require approval (`test/skills/`).
|
|
634
|
+
- MCP tools call the same core services as CLI/TUI and return actionable blocked states (`test/mcp/`).
|
|
635
|
+
- Code runtime behavior across inspect, plan, craft-preview, and craft modes (`test/code/`).
|
|
636
|
+
- OpenCode config rendering and drift detection (`test/mcp/opencode-agent-config-drift.test.ts`).
|
|
679
637
|
- Installation dry-run reports the exact provider config changes before mutation.
|
|
680
638
|
|
|
681
|
-
##
|
|
682
|
-
|
|
683
|
-
The next SDD change should be `harness-runtime-foundation`.
|
|
684
|
-
|
|
685
|
-
Scope:
|
|
686
|
-
|
|
687
|
-
- define schemas for agents, skills, runs, traces, permissions, and adapters
|
|
688
|
-
- add local persistence for these entities where missing
|
|
689
|
-
- add adapter validation/render skeleton
|
|
690
|
-
- add CLI/MCP/TUI interface boundaries for validation, inspection, and guided setup
|
|
691
|
-
- add tests for schema validation, permission decisions, and adapter rendering
|
|
692
|
-
|
|
693
|
-
Out of scope:
|
|
639
|
+
## Future work
|
|
694
640
|
|
|
695
|
-
|
|
696
|
-
- team collaboration
|
|
697
|
-
- web console
|
|
698
|
-
- distributed workers
|
|
699
|
-
- fully autonomous skill mutation
|
|
641
|
+
Planned work that is not yet shipped lives in [Roadmap](./roadmap.md). This document stays focused on the architecture as built; the roadmap is the place to track what is next and what is explicitly deferred.
|
package/docs/cli.md
CHANGED
|
@@ -254,6 +254,45 @@ The command prints a deterministic JSON envelope with `flow`, `confidence`, `rea
|
|
|
254
254
|
|
|
255
255
|
Safety boundary: this is a preview only. It does **not** call providers, edit files, write provider config, create runs, run installers, install global memory, or create `openspec/`. Preview actions are labels/manual commands for review, not executed steps.
|
|
256
256
|
|
|
257
|
+
## Code runtime CLI (`vgxness code`)
|
|
258
|
+
|
|
259
|
+
`vgxness code` is the native workspace runtime for bounded agentic work. It is not a wrapper around OpenCode or any provider; provider adapters translate VGXNESS-native requests only. See [Code runtime](./code-runtime.md) for the full contract; this section lists the CLI surface.
|
|
260
|
+
|
|
261
|
+
Modes (read-only by default unless `--approval-channel` and `--approval-policy` are passed):
|
|
262
|
+
|
|
263
|
+
| Mode | Purpose | Mutations |
|
|
264
|
+
|---|---|---|
|
|
265
|
+
| `inspect` | Read-only investigation of the workspace. | None. |
|
|
266
|
+
| `plan` | Read-only implementation planning. | None. |
|
|
267
|
+
| `craft-preview` | Show the diff that would be applied. | None. |
|
|
268
|
+
| `craft` | Approval-gated, bounded edit-capable work. | Edits, shell, network, git, SDD persistence all routed through explicit policy decisions. |
|
|
269
|
+
|
|
270
|
+
Common flags across modes:
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
vgxness code inspect "<question>" \
|
|
274
|
+
--provider openai-compatible \ # or "fake" for offline testing
|
|
275
|
+
--model <model-id> \
|
|
276
|
+
--stream \ # emit JSONL runtime events as they happen
|
|
277
|
+
--json \ # final response as JSON
|
|
278
|
+
--max-source-bytes <bytes> \ # bound on sources loaded into prompt
|
|
279
|
+
--approval-policy ask|allow|deny \
|
|
280
|
+
--approval-channel stdio|auto \
|
|
281
|
+
--verification none|suggest|run|repair \
|
|
282
|
+
--transcript off|summary|full \
|
|
283
|
+
--memory off|ask|auto
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
SDD-aware mode is exposed through `vgxness code sdd <change> <phase>`; pass `--save-artifact` only when persistence is intended, and pass `--change-id`/`--phase` to scope work. Read-only phases stay artifact-oriented; `apply-progress` may expose edit and shell tools; `verify` may expose verification shell tools.
|
|
287
|
+
|
|
288
|
+
Useful events-only output for piping into the OpenTUI shell or your own tooling:
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
vgxness code inspect "Summarize the current architecture" --events-jsonl
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Safety boundary: `inspect`, `plan`, and `craft-preview` never mutate. `craft` may only mutate through the permission-aware executors and the explicit approval channel; it never writes outside the workspace, never pushes to remote, and never edits `openspec/`. Secret-like values are redacted from prompts, transcripts, checkpoints, and memory saves. See [Safety model](./safety.md).
|
|
295
|
+
|
|
257
296
|
## Workflow CLI
|
|
258
297
|
|
|
259
298
|
Use workflow commands when you want an explicit operator-controlled path from intent classification to a recorded run and, optionally, a guarded execution request. Supported workflows are `explore`, `quickfix`, `plan`, `build`, `debug`, and `sdd`:
|
|
@@ -872,3 +911,17 @@ Existing project-local stores remain compatible; opt in explicitly when needed:
|
|
|
872
911
|
```bash
|
|
873
912
|
bun run cli:bun -- memory search --project vgxness --db .vgx/memory.sqlite
|
|
874
913
|
```
|
|
914
|
+
|
|
915
|
+
For more on schema, scopes, and lifecycle, see [Storage](./storage.md).
|
|
916
|
+
|
|
917
|
+
## See also
|
|
918
|
+
|
|
919
|
+
- [Architecture](./architecture.md) — current-state architecture and core domain model.
|
|
920
|
+
- [Code runtime](./code-runtime.md) — `vgxness code` modes, tools, providers, and approval flow.
|
|
921
|
+
- [MCP tools](./mcp.md) — full reference for the 38 MCP tools exposed to agents.
|
|
922
|
+
- [Safety model](./safety.md) — permission categories, approval flow, redactors, and runtime gates.
|
|
923
|
+
- [Storage](./storage.md) — SQLite schema, scopes, and lifecycle.
|
|
924
|
+
- [Providers](./providers.md) — adapter contract and how to add a new provider.
|
|
925
|
+
- [Roadmap](./roadmap.md) — planned work not yet shipped.
|
|
926
|
+
- [Contributing](./contributing.md) — repository layout, verification, and style.
|
|
927
|
+
- [Glossary](./glossary.md) — terminology used across the docs and the codebase.
|