@vibecompass/vibecompass 0.10.1 → 0.10.3
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/CHANGELOG.md +16 -0
- package/README.md +4 -0
- package/package.json +3 -2
- package/src/cli.js +16 -0
- package/src/docs-review.js +244 -4
- package/src/generators/agent-files/template.js +1 -0
- package/src/scaffold.js +11 -2
- package/src/session.js +41 -9
- package/src/source-inventory.js +915 -0
- package/src/workflows/registry.js +1 -1
package/src/session.js
CHANGED
|
@@ -4,6 +4,7 @@ import { scanProjectMemory } from './project-memory.js';
|
|
|
4
4
|
import { parseSimpleYaml } from './simple-yaml.js';
|
|
5
5
|
import { buildCloseSessionGuidance, resolveWorkflowSettings } from './workflow.js';
|
|
6
6
|
import { syncAgentInstructionFiles } from './generators/agent-files/index.js';
|
|
7
|
+
import { START_MARKER } from './generators/agent-files/markers.js';
|
|
7
8
|
|
|
8
9
|
const CURRENT_SESSION_REQUIRED_FIELDS = ['Date:', 'Working on:', 'Last thing completed:', 'Blockers:', 'Next session should:'];
|
|
9
10
|
const WIP_HEADER_PATTERN = /^# WIP — (\d{4}-\d{2}-\d{2}) \(session (\d+)\)$/m;
|
|
@@ -51,13 +52,13 @@ export async function startProjectSession(options) {
|
|
|
51
52
|
const highestDecisionId = await readHighestDecisionId(normalized.rootDir);
|
|
52
53
|
|
|
53
54
|
const nextSessionNumber = await getNextSessionNumber(normalized.sessionsDir, sessionDate);
|
|
54
|
-
const currentSession = parseCurrentSessionBlock(claude.content);
|
|
55
|
+
const currentSession = parseCurrentSessionBlock(claude.content, { optional: true });
|
|
55
56
|
const updatedClaude = replaceCurrentSessionBlock(claude.content, {
|
|
56
57
|
date: `${sessionDate} (session ${nextSessionNumber}, lane ${sessionId})`,
|
|
57
58
|
workingOn: `${workingOn} [${sessionId}]`,
|
|
58
59
|
lastThingCompleted:
|
|
59
60
|
normalizeOptionalString(options?.lastThingCompleted) ??
|
|
60
|
-
currentSession
|
|
61
|
+
currentSession?.lastThingCompleted ??
|
|
61
62
|
'Project memory bootstrap completed.',
|
|
62
63
|
blockers: normalizeOptionalString(options?.blockers) ?? 'No blocker yet.',
|
|
63
64
|
nextSessionShould:
|
|
@@ -170,11 +171,11 @@ export async function closeProjectSession(options) {
|
|
|
170
171
|
|
|
171
172
|
const wipContent = await readFile(lanePaths.wipFilePath, 'utf8');
|
|
172
173
|
const activeSession = parseActiveSession(wipContent, lanePaths.wipFilePath);
|
|
173
|
-
const currentSession = parseCurrentSessionBlock(claude.content);
|
|
174
|
+
const currentSession = parseCurrentSessionBlock(claude.content, { optional: true });
|
|
174
175
|
const workedOn =
|
|
175
176
|
normalizeOptionalString(options?.workedOn) ??
|
|
176
177
|
extractSectionBody(wipContent, 'Working on') ??
|
|
177
|
-
currentSession
|
|
178
|
+
currentSession?.workingOn;
|
|
178
179
|
|
|
179
180
|
if (!workedOn) {
|
|
180
181
|
throw new Error('session close could not determine what the session worked on. Pass workedOn explicitly.');
|
|
@@ -414,7 +415,7 @@ async function readWorkflowSettings(projectFilePath) {
|
|
|
414
415
|
async function readClaudeFile(claudePath) {
|
|
415
416
|
if (!(await fileExists(claudePath))) {
|
|
416
417
|
throw new Error(
|
|
417
|
-
`No CLAUDE.md was found at ${claudePath}. Re-run "vibecompass init --with-claude" or create
|
|
418
|
+
`No CLAUDE.md was found at ${claudePath}. Re-run "vibecompass init --with-claude" or create the file before using session commands.`,
|
|
418
419
|
);
|
|
419
420
|
}
|
|
420
421
|
|
|
@@ -424,9 +425,13 @@ async function readClaudeFile(claudePath) {
|
|
|
424
425
|
};
|
|
425
426
|
}
|
|
426
427
|
|
|
427
|
-
function parseCurrentSessionBlock(content) {
|
|
428
|
+
function parseCurrentSessionBlock(content, options = {}) {
|
|
428
429
|
const sessionFence = findCurrentSessionFence(content);
|
|
429
430
|
if (!sessionFence) {
|
|
431
|
+
if (options.optional) {
|
|
432
|
+
return null;
|
|
433
|
+
}
|
|
434
|
+
|
|
430
435
|
throw new Error('CLAUDE.md is missing a recognizable "## Current session" fenced block.');
|
|
431
436
|
}
|
|
432
437
|
|
|
@@ -453,19 +458,46 @@ function parseCurrentSessionBlock(content) {
|
|
|
453
458
|
|
|
454
459
|
function replaceCurrentSessionBlock(content, fields) {
|
|
455
460
|
const sessionFence = findCurrentSessionFence(content);
|
|
461
|
+
const blockBody = renderCurrentSessionBlockBody(fields);
|
|
462
|
+
|
|
456
463
|
if (!sessionFence) {
|
|
457
|
-
|
|
464
|
+
return insertCurrentSessionBlock(content, blockBody);
|
|
458
465
|
}
|
|
459
466
|
|
|
460
|
-
|
|
467
|
+
return `${content.slice(0, sessionFence.bodyStart)}${blockBody}${content.slice(sessionFence.bodyEnd)}`;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
function renderCurrentSessionBlockBody(fields) {
|
|
471
|
+
return [
|
|
461
472
|
`Date: ${fields.date}`,
|
|
462
473
|
`Working on: ${fields.workingOn}`,
|
|
463
474
|
`Last thing completed: ${fields.lastThingCompleted}`,
|
|
464
475
|
`Blockers: ${fields.blockers}`,
|
|
465
476
|
`Next session should: ${fields.nextSessionShould}`,
|
|
466
477
|
].join('\n');
|
|
478
|
+
}
|
|
467
479
|
|
|
468
|
-
|
|
480
|
+
function insertCurrentSessionBlock(content, blockBody) {
|
|
481
|
+
const currentSessionBlock = [
|
|
482
|
+
'## Current session',
|
|
483
|
+
'',
|
|
484
|
+
'**Update this block at the start and end of every session.**',
|
|
485
|
+
'',
|
|
486
|
+
'```',
|
|
487
|
+
blockBody,
|
|
488
|
+
'```',
|
|
489
|
+
'',
|
|
490
|
+
].join('\n');
|
|
491
|
+
const markerIndex = content.indexOf(START_MARKER);
|
|
492
|
+
const normalizedContent = content.endsWith('\n') ? content : `${content}\n`;
|
|
493
|
+
|
|
494
|
+
if (markerIndex >= 0) {
|
|
495
|
+
const beforeMarker = content.slice(0, markerIndex).trimEnd();
|
|
496
|
+
const fromMarker = content.slice(markerIndex);
|
|
497
|
+
return `${beforeMarker}\n\n${currentSessionBlock}${fromMarker}`;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
return `${normalizedContent}\n${currentSessionBlock}`;
|
|
469
501
|
}
|
|
470
502
|
|
|
471
503
|
function buildCurrentSessionFieldsForLane(lane, overrides = {}) {
|