@lunora/cli 1.0.0-alpha.144 → 1.0.0-alpha.146

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 (62) hide show
  1. package/dist/bin.mjs +1 -1
  2. package/dist/index.d.mts +5 -0
  3. package/dist/index.d.ts +5 -0
  4. package/dist/index.mjs +1 -1
  5. package/dist/packem_chunks/handler.mjs +1 -1
  6. package/dist/packem_chunks/handler10.mjs +1 -1
  7. package/dist/packem_chunks/handler11.mjs +1 -1
  8. package/dist/packem_chunks/handler12.mjs +2 -2
  9. package/dist/packem_chunks/handler13.mjs +2 -2
  10. package/dist/packem_chunks/handler14.mjs +1 -1
  11. package/dist/packem_chunks/handler15.mjs +1 -1
  12. package/dist/packem_chunks/handler16.mjs +1 -1
  13. package/dist/packem_chunks/handler17.mjs +1 -1
  14. package/dist/packem_chunks/handler18.mjs +2 -2
  15. package/dist/packem_chunks/handler19.mjs +1 -1
  16. package/dist/packem_chunks/handler2.mjs +1 -1
  17. package/dist/packem_chunks/handler20.mjs +1 -1
  18. package/dist/packem_chunks/handler21.mjs +2 -2
  19. package/dist/packem_chunks/handler22.mjs +1 -1
  20. package/dist/packem_chunks/handler23.mjs +1 -1
  21. package/dist/packem_chunks/handler24.mjs +1 -1
  22. package/dist/packem_chunks/handler25.mjs +8 -9
  23. package/dist/packem_chunks/handler3.mjs +2 -2
  24. package/dist/packem_chunks/handler4.mjs +1 -1
  25. package/dist/packem_chunks/handler5.mjs +1 -1
  26. package/dist/packem_chunks/handler6.mjs +1 -1
  27. package/dist/packem_chunks/handler7.mjs +1 -1
  28. package/dist/packem_chunks/handler8.mjs +1 -1
  29. package/dist/packem_chunks/handler9.mjs +3 -3
  30. package/dist/packem_chunks/planDevCommand.mjs +6 -6
  31. package/dist/packem_chunks/runCodegenCommand.mjs +1 -1
  32. package/dist/packem_chunks/runDeployCommand.mjs +1 -1
  33. package/dist/packem_chunks/runInitCommand.mjs +52 -52
  34. package/dist/packem_chunks/runMigrateGenerateCommand.mjs +4 -4
  35. package/dist/packem_chunks/runResetCommand.mjs +1 -1
  36. package/dist/packem_chunks/runRpcCommand.mjs +1 -1
  37. package/dist/packem_shared/{COMMANDS-C7e5qiYV.mjs → COMMANDS-smh_Sw-C.mjs} +1 -1
  38. package/dist/packem_shared/DEFAULT_IMPORT_BATCH_SIZE-DSLYaBzg.mjs +9 -0
  39. package/dist/packem_shared/{admin-token-DV5A9T5b.mjs → admin-token-BKmc3AUm.mjs} +1 -1
  40. package/dist/packem_shared/{cli-DdEKv4ng.mjs → cli-CIFLIzNi.mjs} +2 -2
  41. package/dist/packem_shared/{command-Bjv4VmYA.mjs → command-0l-ZPhIX.mjs} +1 -1
  42. package/dist/packem_shared/{commands-BvfzxKAa.mjs → commands-CG9qEtqR.mjs} +5 -5
  43. package/dist/packem_shared/createLogger-BoSxdb2T.mjs +2 -0
  44. package/dist/packem_shared/detect-package-manager-DXDstphE.mjs +1 -0
  45. package/dist/packem_shared/{diffSnapshots-9bDd9nOK.mjs → diffSnapshots-BbwCuhoN.mjs} +2 -2
  46. package/dist/packem_shared/{lint-ignore-report-CSeEIMkV.mjs → lint-ignore-report-CKDXv9MQ.mjs} +1 -1
  47. package/dist/packem_shared/open-url-zbbAo_D7.mjs +1 -0
  48. package/dist/packem_shared/output-format-Cv3aLqhP.mjs +2 -0
  49. package/dist/packem_shared/{post-codegen-hook-reEtIN59.mjs → post-codegen-hook-DhL1RH5u.mjs} +1 -1
  50. package/dist/packem_shared/runAddCommand-a_rW768_.mjs +1 -0
  51. package/dist/packem_shared/{schemaIrToSnapshot-Clwd2A8e.mjs → schemaIrToSnapshot-Dahp39qH.mjs} +1 -1
  52. package/dist/packem_shared/tui-prompts-BU3irGxV.mjs +4 -0
  53. package/dist/packem_shared/{wrangler-secrets-DzYgUxU-.mjs → wrangler-secrets-D0Tv5GWn.mjs} +1 -1
  54. package/package.json +3 -3
  55. package/skills/lunora-realtime/SKILL.md +15 -0
  56. package/dist/packem_shared/DEFAULT_IMPORT_BATCH_SIZE-xn-frBqK.mjs +0 -12
  57. package/dist/packem_shared/createLogger--C3x1FNE.mjs +0 -2
  58. package/dist/packem_shared/detect-package-manager-D9r2z_X6.mjs +0 -1
  59. package/dist/packem_shared/open-url-CTU_g9gr.mjs +0 -1
  60. package/dist/packem_shared/output-format-D7cKB-O5.mjs +0 -2
  61. package/dist/packem_shared/runAddCommand-oQMYPkp6.mjs +0 -1
  62. package/dist/packem_shared/tui-prompts-CCt3jm1k.mjs +0 -4
