@vibecompass/vibecompass 0.1.0 → 0.2.1

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 CHANGED
@@ -14,7 +14,9 @@ Shipped today:
14
14
  - interactive guided init for placement, workflow bootstrap, and first-session setup
15
15
  - generated `context.md` plus opt-in workflow guide files
16
16
  - opt-in starter `CLAUDE.md` / `AGENTS.md` templates that are created once and never overwritten
17
- - `vibecompass start-session` / `vibecompass close-session` for the local builder workflow
17
+ - `vibecompass start-session` / `vibecompass close-session` for lane-aware local builder workflow
18
+ - `vibecompass list-sessions` / `vibecompass switch-session` for multiple active session lanes
19
+ - `vibecompass end-session` as a discoverable alias for `close-session`
18
20
  - `vibecompass sync-agents` for generated `CLAUDE.md`, `AGENTS.md`, `.cursorrules`, and `.github/copilot-instructions.md` views
19
21
  - canonical file scanning and validation
20
22
  - `state/manifest.json` generation
@@ -39,6 +41,9 @@ broader local-primary sync workflow is still being built on top of it.
39
41
  npx -y @vibecompass/vibecompass --help
40
42
  ```
41
43
 
44
+ The npm package is scoped under the VibeCompass org, but the installed CLI
45
+ command is intentionally unscoped: `vibecompass`.
46
+
42
47
  ### Library
43
48
 
44
49
  ```bash
@@ -77,6 +82,7 @@ npx -y @vibecompass/vibecompass init \
77
82
  --close-session-git-publish \
78
83
  --close-session-git-remote origin \
79
84
  --start-session \
85
+ --session-id mcp-dogfood \
80
86
  --session-working-on "Validate the local-first MCP workflow"
81
87
  ```
82
88
 
@@ -98,6 +104,7 @@ If you do not chain straight into a first session from `init`, open one later:
98
104
 
99
105
  ```bash
100
106
  npx -y @vibecompass/vibecompass start-session \
107
+ --id mcp-dogfood \
101
108
  --working-on "Validate the MCP dogfood workflow against the docs repo"
102
109
  ```
103
110
 
@@ -105,29 +112,49 @@ Close the active builder session:
105
112
 
106
113
  ```bash
107
114
  npx -y @vibecompass/vibecompass close-session \
115
+ --session mcp-dogfood \
108
116
  --title "Workflow Parity Commands" \
109
117
  --completed "Added package-owned start-session and close-session commands" \
110
118
  --next-step "Run the package publish dry-run"
111
119
  ```
112
120
 
121
+ `end-session` is accepted as an alias for the same lifecycle step and flags:
122
+ `npx -y @vibecompass/vibecompass end-session ...`.
123
+
113
124
  The package CLI owns filesystem lifecycle only. The default scaffolded
114
125
  workflow also uses prompt commands inside your coding tool:
115
126
 
116
127
  ```text
117
128
  start session # builder role trigger
118
129
  join as reviewer # reviewer role trigger
