infernoflow 0.38.2 → 0.38.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 +18 -0
- package/dist/lib/commands/login.mjs +1 -12
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -221,6 +221,24 @@
|
|
|
221
221
|
- v0.37.3 — remove Scarf, zero-dep install, no more Windows hang
|
|
222
222
|
- v0.37.3 — remove @scarf/scarf to fix Windows install hang
|
|
223
223
|
|
|
224
|
+
- v0.38.2 — fix login PKCE flow
|
|
225
|
+
- v0.38.1
|
|
226
|
+
- v0.38.0 — cloud login + auto-push to Supabase on every log
|
|
227
|
+
- v0.38.0 — cloud login, auto-push to Supabase on every log
|
|
228
|
+
- v0.37.4
|
|
229
|
+
- v0.37.3 — remove Scarf, zero-dep install, no more Windows hang
|
|
230
|
+
- v0.37.3 — remove @scarf/scarf to fix Windows install hang
|
|
231
|
+
|
|
232
|
+
- v0.38.4 — login via GitHub Device Flow, no redirects
|
|
233
|
+
- v0.38.3 — fix login: use implicit flow
|
|
234
|
+
- v0.38.2 — fix login PKCE flow
|
|
235
|
+
- v0.38.1
|
|
236
|
+
- v0.38.0 — cloud login + auto-push to Supabase on every log
|
|
237
|
+
- v0.38.0 — cloud login, auto-push to Supabase on every log
|
|
238
|
+
- v0.37.4
|
|
239
|
+
- v0.37.3 — remove Scarf, zero-dep install, no more Windows hang
|
|
240
|
+
- v0.37.3 — remove @scarf/scarf to fix Windows install hang
|
|
241
|
+
|
|
224
242
|
## 0.10.25 — 2026-04-22
|
|
225
243
|
|
|
226
244
|
### Added
|
|
@@ -1,12 +1 @@
|
|
|
1
|
-
import*as
|
|
2
|
-
<head><meta charset="utf-8"><title>infernoflow</title>
|
|
3
|
-
<style>body{font-family:system-ui;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;background:#0f172a;color:#f1f5f9;text-align:center}</style>
|
|
4
|
-
</head>
|
|
5
|
-
<body><div><div style="font-size:48px">\u{1F525}</div><h2>Logged in!</h2><p style="color:#94a3b8">You can close this tab and return to the terminal.</p></div></body>
|
|
6
|
-
</html>`),l.close(),r(m)):d?(e.end(`<!DOCTYPE html><html>
|
|
7
|
-
<head><meta charset="utf-8"><title>infernoflow</title>
|
|
8
|
-
<style>body{font-family:system-ui;display:flex;align-items:center;justify-content:center;height:100vh;margin:0;background:#0f172a;color:#f1f5f9;text-align:center}</style>
|
|
9
|
-
</head>
|
|
10
|
-
<body><div><h2>Login failed</h2><p style="color:#f87171">${d}</p></div></body>
|
|
11
|
-
</html>`),l.close(),a(new Error(d))):e.end(`<!DOCTYPE html><html><body style="background:#0f172a;color:#f1f5f9;font-family:system-ui;display:flex;align-items:center;justify-content:center;height:100vh;margin:0">
|
|
12
|
-
<p>Processing\u2026</p></body></html>`)});l.listen(w,"127.0.0.1",()=>{const t=new URLSearchParams({provider:"github",redirect_to:U,code_challenge:s,code_challenge_method:"S256"}),e=`${y}/auth/v1/authorize?${t.toString()}`;console.log(" Opening browser for GitHub login\u2026"),console.log(),console.log(` ${c("If the browser doesn't open, visit:")}`),console.log(` ${h(e)}`),console.log(),R(e),console.log(` ${c("Waiting for login\u2026")} ${c("(Ctrl+C to cancel)")}`)});const f=setTimeout(()=>{l.close(),a(new Error("Login timed out after 3 minutes"))},180*1e3);try{const t=await i;clearTimeout(f);const e=await B(t,o);if(e.status!==200||!e.body?.access_token)throw new Error(e.body?.error_description||e.body?.message||`Auth failed (${e.status})`);const n=e.body,g=await T(n.access_token),m={access_token:n.access_token,refresh_token:n.refresh_token||null,expires_at:n.expires_in?new Date(Date.now()+parseInt(n.expires_in)*1e3).toISOString():null,user:g,logged_in_at:new Date().toISOString()};A(m);const d=g?.user_metadata?.user_name||g?.email||"unknown";console.log(),console.log(` ${p("\u2714")} Logged in as ${u(d)}`),console.log(),console.log(` ${c("Session memory will now sync to the cloud on every")} ${h("infernoflow log")}`),console.log()}catch(t){clearTimeout(f);try{l.close()}catch{}console.log(),console.log(` ${$("\u2718")} Login failed: ${t.message}`),console.log(),process.exit(1)}}function v(){const o=O();console.log(),console.log(o?` ${p("\u2714")} Logged out. Local credentials removed.`:` ${c("Already logged out.")}`),console.log()}async function L(){const o=b();if(console.log(),!o?.access_token){console.log(` ${c("Not logged in.")} Run ${h("infernoflow login")}`),console.log();return}const s=o.user?.user_metadata?.user_name||o.user?.email||"unknown",r=o.user?.email||c("(no email)"),a=o.logged_in_at?new Date(o.logged_in_at).toLocaleDateString():"unknown",i=!S();console.log(` ${u("\u{1F525} infernoflow")} \u2014 logged in as:`),console.log(),console.log(` User: ${u(s)}`),console.log(` Email: ${r}`),console.log(` Since: ${c(a)}`),console.log(i?` Status: ${P("\u26A0 Token expired \u2014 run infernoflow login to refresh")}`:` Status: ${p("\u2714 Active")}`),console.log()}async function q(o){const s=o[1];return s==="logout"?v():s==="whoami"?L():I()}async function J(){return v()}async function z(){return L()}export{q as loginCommand,J as logoutCommand,z as whoamiCommand};
|
|
1
|
+
import*as w from"node:https";import{bold as i,cyan as d,gray as a,green as m,red as f}from"../ui/output.mjs";import{readCredentials as $,writeCredentials as S,deleteCredentials as k,isLoggedIn as b}from"../cloud/credentials.mjs";const h="Ov23liYuUKwDRTzrywsa";function y(o,n,s){return new Promise((r,u)=>{const g=new URLSearchParams(s).toString(),c={hostname:o,port:443,path:n,method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json","User-Agent":"infernoflow-cli","Content-Length":Buffer.byteLength(g)}},l=w.request(c,e=>{let t="";e.on("data",p=>t+=p),e.on("end",()=>{try{r(JSON.parse(t))}catch{r(t)}})});l.on("error",u),l.setTimeout(15e3,()=>l.destroy(new Error("timeout"))),l.write(g),l.end()})}function v(o,n,s){return new Promise((r,u)=>{const g={hostname:o,port:443,path:n,method:"GET",headers:{Accept:"application/json","User-Agent":"infernoflow-cli",Authorization:`Bearer ${s}`}},c=w.request(g,l=>{let e="";l.on("data",t=>e+=t),l.on("end",()=>{try{r(JSON.parse(e))}catch{r(e)}})});c.on("error",u),c.setTimeout(1e4,()=>c.destroy(new Error("timeout"))),c.end()})}function _(o){return new Promise(n=>setTimeout(n,o))}function A(o){try{const{execSync:n}=require("child_process"),s=process.platform==="win32"?`start "" "${o}"`:process.platform==="darwin"?`open "${o}"`:`xdg-open "${o}"`;n(s,{stdio:"ignore"})}catch{}}async function T(){if(b()){const e=$(),t=e?.user?.login||e?.user?.name||"unknown";console.log(),console.log(` ${m("\u2714")} Already logged in as ${i(t)}`),console.log(` Run ${d("infernoflow logout")} to sign out.`),console.log();return}console.log(),console.log(` ${i("\u{1F525} infernoflow login")}`),console.log();let o;try{o=await y("github.com","/login/device/code",{client_id:h,scope:"read:user user:email"})}catch(e){console.log(` ${f("\u2718")} Could not reach GitHub: ${e.message}`),console.log(),process.exit(1)}o.device_code||(console.log(` ${f("\u2718")} GitHub error: ${JSON.stringify(o)}`),console.log(),process.exit(1));const{device_code:n,user_code:s,verification_uri:r,expires_in:u,interval:g}=o,c=(g||5)*1e3;console.log(` ${i("Open this URL in your browser:")}`),console.log(` ${d(r)}`),console.log(),console.log(` ${i("Enter this code:")}`),console.log(` ${i(d(s))}`),console.log(),A(r),console.log(` ${a("Waiting for you to authorize\u2026")} ${a("(Ctrl+C to cancel)")}`),console.log();const l=Date.now()+(u||900)*1e3;for(;Date.now()<l;){await _(c);let e;try{e=await y("github.com","/login/oauth/access_token",{client_id:h,device_code:n,grant_type:"urn:ietf:params:oauth:grant-type:device_code"})}catch{continue}if(e.error!=="authorization_pending"){if(e.error==="slow_down"){await _(5e3);continue}if(e.error==="expired_token"&&(console.log(` ${f("\u2718")} Code expired. Run infernoflow login again.`),process.exit(1)),e.error==="access_denied"&&(console.log(` ${f("\u2718")} Access denied.`),process.exit(1)),e.access_token){const t=await v("api.github.com","/user",e.access_token),p=t?.login||t?.name||"unknown",L={access_token:e.access_token,refresh_token:null,expires_at:null,user:t,logged_in_at:new Date().toISOString()};S(L),console.log(` ${m("\u2714")} Logged in as ${i(p)}`),console.log(),console.log(` ${a("Session memory will now sync to the cloud on every")} ${d("infernoflow log")}`),console.log();return}}}console.log(` ${f("\u2718")} Login timed out. Run infernoflow login to try again.`),process.exit(1)}function x(){const o=k();console.log(),console.log(o?` ${m("\u2714")} Logged out. Local credentials removed.`:` ${a("Already logged out.")}`),console.log()}function C(){const o=$();if(console.log(),!o?.access_token){console.log(` ${a("Not logged in.")} Run ${d("infernoflow login")}`),console.log();return}const n=o.user?.login||o.user?.name||"unknown",s=o.user?.email||a("(no email)"),r=o.logged_in_at?new Date(o.logged_in_at).toLocaleDateString():"unknown";console.log(` ${i("\u{1F525} infernoflow")} \u2014 logged in as:`),console.log(),console.log(` User: ${i(n)}`),console.log(` Email: ${s}`),console.log(` Since: ${a(r)}`),console.log(` Status: ${m("\u2714 Active")}`),console.log()}async function R(o){const n=o[1];return n==="logout"?x():n==="whoami"?C():T()}async function U(){return x()}async function E(){return C()}export{R as loginCommand,U as logoutCommand,E as whoamiCommand};
|
package/package.json
CHANGED