@@ -167,6 +167,13 @@ schema + functions into live TanStack DB collections). Reach for it when the app
167
167
  needs client-side indexes/joins or a persistent optimistic outbox; raw `useQuery`
168
168
  /`useMutation` are enough for straightforward live lists.
169
169
 
170
+ Call `defineCollections` **once** at module scope and treat the returned
171
+ collections as the single source of truth for each table. Don't mirror rows into
172
+ a parallel store, and never build derived indexes (trees, search, undo captures)
173
+ from a copy — optimistic writes and sync deltas land only on the Lunora
174
+ collection, so code reading a copy silently reads stale rows while `useLiveQuery`
175
+ renders fresh data.
176
+
170
177
  ## Common Pitfalls
171
178
 
172
179
  1. **Creating `LunoraClient` inside a component.** It re-opens the socket every
@@ -178,6 +185,12 @@ needs client-side indexes/joins or a persistent optimistic outbox; raw `useQuery
178
185
  4. **Optimistic shape drift.** The provisional value must match the query's
179
186
  element shape (including `_id`/`_creationTime`) or the UI flickers when the
180
187
  real delta lands.
188
+ 5. **Two sources of truth for the same rows.** `defineCollections` more than once
189
+ per table (or a parallel store of your own) mints copies that drift. Reads
190
+ through `useLiveQuery` look fine, but derived indexes built from the copy can
191
+ **miss rows** — rows written to the collection after the copy was taken never
192
+ appear in the index — or **hold stale rows** — rows updated or deleted in the
193
+ collection still show their old value. One instance, one collection per table.
181
194
 
182
195
  ## Checklist
183
196
 
@@ -188,3 +201,5 @@ needs client-side indexes/joins or a persistent optimistic outbox; raw `useQuery
188
201
  - [ ] Query `args` scoped narrowly to avoid over-broad re-renders.
189
202
  - [ ] Pagination via `usePaginatedQuery`/`useInfiniteQuery` over `.paginate`.
190
203
  - [ ] Considered `@lunora/db` if the app needs local indexes/joins or an outbox.
