vibeview 0.30.0 → 0.32.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
  }
@@ -442,6 +461,10 @@ function writeDevState(cwd, state) {
442
461
  ensureGitignored(cwd);
443
462
  }
444
463
  function readDevState(cwd) {
464
+ const found = readDevStateFile(cwd);
465
+ return found && found.alive ? found.state : null;
466
+ }
467
+ function readDevStateFile(cwd) {
445
468
  let raw;
446
469
  try {
447
470
  raw = readFileSync2(statePath(cwd), "utf-8");
@@ -454,10 +477,10 @@ function readDevState(cwd) {
454
477
  } catch {
455
478
  return null;
456
479
  }
457
- if (typeof parsed.pid !== "number" || !isPidAlive(parsed.pid)) {
480
+ if (!parsed || typeof parsed.pid !== "number" || typeof parsed.session_id !== "string") {
458
481
  return null;
459
482
  }
460
- return parsed;
483
+ return { state: parsed, alive: isPidAlive(parsed.pid) };
461
484
  }
462
485
  function clearDevState(cwd) {
463
486
  const path = statePath(cwd);
@@ -2556,7 +2579,7 @@ async function pollUntilActive(api, sessionId, timeoutMs, intervalMs = 2e3, onIn
2556
2579
  }
2557
2580
  function sessionLivenessVerdict(info) {
2558
2581
  if (info && (info.status === "stopped" || info.status === "failed")) {
2559
- return { end: true, message: `session ${info.status} \u2014 ending the reload loop` };
2582
+ return { end: true, message: `session ${info.status} \u2014 ending the dev session` };
2560
2583
  }
2561
2584
  return { end: false };
2562
2585
  }
@@ -3178,6 +3201,8 @@ async function runDevInProcess(opts) {
3178
3201
  process.stdin.pause();
3179
3202
  });
3180
3203
  }
3204
+ }
3205
+ if (rokuBuild || standalone) {
3181
3206
  const sessionId = handle.sessionId;
3182
3207
  const reportedWarnings = handle.reportedWarnings;
3183
3208
  let keepAlive;
@@ -4202,6 +4227,7 @@ export {
4202
4227
  formatBuildRowsHuman,
4203
4228
  listBuilds,
4204
4229
  readDevState,
4230
+ readDevStateFile,
4205
4231
  clearDevState,
4206
4232
  readMetroState,
4207
4233
  killOwnedMetro,