clawpad 0.4.11 → 0.4.12

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 (171) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +10 -10
  3. package/.next/standalone/.next/build-manifest.json +3 -3
  4. package/.next/standalone/.next/prerender-manifest.json +3 -3
  5. package/.next/standalone/.next/react-loadable-manifest.json +1 -1
  6. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  7. package/.next/standalone/.next/server/app/_global-error.html +2 -2
  8. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  11. package/.next/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  12. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  13. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  14. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  15. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  16. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  17. package/.next/standalone/.next/server/app/_not-found.rsc +1 -1
  18. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  19. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  20. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  21. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  22. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  23. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  24. package/.next/standalone/.next/server/app/api/ai/write/route.js +3 -3
  25. package/.next/standalone/.next/server/app/api/ai/write/route_client-reference-manifest.js +1 -1
  26. package/.next/standalone/.next/server/app/api/changes/[id]/route_client-reference-manifest.js +1 -1
  27. package/.next/standalone/.next/server/app/api/changes/record/route_client-reference-manifest.js +1 -1
  28. package/.next/standalone/.next/server/app/api/changes/revert/route_client-reference-manifest.js +1 -1
  29. package/.next/standalone/.next/server/app/api/changes/route_client-reference-manifest.js +1 -1
  30. package/.next/standalone/.next/server/app/api/changes/run/route_client-reference-manifest.js +1 -1
  31. package/.next/standalone/.next/server/app/api/chat/abort/route_client-reference-manifest.js +1 -1
  32. package/.next/standalone/.next/server/app/api/chat/route.js +1 -1
  33. package/.next/standalone/.next/server/app/api/chat/route_client-reference-manifest.js +1 -1
  34. package/.next/standalone/.next/server/app/api/files/pages/[...path]/route_client-reference-manifest.js +1 -1
  35. package/.next/standalone/.next/server/app/api/files/recent/route_client-reference-manifest.js +1 -1
  36. package/.next/standalone/.next/server/app/api/files/search/route_client-reference-manifest.js +1 -1
  37. package/.next/standalone/.next/server/app/api/files/spaces/[space]/pages/route_client-reference-manifest.js +1 -1
  38. package/.next/standalone/.next/server/app/api/files/spaces/route_client-reference-manifest.js +1 -1
  39. package/.next/standalone/.next/server/app/api/files/watch/route_client-reference-manifest.js +1 -1
  40. package/.next/standalone/.next/server/app/api/gateway/config/route_client-reference-manifest.js +1 -1
  41. package/.next/standalone/.next/server/app/api/gateway/detect/route.js +3 -3
  42. package/.next/standalone/.next/server/app/api/gateway/detect/route_client-reference-manifest.js +1 -1
  43. package/.next/standalone/.next/server/app/api/gateway/events/route.js +1 -1
  44. package/.next/standalone/.next/server/app/api/gateway/events/route_client-reference-manifest.js +1 -1
  45. package/.next/standalone/.next/server/app/api/gateway/features/route_client-reference-manifest.js +1 -1
  46. package/.next/standalone/.next/server/app/api/gateway/history/route_client-reference-manifest.js +1 -1
  47. package/.next/standalone/.next/server/app/api/gateway/resolve/route_client-reference-manifest.js +1 -1
  48. package/.next/standalone/.next/server/app/api/gateway/sessions/route.js +2 -2
  49. package/.next/standalone/.next/server/app/api/gateway/sessions/route_client-reference-manifest.js +1 -1
  50. package/.next/standalone/.next/server/app/api/gateway/status/route.js +3 -3
  51. package/.next/standalone/.next/server/app/api/gateway/status/route_client-reference-manifest.js +1 -1
  52. package/.next/standalone/.next/server/app/api/openclaw/commands/route_client-reference-manifest.js +1 -1
  53. package/.next/standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
  54. package/.next/standalone/.next/server/app/api/settings/search-status/route_client-reference-manifest.js +1 -1
  55. package/.next/standalone/.next/server/app/api/setup/bootstrap/route_client-reference-manifest.js +1 -1
  56. package/.next/standalone/.next/server/app/api/setup/bootstrap-workspace/route_client-reference-manifest.js +1 -1
  57. package/.next/standalone/.next/server/app/api/setup/status/route_client-reference-manifest.js +1 -1
  58. package/.next/standalone/.next/server/app/api/setup/trigger-onboarding/route.js +3 -3
  59. package/.next/standalone/.next/server/app/api/setup/trigger-onboarding/route_client-reference-manifest.js +1 -1
  60. package/.next/standalone/.next/server/app/api/version/route_client-reference-manifest.js +1 -1
  61. package/.next/standalone/.next/server/app/index.html +1 -1
  62. package/.next/standalone/.next/server/app/index.rsc +1 -1
  63. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  64. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  65. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  66. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  67. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  68. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  69. package/.next/standalone/.next/server/app/settings/connection/page_client-reference-manifest.js +1 -1
  70. package/.next/standalone/.next/server/app/settings/connection.html +1 -1
  71. package/.next/standalone/.next/server/app/settings/connection.rsc +1 -1
  72. package/.next/standalone/.next/server/app/settings/connection.segments/_full.segment.rsc +1 -1
  73. package/.next/standalone/.next/server/app/settings/connection.segments/_head.segment.rsc +1 -1
  74. package/.next/standalone/.next/server/app/settings/connection.segments/_index.segment.rsc +1 -1
  75. package/.next/standalone/.next/server/app/settings/connection.segments/_tree.segment.rsc +1 -1
  76. package/.next/standalone/.next/server/app/settings/connection.segments/settings/connection/__PAGE__.segment.rsc +1 -1
  77. package/.next/standalone/.next/server/app/settings/connection.segments/settings/connection.segment.rsc +1 -1
  78. package/.next/standalone/.next/server/app/settings/connection.segments/settings.segment.rsc +1 -1
  79. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  80. package/.next/standalone/.next/server/app/settings/relay/page_client-reference-manifest.js +1 -1
  81. package/.next/standalone/.next/server/app/settings/relay.html +1 -1
  82. package/.next/standalone/.next/server/app/settings/relay.rsc +1 -1
  83. package/.next/standalone/.next/server/app/settings/relay.segments/_full.segment.rsc +1 -1
  84. package/.next/standalone/.next/server/app/settings/relay.segments/_head.segment.rsc +1 -1
  85. package/.next/standalone/.next/server/app/settings/relay.segments/_index.segment.rsc +1 -1
  86. package/.next/standalone/.next/server/app/settings/relay.segments/_tree.segment.rsc +1 -1
  87. package/.next/standalone/.next/server/app/settings/relay.segments/settings/relay/__PAGE__.segment.rsc +1 -1
  88. package/.next/standalone/.next/server/app/settings/relay.segments/settings/relay.segment.rsc +1 -1
  89. package/.next/standalone/.next/server/app/settings/relay.segments/settings.segment.rsc +1 -1
  90. package/.next/standalone/.next/server/app/settings.html +1 -1
  91. package/.next/standalone/.next/server/app/settings.rsc +1 -1
  92. package/.next/standalone/.next/server/app/settings.segments/_full.segment.rsc +1 -1
  93. package/.next/standalone/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  94. package/.next/standalone/.next/server/app/settings.segments/_index.segment.rsc +1 -1
  95. package/.next/standalone/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
  96. package/.next/standalone/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +1 -1
  97. package/.next/standalone/.next/server/app/settings.segments/settings.segment.rsc +1 -1
  98. package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  99. package/.next/standalone/.next/server/app/setup.html +1 -1
  100. package/.next/standalone/.next/server/app/setup.rsc +2 -2
  101. package/.next/standalone/.next/server/app/setup.segments/_full.segment.rsc +2 -2
  102. package/.next/standalone/.next/server/app/setup.segments/_head.segment.rsc +1 -1
  103. package/.next/standalone/.next/server/app/setup.segments/_index.segment.rsc +1 -1
  104. package/.next/standalone/.next/server/app/setup.segments/_tree.segment.rsc +1 -1
  105. package/.next/standalone/.next/server/app/setup.segments/setup/__PAGE__.segment.rsc +2 -2
  106. package/.next/standalone/.next/server/app/setup.segments/setup.segment.rsc +1 -1
  107. package/.next/standalone/.next/server/app/waitlist/page_client-reference-manifest.js +1 -1
  108. package/.next/standalone/.next/server/app/waitlist.html +1 -1
  109. package/.next/standalone/.next/server/app/waitlist.rsc +1 -1
  110. package/.next/standalone/.next/server/app/waitlist.segments/_full.segment.rsc +1 -1
  111. package/.next/standalone/.next/server/app/waitlist.segments/_head.segment.rsc +1 -1
  112. package/.next/standalone/.next/server/app/waitlist.segments/_index.segment.rsc +1 -1
  113. package/.next/standalone/.next/server/app/waitlist.segments/_tree.segment.rsc +1 -1
  114. package/.next/standalone/.next/server/app/waitlist.segments/waitlist/__PAGE__.segment.rsc +1 -1
  115. package/.next/standalone/.next/server/app/waitlist.segments/waitlist.segment.rsc +1 -1
  116. package/.next/standalone/.next/server/app/workspace/[...path]/page_client-reference-manifest.js +1 -1
  117. package/.next/standalone/.next/server/app/workspace/page_client-reference-manifest.js +1 -1
  118. package/.next/standalone/.next/server/app/workspace/search/page_client-reference-manifest.js +1 -1
  119. package/.next/standalone/.next/server/app/workspace/search.html +2 -2
  120. package/.next/standalone/.next/server/app/workspace/search.rsc +2 -2
  121. package/.next/standalone/.next/server/app/workspace/search.segments/_full.segment.rsc +2 -2
  122. package/.next/standalone/.next/server/app/workspace/search.segments/_head.segment.rsc +1 -1
  123. package/.next/standalone/.next/server/app/workspace/search.segments/_index.segment.rsc +1 -1
  124. package/.next/standalone/.next/server/app/workspace/search.segments/_tree.segment.rsc +1 -1
  125. package/.next/standalone/.next/server/app/workspace/search.segments/workspace/search/__PAGE__.segment.rsc +1 -1
  126. package/.next/standalone/.next/server/app/workspace/search.segments/workspace/search.segment.rsc +1 -1
  127. package/.next/standalone/.next/server/app/workspace/search.segments/workspace.segment.rsc +2 -2
  128. package/.next/standalone/.next/server/app/workspace.html +2 -2
  129. package/.next/standalone/.next/server/app/workspace.rsc +2 -2
  130. package/.next/standalone/.next/server/app/workspace.segments/_full.segment.rsc +2 -2
  131. package/.next/standalone/.next/server/app/workspace.segments/_head.segment.rsc +1 -1
  132. package/.next/standalone/.next/server/app/workspace.segments/_index.segment.rsc +1 -1
  133. package/.next/standalone/.next/server/app/workspace.segments/_tree.segment.rsc +1 -1
  134. package/.next/standalone/.next/server/app/workspace.segments/workspace/__PAGE__.segment.rsc +1 -1
  135. package/.next/standalone/.next/server/app/workspace.segments/workspace.segment.rsc +2 -2
  136. package/.next/standalone/.next/server/app-paths-manifest.json +10 -10
  137. package/.next/standalone/.next/server/chunks/1210.js +2 -2
  138. package/.next/standalone/.next/server/chunks/2461.js +1 -1
  139. package/.next/standalone/.next/server/chunks/8349.js +1 -1
  140. package/.next/standalone/.next/server/chunks/8353.js +1 -1
  141. package/.next/standalone/.next/server/middleware-build-manifest.js +1 -1
  142. package/.next/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  143. package/.next/standalone/.next/server/pages/404.html +1 -1
  144. package/.next/standalone/.next/server/pages/500.html +2 -2
  145. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  146. package/.next/standalone/node_modules/buffer-from/index.js +72 -0
  147. package/.next/standalone/node_modules/buffer-from/package.json +19 -0
  148. package/.next/standalone/node_modules/source-map/lib/array-set.js +121 -0
  149. package/.next/standalone/node_modules/source-map/lib/base64-vlq.js +140 -0
  150. package/.next/standalone/node_modules/source-map/lib/base64.js +67 -0
  151. package/.next/standalone/node_modules/source-map/lib/binary-search.js +111 -0
  152. package/.next/standalone/node_modules/source-map/lib/mapping-list.js +79 -0
  153. package/.next/standalone/node_modules/source-map/lib/quick-sort.js +114 -0
  154. package/.next/standalone/node_modules/source-map/lib/source-map-consumer.js +1145 -0
  155. package/.next/standalone/node_modules/source-map/lib/source-map-generator.js +425 -0
  156. package/.next/standalone/node_modules/source-map/lib/source-node.js +413 -0
  157. package/.next/standalone/node_modules/source-map/lib/util.js +488 -0
  158. package/.next/standalone/node_modules/source-map/package.json +73 -0
  159. package/.next/standalone/node_modules/source-map/source-map.js +8 -0
  160. package/.next/standalone/node_modules/source-map-support/package.json +31 -0
  161. package/.next/standalone/node_modules/source-map-support/source-map-support.js +625 -0
  162. package/.next/standalone/package.json +50 -2
  163. package/.next/static/chunks/1285-5a2da086334493ab.js +9 -0
  164. package/.next/static/chunks/{6361.30ea8932d09b0d43.js → 6361.4027eebdd6a32ea5.js} +10 -10
  165. package/.next/static/chunks/{webpack-d35467e84f0e8517.js → webpack-bae8b6e8f6434041.js} +1 -1
  166. package/bin/clawpad.js +114 -5
  167. package/desktop/main.mjs +246 -0
  168. package/package.json +50 -2
  169. package/.next/static/chunks/1285-4a6c410db884bf7b.js +0 -9
  170. /package/.next/static/{T15gnrz7Vzb4Fk8oyeO0c → wKlPJe_kS6vhLy0YQ8diN}/_buildManifest.js +0 -0
  171. /package/.next/static/{T15gnrz7Vzb4Fk8oyeO0c → wKlPJe_kS6vhLy0YQ8diN}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- (()=>{"use strict";var e,t,r,o,n,a,i,l,c,d={},u={};function s(e){var t=u[e];if(void 0!==t)return t.exports;var r=u[e]={exports:{}},o=!0;try{d[e].call(r.exports,r,r.exports,s),o=!1}finally{o&&delete u[e]}return r.exports}s.m=d,e=[],s.O=(t,r,o,n)=>{if(r){n=n||0;for(var a=e.length;a>0&&e[a-1][2]>n;a--)e[a]=e[a-1];e[a]=[r,o,n];return}for(var i=1/0,a=0;a<e.length;a++){for(var[r,o,n]=e[a],l=!0,c=0;c<r.length;c++)(!1&n||i>=n)&&Object.keys(s.O).every(e=>s.O[e](r[c]))?r.splice(c--,1):(l=!1,n<i&&(i=n));if(l){e.splice(a--,1);var d=o();void 0!==d&&(t=d)}}return t},s.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return s.d(t,{a:t}),t},r=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,s.t=function(e,o){if(1&o&&(e=this(e)),8&o||"object"==typeof e&&e&&(4&o&&e.__esModule||16&o&&"function"==typeof e.then))return e;var n=Object.create(null);s.r(n);var a={};t=t||[null,r({}),r([]),r(r)];for(var i=2&o&&e;"object"==typeof i&&!~t.indexOf(i);i=r(i))Object.getOwnPropertyNames(i).forEach(t=>a[t]=()=>e[t]);return a.default=()=>e,s.d(n,a),n},s.d=(e,t)=>{for(var r in t)s.o(t,r)&&!s.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},s.f={},s.e=e=>Promise.all(Object.keys(s.f).reduce((t,r)=>(s.f[r](e,t),t),[])),s.u=e=>9352===e?"static/chunks/9352-dcb425f6cf5347f4.js":"static/chunks/"+(({234:"76567b6f",277:"54a60aa6",1375:"6be7e44c",2545:"c16f53c3",4034:"0cc5eebf",4758:"c0e397d0",5004:"70e0d97a"})[e]||e)+"."+({234:"f10e15270bb8b0cf",277:"867b5520f2f42695",1375:"8771fa8ed0278196",2545:"52cb4e268737986f",3678:"620cb571eead466f",4034:"810e51166712a4fc",4758:"4d79f4a4fe21a0b3",5004:"6903b8594c742784",6361:"30ea8932d09b0d43"})[e]+".js",s.miniCssF=e=>"static/css/"+({3266:"d37476854e9e226d",7105:"d64754055f7202fb",8425:"df8c8bd97929f65b"})[e]+".css",s.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),s.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),o={},s.l=(e,t,r,n)=>{if(o[e])return void o[e].push(t);if(void 0!==r)for(var a,i,l=document.getElementsByTagName("script"),c=0;c<l.length;c++){var d=l[c];if(d.getAttribute("src")==e||d.getAttribute("data-webpack")=="_N_E:"+r){a=d;break}}a||(i=!0,(a=document.createElement("script")).charset="utf-8",a.timeout=120,s.nc&&a.setAttribute("nonce",s.nc),a.setAttribute("data-webpack","_N_E:"+r),a.src=s.tu(e)),o[e]=[t];var u=(t,r)=>{a.onerror=a.onload=null,clearTimeout(f);var n=o[e];if(delete o[e],a.parentNode&&a.parentNode.removeChild(a),n&&n.forEach(e=>e(r)),t)return t(r)},f=setTimeout(u.bind(null,void 0,{type:"timeout",target:a}),12e4);a.onerror=u.bind(null,a.onerror),a.onload=u.bind(null,a.onload),i&&document.head.appendChild(a)},s.r=e=>{"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},s.tt=()=>(void 0===n&&(n={createScriptURL:e=>e},"u">typeof trustedTypes&&trustedTypes.createPolicy&&(n=trustedTypes.createPolicy("nextjs#bundler",n))),n),s.tu=e=>s.tt().createScriptURL(e),s.p="/_next/",a={8068:0},s.f.miniCss=(e,t)=>{if(a[e])t.push(a[e]);else 0!==a[e]&&({3266:1,7105:1,8425:1})[e]&&t.push(a[e]=new Promise((t,r)=>{var o,n=s.miniCssF(e),a=s.p+n;if(((e,t)=>{for(var r=document.getElementsByTagName("link"),o=0;o<r.length;o++){var n=r[o],a=n.getAttribute("data-href")||n.getAttribute("href");if("stylesheet"===n.rel&&(a===e||a===t))return n}for(var i=document.getElementsByTagName("style"),o=0;o<i.length;o++){var n=i[o],a=n.getAttribute("data-href");if(a===e||a===t)return n}})(n,a))return t();(o=document.createElement("link")).rel="stylesheet",o.type="text/css",o.onerror=o.onload=n=>{if(o.onerror=o.onload=null,"load"===n.type)t();else{var i=n&&("load"===n.type?"missing":n.type),l=n&&n.target&&n.target.href||a,c=Error("Loading CSS chunk "+e+" failed.\n("+l+")");c.code="CSS_CHUNK_LOAD_FAILED",c.type=i,c.request=l,o.parentNode.removeChild(o),r(c)}},o.href=a,function(e){if("function"==typeof _N_E_STYLE_LOAD){let{href:t,onload:r,onerror:o}=e;_N_E_STYLE_LOAD(0===t.indexOf(window.location.origin)?new URL(t).pathname:t).then(()=>null==r?void 0:r.call(e,{type:"load"}),()=>null==o?void 0:o.call(e,{}))}else document.head.appendChild(e)}(o)}).then(()=>{a[e]=0},t=>{throw delete a[e],t}))},i={8068:0,1817:0,3334:0},s.f.j=(e,t)=>{var r=s.o(i,e)?i[e]:void 0;if(0!==r)if(r)t.push(r[2]);else if(/^(1817|3266|3334|7105|8068|8425)$/.test(e))i[e]=0;else{var o=new Promise((t,o)=>r=i[e]=[t,o]);t.push(r[2]=o);var n=s.p+s.u(e),a=Error();s.l(n,t=>{if(s.o(i,e)&&(0!==(r=i[e])&&(i[e]=void 0),r)){var o=t&&("load"===t.type?"missing":t.type),n=t&&t.target&&t.target.src;a.message="Loading chunk "+e+" failed.\n("+o+": "+n+")",a.name="ChunkLoadError",a.type=o,a.request=n,r[1](a)}},"chunk-"+e,e)}},s.O.j=e=>0===i[e],l=(e,t)=>{var r,o,[n,a,l]=t,c=0;if(n.some(e=>0!==i[e])){for(r in a)s.o(a,r)&&(s.m[r]=a[r]);if(l)var d=l(s)}for(e&&e(t);c<n.length;c++)o=n[c],s.o(i,o)&&i[o]&&i[o][0](),i[o]=0;return s.O(d)},(c=self.webpackChunk_N_E=self.webpackChunk_N_E||[]).forEach(l.bind(null,0)),c.push=l.bind(null,c.push.bind(c)),s.nc=void 0})();
1
+ (()=>{"use strict";var e,t,r,o,n,a,i,l,c,d={},u={};function s(e){var t=u[e];if(void 0!==t)return t.exports;var r=u[e]={exports:{}},o=!0;try{d[e].call(r.exports,r,r.exports,s),o=!1}finally{o&&delete u[e]}return r.exports}s.m=d,e=[],s.O=(t,r,o,n)=>{if(r){n=n||0;for(var a=e.length;a>0&&e[a-1][2]>n;a--)e[a]=e[a-1];e[a]=[r,o,n];return}for(var i=1/0,a=0;a<e.length;a++){for(var[r,o,n]=e[a],l=!0,c=0;c<r.length;c++)(!1&n||i>=n)&&Object.keys(s.O).every(e=>s.O[e](r[c]))?r.splice(c--,1):(l=!1,n<i&&(i=n));if(l){e.splice(a--,1);var d=o();void 0!==d&&(t=d)}}return t},s.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return s.d(t,{a:t}),t},r=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,s.t=function(e,o){if(1&o&&(e=this(e)),8&o||"object"==typeof e&&e&&(4&o&&e.__esModule||16&o&&"function"==typeof e.then))return e;var n=Object.create(null);s.r(n);var a={};t=t||[null,r({}),r([]),r(r)];for(var i=2&o&&e;"object"==typeof i&&!~t.indexOf(i);i=r(i))Object.getOwnPropertyNames(i).forEach(t=>a[t]=()=>e[t]);return a.default=()=>e,s.d(n,a),n},s.d=(e,t)=>{for(var r in t)s.o(t,r)&&!s.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},s.f={},s.e=e=>Promise.all(Object.keys(s.f).reduce((t,r)=>(s.f[r](e,t),t),[])),s.u=e=>9352===e?"static/chunks/9352-dcb425f6cf5347f4.js":"static/chunks/"+(({234:"76567b6f",277:"54a60aa6",1375:"6be7e44c",2545:"c16f53c3",4034:"0cc5eebf",4758:"c0e397d0",5004:"70e0d97a"})[e]||e)+"."+({234:"f10e15270bb8b0cf",277:"867b5520f2f42695",1375:"8771fa8ed0278196",2545:"52cb4e268737986f",3678:"620cb571eead466f",4034:"810e51166712a4fc",4758:"4d79f4a4fe21a0b3",5004:"6903b8594c742784",6361:"4027eebdd6a32ea5"})[e]+".js",s.miniCssF=e=>"static/css/"+({3266:"d37476854e9e226d",7105:"d64754055f7202fb",8425:"df8c8bd97929f65b"})[e]+".css",s.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),s.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),o={},s.l=(e,t,r,n)=>{if(o[e])return void o[e].push(t);if(void 0!==r)for(var a,i,l=document.getElementsByTagName("script"),c=0;c<l.length;c++){var d=l[c];if(d.getAttribute("src")==e||d.getAttribute("data-webpack")=="_N_E:"+r){a=d;break}}a||(i=!0,(a=document.createElement("script")).charset="utf-8",a.timeout=120,s.nc&&a.setAttribute("nonce",s.nc),a.setAttribute("data-webpack","_N_E:"+r),a.src=s.tu(e)),o[e]=[t];var u=(t,r)=>{a.onerror=a.onload=null,clearTimeout(f);var n=o[e];if(delete o[e],a.parentNode&&a.parentNode.removeChild(a),n&&n.forEach(e=>e(r)),t)return t(r)},f=setTimeout(u.bind(null,void 0,{type:"timeout",target:a}),12e4);a.onerror=u.bind(null,a.onerror),a.onload=u.bind(null,a.onload),i&&document.head.appendChild(a)},s.r=e=>{"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},s.tt=()=>(void 0===n&&(n={createScriptURL:e=>e},"u">typeof trustedTypes&&trustedTypes.createPolicy&&(n=trustedTypes.createPolicy("nextjs#bundler",n))),n),s.tu=e=>s.tt().createScriptURL(e),s.p="/_next/",a={8068:0},s.f.miniCss=(e,t)=>{if(a[e])t.push(a[e]);else 0!==a[e]&&({3266:1,7105:1,8425:1})[e]&&t.push(a[e]=new Promise((t,r)=>{var o,n=s.miniCssF(e),a=s.p+n;if(((e,t)=>{for(var r=document.getElementsByTagName("link"),o=0;o<r.length;o++){var n=r[o],a=n.getAttribute("data-href")||n.getAttribute("href");if("stylesheet"===n.rel&&(a===e||a===t))return n}for(var i=document.getElementsByTagName("style"),o=0;o<i.length;o++){var n=i[o],a=n.getAttribute("data-href");if(a===e||a===t)return n}})(n,a))return t();(o=document.createElement("link")).rel="stylesheet",o.type="text/css",o.onerror=o.onload=n=>{if(o.onerror=o.onload=null,"load"===n.type)t();else{var i=n&&("load"===n.type?"missing":n.type),l=n&&n.target&&n.target.href||a,c=Error("Loading CSS chunk "+e+" failed.\n("+l+")");c.code="CSS_CHUNK_LOAD_FAILED",c.type=i,c.request=l,o.parentNode.removeChild(o),r(c)}},o.href=a,function(e){if("function"==typeof _N_E_STYLE_LOAD){let{href:t,onload:r,onerror:o}=e;_N_E_STYLE_LOAD(0===t.indexOf(window.location.origin)?new URL(t).pathname:t).then(()=>null==r?void 0:r.call(e,{type:"load"}),()=>null==o?void 0:o.call(e,{}))}else document.head.appendChild(e)}(o)}).then(()=>{a[e]=0},t=>{throw delete a[e],t}))},i={8068:0,1817:0,3334:0},s.f.j=(e,t)=>{var r=s.o(i,e)?i[e]:void 0;if(0!==r)if(r)t.push(r[2]);else if(/^(1817|3266|3334|7105|8068|8425)$/.test(e))i[e]=0;else{var o=new Promise((t,o)=>r=i[e]=[t,o]);t.push(r[2]=o);var n=s.p+s.u(e),a=Error();s.l(n,t=>{if(s.o(i,e)&&(0!==(r=i[e])&&(i[e]=void 0),r)){var o=t&&("load"===t.type?"missing":t.type),n=t&&t.target&&t.target.src;a.message="Loading chunk "+e+" failed.\n("+o+": "+n+")",a.name="ChunkLoadError",a.type=o,a.request=n,r[1](a)}},"chunk-"+e,e)}},s.O.j=e=>0===i[e],l=(e,t)=>{var r,o,[n,a,l]=t,c=0;if(n.some(e=>0!==i[e])){for(r in a)s.o(a,r)&&(s.m[r]=a[r]);if(l)var d=l(s)}for(e&&e(t);c<n.length;c++)o=n[c],s.o(i,o)&&i[o]&&i[o][0](),i[o]=0;return s.O(d)},(c=self.webpackChunk_N_E=self.webpackChunk_N_E||[]).forEach(l.bind(null,0)),c.push=l.bind(null,c.push.bind(c)),s.nc=void 0})();
package/bin/clawpad.js CHANGED
@@ -381,10 +381,13 @@ function normalizeScopes(raw) {
381
381
  }
382
382
 
383
383
  function scoreScopes(scopes) {
384
- if (scopes.has("operator.admin")) return 100;
385
- if (scopes.has("operator.write")) return 90;
386
- if (scopes.has("operator.read")) return 20;
387
- return 10;
384
+ let score = 10;
385
+ if (scopes.has("operator.read")) score += 100;
386
+ if (scopes.has("operator.write")) score += 200;
387
+ if (scopes.has("operator.admin")) score += 30;
388
+ if (scopes.has("operator.approvals")) score += 5;
389
+ if (scopes.has("operator.pairing")) score += 5;
390
+ return score;
388
391
  }
389
392
 
390
393
  function extractTokenFromEntry(entry) {
@@ -1453,6 +1456,98 @@ function writeOpenClawConfig(configPath, config) {
1453
1456
  fs.writeFileSync(configPath, `${serialized}\n`, "utf-8");
1454
1457
  }
1455
1458
 
1459
+ function hasRequiredOperatorScopes(scopeSet) {
1460
+ return scopeSet.has("operator.read") && scopeSet.has("operator.write");
1461
+ }
1462
+
1463
+ function normalizeScopeArray(raw, defaults = []) {
1464
+ const scopes = normalizeScopes(raw);
1465
+ if (scopes.size === 0 && Array.isArray(defaults)) {
1466
+ for (const item of defaults) {
1467
+ const normalized = String(item || "").trim().toLowerCase();
1468
+ if (normalized) scopes.add(normalized);
1469
+ }
1470
+ }
1471
+ return [...scopes];
1472
+ }
1473
+
1474
+ function normalizeTokenEntry(entry) {
1475
+ const token = extractTokenFromEntry(entry);
1476
+ if (!token) return null;
1477
+ const scopes =
1478
+ entry && typeof entry === "object"
1479
+ ? normalizeScopeArray(entry.scopes ?? entry.scope)
1480
+ : [];
1481
+ return {
1482
+ token,
1483
+ scopes,
1484
+ };
1485
+ }
1486
+
1487
+ function migrateLegacyGatewayAuthConfig(configPath, config) {
1488
+ const auth = config?.gateway?.auth;
1489
+ if (!auth || typeof auth !== "object") {
1490
+ return { updated: false, config };
1491
+ }
1492
+
1493
+ const defaults = ["operator.read", "operator.write", "operator.admin"];
1494
+ const tokenEntries = Array.isArray(auth.tokens) ? auth.tokens.map(normalizeTokenEntry).filter(Boolean) : [];
1495
+ const hasWritableToken = tokenEntries.some((entry) => hasRequiredOperatorScopes(new Set(entry.scopes)));
1496
+ if (hasWritableToken) {
1497
+ return { updated: false, config };
1498
+ }
1499
+
1500
+ const directToken = normalizeToken(auth.token);
1501
+ let updated = false;
1502
+
1503
+ if (directToken) {
1504
+ const directScopes = normalizeScopeArray(auth.scopes ?? auth.scope, defaults);
1505
+ const rebuiltTokens = [
1506
+ { token: directToken, scopes: directScopes },
1507
+ ...tokenEntries.filter((entry) => entry.token !== directToken),
1508
+ ];
1509
+
1510
+ auth.tokens = rebuiltTokens;
1511
+ delete auth.token;
1512
+ delete auth.scope;
1513
+ delete auth.scopes;
1514
+ updated = true;
1515
+ } else if (tokenEntries.length > 0) {
1516
+ const [first, ...rest] = tokenEntries;
1517
+ if (first) {
1518
+ const merged = [...new Set([...first.scopes, ...defaults])];
1519
+ auth.tokens = [{ token: first.token, scopes: merged }, ...rest];
1520
+ updated = true;
1521
+ }
1522
+ }
1523
+
1524
+ if (!updated) {
1525
+ return { updated: false, config };
1526
+ }
1527
+
1528
+ writeOpenClawConfig(configPath, config);
1529
+ return { updated: true, config };
1530
+ }
1531
+
1532
+ function restartOpenClawGateway() {
1533
+ const commands = [
1534
+ "openclaw gateway restart",
1535
+ "openclaw daemon restart",
1536
+ ];
1537
+ for (const cmd of commands) {
1538
+ try {
1539
+ execSync(cmd, {
1540
+ stdio: "ignore",
1541
+ timeout: 20000,
1542
+ });
1543
+ return true;
1544
+ } catch {
1545
+ // try next command
1546
+ }
1547
+ }
1548
+ return false;
1549
+ }
1550
+
1456
1551
  function resolveClawpadPagesDir(config) {
1457
1552
  const explicit = process.env.CLAWPAD_PAGES_DIR;
1458
1553
  if (explicit && explicit.trim()) {
@@ -2244,7 +2339,8 @@ async function main(
2244
2339
  }
2245
2340
  console.log();
2246
2341
 
2247
- const { config } = loadOpenClawConfig();
2342
+ const loadedConfig = loadOpenClawConfig();
2343
+ let config = loadedConfig.config;
2248
2344
  const openclawInstall = await ensureOpenClawCli(platformProfile, {
2249
2345
  autoYes,
2250
2346
  noPrompt,
@@ -2267,6 +2363,19 @@ async function main(
2267
2363
  console.log(` ✅ OpenClaw CLI detected (${versionText}).`);
2268
2364
  }
2269
2365
  }
2366
+ if (openclawInstall.installed) {
2367
+ const migration = migrateLegacyGatewayAuthConfig(loadedConfig.configPath, config);
2368
+ config = migration.config;
2369
+ if (migration.updated) {
2370
+ console.log(" 🔐 Upgraded OpenClaw gateway auth to scoped token format.");
2371
+ if (restartOpenClawGateway()) {
2372
+ console.log(" ♻️ Restarted OpenClaw gateway to apply scoped token config.");
2373
+ } else {
2374
+ console.warn(" ⚠️ Updated config but could not restart gateway automatically.");
2375
+ console.warn(" Run: openclaw gateway restart");
2376
+ }
2377
+ }
2378
+ }
2270
2379
  let pagesDir = resolveClawpadPagesDir(config);
2271
2380
  const migration = await maybeMigrateLegacyPages(config, pagesDir, {
2272
2381
  hasExplicitPagesDir,
@@ -0,0 +1,246 @@
1
+ import { app, BrowserWindow, dialog, shell, utilityProcess } from "electron";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import http from "node:http";
5
+ import net from "node:net";
6
+ import { fileURLToPath } from "node:url";
7
+
8
+ const DEV_URL = process.env.CLAWPAD_ELECTRON_URL || "http://localhost:3000";
9
+ const DEFAULT_PORT = 3333;
10
+ const MAX_PORT_ATTEMPTS = 80;
11
+ const SERVER_READY_TIMEOUT_MS = 45_000;
12
+
13
+ const __filename = fileURLToPath(import.meta.url);
14
+ const __dirname = path.dirname(__filename);
15
+
16
+ let mainWindow = null;
17
+ let serverProcess = null;
18
+ let quitting = false;
19
+
20
+ function isDev() {
21
+ return !app.isPackaged;
22
+ }
23
+
24
+ function canConnect(host, port, timeoutMs = 300) {
25
+ return new Promise((resolve) => {
26
+ const socket = new net.Socket();
27
+ let settled = false;
28
+
29
+ const finish = (value) => {
30
+ if (settled) return;
31
+ settled = true;
32
+ socket.destroy();
33
+ resolve(value);
34
+ };
35
+
36
+ socket.setTimeout(timeoutMs);
37
+ socket.once("connect", () => finish(true));
38
+ socket.once("timeout", () => finish(false));
39
+ socket.once("error", () => finish(false));
40
+ socket.connect(port, host);
41
+ });
42
+ }
43
+
44
+ async function findAvailablePort(startPort = DEFAULT_PORT, attempts = MAX_PORT_ATTEMPTS) {
45
+ for (let i = 0; i < attempts; i += 1) {
46
+ const port = startPort + i;
47
+ const inUse = await canConnect("127.0.0.1", port);
48
+ if (!inUse) return port;
49
+ }
50
+ throw new Error(`No free port found from ${startPort} to ${startPort + attempts - 1}`);
51
+ }
52
+
53
+ function wait(ms) {
54
+ return new Promise((resolve) => setTimeout(resolve, ms));
55
+ }
56
+
57
+ function probeHttp(url, timeoutMs = 1_200) {
58
+ return new Promise((resolve) => {
59
+ const request = http.get(url, (res) => {
60
+ res.resume();
61
+ resolve(res.statusCode ? res.statusCode < 500 : false);
62
+ });
63
+
64
+ request.on("error", () => resolve(false));
65
+ request.setTimeout(timeoutMs, () => {
66
+ request.destroy();
67
+ resolve(false);
68
+ });
69
+ });
70
+ }
71
+
72
+ async function waitForServer(url, timeoutMs = SERVER_READY_TIMEOUT_MS) {
73
+ const startedAt = Date.now();
74
+ while (Date.now() - startedAt < timeoutMs) {
75
+ const ok = await probeHttp(url);
76
+ if (ok) return;
77
+ await wait(250);
78
+ }
79
+ throw new Error(`Timed out waiting for bundled server at ${url}`);
80
+ }
81
+
82
+ function copyDirIfMissing(src, dest) {
83
+ if (fs.existsSync(dest)) return;
84
+ if (!fs.existsSync(src)) return;
85
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
86
+ fs.cpSync(src, dest, { recursive: true });
87
+ }
88
+
89
+ function prepareStandaloneAssets(appRoot, standaloneDir) {
90
+ const staticSrc = path.join(appRoot, ".next", "static");
91
+ const staticDest = path.join(standaloneDir, ".next", "static");
92
+ const publicSrc = path.join(appRoot, "public");
93
+ const publicDest = path.join(standaloneDir, "public");
94
+
95
+ copyDirIfMissing(staticSrc, staticDest);
96
+ copyDirIfMissing(publicSrc, publicDest);
97
+ }
98
+
99
+ function stopBundledServer() {
100
+ if (!serverProcess) return;
101
+ const proc = serverProcess;
102
+ serverProcess = null;
103
+ proc.kill();
104
+ }
105
+
106
+ async function startBundledServer() {
107
+ const appRoot = app.getAppPath();
108
+ const standaloneDir = path.join(appRoot, ".next", "standalone");
109
+ const serverEntry = path.join(standaloneDir, "server.js");
110
+
111
+ if (!fs.existsSync(serverEntry)) {
112
+ throw new Error(
113
+ `Missing bundled server entry at ${serverEntry}. Run "npm run desktop:build:prep" first.`,
114
+ );
115
+ }
116
+
117
+ prepareStandaloneAssets(appRoot, standaloneDir);
118
+
119
+ const port = await findAvailablePort(DEFAULT_PORT);
120
+ const serverUrl = `http://127.0.0.1:${port}`;
121
+
122
+ // Use utilityProcess so the server runs headlessly without creating a second Dock app.
123
+ serverProcess = utilityProcess.fork(serverEntry, [], {
124
+ cwd: standaloneDir,
125
+ stdio: "pipe",
126
+ serviceName: "ClawPad Server",
127
+ env: {
128
+ ...process.env,
129
+ PORT: String(port),
130
+ HOSTNAME: "127.0.0.1",
131
+ },
132
+ });
133
+
134
+ serverProcess.stdout?.on("data", (chunk) => {
135
+ process.stdout.write(`[desktop-server] ${chunk}`);
136
+ });
137
+
138
+ serverProcess.stderr?.on("data", (chunk) => {
139
+ process.stderr.write(`[desktop-server] ${chunk}`);
140
+ });
141
+
142
+ const exitedEarly = new Promise((_, reject) => {
143
+ serverProcess.once("exit", (code) => {
144
+ reject(new Error(`Bundled server exited early (code=${code})`));
145
+ });
146
+ });
147
+
148
+ await Promise.race([
149
+ waitForServer(`${serverUrl}/api/version`),
150
+ exitedEarly,
151
+ ]);
152
+
153
+ return serverUrl;
154
+ }
155
+
156
+ async function resolveStartUrl() {
157
+ if (isDev()) {
158
+ return DEV_URL;
159
+ }
160
+ return startBundledServer();
161
+ }
162
+
163
+ async function createMainWindow() {
164
+ const startUrl = await resolveStartUrl();
165
+
166
+ mainWindow = new BrowserWindow({
167
+ width: 1440,
168
+ height: 920,
169
+ minWidth: 980,
170
+ minHeight: 680,
171
+ show: false,
172
+ autoHideMenuBar: false,
173
+ backgroundColor: "#0b0f14",
174
+ webPreferences: {
175
+ preload: path.join(__dirname, "preload.mjs"),
176
+ contextIsolation: true,
177
+ nodeIntegration: false,
178
+ sandbox: false,
179
+ },
180
+ });
181
+
182
+ mainWindow.once("ready-to-show", () => {
183
+ mainWindow.show();
184
+ });
185
+
186
+ mainWindow.webContents.setWindowOpenHandler(({ url }) => {
187
+ shell.openExternal(url);
188
+ return { action: "deny" };
189
+ });
190
+
191
+ await mainWindow.loadURL(startUrl);
192
+
193
+ mainWindow.on("closed", () => {
194
+ mainWindow = null;
195
+ });
196
+ }
197
+
198
+ app.on("second-instance", () => {
199
+ if (!mainWindow) return;
200
+ if (mainWindow.isMinimized()) mainWindow.restore();
201
+ mainWindow.focus();
202
+ });
203
+
204
+ const lock = app.requestSingleInstanceLock();
205
+ if (!lock) {
206
+ app.quit();
207
+ } else {
208
+ app.whenReady().then(async () => {
209
+ try {
210
+ await createMainWindow();
211
+ } catch (error) {
212
+ dialog.showErrorBox(
213
+ "ClawPad failed to start",
214
+ error instanceof Error ? error.message : String(error),
215
+ );
216
+ app.quit();
217
+ return;
218
+ }
219
+
220
+ app.on("activate", async () => {
221
+ if (BrowserWindow.getAllWindows().length === 0) {
222
+ try {
223
+ await createMainWindow();
224
+ } catch (error) {
225
+ dialog.showErrorBox(
226
+ "ClawPad failed to re-open",
227
+ error instanceof Error ? error.message : String(error),
228
+ );
229
+ }
230
+ }
231
+ });
232
+ });
233
+
234
+ app.on("before-quit", () => {
235
+ quitting = true;
236
+ stopBundledServer();
237
+ });
238
+
239
+ app.on("window-all-closed", () => {
240
+ if (process.platform !== "darwin") {
241
+ app.quit();
242
+ } else if (quitting) {
243
+ stopBundledServer();
244
+ }
245
+ });
246
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawpad",
3
- "version": "0.4.11",
3
+ "version": "0.4.12",
4
4
  "description": "A file-based, Notion-style document workspace for OpenClaw",
5
5
  "keywords": [
6
6
  "openclaw",
@@ -21,6 +21,7 @@
21
21
  "bin": {
22
22
  "clawpad": "./bin/clawpad.js"
23
23
  },
24
+ "main": "desktop/main.mjs",
24
25
  "engines": {
25
26
  "node": ">=18"
26
27
  },
@@ -39,6 +40,11 @@
39
40
  "build": "next build --webpack",
40
41
  "start": "next start",
41
42
  "postinstall": "node bin/postinstall-repair.js",
43
+ "desktop:dev": "concurrently -k \"npm run dev\" \"wait-on http://localhost:3000 && electron .\"",
44
+ "desktop:build:prep": "npm run build && node scripts/prepare-standalone.mjs",
45
+ "desktop:build:mac": "npm run desktop:build:prep && electron-builder --mac dmg",
46
+ "desktop:build:win": "npm run desktop:build:prep && electron-builder --win nsis",
47
+ "desktop:build": "npm run desktop:build:prep && electron-builder --mac dmg --win nsis",
42
48
  "lint": "eslint",
43
49
  "test": "tsx --test --test-concurrency=1 tests/**/*.test.ts",
44
50
  "test:unit": "tsx --test --test-concurrency=1 tests/unit/**/*.test.ts",
@@ -48,6 +54,44 @@
48
54
  "check:installer:live": "bash scripts/check-live-installer.sh",
49
55
  "prepublishOnly": "next build --webpack"
50
56
  },
57
+ "build": {
58
+ "appId": "io.clawpad.desktop",
59
+ "productName": "ClawPad",
60
+ "icon": "desktop/assets/icon.png",
61
+ "directories": {
62
+ "output": "dist-desktop"
63
+ },
64
+ "files": [
65
+ "desktop/**/*",
66
+ ".next/standalone/**/*",
67
+ ".next/static/**/*",
68
+ "public/**/*",
69
+ "package.json"
70
+ ],
71
+ "asar": false,
72
+ "mac": {
73
+ "target": [
74
+ "dmg"
75
+ ],
76
+ "icon": "desktop/assets/icon.icns",
77
+ "category": "public.app-category.productivity",
78
+ "hardenedRuntime": true,
79
+ "gatekeeperAssess": false,
80
+ "entitlements": "build/entitlements.mac.plist",
81
+ "entitlementsInherit": "build/entitlements.mac.plist"
82
+ },
83
+ "win": {
84
+ "target": [
85
+ "nsis"
86
+ ],
87
+ "icon": "desktop/assets/icon.ico"
88
+ },
89
+ "nsis": {
90
+ "oneClick": false,
91
+ "allowToChangeInstallationDirectory": true,
92
+ "perMachine": false
93
+ }
94
+ },
51
95
  "dependencies": {
52
96
  "@ai-sdk/openai": "^3.0.25",
53
97
  "@ai-sdk/react": "^3.0.71",
@@ -86,11 +130,15 @@
86
130
  "@types/react": "^19",
87
131
  "@types/react-dom": "^19",
88
132
  "@types/ws": "^8.18.1",
133
+ "concurrently": "^9.2.1",
134
+ "electron": "^37.7.0",
135
+ "electron-builder": "^26.0.16",
89
136
  "eslint": "^9",
90
137
  "eslint-config-next": "16.1.6",
91
138
  "tailwindcss": "^4",
92
139
  "tsx": "^4.21.0",
93
140
  "tw-animate-css": "^1.4.0",
94
- "typescript": "^5"
141
+ "typescript": "^5",
142
+ "wait-on": "^9.0.3"
95
143
  }
96
144
  }