204
+ - [ ] `@lunora/db`: one `defineCollections` instance; no parallel copy of rows;
205
+ derived indexes built from the same collection the UI renders.
@@ -1,12 +0,0 @@
1
- import{createWriteStream as P,createReadStream as E}from"node:fs";import{unlink as _,stat as v,readdir as A}from"node:fs/promises";import{join as R}from"node:path";import{LunoraError as N}from"@lunora/errors";import{l as j}from"./admin-token-DV5A9T5b.mjs";import{u as C}from"./admin-url-Ca-KI3d_.mjs";const L="/_lunora/admin/export",q="/_lunora/admin/import",U=500,z=t=>{if(t===void 0)return;const r=t.split(",").map(o=>o.trim()).filter(o=>o.length>0);return r.length>0?r:void 0},k=async(t,r)=>{t.write(r)||await new Promise(o=>{t.once("drain",o)})},B=async(t,r)=>{const o=t.getReader(),e=new TextDecoder;let n=0,a=0,i="",l=!1;try{for(;!l;){const u=await o.read();if(l=u.done,u.value===void 0)continue;n+=u.value.length,i+=e.decode(u.value,{stream:!0});let d=i.indexOf(`
2
- `);for(;d!==-1;){a+=1;const g=`${i.slice(0,d)}
3
- `;await k(r,g),i=i.slice(d+1),d=i.indexOf(`
4
- `)}}return i.length>0&&(a+=1,await k(r,`${i}
5
- `)),{bytes:n,rows:a}}finally{o.releaseLock()}},F=async(t,r)=>{if(r!==void 0){t.destroy();try{await _(r)}catch{}}},ot=async t=>{if(t.prod&&t.url===void 0)return t.logger.error("--prod requires an explicit --url (refusing to export from the implicit localhost worker)"),{bytes:0,code:1,rows:0};const r=C(t.url,t.logger,t.cwd);if(r===void 0)return{bytes:0,code:1,rows:0};const{token:o}=j({cwd:t.cwd??process.cwd(),token:t.token,url:r});if(!o)return t.logger.error("admin token required — pass --token, set LUNORA_ADMIN_TOKEN, or add it to .dev.vars (local targets only)"),{bytes:0,code:1,rows:0};const e=`${r}${L}`,n=z(t.tables),a=t.fetchImpl??globalThis.fetch;if(typeof a!="function")throw new TypeError("no fetch implementation available — pass fetchImpl or run on Node >= 18");t.logger.info(`POST ${e} -> export${n?` (tables: ${n.join(",")})`:""}`);const i=await a(e,{body:JSON.stringify(n?{tables:n}:{}),headers:{authorization:`Bearer ${o}`,"content-type":"application/json"},method:"POST"});if(!i.ok){const p=await i.text();return t.logger.error(`export failed: HTTP ${String(i.status)}: ${p}`),{bytes:0,code:1,rows:0}}if(!i.body)return t.logger.error("export response carried no body"),{bytes:0,code:1,rows:0};const l=t.out===void 0||t.out==="-"?void 0:t.out,u=l===void 0?process.stdout:P(l,{encoding:"utf8"});let d,g;try{({bytes:d,rows:g}=await B(i.body,u))}catch(p){throw await F(u,l),p}return l!==void 0&&(await new Promise((p,b)=>{u.end(w=>{w?b(w):p()})}),t.logger.success(`wrote ${String(g)} rows to ${l} (${String(d)} bytes)`)),{bytes:d,code:0,rows:g}},H=async t=>{if(t.prod&&t.url===void 0){t.logger.error("--prod requires an explicit --url (refusing to import to the implicit localhost worker)");return}if(t.prod&&t.yes!==!0){t.logger.error("import --prod bulk-writes production. Re-run with --yes to confirm.");return}const r=C(t.url,t.logger,t.cwd);if(r===void 0)return;const{token:o}=j({cwd:t.cwd??process.cwd(),token:t.token,url:r});if(!o){t.logger.error("admin token required — pass --token, set LUNORA_ADMIN_TOKEN, or add it to .dev.vars (local targets only)");return}try{const n=await v(t.file);if(!n.isFile()&&!n.isDirectory()){t.logger.error(`not a file or directory: ${t.file}`);return}}catch(n){const a=n instanceof Error?n.message:String(n);t.logger.error(`failed to stat ${t.file}: ${a}`);return}const e=t.fetchImpl??globalThis.fetch;if(typeof e!="function")throw new TypeError("no fetch implementation available — pass fetchImpl or run on Node >= 18");return{fetchImpl:e,requestUrl:`${r}${q}`,token:o}},I="_storage",M=async t=>{if(!(await v(t).catch(()=>{}))?.isDirectory())return;const r=[];for(const o of await A(t,{withFileTypes:!0})){if(!o.isDirectory())continue;const e=R(t,o.name,"documents.jsonl");(await v(e).catch(()=>{}))?.isFile()&&r.push({file:e,table:o.name})}return r.length>0?r.toSorted((o,e)=>o.table.localeCompare(e.table)):void 0};async function*K(t,r){let o="";for await(const n of E(t,{encoding:"utf8"})){o+=typeof n=="string"?n:n.toString("utf8");let a=o.indexOf(`
6
- `);for(;a!==-1;){const i=o.slice(0,a).trim();o=o.slice(a+1),i.length>0&&(yield`${JSON.stringify({doc:JSON.parse(i),table:r})}
7
- `),a=o.indexOf(`
8
- `)}}const e=o.trim();e.length>0&&(yield`${JSON.stringify({doc:JSON.parse(e),table:r})}
9
- `)}async function*W(t,r){for(const{file:o,table:e}of t){if(e===I){r.warn(`skipping "${I}" — those rows describe stored files. Upload the exported blobs to R2 and re-point the keys.`);continue}yield*K(o,e)}}const Z=async t=>{const r=await M(t.file),o=await v(t.file);return r===void 0&&o.isDirectory()?(t.logger.error(`${t.file} is a directory but holds no <table>/documents.jsonl — expected a \`npx convex export --path <dir>\` dump, or pass an NDJSON file.`),{error:!0}):r&&t.table!==void 0?(t.logger.error("--table cannot be combined with a Convex export directory — each row's table comes from its source directory."),{error:!0}):{convexTables:r,error:!1}},G=(t,r)=>{for(const e of r.warnings)t.warn(e);const o=r.received-r.insertedTotal-r.conflicts-r.errorCount;o>0&&t.warn(`${String(o)} of ${String(r.received)} rows were neither inserted, conflicted, nor reported as errors`),t.success(`imported ${String(r.insertedTotal)} of ${String(r.received)} rows (${String(r.conflicts)} conflicts, ${String(r.errorCount)} errors)`)},et=async t=>{const r=await H(t);if(r===void 0)return{body:void 0,code:1,inserted:0};const{fetchImpl:o,requestUrl:e,token:n}=r,a=t.batchSize??U,i=await Z(t);if(i.error)return{body:void 0,code:1,inserted:0};const{convexTables:l}=i;t.logger.info(l?`POST ${e} -> import Convex export ${t.file} (${String(l.length)} tables)`:`POST ${e} -> import ${t.file}`);const u=l?W(l,t.logger):E(t.file,{encoding:"utf8"}),d={},g=[];let p=0,b=0;const w=[];let m="",h=[],$=0;const D=c=>{for(const[s,f]of Object.entries(c.inserted??{}))d[s]=(d[s]??0)+f;g.push(...c.errors??[]),p+=c.conflicts??0,b+=c.received??0;for(const s of c.warnings??[])w.includes(s)||w.push(s)},S=async()=>{if(h.length===0)return;const c=h.join(`
10
- `);h=[];const s=await o(e,{body:c,headers:{authorization:`Bearer ${n}`,"content-type":"application/x-ndjson"},method:"POST"});if(!s.ok){const y=await s.text().catch(()=>"<no body>");throw new N("INTERNAL",`import batch failed (HTTP ${String(s.status)}): ${y}`)}const f=await s.json();D(f)},x=c=>{const s=c.trim();if(s.length===0)return;if($+=1,t.table===void 0){h.push(s);return}let f;try{f=JSON.parse(s)}catch(y){const J=y instanceof Error?y.message:String(y);throw new N("INTERNAL",`invalid JSON on line ${String($)}: ${J}`,{cause:y})}h.push(JSON.stringify({doc:f,table:t.table}))};for await(const c of u){const s=typeof c=="string"?c:c.toString("utf8");m+=s;let f=m.indexOf(`
11
- `);for(;f!==-1;)x(m.slice(0,f)),m=m.slice(f+1),f=m.indexOf(`
12
- `),h.length>=a&&await S()}m.length>0&&x(m),await S();const O=Object.values(d).reduce((c,s)=>c+s,0),T={conflicts:p,errors:g,inserted:d,received:b,...w.length>0?{warnings:w}:{}};return t.logger.info(JSON.stringify(T,void 0,2)),G(t.logger,{conflicts:p,errorCount:g.length,insertedTotal:O,received:b,warnings:w}),{body:T,code:g.length>0?1:0,inserted:O}};export{U as DEFAULT_IMPORT_BATCH_SIZE,ot as runExportCommand,et as runImportCommand};
@@ -1,2 +0,0 @@
1
- import{STEP_BADGE_NAMES as p,LunoraReporter as u}from"@lunora/config";import{JsonReporter as g}from"@visulima/pail/reporter/json";import{createPail as l}from"@visulima/pail/server";let n,a=!1,t;const d=()=>{if(a)return!0;const r=process.env.LUNORA_LOG_JSON;return r==="1"||r==="true"},c=r=>new r,f=()=>a?[c(g)]:t!==void 0&&t.length>0?t:[c(d()?g:u)],v=()=>{a||(a=!0,n=void 0)},S={compose:(...r)=>r,console:()=>c(u),json:()=>c(g)},y=r=>{t=Array.isArray(r)?r:[r],n=void 0},m=Object.fromEntries(p.map(r=>[r,{label:r,logLevel:"informational"}])),o=()=>(n??=l({reporters:f(),scope:["lunora"],stderr:process.stderr,stdout:process.stdout,types:m}),n),A=()=>({debug:r=>{o().debug(r)},error:r=>{o().error(r)},info:r=>{o().info(r)},success:r=>{o().success(r)},warn:r=>{o().warn(r)}}),P=()=>{const r=(e,s)=>{process.stderr.write(`${e} ${s}
2
- `)};return{debug:e=>{r("debug",e)},error:e=>{r("error",e)},info:e=>{r("info ",e)},success:e=>{r("ok ",e)},warn:e=>{r("warn ",e)}}},E=new Proxy({},{get(r,e){const s=o(),i=s[e];return typeof i=="function"?i.bind(s):i}}),O=(r,e)=>{o()[r](e)};export{y as configureLogHandlers,A as createLogger,P as createStderrLogger,v as forceJsonLogging,o as getPail,S as logHandlers,O as logStep,E as pail};
@@ -1 +0,0 @@
1
- import{spawnSync as m}from"node:child_process";import{LunoraError as o}from"@lunora/errors";import{findPackageManagerSync as t,identifyInitiatingPackageManager as c}from"@visulima/package/package-manager";const d=["pnpm","bun","yarn","npm"],p=new Set(["bun","npm","pnpm","yarn"]),s=n=>p.has(n),i=n=>{try{return m(n,["--version"],{stdio:"ignore",timeout:5e3}).status===0}catch{return!1}},u=(n=i)=>d.filter(a=>n(a)),y=n=>({args:["install"],command:n}),b=(n,a,r={})=>{const e=r.dev===!0;return n==="npm"?{args:["install",...e?["--save-dev"]:[],...a],command:"npm"}:n==="bun"?{args:["add",...e?["-d"]:[],...a],command:"bun"}:{args:["add",...e?["-D"]:[],...a],command:n}},k=n=>{try{return t(n).packageManager}catch{}const a=c();if(a!==void 0){const e=a.name==="cnpm"?"npm":a.name;if(s(e))return e}const[r]=u();if(r!==void 0)return r;throw new o("INTERNAL","Could not detect a package manager: no lock file or `packageManager` field was found, and none (pnpm, bun, yarn, npm) is installed on PATH.")},v=(n,a,r)=>n==="yarn"?{args:[a,...r],command:"yarn"}:n==="bun"?{args:["x",a,...r],command:"bun"}:n==="npm"?{args:["--",a,...r],command:"npx"}:{args:["exec",a,...r],command:"pnpm"},w=(n,a)=>({args:["run",a],command:n}),M=(n,a)=>n==="npm"?`npm run ${a}`:n==="bun"?`bun run ${a}`:`${n} ${a}`;export{v as M,b as P,M as f,w as k,k as l,y as p,u as t};
@@ -1 +0,0 @@
1
- import{spawn as s}from"node:child_process";import{platform as a}from"node:os";import{LunoraError as n}from"@lunora/errors";const i=()=>{const e=a();return e==="darwin"?{args:[],command:"open"}:e==="win32"?{args:["/c","start",""],command:"cmd"}:{args:[],command:"xdg-open"}},d=e=>e.replaceAll("%","%25").replaceAll("&","%26").replaceAll("|","%7C").replaceAll("^","%5E").replaceAll("<","%3C").replaceAll(">","%3E").replaceAll("(","%28").replaceAll(")","%29").replaceAll('"',"%22").replaceAll("!","%21"),w=e=>new Promise((o,r)=>{const{args:t,command:c}=i(),p=a()==="win32"?d(e):e,l=s(c,[...t,p],{detached:!0,stdio:"ignore"});l.once("error",m=>{r(m)}),l.once("spawn",()=>{l.unref(),o()})}),h=async(e,o={})=>{let r;try{r=new URL(e)}catch{throw new n("INTERNAL",`Invalid URL: ${e}`)}if(r.protocol!=="http:"&&r.protocol!=="https:")throw new n("INTERNAL",`Refusing to open non-http(s) URL: ${e}`);await(o.opener??w)(e)};export{h as f};
@@ -1,2 +0,0 @@
1
- import{createStderrLogger as o}from"./createLogger--C3x1FNE.mjs";const e=new Set(["json","pretty"]),i=(t,r)=>{if(r!==void 0&&!e.has(r))return`${t}: unknown --format "${r}" — expected pretty | json`},s=t=>t==="json",d=(t,r)=>s(t)?o():r,p=t=>{process.stdout.write(`${JSON.stringify(t,void 0,2)}
2
- `)};export{p as d,i,s as r,d as s};
@@ -1 +0,0 @@
1
- import"node:fs";import"@visulima/path";import"./detect-package-manager-D9r2z_X6.mjs";import{I as i,F as t,R as s,E as p}from"./commands-BvfzxKAa.mjs";import"./buildRegistryIndex-DwySASBu.mjs";export{i as runAddCommand,t as runBuildIndexCommand,s as runListCommand,p as runRegistryViewCommand};
@@ -1,4 +0,0 @@
1
- import{jsx as t,jsxs as c}from"react/jsx-runtime";import{isInteractive as m,ACCENT as b,LUNA_ART as oe,LUNA_NAME as se,LUNA_SIGNOFF as ce,BADGE_COLUMN_WIDTH as j,badgeLead as de,padBadge as ue,badgeWidth as K}from"@lunora/config";import{render as V}from"@visulima/tui";import"@visulima/tui/components/big-text";import{Box as d}from"@visulima/tui/components/box";import{CommandPalette as fe}from"@visulima/tui/components/command-palette";import{ConfirmInput as he}from"@visulima/tui/components/confirm-input";import{SelectInput as me}from"@visulima/tui/components/select-input";import{Spinner as ge}from"@visulima/tui/components/spinner";import{Text as o}from"@visulima/tui/components/text";import{TextInput as pe}from"@visulima/tui/components/text-input";import{useApp as $}from"@visulima/tui/hooks/use-app";import{useInput as W}from"@visulima/tui/hooks/use-input";import{useInterval as be}from"@visulima/tui/hooks/use-interval";import{useEffect as L,useState as x}from"react";import{P as Z}from"./prompt-cancelled-C8Sj7OqI.mjs";let H=!1;const F=()=>{H||(H=!0,process.getMaxListeners()<64&&process.setMaxListeners(64))},ve=({children:e,onCancel:r})=>{const{exit:n}=$();return W((a,l)=>{l.ctrl&&a==="c"&&(r(),n())}),e},z=e=>e instanceof Error?e:new Error(typeof e=="string"?e:"task failed"),J=10,we=8,I=({spec:e})=>c(o,{children:[t(o,{children:de(e.text)}),t(o,{backgroundColor:e.bg,bold:!0,color:e.fg,children:ue(e.text)})]}),ee=({badge:e,message:r})=>e===void 0?t(o,{bold:!0,children:r}):c(d,{children:[t(I,{spec:e}),t(o,{bold:!0,children:` ${r}`})]}),re=2,ne=" ".repeat(j-1),te=e=>" ".repeat(K(e)+1),xe=e=>e===void 0?re:K(e)+1,N=({badge:e,children:r,message:n})=>c(d,{flexDirection:"column",children:[t(ee,{badge:e,message:n}),t(d,{flexDirection:"column",marginLeft:xe(e),children:r})]}),S=({answer:e,badge:r,message:n})=>c(d,{flexDirection:"column",children:[t(ee,{badge:r,message:n}),e===""?null:t(o,{dimColor:!0,children:`${r===void 0?" ".repeat(re):te(r)}${e}`})]}),A=e=>{const{exit:r}=$(),[n,a]=x(void 0);return L(()=>{n!==void 0&&r()},[n,r]),{answer:n,submit:(l,i)=>{e(l),a(i)}}},$e=({children:e})=>{const{exit:r}=$();return L(()=>{r()},[r]),e},y=async e=>{F(),process.stdout.write(`
2
- `);const r=V(t($e,{children:e}));try{await r.waitUntilExit()}catch{}finally{r.unmount()}},rr=async(e,r,n)=>{if(!m())return;const a=n===void 0||n===""?[]:n.split(`
3
- `);await y(c(d,{flexDirection:"column",children:[c(d,{children:[t(I,{spec:e}),t(o,{bold:!0,children:` ${r}`})]}),a.map(l=>t(o,{dimColor:!0,children:`${te(e)}${l}`},l))]}))},G=async e=>{F(),process.stdout.write(`
4
- `);const r={value:!1},n=V(t(ve,{onCancel:()=>{r.value=!0},children:e}),{exitOnCtrlC:!1});try{await n.waitUntilExit()}finally{n.unmount()}if(r.value)throw new Z},k=async(e,r)=>{let n=r;return await G(e(a=>{n=a})),n},le=e=>e.description===void 0?e.label:`${e.label} — ${e.description}`,O=()=>{const{exit:e}=$();W((r,n)=>{n.escape&&e()})},ye=({badge:e,finish:r,initialIndex:n,message:a,options:l})=>{const{answer:i,submit:u}=A(r);return O(),i!==void 0?t(S,{answer:i,badge:e,message:a}):t(N,{badge:e,message:a,children:t(me,{accentColor:b,initialIndex:n,items:l.map(s=>({key:s.value,label:le(s),value:s.value})),limit:J,onSelect:s=>{u(s.value,l.find(f=>f.value===s.value)?.label??s.value)}})})},Ce=({badge:e,finish:r,message:n,options:a})=>{const{exit:l}=$(),{answer:i,submit:u}=A(r);return i!==void 0?t(S,{answer:i,badge:e,message:n}):t(N,{badge:e,message:n,children:t(fe,{accentColor:b,autoFocus:!0,commands:a.map(s=>({description:s.description,id:s.value,label:s.label})),limit:J,onCancel:()=>{l()},onSelect:s=>{u(s,a.find(f=>f.value===s)?.label??s)},placeholder:"Type to filter…"})})},nr=async(e,r,n)=>{if(!m()||r.length===0)return n?.default;const{badge:a}=n??{};if(r.length>we)return k(i=>t(Ce,{badge:a,finish:i,message:e,options:r}),n?.default);const l=n?.default===void 0?-1:r.findIndex(i=>i.value===n.default);return k(i=>t(ye,{badge:a,finish:i,initialIndex:l>=0?l:void 0,message:e,options:r}),n?.default)},De=({badge:e,defaultValue:r,finish:n,message:a,placeholder:l})=>{const{answer:i,submit:u}=A(n);return O(),i!==void 0?t(S,{answer:i,badge:e,message:a}):t(N,{badge:e,message:a,children:t(pe,{defaultValue:r,onSubmit:s=>{const f=s.trim()===""?r:s.trim();u(f,f)},placeholder:l})})},tr=async(e,r)=>{const n=r?.default??"";if(!m())return n;const{badge:a}=r??{};return k(l=>t(De,{badge:a,defaultValue:n,finish:l,message:e,placeholder:r?.placeholder}),n)},ke=({badge:e,defaults:r,finish:n,message:a,options:l})=>{const{answer:i,submit:u}=A(n),[s,f]=x(0),[g,C]=x(()=>new Set(r));return O(),W((p,v)=>{if(!(i!==void 0||l.length===0)){if(v.upArrow)f(h=>(h-1+l.length)%l.length);else if(v.downArrow)f(h=>(h+1)%l.length);else if(p===" "){const h=l[s];h!==void 0&&C(w=>{const E=new Set(w);return E.has(h.value)?E.delete(h.value):E.add(h.value),E})}else if(v.return){const h=l.filter(w=>g.has(w.value));u(h.map(w=>w.value),h.length>0?h.map(w=>w.label).join(", "):"none")}}}),i!==void 0?t(S,{answer:i,badge:e,message:a}):t(N,{badge:e,message:a,children:c(d,{flexDirection:"column",children:[t(o,{dimColor:!0,children:"space toggles · enter confirms · esc cancels"}),l.map((p,v)=>{const h=v===s;return t(o,{color:h?b:void 0,children:`${h?"▸ ":" "}${g.has(p.value)?"◼":"◻"} ${le(p)}`},p.value)})]})})},lr=async(e,r,n)=>{const a=n?.defaults??[];if(!m()||r.length===0)return[...a];const{badge:l}=n??{};return k(i=>t(ke,{badge:l,defaults:a,finish:i,message:e,options:r}),[...a])},Ie=({badge:e,defaultYes:r,finish:n,message:a})=>{const{answer:l,submit:i}=A(n);return l!==void 0?t(S,{answer:l,badge:e,message:a}):c(d,{children:[e===void 0?null:t(I,{spec:e}),t(o,{bold:!0,children:e===void 0?`${a} `:` ${a} `}),t(he,{defaultChoice:r?"confirm":"cancel",onCancel:()=>{i(!1,"No")},onConfirm:()=>{i(!0,"Yes")}})]})},Se=async(e,r)=>{const n=r?.defaultYes===!0;if(!m())return n;const{badge:a}=r??{};return k(l=>t(Ie,{badge:a,defaultYes:n,finish:l,message:e}),!1)},ar=()=>m()?e=>Se(e,{defaultYes:!0}):()=>Promise.resolve(!1),P="#c8a8ff",U="#d9c8ff",Ae="#6b5b9a",M=({moon:e,prefix:r,suffix:n})=>c(d,{children:[t(o,{color:P,dimColor:!0,children:r}),typeof e=="string"?t(o,{color:U,children:e}):e,n===void 0?null:t(o,{color:P,children:n})]}),Q=({left:e,right:r})=>c(o,{color:U,children:[e,t(o,{color:Ae,children:"●●"}),r]}),Ee=()=>c(d,{flexDirection:"column",paddingX:1,children:[t(M,{moon:".-‐-.",prefix:"· ✦ · ",suffix:" ✦"}),t(M,{moon:t(Q,{left:"/",right:"\\"}),prefix:" ✦ · ",suffix:" ·"}),t(M,{moon:t(Q,{left:"\\",right:"/"}),prefix:" . ✦ · "}),c(d,{children:[t(o,{bold:!0,color:b,children:" lunora init "}),t(o,{dimColor:!0,children:"· moonrise sequence"}),t(o,{color:U})]})]}),ir=async e=>{m()&&await y(c(d,{flexDirection:"column",children:[t(Ee,{}),t(d,{paddingX:1,children:t(o,{dimColor:!0,children:e})})]}))},Te=({label:e})=>c(d,{children:[t(o,{color:b,children:t(ge,{type:"dots"})}),c(o,{children:[" ",e]})]}),or=async(e,r)=>{if(!m())return r();F();const n=V(t(Te,{label:e}));try{return await r()}finally{n.unmount()}},sr=async()=>{m()&&await y(c(d,{paddingX:1,children:[t(o,{color:U,children:oe}),c(d,{flexDirection:"column",marginLeft:2,children:[t(o,{bold:!0,color:b,children:se}),t(o,{children:ce})]})]}))},Le="#06b6d4",_=" ".repeat(9),cr=async e=>{m()&&await y(t(o,{bold:!0,children:`${_}${e}`}))},dr=async e=>{m()&&await y(c(d,{children:[t(o,{color:Le,children:`${ne}◼`}),t(o,{children:` ${e}`})]}))},ur=async(e,r,n,a)=>{m()&&await y(c(d,{flexDirection:"column",children:[c(d,{children:[t(I,{spec:e}),t(o,{bold:!0,children:` ${r}`})]}),t(d,{flexDirection:"column",marginTop:1,children:n.map(l=>c(o,{children:[`${_}${l.lead} `,t(o,{color:b,children:l.code}),l.tail??""]},l.lead))}),t(d,{flexDirection:"column",marginTop:1,children:a.map(l=>c(o,{children:[`${_}${l.lead} `,t(o,{color:b,children:l.code}),l.tail??""]},l.lead))})]}))},T=" ".repeat(j-1),q="#a855f7",ae="#06b6d4",D=[q,"#9b51f6","#8a5cf6","#6f86f6","#4aa6ef","#2bb6dd","#12bcd0",ae],B=D.length-2,X=(e,r)=>Array.from({length:Math.max(0,e)},()=>r),R=[...X(D.length-1,q),...D,...X(D.length-1,ae),...D.toReversed()],Y=R.map((e,r)=>{const n=R.slice(r,r+B);return[...n,...X(B-n.length,q)]}),Ne=" ".repeat(Math.max(0,j-B)),ie=({label:e})=>{const[r,n]=x(0);be(()=>{n(l=>(l+1)%Y.length)},90);const a=Y[r%Y.length]??[];return c(o,{children:[Ne,a.map((l,i)=>t(o,{color:l,children:"█"},i)),` ${e}`]})},Ue=({label:e,status:r})=>r==="running"?t(o,{color:b,children:`${T}▶ ${e}`}):r==="failed"?t(o,{color:"red",children:`${T}✖ ${e}`}):r==="done"?t(o,{dimColor:!0,children:`${T}■ ${e}`}):t(o,{dimColor:!0,children:`${T}□ ${e}`}),Me=async(e,r)=>{const n=[];let a;for(const[l,i]of e.entries()){r(l,"running");try{n.push(await i.run()),r(l,"done")}catch(u){r(l,"failed"),a=u;break}}return{failure:a,results:n}},Ye=(e,r,n,a)=>{let l=!0;return Me(e,(i,u)=>{l&&r(s=>s.map((f,g)=>g===i?u:f))}).then(({failure:i,results:u})=>{setTimeout(()=>{l&&(n(u,i),a())},400)}).catch(()=>{}),()=>{l=!1}},_e=({end:e,onSettle:r,start:n,tasks:a})=>{const{exit:l}=$(),[i,u]=x(()=>a.map(()=>"pending"));L(()=>Ye(a,u,r,l),[l,r,a]);const s=i.length>0&&i.every(f=>f==="done");return c(d,{flexDirection:"column",children:[s?c(d,{children:[t(o,{bold:!0,color:"green",children:`${ne}✔`}),t(o,{bold:!0,color:"green",children:` ${e}`})]}):t(ie,{label:n}),a.map((f,g)=>t(Ue,{label:f.label,status:i[g]??"pending"},f.label))]})},fr=async(e,r)=>{if(!m()){const l=[];for(const i of e)l.push(await i.run());return l}let n=[],a;if(await G(t(_e,{end:r.end,onSettle:(l,i)=>{n=l,a=i},start:r.start,tasks:e})),a!==void 0)throw z(a);return n},Be=async(e,r)=>{const n=[];let a;for(const[l,i]of e.entries()){r(l);try{n.push(await i.task())}catch(u){a=u;break}}return{failure:a,values:n}},Xe=({badge:e,done:r,onSettle:n,steps:a})=>{const{exit:l}=$(),[i,u]=x(0),[s,f]=x(!1);return L(()=>{let g=!0,C;return Be(a,p=>{g&&u(p)}).then(({failure:p,values:v})=>{if(g){if(p!==void 0){n({error:p,ok:!1}),l();return}f(!0),C=setTimeout(()=>{g&&(n({ok:!0,values:v}),l())},400)}}).catch(()=>{}),()=>{g=!1,C!==void 0&&clearTimeout(C)}},[l,n,a]),s?c(d,{children:[t(I,{spec:e}),t(o,{bold:!0,children:` ${r}`})]}):t(ie,{label:a[i]?.running??""})},hr=async(e,r,n)=>{if(!m()){const l=[];for(const i of r)l.push(await i.task());return l}let a;if(await G(t(Xe,{badge:e,done:n,onSettle:l=>{a=l},steps:r})),a===void 0)throw new Z;if(!a.ok)throw z(a.error);return a.values};export{ar as $,nr as B,tr as C,or as H,lr as I,ir as M,fr as Q,cr as U,ur as W,dr as X,sr as Y,rr as h,Se as i,hr as t};