@vibecompass/vibecompass 0.17.2 → 0.17.4

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 CHANGED
@@ -1,5 +1,33 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.17.4 - 2026-10-17
4
+
5
+ A small sync fix: `pull-preview` and `sync-adopt` work on a root that has never
6
+ synced. The lane brief stays opt-in (D-368).
7
+
8
+ - `pull-preview` and `sync-adopt` no longer fail on a newly connected root.
9
+ With no sync cursor yet, they sent an empty base revision, which the hosted
10
+ server rejects as invalid (a 422) instead of returning a preview. They now
11
+ leave the base revision out until there is one, as `push` does.
12
+ - Tests: the suite passes under any temp directory. One A7 evaluation-harness
13
+ test passed only under a long temp path, such as a `lane-env` shell's. The
14
+ harness's isolation index also names its own-location rule in its method
15
+ text; its fingerprints are unchanged. The harness is not part of the
16
+ published package.
17
+
18
+ ## 0.17.3 - 2026-10-12
19
+
20
+ A small sync release: `push` tells you what the hosted dashboard could not
21
+ show. The lane brief stays opt-in (D-368).
22
+
23
+ - `push` prints the server's projection warnings. The server builds the
24
+ dashboard in the same step as the push and reports anything it could not
25
+ build, such as a file whose decision links could not be read
26
+ (`lineage_extraction_failed`, D-371). `push` now prints each one as a
27
+ `Note: <code> (<path>): <message>` line after the run, so you learn about it
28
+ in the terminal instead of only from a dashboard notice. The push itself
29
+ still succeeded. A push with nothing to report prints no extra lines.
30
+
3
31
  ## 0.17.2 - 2026-10-12
4
32
 
5
33
  Lockstep release with the app's lineage port: section headings open a fence
package/README.md CHANGED
@@ -339,6 +339,11 @@ changed canonical project-memory files and the hosted dashboard should catch
339
339
  up. Hosted-only projects do not use a local authoritative push; update or
340
340
  refresh them through the hosted dashboard/proposal flow.
341
341
 
342
+ `push` prints a `Note: <code> (<path>): <message>` line for anything the
343
+ hosted dashboard could not build from your files, such as a file whose decision
344
+ links could not be read. The push itself succeeded; the note names the file so
345
+ you can check it.
346
+
342
347
  ### Where the token lives (D-355)
343
348
 
344
349
  Hosted commands look for the token in this order:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibecompass/vibecompass",
3
- "version": "0.17.2",
3
+ "version": "0.17.4",
4
4
  "description": "Local-first project-memory core for VibeCompass",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.js CHANGED
@@ -619,6 +619,10 @@ export async function runCli(argv, io = createDefaultIo(), runtime = {}) {
619
619
  if (result.staleProposalIds.length > 0) {
620
620
  io.stdout.write(`Stale proposals: ${result.staleProposalIds.join(', ')}\n`);
621
621
  }
622
+ for (const warning of result.warnings) {
623
+ const where = warning.path ? ` (${warning.path})` : '';
624
+ io.stdout.write(`Note: ${warning.code}${where}: ${warning.message}\n`);
625
+ }
622
626
  io.stdout.write(`Recorded ${result.manifestPath}\n`);
623
627
  io.stdout.write(`${result.message}\n`);
624
628
  return 0;
package/src/sync.js CHANGED
@@ -56,10 +56,32 @@ export async function pushProjectMemory(options = {}, environment = {}) {
56
56
  remoteRevisionId: response.remote_revision_id,
57
57
  appliedProposalIds: response.applied_proposal_ids ?? [],
58
58
  staleProposalIds: response.stale_proposal_ids ?? [],
59
+ warnings: readProjectionWarnings(response),
59
60
  message: `Pushed ${documents.length} canonical document${documents.length === 1 ? '' : 's'} to hosted project memory.`,
60
61
  };
61
62
  }
62
63
 
64
+ /**
65
+ * The hosted push projects the dashboard read model in the same transaction
66
+ * (D-239) and reports what it could not project as `projection.warnings`
67
+ * (`{ code, message, path? }`), such as `lineage_extraction_failed` (D-371).
68
+ * The push itself succeeded, so these are notes, not errors. A server that
69
+ * sends no projection block, or an entry without a message, yields nothing.
70
+ */
71
+ function readProjectionWarnings(response) {
72
+ const warnings = response?.projection?.warnings;
73
+ if (!Array.isArray(warnings)) {
74
+ return [];
75
+ }
76
+ return warnings
77
+ .filter((warning) => warning && typeof warning === 'object' && typeof warning.message === 'string')
78
+ .map((warning) => ({
79
+ code: typeof warning.code === 'string' && warning.code ? warning.code : 'projection_warning',
80
+ message: warning.message,
81
+ ...(typeof warning.path === 'string' && warning.path ? { path: warning.path } : {}),
82
+ }));
83
+ }
84
+
63
85
  export async function pullPreviewProjectMemory(options = {}, environment = {}) {
64
86
  const context = await loadSyncContext(options, environment);
65
87
  const existingManifest = await readJsonIfPresent(context.manifestPath);
@@ -68,10 +90,11 @@ export async function pullPreviewProjectMemory(options = {}, environment = {}) {
68
90
  });
69
91
  const manifest = manifestResult.manifest;
70
92
  const cursor = readSyncCursor(manifest.sync, context.binding);
93
+ const baseRemoteRevisionId = normalizeUuid(cursor.last_successful_remote_revision);
71
94
 
72
95
  const response = await postJson(context, 'pull-preview', {
73
96
  state_version: manifest.state_version,
74
- base_remote_revision_id: normalizeUuid(cursor.last_successful_remote_revision),
97
+ ...(baseRemoteRevisionId ? { base_remote_revision_id: baseRemoteRevisionId } : {}),
75
98
  local_root_revision: manifest.canonical.local_root_revision,
76
99
  local_manifest_hash: manifest.canonical.manifest_hash,
77
100
  local_documents: buildLocalDocumentSummaries(manifest.documents),
@@ -250,10 +273,11 @@ export async function adoptRemoteHead(options = {}, environment = {}) {
250
273
  });
251
274
  const manifest = manifestResult.manifest;
252
275
  const cursor = readSyncCursor(manifest.sync, context.binding);
276
+ const baseRemoteRevisionId = normalizeUuid(cursor.last_successful_remote_revision);
253
277
 
254
278
  const response = await postJson(context, 'pull-preview', {
255
279
  state_version: manifest.state_version,
256
- base_remote_revision_id: normalizeUuid(cursor.last_successful_remote_revision),
280
+ ...(baseRemoteRevisionId ? { base_remote_revision_id: baseRemoteRevisionId } : {}),
257
281
  local_root_revision: manifest.canonical.local_root_revision,
258
282
  local_manifest_hash: manifest.canonical.manifest_hash,
259
283
  local_documents: buildLocalDocumentSummaries(manifest.documents),