clawpad 0.4.10 → 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 (172) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +5 -5
  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 +5 -5
  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 +51 -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 +239 -5
  167. package/bin/postinstall-repair.js +79 -0
  168. package/desktop/main.mjs +246 -0
  169. package/package.json +51 -2
  170. package/.next/static/chunks/1285-4a6c410db884bf7b.js +0 -9
  171. /package/.next/static/{1UGyv1hkNZ7yaspLRoDX6 → wKlPJe_kS6vhLy0YQ8diN}/_buildManifest.js +0 -0
  172. /package/.next/static/{1UGyv1hkNZ7yaspLRoDX6 → 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
@@ -34,11 +34,21 @@ const CURRENT_VERSION = (() => {
34
34
  return "0.0.0";
35
35
  }
36
36
  })();
37
+ const CURRENT_LAUNCHER_REALPATH = (() => {
38
+ try {
39
+ if (!process.argv[1]) return null;
40
+ return fs.realpathSync(process.argv[1]);
41
+ } catch {
42
+ return null;
43
+ }
44
+ })();
37
45
 
38
46
  // ─── Arg Parsing ─────────────────────────────────────────
39
47
  const args = process.argv.slice(2);
40
48
 
41
49
  async function bootstrap() {
50
+ maybeHandoffToNewerInstall(args);
51
+
42
52
  // Handle Cloud Share Command
43
53
  if (args[0] === "share") {
44
54
  await startShare(args.slice(1));
@@ -173,6 +183,121 @@ function compareSemver(a, b) {
173
183
  return 0;
174
184
  }
175
185
 
186
+ function parseCliPaths(output) {
187
+ return String(output || "")
188
+ .split(/\r?\n/g)
189
+ .map((line) => line.trim())
190
+ .filter(Boolean);
191
+ }
192
+
193
+ function collectCandidateClawpadExecutables() {
194
+ const candidates = [];
195
+ if (process.platform === "win32") {
196
+ const result = runBinary("where", ["clawpad"]);
197
+ if (result.ok) {
198
+ candidates.push(...parseCliPaths(result.stdout));
199
+ }
200
+ } else {
201
+ const result = runBinary("which", ["-a", "clawpad"]);
202
+ if (result.ok) {
203
+ candidates.push(...parseCliPaths(result.stdout));
204
+ }
205
+ }
206
+
207
+ // Include common global install locations in case shell lookup misses one.
208
+ candidates.push(
209
+ path.join(os.homedir(), ".local", "bin", "clawpad"),
210
+ "/opt/homebrew/bin/clawpad",
211
+ "/usr/local/bin/clawpad",
212
+ );
213
+
214
+ const dedup = new Set();
215
+ const existing = [];
216
+ for (const candidate of candidates) {
217
+ const resolved = String(candidate || "").trim();
218
+ if (!resolved || dedup.has(resolved)) continue;
219
+ dedup.add(resolved);
220
+ try {
221
+ fs.accessSync(resolved, fs.constants.X_OK);
222
+ existing.push(resolved);
223
+ } catch {
224
+ // ignore
225
+ }
226
+ }
227
+ return existing;
228
+ }
229
+
230
+ function resolveClawpadPackageInfo(executablePath) {
231
+ let launcherRealpath;
232
+ try {
233
+ launcherRealpath = fs.realpathSync(executablePath);
234
+ } catch {
235
+ return null;
236
+ }
237
+
238
+ let dir = path.dirname(launcherRealpath);
239
+ for (let i = 0; i < 8; i += 1) {
240
+ const pkgPath = path.join(dir, "package.json");
241
+ try {
242
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
243
+ if (pkg && pkg.name === "clawpad" && typeof pkg.version === "string") {
244
+ return {
245
+ executablePath,
246
+ launcherRealpath,
247
+ packageRoot: dir,
248
+ version: pkg.version,
249
+ };
250
+ }
251
+ } catch {
252
+ // continue walking up
253
+ }
254
+ const parent = path.dirname(dir);
255
+ if (parent === dir) break;
256
+ dir = parent;
257
+ }
258
+ return null;
259
+ }
260
+
261
+ function maybeHandoffToNewerInstall(cliArgs) {
262
+ if (process.env.CLAWPAD_HANDOFF_DONE === "1") return;
263
+ if (process.env.CLAWPAD_DISABLE_HANDOFF === "1") return;
264
+
265
+ // In source checkouts, keep local run behavior predictable for development.
266
+ try {
267
+ if (fs.existsSync(path.join(ROOT_DIR, ".git"))) return;
268
+ } catch {
269
+ // ignore
270
+ }
271
+
272
+ const currentVersion = CURRENT_VERSION;
273
+ const candidates = collectCandidateClawpadExecutables()
274
+ .map(resolveClawpadPackageInfo)
275
+ .filter(Boolean)
276
+ .filter((info) => info.launcherRealpath !== CURRENT_LAUNCHER_REALPATH);
277
+
278
+ if (candidates.length === 0) return;
279
+
280
+ candidates.sort((a, b) => compareSemver(b.version, a.version));
281
+ const best = candidates[0];
282
+ if (!best) return;
283
+ if (compareSemver(best.version, currentVersion) <= 0) return;
284
+
285
+ console.log(
286
+ ` 🔁 Found newer ClawPad install (${best.version}). Relaunching from ${best.executablePath}...`,
287
+ );
288
+ const handoff = spawnSync(best.executablePath, cliArgs, {
289
+ stdio: "inherit",
290
+ windowsHide: true,
291
+ env: { ...process.env, CLAWPAD_HANDOFF_DONE: "1" },
292
+ });
293
+ if (handoff.error) {
294
+ console.warn(` ⚠️ Relaunch failed: ${handoff.error.message}`);
295
+ return;
296
+ }
297
+ const code = typeof handoff.status === "number" ? handoff.status : 0;
298
+ process.exit(code);
299
+ }
300
+
176
301
  async function checkForUpdates(currentVersion, platformProfile) {
177
302
  if (process.env.CLAWPAD_SKIP_UPDATE_CHECK === "1") return;
178
303
  if (process.env.CI === "1" || process.env.NODE_ENV === "test") return;
@@ -256,10 +381,13 @@ function normalizeScopes(raw) {
256
381
  }
257
382
 
258
383
  function scoreScopes(scopes) {
259
- if (scopes.has("operator.admin")) return 100;
260
- if (scopes.has("operator.write")) return 90;
261
- if (scopes.has("operator.read")) return 20;
262
- 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;
263
391
  }
264
392
 
265
393
  function extractTokenFromEntry(entry) {
@@ -1328,6 +1456,98 @@ function writeOpenClawConfig(configPath, config) {
1328
1456
  fs.writeFileSync(configPath, `${serialized}\n`, "utf-8");
1329
1457
  }
1330
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
+
1331
1551
  function resolveClawpadPagesDir(config) {
1332
1552
  const explicit = process.env.CLAWPAD_PAGES_DIR;
1333
1553
  if (explicit && explicit.trim()) {
@@ -2119,7 +2339,8 @@ async function main(
2119
2339
  }
2120
2340
  console.log();
2121
2341
 
2122
- const { config } = loadOpenClawConfig();
2342
+ const loadedConfig = loadOpenClawConfig();
2343
+ let config = loadedConfig.config;
2123
2344
  const openclawInstall = await ensureOpenClawCli(platformProfile, {
2124
2345
  autoYes,
2125
2346
  noPrompt,
@@ -2142,6 +2363,19 @@ async function main(
2142
2363
  console.log(` ✅ OpenClaw CLI detected (${versionText}).`);
2143
2364
  }
2144
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
+ }
2145
2379
  let pagesDir = resolveClawpadPagesDir(config);
2146
2380
  const migration = await maybeMigrateLegacyPages(config, pagesDir, {
2147
2381
  hasExplicitPagesDir,
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require("fs");
4
+ const os = require("os");
5
+ const path = require("path");
6
+
7
+ function isGlobalInstall() {
8
+ return (
9
+ process.env.npm_config_global === "true" ||
10
+ process.env.npm_config_location === "global"
11
+ );
12
+ }
13
+
14
+ function isManagedClawpadLinkTarget(targetPath) {
15
+ const normalized = String(targetPath || "").replace(/\\/g, "/");
16
+ return normalized.includes("/node_modules/clawpad/bin/clawpad.js");
17
+ }
18
+
19
+ function repairLocalBinSymlink() {
20
+ const binTarget = path.resolve(__dirname, "clawpad.js");
21
+ if (!fs.existsSync(binTarget)) return;
22
+
23
+ const localBinDir = path.join(os.homedir(), ".local", "bin");
24
+ const launcherLink = path.join(localBinDir, "clawpad");
25
+
26
+ try {
27
+ fs.mkdirSync(localBinDir, { recursive: true });
28
+ } catch {
29
+ return;
30
+ }
31
+
32
+ let stat = null;
33
+ try {
34
+ stat = fs.lstatSync(launcherLink);
35
+ } catch {
36
+ stat = null;
37
+ }
38
+
39
+ if (!stat) {
40
+ try {
41
+ fs.symlinkSync(binTarget, launcherLink);
42
+ console.log(`clawpad: linked ${launcherLink} -> ${binTarget}`);
43
+ } catch {
44
+ // ignore
45
+ }
46
+ return;
47
+ }
48
+
49
+ if (!stat.isSymbolicLink()) {
50
+ return;
51
+ }
52
+
53
+ let currentTarget;
54
+ try {
55
+ currentTarget = path.resolve(path.dirname(launcherLink), fs.readlinkSync(launcherLink));
56
+ } catch {
57
+ return;
58
+ }
59
+
60
+ if (currentTarget === binTarget) return;
61
+ if (!isManagedClawpadLinkTarget(currentTarget)) return;
62
+
63
+ try {
64
+ fs.unlinkSync(launcherLink);
65
+ fs.symlinkSync(binTarget, launcherLink);
66
+ console.log(`clawpad: updated ${launcherLink} -> ${binTarget}`);
67
+ } catch {
68
+ // ignore
69
+ }
70
+ }
71
+
72
+ function main() {
73
+ if (process.env.CLAWPAD_SKIP_POSTINSTALL_REPAIR === "1") return;
74
+ if (!isGlobalInstall()) return;
75
+ if (process.platform === "win32") return;
76
+ repairLocalBinSymlink();
77
+ }
78
+
79
+ main();
@@ -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
+ }