119
- review handoff # reviewer reads the latest note, wip.md, handoff.md, and diffs
120
- address review # builder reads reviewer feedback, responds inline, and continues
130
+ review handoff # reviewer reads selected-lane wip.md, handoff.md, and diffs
131
+ address review # builder reads selected-lane feedback, responds inline, and continues
121
132
  ```
122
133
 
123
134
  Those prompt commands are documented in the generated `context.md`,
124
135
  `CLAUDE.md`, and `AGENTS.md` templates. They are not additional
125
136
  `vibecompass` CLI subcommands.
126
137
  Reviewer handback is explicit in the package-managed workflow: the reviewer
127
- ends the pass by updating `wip.md` + `handoff.md`, and the builder closes
128
- the session with `vibecompass close-session` using the defaults stored in
138
+ ends the pass by updating the selected lane's `wip.md` + `handoff.md`, and
139
+ the builder closes the session with `vibecompass close-session --session
140
+ <lane-id>` using the defaults stored in
129
141
  `project.yaml.metadata.workflow.close_session`.
130
142
 
143
+ Active builder sessions are named lanes under
144
+ `sessions/active/<lane-id>/`. Use one lane per active feature or workstream.
145
+ `start-session` requires `--id <lane-id>` for every lane, including the first
146
+ one in a project.
147
+ Finalized sessions are append-only notes named
148
+ `sessions/YYYY-MM-DD-N-title.md`, so multiple sessions on the same day
149
+ increment `N`. Decisions remain append-only in `decisions/`; a session note
150
+ can reference a decision, but the decision file is the durable source of truth.
151
+
152
+ For higher-risk work, use planning mode as a prompt-level step inside the
153
+ active session. Planning mode should read the same context, propose scope and
154
+ tradeoffs, and record the agreed plan in the selected lane's `wip.md`; it
155
+ should not create a separate lifecycle artifact or finalize decisions until
156
+ you approve implementation.
157
+
131
158
  Generate agent-instruction files from project memory:
132
159
 
133
160
  ```bash
@@ -206,6 +233,7 @@ Options:
206
233
  - `--with-agents`: create a starter `AGENTS.md` if it does not already exist
207
234
  - `--start-session`: open the first builder session after init
208
235
  - `--session-working-on <text>`: required with `--start-session` outside guided mode
236
+ - `--session-id <lane-id>`: required with `--start-session`; names the first builder lane
209
237
  - `--close-session-git-publish`: store that the close-session workflow includes a Git publish step
210
238
  - `--close-session-git-remote <name>`: optional default Git remote name for that stored publish step
211
239
  - `--force`: overwrite an existing `project.yaml`
@@ -219,7 +247,7 @@ include a Git publish step and which remote name to use for that step.
219
247
  ### `vibecompass start-session`
220
248
 
221
249
  ```text
222
- vibecompass start-session --working-on <text> [options]
250
+ vibecompass start-session --id <lane-id> --working-on <text> [options]
223
251
  ```
224
252
 
225
253
  Options:
@@ -227,10 +255,31 @@ Options:
227
255
  - `--root <path>`: project-memory root; defaults to `.compass`
228
256
  - `--tooling-root <path>`: workspace root that contains `CLAUDE.md`; defaults to cwd
229
257
  - `--working-on <text>`: required active-session summary
258
+ - `--id <lane-id>`: required lane ID
259
+ - `--feature <slug>`: repeatable feature slug for the lane
260
+ - `--repo <id>`: repeatable repo ID for the lane
261
+ - `--claim <path>`: repeatable path claim for overlap warnings
230
262
  - `--date <YYYY-MM-DD>`: optional explicit session date
231
263
 
232
264
  This command updates the `Current session` block in `CLAUDE.md` and creates
233
- `sessions/wip.md` plus `sessions/handoff.md` for the next session number.
265
+ `sessions/active/<lane-id>/session.yaml`, `wip.md`, and `handoff.md` for the
266
+ next session number. It also updates `sessions/active/index.yaml`.
267
+
268
+ ### `vibecompass list-sessions`
269
+
270
+ ```text
271
+ vibecompass list-sessions [options]
272
+ ```
273
+
274
+ Lists active session lanes and marks the current lane.
275
+
276
+ ### `vibecompass switch-session`
277
+
278
+ ```text
279
+ vibecompass switch-session <lane-id> [options]
280
+ ```
281
+
282
+ Changes the current lane in `sessions/active/index.yaml`.
234
283
 
235
284
  ### `vibecompass close-session`
236
285
 
@@ -238,12 +287,17 @@ This command updates the `Current session` block in `CLAUDE.md` and creates
238
287
  vibecompass close-session --title <text> --completed <text> --next-step <text> [options]
