vibeview 0.30.0 → 0.31.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.
@@ -179,9 +179,33 @@ function saveDevConfig(cwd, cfg) {
179
179
  function updateDevConfig(cwd, platform, apply) {
180
180
  const fresh = loadDevConfig(cwd) ?? { defaultPlatform: platform, platforms: {} };
181
181
  if (apply(fresh) === false) return fresh;
182
+ const onDisk = readRawConfig(cwd);
183
+ if (onDisk !== void 0 && canonicalJson(onDisk) === canonicalJson(fresh)) return fresh;
182
184
  saveDevConfig(cwd, fresh);
183
185
  return fresh;
184
186
  }
187
+ function readRawConfig(cwd) {
188
+ try {
189
+ return JSON.parse(readFileSync(join(cwd, FILE), "utf-8"));
190
+ } catch {
191
+ return void 0;
192
+ }
193
+ }
194
+ function canonicalJson(value) {
195
+ const sortKeys = (v) => {
196
+ if (Array.isArray(v)) return v.map(sortKeys);
197
+ if (v && typeof v === "object") {
198
+ const out = {};
199
+ for (const k of Object.keys(v).sort()) {
200
+ const child = v[k];
201
+ if (child !== void 0) out[k] = sortKeys(child);
202
+ }
203
+ return out;
204
+ }
205
+ return v;
206
+ };
207
+ return JSON.stringify(sortKeys(value));
208
+ }
185
209
  function configLeaves(value, path = [], out = []) {
186
210
  if (value && typeof value === "object" && !Array.isArray(value)) {
187
211
  for (const [k, v] of Object.entries(value)) {
@@ -408,30 +432,25 @@ function isPidAlive(pid) {
408
432
  }
409
433
  }
410
434
  var WHOLE_DIR_LINE = /^(\/?)\.vibeview\/?$/;
435
+ var VIBEVIEW_DIR_GITIGNORE = "# VibeView local state (written by the vibeview CLI). test-spec.json is committed for CI.\n*\n!test-spec.json\n";
411
436
  function ensureGitignored(cwd) {
437
+ try {
438
+ const dir = join2(cwd, ".vibeview");
439
+ mkdirSync(dir, { recursive: true });
440
+ const inner = join2(dir, ".gitignore");
441
+ if (!existsSync(inner)) writeFileSync2(inner, VIBEVIEW_DIR_GITIGNORE);
442
+ } catch {
443
+ }
412
444
  try {
413
445
  const gitignore = join2(cwd, ".gitignore");
414
446
  if (!existsSync(gitignore)) return;
415
447
  const content = readFileSync2(gitignore, "utf-8");
416
448
  const lines = content.split("\n");
417
- const trimmed = lines.map((l) => l.trim());
418
- if (trimmed.some((l) => /^\/?\.vibeview\/\*$/.test(l))) return;
419
- const i = trimmed.findIndex((l) => WHOLE_DIR_LINE.test(l));
420
- if (i !== -1) {
421
- const anchor = WHOLE_DIR_LINE.exec(trimmed[i])[1];
422
- lines.splice(i, 1, `${anchor}.vibeview/*`, `!${anchor}.vibeview/test-spec.json`);
423
- writeFileSync2(gitignore, lines.join("\n"));
424
- return;
425
- }
426
- const prefix = content.length > 0 && !content.endsWith("\n") ? "\n" : "";
427
- writeFileSync2(
428
- gitignore,
429
- `${content}${prefix}
430
- # VibeView local session state (test-spec.json is committed for CI)
431
- .vibeview/*
432
- !.vibeview/test-spec.json
433
- `
434
- );
449
+ const i = lines.findIndex((l) => WHOLE_DIR_LINE.test(l.trim()));
450
+ if (i === -1) return;
451
+ const anchor = WHOLE_DIR_LINE.exec(lines[i].trim())[1];
452
+ lines.splice(i, 1, `${anchor}.vibeview/*`, `!${anchor}.vibeview/test-spec.json`);
453
+ writeFileSync2(gitignore, lines.join("\n"));
435
454
  } catch {
436
455
  }
437
456
  }