knarr 0.0.3 → 0.1.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.
Files changed (111) hide show
  1. package/README.md +1 -0
  2. package/dist/add-4Z3V5722.mjs +3 -0
  3. package/dist/bell-SIN4ERLS.mjs +2 -0
  4. package/dist/{check-YVEJEI2G.mjs → check-7CJHAF6Y.mjs} +1 -1
  5. package/dist/{chokidar-LVDD2IK4.mjs → chokidar-2G63V464.mjs} +1 -1
  6. package/dist/chunk-3SXN6MQL.mjs +4 -0
  7. package/dist/chunk-7GCKCCHU.mjs +3 -0
  8. package/dist/chunk-7ROQJISX.mjs +15 -0
  9. package/dist/chunk-AA43FODB.mjs +3 -0
  10. package/dist/chunk-ABG6UD3X.mjs +22 -0
  11. package/dist/chunk-BH2WXCLS.mjs +4 -0
  12. package/dist/chunk-COI7GWH3.mjs +4 -0
  13. package/dist/chunk-E3HZCU3S.mjs +5 -0
  14. package/dist/chunk-FSVETLZK.mjs +4 -0
  15. package/dist/{chunk-3KNUBUPH.mjs → chunk-G7HFTV5Y.mjs} +1 -1
  16. package/dist/chunk-GAWQLCRB.mjs +3 -0
  17. package/dist/{chunk-MBKCCWSD.mjs → chunk-HVN6HBWZ.mjs} +1 -1
  18. package/dist/{chunk-SYADAYF4.mjs → chunk-ICU4V73X.mjs} +1 -1
  19. package/dist/{chunk-XQPVRRTN.mjs → chunk-IP5ROSRE.mjs} +1 -1
  20. package/dist/chunk-J6HZHQVL.mjs +3 -0
  21. package/dist/chunk-L7O2RSTN.mjs +3 -0
  22. package/dist/chunk-M3TRMEJV.mjs +3 -0
  23. package/dist/chunk-MN4DV2NO.mjs +3 -0
  24. package/dist/chunk-N3B2JO4H.mjs +13 -0
  25. package/dist/{chunk-7HVPEBK5.mjs → chunk-NGPAGRK4.mjs} +1 -1
  26. package/dist/{chunk-B3DZ5HVQ.mjs → chunk-OQDZJP55.mjs} +1 -1
  27. package/dist/chunk-QEH5VHRO.mjs +13 -0
  28. package/dist/chunk-QFHYSC3K.mjs +3 -0
  29. package/dist/{chunk-CTJF2EWO.mjs → chunk-QHNHLR6T.mjs} +2 -2
  30. package/dist/chunk-RJSBXX2Q.mjs +3 -0
  31. package/dist/{chunk-NBSJGM2X.mjs → chunk-SPHWZS5P.mjs} +1 -1
  32. package/dist/chunk-U6O35NZ7.mjs +3 -0
  33. package/dist/chunk-UCSYKFEZ.mjs +3 -0
  34. package/dist/chunk-W2MMKBWU.mjs +3 -0
  35. package/dist/chunk-WBTSRLB6.mjs +7 -0
  36. package/dist/chunk-WN3DOKIM.mjs +3 -0
  37. package/dist/{chunk-TEFMLGCB.mjs → chunk-XDWZZBCM.mjs} +1 -1
  38. package/dist/{chunk-2GDRDQA5.mjs → chunk-Z5K6DFA6.mjs} +1 -1
  39. package/dist/clean-EJIYYQZM.mjs +3 -0
  40. package/dist/cli.mjs +4 -4
  41. package/dist/dev-PUNHH4MS.mjs +3 -0
  42. package/dist/doctor-ZK4OPSD4.mjs +6 -0
  43. package/dist/explain-BDTONX7H.mjs +5 -0
  44. package/dist/fs-NU36NNEG.mjs +2 -0
  45. package/dist/history-MLJHRV3Q.mjs +2 -0
  46. package/dist/index.d.ts +79 -18
  47. package/dist/index.mjs +1524 -443
  48. package/dist/init-X4F3XKVC.mjs +16 -0
  49. package/dist/{list-GLSA6I67.mjs → list-4PTHMIQ4.mjs} +2 -2
  50. package/dist/migrate-VHDLW6I7.mjs +8 -0
  51. package/dist/nextjs-config-T5D6LOJE.mjs +2 -0
  52. package/dist/preflight-IXICTR6G.mjs +2 -0
  53. package/dist/{publish-TAWTHPSD.mjs → publish-UGDDG6OT.mjs} +2 -2
  54. package/dist/push-V575ASM4.mjs +3 -0
  55. package/dist/remove-EPVDMWCS.mjs +2 -0
  56. package/dist/reset-5M6AU4FU.mjs +3 -0
  57. package/dist/restore-QPISOGEK.mjs +12 -0
  58. package/dist/rollback-CTGK7SXG.mjs +3 -0
  59. package/dist/{status-FA6UEHEF.mjs → status-3ZXM3CRH.mjs} +2 -2
  60. package/dist/{tailwind-source-RIWWXW2Y.mjs → tailwind-source-HCTY2XDU.mjs} +2 -2
  61. package/dist/topo-sort-ZNGR6D7M.mjs +2 -0
  62. package/dist/{tracker-JJEYXX45.mjs → tracker-QAKEXYUJ.mjs} +1 -1
  63. package/dist/update-RSPDDAJK.mjs +12 -0
  64. package/dist/use-LZ2GIXYZ.mjs +3 -0
  65. package/dist/vite-config-XOGAKYGQ.mjs +2 -0
  66. package/dist/watch-orchestrator-N6HZUDS3.mjs +3 -0
  67. package/dist/watcher-KOLIXRUG.mjs +3 -0
  68. package/dist/workspace-T6PNO4L3.mjs +2 -0
  69. package/dist/{xxhash-wasm-DTW44IIQ.mjs → xxhash-wasm-I6Q3T2SL.mjs} +1 -1
  70. package/package.json +4 -1
  71. package/dist/add-LZ6CZTHG.mjs +0 -3
  72. package/dist/bell-YD6IWNXO.mjs +0 -2
  73. package/dist/chunk-2VCW5RWI.mjs +0 -3
  74. package/dist/chunk-37AAX47E.mjs +0 -19
  75. package/dist/chunk-5BZD55UB.mjs +0 -3
  76. package/dist/chunk-7JG555TZ.mjs +0 -3
  77. package/dist/chunk-7SDPRKFT.mjs +0 -13
  78. package/dist/chunk-BS4VKVYH.mjs +0 -3
  79. package/dist/chunk-EE2UYGFD.mjs +0 -4
  80. package/dist/chunk-GO6F6AGH.mjs +0 -3
  81. package/dist/chunk-GQYG5FCW.mjs +0 -5
  82. package/dist/chunk-HEDVIVEO.mjs +0 -14
  83. package/dist/chunk-KOHUNKHP.mjs +0 -3
  84. package/dist/chunk-LXGALE74.mjs +0 -13
  85. package/dist/chunk-OPLSUHCD.mjs +0 -4
  86. package/dist/chunk-QGLOGD5G.mjs +0 -3
  87. package/dist/chunk-SFLWVTJC.mjs +0 -3
  88. package/dist/chunk-SN4TOUQW.mjs +0 -7
  89. package/dist/chunk-UBGMLVMB.mjs +0 -3
  90. package/dist/chunk-XKO24LUM.mjs +0 -3
  91. package/dist/chunk-ZJEEAMB3.mjs +0 -3
  92. package/dist/clean-ZD5GPGXQ.mjs +0 -3
  93. package/dist/dev-TMWMIT7W.mjs +0 -3
  94. package/dist/doctor-AXP7GVBM.mjs +0 -4
  95. package/dist/fs-2NITBGIO.mjs +0 -2
  96. package/dist/history-SKKGT225.mjs +0 -2
  97. package/dist/init-XK4B7XYG.mjs +0 -7
  98. package/dist/migrate-MW4BVLL2.mjs +0 -8
  99. package/dist/preflight-TVJFHRI2.mjs +0 -2
  100. package/dist/push-65ZZFZJY.mjs +0 -3
  101. package/dist/remove-LOBXHBMC.mjs +0 -2
  102. package/dist/reset-EAN5NVGM.mjs +0 -3
  103. package/dist/restore-YHZYT54B.mjs +0 -11
  104. package/dist/rollback-U3LQTWH5.mjs +0 -3
  105. package/dist/topo-sort-WEIVPJKN.mjs +0 -2
  106. package/dist/update-VOUKMOLK.mjs +0 -3
  107. package/dist/use-BXAZ5OP3.mjs +0 -3
  108. package/dist/vite-config-UWCLPTOZ.mjs +0 -2
  109. package/dist/watch-orchestrator-I2623SMT.mjs +0 -3
  110. package/dist/watcher-PTPUN2HE.mjs +0 -3
  111. package/dist/workspace-S3TAUSS3.mjs +0 -2
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ import {createRequire}from'node:module';import {G}from'./chunk-BH2WXCLS.mjs';import {a}from'./chunk-L7O2RSTN.mjs';import {readFile}from'fs/promises';globalThis.require=createRequire(import.meta.url);
3
+ function m(e){return e.match(/^(\s+)\S/m)?.[1]||" "}a(m,"detectIndent");function d(e){return e.includes("knarr/vite")||e.includes("vite-plugin-knarr")}a(d,"hasKnarrPlugin");async function $(e){try{let i=await readFile(e,"utf-8");return {configured:d(i)}}catch{return {configured:false,error:"could not read config file"}}}a($,"hasKnarrVitePlugin");function w(e){let i=/(^|[^A-Za-z0-9_$])defineConfig\s*\(/g,o;for(;(o=i.exec(e))!==null;){let f=o.index+o[0].length-1,t=1,n=f+1,s=false,l=false;for(;n<e.length&&t>0;){let r=e[n];if(l){l=false,n++;continue}if(r==="\\"){l=true,n++;continue}if(s){r===s&&(s=false),n++;continue}if(r==='"'||r==="'"||r==="`"){s=r,n++;continue}if(r==="/"&&e[n+1]==="/"){let c=e.indexOf(`
4
+ `,n);n=c===-1?e.length:c+1;continue}if(r==="/"&&e[n+1]==="*"){let c=e.indexOf("*/",n+2);n=c===-1?e.length:c+2;continue}if(r==="?"){let c=e[n+1];if(c==="."||c==="?"){n+=2;continue}return true}r==="("&&t++,r===")"&&t--,n++;}i.lastIndex=n;}return false}a(w,"defineConfigUsesTernary");function p(e){let i=[],o="",f=0;for(let n of e)if(n==="("&&f++,n===")"&&f--,n===","&&f===0){let s=o.trim();s&&i.push(s),o="";}else o+=n;let t=o.trim();return t&&i.push(t),i}a(p,"parsePluginItems");function h(e,i){return e.length===0?"[]":e.length===1?`[${e[0]}]`:`[
5
+ ${e.map(f=>`${i}${i}${f},`).join(`
6
+ `)}
7
+ ${i}]`}a(h,"formatPlugins");function x(e){let o=/plugins\s*:\s*\[/g.exec(e);if(!o)return null;let f=o.index+o[0].length-1,t=1,n=f+1,s=false,l=false;for(;n<e.length&&t>0;){let r=e[n];if(l){l=false,n++;continue}if(r==="\\"){l=true,n++;continue}if(s){r===s&&(s=false),n++;continue}if(r==='"'||r==="'"||r==="`"){s=r,n++;continue}if(r==="/"&&e[n+1]==="/"){let c=e.indexOf(`
8
+ `,n);n=c===-1?e.length:c+1;continue}if(r==="/"&&e[n+1]==="*"){let c=e.indexOf("*/",n+2);n=c===-1?e.length:c+2;continue}(r==="["||r==="("||r==="{")&&t++,(r==="]"||r===")"||r==="}")&&t--,n++;}return t!==0?null:{start:f,end:n,inner:e.slice(f+1,n-1)}}a(x,"findPluginsArray");function y(e){let i=0,o=/^import\s/gm,f;for(;(f=o.exec(e))!==null;){let t=f.index,n=t+f[0].length,s=false,l=0;for(;n<e.length;){let r=e[n];if(s){r===s&&(s=false),n++;continue}if(r==='"'||r==="'"||r==="`"){s=r,n++;continue}if(r==="{"&&l++,r==="}"&&l--,r===";"&&l<=0){n++;break}if(r===`
9
+ `&&l<=0){let c=e.slice(t,n).trimEnd();if(c.endsWith('"')||c.endsWith("'"))break}n++;}i=n;}return i}a(y,"findLastImportEnd");function k(e){return w(e)?{complex:true,reason:"conditional defineConfig"}:/export\s+default\s+function/.test(e)?{complex:true,reason:"dynamic export (function)"}:/plugins\s*:\s*\[\s*\.\.\./.test(e)?{complex:true,reason:"spread operator in plugins array"}:/defineConfig\s*\(\s*async/.test(e)||/mergeConfig\s*\(/.test(e)?{complex:true,reason:"async or merged config"}:{complex:false}}a(k,"isComplexConfig");async function R(e){let i;try{i=await readFile(e,"utf-8");}catch{return {modified:false,error:"could not read config file"}}if(d(i))return {modified:false};let o=k(i);if(o.complex)return {modified:false,error:`config too complex (${o.reason})`};let f=m(i),t=x(i);if(t){let l=p(t.inner);l.push("knarr()");let r=h(l,f);i=i.slice(0,t.start)+r+i.slice(t.end);}else {let r=/(?:defineConfig\s*\(\s*\{|export\s+default\s+\{)/.exec(i);if(r){let c=r.index+r[0].length,b=`
10
+ ${f}plugins: [knarr()],`;i=i.slice(0,c)+b+i.slice(c);}else return {modified:false,error:"unrecognized Vite config pattern"}}let n=`import knarr from "knarr/vite";
11
+ `,s=y(i);return s>0?i=i.slice(0,s)+`
12
+ `+n+i.slice(s):i=n+`
13
+ `+i,await G(e,i),{modified:true}}a(R,"addKnarrVitePlugin");async function O(e){let i;try{i=await readFile(e,"utf-8");}catch{return {modified:false}}if(!d(i))return {modified:false};let o=false,f=/^import\s+\w+\s+from\s+["']knarr\/vite["'];?\s*\n?/m;f.test(i)&&(i=i.replace(f,""),o=true);let t=x(i);if(t){let n=p(t.inner),s=n.filter(l=>!l.startsWith("knarr("));if(s.length!==n.length){let l=m(i),r=h(s,l);i=i.slice(0,t.start)+r+i.slice(t.end),o=true;}}return o&&await G(e,i),{modified:o}}a(O,"removeFromViteConfig");export{$ as a,k as b,R as c,O as d};
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import {createRequire}from'node:module';import {a as a$1}from'./chunk-W2MMKBWU.mjs';import {r,e,x,D,q as q$1,G as G$1,i,g as g$1,E,t,F}from'./chunk-BH2WXCLS.mjs';import {b}from'./chunk-OQDZJP55.mjs';import {a}from'./chunk-L7O2RSTN.mjs';import {readFile}from'fs/promises';import {dirname}from'path';globalThis.require=createRequire(import.meta.url);
3
+ async function J(e){let{state:r}=await g(e);return r}a(J,"readConsumerState");async function g(e$1){let r$1=r(e$1);try{let t=await readFile(r$1,"utf-8"),s=JSON.parse(t);return e(s)?{state:s,reliable:!0}:(b.warn(`Invalid consumer state in ${r$1}, using defaults`),{state:{version:"1",links:{}},reliable:!1})}catch(t){return x(t)&&t.code==="ENOENT"?{state:{version:"1",links:{}},reliable:true}:(b.warn(`Failed to read consumer state: ${t instanceof Error?t.message:String(t)}`),{state:{version:"1",links:{}},reliable:false})}}a(g,"readConsumerStateSafe");async function R(e,r$1){await D(q$1(e));let t=r(e);await G$1(t,JSON.stringify(r$1,null,2));}a(R,"writeConsumerState");async function q(e,r$1,t){let s=r(e);await a$1(s,async()=>{let{state:i,reliable:u}=await g(e);if(!u)throw new Error(`Consumer state in ${s} is corrupt \u2014 refusing to write to avoid destroying existing links. Delete .knarr/state.json and re-run 'knarr add' for each package.`);i.links[r$1]=t,await R(e,i);});}a(q,"addLink");async function A(e,r$1){let t=r(e);await a$1(t,async()=>{let{state:s,reliable:i}=await g(e);if(!i)throw new Error(`Consumer state in ${t} is corrupt \u2014 refusing to write to avoid destroying existing links. Delete .knarr/state.json and re-run 'knarr add' for each package.`);delete s.links[r$1],await R(e,s);});}a(A,"removeLink");async function B(e,r){return (await J(e)).links[r]??null}a(B,"getLink");async function d(){let e=i();try{let r=await readFile(e,"utf-8"),t=JSON.parse(r);return g$1(t)?t:(b.warn("Invalid consumers registry, using empty registry"),{})}catch(r){return x(r)&&r.code!=="ENOENT"&&b.warn(`Failed to read consumers registry: ${r instanceof Error?r.message:String(r)}`),{}}}a(d,"readConsumersRegistry");async function v(e){let r=i();await E(dirname(i())),await G$1(r,JSON.stringify(e,null,2));}a(v,"writeConsumersRegistry");async function G(e,r){let t$1=i();await a$1(t$1,async()=>{let s=await d();s[e]||(s[e]=[]);let i=t(r);s[e].includes(i)||s[e].push(i),await v(s);});}a(G,"registerConsumer");async function H(e,r){let t$1=i();await a$1(t$1,async()=>{let s=await d();if(!s[e])return;let i=t(r);s[e]=s[e].filter(u=>u!==i),s[e].length===0&&delete s[e],await v(s);});}a(H,"unregisterConsumer");async function Q(e){return (await d())[e]??[]}a(Q,"getConsumers");async function V(e={}){let r=i(),t=0,s=0,i$1=0,u=0;return await a$1(r,async()=>{let D=await d(),C={};for(let[k,b]of Object.entries(D)){let P=await Promise.all(b.map(async o=>{if(!await F(o))return {consumerPath:o,valid:false,reason:"missing-dir"};if(e.removeMissingLinks){let{state:F,reliable:$}=await g(o);if(!$)return u++,{consumerPath:o,valid:true,reason:"unreliable-state"};if(!F.links[k])return {consumerPath:o,valid:false,reason:"missing-link"}}return {consumerPath:o,valid:true,reason:null}})),f=P.filter(o=>o.valid).map(o=>o.consumerPath);t+=b.length-f.length,i$1+=P.filter(o=>o.reason==="missing-link").length,f.length>0?C[k]=f:s++;}await v(C);}),{removedConsumers:t,removedPackages:s,removedMissingLinks:i$1,skippedUnreliableConsumers:u}}a(V,"cleanStaleConsumers");export{J as a,g as b,R as c,q as d,A as e,B as f,d as g,G as h,H as i,Q as j,V as k};
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import {createRequire}from'node:module';import {n,d,z,m,H,h,j as j$1,k,E,l}from'./chunk-GQYG5FCW.mjs';import {b}from'./chunk-B3DZ5HVQ.mjs';import {a}from'./chunk-2VCW5RWI.mjs';import {readFile,readdir}from'fs/promises';import'path';globalThis.require=createRequire(import.meta.url);
3
- async function y(t,r){let s=n(t,r);try{let a=await readFile(s,"utf-8"),e=JSON.parse(a);return d(e)?e:(b.warn(`Invalid metadata for ${t}@${r}, ignoring`),null)}catch(a){return z(a)&&a.code!=="ENOENT"&&b.warn(`Failed to read metadata for ${t}@${r}: ${a instanceof Error?a.message:String(a)}`),null}}a(y,"readMeta");async function j(t,r){let s=m(t,r),a=await y(t,r);return !a||!await H(s)?null:{name:t,version:r,packageDir:s,meta:a}}a(j,"getStoreEntry");async function A(t){let r=h();if(!await H(r))return null;let s=j$1(t)+"@",e=(await readdir(r,{withFileTypes:true})).filter(n=>n.isDirectory()&&n.name.startsWith(s)),u=(await Promise.all(e.map(async n=>{let i=n.name.slice(s.length),c=await y(t,i);return c?{name:t,version:i,packageDir:m(t,i),meta:c}:null}))).filter(n=>n!==null);return u.length===0?null:u.reduce((n,i)=>new Date(i.meta.publishedAt).getTime()>new Date(n.meta.publishedAt).getTime()?i:n)}a(A,"findStoreEntry");async function J(){let t=h();if(!await H(t))return [];let s=(await readdir(t,{withFileTypes:true})).filter(e=>e.isDirectory()?e.name.lastIndexOf("@")>0:false);return (await Promise.all(s.map(async e=>{let l=e.name.lastIndexOf("@"),u=e.name.slice(0,l),n=e.name.slice(l+1),i=k(u),c=await y(i,n);return c?{name:i,version:n,packageDir:m(i,n),meta:c}:null}))).filter(e=>e!==null)}a(J,"listStoreEntries");async function W(t,r){await E(l(t,r));}a(W,"removeStoreEntry");export{y as a,j as b,A as c,J as d,W as e};
2
+ import {createRequire}from'node:module';import {n,d,x,m,F,h,j as j$1,k,C,l}from'./chunk-BH2WXCLS.mjs';import {b}from'./chunk-OQDZJP55.mjs';import {a}from'./chunk-L7O2RSTN.mjs';import {readFile,readdir}from'fs/promises';import'path';globalThis.require=createRequire(import.meta.url);
3
+ async function y(t,r){let s=n(t,r);try{let a=await readFile(s,"utf-8"),e=JSON.parse(a);return d(e)?e:(b.warn(`Invalid metadata for ${t}@${r}, ignoring`),null)}catch(a){return x(a)&&a.code!=="ENOENT"&&b.warn(`Failed to read metadata for ${t}@${r}: ${a instanceof Error?a.message:String(a)}`),null}}a(y,"readMeta");async function j(t,r){let s=m(t,r),a=await y(t,r);return !a||!await F(s)?null:{name:t,version:r,packageDir:s,meta:a}}a(j,"getStoreEntry");async function A(t){let r=h();if(!await F(r))return null;let s=j$1(t)+"@",e=(await readdir(r,{withFileTypes:true})).filter(n=>n.isDirectory()&&n.name.startsWith(s)),u=(await Promise.all(e.map(async n=>{let i=n.name.slice(s.length),c=await y(t,i);return c?{name:t,version:i,packageDir:m(t,i),meta:c}:null}))).filter(n=>n!==null);return u.length===0?null:u.reduce((n,i)=>new Date(i.meta.publishedAt).getTime()>new Date(n.meta.publishedAt).getTime()?i:n)}a(A,"findStoreEntry");async function J(){let t=h();if(!await F(t))return [];let s=(await readdir(t,{withFileTypes:true})).filter(e=>e.isDirectory()?e.name.lastIndexOf("@")>0:false);return (await Promise.all(s.map(async e=>{let l=e.name.lastIndexOf("@"),u=e.name.slice(0,l),n=e.name.slice(l+1),i=k(u),c=await y(i,n);return c?{name:i,version:n,packageDir:m(i,n),meta:c}:null}))).filter(e=>e!==null)}a(J,"listStoreEntries");async function W(t,r){await C(l(t,r));}a(W,"removeStoreEntry");export{y as a,j as b,A as c,J as d,W as e};
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import {createRequire}from'node:module';import {c,d as d$1}from'./chunk-ABG6UD3X.mjs';import {a as a$5}from'./chunk-XDWZZBCM.mjs';import {c as c$1}from'./chunk-WBTSRLB6.mjs';import {a as a$1}from'./chunk-MN4DV2NO.mjs';import {a as a$3}from'./chunk-HVN6HBWZ.mjs';import {b as b$1,a as a$4}from'./chunk-U6O35NZ7.mjs';import {e,i,a as a$2,f}from'./chunk-QFHYSC3K.mjs';import {d as d$2}from'./chunk-E3HZCU3S.mjs';import {d,b as b$2}from'./chunk-SPHWZS5P.mjs';import {b}from'./chunk-OQDZJP55.mjs';import {a}from'./chunk-L7O2RSTN.mjs';import {basename,resolve}from'path';globalThis.require=createRequire(import.meta.url);
3
+ var z={meta:{name:"remove",description:"Remove a Knarr-linked package and restore the original"},args:{package:{type:"positional",description:"Package name to remove",required:false},all:{type:"boolean",description:"Remove all linked packages",default:false},force:{type:"boolean",description:"Skip error checking",default:false},yes:{type:"boolean",alias:"y",description:"Skip confirmation prompts",default:false}},async run({args:o}){b$1();let e=new a$3,n=resolve(".");if(o.all){let u=await a$2(n),l=Object.entries(u.links);if(l.length===0){b.info("No linked packages to remove"),a$4({removed:0});return}if(!o.yes){let m=l.map(([c])=>c).join(", "),f=await b.prompt(`Remove ${l.length} linked package(s)? (${m})`,{type:"confirm"});if(!f||typeof f=="symbol"){b.info("Cancelled");return}}let s=0,i=0;for(let[m,f]of l)try{await E(n,m,f),s++;}catch(c){i++,b.warn(`Failed to remove ${m}: ${c instanceof Error?c.message:String(c)}`);}b.success(`Removed ${s} Knarr link(s)${i>0?`, ${i} failed`:""} in ${e.elapsed()}`),a$4({removed:s,failed:i,elapsed:e.elapsedMs()}),b$2()&&d$2();return}let r=o.package;r||(a$5("Package name required. Use --all to remove all linked packages."),process.exit(1));let t=await f(n,r);if(!t){if(o.force){b.warn(`Package "${r}" is not linked, skipping`),a$4({removed:0});return}a$5(`Package "${r}" is not linked in this project`),process.exit(1);}await E(n,r,t),b.success(`Removed Knarr link for ${r} in ${e.elapsed()}`),a$4({removed:1,package:r,elapsed:e.elapsedMs()}),b$2()&&d$2();}};async function E(o,e$1,n){d(`[remove] Removing ${e$1}`);let r=false;if(n.backupExists)try{r=await c(o,e$1,n.packageManager,n.version),r&&b.success(`Restored original ${e$1} from backup`);}catch(i){b.warn(`Failed to restore backup for ${e$1}: ${i instanceof Error?i.message:String(i)}. Run your package manager's install command to restore it.`);}r||await d$1(o,e$1,n.packageManager,n.version);let t=await a$1(o);t.type==="next"&&t.configFile&&(await c$1(t.configFile,e$1)).modified&&d(`[remove] Removed ${e$1} from ${basename(t.configFile)}`);let{findTailwindCss:u,removeTailwindSource:l}=await import('./tailwind-source-HCTY2XDU.mjs'),s=await u(o);if(s&&(await l(s,e$1)).modified&&d(`[remove] Removed @source for ${e$1} from ${basename(s)}`),await e(o,e$1),await i(e$1,o),t.type==="vite"&&t.configFile){let i=await a$2(o);if(Object.keys(i.links).length===0){let{removeFromViteConfig:m}=await import('./vite-config-XOGAKYGQ.mjs');(await m(t.configFile)).modified&&d(`[remove] Removed Knarr plugin from ${basename(t.configFile)}`);}}}a(E,"removeSinglePackage");export{z as a,E as b};
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import {createRequire}from'node:module';import {b}from'./chunk-B3DZ5HVQ.mjs';import {a as a$1}from'./chunk-2VCW5RWI.mjs';globalThis.require=createRequire(import.meta.url);
2
+ import {createRequire}from'node:module';import {b}from'./chunk-OQDZJP55.mjs';import {a as a$1}from'./chunk-L7O2RSTN.mjs';globalThis.require=createRequire(import.meta.url);
3
3
  var n=false,r=false,s=false;function l(){n=process.argv.includes("--verbose")||process.argv.includes("-v"),r=process.argv.includes("--dry-run"),s=process.argv.includes("--json"),n&&(b.level=4);}a$1(l,"initFlags");function c(){return r}a$1(c,"isDryRun");function a(){return s}a$1(a,"isJsonOutput");function p(t,...u){n&&b.debug(t,...u);}a$1(p,"verbose");export{l as a,c as b,a as c,p as d};
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import {createRequire}from'node:module';import {c as c$1,b as b$1}from'./chunk-E3HZCU3S.mjs';import {c,b}from'./chunk-SPHWZS5P.mjs';import {b as b$2}from'./chunk-OQDZJP55.mjs';import {a}from'./chunk-L7O2RSTN.mjs';globalThis.require=createRequire(import.meta.url);
3
+ function p(o){if(c()){if(b()){c$1(),o&&typeof o=="object"&&!Array.isArray(o)?console.log(JSON.stringify({...o,dryRun:true,mutations:b$1()},null,2)):console.log(JSON.stringify({data:o,dryRun:true,mutations:b$1()},null,2));return}console.log(JSON.stringify(o,null,2));}}a(p,"output");function m(){c()&&(b$2.level=-1);}a(m,"suppressHumanOutput");export{p as a,m as b};
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import {createRequire}from'node:module';import {a as a$1}from'./chunk-BH2WXCLS.mjs';import {a as a$2}from'./chunk-E3HZCU3S.mjs';import {b}from'./chunk-SPHWZS5P.mjs';import {a}from'./chunk-L7O2RSTN.mjs';import {spawn}from'child_process';import {platform}from'os';globalThis.require=createRequire(import.meta.url);
3
+ function d(e){return [e.executable,...e.args].join(" ")}a(d,"formatPackageManagerCommand");function k(e,a){if(a.length===0)throw new Error("No dependencies provided");for(let n of a)a$1(n);switch(e){case "pnpm":return {executable:"pnpm",args:["add",...a]};case "yarn":return {executable:"yarn",args:["add",...a]};case "bun":return {executable:"bun",args:["add",...a]};default:return {executable:"npm",args:["install",...a]}}}a(k,"buildInstallCommand");function M(e,a){switch(a$1(a),e){case "pnpm":return {executable:"pnpm",args:["add","-D",a]};case "yarn":return {executable:"yarn",args:["add","-D",a]};case "bun":return {executable:"bun",args:["add","-d",a]};default:return {executable:"npm",args:["install","-D",a]}}}a(M,"buildDevInstallCommand");function y(e,a){let n=d(e);return b()?(a$2({type:"command-skip",path:a,detail:n}),Promise.resolve(true)):new Promise(o=>{let m=platform()==="win32",i=spawn(e.executable,e.args,{cwd:a,stdio:"inherit",shell:m});i.on("close",g=>o(g===0)),i.on("error",()=>o(false));})}a(y,"runPackageManagerCommand");export{d as a,k as b,M as c,y as d};
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import {createRequire}from'node:module';import {x}from'./chunk-BH2WXCLS.mjs';import {a as a$1}from'./chunk-E3HZCU3S.mjs';import {b}from'./chunk-SPHWZS5P.mjs';import {a}from'./chunk-L7O2RSTN.mjs';import {mkdir,stat,rm}from'fs/promises';import {dirname}from'path';import {setTimeout}from'timers/promises';globalThis.require=createRequire(import.meta.url);
3
+ var r={retries:5,minTimeout:100,maxTimeout:1e3,factor:2,stale:3e4};async function F(i,s,w){if(b())return a$1({type:"lock-skip",path:i}),s();await mkdir(dirname(i),{recursive:true});let t=i+".lk",d=w?.stale??r.stale,m=false;for(let e=0;e<=r.retries;e++)try{await mkdir(t),m=!0;break}catch(o){if(x(o)&&o.code==="EEXIST"){try{let a=await stat(t);if(Date.now()-a.mtimeMs>d){await rm(t,{recursive:!0,force:!0});continue}}catch{continue}if(e<r.retries){let a=Math.min(r.minTimeout*r.factor**e,r.maxTimeout);await setTimeout(a);}}else throw o}if(!m)throw new Error(`Failed to acquire lock after ${r.retries} attempts. Another Knarr process may be running. If this persists, delete ${t} and retry.`);try{return await s()}finally{await rm(t,{recursive:true,force:true});}}a(F,"withFileLock");export{F as a};
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ import {createRequire}from'node:module';import {b as b$1}from'./chunk-QEH5VHRO.mjs';import {G}from'./chunk-BH2WXCLS.mjs';import {a}from'./chunk-L7O2RSTN.mjs';import {readFile}from'fs/promises';globalThis.require=createRequire(import.meta.url);
3
+ function x(e){return e.match(/^(\s+)\S/m)?.[1]||" "}a(x,"detectIndent");function g(e){let r=[],t=/['"]([^'"]*)['"]/g,n;for(;(n=t.exec(e))!==null;)r.push(n[1]);return r}a(g,"parseArrayItems");async function b(e,r){let t;try{t=await readFile(e,"utf-8");}catch{return {configured:false,error:"could not read config file"}}let s=/transpilePackages\s*:\s*\[([^\]]*)\]/s.exec(t);return s?{configured:g(s[1]).includes(r)}:{configured:false}}a(b,"hasTranspilePackage");function h(e,r){return e.length===0?"[]":e.length<=3?`[${e.map(n=>`'${n}'`).join(", ")}]`:`[
4
+ ${e.map(n=>`${r}${r}'${n}',`).join(`
5
+ `)}
6
+ ${r}]`}a(h,"formatArray");function y(e){let r=b$1(e);return r.complex?r:/(?:module\.exports\s*=\s*|export\s+default\s+)[\w.]+\s*\(\s*\{/.test(e)?{complex:true,reason:"wrapper function pattern"}:/\w+\s*\(\s*\w+\s*\(/.test(e)&&e.includes("module.exports")?{complex:true,reason:"chained wrapper functions"}:{complex:false}}a(y,"isComplexNextConfig");async function C(e,r){let t;try{t=await readFile(e,"utf-8");}catch{return {modified:false,error:"could not read config file"}}let n=y(t);if(n.complex)return {modified:false,error:`config too complex (${n.reason})`};let s=x(t),l=/transpilePackages\s*:\s*\[([^\]]*)\]/s,f=l.exec(t);if(f){let o=g(f[1]);if(o.includes(r))return {modified:false};o.push(r);let a=h(o,s),c=t.replace(l,`transpilePackages: ${a}`);return await G(e,c),{modified:true}}let u=[/module\.exports\s*=\s*\{/,/export\s+default\s+\{/,/(?:const|let|var)\s+\w*[Cc]onfig\w*\s*=\s*\{/];for(let o of u){let a=o.exec(t);if(a){let c=a.index+a[0].length,w=`
7
+ ${s}transpilePackages: ['${r}'],`,$=t.slice(0,c)+w+t.slice(c);return await G(e,$),{modified:true}}}return {modified:false,error:"unrecognized config pattern"}}a(C,"addToTranspilePackages");async function A(e,r){let t;try{t=await readFile(e,"utf-8");}catch{return {modified:false}}let n=x(t),s=/transpilePackages\s*:\s*\[([^\]]*)\]/s,l=s.exec(t);if(!l)return {modified:false};let f=g(l[1]),u=f.filter(c=>c!==r);if(u.length===f.length)return {modified:false};let o=h(u,n),a=t.replace(s,`transpilePackages: ${o}`);return await G(e,a),{modified:true}}a(A,"removeFromTranspilePackages");export{b as a,C as b,A as c};
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import {createRequire}from'node:module';import {a}from'./chunk-L7O2RSTN.mjs';import {readFile}from'fs/promises';import {join}from'path';globalThis.require=createRequire(import.meta.url);
3
+ async function f(e,r){let o=r==="npm"||r==="bun"?`${r} run `:`${r} `;try{let a=JSON.parse(await readFile(join(e,"package.json"),"utf-8")).scripts||{};for(let n of ["build","compile","bundle","tsc"])if(a[n])return `${o}${n}`}catch{}return null}a(f,"detectBuildCommand");export{f as a};
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import {createRequire}from'node:module';import {a,b}from'./chunk-B3DZ5HVQ.mjs';import {c as c$1,a as a$1}from'./chunk-2VCW5RWI.mjs';globalThis.require=createRequire(import.meta.url);
2
+ import {createRequire}from'node:module';import {a,b}from'./chunk-OQDZJP55.mjs';import {c as c$1,a as a$1}from'./chunk-L7O2RSTN.mjs';globalThis.require=createRequire(import.meta.url);
3
3
  var r=c$1(a(),1);var p=[{pattern:/not found in store/i,message:"Run 'knarr publish' in the package directory first, or use --from <path>."},{pattern:/is not linked/i,message:"Run 'knarr add <package>' to link it first."},{pattern:/No package\.json/i,message:"Make sure you're in a valid package directory with a package.json."},{pattern:/missing 'name'/i,message:"Add a 'name' field to your package.json."},{pattern:/missing 'version'/i,message:"Add a 'version' field to your package.json."},{pattern:/store entry missing/i,message:"Re-publish the package with 'knarr publish'."},{pattern:/EACCES|EPERM/i,message:"Permission denied. Try running with elevated privileges or check file ownership."},{pattern:/ENOSPC/i,message:"Disk is full. Free up some space and try again."},{pattern:/No publishable files/i,message:"Check the 'files' field in package.json, or ensure the build output exists."},{pattern:/private.*package/i,message:"Use --private flag to publish private packages."},{pattern:/Failed to read store entry/i,message:"The store may be corrupted. Try 'knarr clean' then re-publish."},{pattern:/Failed to acquire lock/i,message:"Another Knarr process may be running. Wait or delete stale .lk directories."},{pattern:/not a directory/i,message:"Check that the path exists and is a directory."},{pattern:/timed out/i,message:"Set KNARR_HOOK_TIMEOUT to a higher value (in ms) if your scripts need more time."},{pattern:/state.*corrupt|corrupt.*state/i,message:"Delete .knarr/state.json and re-run 'knarr add' for each package."},{pattern:/EBUSY/i,message:"A file is locked by another process (e.g. dev server). Stop the process and retry."},{pattern:/Invalid package name/i,message:"Package names must be non-empty. Use format: package-name or @scope/package-name."}];function c(a){b.error(a);for(let{pattern:s,message:i}of p)if(s.test(a)){b.info(`${r.default.dim("Suggestion:")} ${i}`);break}}a$1(c,"errorWithSuggestion");export{c as a};
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import {createRequire}from'node:module';import {a}from'./chunk-2VCW5RWI.mjs';globalThis.require=createRequire(import.meta.url);
2
+ import {createRequire}from'node:module';import {a}from'./chunk-L7O2RSTN.mjs';globalThis.require=createRequire(import.meta.url);
3
3
  function B(t){if(t===0)return "0 B";let o=["B","KB","MB","GB"],n=Math.min(Math.floor(Math.log(t)/Math.log(1024)),o.length-1),i=t/1024**n;return n===0?`${t} B`:`${i.toFixed(1)} ${o[n]}`}a(B,"formatBytes");export{B as a};
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import {createRequire}from'node:module';import {a as a$1}from'./chunk-Z5K6DFA6.mjs';import {d as d$1,e}from'./chunk-QHNHLR6T.mjs';import {a}from'./chunk-HVN6HBWZ.mjs';import {b,a as a$2}from'./chunk-U6O35NZ7.mjs';import'./chunk-NGPAGRK4.mjs';import {k,g,b as b$2}from'./chunk-QFHYSC3K.mjs';import'./chunk-W2MMKBWU.mjs';import {t,h,F,H,C}from'./chunk-BH2WXCLS.mjs';import {d as d$2}from'./chunk-E3HZCU3S.mjs';import {d,b as b$3}from'./chunk-SPHWZS5P.mjs';import {b as b$1}from'./chunk-OQDZJP55.mjs';import'./chunk-L7O2RSTN.mjs';import {readdir}from'fs/promises';import {join}from'path';globalThis.require=createRequire(import.meta.url);
3
+ var ne={meta:{name:"clean",description:"Remove unreferenced store entries and stale consumer registrations"},args:{yes:{type:"boolean",alias:"y",description:"Skip confirmation prompts",default:false}},async run({args:A}){b();let y=new a;b$1.start("Checking consumer registrations...");let{removedConsumers:l,removedPackages:v}=await k();l>0&&b$1.success(`Removed ${l} stale consumer registration(s) across ${v} package(s)`);let $=await g(),f=new Set,F$1=[...new Set(Object.values($).flat())],w=await Promise.all(F$1.map(async e=>{let{state:t,reliable:o}=await b$2(e);return {path:e,state:t,reliable:o}}));for(let{state:e,reliable:t}of w)if(t)for(let[o,g]of Object.entries(e.links))f.add(`${o}@${g.version}`);let d$3=new Set,u=w.filter(e=>!e.reliable);if(u.length>0){b$1.warn(`${u.length} consumer(s) have corrupt state; their store entries will be preserved`);let e=new Set(u.map(t$1=>t(t$1.path)));for(let[t,o]of Object.entries($))o.some(g=>e.has(g))&&d$3.add(t);d(`[clean] Protected packages (corrupt state): ${[...d$3].join(", ")}`);}d(`[clean] Referenced entries: ${[...f].join(", ")||"(none)"}`);let H$1=await d$1(),s=[];for(let e of H$1){let t=`${e.name}@${e.version}`;if(!f.has(t)){if(d$3.has(e.name)){d(`[clean] Preserving ${t} (consumer state unreadable)`);continue}let o=Date.now()-new Date(e.meta.publishedAt).getTime();if(o<300*1e3){d(`[clean] Skipping recently published entry: ${t} (${Math.round(o/1e3)}s old)`);continue}s.push(e);}}let n=[],p=h();if(await F(p)){let e=await readdir(p,{withFileTypes:true});for(let t of e)t.isDirectory()&&(t.name.includes(".tmp-")||t.name.includes(".old-"))&&n.push(t.name);}if(s.length+n.length>0&&!A.yes){let e=[];s.length>0&&e.push(`${s.length} unreferenced store entry(ies)`),n.length>0&&e.push(`${n.length} orphaned temp directory(ies)`);let t=await b$1.prompt(`Remove ${e.join(" and ")}?`,{type:"confirm"});if(!t||typeof t=="symbol"){b$1.info("Cancelled");return}}let a$3=0,q=await Promise.all(s.map(e=>H(e.packageDir))),G=await Promise.all(n.map(e=>H(join(p,e)))),m=0;for(let e$1=0;e$1<s.length;e$1++){let t=s[e$1];d(`[clean] Removing unreferenced store entry: ${t.name}@${t.version}`),await e(t.name,t.version),a$3+=q[e$1],m++;}m>0&&b$1.success(`Removed ${m} unreferenced store entry(ies)`);let c=0;for(let e=0;e<n.length;e++)d(`[clean] Removing orphaned directory: ${n[e]}`),await C(join(p,n[e])),a$3+=G[e],c++;c>0&&b$1.success(`Removed ${c} orphaned temp directory(ies)`),l===0&&m===0&&c===0&&b$1.info("Store is clean; no stale entries or registrations found");let I=a$3>0?` (reclaimed ${a$1(a$3)})`:"";b$1.info(`Clean complete in ${y.elapsed()}${I}`),a$2({removedConsumers:l,removedPackages:v,removedEntries:m,removedOrphans:c,reclaimedBytes:a$3,elapsed:y.elapsedMs()}),b$3()&&d$2();}};export{ne as default};
package/dist/cli.mjs CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import {createRequire}from'node:module';import {a as a$4}from'./chunk-7HVPEBK5.mjs';import {a as a$3}from'./chunk-NBSJGM2X.mjs';import {a as a$1,b as b$1}from'./chunk-B3DZ5HVQ.mjs';import {c,a as a$2}from'./chunk-2VCW5RWI.mjs';import {availableParallelism}from'os';globalThis.require=createRequire(import.meta.url);
3
- var o=c(a$1(),1);var _=`
2
+ import {createRequire}from'node:module';import {a as a$4}from'./chunk-NGPAGRK4.mjs';import {a as a$3}from'./chunk-SPHWZS5P.mjs';import {a as a$1,b as b$1}from'./chunk-OQDZJP55.mjs';import {c,a as a$2}from'./chunk-L7O2RSTN.mjs';import {availableParallelism}from'os';globalThis.require=createRequire(import.meta.url);
3
+ var a=c(a$1(),1);var _=`
4
4
  _ __
5
5
  | |/ /_ __ __ _ _ __ _ __
6
6
  | ' /| '_ \\ / _\` | '__| '__|
7
7
  | . \\| | | | (_| | | | |
8
8
  |_|\\_\\_| |_|\\__,_|_| |_|
9
- `;function s(){console.log(o.default.yellow(_)),console.log(o.default.cyan(" Local npm package development without symlinks")),console.log(o.default.dim(` Copies built files into consumer node_modules with incremental sync
10
- `));}a$2(s,"showBanner");process.env.UV_THREADPOOL_SIZE??=String(Math.max(availableParallelism(),8));a$3();var a=process.argv.slice(2),b=["init","publish","add","use","remove","push","dev","restore","list","status","update","clean","gc","doctor","migrate","reset","rollback","check"],u=a.some(e=>!e.startsWith("-")&&b.includes(e)),v=a.includes("--help")||a.includes("-h")||a.includes("--version");if(!u&&!v&&process.stdin.isTTY){s();let e=await g();e&&process.argv.splice(2,0,e);}else u||s();async function g(){try{let{readConsumerStateSafe:c}=await import('./tracker-JJEYXX45.mjs'),{resolve:p}=await import('path'),{state:d}=await c(p(".")),n=Object.keys(d.links).length;n>0&&b$1.info(`${n} package(s) linked in this project`);}catch{}return await b$1.prompt("What would you like to do?",{type:"select",options:[{label:"init - Set up knarr in this project",value:"init"},{label:"publish - Publish package to the knarr store",value:"publish"},{label:"add - Link a package from the store",value:"add"},{label:"use - Link a local package path",value:"use"},{label:"push - Publish and push to all consumers",value:"push"},{label:"dev - Watch, rebuild, and push continuously",value:"dev"},{label:"list - Show linked packages",value:"list"},{label:"status - Show project status",value:"status"},{label:"help - Show help",value:"--help"}]})||null}a$2(g,"showInteractiveMenu");var k={meta:{name:"knarr",version:"0.0.3",description:"Local npm package development - copies built files into consumer node_modules"},args:{verbose:{type:"boolean",alias:"v",description:"Enable verbose debug logging",default:false},"dry-run":{type:"boolean",description:"Preview changes without writing files",default:false},json:{type:"boolean",description:"Output machine-readable JSON",default:false}},subCommands:{init:a$2(()=>import('./init-XK4B7XYG.mjs').then(e=>e.default),"init"),publish:a$2(()=>import('./publish-TAWTHPSD.mjs').then(e=>e.default),"publish"),add:a$2(()=>import('./add-LZ6CZTHG.mjs').then(e=>e.default),"add"),use:a$2(()=>import('./use-BXAZ5OP3.mjs').then(e=>e.default),"use"),remove:a$2(()=>import('./remove-LOBXHBMC.mjs').then(e=>e.default),"remove"),push:a$2(()=>import('./push-65ZZFZJY.mjs').then(e=>e.default),"push"),dev:a$2(()=>import('./dev-TMWMIT7W.mjs').then(e=>e.default),"dev"),restore:a$2(()=>import('./restore-YHZYT54B.mjs').then(e=>e.default),"restore"),list:a$2(()=>import('./list-GLSA6I67.mjs').then(e=>e.default),"list"),status:a$2(()=>import('./status-FA6UEHEF.mjs').then(e=>e.default),"status"),update:a$2(()=>import('./update-VOUKMOLK.mjs').then(e=>e.default),"update"),clean:a$2(()=>import('./clean-ZD5GPGXQ.mjs').then(e=>e.default),"clean"),gc:a$2(()=>import('./clean-ZD5GPGXQ.mjs').then(e=>e.default),"gc"),doctor:a$2(()=>import('./doctor-AXP7GVBM.mjs').then(e=>e.default),"doctor"),migrate:a$2(()=>import('./migrate-MW4BVLL2.mjs').then(e=>e.default),"migrate"),reset:a$2(()=>import('./reset-EAN5NVGM.mjs').then(e=>e.default),"reset"),rollback:a$2(()=>import('./rollback-U3LQTWH5.mjs').then(e=>e.default),"rollback"),check:a$2(()=>import('./check-YVEJEI2G.mjs').then(e=>e.default),"check")}};a$4(k);
9
+ `;function n(){console.log(a.default.yellow(_)),console.log(a.default.cyan(" Local npm package development without symlinks")),console.log(a.default.dim(` Copies built files into consumer node_modules with incremental sync
10
+ `));}a$2(n,"showBanner");process.env.UV_THREADPOOL_SIZE??=String(Math.max(availableParallelism(),8));a$3();var l=process.argv.slice(2),b=["init","publish","add","use","remove","push","dev","restore","list","status","update","clean","gc","doctor","explain","migrate","reset","rollback","check"],u=l.some(e=>!e.startsWith("-")&&b.includes(e)),v=l.includes("--help")||l.includes("-h")||l.includes("--version");if(!u&&!v&&process.stdin.isTTY){n();let e=await g();e&&process.argv.splice(2,0,e);}else u||n();async function g(){try{let{readConsumerStateSafe:p}=await import('./tracker-QAKEXYUJ.mjs'),{resolve:c}=await import('path'),{state:d}=await p(c(".")),i=Object.keys(d.links).length;i>0&&b$1.info(`${i} package(s) linked in this project`);}catch{}return await b$1.prompt("What would you like to do?",{type:"select",options:[{label:"init - Set up knarr in this project",value:"init"},{label:"publish - Publish package to the knarr store",value:"publish"},{label:"add - Link a package from the store",value:"add"},{label:"use - Link a local package path",value:"use"},{label:"push - Publish and push to all consumers",value:"push"},{label:"dev - Watch, rebuild, and push continuously",value:"dev"},{label:"list - Show linked packages",value:"list"},{label:"status - Show project status",value:"status"},{label:"explain - Explain linked package state",value:"explain"},{label:"help - Show help",value:"--help"}]})||null}a$2(g,"showInteractiveMenu");var k={meta:{name:"knarr",version:"0.1.0",description:"Local npm package development - copies built files into consumer node_modules"},args:{verbose:{type:"boolean",alias:"v",description:"Enable verbose debug logging",default:false},"dry-run":{type:"boolean",description:"Preview changes without writing files",default:false},json:{type:"boolean",description:"Output machine-readable JSON",default:false}},subCommands:{init:a$2(()=>import('./init-X4F3XKVC.mjs').then(e=>e.default),"init"),publish:a$2(()=>import('./publish-UGDDG6OT.mjs').then(e=>e.default),"publish"),add:a$2(()=>import('./add-4Z3V5722.mjs').then(e=>e.default),"add"),use:a$2(()=>import('./use-LZ2GIXYZ.mjs').then(e=>e.default),"use"),remove:a$2(()=>import('./remove-EPVDMWCS.mjs').then(e=>e.default),"remove"),push:a$2(()=>import('./push-V575ASM4.mjs').then(e=>e.default),"push"),dev:a$2(()=>import('./dev-PUNHH4MS.mjs').then(e=>e.default),"dev"),restore:a$2(()=>import('./restore-QPISOGEK.mjs').then(e=>e.default),"restore"),list:a$2(()=>import('./list-4PTHMIQ4.mjs').then(e=>e.default),"list"),status:a$2(()=>import('./status-3ZXM3CRH.mjs').then(e=>e.default),"status"),explain:a$2(()=>import('./explain-BDTONX7H.mjs').then(e=>e.default),"explain"),update:a$2(()=>import('./update-RSPDDAJK.mjs').then(e=>e.default),"update"),clean:a$2(()=>import('./clean-EJIYYQZM.mjs').then(e=>e.default),"clean"),gc:a$2(()=>import('./clean-EJIYYQZM.mjs').then(e=>e.default),"gc"),doctor:a$2(()=>import('./doctor-ZK4OPSD4.mjs').then(e=>e.default),"doctor"),migrate:a$2(()=>import('./migrate-VHDLW6I7.mjs').then(e=>e.default),"migrate"),reset:a$2(()=>import('./reset-5M6AU4FU.mjs').then(e=>e.default),"reset"),rollback:a$2(()=>import('./rollback-CTGK7SXG.mjs').then(e=>e.default),"rollback"),check:a$2(()=>import('./check-7CJHAF6Y.mjs').then(e=>e.default),"check")}};a$4(k);
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import {createRequire}from'node:module';import {a as a$1}from'./chunk-GAWQLCRB.mjs';import'./chunk-ICU4V73X.mjs';import {e,g,a as a$3,d as d$1,c}from'./chunk-AA43FODB.mjs';import'./chunk-COI7GWH3.mjs';import'./chunk-QHNHLR6T.mjs';import'./chunk-ABG6UD3X.mjs';import'./chunk-XDWZZBCM.mjs';import {a}from'./chunk-3SXN6MQL.mjs';import'./chunk-WN3DOKIM.mjs';import'./chunk-MN4DV2NO.mjs';import'./chunk-HVN6HBWZ.mjs';import'./chunk-FSVETLZK.mjs';import {b}from'./chunk-U6O35NZ7.mjs';import'./chunk-NGPAGRK4.mjs';import'./chunk-QFHYSC3K.mjs';import'./chunk-W2MMKBWU.mjs';import'./chunk-7GCKCCHU.mjs';import'./chunk-G7HFTV5Y.mjs';import'./chunk-BH2WXCLS.mjs';import {d}from'./chunk-E3HZCU3S.mjs';import {b as b$1}from'./chunk-SPHWZS5P.mjs';import'./chunk-OQDZJP55.mjs';import {a as a$2}from'./chunk-L7O2RSTN.mjs';import {resolve}from'path';globalThis.require=createRequire(import.meta.url);
3
+ var O={meta:{name:"dev",description:"Watch, rebuild, and push to all consumers. Auto-detects build command."},args:{all:{type:"boolean",description:"Watch all workspace packages in dependency order",default:false},build:{type:"string",description:"Override build command (default: auto-detect from package.json)"},"skip-build":{type:"boolean",description:"Watch output dirs directly, skip build command detection",default:false},debounce:{type:"string",description:"Debounce delay in ms (default: 500)"},cooldown:{type:"string",description:"Minimum time between builds in ms (default: 500)"},"no-scripts":{type:"boolean",description:"Skip prepack/postpack lifecycle hooks",default:false},force:{type:"boolean",alias:"f",description:"Force copy all files, bypassing hash comparison",default:false},notify:{type:"boolean",description:"Ring terminal bell on push completion",default:false},"no-cascade":{type:"boolean",description:"Disable cascading rebuilds in --all mode",default:false}},async run({args:i}){b();let e$1=resolve("."),s=await a(e$1),o={runScripts:!i["no-scripts"],force:i.force,historyLimit:s.historyLimit};if(i.all){let t=await e(e$1,i),l=new Set([...t.failedPackages,...t.skippedPackages]);if(t.canPush&&await a$1(e$1,{...o,skipPackages:l}),b$1()){d();return}await g(e$1,i,o);}else {let t=a$2(()=>a$3(e$1,o),"push");if(await d$1(e$1,i,s)&&await t(),b$1()){d();return}await c(e$1,i,t);}}};export{O as default};
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ import {createRequire}from'node:module';import {d,b as b$2}from'./chunk-QHNHLR6T.mjs';import {f as f$1}from'./chunk-ABG6UD3X.mjs';import {c as c$3,b as b$3,d as d$1,e as e$1}from'./chunk-N3B2JO4H.mjs';import {a as a$3}from'./chunk-MN4DV2NO.mjs';import {a as a$2,e,f,g,c as c$1,h}from'./chunk-FSVETLZK.mjs';import {b as b$4,a as a$4}from'./chunk-U6O35NZ7.mjs';import'./chunk-NGPAGRK4.mjs';import {g as g$1,b as b$1,c as c$2,k}from'./chunk-QFHYSC3K.mjs';import'./chunk-W2MMKBWU.mjs';import {h as h$1,F,i,r,q,D,x}from'./chunk-BH2WXCLS.mjs';import {d as d$2}from'./chunk-E3HZCU3S.mjs';import {b,c as c$4}from'./chunk-SPHWZS5P.mjs';import {a,b as b$5}from'./chunk-OQDZJP55.mjs';import {c,a as a$1}from'./chunk-L7O2RSTN.mjs';import {join,basename,resolve}from'path';import {readFile,stat}from'fs/promises';globalThis.require=createRequire(import.meta.url);
3
+ var w=c(a(),1);async function Se(a,o={}){let n=[],l=b(),f$2=o.fix===true,k$1=l?"Would ":"";async function s(e,t){let i={fixable:false,fixed:false,fixes:[],...e};if(f$2&&i.fixable&&t){let u=await t();u&&(i.fixed=!l,i.fixes.push(`${k$1}${u}`));}n.push(i);}a$1(s,"addCheck");let x=await a$2(a),$=await e(a),M=await f(a),we=await g(a),_=x==="yarn"||$||M,j=_?await c$1(a):null,E=we||x==="yarn"&&await h(a),d$2=!E,b$3="Yarn PnP has no node_modules tree for Knarr to manage. Set `nodeLinker: node-modules` or `nodeLinker: pnpm`, run `yarn install`, then re-run `knarr doctor --fix`.",F$1=h$1();if(await F(F$1)){let e=await d();await s({name:"Store directory",status:"pass",message:`${e.length} entries in ${F$1}`});}else await s({name:"Store directory",status:"warn",message:`Store not found at ${F$1}. Run 'knarr publish' to create it.`});let ke=i(),D$1=await g$1();if(await F(ke)){let e=Object.values(D$1).flat().length;await s({name:"Global registry",status:"pass",message:`${Object.keys(D$1).length} packages, ${e} consumer registrations`});}else await s({name:"Global registry",status:"warn",message:"No consumers registered yet. Use 'knarr add' to link packages."});let R=await je(D$1),O=R.missingDirectories+R.missingLinks;O>0&&await s({name:"Stale registry entries",status:"warn",message:`${O} stale consumer registration(s) found`+(R.unreadableConsumers>0?`; ${R.unreadableConsumers} unreadable state file(s) skipped`:""),fixable:true},async()=>`remove ${(await k({removeMissingLinks:true})).removedConsumers} stale consumer registration(s)`);let A=r(a),P=q(a),xe=await De(P),K=await F(A),{state:I,reliable:y}=await b$1(a);if(xe==="file")await s({name:"Consumer state",status:"fail",message:`${P} exists but is not a directory.`,unfixableReason:`Move or delete ${P}, then run 'knarr init'.`}),y=false;else if(K)y||await s({name:"Consumer state",status:"fail",message:"state.json is corrupt or unreadable. Delete .knarr/state.json and re-run 'knarr add' for each package.",unfixableReason:"Corrupt state may contain links Knarr cannot safely reconstruct."});else {let e={name:"Consumer state",status:"warn",message:"No .knarr/state.json found.",fixable:d$2,fixed:false,fixes:[],...d$2?{}:{unfixableReason:b$3}};f$2&&e.fixable&&(await D(P),await c$2(a,{version:"1",packageManager:x,role:"consumer",links:{}}),e.fixed=!l,e.fixes.push(`${k$1}create .knarr/state.json`),K=await F(A),{state:I,reliable:y}=await b$1(a)),n.push(e);}let C=y?Object.entries(I.links):[];y&&K&&(C.length>0?await s({name:"Consumer state",status:"pass",message:`${C.length} linked package(s)`}):await s({name:"Consumer state",status:"warn",message:"No packages linked. Use 'knarr add' to link a package."}));for(let[e,t]of C){let i=await b$2(e,t.version);i?i.meta.contentHash!==t.contentHash?await s({name:`Store: ${e}`,status:"warn",message:"Store has newer content. Run 'knarr update' to sync."}):await s({name:`Store: ${e}`,status:"pass",message:`${e}@${t.version} in sync`}):await s({name:`Store: ${e}`,status:"fail",message:`Store entry missing for ${e}@${t.version}. Re-publish it.`});let u;try{u=await f$1(a,e,t.packageManager,t.version,{warnOnFallback:!1});}catch(r){await s({name:`node_modules: ${e}`,status:"fail",message:`Cannot resolve package target. ${r instanceof Error?r.message:String(r)}`});continue}if(!await F(u))await s({name:`node_modules: ${e}`,status:"fail",message:"Missing from node_modules. Run 'knarr restore'."});else try{let r=JSON.parse(await readFile(join(u,"package.json"),"utf-8"));r.name&&r.name!==e?await s({name:`node_modules: ${e}`,status:"fail",message:`node_modules target contains package "${r.name}". Run your package manager install, then 'knarr restore'.`}):r.version&&r.version!==t.version?await s({name:`node_modules: ${e}`,status:"warn",message:`node_modules has v${r.version} but Knarr linked v${t.version}. Run 'knarr restore'.`}):await s({name:`node_modules: ${e}`,status:"pass",message:"present"});}catch{await s({name:`node_modules: ${e}`,status:"pass",message:"present"});}}await s({name:"Package manager",status:"pass",message:x}),_&&(j==="node-modules"?await s({name:"Yarn linker",status:"pass",message:"Yarn Berry with node-modules linker"}):j==="pnpm"?await s({name:"Yarn linker",status:"pass",message:"Yarn pnpm linker mode (.store virtual store)"}):E?await s({name:"Yarn linker",status:"fail",message:`${j==="pnp"||M?"Yarn PnP is not compatible.":"Yarn Berry defaults to PnP."} Set \`nodeLinker: node-modules\` or \`nodeLinker: pnpm\` in .yarnrc.yml`}):$?await s({name:"Yarn linker",status:"warn",message:"Yarn Berry defaults to PnP. Add `nodeLinker: node-modules` or `nodeLinker: pnpm` to .yarnrc.yml"}):await s({name:"Yarn linker",status:"pass",message:"Yarn Classic, node_modules mode"}));let c=await a$3(a);if(c.type?await s({name:"Bundler",status:"pass",message:`${c.type}${c.configFile?` (${c.configFile})`:""}`}):await s({name:"Bundler",status:"warn",message:"No bundler config detected"}),c.type==="vite"&&c.configFile){let{addKnarrVitePlugin:e,hasKnarrVitePlugin:t}=await import('./vite-config-XOGAKYGQ.mjs'),i=await t(c.configFile);if(i.error)await s({name:"Vite integration",status:"warn",message:i.error});else if(i.configured)await s({name:"Vite integration",status:"pass",message:"Knarr plugin configured"});else {let u={name:"Vite integration",status:"warn",message:"Knarr Vite plugin is missing.",fixable:d$2,fixed:false,fixes:[],...d$2?{}:{unfixableReason:b$3}};if(f$2&&u.fixable){let r=await e(c.configFile);r.modified?(u.fixed=!l,u.fixes.push(`${k$1}add Knarr Vite plugin to ${basename(c.configFile)}`)):r.error&&(u.unfixableReason=r.error);}n.push(u);}}if(c.type==="next"&&c.configFile){let{addToTranspilePackages:e,hasTranspilePackage:t}=await import('./nextjs-config-T5D6LOJE.mjs');for(let[i]of C){let u=await t(c.configFile,i);if(u.configured){await s({name:`Next.js integration: ${i}`,status:"pass",message:"transpilePackages configured"});continue}let r={name:`Next.js integration: ${i}`,status:"warn",message:`${i} is missing from transpilePackages.`,fixable:!u.error&&d$2,fixed:false,fixes:[],...u.error?{unfixableReason:u.error}:d$2?{}:{unfixableReason:b$3}};if(f$2&&r.fixable){let Y=await e(c.configFile,i);Y.modified?(r.fixed=!l,r.fixes.push(`${k$1}add ${i} to transpilePackages in ${basename(c.configFile)}`)):Y.error&&(r.unfixableReason=Y.error);}n.push(r);}}let V=join(a,".gitignore");await Fe(V)?await s({name:".gitignore",status:"pass",message:".knarr/ is ignored"}):await s({name:".gitignore",status:"warn",message:".knarr/ not in .gitignore.",fixable:d$2,...d$2?{}:{unfixableReason:b$3}},async()=>await d$1(V)?"add .knarr/ to .gitignore":null);let N=join(a,"package.json");if(await F(N)){let e=await Ye(N),t=e?.scripts?.postinstall;typeof t=="string"&&c$3(t)?await Ke(a,e,t)?await s({name:"Postinstall restore",status:"pass",message:"postinstall runs knarr restore"}):await s({name:"Postinstall restore",status:"warn",message:"postinstall runs knarr restore, but no local knarr dependency or binary was found.",unfixableReason:"Install knarr as a devDependency for reliable auto-restore, or ensure a global knarr binary is available during installs."}):typeof t=="string"?await s({name:"Postinstall restore",status:"warn",message:"postinstall exists but does not run knarr restore.",unfixableReason:"Existing postinstall scripts are not merged automatically."}):await s({name:"Postinstall restore",status:"warn",message:"postinstall restore hook is missing.",fixable:d$2,...d$2?{}:{unfixableReason:b$3}},async()=>await e$1(N)?"add postinstall restore hook to package.json":null);}else await s({name:"Postinstall restore",status:"warn",message:"No package.json found."});parseInt(process.versions.node.split(".")[0],10)>=22?await s({name:"Node.js version",status:"pass",message:`v${process.versions.node}`}):await s({name:"Node.js version",status:"fail",message:`v${process.versions.node}; Knarr requires Node.js >= 22`});let be=n.filter(e=>e.status==="fail").length,ye=n.filter(e=>e.status==="warn").length,he=n.filter(e=>e.fixed).length,$e=l?n.reduce((e,t)=>e+t.fixes.length,0):0;return {results:n,failures:be,warnings:ye,fixed:he,plannedFixes:$e,dryRun:l}}a$1(Se,"runDoctorDiagnostics");var Xe={meta:{name:"doctor",description:"Run diagnostic checks on your Knarr setup"},args:{fix:{type:"boolean",description:"Apply safe automatic repairs",default:false}},async run({args:a}){b$4();let o=resolve(".");b$5.info(a.fix?`Running Knarr diagnostics with safe fixes...
4
+ `:`Running Knarr diagnostics...
5
+ `);let n=await Se(o,{fix:a.fix}),l={pass:w.default.green("PASS"),fail:w.default.red("FAIL"),warn:w.default.yellow("WARN")};for(let f of n.results){b$5.log(` ${l[f.status]} ${f.name}: ${w.default.dim(f.message)}`);for(let k of f.fixes)b$5.log(` ${w.default.cyan(b()?"PLAN":"FIX")} ${w.default.dim(k)}`);f.unfixableReason&&b$5.log(` ${w.default.yellow("!")} ${w.default.dim(f.unfixableReason)}`);}b$5.log(""),n.plannedFixes>0?b$5.info(`${n.plannedFixes} fix(es) would be applied`):n.fixed>0&&b$5.success(`Applied ${n.fixed} fix(es)`),n.failures>0?b$5.error(`${n.failures} issue(s) found that need attention`):n.warnings>0?b$5.warn(`${n.warnings} warning(s), but no critical issues`):b$5.success("All checks passed!"),a$4(n),a.fix&&b()&&!c$4()&&d$2();}};async function je(a){let o=0,n=0,l=0;for(let[f,k]of Object.entries(a))for(let s of k){if(!await F(s)){o++;continue}let{state:x,reliable:$}=await b$1(s);if(!$){l++;continue}x.links[f]||n++;}return {missingDirectories:o,missingLinks:n,unreadableConsumers:l}}a$1(je,"findStaleRegistryEntries");async function Fe(a){try{return (await readFile(a,"utf-8")).split(`
6
+ `).some(n=>{let l=n.trim();return l===".knarr/"||l===".knarr"||l==="/.knarr/"||l==="/.knarr"})}catch{return false}}a$1(Fe,"gitignoreIncludesKnarr");async function De(a){try{return (await stat(a)).isDirectory()?"dir":"file"}catch(o){return x(o)&&o.code==="ENOENT"?"missing":"file"}}a$1(De,"pathKind");async function Ke(a,o,n){return b$3(n)||Ne(o)?true:await F(join(a,"node_modules",".bin","knarr"))||await F(join(a,"node_modules",".bin","knarr.cmd"))}a$1(Ke,"canVerifyKnarrForPostinstall");function Ne(a){return a?[a.dependencies,a.devDependencies,a.optionalDependencies,a.peerDependencies].some(o=>o&&typeof o=="object"&&"knarr"in o):false}a$1(Ne,"declaresKnarrDependency");async function Ye(a){try{return JSON.parse(await readFile(a,"utf-8"))}catch{return null}}a$1(Ye,"readJsonFile");export{Xe as default,Se as runDoctorDiagnostics};
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ import {createRequire}from'node:module';import {b as b$1,c as c$1}from'./chunk-QHNHLR6T.mjs';import {f}from'./chunk-ABG6UD3X.mjs';import'./chunk-MN4DV2NO.mjs';import {a as a$2}from'./chunk-FSVETLZK.mjs';import {b as b$3,a as a$3}from'./chunk-U6O35NZ7.mjs';import'./chunk-NGPAGRK4.mjs';import {b,g}from'./chunk-QFHYSC3K.mjs';import'./chunk-W2MMKBWU.mjs';import {t,F,u,s}from'./chunk-BH2WXCLS.mjs';import'./chunk-E3HZCU3S.mjs';import'./chunk-SPHWZS5P.mjs';import {a,b as b$2}from'./chunk-OQDZJP55.mjs';import {c,a as a$1}from'./chunk-L7O2RSTN.mjs';import {join,resolve}from'path';import {readFile}from'fs/promises';globalThis.require=createRequire(import.meta.url);
3
+ var r=c(a(),1);async function J(t,n){let{state:e,reliable:o}=await b(t),a=await a$2(t);if(!o)return {consumerPath:t,stateReliable:false,packages:n?[await O(t,n,null,a,false)]:[]};let i=n?[[n,e.links[n]??null]]:Object.entries(e.links),p=await Promise.all(i.map(([m,h])=>O(t,m,h,a,true)));return {consumerPath:t,stateReliable:true,packages:p}}a$1(J,"explainState");var oe={meta:{name:"explain",description:"Explain linked package state and suggested recovery actions"},args:{package:{type:"positional",description:"Package name to explain (default: all linked packages)",required:false}},async run({args:t}){b$3();let n=resolve("."),e=await J(n,t.package);if(!e.stateReliable)b$2.error("Consumer state is corrupt or unreadable"),b$2.info("Delete .knarr/state.json and re-run 'knarr add' for each package.");else if(e.packages.length===0)b$2.info("No linked packages in this project");else if(t.package)N(e.packages[0]);else {b$2.info(`Linked packages (${e.packages.length}):
4
+ `);for(let o of e.packages){let a=o.status==="ok"?r.default.green("OK"):o.status==="warn"?r.default.yellow("!"):r.default.red("FAIL"),i=o.version?r.default.dim(`@${o.version}`):r.default.dim("(not linked)"),p=o.buildId?r.default.dim(` [${o.buildId}]`):"";b$2.log(` ${a} ${r.default.cyan(o.name)} ${i}${p}`),b$2.log(` ${r.default.dim(o.summary)}`);}b$2.log(""),b$2.info(`Run ${r.default.cyan("knarr explain <package>")} for details.`);}a$3(e);}};async function O(t$1,n,e,o,a){let i=e?await b$1(n,e.version):await c$1(n),m=(await g())[n]??[],h=t(t$1),l=[];a||l.push("consumer state is corrupt or unreadable"),e||l.push("package is not linked in this project");let d=e?.sourcePath??i?.meta.sourcePath??null,$=d?await F(d):null;d&&$===false&&l.push(`source directory missing: ${d}`),i?e&&i.meta.contentHash!==e.contentHash&&l.push("store has newer content than the current link"):l.push(e?`store entry missing for ${n}@${e.version}`:"package not found in store");let w=u(t$1,n),k=e?await f(t$1,n,e.packageManager,e.version,{warnOnFallback:false}):w,b$2=await F(k),f$1=b$2?await G(k):null;e&&!b$2?l.push("package is missing from node_modules"):e&&f$1&&f$1!==e.version&&l.push(`node_modules has v${f$1} but link expects v${e.version}`);let x=e?s(t$1,n):null,E=x?await F(x):false;e?.backupExists&&!E&&l.push("backup is recorded but missing on disk");let _=await Promise.all(m.map(async u=>{if(!await F(u))return {path:u,exists:false,stateReliable:null,hasLink:null};let{state:V,reliable:P}=await b(u);return {path:u,exists:true,stateReliable:P,hasLink:P?!!V.links[n]:null}}));e&&!m.includes(h)&&l.push("current project is not registered for pushes");let D=l.some(u=>u.includes("corrupt")||u.includes("missing from node_modules")||u.includes("store entry missing")||u.includes("not linked"))?"fail":l.length>0?"warn":"ok";return {name:n,status:D,summary:T(n,e,l),suggestedAction:W(n,e,l,d),linked:!!e,version:e?.version??i?.version??null,buildId:e?.buildId||i?.meta.buildId||null,sourcePath:d,sourceExists:$,packageManager:e?.packageManager??o,store:{exists:!!i,path:i?.packageDir??null,contentHash:i?.meta.contentHash??null,matchesLink:e&&i?i.meta.contentHash===e.contentHash:null,publishedAt:i?.meta.publishedAt??null},nodeModules:{path:w,targetPath:k,exists:b$2,packageVersion:f$1},backup:{expected:e?.backupExists??false,exists:E,path:x},consumers:_,issues:l}}a$1(O,"explainPackage");function N(t){let n=t.status==="ok"?r.default.green("OK"):t.status==="warn"?r.default.yellow("WARN"):r.default.red("FAIL");if(b$2.info(`${n} ${r.default.cyan(t.name)} ${r.default.dim(t.summary)}
5
+ `),b$2.log(` Version: ${t.version??"(not linked)"}`),b$2.log(` Build ID: ${t.buildId??"(none)"}`),b$2.log(` Package manager: ${t.packageManager}`),b$2.log(` Source: ${t.sourcePath??"(unknown)"}${t.sourceExists===false?" (missing)":""}`),b$2.log(` Store: ${t.store.exists?t.store.path:"(missing)"}`),t.store.matchesLink!==null&&b$2.log(` Content hash: ${t.store.matchesLink?"matches link":"differs from link"}`),b$2.log(` node_modules: ${t.nodeModules.targetPath}${t.nodeModules.exists?"":" (missing)"}`),b$2.log(` Backup: ${t.backup.expected?t.backup.exists?"present":"missing":"not recorded"}`),b$2.log(` Registered consumers: ${t.consumers.length}`),t.issues.length>0){b$2.log("");for(let e of t.issues)b$2.log(` ${r.default.yellow("!")} ${e}`);}b$2.log(""),b$2.info(`Suggested action: ${t.suggestedAction}`);}a$1(N,"renderDetailed");function T(t,n,e){return n?e.length===0?"link, store, and node_modules are in sync":e[0]:`${t} is not linked in this project`}a$1(T,"summarize");function W(t,n,e,o){return e.some(a=>a.includes("corrupt"))?"Delete .knarr/state.json and re-run 'knarr add' for each package.":n?e.some(a=>a.includes("store entry missing"))?o?`Run 'knarr publish' in ${o}, then 'knarr restore'.`:"Re-publish the package, then run 'knarr restore'.":e.some(a=>a.includes("newer content"))?`Run 'knarr update ${t}'.`:e.some(a=>a.includes("node_modules"))?"Run 'knarr restore'.":e.some(a=>a.includes("not registered"))?`Run 'knarr add ${t}' again to refresh registration.`:e.some(a=>a.includes("source directory"))?"Check the source path or re-run 'knarr use <path>'.":"No action needed.":`Run 'knarr add ${t}' or 'knarr use <path>'.`}a$1(W,"suggestAction");async function G(t){try{let n=JSON.parse(await readFile(join(t,"package.json"),"utf-8"));return typeof n.version=="string"?n.version:null}catch{return null}}a$1(G,"readPackageVersion");export{oe as default,J as explainState};
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import {createRequire}from'node:module';export{G as atomicWriteFile,z as collectFiles,I as copyDir,y as copyWithCoW,H as dirSize,D as ensureDir,E as ensurePrivateDir,F as exists,A as incrementalCopy,x as isNodeError,B as moveDir,C as removeDir}from'./chunk-BH2WXCLS.mjs';import'./chunk-E3HZCU3S.mjs';import'./chunk-SPHWZS5P.mjs';import'./chunk-OQDZJP55.mjs';import'./chunk-L7O2RSTN.mjs';globalThis.require=createRequire(import.meta.url);
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import {createRequire}from'node:module';export{a as captureHistory,f as clearHistory,c as getHistoryEntry,b as listHistory,e as pruneHistory,g as resolveHistoryLimit,d as restoreHistoryEntry}from'./chunk-M3TRMEJV.mjs';import'./chunk-BH2WXCLS.mjs';import'./chunk-E3HZCU3S.mjs';import'./chunk-SPHWZS5P.mjs';import'./chunk-OQDZJP55.mjs';import'./chunk-L7O2RSTN.mjs';globalThis.require=createRequire(import.meta.url);
package/dist/index.d.ts CHANGED
@@ -137,6 +137,7 @@ interface InjectResult {
137
137
  removed: number;
138
138
  skipped: number;
139
139
  binLinks: number;
140
+ cacheInvalidations: number;
140
141
  }
141
142
  interface InjectOptions {
142
143
  /** Force copy all files, bypassing hash comparison */
@@ -145,8 +146,9 @@ interface InjectOptions {
145
146
  /**
146
147
  * Inject a package from the store into a consumer's node_modules.
147
148
  * Strategy depends on the package manager:
148
- * - npm/yarn/bun: direct node_modules/<pkg>/
149
+ * - npm/yarn/bun: direct node_modules/<pkg>/ (Bun isolated symlinks must stay local)
149
150
  * - pnpm: follow .pnpm/ structure
151
+ * - yarn with nodeLinker: pnpm: follow .store/ structure
150
152
  */
151
153
  declare function inject(storeEntry: StoreEntry, consumerPath: string, pm: PackageManager, options?: InjectOptions): Promise<InjectResult>;
152
154
  /**
@@ -156,17 +158,17 @@ declare function backupExisting(consumerPath: string, packageName: string, pm: P
156
158
  /**
157
159
  * Restore a backed-up package to node_modules.
158
160
  */
159
- declare function restoreBackup(consumerPath: string, packageName: string, pm: PackageManager): Promise<boolean>;
161
+ declare function restoreBackup(consumerPath: string, packageName: string, pm: PackageManager, version?: string): Promise<boolean>;
160
162
  /**
161
163
  * Remove an injected package from node_modules.
162
164
  */
163
- declare function removeInjected(consumerPath: string, packageName: string, pm: PackageManager): Promise<void>;
165
+ declare function removeInjected(consumerPath: string, packageName: string, pm: PackageManager, version?: string): Promise<void>;
164
166
  /**
165
167
  * Check for missing transitive dependencies.
166
168
  * Returns a list of dependency names that are in the linked package's
167
169
  * dependencies but not installed in the consumer's node_modules.
168
170
  */
169
- declare function checkMissingDeps(storeEntry: StoreEntry, consumerPath: string): Promise<string[]>;
171
+ declare function checkMissingDeps(storeEntry: StoreEntry, consumerPath: string, pm?: PackageManager): Promise<string[]>;
170
172
 
171
173
  /** Get a store entry if it exists */
172
174
  declare function getStoreEntry(name: string, version: string): Promise<StoreEntry | null>;
@@ -206,6 +208,16 @@ declare function getConsumers(packageName: string): Promise<string[]>;
206
208
  declare function cleanStaleConsumers(): Promise<{
207
209
  removedConsumers: number;
208
210
  removedPackages: number;
211
+ removedMissingLinks: number;
212
+ skippedUnreliableConsumers: number;
213
+ }>;
214
+ declare function cleanStaleConsumers(options: {
215
+ removeMissingLinks?: boolean;
216
+ }): Promise<{
217
+ removedConsumers: number;
218
+ removedPackages: number;
219
+ removedMissingLinks: number;
220
+ skippedUnreliableConsumers: number;
209
221
  }>;
210
222
 
211
223
  /**
@@ -225,6 +237,17 @@ interface KnarrConfig {
225
237
  */
226
238
  declare function loadKnarrConfig(projectDir: string): Promise<KnarrConfig>;
227
239
 
240
+ /**
241
+ * Simple timer for measuring command execution time.
242
+ */
243
+ declare class Timer {
244
+ private start;
245
+ /** Return elapsed time in ms */
246
+ elapsedMs(): number;
247
+ /** Return human-readable elapsed time (e.g., "1.2s" or "150ms") */
248
+ elapsed(): string;
249
+ }
250
+
228
251
  interface PushOptions {
229
252
  runScripts?: boolean;
230
253
  /** Force copy all files, bypassing hash comparison */
@@ -232,11 +255,40 @@ interface PushOptions {
232
255
  /** Max historical builds to keep per package */
233
256
  historyLimit?: number;
234
257
  }
258
+ interface PushConsumerResult {
259
+ consumerPath: string;
260
+ status: "updated" | "failed" | "skipped";
261
+ copied: number;
262
+ removed: number;
263
+ skipped: number;
264
+ binLinks: number;
265
+ cacheInvalidations: number;
266
+ reason?: string;
267
+ error?: string;
268
+ }
269
+ interface PushSummary {
270
+ name: string;
271
+ version: string;
272
+ buildId: string;
273
+ noChange: boolean;
274
+ skippedReason?: string;
275
+ consumers: number;
276
+ updatedConsumers: number;
277
+ failedConsumers: number;
278
+ skippedConsumers: number;
279
+ copied: number;
280
+ removed: number;
281
+ skipped: number;
282
+ binLinks: number;
283
+ cacheInvalidations: number;
284
+ elapsed: number;
285
+ consumerResults: PushConsumerResult[];
286
+ }
235
287
  /**
236
288
  * Publish a package to the store, then inject into all registered consumers.
237
289
  * Shared by both `push` and `dev` commands.
238
290
  */
239
- declare function doPush(packageDir: string, options?: PushOptions): Promise<void>;
291
+ declare function doPush(packageDir: string, options?: PushOptions): Promise<PushSummary>;
240
292
  /** Common CLI args shared by push --watch and dev */
241
293
  interface WatchArgs {
242
294
  build?: string;
@@ -247,12 +299,19 @@ interface WatchArgs {
247
299
  "no-cascade"?: boolean;
248
300
  }
249
301
 
302
+ interface PushAllOptions extends PushOptions {
303
+ /**
304
+ * Workspace packages to skip before pushing. Used by watch-mode initial
305
+ * builds so a failed build does not publish stale output.
306
+ */
307
+ skipPackages?: Iterable<string>;
308
+ }
250
309
  /**
251
310
  * Push all workspace packages in topological (dependency-first) order.
252
311
  * Each package is published and injected sequentially to ensure
253
312
  * dependencies are available before dependents.
254
313
  */
255
- declare function doPushAll(startDir: string, options?: PushOptions): Promise<void>;
314
+ declare function doPushAll(startDir: string, options?: PushAllOptions): Promise<void>;
256
315
 
257
316
  /**
258
317
  * Capture the current store entry as a history entry before it gets replaced.
@@ -320,10 +379,18 @@ declare class WatchOrchestrator {
320
379
  constructor(cascade: boolean);
321
380
  start(startDir: string, args: WatchArgs, pushOptions: PushOptions): Promise<void>;
322
381
  private onPackagePushed;
382
+ private runExclusive;
323
383
  private requestRebuild;
324
384
  close(): Promise<void>;
325
385
  }
326
386
 
387
+ type PackageManagerDetectionSource = "packageManager" | "lockfile" | "yarnArtifact" | "default";
388
+ interface PackageManagerDetection {
389
+ packageManager: PackageManager;
390
+ source: PackageManagerDetectionSource;
391
+ dir: string;
392
+ file?: string;
393
+ }
327
394
  /**
328
395
  * Detect the package manager used in a project directory.
329
396
  * Checks `packageManager` field in package.json first (Corepack convention),
@@ -332,6 +399,11 @@ declare class WatchOrchestrator {
332
399
  * Falls back to "npm" if nothing is found.
333
400
  */
334
401
  declare function detectPackageManager(projectDir: string): Promise<PackageManager>;
402
+ /**
403
+ * Detect the package manager and return where the decision came from.
404
+ * Useful for distinguishing an explicit npm project from the npm fallback.
405
+ */
406
+ declare function detectPackageManagerInfo(projectDir: string): Promise<PackageManagerDetection>;
335
407
 
336
408
  /**
337
409
  * Topological sort using Kahn's algorithm.
@@ -391,17 +463,6 @@ declare function runPreflightChecks(packageDir: string): Promise<PreflightIssue[
391
463
  */
392
464
  declare function ringBell(enabled: boolean): void;
393
465
 
394
- /**
395
- * Simple timer for measuring command execution time.
396
- */
397
- declare class Timer {
398
- private start;
399
- /** Return elapsed time in ms */
400
- elapsedMs(): number;
401
- /** Return human-readable elapsed time (e.g., "1.2s" or "150ms") */
402
- elapsed(): string;
403
- }
404
-
405
466
  /** Type guard for Node.js system errors with an error code */
406
467
  declare function isNodeError(err: unknown): err is NodeJS.ErrnoException;
407
468
 
@@ -431,4 +492,4 @@ declare function isComplexConfig(content: string): {
431
492
  reason?: string;
432
493
  };
433
494
 
434
- export { type ConsumerState, type ConsumersRegistry, CycleError, type DryRunMutation, type HistoryEntry, type InjectOptions, type InjectResult, type KnarrConfig, type KnarrMeta, type LinkEntry, type MutationType, type PackageJson, type PackageManager, type PreflightIssue, type PreflightSeverity, type PublishOptions, type PublishResult, type PushOptions, type StoreEntry, Timer, type WatchOptions, WatchOrchestrator, type WorkspaceGraph, type WorkspacePackage, addLink, backupExisting, buildReverseAdjacency, buildWorkspaceGraph, captureHistory, checkMissingDeps, cleanStaleConsumers, clearHistory, detectPackageManager, doPush, doPushAll, findStoreEntry, getConsumers, getHistoryEntry, getLink, getStoreEntry, inject, isComplexConfig, isNodeError, killActiveBuild, listHistory, listStoreEntries, loadKnarrConfig, normalizePath, printDryRunReport, pruneHistory, publish, readConsumerState, readConsumerStateSafe, recordMutation, registerConsumer, removeInjected, removeLink, resetMutations, resolveHistoryLimit, restoreBackup, restoreHistoryEntry, ringBell, runBuildCommand, runPreflightChecks, startWatcher, topoSort, unregisterConsumer };
495
+ export { type ConsumerState, type ConsumersRegistry, CycleError, type DryRunMutation, type HistoryEntry, type InjectOptions, type InjectResult, type KnarrConfig, type KnarrMeta, type LinkEntry, type MutationType, type PackageJson, type PackageManager, type PackageManagerDetection, type PackageManagerDetectionSource, type PreflightIssue, type PreflightSeverity, type PublishOptions, type PublishResult, type PushOptions, type StoreEntry, Timer, type WatchOptions, WatchOrchestrator, type WorkspaceGraph, type WorkspacePackage, addLink, backupExisting, buildReverseAdjacency, buildWorkspaceGraph, captureHistory, checkMissingDeps, cleanStaleConsumers, clearHistory, detectPackageManager, detectPackageManagerInfo, doPush, doPushAll, findStoreEntry, getConsumers, getHistoryEntry, getLink, getStoreEntry, inject, isComplexConfig, isNodeError, killActiveBuild, listHistory, listStoreEntries, loadKnarrConfig, normalizePath, printDryRunReport, pruneHistory, publish, readConsumerState, readConsumerStateSafe, recordMutation, registerConsumer, removeInjected, removeLink, resetMutations, resolveHistoryLimit, restoreBackup, restoreHistoryEntry, ringBell, runBuildCommand, runPreflightChecks, startWatcher, topoSort, unregisterConsumer };