239
288
  ```
240
289
 
290
+ `vibecompass end-session` accepts the same options and runs the same close
291
+ path. `close-session` remains the canonical command name in generated workflow
292
+ metadata and docs.
293
+
241
294
  Options:
242
295
 
243
296
  - `--root <path>`: project-memory root; defaults to `.compass`
244
297
  - `--tooling-root <path>`: workspace root that contains `CLAUDE.md`; defaults to cwd
245
298
  - `--title <text>`: required finalized session-note title
246
299
  - `--worked-on <text>`: optional override for the "What we worked on" section
300
+ - `--session <lane-id>`: active lane to close; required when multiple lanes are active
247
301
  - `--completed <text>`: repeatable completed item
248
302
  - `--decision <text>`: repeatable decision reference or summary
249
303
  - `--model <text>`: optional repeatable model contribution entry
@@ -251,7 +305,8 @@ Options:
251
305
  - `--next-step <text>`: repeatable next-session instruction
252
306
 
253
307
  This command finalizes the active scratchpad into
254
- `sessions/YYYY-MM-DD-N-display-title.md`, deletes `wip.md` / `handoff.md`, and
308
+ `sessions/YYYY-MM-DD-N-display-title.md`, deletes the closed lane directory
309
+ under `sessions/active/<lane-id>/`, updates `sessions/active/index.yaml`, and
255
310
  updates the `Current session` block in `CLAUDE.md`. If no `--model` flags are
256
311
  provided, the session note records `Not recorded.` under `Models used`.
257
312
  This is the final builder lifecycle step after the last `address review`
@@ -283,15 +338,15 @@ These are the default prompt commands used by the scaffolded workflow files:
283
338
 
284
339
  - `start session`: builder role trigger
285
340
  - `join as reviewer`: reviewer role trigger
286
- - `review handoff`: reviewer reads the latest finalized note, `wip.md`, `handoff.md`, and relevant diffs before appending findings
287
- - `address review`: builder reads the latest reviewer feedback in `wip.md` / `handoff.md`, responds inline, applies accepted changes, and refreshes the builder handoff
341
+ - `review handoff`: reviewer reads the selected lane's latest `wip.md`, `handoff.md`, latest finalized note, and relevant diffs before appending findings
342
+ - `address review`: builder reads the latest reviewer feedback in the selected lane's `wip.md` / `handoff.md`, responds inline, applies accepted changes, and refreshes the builder handoff
288
343
 
289
344
  They are prompt commands for AI-tool behavior, not package CLI commands.
290
- Reviewer handback ends when the reviewer has updated `wip.md` and
291
- `handoff.md`; there is no extra reviewer-exit step. The builder remains
292
- in builder role, uses `address review` until findings are resolved or
293
- explicitly deferred, and then runs `vibecompass close-session` using the
294
- workflow defaults recorded in `project.yaml`.
345
+ Reviewer handback ends when the reviewer has updated the selected lane's
346
+ `wip.md` and `handoff.md`; there is no extra reviewer-exit step. The builder
347
+ remains in builder role, uses `address review` until findings are resolved or
348
+ explicitly deferred, and then runs `vibecompass close-session --session
349
+ <lane-id>` using the workflow defaults recorded in `project.yaml`.
295
350
 
296
351
  ## JavaScript API
297
352
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibecompass/vibecompass",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "Local-first project-memory core for VibeCompass",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.js CHANGED
@@ -4,7 +4,7 @@ import { realpathSync } from 'node:fs';
4
4
  import { pathToFileURL } from 'node:url';
5
5
  import { initializeProjectMemory } from './init.js';
6
6
  import { resolveInitCliOptions } from './setup.js';
7
- import { closeProjectSession, startProjectSession } from './session.js';
7
+ import { closeProjectSession, listProjectSessions, startProjectSession, switchProjectSession } from './session.js';
8
8
  import { syncAgentInstructionFiles } from './generators/agent-files/index.js';
9
9
 
10
10
  export async function runCli(argv, io = createDefaultIo(), runtime = {}) {
@@ -62,6 +62,7 @@ export async function runCli(argv, io = createDefaultIo(), runtime = {}) {
62
62
  const sessionResult = await startProjectSession({
63
63
  rootDir: initPlan.initOptions.rootDir,
64
64
  toolingRootDir: initPlan.initOptions.toolingRootDir,
65
+ sessionId: initPlan.sessionPlan.sessionId,
65
66
  workingOn: initPlan.sessionPlan.workingOn,
66
67
  ...(runtime.cwd ? { cwd: runtime.cwd } : {}),
67
68
  });
@@ -69,6 +70,7 @@ export async function runCli(argv, io = createDefaultIo(), runtime = {}) {
69
70
  io.stdout.write(`Updated ${sessionResult.claudePath}\n`);
70
71
  io.stdout.write(`Created ${sessionResult.wipFilePath}\n`);
71
72
  io.stdout.write(`Created ${sessionResult.handoffFilePath}\n`);
73
+ writeAgentFileSyncResult(io, sessionResult.agentFileSync);
72
74
  }
73
75
 
74
76
  return 0;
@@ -83,10 +85,11 @@ export async function runCli(argv, io = createDefaultIo(), runtime = {}) {
83
85
  io.stdout.write(`Updated ${result.claudePath}\n`);
84
86
  io.stdout.write(`Created ${result.wipFilePath}\n`);
85
87
  io.stdout.write(`Created ${result.handoffFilePath}\n`);
88
+ writeAgentFileSyncResult(io, result.agentFileSync);
86
89
  return 0;
87
90
  }
88
91
 
89
- if (parsed.command === 'close-session') {
92
+ if (parsed.command === 'close-session' || parsed.command === 'end-session') {
90
93
  const result = await closeProjectSession({
91
94
  ...parsed.options,
92
95
  ...(runtime.cwd ? { cwd: runtime.cwd } : {}),
@@ -104,6 +107,34 @@ export async function runCli(argv, io = createDefaultIo(), runtime = {}) {
104
107
  return 0;
105
108
  }
106
109
 
110
+ if (parsed.command === 'list-sessions') {
111
+ const result = await listProjectSessions({
112
+ ...parsed.options,
113
+ ...(runtime.cwd ? { cwd: runtime.cwd } : {}),
114
+ });
115
+ io.stdout.write(`Active session lanes${result.current ? ` (current: ${result.current})` : ''}:\n`);
116
+ if (result.lanes.length === 0) {
117
+ io.stdout.write('- None\n');
118
+ } else {
119
+ for (const lane of result.lanes) {
120
+ const marker = lane.id === result.current ? '*' : '-';
121
+ io.stdout.write(`${marker} ${lane.id}: ${lane.workingOn ?? 'No summary recorded'}\n`);
122
+ }
123
+ }
124
+ return 0;
125
+ }
126
+
127
+ if (parsed.command === 'switch-session') {
128
+ const result = await switchProjectSession({
129
+ ...parsed.options,
130
+ ...(runtime.cwd ? { cwd: runtime.cwd } : {}),
131
+ });
132
+ io.stdout.write(`Current session lane: ${result.current}\n`);
133
+ io.stdout.write(`Updated ${result.claudePath}\n`);
134
+ writeAgentFileSyncResult(io, result.agentFileSync);
135
+ return 0;
136
+ }
137
+
107
138
  if (parsed.command === 'sync-agents') {
108
139
  const result = await syncAgentInstructionFiles({
109
140
  ...parsed.options,
@@ -128,10 +159,18 @@ export function parseCliArgs(argv) {
128
159
  return parseStartSessionArgs(rest);
129
160
  }
130
161
 
131
- if (command === 'close-session') {
162
+ if (command === 'close-session' || command === 'end-session') {
132
163
  return parseCloseSessionArgs(rest);
133
164
  }
134
165
 
166
+ if (command === 'list-sessions') {
167
+ return parseListSessionsArgs(rest);
168
+ }
169
+
170
+ if (command === 'switch-session') {
171
+ return parseSwitchSessionArgs(rest);
172
+ }
173
+
135
174
  if (command === 'sync-agents') {
136
175
  return parseSyncAgentsArgs(rest);
137
176
  }
@@ -236,6 +275,9 @@ export function parseCliArgs(argv) {
236
275
  case '--session-working-on':
237
276
  parsed.sessionWorkingOn = value;
238
277
  break;
278
+ case '--session-id':
279
+ parsed.sessionId = value;
280
+ break;
239
281
  case '--close-session-git-remote':
240
282
  parsed.closeSessionGitRemote = value;
241
283
  break;
@@ -272,6 +314,7 @@ export function parseCliArgs(argv) {
272
314
  force: parsed.force,
273
315
  startSession: parsed.startSession,
274
316
  sessionWorkingOn: parsed.sessionWorkingOn,
317
+ sessionId: parsed.sessionId,
275
318
  closeSessionGitPublish: parsed.closeSessionGitPublish,
276
319
  closeSessionGitRemote: parsed.closeSessionGitRemote,
277
320
  ...(parsed.withWorkflow || parsed.withClaude || parsed.withAgents
@@ -322,6 +365,18 @@ function parseStartSessionArgs(argv) {
322
365
  case '--working-on':
323
366
  parsed.workingOn = value;
324
367
  break;
368
+ case '--id':
369
+ parsed.sessionId = value;
370
+ break;
371
+ case '--feature':
372
+ parsed.features = [...(parsed.features ?? []), value];
373
+ break;
374
+ case '--repo':
375
+ parsed.repos = [...(parsed.repos ?? []), value];
376
+ break;
377
+ case '--claim':
378
+ parsed.claims = [...(parsed.claims ?? []), value];
379
+ break;
325
380
  case '--date':
326
381
  parsed.date = value;
327
382
  break;
@@ -381,6 +436,9 @@ function parseCloseSessionArgs(argv) {
381
436
  case '--worked-on':
382
437
  parsed.workedOn = value;
383
438
  break;
439
+ case '--session':
440
+ parsed.sessionId = value;
441
+ break;
384
442
  case '--completed':
385
443
  parsed.completed.push(value);
386
444
  break;
@@ -413,6 +471,80 @@ function parseCloseSessionArgs(argv) {
413
471
  };
414
472
  }
415
473
 
474
+ function parseListSessionsArgs(argv) {
475
+ const parsed = {};
476
+
477
+ for (let index = 0; index < argv.length; index += 1) {
478
+ const token = argv[index];
479
+ if (!token.startsWith('--')) {
480
+ throw new Error(`Unexpected argument "${token}".`);
481
+ }
482
+
483
+ const value = argv[index + 1];
484
+ if (value === undefined) {
485
+ throw new Error(`Flag "${token}" requires a value.`);
486
+ }
487
+ index += 1;
488
+
489
+ switch (token) {
490
+ case '--root':
491
+ parsed.rootDir = value;
492
+ break;
493
+ default:
494
+ throw new Error(`Unknown flag "${token}".`);
495
+ }
496
+ }
497
+
498
+ return {
499
+ command: 'list-sessions',
500
+ options: parsed,
501
+ };
502
+ }
503
+
504
+ function parseSwitchSessionArgs(argv) {
505
+ const parsed = {};
506
+ const positional = [];
507
+
508
+ for (let index = 0; index < argv.length; index += 1) {
509
+ const token = argv[index];
510
+
511
+ if (!token.startsWith('--')) {
512
+ positional.push(token);
513
+ continue;
514
+ }
515
+
516
+ const value = argv[index + 1];
517
+ if (value === undefined) {
518
+ throw new Error(`Flag "${token}" requires a value.`);
519
+ }
520
+ index += 1;
521
+
522
+ switch (token) {
523
+ case '--root':
524
+ parsed.rootDir = value;
525
+ break;
526
+ case '--session':
527
+ parsed.sessionId = value;
528
+ break;
529
+ default:
530
+ throw new Error(`Unknown flag "${token}".`);
531
+ }
532
+ }
533
+
534
+ if (positional.length > 1) {
535
+ throw new Error(`Unexpected argument "${positional[1]}".`);
536
+ }
537
+
538
+ if (!parsed.sessionId && positional[0]) {
539
+ parsed.sessionId = positional[0];
540
+ }
541
+
542
+ return {
543
+ command: 'switch-session',
544
+ options: parsed,
545
+ };
546
+ }
547
+
416
548
  function parseSyncAgentsArgs(argv) {
417
549
  const parsed = {};
418
550
 
@@ -481,8 +613,11 @@ function usageText() {
481
613
  return [
482
614
  'Usage:',
483
615
  ' vibecompass init --name <project-name> --mode <local-only|local-primary|hosted-only> --repo <id=remote> [options]',
484
- ' vibecompass start-session --working-on <text> [options]',
616
+ ' vibecompass start-session --id <lane-id> --working-on <text> [options]',
485
617
  ' vibecompass close-session --title <text> --completed <text> --next-step <text> [options]',
618
+ ' vibecompass end-session --title <text> --completed <text> --next-step <text> [options] # alias',
619
+ ' vibecompass list-sessions [options]',
620
+ ' vibecompass switch-session <id> [options]',
486
621
  ' vibecompass sync-agents [options]',
487
622
  '',
488
623
  'Init options:',
@@ -503,6 +638,7 @@ function usageText() {
503
638
  ' --with-agents Create a starter AGENTS.md if missing',
504
639
  ' --start-session Open the first builder session after init',
505
640
  ' --session-working-on <text> Required with --start-session outside guided mode',
641
+ ' --session-id <lane-id> Required with --start-session; names the first builder lane',
506
642
  ' --close-session-git-publish Include a Git publish step in the stored close-session workflow',
507
643
  ' --close-session-git-remote <name> Default Git remote name for that close-session publish step',
508
644
  ' --force Overwrite an existing project.yaml',
@@ -511,16 +647,21 @@ function usageText() {
511
647
  ' --root <path> Project-memory root. Defaults to .compass',
512
648
  ' --tooling-root <path> Tooling root that contains CLAUDE.md. Defaults to cwd',
513
649
  ' --working-on <text> Required active-session summary',
650
+ ' --id <lane-id> Required active session lane ID',
651
+ ' --feature <slug> Repeatable feature slug for the lane',
652
+ ' --repo <id> Repeatable repo ID for the lane',
653
+ ' --claim <path> Repeatable path claim for overlap warnings',
514
654
  ' --date <YYYY-MM-DD> Optional explicit session date',
515
655
  ' --last-thing-completed <text> Optional override for the CLAUDE.md current-session block',
516
656
  ' --blockers <text> Optional current blockers summary',
517
657
  ' --next-session-should <text> Optional current-session handoff summary',
518
658
  '',
519
- 'Close-session options:',
659
+ 'Close-session options (also accepted by end-session):',
520
660
  ' --root <path> Project-memory root. Defaults to .compass',
521
661
  ' --tooling-root <path> Tooling root that contains CLAUDE.md. Defaults to cwd',
522
662
  ' --title <text> Required display title for the finalized session note',
523
663
  ' --worked-on <text> Optional override for "What we worked on"',
664
+ ' --session <lane-id> Active session lane to close',
524
665
  ' --completed <text> Repeatable completed item',
525
666
  ' --decision <text> Repeatable decision reference or summary',
526
667
  ' --model <text> Optional repeatable model contribution entry',
@@ -529,6 +670,10 @@ function usageText() {
529
670
  ' --last-thing-completed <text> Optional override for the CLAUDE.md completed summary',
530
671
  ' --next-session-should <text> Optional override for the CLAUDE.md next-session summary',
531
672
  '',
673
+ 'List/switch-session options:',
674
+ ' --root <path> Project-memory root. Defaults to .compass',
675
+ ' --session <lane-id> Lane ID for switch-session; positional ID is also accepted',
676
+ '',
532
677
  'Sync-agents options:',
533
678
  ' --root <path> Project-memory root. Defaults to .compass',
534
679
  ' --tooling-root <path> Directory where agent files are written. Defaults to cwd',
@@ -26,16 +26,25 @@ export function renderSharedInstructionBody(context, options = {}) {
26
26
  `- Project memory root: \`${context.rootDir}\``,
