flowviant 0.55.1 → 0.55.2

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.
Files changed (2) hide show
  1. package/bin/cli.mjs +45 -5
  2. package/package.json +1 -1
package/bin/cli.mjs CHANGED
@@ -239,6 +239,11 @@ if (process.argv[2] === 'env') {
239
239
  // key. Same reasoning as the headless case, and the same answer.
240
240
  const interactive =
241
241
  Boolean(process.stdin.isTTY && process.stdout.isTTY) && process.env.FLOWVIANT_REEXEC !== '1';
242
+
243
+ /** How long the one-time binding confirm waits before serving unbound. A person
244
+ * who just typed `flowviant` answers in seconds; anything longer is a restart
245
+ * nobody is watching, and the machine must not sit dark for it. */
246
+ const CONFIRM_TIMEOUT_MS = 20_000;
242
247
  const externalToken = process.argv.includes('--fleet') || Boolean(process.env.FLOWVIANT_FLEET);
243
248
 
244
249
  /** Re-exec a plain `flowviant` after an inline login — the login command's own
@@ -321,17 +326,52 @@ if (!FLEET_TOKEN) {
321
326
  // ONE stored project, never tied to a repo — the pre-0.55.0 world. Ask once;
322
327
  // yes binds and every later start is silent. This is the exact question
323
328
  // whose absence had a calendar checkout serving skadooble.
329
+ //
330
+ // AND IT TIMES OUT, because a prompt on a start path is a way for a machine
331
+ // to go dark. `FLOWVIANT_REEXEC` above covers the restart THIS version
332
+ // performs, but it cannot cover the one that matters most: the hop that
333
+ // installs a fixed daemon is spawned by the OLD one, which never sets it.
334
+ // 0.55.0 → 0.55.1 was exactly that — an auto-update landing unattended would
335
+ // stop here with the machine serving nothing. A guard that only works once
336
+ // everyone already has it is not a guard.
337
+ //
338
+ // ON TIMEOUT WE SERVE, AND WE DO NOT BIND. Those are two decisions:
339
+ // · SERVE, because it is what every version before 0.55.0 did with this
340
+ // exact store, so the silent path is the status quo rather than a new
341
+ // risk — and a daemon that answers is strictly better than one that does
342
+ // not, which is the whole reason this product has exactly one refusal.
343
+ // · DO NOT BIND, because binding is the thing the question was FOR. Nobody
344
+ // answered, so nothing is cemented; the next human start asks again. That
345
+ // keeps the skadooble case fixed for the person who is actually looking,
346
+ // which is the only person it could ever have been fixed for.
324
347
  const creds = await import('./lib/credentials.mjs');
325
348
  const label = creds.projectLabel(CREDENTIAL.entry);
326
349
  const rl = (await import('node:readline/promises')).createInterface({
327
350
  input: process.stdin,
328
351
  output: process.stdout,
329
352
  });
330
- const raw = (
331
- await rl.question(`This machine's one connected project is ${label}. Serve this repo (${CREDENTIAL.repoRoot}) as ${label}? [Y/n] `)
332
- ).trim().toLowerCase();
333
- rl.close();
334
- if (raw === '' || raw === 'y' || raw === 'yes') {
353
+ const ac = new AbortController();
354
+ const timer = setTimeout(() => ac.abort(), CONFIRM_TIMEOUT_MS);
355
+ let raw = null; // null = nobody answered
356
+ try {
357
+ raw = (
358
+ await rl.question(
359
+ `This machine's one connected project is ${label}. Serve this repo (${CREDENTIAL.repoRoot}) as ${label}? [Y/n] `,
360
+ { signal: ac.signal }
361
+ )
362
+ ).trim().toLowerCase();
363
+ } catch {
364
+ /* aborted — nobody is at this terminal */
365
+ } finally {
366
+ clearTimeout(timer);
367
+ rl.close();
368
+ }
369
+ if (raw === null) {
370
+ console.log(
371
+ `\n no answer in ${Math.round(CONFIRM_TIMEOUT_MS / 1000)}s — serving ${label} for this run ` +
372
+ `without tying it to this repo. Run \`flowviant\` here and answer to make it stick.`
373
+ );
374
+ } else if (raw === '' || raw === 'y' || raw === 'yes') {
335
375
  creds.bindStoredRepo(CREDENTIAL.entry.projectId, CREDENTIAL.repoRoot);
336
376
  } else {
337
377
  console.error(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flowviant",
3
- "version": "0.55.1",
3
+ "version": "0.55.2",
4
4
  "description": "Run your own coding CLIs as build agents for Flowviant \u2014 Claude Code, Codex or Antigravity, on your own credentials. Holds your sessions, keeps a worktree per tab, and ships branches on your word.",
5
5
  "type": "module",
6
6
  "bin": {