@vibecompass/vibecompass 0.4.0 → 0.5.0
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 +32 -5
- package/package.json +1 -1
- package/src/docs-review.js +51 -4
- package/src/generators/agent-files/index.js +2 -11
- package/src/generators/agent-files/template.js +33 -34
- package/src/project-memory.js +3 -1
- package/src/refresh-workflow.js +3 -0
- package/src/scaffold.js +45 -86
- package/src/setup.js +2 -11
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ Shipped today:
|
|
|
20
20
|
- interactive guided init for placement, workflow bootstrap, and first-session setup
|
|
21
21
|
- lightweight starter architecture/session memory plus example-only decision guidance
|
|
22
22
|
- generated `context.md` plus opt-in workflow guide files
|
|
23
|
-
- opt-in starter `CLAUDE.md` / `AGENTS.md` templates that are created
|
|
23
|
+
- opt-in starter `CLAUDE.md` / `AGENTS.md` templates that are created only when missing, with VibeCompass-managed regions for future refreshes
|
|
24
24
|
- `vibecompass start-session` / `vibecompass close-session` for lane-aware local builder workflow
|
|
25
25
|
- `vibecompass list-sessions` / `vibecompass switch-session` for multiple active session lanes
|
|
26
26
|
- `vibecompass end-session` as a discoverable alias for `close-session`
|
|
@@ -31,6 +31,7 @@ Shipped today:
|
|
|
31
31
|
- `vibecompass docs-review --submit-hosted` — submit the review request to the hosted app and poll for proposal/artifact output
|
|
32
32
|
- `vibecompass docs-review --run-local --provider anthropic` — local provider adapter that saves review output locally
|
|
33
33
|
- `vibecompass docs-review --apply-output` — apply accepted architecture-doc blocks into canonical `architecture/` docs
|
|
34
|
+
- strict docs-review output validation for architecture-doc fences, duplicate paths, and required frontmatter
|
|
34
35
|
- `vibecompass docs-review --complete` — mark the review accepted after the docs land
|
|
35
36
|
- hosted sync commands: `push`, `pull-preview`, `pull-export`, and `apply-export`
|
|
36
37
|
- canonical file scanning and validation
|
|
@@ -144,6 +145,11 @@ AGENTS.md # at the tooling root, only if missing and --with-agents is
|
|
|
144
145
|
|
|
145
146
|
`context.md` is a derived package-owned file. Re-running `init --force --with-workflow`
|
|
146
147
|
regenerates it; do not treat it as a hand-edited source document.
|
|
148
|
+
Starter `CLAUDE.md` / `AGENTS.md` files include VibeCompass managed markers
|
|
149
|
+
when the package creates them, so later `sync-agents` and session lifecycle
|
|
150
|
+
commands can refresh the generated region without warning. If those files
|
|
151
|
+
already exist without markers, init leaves them untouched unless you explicitly
|
|
152
|
+
adopt them.
|
|
147
153
|
|
|
148
154
|
Check an initialized root without writing files:
|
|
149
155
|
|
|
@@ -283,7 +289,7 @@ Generate agent-instruction files from project memory:
|
|
|
283
289
|
npx -y @vibecompass/vibecompass sync-agents --root .compass
|
|
284
290
|
```
|
|
285
291
|
|
|
286
|
-
`sync-agents` writes
|
|
292
|
+
`sync-agents` writes compact VibeCompass bootloader regions:
|
|
287
293
|
|
|
288
294
|
```md
|
|
289
295
|
<!-- vibecompass:start - managed by VibeCompass, do not edit -->
|
|
@@ -291,13 +297,23 @@ npx -y @vibecompass/vibecompass sync-agents --root .compass
|
|
|
291
297
|
<!-- vibecompass:end -->
|
|
292
298
|
```
|
|
293
299
|
|
|
294
|
-
Content outside those markers is preserved.
|
|
295
|
-
|
|
300
|
+
Content outside those markers is preserved. Package-created starter files
|
|
301
|
+
include managed markers from the beginning. Existing user files without markers
|
|
302
|
+
are reported as warnings and left untouched unless you explicitly adopt them:
|
|
296
303
|
|
|
297
304
|
```bash
|
|
298
305
|
npx -y @vibecompass/vibecompass sync-agents --root .compass --adopt-existing
|
|
299
306
|
```
|
|
300
307
|
|
|
308
|
+
The managed block intentionally stays short: project-memory root, read order,
|
|
309
|
+
prompt-command routing, and hard safety rules. Detailed workflow lives in
|
|
310
|
+
`context.md` and generated files under `workflows/`, so `CLAUDE.md`, `AGENTS.md`,
|
|
311
|
+
`.cursorrules`, and Copilot instructions do not duplicate long protocol text.
|
|
312
|
+
`CLAUDE.md` starters also keep the mutable `Current session` block above the
|
|
313
|
+
managed region because session lifecycle commands update it. `AGENTS.md`
|
|
314
|
+
starters are intentionally just the managed bootloader; add Codex/team notes
|
|
315
|
+
before or after the marker block if needed, and `sync-agents` will preserve them.
|
|
316
|
+
|
|
301
317
|
Adoption appends a managed VibeCompass block to the end of existing unmarked
|
|
302
318
|
agent files, preserves everything outside the markers, and reports possible
|
|
303
319
|
workflow-overlap lines before you rely on the result. Guided init may offer the
|
|
@@ -665,7 +681,18 @@ Accepted review content.
|
|
|
665
681
|
```
|
|
666
682
|
````
|
|
667
683
|
|
|
668
|
-
|
|
684
|
+
The fence opening is strict: it must be exactly
|
|
685
|
+
`vibecompass-architecture-doc path=<architecture/*.md>` with one `path`
|
|
686
|
+
attribute and no extra attributes. Malformed architecture-doc fences report a
|
|
687
|
+
targeted error instead of being treated as "no output found".
|
|
688
|
+
|
|
689
|
+
Only `architecture/*.md` paths are writable through this apply step. Component
|
|
690
|
+
docs require non-empty `domain`, `feature`, `component`, and `status`
|
|
691
|
+
frontmatter. The project overview file,
|
|
692
|
+
`architecture/overview/project-shape.md`, may use status-only frontmatter so it
|
|
693
|
+
matches hosted docs-review proposal behavior. If one accepted output contains
|
|
694
|
+
multiple blocks for the same architecture path, local apply fails rather than
|
|
695
|
+
silently overwriting earlier accepted content.
|
|
669
696
|
|
|
670
697
|
`vibecompass docs-review --complete` updates the marker in
|
|
671
698
|
`state/docs-review.json` to `status: "completed"` once the docs have
|
package/package.json
CHANGED
package/src/docs-review.js
CHANGED
|
@@ -59,8 +59,10 @@ export async function preflightDocsReview(options = {}, environment = {}) {
|
|
|
59
59
|
const localProvider = resolveLocalProvider(options);
|
|
60
60
|
const runtime = resolveDocsReviewRuntime(project, {
|
|
61
61
|
env,
|
|
62
|
+
guided: Boolean(options.guided),
|
|
62
63
|
localProvider,
|
|
63
64
|
runLocal: shouldRunLocal(options),
|
|
65
|
+
anthropicEnvVar: options.anthropicEnvVar ?? 'ANTHROPIC_API_KEY',
|
|
64
66
|
});
|
|
65
67
|
const reviewPrompt = renderReviewPrompt({
|
|
66
68
|
project,
|
|
@@ -180,14 +182,19 @@ async function applyDocsReviewOutput(options) {
|
|
|
180
182
|
const blocks = parseArchitectureDocBlocks(source);
|
|
181
183
|
|
|
182
184
|
if (blocks.length === 0) {
|
|
185
|
+
const malformedFenceCount = countMalformedArchitectureDocFences(source);
|
|
186
|
+
if (malformedFenceCount > 0) {
|
|
187
|
+
throw new Error(
|
|
188
|
+
`Malformed architecture doc fence found in ${outputPath}. Expected fence openings like \`\`\`vibecompass-architecture-doc path=architecture/domain/feature/component.md\` with exactly one path attribute and no extra attributes.`,
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
|
|
183
192
|
throw new Error(
|
|
184
193
|
`No accepted architecture doc blocks found in ${outputPath}. Expected fenced blocks like \`\`\`vibecompass-architecture-doc path=architecture/domain/feature/component.md\`.`,
|
|
185
194
|
);
|
|
186
195
|
}
|
|
187
196
|
|
|
188
|
-
|
|
189
|
-
validateArchitectureDocBlock(block);
|
|
190
|
-
}
|
|
197
|
+
validateArchitectureDocBlocks(blocks);
|
|
191
198
|
|
|
192
199
|
const applied = [];
|
|
193
200
|
for (const block of blocks) {
|
|
@@ -357,6 +364,13 @@ function validateDocsReviewMode(options) {
|
|
|
357
364
|
}
|
|
358
365
|
|
|
359
366
|
async function promptForReviewConfig(options, environment) {
|
|
367
|
+
if (options.llm && options.model) {
|
|
368
|
+
return normalizeReviewConfig({
|
|
369
|
+
llm: options.llm,
|
|
370
|
+
model: options.model,
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
|
|
360
374
|
const prompter = createPrompter(environment.io, environment.runtime);
|
|
361
375
|
try {
|
|
362
376
|
if (!options.llm) {
|
|
@@ -485,6 +499,10 @@ function resolveDocsReviewRuntime(project, options) {
|
|
|
485
499
|
};
|
|
486
500
|
}
|
|
487
501
|
|
|
502
|
+
if (options.guided) {
|
|
503
|
+
return { provider: 'external' };
|
|
504
|
+
}
|
|
505
|
+
|
|
488
506
|
throw new Error(
|
|
489
507
|
`docs-review for local-primary projects requires a hosted sync binding or ${options.anthropicEnvVar}.`,
|
|
490
508
|
);
|
|
@@ -601,6 +619,32 @@ function parseArchitectureDocBlocks(source) {
|
|
|
601
619
|
return blocks;
|
|
602
620
|
}
|
|
603
621
|
|
|
622
|
+
function countMalformedArchitectureDocFences(source) {
|
|
623
|
+
const fencePattern = /^```vibecompass-architecture-doc\b.*$/gm;
|
|
624
|
+
const acceptedOpeningPattern = /^```vibecompass-architecture-doc\s+path=[^\s`]+\s*$/;
|
|
625
|
+
let count = 0;
|
|
626
|
+
let match;
|
|
627
|
+
|
|
628
|
+
while ((match = fencePattern.exec(source)) !== null) {
|
|
629
|
+
if (!acceptedOpeningPattern.test(match[0])) {
|
|
630
|
+
count += 1;
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
return count;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
function validateArchitectureDocBlocks(blocks) {
|
|
638
|
+
const seenPaths = new Set();
|
|
639
|
+
for (const block of blocks) {
|
|
640
|
+
if (seenPaths.has(block.path)) {
|
|
641
|
+
throw new Error(`Accepted docs-review output contains duplicate architecture doc path: ${block.path}`);
|
|
642
|
+
}
|
|
643
|
+
seenPaths.add(block.path);
|
|
644
|
+
validateArchitectureDocBlock(block);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
|
|
604
648
|
function normalizeBlockPath(value) {
|
|
605
649
|
return String(value ?? '').trim().replaceAll('\\', '/');
|
|
606
650
|
}
|
|
@@ -625,7 +669,10 @@ function validateArchitectureDocBlock(block) {
|
|
|
625
669
|
throw new Error(`Accepted architecture doc ${block.path} must include frontmatter.`);
|
|
626
670
|
}
|
|
627
671
|
|
|
628
|
-
|
|
672
|
+
const requiredFields = block.path === 'architecture/overview/project-shape.md'
|
|
673
|
+
? ['status']
|
|
674
|
+
: ['domain', 'feature', 'component', 'status'];
|
|
675
|
+
for (const field of requiredFields) {
|
|
629
676
|
if (typeof frontmatter.data[field] !== 'string' || frontmatter.data[field].trim() === '') {
|
|
630
677
|
throw new Error(`Accepted architecture doc ${block.path} requires non-empty frontmatter field "${field}".`);
|
|
631
678
|
}
|
|
@@ -8,6 +8,7 @@ import { claudeMdFormat } from './claude-md.js';
|
|
|
8
8
|
import { agentsMdFormat } from './agents-md.js';
|
|
9
9
|
import { cursorRulesFormat } from './cursor-rules.js';
|
|
10
10
|
import { copilotInstructionsFormat } from './copilot-instructions.js';
|
|
11
|
+
import { getWorkflowConflictScanPatterns } from '../../workflows/registry.js';
|
|
11
12
|
|
|
12
13
|
const FORMATS = [
|
|
13
14
|
claudeMdFormat,
|
|
@@ -17,17 +18,7 @@ const FORMATS = [
|
|
|
17
18
|
];
|
|
18
19
|
|
|
19
20
|
const FORMAT_MAP = new Map(FORMATS.map((format) => [format.name, format]));
|
|
20
|
-
const CONFLICT_SCAN_PATTERNS =
|
|
21
|
-
'session',
|
|
22
|
-
'handoff',
|
|
23
|
-
'decisions',
|
|
24
|
-
'wip.md',
|
|
25
|
-
'review handoff',
|
|
26
|
-
'close-session',
|
|
27
|
-
'address review',
|
|
28
|
-
'builder',
|
|
29
|
-
'reviewer',
|
|
30
|
-
];
|
|
21
|
+
const CONFLICT_SCAN_PATTERNS = getWorkflowConflictScanPatterns();
|
|
31
22
|
|
|
32
23
|
export async function syncAgentInstructionFiles(options = {}) {
|
|
33
24
|
const cwd = options.cwd ? path.resolve(options.cwd) : process.cwd();
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { renderPromptCommandLines } from '../../workflows/registry.js';
|
|
2
|
+
|
|
1
3
|
export function buildAgentContext(readModel) {
|
|
2
4
|
return {
|
|
3
5
|
projectName: readModel.project.name ?? 'Unnamed project',
|
|
@@ -16,47 +18,40 @@ export function renderSharedInstructionBody(context, options = {}) {
|
|
|
16
18
|
const intro =
|
|
17
19
|
options.intro ??
|
|
18
20
|
'Use VibeCompass project memory as the source of truth before making code changes.';
|
|
21
|
+
const contextPath = `${context.rootDir}/context.md`;
|
|
19
22
|
|
|
20
23
|
return [
|
|
21
24
|
`# ${heading}`,
|
|
22
25
|
'',
|
|
23
26
|
intro,
|
|
24
27
|
'',
|
|
25
|
-
`Read \`${
|
|
28
|
+
`This managed block is a compact bootloader. Read \`${contextPath}\` for the full VibeCompass workflow protocol; workflow-specific details live under \`${context.rootDir}/workflows/\`.`,
|
|
26
29
|
'',
|
|
27
30
|
'Existing project-specific coding, style, framework, and safety instructions outside this managed block remain authoritative. This block owns only VibeCompass project-memory workflow: sessions, handoffs, decisions, docs-review, and close-out.',
|
|
28
31
|
'',
|
|
29
|
-
'##
|
|
32
|
+
'## Project Snapshot',
|
|
30
33
|
`- Project memory root: \`${context.rootDir}\``,
|
|
31
|
-
|
|
32
|
-
'- Read the latest finalized session note under `sessions/` before resuming work.',
|
|
33
|
-
'- Read `sessions/active/index.yaml` when it exists, then read the selected lane under `sessions/active/<lane-id>/`.',
|
|
34
|
-
'- Read the selected lane `wip.md` and `handoff.md` when they exist; they are the active builder/reviewer scratch files.',
|
|
35
|
-
'- Read relevant `architecture/` and `decisions/` files before changing implementation.',
|
|
34
|
+
...renderProjectSnapshot(context),
|
|
36
35
|
'',
|
|
37
|
-
'##
|
|
38
|
-
|
|
36
|
+
'## Read Order',
|
|
37
|
+
`1. Read \`${contextPath}\`.`,
|
|
38
|
+
`2. Read the latest finalized session note under \`${context.rootDir}/sessions/\`.`,
|
|
39
|
+
`3. If present, read \`${context.rootDir}/sessions/active/index.yaml\`, then the selected lane's \`wip.md\` and \`handoff.md\`.`,
|
|
40
|
+
`4. Read relevant \`${context.rootDir}/architecture/\` and \`${context.rootDir}/decisions/\` docs before editing implementation.`,
|
|
39
41
|
'',
|
|
40
|
-
'##
|
|
41
|
-
|
|
42
|
-
'-
|
|
43
|
-
'- Use `vibecompass start-session --id <lane-id>` to open a named lane for every active feature or workstream.',
|
|
44
|
-
'- Use `vibecompass list-sessions` and `vibecompass switch-session <lane-id>` to inspect or change the current lane.',
|
|
45
|
-
'- Treat `sessions/active/index.yaml` as the current lane source of truth; tool-specific Current session blocks are continuity summaries.',
|
|
46
|
-
'- Use optional planning mode for risky or ambiguous work: read the same context, propose scope, and record the agreed plan in the selected lane `wip.md` before implementation.',
|
|
47
|
-
'- Use `review handoff` to ask a reviewer to inspect the active handoff.',
|
|
48
|
-
'- Use `address review` to process reviewer feedback from the selected lane `wip.md` and `handoff.md`.',
|
|
49
|
-
'- End the active builder session with the `close session` prompt, which runs close-out and ends with `vibecompass close-session --session <lane-id>`; `end session` and `vibecompass end-session` are accepted aliases.',
|
|
50
|
-
'- If stale scratch files block `start-session`, read them first, then close, recover, move, or delete them intentionally before retrying.',
|
|
51
|
-
'- Keep decisions append-only in `decisions/`. Session notes may reference decisions, but decisions are the durable source of truth.',
|
|
52
|
-
'- Treat generated agent files as views. Update canonical VibeCompass project memory instead of editing managed regions.',
|
|
42
|
+
'## Prompt Commands',
|
|
43
|
+
...renderPromptCommandLines({ rootRelativePath: context.rootDir }),
|
|
44
|
+
'- The prompt commands above are agent behaviors. The `vibecompass` CLI commands remain the filesystem mechanics behind them.',
|
|
53
45
|
'',
|
|
54
|
-
'##
|
|
55
|
-
|
|
46
|
+
'## Hard Rules',
|
|
47
|
+
'- Treat `sessions/active/index.yaml` as the current lane source of truth; tool-specific Current session blocks are continuity summaries.',
|
|
48
|
+
'- Keep the selected lane `wip.md` and `handoff.md` current during active builder/reviewer work.',
|
|
49
|
+
'- Keep decisions append-only in `decisions/`; append accepted architectural decisions before implementing them.',
|
|
50
|
+
'- Do not edit this managed block directly. Update canonical VibeCompass memory, then rerun package commands such as `vibecompass sync-agents`.',
|
|
56
51
|
].join('\n');
|
|
57
52
|
}
|
|
58
53
|
|
|
59
|
-
function
|
|
54
|
+
function renderProjectSnapshot(context) {
|
|
60
55
|
const lines = [];
|
|
61
56
|
|
|
62
57
|
if (context.description) {
|
|
@@ -71,18 +66,22 @@ function renderProjectShape(context) {
|
|
|
71
66
|
lines.push(`- Repo \`${repo.id}\`: ${repo.remote}`);
|
|
72
67
|
}
|
|
73
68
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
lines.push(`-
|
|
69
|
+
const domainCount = context.domains.length;
|
|
70
|
+
if (domainCount > 0) {
|
|
71
|
+
lines.push(`- Architecture domains recorded: ${domainCount}`);
|
|
77
72
|
}
|
|
78
73
|
|
|
79
|
-
|
|
80
|
-
}
|
|
74
|
+
if (context.recentDecisions.length > 0) {
|
|
75
|
+
lines.push(`- Latest decision: ${renderDecisionLine(context.recentDecisions[0])}`);
|
|
76
|
+
}
|
|
81
77
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
return ['- No decisions recorded yet.'];
|
|
78
|
+
if (context.recentSessions.length > 0) {
|
|
79
|
+
lines.push(`- Latest session: ${context.recentSessions[0].title ?? context.recentSessions[0].path}`);
|
|
85
80
|
}
|
|
86
81
|
|
|
87
|
-
return
|
|
82
|
+
return lines.length > 0 ? lines : ['- No project details recorded yet.'];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function renderDecisionLine(decision) {
|
|
86
|
+
return `D-${String(decision.decision_id).padStart(3, '0')} — ${decision.title}`;
|
|
88
87
|
}
|
package/src/project-memory.js
CHANGED
|
@@ -364,7 +364,9 @@ function parseArchitectureDocument(options) {
|
|
|
364
364
|
}
|
|
365
365
|
|
|
366
366
|
const data = frontmatter.data;
|
|
367
|
-
const requiredFields =
|
|
367
|
+
const requiredFields = options.relativePath === 'architecture/overview/project-shape.md'
|
|
368
|
+
? ['status']
|
|
369
|
+
: ['domain', 'feature', 'component', 'status'];
|
|
368
370
|
|
|
369
371
|
for (const field of requiredFields) {
|
|
370
372
|
if (typeof data[field] !== 'string' || data[field].trim() === '') {
|
package/src/refresh-workflow.js
CHANGED
|
@@ -161,6 +161,9 @@ function isGeneratedWorkflowGuide(kind, content) {
|
|
|
161
161
|
if (kind === 'sessions-guide') {
|
|
162
162
|
return content.includes('Those scratch files are session-scoped working artifacts, not finalized history.');
|
|
163
163
|
}
|
|
164
|
+
if (kind === 'workflow-docs-review') {
|
|
165
|
+
return content.includes('Generated by VibeCompass. This file is a package-owned workflow guide');
|
|
166
|
+
}
|
|
164
167
|
|
|
165
168
|
return false;
|
|
166
169
|
}
|
package/src/scaffold.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { access, mkdir, readdir, writeFile } from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { resolveWorkflowSettings } from './workflow.js';
|
|
4
|
+
import { getGeneratedWorkflowFiles, renderPromptCommandLines } from './workflows/registry.js';
|
|
5
|
+
import { renderManagedBlock } from './generators/agent-files/markers.js';
|
|
6
|
+
import { renderSharedInstructionBody } from './generators/agent-files/template.js';
|
|
4
7
|
|
|
5
8
|
export async function scaffoldInitFiles(options) {
|
|
6
9
|
const createdFiles = [];
|
|
@@ -59,7 +62,7 @@ export async function scaffoldInitFiles(options) {
|
|
|
59
62
|
await writeFile(contextFilePath, workflowScaffold.context.content, 'utf8');
|
|
60
63
|
createdFiles.push(contextFilePath);
|
|
61
64
|
|
|
62
|
-
for (const file of workflowScaffold.guides) {
|
|
65
|
+
for (const file of [...workflowScaffold.guides, ...workflowScaffold.workflowFiles]) {
|
|
63
66
|
const outcome = await writeIfMissing(file.path, file.content);
|
|
64
67
|
if (outcome.created) {
|
|
65
68
|
createdFiles.push(file.path);
|
|
@@ -124,12 +127,20 @@ export function buildWorkflowScaffoldFiles(options) {
|
|
|
124
127
|
content: generateSessionsGuide(options.projectConfig),
|
|
125
128
|
},
|
|
126
129
|
];
|
|
130
|
+
const workflowFiles = getGeneratedWorkflowFiles({
|
|
131
|
+
rootRelativePath: options.rootRelativePath,
|
|
132
|
+
}).map((file) => ({
|
|
133
|
+
kind: file.kind,
|
|
134
|
+
path: path.join(options.rootDir, file.relativePath),
|
|
135
|
+
content: file.content,
|
|
136
|
+
}));
|
|
127
137
|
|
|
128
138
|
return {
|
|
129
139
|
contextFilePath,
|
|
130
140
|
context,
|
|
131
141
|
guides,
|
|
132
|
-
|
|
142
|
+
workflowFiles,
|
|
143
|
+
files: [context, ...guides, ...workflowFiles],
|
|
133
144
|
};
|
|
134
145
|
}
|
|
135
146
|
|
|
@@ -193,6 +204,7 @@ function generateContextMarkdown(options) {
|
|
|
193
204
|
const projectName = options.projectConfig.name;
|
|
194
205
|
const rootRelativePath = options.rootRelativePath;
|
|
195
206
|
const workflow = resolveWorkflowSettings(options.projectConfig);
|
|
207
|
+
const promptCommands = renderPromptCommandLines({ rootRelativePath }).join('\n');
|
|
196
208
|
const repos = options.projectConfig.repos
|
|
197
209
|
.map((repo) => `- \`${repo.id}\` → ${repo.remote}`)
|
|
198
210
|
.join('\n');
|
|
@@ -233,12 +245,7 @@ ${repos}
|
|
|
233
245
|
| "join as reviewer" | Reviewer | No — reviews the builder's work, appends findings, and updates handoff guidance |
|
|
234
246
|
|
|
235
247
|
## Session prompt commands
|
|
236
|
-
|
|
237
|
-
- \`join as reviewer\` — reviewer role trigger
|
|
238
|
-
- \`planning mode\` — optional prompt-level mode for scoping work before implementation
|
|
239
|
-
- \`review handoff\` — reviewer reads the selected lane's \`wip.md\`, \`handoff.md\`, latest finalized note, and relevant diffs before appending findings
|
|
240
|
-
- \`address review\` — builder reads reviewer feedback in the selected lane's \`wip.md\` / \`handoff.md\`, responds inline, applies accepted changes, and refreshes the builder handoff
|
|
241
|
-
- \`close session\` — builder runs the close-out checklist and ends with \`vibecompass close-session --session <lane-id>\`; \`end session\` is accepted as a synonym
|
|
248
|
+
${promptCommands}
|
|
242
249
|
|
|
243
250
|
These are prompt commands for agent behavior, not \`vibecompass\` CLI subcommands.
|
|
244
251
|
Reviewer handback is explicit: the reviewer ends the pass by updating the selected lane's \`wip.md\` + \`handoff.md\` and then stopping. The \`close session\` prompt runs builder close-out and ends with \`vibecompass close-session --session <lane-id>\`, which follows the workflow defaults recorded in \`${rootRelativePath}/project.yaml\`.
|
|
@@ -250,7 +257,7 @@ ${renderWorkflowDefaults(workflow)}
|
|
|
250
257
|
## Documentation coverage
|
|
251
258
|
- The architecture, decision, and session files created by init are an initial scaffold, not a comprehensive codebase review.
|
|
252
259
|
- Before risky implementation work, inspect the relevant code and update the affected architecture docs.
|
|
253
|
-
-
|
|
260
|
+
- Use the \`docs review\` prompt command when you want the current AI session to run a comprehensive documentation review. It may run \`vibecompass docs-review --guided\` as package mechanics to record marker state and print the canonical review contract.
|
|
254
261
|
|
|
255
262
|
## Session startup
|
|
256
263
|
1. Read \`${rootRelativePath}/project.yaml\`.
|
|
@@ -387,7 +394,7 @@ Not yet documented:
|
|
|
387
394
|
Before changing any undocumented area, inspect the relevant code and update or add architecture docs.
|
|
388
395
|
|
|
389
396
|
## Next steps
|
|
390
|
-
-
|
|
397
|
+
- Use the \`docs review\` prompt command for a comprehensive documentation review.
|
|
391
398
|
- Replace this placeholder with domain/feature/component docs as the project map becomes evidence-backed.
|
|
392
399
|
- Keep architecture docs aligned with implementation changes during each builder session.
|
|
393
400
|
|
|
@@ -445,7 +452,7 @@ Initialized VibeCompass project memory for ${projectConfig.name}.
|
|
|
445
452
|
${repoLines}
|
|
446
453
|
|
|
447
454
|
## Next session should start with
|
|
448
|
-
1.
|
|
455
|
+
1. Use the \`docs review\` prompt command if you want a comprehensive documentation review.
|
|
449
456
|
2. Inspect relevant code before making implementation changes in areas not covered by architecture docs.
|
|
450
457
|
3. Replace starter placeholders with evidence-backed domain/feature/component docs.
|
|
451
458
|
`;
|
|
@@ -531,33 +538,21 @@ Those scratch files are session-scoped working artifacts, not finalized history.
|
|
|
531
538
|
}
|
|
532
539
|
|
|
533
540
|
function generateClaudeTemplate(options) {
|
|
534
|
-
|
|
541
|
+
return [
|
|
542
|
+
generateClaudeSessionHeader(options),
|
|
543
|
+
renderManagedBlock(renderSharedInstructionBody(buildScaffoldAgentContext(options), {
|
|
544
|
+
heading: `${options.projectConfig.name} Claude Instructions`,
|
|
545
|
+
intro:
|
|
546
|
+
'Claude should use VibeCompass project memory as the source of truth before planning, editing, or reviewing code.',
|
|
547
|
+
})),
|
|
548
|
+
].join('\n');
|
|
549
|
+
}
|
|
535
550
|
|
|
551
|
+
function generateClaudeSessionHeader(options) {
|
|
536
552
|
return `# ${options.projectConfig.name} Workspace
|
|
537
553
|
|
|
538
554
|
Read \`${options.contextRelativeToToolingRoot}\` before doing substantive work.
|
|
539
555
|
|
|
540
|
-
## Session roles
|
|
541
|
-
|
|
542
|
-
| Entry trigger | Role | Owns session lifecycle? |
|
|
543
|
-
|---|---|---|
|
|
544
|
-
| "start session" | Builder | Yes |
|
|
545
|
-
| "join as reviewer" | Reviewer | No |
|
|
546
|
-
| "planning mode" | Planner | No — scopes work inside the selected active lane before implementation |
|
|
547
|
-
|
|
548
|
-
## Prompt commands
|
|
549
|
-
|
|
550
|
-
- \`start session\` — builder role trigger
|
|
551
|
-
- \`join as reviewer\` — reviewer role trigger
|
|
552
|
-
- \`planning mode\` — optional prompt-level mode for scoping risky or ambiguous work before implementation
|
|
553
|
-
- \`review handoff\` — reviewer reads the selected lane's \`wip.md\`, \`handoff.md\`, latest finalized note, and relevant diffs before appending findings
|
|
554
|
-
- \`address review\` — builder reads reviewer feedback in the selected lane's \`wip.md\` / \`handoff.md\`, responds inline, applies accepted changes, and refreshes the builder handoff
|
|
555
|
-
- \`close session\` — builder runs the close-out checklist and ends with \`vibecompass close-session --session <lane-id>\`; \`end session\` is accepted as a synonym
|
|
556
|
-
|
|
557
|
-
These are prompt commands for agent behavior, not \`vibecompass\` CLI subcommands.
|
|
558
|
-
Reviewer handback is explicit: the reviewer ends the pass by updating the selected lane's \`wip.md\` + \`handoff.md\` and then stopping. The \`close session\` prompt runs builder close-out and ends with \`vibecompass close-session --session <lane-id>\`, which follows the workflow defaults recorded in \`${options.rootRelativePath}/project.yaml\`.
|
|
559
|
-
\`vibecompass end-session\` is accepted as an alias for \`vibecompass close-session\`; \`close-session\` remains the canonical command name.
|
|
560
|
-
|
|
561
556
|
## Current session
|
|
562
557
|
|
|
563
558
|
**Update this block at the start and end of every session.**
|
|
@@ -569,64 +564,28 @@ Last thing completed: Project memory bootstrap completed.
|
|
|
569
564
|
Blockers: None recorded.
|
|
570
565
|
Next session should: Read \`${options.contextRelativeToToolingRoot}\`, then open the first builder or reviewer session.
|
|
571
566
|
\`\`\`
|
|
572
|
-
|
|
573
|
-
## Startup
|
|
574
|
-
- Read \`${options.contextRelativeToToolingRoot}\`
|
|
575
|
-
- Follow the builder/reviewer protocol defined there
|
|
576
|
-
- Use \`vibecompass start-session --id <lane-id>\`, \`vibecompass list-sessions\`, \`vibecompass switch-session <lane-id>\`, and \`vibecompass close-session --session <lane-id>\` to manage active lanes when possible
|
|
577
|
-
- Treat \`${options.rootRelativePath}/sessions/active/index.yaml\` as the current lane source of truth; this Current session block is only a continuity summary
|
|
578
|
-
- Keep the selected lane's \`${options.rootRelativePath}/sessions/active/<lane-id>/wip.md\` and \`${options.rootRelativePath}/sessions/active/<lane-id>/handoff.md\` current during an active session
|
|
579
|
-
- Use planning mode when scope is unclear; record the agreed plan in the selected lane's \`wip.md\` before implementing
|
|
580
|
-
- If stale scratch files block \`start-session\`, read them first, then close, recover, move, or delete them intentionally before retrying
|
|
581
|
-
- Workflow defaults:
|
|
582
|
-
${renderWorkflowDefaults(workflow)}
|
|
583
567
|
`;
|
|
584
568
|
}
|
|
585
569
|
|
|
586
570
|
function generateAgentsTemplate(options) {
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
## Session roles
|
|
594
|
-
|
|
595
|
-
| Entry trigger | Role | Owns session lifecycle? |
|
|
596
|
-
|---|---|---|
|
|
597
|
-
| "start session" | Builder | Yes — opens and closes the session lifecycle |
|
|
598
|
-
| "join as reviewer" | Reviewer | No — reviews the builder's work and updates the handoff |
|
|
599
|
-
| "planning mode" | Planner | No — scopes work inside the selected active lane before implementation |
|
|
600
|
-
|
|
601
|
-
## Prompt commands
|
|
602
|
-
|
|
603
|
-
- \`start session\` — builder role trigger
|
|
604
|
-
- \`join as reviewer\` — reviewer role trigger
|
|
605
|
-
- \`planning mode\` — optional prompt-level mode for scoping risky or ambiguous work before implementation
|
|
606
|
-
- \`review handoff\` — reviewer reads the selected lane's \`wip.md\`, \`handoff.md\`, latest finalized note, and relevant diffs before appending findings
|
|
607
|
-
- \`address review\` — builder reads reviewer feedback in the selected lane's \`wip.md\` / \`handoff.md\`, responds inline, applies accepted changes, and refreshes the builder handoff
|
|
608
|
-
- \`close session\` — builder runs the close-out checklist and ends with \`vibecompass close-session --session <lane-id>\`; \`end session\` is accepted as a synonym
|
|
571
|
+
return renderManagedBlock(renderSharedInstructionBody(buildScaffoldAgentContext(options), {
|
|
572
|
+
heading: `${options.projectConfig.name} Agent Instructions`,
|
|
573
|
+
intro:
|
|
574
|
+
'Agents should use VibeCompass project memory as the source of truth before planning, editing, or reviewing code.',
|
|
575
|
+
}));
|
|
576
|
+
}
|
|
609
577
|
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
6. Read the relevant docs under \`${options.rootRelativePath}/architecture/\` and \`${options.rootRelativePath}/decisions/\`.
|
|
622
|
-
|
|
623
|
-
## Working rule
|
|
624
|
-
Treat \`${options.contextRelativeToToolingRoot}\` as the local workflow source of truth for the builder/reviewer protocol and session scratch-file structure. When the package provides \`start-session\` / \`close-session\`, prefer those commands over hand-editing boilerplate.
|
|
625
|
-
Use planning mode when scope is unclear; record the agreed plan in the selected lane's \`wip.md\` before implementing.
|
|
626
|
-
If stale scratch files block \`start-session\`, read them first, then close, recover, move, or delete them intentionally before retrying.
|
|
627
|
-
- Workflow defaults:
|
|
628
|
-
${renderWorkflowDefaults(workflow)}
|
|
629
|
-
`;
|
|
578
|
+
function buildScaffoldAgentContext(options) {
|
|
579
|
+
return {
|
|
580
|
+
projectName: options.projectConfig.name ?? 'Unnamed project',
|
|
581
|
+
description: options.projectConfig.description ?? null,
|
|
582
|
+
mode: options.projectConfig.mode ?? null,
|
|
583
|
+
rootDir: options.rootRelativePath,
|
|
584
|
+
repos: options.projectConfig.repos ?? [],
|
|
585
|
+
domains: [],
|
|
586
|
+
recentDecisions: [],
|
|
587
|
+
recentSessions: [],
|
|
588
|
+
};
|
|
630
589
|
}
|
|
631
590
|
|
|
632
591
|
function renderWorkflowDefaults(workflow) {
|
package/src/setup.js
CHANGED
|
@@ -7,6 +7,7 @@ import { promisify } from 'node:util';
|
|
|
7
7
|
import { getSupportedAgentFilePaths } from './generators/agent-files/index.js';
|
|
8
8
|
import { END_MARKER, START_MARKER } from './generators/agent-files/markers.js';
|
|
9
9
|
import { parseSimpleYaml } from './simple-yaml.js';
|
|
10
|
+
import { getWorkflowConflictScanPatterns } from './workflows/registry.js';
|
|
10
11
|
|
|
11
12
|
const execFileAsync = promisify(execFile);
|
|
12
13
|
|
|
@@ -859,17 +860,7 @@ function writeAgentAdoptionPreview(prompter, candidates) {
|
|
|
859
860
|
}
|
|
860
861
|
|
|
861
862
|
function scanPotentialAgentWorkflowConflicts(content) {
|
|
862
|
-
const patterns =
|
|
863
|
-
'session',
|
|
864
|
-
'handoff',
|
|
865
|
-
'decisions',
|
|
866
|
-
'wip.md',
|
|
867
|
-
'review handoff',
|
|
868
|
-
'close-session',
|
|
869
|
-
'address review',
|
|
870
|
-
'builder',
|
|
871
|
-
'reviewer',
|
|
872
|
-
];
|
|
863
|
+
const patterns = getWorkflowConflictScanPatterns();
|
|
873
864
|
|
|
874
865
|
return content
|
|
875
866
|
.split(/\r?\n/)
|