27
27
  '- Read `project.yaml` for project identity, repos, mode, and workflow defaults.',
28
28
  '- Read the latest finalized session note under `sessions/` before resuming work.',
29
- '- Read `sessions/wip.md` and `sessions/handoff.md` when they exist; they are the active builder/reviewer scratch files.',
29
+ '- Read `sessions/active/index.yaml` when it exists, then read the selected lane under `sessions/active/<lane-id>/`.',
30
+ '- Read the selected lane `wip.md` and `handoff.md` when they exist; they are the active builder/reviewer scratch files.',
30
31
  '- Read relevant `architecture/` and `decisions/` files before changing implementation.',
31
32
  '',
32
33
  '## Project Shape',
33
34
  ...renderProjectShape(context),
34
35
  '',
35
36
  '## Workflow Rules',
37
+ '- VibeCompass active builder sessions are named lanes. Use one lane per active feature or workstream; finalized session notes are append-only history under `sessions/YYYY-MM-DD-N-title.md`.',
36
38
  '- Use `start session` for builder work and `join as reviewer` for review work.',
39
+ '- Use `vibecompass start-session --id <lane-id>` to open a named lane for every active feature or workstream.',
40
+ '- Use `vibecompass list-sessions` and `vibecompass switch-session <lane-id>` to inspect or change the current lane.',
41
+ '- Treat `sessions/active/index.yaml` as the current lane source of truth; tool-specific Current session blocks are continuity summaries.',
42
+ '- 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.',
37
43
  '- Use `review handoff` to ask a reviewer to inspect the active handoff.',
