@vibecompass/vibecompass 0.3.4 → 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 +198 -14
- package/package.json +1 -1
- package/src/cli.js +263 -0
- package/src/compatibility.js +308 -0
- 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/index.js +5 -1
- package/src/init.js +42 -2
- package/src/manifest.js +16 -4
- package/src/project-memory.js +3 -1
- package/src/read-model.js +17 -1
- package/src/refresh-workflow.js +236 -0
- package/src/scaffold.js +81 -102
- package/src/setup.js +253 -11
- package/src/status.js +350 -0
- package/src/version.js +6 -0
package/src/cli.js
CHANGED
|
@@ -7,6 +7,9 @@ import { preflightDocsReview } from './docs-review.js';
|
|
|
7
7
|
import { resolveConnectHostedCliOptions, resolveInitCliOptions } from './setup.js';
|
|
8
8
|
import { closeProjectSession, listProjectSessions, startProjectSession, switchProjectSession } from './session.js';
|
|
9
9
|
import { syncAgentInstructionFiles } from './generators/agent-files/index.js';
|
|
10
|
+
import { getProjectStatus, renderStatusText, toStatusJson } from './status.js';
|
|
11
|
+
import { refreshWorkflow } from './refresh-workflow.js';
|
|
12
|
+
import { inspectProjectCompatibility, formatCompatibilityWarnings } from './compatibility.js';
|
|
10
13
|
import {
|
|
11
14
|
applyPullExport,
|
|
12
15
|
pullExportProjectMemory,
|
|
@@ -28,6 +31,10 @@ export async function runCli(argv, io = createDefaultIo(), runtime = {}) {
|
|
|
28
31
|
io,
|
|
29
32
|
runtime,
|
|
30
33
|
});
|
|
34
|
+
if (initPlan.existingProject) {
|
|
35
|
+
return writeExistingInitProjectResult(io, initPlan.existingProject);
|
|
36
|
+
}
|
|
37
|
+
|
|
31
38
|
const result = await initializeProjectMemory({
|
|
32
39
|
...initPlan.initOptions,
|
|
33
40
|
...(runtime.cwd ? { cwd: runtime.cwd } : {}),
|
|
@@ -106,6 +113,7 @@ export async function runCli(argv, io = createDefaultIo(), runtime = {}) {
|
|
|
106
113
|
}
|
|
107
114
|
|
|
108
115
|
if (parsed.command === 'start-session') {
|
|
116
|
+
await writeCompatibilityPreflightWarnings(io, parsed.options, runtime);
|
|
109
117
|
const result = await startProjectSession({
|
|
110
118
|
...parsed.options,
|
|
111
119
|
...(runtime.cwd ? { cwd: runtime.cwd } : {}),
|
|
@@ -120,6 +128,7 @@ export async function runCli(argv, io = createDefaultIo(), runtime = {}) {
|
|
|
120
128
|
}
|
|
121
129
|
|
|
122
130
|
if (parsed.command === 'connect-hosted') {
|
|
131
|
+
await writeCompatibilityPreflightWarnings(io, parsed.options, runtime);
|
|
123
132
|
const connectPlan = await resolveConnectHostedCliOptions(parsed.options, {
|
|
124
133
|
cwd: runtime.cwd,
|
|
125
134
|
io,
|
|
@@ -141,7 +150,30 @@ export async function runCli(argv, io = createDefaultIo(), runtime = {}) {
|
|
|
141
150
|
return 0;
|
|
142
151
|
}
|
|
143
152
|
|
|
153
|
+
if (parsed.command === 'status') {
|
|
154
|
+
const result = await getProjectStatus({
|
|
155
|
+
...parsed.options,
|
|
156
|
+
...(runtime.cwd ? { cwd: runtime.cwd } : {}),
|
|
157
|
+
});
|
|
158
|
+
if (parsed.options.json) {
|
|
159
|
+
io.stdout.write(`${JSON.stringify(toStatusJson(result), null, 2)}\n`);
|
|
160
|
+
} else {
|
|
161
|
+
io.stdout.write(renderStatusText(result));
|
|
162
|
+
}
|
|
163
|
+
return 0;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (parsed.command === 'refresh-workflow') {
|
|
167
|
+
const result = await refreshWorkflow({
|
|
168
|
+
...parsed.options,
|
|
169
|
+
...(runtime.cwd ? { cwd: runtime.cwd } : {}),
|
|
170
|
+
});
|
|
171
|
+
writeRefreshWorkflowResult(io, result);
|
|
172
|
+
return 0;
|
|
173
|
+
}
|
|
174
|
+
|
|
144
175
|
if (parsed.command === 'close-session' || parsed.command === 'end-session') {
|
|
176
|
+
await writeCompatibilityPreflightWarnings(io, parsed.options, runtime);
|
|
145
177
|
const result = await closeProjectSession({
|
|
146
178
|
...parsed.options,
|
|
147
179
|
...(runtime.cwd ? { cwd: runtime.cwd } : {}),
|
|
@@ -160,6 +192,7 @@ export async function runCli(argv, io = createDefaultIo(), runtime = {}) {
|
|
|
160
192
|
}
|
|
161
193
|
|
|
162
194
|
if (parsed.command === 'list-sessions') {
|
|
195
|
+
await writeCompatibilityPreflightWarnings(io, parsed.options, runtime);
|
|
163
196
|
const result = await listProjectSessions({
|
|
164
197
|
...parsed.options,
|
|
165
198
|
...(runtime.cwd ? { cwd: runtime.cwd } : {}),
|
|
@@ -177,6 +210,7 @@ export async function runCli(argv, io = createDefaultIo(), runtime = {}) {
|
|
|
177
210
|
}
|
|
178
211
|
|
|
179
212
|
if (parsed.command === 'switch-session') {
|
|
213
|
+
await writeCompatibilityPreflightWarnings(io, parsed.options, runtime);
|
|
180
214
|
const result = await switchProjectSession({
|
|
181
215
|
...parsed.options,
|
|
182
216
|
...(runtime.cwd ? { cwd: runtime.cwd } : {}),
|
|
@@ -188,6 +222,7 @@ export async function runCli(argv, io = createDefaultIo(), runtime = {}) {
|
|
|
188
222
|
}
|
|
189
223
|
|
|
190
224
|
if (parsed.command === 'sync-agents') {
|
|
225
|
+
await writeCompatibilityPreflightWarnings(io, parsed.options, runtime);
|
|
191
226
|
const result = await syncAgentInstructionFiles({
|
|
192
227
|
...parsed.options,
|
|
193
228
|
...(runtime.cwd ? { cwd: runtime.cwd } : {}),
|
|
@@ -197,6 +232,7 @@ export async function runCli(argv, io = createDefaultIo(), runtime = {}) {
|
|
|
197
232
|
}
|
|
198
233
|
|
|
199
234
|
if (parsed.command === 'docs-review') {
|
|
235
|
+
await writeCompatibilityPreflightWarnings(io, parsed.options, runtime);
|
|
200
236
|
const result = await preflightDocsReview({
|
|
201
237
|
...parsed.options,
|
|
202
238
|
...(runtime.cwd ? { cwd: runtime.cwd } : {}),
|
|
@@ -246,6 +282,7 @@ export async function runCli(argv, io = createDefaultIo(), runtime = {}) {
|
|
|
246
282
|
}
|
|
247
283
|
|
|
248
284
|
if (parsed.command === 'push') {
|
|
285
|
+
await writeCompatibilityPreflightWarnings(io, parsed.options, runtime);
|
|
249
286
|
const result = await pushProjectMemory(parsed.options, {
|
|
250
287
|
cwd: runtime.cwd,
|
|
251
288
|
env: runtime.env,
|
|
@@ -266,6 +303,7 @@ export async function runCli(argv, io = createDefaultIo(), runtime = {}) {
|
|
|
266
303
|
}
|
|
267
304
|
|
|
268
305
|
if (parsed.command === 'pull-preview') {
|
|
306
|
+
await writeCompatibilityPreflightWarnings(io, parsed.options, runtime);
|
|
269
307
|
const result = await pullPreviewProjectMemory(parsed.options, {
|
|
270
308
|
cwd: runtime.cwd,
|
|
271
309
|
env: runtime.env,
|
|
@@ -290,6 +328,7 @@ export async function runCli(argv, io = createDefaultIo(), runtime = {}) {
|
|
|
290
328
|
}
|
|
291
329
|
|
|
292
330
|
if (parsed.command === 'pull-export') {
|
|
331
|
+
await writeCompatibilityPreflightWarnings(io, parsed.options, runtime);
|
|
293
332
|
const result = await pullExportProjectMemory(parsed.options, {
|
|
294
333
|
cwd: runtime.cwd,
|
|
295
334
|
env: runtime.env,
|
|
@@ -305,6 +344,7 @@ export async function runCli(argv, io = createDefaultIo(), runtime = {}) {
|
|
|
305
344
|
}
|
|
306
345
|
|
|
307
346
|
if (parsed.command === 'apply-export') {
|
|
347
|
+
await writeCompatibilityPreflightWarnings(io, parsed.options, runtime);
|
|
308
348
|
const result = await applyPullExport(parsed.options, {
|
|
309
349
|
cwd: runtime.cwd,
|
|
310
350
|
env: runtime.env,
|
|
@@ -338,6 +378,14 @@ export function parseCliArgs(argv) {
|
|
|
338
378
|
return parseConnectHostedArgs(rest);
|
|
339
379
|
}
|
|
340
380
|
|
|
381
|
+
if (command === 'status') {
|
|
382
|
+
return parseStatusArgs(rest);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
if (command === 'refresh-workflow') {
|
|
386
|
+
return parseRefreshWorkflowArgs(rest);
|
|
387
|
+
}
|
|
388
|
+
|
|
341
389
|
if (command === 'close-session' || command === 'end-session') {
|
|
342
390
|
return parseCloseSessionArgs(rest);
|
|
343
391
|
}
|
|
@@ -390,6 +438,11 @@ export function parseCliArgs(argv) {
|
|
|
390
438
|
continue;
|
|
391
439
|
}
|
|
392
440
|
|
|
441
|
+
if (token === '--replace-active-lanes') {
|
|
442
|
+
parsed.replaceActiveLanes = true;
|
|
443
|
+
continue;
|
|
444
|
+
}
|
|
445
|
+
|
|
393
446
|
if (token === '--guided') {
|
|
394
447
|
parsed.guided = true;
|
|
395
448
|
continue;
|
|
@@ -516,6 +569,7 @@ export function parseCliArgs(argv) {
|
|
|
516
569
|
mode: parsed.mode,
|
|
517
570
|
repos: parsed.repos,
|
|
518
571
|
force: parsed.force,
|
|
572
|
+
replaceActiveLanes: parsed.replaceActiveLanes,
|
|
519
573
|
startSession: parsed.startSession,
|
|
520
574
|
sessionWorkingOn: parsed.sessionWorkingOn,
|
|
521
575
|
sessionId: parsed.sessionId,
|
|
@@ -662,6 +716,99 @@ function parseConnectHostedArgs(argv) {
|
|
|
662
716
|
};
|
|
663
717
|
}
|
|
664
718
|
|
|
719
|
+
function parseStatusArgs(argv) {
|
|
720
|
+
const parsed = {};
|
|
721
|
+
|
|
722
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
723
|
+
const token = argv[index];
|
|
724
|
+
|
|
725
|
+
if (token === '--json') {
|
|
726
|
+
parsed.json = true;
|
|
727
|
+
continue;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
if (!token.startsWith('--')) {
|
|
731
|
+
throw new Error(`Unexpected argument "${token}".`);
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
const value = argv[index + 1];
|
|
735
|
+
if (value === undefined) {
|
|
736
|
+
throw new Error(`Flag "${token}" requires a value.`);
|
|
737
|
+
}
|
|
738
|
+
index += 1;
|
|
739
|
+
|
|
740
|
+
switch (token) {
|
|
741
|
+
case '--root':
|
|
742
|
+
parsed.rootDir = value;
|
|
743
|
+
break;
|
|
744
|
+
case '--tooling-root':
|
|
745
|
+
parsed.toolingRootDir = value;
|
|
746
|
+
break;
|
|
747
|
+
default:
|
|
748
|
+
throw new Error(`Unknown flag "${token}".`);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
return {
|
|
753
|
+
command: 'status',
|
|
754
|
+
options: parsed,
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
function parseRefreshWorkflowArgs(argv) {
|
|
759
|
+
const parsed = {};
|
|
760
|
+
|
|
761
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
762
|
+
const token = argv[index];
|
|
763
|
+
|
|
764
|
+
if (token === '--dry-run') {
|
|
765
|
+
parsed.apply = false;
|
|
766
|
+
continue;
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
if (token === '--apply') {
|
|
770
|
+
parsed.apply = true;
|
|
771
|
+
continue;
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
if (token === '--update-package-stamp') {
|
|
775
|
+
parsed.updatePackageStamp = true;
|
|
776
|
+
continue;
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
if (token === '--allow-downgrade-templates') {
|
|
780
|
+
parsed.allowDowngradeTemplates = true;
|
|
781
|
+
continue;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
if (!token.startsWith('--')) {
|
|
785
|
+
throw new Error(`Unexpected argument "${token}".`);
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
const value = argv[index + 1];
|
|
789
|
+
if (value === undefined) {
|
|
790
|
+
throw new Error(`Flag "${token}" requires a value.`);
|
|
791
|
+
}
|
|
792
|
+
index += 1;
|
|
793
|
+
|
|
794
|
+
switch (token) {
|
|
795
|
+
case '--root':
|
|
796
|
+
parsed.rootDir = value;
|
|
797
|
+
break;
|
|
798
|
+
case '--tooling-root':
|
|
799
|
+
parsed.toolingRootDir = value;
|
|
800
|
+
break;
|
|
801
|
+
default:
|
|
802
|
+
throw new Error(`Unknown flag "${token}".`);
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
return {
|
|
807
|
+
command: 'refresh-workflow',
|
|
808
|
+
options: parsed,
|
|
809
|
+
};
|
|
810
|
+
}
|
|
811
|
+
|
|
665
812
|
function parseCloseSessionArgs(argv) {
|
|
666
813
|
const parsed = {
|
|
667
814
|
completed: [],
|
|
@@ -1113,6 +1260,46 @@ function writeAgentFileSyncResult(io, result) {
|
|
|
1113
1260
|
}
|
|
1114
1261
|
}
|
|
1115
1262
|
|
|
1263
|
+
function writeRefreshWorkflowResult(io, result) {
|
|
1264
|
+
io.stdout.write(`${result.dryRun ? 'Planned' : 'Applied'} workflow refresh for ${result.rootDir}\n`);
|
|
1265
|
+
writeCompatibilityWarnings(io, result.compatibility);
|
|
1266
|
+
io.stdout.write('Project package stamp:\n');
|
|
1267
|
+
const projectSuffix = result.projectFile.warning ? ` — ${result.projectFile.warning}` : '';
|
|
1268
|
+
const projectStatus = result.dryRun && result.projectFile.changed
|
|
1269
|
+
? `dry-run-${result.projectFile.status}`
|
|
1270
|
+
: result.projectFile.status;
|
|
1271
|
+
io.stdout.write(`- project.yaml: ${projectStatus}${projectSuffix}\n`);
|
|
1272
|
+
|
|
1273
|
+
io.stdout.write('Workflow files:\n');
|
|
1274
|
+
for (const file of result.workflowFiles) {
|
|
1275
|
+
const suffix = file.warning ? ` — ${file.warning}` : '';
|
|
1276
|
+
io.stdout.write(`- ${file.relativePath}: ${result.dryRun && file.changed ? `dry-run-${file.status}` : file.status}${suffix}\n`);
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
io.stdout.write('State manifest:\n');
|
|
1280
|
+
io.stdout.write(`- ${result.manifest.path}: ${result.manifest.status} (${result.manifest.documentCount} canonical docs, ${result.manifest.warningCount} warnings)\n`);
|
|
1281
|
+
writeAgentFileSyncResult(io, result.agentFileSync);
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
async function writeCompatibilityPreflightWarnings(io, options = {}, runtime = {}) {
|
|
1285
|
+
const result = await inspectProjectCompatibility({
|
|
1286
|
+
...options,
|
|
1287
|
+
...(runtime.cwd ? { cwd: runtime.cwd } : {}),
|
|
1288
|
+
});
|
|
1289
|
+
writeCompatibilityWarnings(io, result);
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
function writeCompatibilityWarnings(io, result) {
|
|
1293
|
+
const warnings = formatCompatibilityWarnings(result);
|
|
1294
|
+
if (warnings.length === 0) {
|
|
1295
|
+
return;
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
io.stderr.write('Compatibility warnings:\n');
|
|
1299
|
+
writeWarnings(io, warnings);
|
|
1300
|
+
io.stderr.write('Run `vibecompass status` for detail.\n');
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1116
1303
|
function writeWarnings(io, warnings = []) {
|
|
1117
1304
|
for (const warning of warnings) {
|
|
1118
1305
|
io.stderr.write(`Warning: ${warning}\n`);
|
|
@@ -1133,6 +1320,8 @@ function usageText() {
|
|
|
1133
1320
|
'Usage:',
|
|
1134
1321
|
' vibecompass init --name <project-name> --mode <local-only|local-primary|hosted-only> --repo <id=remote> [options]',
|
|
1135
1322
|
' vibecompass connect-hosted [options]',
|
|
1323
|
+
' vibecompass status [options]',
|
|
1324
|
+
' vibecompass refresh-workflow [--dry-run|--apply] [options]',
|
|
1136
1325
|
' vibecompass start-session --id <lane-id> --working-on <text> [options]',
|
|
1137
1326
|
' vibecompass close-session --title <text> --completed <text> --next-step <text> [options]',
|
|
1138
1327
|
' vibecompass end-session --title <text> --completed <text> --next-step <text> [options] # alias',
|
|
@@ -1168,6 +1357,7 @@ function usageText() {
|
|
|
1168
1357
|
' --close-session-git-publish Include a Git publish step in the stored close-session workflow',
|
|
1169
1358
|
' --close-session-git-remote <name> Default Git remote name for that close-session publish step',
|
|
1170
1359
|
' --force Overwrite an existing project.yaml',
|
|
1360
|
+
' --replace-active-lanes Allow --force to replace a root that has active session lanes',
|
|
1171
1361
|
'',
|
|
1172
1362
|
'Connect-hosted options:',
|
|
1173
1363
|
' --root <path> Project-memory root. Defaults to .compass',
|
|
@@ -1176,6 +1366,19 @@ function usageText() {
|
|
|
1176
1366
|
' --sync-credential-env-var <name> Hosted sync env var reference',
|
|
1177
1367
|
' Replaces any existing project.yaml sync binding',
|
|
1178
1368
|
'',
|
|
1369
|
+
'Status options:',
|
|
1370
|
+
' --root <path> Project-memory root. Defaults to .compass',
|
|
1371
|
+
' --tooling-root <path> Directory where agent files are inspected. Defaults to cwd',
|
|
1372
|
+
' --json Print the typed status model as JSON',
|
|
1373
|
+
'',
|
|
1374
|
+
'Refresh-workflow options:',
|
|
1375
|
+
' --root <path> Project-memory root. Defaults to .compass',
|
|
1376
|
+
' --tooling-root <path> Directory where agent files are refreshed. Defaults to cwd',
|
|
1377
|
+
' --dry-run Show planned refresh without changing files (default)',
|
|
1378
|
+
' --apply Apply the planned workflow refresh',
|
|
1379
|
+
' --update-package-stamp Update an existing project.yaml package_version stamp',
|
|
1380
|
+
' --allow-downgrade-templates Allow applying templates with a CLI older than the root stamp',
|
|
1381
|
+
'',
|
|
1179
1382
|
'Start-session options:',
|
|
1180
1383
|
' --root <path> Project-memory root. Defaults to .compass',
|
|
1181
1384
|
' --tooling-root <path> Tooling root that contains CLAUDE.md. Defaults to cwd',
|
|
@@ -1260,6 +1463,66 @@ function formatOptionalRootFlag(rootDir) {
|
|
|
1260
1463
|
return ` --root ${rootDir}`;
|
|
1261
1464
|
}
|
|
1262
1465
|
|
|
1466
|
+
function writeExistingInitProjectResult(io, existingProject) {
|
|
1467
|
+
const rootFlag = formatOptionalRootFlag(existingProject.displayPath);
|
|
1468
|
+
const active = existingProject.activeSummary ?? { count: 0, current: null };
|
|
1469
|
+
|
|
1470
|
+
if (existingProject.status === 'ambiguous') {
|
|
1471
|
+
(io.stderr ?? process.stderr).write(
|
|
1472
|
+
[
|
|
1473
|
+
'Multiple VibeCompass project memory roots found:',
|
|
1474
|
+
...existingProject.candidates.map((candidate) => `- ${candidate.displayPath}`),
|
|
1475
|
+
'Pass --root explicitly to choose one.',
|
|
1476
|
+
'',
|
|
1477
|
+
].join('\n'),
|
|
1478
|
+
);
|
|
1479
|
+
return 1;
|
|
1480
|
+
}
|
|
1481
|
+
|
|
1482
|
+
if (existingProject.status === 'unreadable') {
|
|
1483
|
+
(io.stderr ?? process.stderr).write('VibeCompass project memory already exists, but project.yaml is unreadable.\n');
|
|
1484
|
+
(io.stderr ?? process.stderr).write(`Root: ${existingProject.displayPath}\n`);
|
|
1485
|
+
(io.stderr ?? process.stderr).write(`Project file: ${existingProject.projectFilePath}\n`);
|
|
1486
|
+
(io.stderr ?? process.stderr).write(`Error: ${existingProject.errorMessage}\n`);
|
|
1487
|
+
if (active.count > 0) {
|
|
1488
|
+
(io.stderr ?? process.stderr).write(`Active lanes: ${formatActiveLaneSummary(active)}\n`);
|
|
1489
|
+
(io.stderr ?? process.stderr).write('Close active lanes before replacing this root, or pass --force --replace-active-lanes if replacement is intentional.\n');
|
|
1490
|
+
} else {
|
|
1491
|
+
(io.stderr ?? process.stderr).write('Fix project.yaml manually, or rerun with --force if replacement is intentional.\n');
|
|
1492
|
+
}
|
|
1493
|
+
return 1;
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
const config = existingProject.projectConfig;
|
|
1497
|
+
const repos = Array.isArray(config.repos)
|
|
1498
|
+
? config.repos.map((repo) => repo.id).filter(Boolean)
|
|
1499
|
+
: [];
|
|
1500
|
+
io.stdout.write('VibeCompass is already initialized — here is how to continue.\n');
|
|
1501
|
+
io.stdout.write(`Project: ${config.name ?? 'Unknown'}\n`);
|
|
1502
|
+
io.stdout.write(`Mode: ${config.mode ?? 'Unknown'}\n`);
|
|
1503
|
+
io.stdout.write(`Root: ${existingProject.displayPath}\n`);
|
|
1504
|
+
io.stdout.write(`Repos: ${repos.length > 0 ? repos.join(', ') : 'None recorded'}\n`);
|
|
1505
|
+
io.stdout.write(`Active lanes: ${formatActiveLaneSummary(active)}\n`);
|
|
1506
|
+
io.stdout.write('Next commands:\n');
|
|
1507
|
+
io.stdout.write(`- vibecompass status${rootFlag}\n`);
|
|
1508
|
+
io.stdout.write(`- vibecompass list-sessions${rootFlag}\n`);
|
|
1509
|
+
io.stdout.write(`- vibecompass start-session${rootFlag} --id LANE_ID --working-on "TASK"\n`);
|
|
1510
|
+
io.stdout.write(`- vibecompass docs-review${rootFlag} --guided\n`);
|
|
1511
|
+
io.stdout.write(`- vibecompass sync-agents${rootFlag}\n`);
|
|
1512
|
+
if (['local-primary', 'hosted-only'].includes(config.mode)) {
|
|
1513
|
+
io.stdout.write(`- vibecompass connect-hosted${rootFlag}\n`);
|
|
1514
|
+
}
|
|
1515
|
+
return 0;
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1518
|
+
function formatActiveLaneSummary(activeSummary) {
|
|
1519
|
+
if (!activeSummary || activeSummary.count === 0) {
|
|
1520
|
+
return 'none';
|
|
1521
|
+
}
|
|
1522
|
+
|
|
1523
|
+
return `${activeSummary.count}${activeSummary.current ? ` (current: ${activeSummary.current})` : ''}`;
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1263
1526
|
async function main() {
|
|
1264
1527
|
try {
|
|
1265
1528
|
const exitCode = await runCli(process.argv.slice(2));
|