neagen 0.1.4 → 0.1.5

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.
@@ -85,7 +85,7 @@ export async function runDeviceGrantLogin({ host, profile, renderer }) {
85
85
 
86
86
  ui.renderLine(`Your code: ${code.user_code}`, "info");
87
87
  ui.renderLine(code.verification_uri_complete, "info");
88
- ui.renderLine("Opening your browser create or sign in, then approve…", "info");
88
+ ui.renderLine("Opening your browser. Create or sign in, then approve…", "info");
89
89
  // Mirror to stderr so login is never silent if the panel hasn't painted yet.
90
90
  console.error(
91
91
  `\n Your code: ${code.user_code}\n Approve at: ${code.verification_uri_complete}\n\n` +
@@ -97,8 +97,18 @@ export async function runDeviceGrantLogin({ host, profile, renderer }) {
97
97
  const intervalMs = (code.interval ?? 5) * 1000;
98
98
  const deadline = Date.now() + (code.expires_in ?? 600) * 1000;
99
99
 
100
+ let lastReminderAt = Date.now();
100
101
  while (Date.now() < deadline) {
101
- ui.setStatus("Waiting for passkey approval…");
102
+ // Keep the code and remaining time visible so a failed browser-open never
103
+ // strands the user scrolling back for the URL.
104
+ const minutesLeft = Math.max(1, Math.ceil((deadline - Date.now()) / 60_000));
105
+ ui.setStatus(
106
+ `Waiting for passkey approval… code ${code.user_code}, ~${minutesLeft} min left`,
107
+ );
108
+ if (Date.now() - lastReminderAt >= 60_000) {
109
+ lastReminderAt = Date.now();
110
+ ui.renderLine(`Still waiting. Approve at: ${code.verification_uri_complete}`, "info");
111
+ }
102
112
  await new Promise((r) => setTimeout(r, intervalMs));
103
113
 
104
114
  const tokRes = await fetch(`${host}/api/auth/device/token`, {
@@ -129,7 +139,7 @@ export async function runDeviceGrantLogin({ host, profile, renderer }) {
129
139
  throw new Error(err.error_description ?? err.error ?? "device/token failed");
130
140
  }
131
141
 
132
- ui.renderLine("The code expired before approval. Run neagen again.", "error");
142
+ ui.renderLine("The code expired before approval. Run `neagen login` for a fresh one.", "error");
133
143
  throw new Error("device code expired");
134
144
  } finally {
135
145
  ui.setStatus(undefined);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neagen",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Your personal networking agent, in the terminal. Chat, agent-mail, and files against your Neagen — passkey login, no passwords.",
5
5
  "type": "module",
6
6
  "bin": {