38
- '- Use `address review` to process reviewer feedback from `sessions/wip.md` and `sessions/handoff.md`.',
44
+ '- Use `address review` to process reviewer feedback from the selected lane `wip.md` and `handoff.md`.',
45
+ '- End the active builder session with `vibecompass close-session --session <lane-id>`; `vibecompass end-session` is an accepted alias.',
46
+ '- If stale scratch files block `start-session`, read them first, then close, recover, move, or delete them intentionally before retrying.',
47
+ '- Keep decisions append-only in `decisions/`. Session notes may reference decisions, but decisions are the durable source of truth.',
39
48
  '- Treat generated agent files as views. Update canonical VibeCompass project memory instead of editing managed regions.',
40
49
  '',
41
50
  '## Recent Decisions',
package/src/index.js CHANGED
@@ -1,7 +1,12 @@
1
1
  export { STATE_VERSION, generateStateManifest, writeStateManifest } from './manifest.js';
2
2
  export { initializeProjectMemory } from './init.js';
3
3
  export { scanProjectMemory } from './project-memory.js';
4
- export { startProjectSession, closeProjectSession } from './session.js';
4
+ export {
5
+ closeProjectSession,
6
+ listProjectSessions,
7
+ startProjectSession,
8
+ switchProjectSession,
9
+ } from './session.js';
5
10
  export {
6
11
  syncAgentInstructionFiles,
7
12
  getSupportedAgentFormats,