nextclaw 0.31.0 → 0.32.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 (231) hide show
  1. package/dist/cli/app/index.js +1 -1
  2. package/dist/cli/launcher/index.js +1 -1
  3. package/dist/{nextclaw-distribution.utils-D6Rz73fp.js → nextclaw-distribution.utils-CfUuTwjt.js} +3 -2
  4. package/dist/{nextclaw-distribution.utils-D6Rz73fp.js.map → nextclaw-distribution.utils-CfUuTwjt.js.map} +1 -1
  5. package/package.json +14 -14
  6. package/resources/apps/nextclaw-personal-organizer/README.md +24 -0
  7. package/resources/apps/nextclaw-personal-organizer/assets/icon.svg +13 -0
  8. package/resources/apps/nextclaw-personal-organizer/manifest.json +44 -0
  9. package/resources/apps/nextclaw-personal-organizer/marketplace.json +18 -0
  10. package/resources/apps/nextclaw-personal-organizer/panels/nextclaw-personal-organizer-calendar.panel/index.html +24 -0
  11. package/resources/apps/nextclaw-personal-organizer/panels/nextclaw-personal-organizer-calendar.panel/panel-app.json +21 -0
  12. package/resources/apps/nextclaw-personal-organizer/panels/nextclaw-personal-organizer-favorites.panel/index.html +23 -0
  13. package/resources/apps/nextclaw-personal-organizer/panels/nextclaw-personal-organizer-favorites.panel/panel-app.json +18 -0
  14. package/resources/apps/nextclaw-personal-organizer/panels/nextclaw-personal-organizer-notes.panel/index.html +28 -0
  15. package/resources/apps/nextclaw-personal-organizer/panels/nextclaw-personal-organizer-notes.panel/panel-app.json +18 -0
  16. package/resources/apps/nextclaw-personal-organizer/panels/nextclaw-personal-organizer-todos.panel/index.html +43 -0
  17. package/resources/apps/nextclaw-personal-organizer/panels/nextclaw-personal-organizer-todos.panel/panel-app.json +18 -0
  18. package/resources/apps/nextclaw-personal-organizer/service-components/nextclaw-personal-organizer-data/calendar-subscription.service.mjs +152 -0
  19. package/resources/apps/nextclaw-personal-organizer/service-components/nextclaw-personal-organizer-data/index.mjs +341 -0
  20. package/resources/apps/nextclaw-personal-organizer/service-components/nextclaw-personal-organizer-data/service-app.json +35 -0
  21. package/ui-dist/assets/{abnfDiagram-VRR7QNED-DvTjgVMf.js → abnfDiagram-VRR7QNED-BcFJp_1X.js} +1 -1
  22. package/ui-dist/assets/{aiden0z-pptx-renderer.es-C1nfBAXR.js → aiden0z-pptx-renderer.es-Dp2ezlQn.js} +1 -1
  23. package/ui-dist/assets/{api-FK7tikI1.js → api-CK3Fro7z.js} +6 -6
  24. package/ui-dist/assets/appearance-settings-page-zqwWO8Dy.js +1 -0
  25. package/ui-dist/assets/{arc-BvhODBXv.js → arc-CkgyPMyW.js} +1 -1
  26. package/ui-dist/assets/architecture-TIHT7OUA-DO2x53FK.js +1 -0
  27. package/ui-dist/assets/{architectureDiagram-ZJ3FMSHR-BKO9RgNS.js → architectureDiagram-ZJ3FMSHR-CMd4cIjI.js} +1 -1
  28. package/ui-dist/assets/{blockDiagram-677ZJIJ3-DHpDXy7D.js → blockDiagram-677ZJIJ3-Bz3tbhet.js} +1 -1
  29. package/ui-dist/assets/{c4Diagram-LMCZKHZV-BG_iQnDr.js → c4Diagram-LMCZKHZV-D9hFNAGv.js} +1 -1
  30. package/ui-dist/assets/channel-nBvMaVyP.js +1 -0
  31. package/ui-dist/assets/{channels-list-page-CocdcIko.js → channels-list-page-CVCZBlCL.js} +2 -2
  32. package/ui-dist/assets/chat-page-D4wehRTz.js +1 -0
  33. package/ui-dist/assets/chunk-2Q5K7J3B-CJgqFDS4.js +1 -0
  34. package/ui-dist/assets/{chunk-32BRIVSS-DR9M0LLx.js → chunk-32BRIVSS-7NrjEITq.js} +1 -1
  35. package/ui-dist/assets/{chunk-52WLFC77-698iC3BB.js → chunk-52WLFC77-viIcqj9q.js} +1 -1
  36. package/ui-dist/assets/{chunk-5FCAYU7R-DikTj9Ey.js → chunk-5FCAYU7R-Vsu4J-VM.js} +1 -1
  37. package/ui-dist/assets/{chunk-5HE753X5-ko0o7_q0.js → chunk-5HE753X5-C-w6CQZK.js} +1 -1
  38. package/ui-dist/assets/{chunk-5JV3BV7I-CEHufhgo.js → chunk-5JV3BV7I-CuKgJQ4W.js} +1 -1
  39. package/ui-dist/assets/{chunk-5TONJI2A-CGgno1cu.js → chunk-5TONJI2A-CYeiWZKb.js} +1 -1
  40. package/ui-dist/assets/{chunk-5VM5RSS4-DkiB4cUQ.js → chunk-5VM5RSS4-DRCbfwIn.js} +1 -1
  41. package/ui-dist/assets/{chunk-7BUUIJ7U-DzptcytQ.js → chunk-7BUUIJ7U-BvydOcm3.js} +1 -1
  42. package/ui-dist/assets/{chunk-BIQX33UG-DMRSQJvT.js → chunk-BIQX33UG-RlppOXKo.js} +1 -1
  43. package/ui-dist/assets/{chunk-C7G6YPKG-Bw1BwwuY.js → chunk-C7G6YPKG-DAizzYwr.js} +1 -1
  44. package/ui-dist/assets/{chunk-CQNSW5MT-C0z6eHBk.js → chunk-CQNSW5MT-5eChJHca.js} +1 -1
  45. package/ui-dist/assets/{chunk-CYSBUYHQ-ByPyAouO.js → chunk-CYSBUYHQ-YHPr53fv.js} +1 -1
  46. package/ui-dist/assets/{chunk-EMLP6XTP-CJlAXWZg.js → chunk-EMLP6XTP-CK4D7Hz5.js} +1 -1
  47. package/ui-dist/assets/{chunk-EX3LRPZG-Dqq4zKJu.js → chunk-EX3LRPZG-BmlDFIRW.js} +1 -1
  48. package/ui-dist/assets/{chunk-FWX5IMBZ-B0SNoCmi.js → chunk-FWX5IMBZ-D0ksHZZ9.js} +2 -2
  49. package/ui-dist/assets/{chunk-HOUHSVGY-DG_GJih_.js → chunk-HOUHSVGY-DPkq8FCm.js} +1 -1
  50. package/ui-dist/assets/{chunk-ICXQ74PX-Drxk_6bE.js → chunk-ICXQ74PX-FAatv5fC.js} +1 -1
  51. package/ui-dist/assets/{chunk-JG7HCLWE-DdLFPpnd.js → chunk-JG7HCLWE-DLkIi4F7.js} +1 -1
  52. package/ui-dist/assets/{chunk-JWPE2WC7-B8M4G76F.js → chunk-JWPE2WC7-DawOjNE3.js} +1 -1
  53. package/ui-dist/assets/{chunk-MOJQB5TN-XP6FJHY_.js → chunk-MOJQB5TN-Di52TorW.js} +1 -1
  54. package/ui-dist/assets/{chunk-MOZMSUNE-C_6x18Qw.js → chunk-MOZMSUNE-PfyK9w1-.js} +1 -1
  55. package/ui-dist/assets/{chunk-OGEWGWER-N25BzCmG.js → chunk-OGEWGWER-C3jdH3Ty.js} +1 -1
  56. package/ui-dist/assets/{chunk-OSBZ3O6U-ASDEm7y0.js → chunk-OSBZ3O6U-CecHo-f0.js} +1 -1
  57. package/ui-dist/assets/{chunk-PUDLZKDR-CTlvAcn7.js → chunk-PUDLZKDR-f3IJh3sN.js} +1 -1
  58. package/ui-dist/assets/{chunk-Q4XR5HBZ-Da9BWfB6.js → chunk-Q4XR5HBZ-DQFeUPxZ.js} +1 -1
  59. package/ui-dist/assets/{chunk-QBLGF6JB-Bi6RpTJO.js → chunk-QBLGF6JB-BhUeG0y2.js} +1 -1
  60. package/ui-dist/assets/{chunk-R7FJI6CG-DkMsSPvK.js → chunk-R7FJI6CG-C3XpZ-2u.js} +1 -1
  61. package/ui-dist/assets/{chunk-RYQCIY6F-DZp0eU-j.js → chunk-RYQCIY6F-CAqa5klQ.js} +1 -1
  62. package/ui-dist/assets/{chunk-U6XO7XAA-vfinDSrj.js → chunk-U6XO7XAA-D_WXezeD.js} +1 -1
  63. package/ui-dist/assets/{chunk-V7JOEXUC-C9Nksccs.js → chunk-V7JOEXUC-CZ70oOtp.js} +1 -1
  64. package/ui-dist/assets/chunk-VAUOI2AC-BGvh3yIx.js +1 -0
  65. package/ui-dist/assets/{chunk-VR4S4FIN-Xv6zfwXs.js → chunk-VR4S4FIN-B7AHEYYk.js} +1 -1
  66. package/ui-dist/assets/{chunk-WYO6CB5R-mOJNzbWl.js → chunk-WYO6CB5R-Dn9To_OI.js} +2 -2
  67. package/ui-dist/assets/chunk-XXDRQBXY-DaBxG5gs.js +1 -0
  68. package/ui-dist/assets/{chunk-YOTPTUD7-1-aKSu4o.js → chunk-YOTPTUD7-BYEgRBk3.js} +1 -1
  69. package/ui-dist/assets/{chunk-ZGVPDNZ5-OJ8veMpK.js → chunk-ZGVPDNZ5-C6YtZDU0.js} +1 -1
  70. package/ui-dist/assets/{chunk-ZIRB5QZD-SR_Nq_PP.js → chunk-ZIRB5QZD-DMuYtnHF.js} +1 -1
  71. package/ui-dist/assets/classDiagram-OUVF2IWQ-P6N03G2R.js +1 -0
  72. package/ui-dist/assets/classDiagram-v2-EOCWNBFH-B1_uLvMv.js +1 -0
  73. package/ui-dist/assets/config-split-page-CceNFvlY.js +1 -0
  74. package/ui-dist/assets/confirm-dialog-CWeNYWZY.js +5 -0
  75. package/ui-dist/assets/{cose-bilkent-JH36ORCC-NjVgz2Bw.js → cose-bilkent-JH36ORCC-Bc2Ex5Y3.js} +1 -1
  76. package/ui-dist/assets/cynefin-VYW2F7L2-B-H8Qp-n.js +1 -0
  77. package/ui-dist/assets/{cynefinDiagram-TSTJHNR4-B_17LDqD.js → cynefinDiagram-TSTJHNR4-DVysQoGz.js} +1 -1
  78. package/ui-dist/assets/{dagre-CMe101gk.js → dagre-CMhQ1cAG.js} +1 -1
  79. package/ui-dist/assets/{dagre-VKFMJZFB-qo8nLb3B.js → dagre-VKFMJZFB-RYyWpPJZ.js} +1 -1
  80. package/ui-dist/assets/desktop-update-config-Dirc3bpt.js +1 -0
  81. package/ui-dist/assets/{diagram-FQU43EPY-Ba3XIklC.js → diagram-FQU43EPY-BD6KONdF.js} +1 -1
  82. package/ui-dist/assets/{diagram-G47NLZAW-CG45TcUx.js → diagram-G47NLZAW-CGB2ptRR.js} +1 -1
  83. package/ui-dist/assets/{diagram-NH7WQ7WH-2F2HrwV-.js → diagram-NH7WQ7WH-DnkOI6cU.js} +1 -1
  84. package/ui-dist/assets/{diagram-OA4YK3LP-CXfWH9NZ.js → diagram-OA4YK3LP-DF82RZ7P.js} +1 -1
  85. package/ui-dist/assets/{diagram-WEI45ONY-CH_4yepc.js → diagram-WEI45ONY-Be2v7Ck9.js} +1 -1
  86. package/ui-dist/assets/{dist-BH7W5yCi.js → dist-AYxkFx2B.js} +1 -1
  87. package/ui-dist/assets/{dist-CaYdVVeO.js → dist-D9xtGgdL.js} +1 -1
  88. package/ui-dist/assets/doc-browser-4Sud6dWw.js +1 -0
  89. package/ui-dist/assets/doc-browser-D4x_yH5F.js +1 -0
  90. package/ui-dist/assets/doc-browser-context-Cb7Z0j90.js +1 -0
  91. package/ui-dist/assets/{docx-preview-CoM4JK7_.js → docx-preview-BqwAjrj3.js} +1 -1
  92. package/ui-dist/assets/{ebnfDiagram-CCIWWBDH-BwiG4Ea1.js → ebnfDiagram-CCIWWBDH-CP98OYk8.js} +1 -1
  93. package/ui-dist/assets/{erDiagram-Q63AITRT-BML3hpnQ.js → erDiagram-Q63AITRT-ZLlx8xfs.js} +1 -1
  94. package/ui-dist/assets/eventmodeling-45OFAUF4-YVtShyFA.js +1 -0
  95. package/ui-dist/assets/flowDiagram-23GEKE2U-BeKXabVO.js +1 -0
  96. package/ui-dist/assets/form-actions-B2q4jgjE.js +1 -0
  97. package/ui-dist/assets/{ganttDiagram-NO4QXBWP-80enfWbD.js → ganttDiagram-NO4QXBWP-DXCDjHR2.js} +1 -1
  98. package/ui-dist/assets/gitGraph-TEB2WS4Q-jTSiBj-p.js +1 -0
  99. package/ui-dist/assets/{gitGraphDiagram-IHSO6WYX-CVLqXr-b.js → gitGraphDiagram-IHSO6WYX-l2HWrTJp.js} +1 -1
  100. package/ui-dist/assets/index-CdyTsSBu.css +1 -0
  101. package/ui-dist/assets/index-Das_bw2h.js +107 -0
  102. package/ui-dist/assets/info-DKCQHKI2-BIporNWb.js +1 -0
  103. package/ui-dist/assets/{infoDiagram-FWYZ7A6U-Dyvs2t0i.js → infoDiagram-FWYZ7A6U-D-DjX-bn.js} +1 -1
  104. package/ui-dist/assets/{ishikawaDiagram-FXEZZL3T-sSnxDKfh.js → ishikawaDiagram-FXEZZL3T-y_Xy128F.js} +1 -1
  105. package/ui-dist/assets/{journeyDiagram-5HDEW3XC-D22V71Mf.js → journeyDiagram-5HDEW3XC-DJn5xYcQ.js} +1 -1
  106. package/ui-dist/assets/{kanban-definition-HUTT4EX6-D3ds0p-g.js → kanban-definition-HUTT4EX6-DJVIOR21.js} +1 -1
  107. package/ui-dist/assets/{line-CbyFs065.js → line-Cos7PIOj.js} +1 -1
  108. package/ui-dist/assets/{linear-4DKtnZBS.js → linear-BtDLqtzF.js} +1 -1
  109. package/ui-dist/assets/loader-circle-CpmBdaon.js +1 -0
  110. package/ui-dist/assets/{map-CcZzEoz6.js → map-BKnQyvd0.js} +1 -1
  111. package/ui-dist/assets/mcp-marketplace-page-CdOY3Sop.js +1 -0
  112. package/ui-dist/assets/mcp-marketplace-page-DvjrfqEt.js +9 -0
  113. package/ui-dist/assets/{mermaid-parser.core-DPmMOjXD.js → mermaid-parser.core-XUNZhr2W.js} +2 -2
  114. package/ui-dist/assets/{mermaid.core-BSf-ddRa.js → mermaid.core-ySrvolIe.js} +3 -3
  115. package/ui-dist/assets/{mindmap-definition-LN4V7U3C-BUTwWPyx.js → mindmap-definition-LN4V7U3C-BypL9tei.js} +1 -1
  116. package/ui-dist/assets/model-config-page-DfOLyQqR.js +1 -0
  117. package/ui-dist/assets/{navigation-link-CVy0_kVl.js → navigation-link-MiiyoIjH.js} +2 -2
  118. package/ui-dist/assets/{ordinal-BgLYtOZE.js → ordinal-CxxVWxYU.js} +1 -1
  119. package/ui-dist/assets/packet-7NZHBO7P-CuFMADV0.js +1 -0
  120. package/ui-dist/assets/{pegDiagram-2B236MQR-BEu_ZBjc.js → pegDiagram-2B236MQR-D-U2KBGv.js} +1 -1
  121. package/ui-dist/assets/pie-RZYD4A2V-XUeIXhM9.js +1 -0
  122. package/ui-dist/assets/{pieDiagram-ENE6RG2P-CAwAwuBd.js → pieDiagram-ENE6RG2P-CBi3GusJ.js} +1 -1
  123. package/ui-dist/assets/plus-C8FkjpSZ.js +1 -0
  124. package/ui-dist/assets/provider-scoped-model-input-DXzjr5l0.js +1 -0
  125. package/ui-dist/assets/providers-config-page-CaO8WfZH.js +1 -0
  126. package/ui-dist/assets/{quadrantDiagram-ABIIQ3AL-CwE6F-_2.js → quadrantDiagram-ABIIQ3AL-H0ZuvnZL.js} +1 -1
  127. package/ui-dist/assets/radar-I7S5WNFK-D-NNGh1k.js +1 -0
  128. package/ui-dist/assets/railroad-3IZDKUUU-C67_uDaM.js +1 -0
  129. package/ui-dist/assets/railroad-abnf-AHOZXSZD-BZ8Yflnd.js +1 -0
  130. package/ui-dist/assets/railroad-ebnf-EBAXGLYW-B7zO7RoK.js +1 -0
  131. package/ui-dist/assets/railroad-peg-LSFZ7HO6-R63PTgLz.js +1 -0
  132. package/ui-dist/assets/{railroadDiagram-RFXS5EU6-xgLekU3B.js → railroadDiagram-RFXS5EU6-D7Y2EqSd.js} +1 -1
  133. package/ui-dist/assets/react-C8XFFvuz.js +8 -0
  134. package/ui-dist/assets/{refresh-cw-j2bl79Ea.js → refresh-cw-a2VVeeAF.js} +1 -1
  135. package/ui-dist/assets/remote-BJHXa4mB.js +1 -0
  136. package/ui-dist/assets/{requirementDiagram-TGXJPOKE-CyVUzEX5.js → requirementDiagram-TGXJPOKE-BiXNX1NN.js} +1 -1
  137. package/ui-dist/assets/rotate-cw-DJ7UF3F2.js +1 -0
  138. package/ui-dist/assets/runtime-config-page-BuA4A02z.js +1 -0
  139. package/ui-dist/assets/{sankeyDiagram-HTMAVEWB-JK6bFmYB.js → sankeyDiagram-HTMAVEWB-qzDeLztW.js} +1 -1
  140. package/ui-dist/assets/{save-BKNrtK81.js → save-CGm23Yww.js} +1 -1
  141. package/ui-dist/assets/{search-CkOm65W_.js → search-CH2t--sH.js} +1 -1
  142. package/ui-dist/assets/search-config-page-BAmYqoAz.js +1 -0
  143. package/ui-dist/assets/{secrets-config-page-CJjtdFAl.js → secrets-config-page-BlPOuql_.js} +2 -2
  144. package/ui-dist/assets/security-config-CbDiY2xr.js +1 -0
  145. package/ui-dist/assets/{select-Ea7ffKCE.js → select-DnxxDpcV.js} +2 -2
  146. package/ui-dist/assets/{sequenceDiagram-DBY2YBRQ-BR5IokXV.js → sequenceDiagram-DBY2YBRQ-BtRbPQtL.js} +1 -1
  147. package/ui-dist/assets/{settings-2-CtyN3m_V.js → settings-2-agnMYc8a.js} +1 -1
  148. package/ui-dist/assets/{sizeCapture-X5ZJPWSS-SxG_YnMA.js → sizeCapture-X5ZJPWSS-CMYvM3SL.js} +1 -1
  149. package/ui-dist/assets/skeleton-XpqeWL62.js +1 -0
  150. package/ui-dist/assets/{src-vgz8E_-O.js → src-Bw-mzbQb.js} +1 -1
  151. package/ui-dist/assets/{stateDiagram-2N3HPSRC-DD4OoYhn.js → stateDiagram-2N3HPSRC-BJ-mFeOz.js} +1 -1
  152. package/ui-dist/assets/stateDiagram-v2-6OUMAXLB-BE-HqxOK.js +1 -0
  153. package/ui-dist/assets/{swimlanes-5IMT3BWC-BWkFeyCT.js → swimlanes-5IMT3BWC-BsucVOO2.js} +2 -2
  154. package/ui-dist/assets/swimlanesDiagram-G3AALYLV-Dr1H9LJH.js +8 -0
  155. package/ui-dist/assets/{tag-chip-C9l4xsKp.js → tag-chip-CPOc8b2N.js} +1 -1
  156. package/ui-dist/assets/{timeline-definition-FHXFAJF6-VTRPy6KA.js → timeline-definition-FHXFAJF6-Bicewlzo.js} +1 -1
  157. package/ui-dist/assets/treeView-QDETBFTQ-npJ5dbqS.js +1 -0
  158. package/ui-dist/assets/treemap-6X3UGDF4-pYrBx6oa.js +1 -0
  159. package/ui-dist/assets/{vennDiagram-L72KCM5P-Bvk42Pek.js → vennDiagram-L72KCM5P-BxOOnO9x.js} +1 -1
  160. package/ui-dist/assets/wardley-OPB4EBWU-CmSRKLR8.js +1 -0
  161. package/ui-dist/assets/{wardleyDiagram-EHGQE667-DOFjx2s3.js → wardleyDiagram-EHGQE667-Cl7NltMv.js} +1 -1
  162. package/ui-dist/assets/x-odTHAtLZ.js +1 -0
  163. package/ui-dist/assets/{xychartDiagram-FW5EYKEG-DY5yRTUc.js → xychartDiagram-FW5EYKEG-DiMIxQ7N.js} +1 -1
  164. package/ui-dist/index.html +21 -22
  165. package/ui-dist/assets/appearance-settings-page-BYbvl2wj.js +0 -1
  166. package/ui-dist/assets/architecture-TIHT7OUA-Bjp9jf0h.js +0 -1
  167. package/ui-dist/assets/channel-5T3pdR-s.js +0 -1
  168. package/ui-dist/assets/chat-page-C5E-LLVd.js +0 -1
  169. package/ui-dist/assets/chunk-2Q5K7J3B-DTZ3tGfE.js +0 -1
  170. package/ui-dist/assets/chunk-VAUOI2AC-HLGIHQ6k.js +0 -1
  171. package/ui-dist/assets/chunk-XXDRQBXY-Dl0m6Ni-.js +0 -1
  172. package/ui-dist/assets/classDiagram-OUVF2IWQ-DcDnzGNX.js +0 -1
  173. package/ui-dist/assets/classDiagram-v2-EOCWNBFH-BKXKMzKM.js +0 -1
  174. package/ui-dist/assets/config-split-page-CA_a0AJ5.js +0 -1
  175. package/ui-dist/assets/confirm-dialog-CxZfenjK.js +0 -5
  176. package/ui-dist/assets/cynefin-VYW2F7L2-BWg7U2UD.js +0 -1
  177. package/ui-dist/assets/desktop-update-config-BEKC8Ly9.js +0 -1
  178. package/ui-dist/assets/doc-browser-Cl2ldE3f.js +0 -1
  179. package/ui-dist/assets/doc-browser-DXCSd63E.js +0 -1
  180. package/ui-dist/assets/doc-browser-context-FDPs3gJf.js +0 -1
  181. package/ui-dist/assets/eventmodeling-45OFAUF4-SB-J4tpq.js +0 -1
  182. package/ui-dist/assets/flowDiagram-23GEKE2U-BQ_u-eLM.js +0 -1
  183. package/ui-dist/assets/form-actions-0c0aw_bl.js +0 -1
  184. package/ui-dist/assets/gitGraph-TEB2WS4Q-DPxNwsFd.js +0 -1
  185. package/ui-dist/assets/i18n-provider-DkITJNz8.js +0 -1
  186. package/ui-dist/assets/index-CQ2LcI2p.css +0 -1
  187. package/ui-dist/assets/index-CrdfvBVg.js +0 -107
  188. package/ui-dist/assets/info-DKCQHKI2-DNlNGH90.js +0 -1
  189. package/ui-dist/assets/loader-circle-DHtUxCIA.js +0 -1
  190. package/ui-dist/assets/mcp-marketplace-page-Bc_jI5iH.js +0 -9
  191. package/ui-dist/assets/mcp-marketplace-page-CzCieD9r.js +0 -1
  192. package/ui-dist/assets/model-config-page-C4jw-pcj.js +0 -1
  193. package/ui-dist/assets/packet-7NZHBO7P-BpeiqkBZ.js +0 -1
  194. package/ui-dist/assets/pie-RZYD4A2V-Cy1yxsPd.js +0 -1
  195. package/ui-dist/assets/plus-CG1RwZQq.js +0 -1
  196. package/ui-dist/assets/provider-scoped-model-input-CmH4BFvc.js +0 -1
  197. package/ui-dist/assets/providers-config-page-CJQjwzaw.js +0 -1
  198. package/ui-dist/assets/radar-I7S5WNFK-CEcPKCj8.js +0 -1
  199. package/ui-dist/assets/railroad-3IZDKUUU-CW38eNDs.js +0 -1
  200. package/ui-dist/assets/railroad-abnf-AHOZXSZD-ByrylcXf.js +0 -1
  201. package/ui-dist/assets/railroad-ebnf-EBAXGLYW-CNB6GwP-.js +0 -1
  202. package/ui-dist/assets/railroad-peg-LSFZ7HO6-x6hnqlBG.js +0 -1
  203. package/ui-dist/assets/react-DjFBVA0n.js +0 -8
  204. package/ui-dist/assets/remote-BIlpD3yL.js +0 -1
  205. package/ui-dist/assets/rotate-cw-bKG8zH8M.js +0 -1
  206. package/ui-dist/assets/runtime-config-page-B_x2Glz5.js +0 -1
  207. package/ui-dist/assets/search-config-page-BaIijtmO.js +0 -1
  208. package/ui-dist/assets/security-config-DB8apj09.js +0 -1
  209. package/ui-dist/assets/skeleton-Bt6zxcAB.js +0 -1
  210. package/ui-dist/assets/stateDiagram-v2-6OUMAXLB-ZC6dFORv.js +0 -1
  211. package/ui-dist/assets/swimlanesDiagram-G3AALYLV-CRkh51Im.js +0 -8
  212. package/ui-dist/assets/treeView-QDETBFTQ-Bw0DSCH7.js +0 -1
  213. package/ui-dist/assets/treemap-6X3UGDF4-DFWBFcfh.js +0 -1
  214. package/ui-dist/assets/wardley-OPB4EBWU-CoWturk0.js +0 -1
  215. package/ui-dist/assets/x-CowtCu9Z.js +0 -1
  216. /package/ui-dist/assets/{array-NADKd9aU.js → array-BQVzeGRt.js} +0 -0
  217. /package/ui-dist/assets/{chunk-KEIR6QF5-BuyuzJJL.js → chunk-KEIR6QF5-f9psyCXK.js} +0 -0
  218. /package/ui-dist/assets/{chunk-Y2CYZVJY-D_B2ZRNt.js → chunk-Y2CYZVJY-D1mAU_Po.js} +0 -0
  219. /package/ui-dist/assets/{config-hints-BcfVUMij.js → config-hints-nV5HPOvq.js} +0 -0
  220. /package/ui-dist/assets/{cytoscape.esm-BANTlgza.js → cytoscape.esm-0uDtdD0l.js} +0 -0
  221. /package/ui-dist/assets/{defaultLocale-C4_L0aEs.js → defaultLocale-DSWXGgt0.js} +0 -0
  222. /package/ui-dist/assets/{dist-DAPEIJbz.js → dist--ta5rX12.js} +0 -0
  223. /package/ui-dist/assets/{graphlib-ChqXg0dI.js → graphlib-CQ6QV4yP.js} +0 -0
  224. /package/ui-dist/assets/{host-capabilities-D9C4CBK5.js → host-capabilities-Tk038i04.js} +0 -0
  225. /package/ui-dist/assets/{init-D8wZg9xq.js → init-Y6h9jGtZ.js} +0 -0
  226. /package/ui-dist/assets/{jszip.min-CkbBfwAQ.js → jszip.min-8hyJpgpx.js} +0 -0
  227. /package/ui-dist/assets/{katex-TZJFa0J_.js → katex-ARhY9PS1.js} +0 -0
  228. /package/ui-dist/assets/{middleware-B3k-TSmZ.js → middleware-DXsbf9xI.js} +0 -0
  229. /package/ui-dist/assets/{path-DodfxcX7.js → path-10BjdyLh.js} +0 -0
  230. /package/ui-dist/assets/{rough.esm-CUaa1Rbe.js → rough.esm-DxgC_14r.js} +0 -0
  231. /package/ui-dist/assets/{xlsx-CxByi7bR.js → xlsx-DrDuDNAa.js} +0 -0
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as createNextclawDistribution } from "../../nextclaw-distribution.utils-D6Rz73fp.js";
2
+ import { t as createNextclawDistribution } from "../../nextclaw-distribution.utils-CfUuTwjt.js";
3
3
  import { createRequire } from "node:module";
4
4
  import { APP_NAME, APP_TAGLINE, getConfigPath, getDataDir, getRunPath, loadConfig, resolveConfigSecrets } from "@nextclaw/core";
5
5
  import { Command, InvalidArgumentError } from "commander";
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as createNextclawDistribution } from "../../nextclaw-distribution.utils-D6Rz73fp.js";
2
+ import { t as createNextclawDistribution } from "../../nextclaw-distribution.utils-CfUuTwjt.js";
3
3
  import { NextclawDistributionService, runNextclawNpmRuntimeLauncher } from "@nextclaw/service";
4
4
  //#region src/cli/launcher/index.ts
5
5
  NextclawDistributionService.configure(createNextclawDistribution(import.meta.url));
@@ -12,10 +12,11 @@ function createNextclawDistribution(importMetaUrl) {
12
12
  launcherEntrypoint: resolve(dirname(entrypoint), "../launcher", basename(entrypoint)),
13
13
  templatesDir: resolve(packageRoot, "templates"),
14
14
  uiDistDir: resolve(packageRoot, "ui-dist"),
15
- runtimeUpdatePublicKeyPath: resolve(packageRoot, "resources/update-bundle-public.pem")
15
+ runtimeUpdatePublicKeyPath: resolve(packageRoot, "resources/update-bundle-public.pem"),
16
+ builtInAppsDirectory: resolve(packageRoot, "resources/apps")
16
17
  };
17
18
  }
18
19
  //#endregion
19
20
  export { createNextclawDistribution as t };
20
21
 
21
- //# sourceMappingURL=nextclaw-distribution.utils-D6Rz73fp.js.map
22
+ //# sourceMappingURL=nextclaw-distribution.utils-CfUuTwjt.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"nextclaw-distribution.utils-D6Rz73fp.js","names":[],"sources":["../src/cli/shared/lib/distribution/nextclaw-distribution.utils.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { basename, dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { NextclawDistribution } from \"@nextclaw/service\";\n\nexport function createNextclawDistribution(importMetaUrl: string): NextclawDistribution {\n const entrypoint = fileURLToPath(importMetaUrl);\n const packageRoot = resolve(dirname(entrypoint), \"../../..\");\n const { version } = JSON.parse(readFileSync(resolve(packageRoot, \"package.json\"), \"utf-8\")) as { version?: string };\n return {\n version: typeof version === \"string\" ? version : \"0.0.0\",\n appEntrypoint: resolve(packageRoot, \"dist/cli/app/index.js\"),\n launcherEntrypoint: resolve(dirname(entrypoint), \"../launcher\", basename(entrypoint)),\n templatesDir: resolve(packageRoot, \"templates\"),\n uiDistDir: resolve(packageRoot, \"ui-dist\"),\n runtimeUpdatePublicKeyPath: resolve(packageRoot, \"resources/update-bundle-public.pem\")\n };\n}\n"],"mappings":";;;;AAKA,SAAgB,2BAA2B,eAA6C;CACtF,MAAM,aAAa,cAAc,cAAc;CAC/C,MAAM,cAAc,QAAQ,QAAQ,WAAW,EAAE,WAAW;CAC5D,MAAM,EAAE,YAAY,KAAK,MAAM,aAAa,QAAQ,aAAa,eAAe,EAAE,QAAQ,CAAC;AAC3F,QAAO;EACL,SAAS,OAAO,YAAY,WAAW,UAAU;EACjD,eAAe,QAAQ,aAAa,wBAAwB;EAC5D,oBAAoB,QAAQ,QAAQ,WAAW,EAAE,eAAe,SAAS,WAAW,CAAC;EACrF,cAAc,QAAQ,aAAa,YAAY;EAC/C,WAAW,QAAQ,aAAa,UAAU;EAC1C,4BAA4B,QAAQ,aAAa,qCAAqC;EACvF"}
1
+ {"version":3,"file":"nextclaw-distribution.utils-CfUuTwjt.js","names":[],"sources":["../src/cli/shared/lib/distribution/nextclaw-distribution.utils.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { basename, dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { NextclawDistribution } from \"@nextclaw/service\";\n\nexport function createNextclawDistribution(importMetaUrl: string): NextclawDistribution {\n const entrypoint = fileURLToPath(importMetaUrl);\n const packageRoot = resolve(dirname(entrypoint), \"../../..\");\n const { version } = JSON.parse(readFileSync(resolve(packageRoot, \"package.json\"), \"utf-8\")) as { version?: string };\n return {\n version: typeof version === \"string\" ? version : \"0.0.0\",\n appEntrypoint: resolve(packageRoot, \"dist/cli/app/index.js\"),\n launcherEntrypoint: resolve(dirname(entrypoint), \"../launcher\", basename(entrypoint)),\n templatesDir: resolve(packageRoot, \"templates\"),\n uiDistDir: resolve(packageRoot, \"ui-dist\"),\n runtimeUpdatePublicKeyPath: resolve(packageRoot, \"resources/update-bundle-public.pem\"),\n builtInAppsDirectory: resolve(packageRoot, \"resources/apps\")\n };\n}\n"],"mappings":";;;;AAKA,SAAgB,2BAA2B,eAA6C;CACtF,MAAM,aAAa,cAAc,cAAc;CAC/C,MAAM,cAAc,QAAQ,QAAQ,WAAW,EAAE,WAAW;CAC5D,MAAM,EAAE,YAAY,KAAK,MAAM,aAAa,QAAQ,aAAa,eAAe,EAAE,QAAQ,CAAC;AAC3F,QAAO;EACL,SAAS,OAAO,YAAY,WAAW,UAAU;EACjD,eAAe,QAAQ,aAAa,wBAAwB;EAC5D,oBAAoB,QAAQ,QAAQ,WAAW,EAAE,eAAe,SAAS,WAAW,CAAC;EACrF,cAAc,QAAQ,aAAa,YAAY;EAC/C,WAAW,QAAQ,aAAa,UAAU;EAC1C,4BAA4B,QAAQ,aAAa,qCAAqC;EACtF,sBAAsB,QAAQ,aAAa,iBAAiB;EAC7D"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nextclaw",
3
- "version": "0.31.0",
3
+ "version": "0.32.0",
4
4
  "description": "Powerful AI assistant for coordinating agents, skills, CLI tools, automations, and messaging apps.",
5
5
  "private": false,
6
6
  "type": "module",
@@ -41,20 +41,20 @@
41
41
  "commander": "^12.1.0",
42
42
  "jszip": "^3.10.1",
43
43
  "yaml": "^2.8.1",
44
- "@nextclaw/core": "0.15.22",
45
- "@nextclaw/kernel": "0.6.24",
44
+ "@nextclaw/core": "0.15.23",
45
+ "@nextclaw/kernel": "0.6.25",
46
+ "@nextclaw/mcp": "0.3.23",
46
47
  "@nextclaw/ncp": "0.7.17",
47
- "@nextclaw/mcp": "0.3.22",
48
- "@nextclaw/ncp-mcp": "0.2.22",
49
- "@nextclaw/ncp-toolkit": "0.6.19",
50
- "@nextclaw/nextclaw-hermes-acp-bridge": "0.3.17",
51
- "@nextclaw/ncp-agent-runtime": "0.4.17",
48
+ "@nextclaw/ncp-mcp": "0.2.23",
52
49
  "@nextclaw/nextclaw-ncp-runtime-http-client": "0.3.17",
53
- "@nextclaw/nextclaw-ncp-runtime-stdio-client": "0.3.23",
54
- "@nextclaw/remote": "0.3.24",
55
- "@nextclaw/runtime": "0.4.22",
56
- "@nextclaw/service": "0.3.25",
57
- "@nextclaw/server": "0.15.24"
50
+ "@nextclaw/nextclaw-ncp-runtime-stdio-client": "0.3.24",
51
+ "@nextclaw/remote": "0.3.25",
52
+ "@nextclaw/nextclaw-hermes-acp-bridge": "0.3.17",
53
+ "@nextclaw/runtime": "0.4.23",
54
+ "@nextclaw/service": "0.3.26",
55
+ "@nextclaw/ncp-toolkit": "0.6.19",
56
+ "@nextclaw/server": "0.15.25",
57
+ "@nextclaw/ncp-agent-runtime": "0.4.17"
58
58
  },
59
59
  "devDependencies": {
60
60
  "@types/node": "^20.17.6",
@@ -62,7 +62,7 @@
62
62
  "tsx": "^4.19.2",
63
63
  "typescript": "^5.6.3",
64
64
  "vitest": "^4.1.2",
65
- "@nextclaw/ui": "0.15.25"
65
+ "@nextclaw/ui": "0.15.26"
66
66
  },
67
67
  "scripts": {
68
68
  "dev": "tsx watch --tsconfig ../../scripts/dev/dev-runtime.tsconfig.json src/cli/app/index.ts",
@@ -0,0 +1,24 @@
1
+ # Personal Space
2
+
3
+ Personal Space brings four small, everyday apps into NextClaw without turning them into a heavyweight productivity suite:
4
+
5
+ - **Todos** — capture, prioritize, complete, edit, and delete personal tasks.
6
+ - **Notes** — keep lightweight notes as real Markdown files.
7
+ - **Favorites** — save links with a title, note, and simple tags.
8
+ - **Calendar** — manage local events and connect public ICS calendars.
9
+
10
+ The four panels share one local data service. Application code is installed by version, while personal data stays in a stable directory across upgrades, rollbacks, disable/enable cycles, and ordinary uninstall/reinstall flows.
11
+
12
+ ## Privacy and permissions
13
+
14
+ Data is stored locally under NextClaw's app data directory. Each panel only declares the service actions it uses, and NextClaw asks before granting those actions. Calendar subscriptions accept public HTTP(S) ICS endpoints and enforce timeout, download-size, redirect, and private-network boundaries.
15
+
16
+ ## Install
17
+
18
+ Personal Space is built into supported NextClaw releases. It can also be installed from the official Apps Registry:
19
+
20
+ ```bash
21
+ napp install nextclaw.personal-organizer
22
+ ```
23
+
24
+ After installation, open **Apps** in NextClaw and enable Personal Space. You can then launch Todos, Notes, Favorites, or Calendar independently.
@@ -0,0 +1,13 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" role="img" aria-label="Personal space">
2
+ <defs>
3
+ <linearGradient id="g" x1="18" y1="14" x2="112" y2="118" gradientUnits="userSpaceOnUse">
4
+ <stop stop-color="#7C6BF2"/>
5
+ <stop offset="1" stop-color="#4BAE8A"/>
6
+ </linearGradient>
7
+ </defs>
8
+ <rect x="8" y="8" width="112" height="112" rx="30" fill="#F5F2EA"/>
9
+ <path d="M31 65c0-19 14-34 33-34s33 15 33 34v31H31V65Z" fill="url(#g)"/>
10
+ <path d="M47 67c0-10 7-18 17-18s17 8 17 18v29H47V67Z" fill="#F8F6F0"/>
11
+ <circle cx="64" cy="69" r="6" fill="#E9A35B"/>
12
+ <path d="M23 101h82" stroke="#27312D" stroke-width="6" stroke-linecap="round"/>
13
+ </svg>
@@ -0,0 +1,44 @@
1
+ {
2
+ "schemaVersion": 2,
3
+ "id": "nextclaw.personal-organizer",
4
+ "name": "个人空间",
5
+ "nameI18n": {
6
+ "zh-CN": "个人空间",
7
+ "en-US": "Personal Space"
8
+ },
9
+ "version": "0.1.1",
10
+ "description": "待办、Markdown 笔记、收藏和日历组成的轻量个人上下文空间。",
11
+ "descriptionI18n": {
12
+ "zh-CN": "待办、Markdown 笔记、收藏和日历组成的轻量个人上下文空间。",
13
+ "en-US": "A lightweight personal space for todos, Markdown notes, favorites, and calendars."
14
+ },
15
+ "icon": "assets/icon.svg",
16
+ "engines": {
17
+ "nextclaw": ">=0.32.0"
18
+ },
19
+ "presentation": {
20
+ "primaryPanel": "nextclaw-personal-organizer-todos"
21
+ },
22
+ "components": [
23
+ {
24
+ "kind": "panel",
25
+ "path": "panels/nextclaw-personal-organizer-todos.panel"
26
+ },
27
+ {
28
+ "kind": "panel",
29
+ "path": "panels/nextclaw-personal-organizer-notes.panel"
30
+ },
31
+ {
32
+ "kind": "panel",
33
+ "path": "panels/nextclaw-personal-organizer-favorites.panel"
34
+ },
35
+ {
36
+ "kind": "panel",
37
+ "path": "panels/nextclaw-personal-organizer-calendar.panel"
38
+ },
39
+ {
40
+ "kind": "service",
41
+ "path": "service-components/nextclaw-personal-organizer-data"
42
+ }
43
+ ]
44
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "slug": "personal-organizer",
3
+ "summary": "A calm home for todos, Markdown notes, favorites, and calendar.",
4
+ "summaryI18n": {
5
+ "zh-CN": "把待办、Markdown 笔记、收藏和日历放进一个安静的个人空间。",
6
+ "en-US": "A calm home for todos, Markdown notes, favorites, and calendar."
7
+ },
8
+ "description": "Four lightweight personal context apps backed by local, portable data.",
9
+ "descriptionI18n": {
10
+ "zh-CN": "四个轻量个人上下文应用,数据保存在本机稳定目录,可持续、可迁移。",
11
+ "en-US": "Four lightweight personal context apps backed by local, portable data."
12
+ },
13
+ "author": "NextClaw",
14
+ "tags": ["productivity", "personal", "notes", "calendar"],
15
+ "sourceRepo": "https://github.com/Peiiii/nextclaw",
16
+ "homepage": "https://nextclaw.io",
17
+ "featured": true
18
+ }
@@ -0,0 +1,24 @@
1
+ <!doctype html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>日历</title>
5
+ <style>
6
+ :root{color-scheme:light dark;--bg:#eef1ef;--card:#fbfcfa;--ink:#28312e;--muted:#7c8581;--line:#d9dfdc;--accent:#3d7e79;--soft:#dcebe7;--today:#e6a55e;--danger:#a54640;font:14px/1.5 Inter,ui-sans-serif,system-ui,-apple-system,"PingFang SC",sans-serif}*{box-sizing:border-box}body{margin:0;min-height:100vh;background:linear-gradient(160deg,#dcebe7,transparent 35%),var(--bg);color:var(--ink)}button,input,textarea{font:inherit;color:inherit}button{cursor:pointer}.shell{max-width:1100px;margin:auto;padding:28px 24px 70px}.header{display:flex;justify-content:space-between;align-items:end;gap:14px;margin-bottom:20px}.eyebrow{font-size:12px;text-transform:uppercase;letter-spacing:.16em;color:var(--muted);font-weight:700}h1{font:600 35px/1.1 Georgia,"Songti SC",serif;margin:5px 0}.subtitle{color:var(--muted)}.header-actions,.month-nav{display:flex;gap:7px;align-items:center}.primary,.ghost,.icon{border:0;border-radius:11px;padding:9px 12px}.primary{background:var(--ink);color:var(--card);font-weight:700}.ghost,.icon{background:transparent}.ghost:hover,.icon:hover{background:#0000000a}.layout{display:grid;grid-template-columns:minmax(0,1fr) 285px;gap:14px}.calendar,.agenda{border:1px solid var(--line);background:color-mix(in srgb,var(--card) 96%,transparent);border-radius:18px;box-shadow:0 18px 50px #26332e0c;overflow:hidden}.month-bar{display:flex;justify-content:space-between;align-items:center;padding:15px 17px;border-bottom:1px solid var(--line)}.month-title{font:600 20px Georgia,"Songti SC",serif}.weekdays,.days{display:grid;grid-template-columns:repeat(7,1fr)}.weekdays div{padding:9px;text-align:center;color:var(--muted);font-size:11px;font-weight:700;border-bottom:1px solid var(--line)}.day{min-height:95px;border-right:1px solid var(--line);border-bottom:1px solid var(--line);padding:7px;overflow:hidden}.day:nth-child(7n){border-right:0}.day.other{color:#a7ada9;background:#000000025}.date{width:25px;height:25px;display:grid;place-items:center;border-radius:50%;font-size:12px}.today .date{background:var(--today);color:white;font-weight:800}.event{display:block;width:100%;border:0;text-align:left;background:var(--soft);color:#275f5a;border-radius:6px;padding:3px 5px;margin-top:4px;font-size:11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.event.ics{background:#e8e2f2;color:#62527f}.agenda{padding:17px;align-self:start}.agenda h2{font:600 20px Georgia,"Songti SC",serif;margin:0}.agenda-sub{color:var(--muted);font-size:12px;margin:4px 0 14px}.agenda-list{display:grid;gap:8px}.agenda-item{border-left:3px solid var(--accent);padding:7px 8px;background:var(--bg);border-radius:0 9px 9px 0}.agenda-item.ics{border-color:#806ba2}.agenda-item b{display:block}.agenda-item small{color:var(--muted)}.connections{border-top:1px solid var(--line);margin-top:18px;padding-top:15px}.connections-head{display:flex;justify-content:space-between;align-items:center}.connections h3{font-size:13px;margin:0}.source{display:grid;grid-template-columns:1fr auto;gap:4px;margin-top:9px}.source small{color:var(--muted)}.source-error{color:var(--danger)!important}.empty{color:var(--muted);padding:15px 0}dialog{border:1px solid var(--line);border-radius:20px;background:var(--card);color:var(--ink);padding:0;width:min(520px,calc(100% - 28px));box-shadow:0 30px 100px #0003}dialog::backdrop{background:#14231f66;backdrop-filter:blur(4px)}form{padding:22px}.form-head{display:flex;justify-content:space-between;align-items:center}.form-head h2{font:600 24px Georgia,"Songti SC",serif;margin:0}.field{display:grid;gap:6px;margin:13px 0}.field label{font-size:12px;color:var(--muted);font-weight:700}.field input,.field textarea{border:1px solid var(--line);border-radius:11px;background:transparent;padding:10px 11px;outline:none}.field textarea{min-height:75px;resize:vertical}.grid{display:grid;grid-template-columns:1fr 1fr;gap:11px}.check{display:flex;align-items:center;gap:7px}.form-actions{display:flex;justify-content:space-between;gap:8px;margin-top:18px}.right{display:flex;gap:8px}.danger{color:var(--danger)}.toast{position:fixed;right:20px;bottom:20px;background:var(--ink);color:var(--card);padding:10px 13px;border-radius:11px}.error{background:var(--danger)}@media(max-width:820px){.layout{grid-template-columns:1fr}.agenda{order:-1}.day{min-height:76px}.header{align-items:start}.header-actions{flex-wrap:wrap;justify-content:flex-end}}@media(max-width:560px){.shell{padding:20px 10px 60px}h1{font-size:30px}.subtitle{display:none}.header{padding:0 6px}.header-actions .ghost{font-size:0}.header-actions .ghost:after{content:'连接';font-size:14px}.day{min-height:60px;padding:4px}.event{font-size:0;height:7px;padding:0;border-radius:4px}.weekdays div{padding:6px 2px}.grid{grid-template-columns:1fr}}@media(prefers-color-scheme:dark){:root{--bg:#202624;--card:#29312e;--ink:#eef2ef;--muted:#a2aca7;--line:#3e4944;--soft:#304c46;--accent:#7fc2b8}.event{color:#c5f5ed}.event.ics{background:#443c55;color:#e6dcfb}.ghost:hover,.icon:hover{background:#ffffff0a}}
7
+ </style>
8
+ </head>
9
+ <body>
10
+ <main class="shell"><header class="header"><div><div class="eyebrow">Personal space</div><h1>日历</h1><div class="subtitle">自己的安排,和已有日历放在一起看。</div></div><div class="header-actions"><button class="ghost" id="connect">连接已有日历</button><button class="primary" id="add">+ 新日程</button></div></header><div class="layout"><section class="calendar"><div class="month-bar"><button class="icon" id="prev" aria-label="上个月">←</button><div class="month-title" id="monthTitle"></div><div class="month-nav"><button class="ghost" id="today">今天</button><button class="icon" id="next" aria-label="下个月">→</button></div></div><div class="weekdays"><div>一</div><div>二</div><div>三</div><div>四</div><div>五</div><div>六</div><div>日</div></div><div class="days" id="days"></div></section><aside class="agenda"><h2 id="agendaTitle">本月安排</h2><div class="agenda-sub" id="agendaSub"></div><div class="agenda-list" id="agenda"></div><div class="connections"><div class="connections-head"><h3>已连接日历</h3><button class="icon" id="sync" aria-label="同步">↻</button></div><div id="sources"></div></div></aside></div></main>
11
+ <dialog id="eventDialog"><form method="dialog" id="eventForm"><div class="form-head"><h2 id="eventFormTitle">新日程</h2><button class="icon" value="cancel">✕</button></div><input type="hidden" id="eventId"><div class="field"><label for="eventTitle">标题</label><input id="eventTitle" required maxlength="180"></div><div class="grid"><div class="field"><label for="eventStart">开始</label><input id="eventStart" type="datetime-local" required></div><div class="field"><label for="eventEnd">结束</label><input id="eventEnd" type="datetime-local"></div></div><label class="check"><input id="allDay" type="checkbox"> 全天</label><div class="field"><label for="location">地点</label><input id="location"></div><div class="field"><label for="eventNotes">备注</label><textarea id="eventNotes"></textarea></div><div class="form-actions"><button class="ghost danger" id="eventDelete" type="button" hidden>删除</button><div class="right"><button class="ghost" value="cancel">取消</button><button class="primary" value="default">保存</button></div></div></form></dialog>
12
+ <dialog id="connectDialog"><form method="dialog" id="connectForm"><div class="form-head"><h2>连接 ICS 日历</h2><button class="icon" value="cancel">✕</button></div><p class="subtitle">粘贴现有日历提供的私密 ICS 订阅链接。链接只保存在本机。</p><div class="field"><label for="sourceName">名称</label><input id="sourceName" required placeholder="工作日历"></div><div class="field"><label for="sourceUrl">ICS 订阅链接</label><input id="sourceUrl" type="url" required placeholder="https://…/calendar.ics"></div><div class="form-actions"><span></span><div class="right"><button class="ghost" value="cancel">取消</button><button class="primary" value="default">连接并同步</button></div></div></form></dialog><div id="toast" class="toast" role="status" hidden></div>
13
+ <script>
14
+ const service='nextclaw-personal-organizer-data.';let cursor=startMonth(new Date()),items=[],subscriptions=[];const $=id=>document.getElementById(id),toast=$('toast');
15
+ async function invoke(action,input={}){if(!window.nextclaw?.serviceActions)throw new Error('NextClaw 服务桥接不可用');return await window.nextclaw.serviceActions.invoke(service+action,input)}function esc(v=''){return String(v).replace(/[&<>"]/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;'}[c]))}function notify(message,error=false){toast.textContent=message;toast.classList.toggle('error',error);toast.hidden=false;clearTimeout(notify.timer);notify.timer=setTimeout(()=>toast.hidden=true,3000)}function startMonth(date){return new Date(date.getFullYear(),date.getMonth(),1)}function addMonths(date,n){return new Date(date.getFullYear(),date.getMonth()+n,1)}function dayKey(value){const d=new Date(value),p=n=>String(n).padStart(2,'0');return `${d.getFullYear()}-${p(d.getMonth()+1)}-${p(d.getDate())}`}
16
+ async function load(){const end=addMonths(cursor,1);try{const payload=await invoke('event_list',{start:cursor.toISOString(),end:end.toISOString()});items=payload.items||[];subscriptions=payload.subscriptions||[];render()}catch(error){$('days').innerHTML='<div class="empty" style="grid-column:1/-1">无法读取日历,请检查授权或应用状态。</div>';notify(error.message||String(error),true)}}
17
+ function render(){const locale=navigator.language||'zh-CN';$('monthTitle').textContent=new Intl.DateTimeFormat(locale,{year:'numeric',month:'long'}).format(cursor);const start=new Date(cursor),offset=(start.getDay()+6)%7;start.setDate(start.getDate()-offset);const today=dayKey(new Date());$('days').innerHTML=Array.from({length:42},(_,index)=>{const date=new Date(start);date.setDate(start.getDate()+index);const key=dayKey(date),dayItems=items.filter(item=>dayKey(item.start)===key);return `<div class="day ${date.getMonth()!==cursor.getMonth()?'other':''} ${key===today?'today':''}" data-date="${key}"><span class="date">${date.getDate()}</span>${dayItems.slice(0,3).map(item=>`<button class="event ${item.source==='ics'?'ics':''}" data-id="${esc(item.id)}" title="${esc(item.title)}">${esc(item.title)}</button>`).join('')}</div>`}).join('');const upcoming=items.filter(item=>new Date(item.end||item.start)>=new Date()).slice(0,8);$('agendaSub').textContent=`${items.length} 个日程`;$('agenda').innerHTML=upcoming.length?upcoming.map(item=>`<button class="agenda-item ${item.source==='ics'?'ics':''}" data-id="${esc(item.id)}"><b>${esc(item.title)}</b><small>${formatEventTime(item)}${item.location?' · '+esc(item.location):''}</small></button>`).join(''):'<div class="empty">本月还没有安排。</div>';$('sources').innerHTML=subscriptions.length?subscriptions.map(source=>`<div class="source" data-id="${source.id}"><div><b>${esc(source.name)}</b><br><small class="${source.lastError?'source-error':''}">${source.lastError?esc(source.lastError):source.lastSyncedAt?'已同步 '+new Date(source.lastSyncedAt).toLocaleString():'等待同步'}</small></div><button class="icon unsubscribe" aria-label="断开">×</button></div>`).join(''):'<div class="empty">尚未连接外部日历。</div>'}
18
+ function formatEventTime(item){const d=new Date(item.start);return item.allDay?d.toLocaleDateString():new Intl.DateTimeFormat(undefined,{month:'short',day:'numeric',hour:'2-digit',minute:'2-digit'}).format(d)}function localDate(value){if(!value)return '';const d=new Date(value),p=n=>String(n).padStart(2,'0');return `${d.getFullYear()}-${p(d.getMonth()+1)}-${p(d.getDate())}T${p(d.getHours())}:${p(d.getMinutes())}`}
19
+ function openEvent(item,date){if(item?.source==='ics'){notify('外部日历事件请在原日历中修改');return}const start=item?.start||new Date(`${date||dayKey(new Date())}T09:00:00`).toISOString();$('eventFormTitle').textContent=item?'编辑日程':'新日程';$('eventId').value=item?.id||'';$('eventTitle').value=item?.title||'';$('eventStart').value=localDate(start);$('eventEnd').value=localDate(item?.end||new Date(new Date(start).getTime()+3600000));$('allDay').checked=item?.allDay||false;$('location').value=item?.location||'';$('eventNotes').value=item?.notes||'';$('eventDelete').hidden=!item;$('eventDialog').showModal();setTimeout(()=>$('eventTitle').focus(),20)}
20
+ $('add').addEventListener('click',()=>openEvent());$('connect').addEventListener('click',()=>$('connectDialog').showModal());$('prev').addEventListener('click',()=>{cursor=addMonths(cursor,-1);load()});$('next').addEventListener('click',()=>{cursor=addMonths(cursor,1);load()});$('today').addEventListener('click',()=>{cursor=startMonth(new Date());load()});$('days').addEventListener('dblclick',event=>{const day=event.target.closest('.day');if(day)openEvent(null,day.dataset.date)});document.addEventListener('click',event=>{const target=event.target.closest('[data-id]');if(!target||target.classList.contains('source'))return;const item=items.find(entry=>entry.id===target.dataset.id);if(item)openEvent(item)});
21
+ $('eventForm').addEventListener('submit',async event=>{if(event.submitter?.value==='cancel')return;event.preventDefault();const id=$('eventId').value,input={title:$('eventTitle').value.trim(),start:new Date($('eventStart').value).toISOString(),end:$('eventEnd').value?new Date($('eventEnd').value).toISOString():'',allDay:$('allDay').checked,location:$('location').value.trim(),notes:$('eventNotes').value.trim()};try{await invoke(id?'event_update':'event_create',id?{id,...input}:input);$('eventDialog').close();await load();notify('日程已保存')}catch(error){notify(error.message||String(error),true)}});$('eventDelete').addEventListener('click',async()=>{const id=$('eventId').value;if(!id||!confirm('删除这个日程?'))return;try{await invoke('event_delete',{id});$('eventDialog').close();await load();notify('日程已删除')}catch(error){notify(error.message||String(error),true)}});$('connectForm').addEventListener('submit',async event=>{if(event.submitter?.value==='cancel')return;event.preventDefault();try{await invoke('calendar_subscribe',{name:$('sourceName').value.trim(),url:$('sourceUrl').value.trim()});$('connectDialog').close();$('connectForm').reset();await load();notify('日历已连接')}catch(error){notify(error.message||String(error),true)}});$('sync').addEventListener('click',async()=>{try{await invoke('calendar_sync',{});await load();notify('日历已同步')}catch(error){await load();notify(error.message||String(error),true)}});$('sources').addEventListener('click',async event=>{const button=event.target.closest('.unsubscribe');if(!button)return;const source=button.closest('.source');if(!confirm('断开这个日历并移除已同步事件?'))return;try{await invoke('calendar_unsubscribe',{id:source.dataset.id});await load();notify('日历已断开')}catch(error){notify(error.message||String(error),true)}});load();
22
+ </script>
23
+ </body>
24
+ </html>
@@ -0,0 +1,21 @@
1
+ {
2
+ "id": "nextclaw-personal-organizer-calendar",
3
+ "title": "日历",
4
+ "titleI18n": { "zh-CN": "日历", "en-US": "Calendar" },
5
+ "description": "查看本地日程,并优先连接已有 ICS 日历。",
6
+ "descriptionI18n": {
7
+ "zh-CN": "查看本地日程,并优先连接已有 ICS 日历。",
8
+ "en-US": "See local events alongside your existing ICS calendars."
9
+ },
10
+ "icon": "□",
11
+ "entry": "index.html",
12
+ "actions": [
13
+ "nextclaw-personal-organizer-data.event_list",
14
+ "nextclaw-personal-organizer-data.event_create",
15
+ "nextclaw-personal-organizer-data.event_update",
16
+ "nextclaw-personal-organizer-data.event_delete",
17
+ "nextclaw-personal-organizer-data.calendar_subscribe",
18
+ "nextclaw-personal-organizer-data.calendar_sync",
19
+ "nextclaw-personal-organizer-data.calendar_unsubscribe"
20
+ ]
21
+ }
@@ -0,0 +1,23 @@
1
+ <!doctype html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>收藏</title>
5
+ <style>
6
+ :root{color-scheme:light dark;--bg:#f5f0e7;--card:#fffaf2;--ink:#302e2a;--muted:#817d74;--line:#dfd7ca;--accent:#bd6d42;--soft:#f2dfd0;--danger:#a4433e;font:14px/1.5 Inter,ui-sans-serif,system-ui,-apple-system,"PingFang SC",sans-serif}*{box-sizing:border-box}body{margin:0;min-height:100vh;background:linear-gradient(135deg,#f7e9d7 0,transparent 36%),var(--bg);color:var(--ink)}button,input,textarea{font:inherit;color:inherit}button{cursor:pointer}.shell{max-width:980px;margin:auto;padding:30px 28px 80px}.header{display:flex;align-items:end;justify-content:space-between;gap:18px}.eyebrow{font-size:12px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted);font-weight:700}h1{font:600 36px/1.1 Georgia,"Songti SC",serif;margin:5px 0}.subtitle{color:var(--muted)}.primary{border:0;border-radius:12px;background:var(--ink);color:var(--card);padding:10px 14px;font-weight:700}.tools{display:flex;gap:10px;margin:24px 0 17px}.search{flex:1;max-width:460px;border:1px solid var(--line);background:var(--card);border-radius:13px;padding:10px 13px;outline:none}.tags{display:flex;gap:6px;overflow:auto;padding-bottom:4px}.tag-filter,.tag{white-space:nowrap;border:0;border-radius:999px;background:var(--soft);padding:5px 9px;color:#78472f}.tag-filter{background:transparent;color:var(--muted)}.tag-filter.active{background:var(--soft);color:#78472f;font-weight:700}.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:12px}.card{display:flex;flex-direction:column;min-width:0;min-height:165px;border:1px solid var(--line);background:color-mix(in srgb,var(--card) 95%,transparent);border-radius:17px;padding:16px;box-shadow:0 12px 40px #5537220a;transition:.18s}.card:hover{transform:translateY(-2px);box-shadow:0 17px 45px #55372216}.domain{color:var(--accent);font-size:12px;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.card h2{font:600 18px/1.35 Georgia,"Songti SC",serif;margin:7px 0 6px;overflow-wrap:anywhere}.note{color:var(--muted);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.card-tags{display:flex;gap:5px;flex-wrap:wrap;margin-top:10px}.tag{font-size:11px;padding:2px 7px}.card-actions{display:flex;align-items:center;gap:4px;margin-top:auto;padding-top:12px}.open{color:var(--accent);text-decoration:none;font-weight:700;margin-right:auto}.icon,.ghost{border:0;background:transparent;border-radius:9px;padding:6px 8px}.icon:hover,.ghost:hover{background:#0000000a}.empty{text-align:center;color:var(--muted);padding:80px 20px}.empty b{display:block;color:var(--ink);font:600 23px Georgia,"Songti SC",serif;margin-bottom:6px}dialog{border:1px solid var(--line);border-radius:20px;background:var(--card);color:var(--ink);padding:0;width:min(520px,calc(100% - 28px));box-shadow:0 30px 100px #0003}dialog::backdrop{background:#281a1266;backdrop-filter:blur(4px)}form{padding:22px}.form-head{display:flex;justify-content:space-between;align-items:center}.form-head h2{font:600 24px Georgia,"Songti SC",serif;margin:0}.field{display:grid;gap:6px;margin:13px 0}.field label{font-size:12px;color:var(--muted);font-weight:700}.field input,.field textarea{border:1px solid var(--line);border-radius:11px;background:transparent;padding:10px 11px;outline:none}.field textarea{min-height:85px;resize:vertical}.form-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:18px}.toast{position:fixed;right:20px;bottom:20px;background:var(--ink);color:var(--card);padding:10px 13px;border-radius:11px}.error{background:var(--danger)}@media(max-width:580px){.shell{padding:22px 16px 70px}.header{align-items:start}h1{font-size:31px}.tools{display:grid}.search{max-width:none}.grid{grid-template-columns:1fr}}@media(prefers-color-scheme:dark){:root{--bg:#211f1b;--card:#2e2a25;--ink:#f1ece3;--muted:#aaa398;--line:#464038;--soft:#4b372c;--accent:#e19a70}.tag,.tag-filter.active{color:#f1b28e}.icon:hover,.ghost:hover{background:#ffffff0a}}
7
+ </style>
8
+ </head>
9
+ <body>
10
+ <main class="shell"><header class="header"><div><div class="eyebrow">Personal space</div><h1>收藏</h1><div class="subtitle">只保存值得回来看的东西。</div></div><button class="primary" id="add">+ 保存链接</button></header><section class="tools"><input class="search" id="search" placeholder="搜索标题、链接或备注…" aria-label="搜索收藏"><div class="tags" id="tags"></div></section><section class="grid" id="grid" aria-live="polite"><div class="empty">正在打开收藏夹…</div></section></main>
11
+ <dialog id="editor"><form method="dialog" id="form"><div class="form-head"><h2 id="formTitle">保存链接</h2><button class="icon" value="cancel" aria-label="关闭">✕</button></div><input type="hidden" id="id"><div class="field"><label for="url">链接</label><input id="url" type="url" required placeholder="https://"></div><div class="field"><label for="title">标题</label><input id="title" required maxlength="180"></div><div class="field"><label for="note">为什么保存</label><textarea id="note" placeholder="一句话就够了。"></textarea></div><div class="field"><label for="tagInput">标签(用逗号分隔)</label><input id="tagInput" placeholder="设计, 稍后读"></div><div class="form-actions"><button class="ghost" value="cancel">取消</button><button class="primary" value="default">保存</button></div></form></dialog><div id="toast" class="toast" role="status" hidden></div>
12
+ <script>
13
+ const service='nextclaw-personal-organizer-data.';let items=[],activeTag='';const $=id=>document.getElementById(id),grid=$('grid'),editor=$('editor'),toast=$('toast');
14
+ async function invoke(action,input={}){if(!window.nextclaw?.serviceActions)throw new Error('NextClaw 服务桥接不可用');return await window.nextclaw.serviceActions.invoke(service+action,input)}
15
+ function esc(value=''){return String(value).replace(/[&<>"]/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;'}[c]))}function notify(message,error=false){toast.textContent=message;toast.classList.toggle('error',error);toast.hidden=false;clearTimeout(notify.timer);notify.timer=setTimeout(()=>toast.hidden=true,2800)}
16
+ function domain(url){try{return new URL(url).hostname.replace(/^www\./,'')}catch{return url}}
17
+ async function load(){try{items=(await invoke('favorite_list',{query:$('search').value,tag:activeTag})).items||[];render()}catch(error){grid.innerHTML='<div class="empty"><b>还不能读取收藏</b><span>请检查个人空间的权限和启用状态。</span></div>';notify(error.message||String(error),true)}}
18
+ function render(){const allTags=[...new Set(items.flatMap(item=>item.tags||[]))].sort();$('tags').innerHTML=`<button class="tag-filter ${!activeTag?'active':''}" data-tag="">全部</button>${allTags.map(tag=>`<button class="tag-filter ${activeTag===tag?'active':''}" data-tag="${esc(tag)}"># ${esc(tag)}</button>`).join('')}`;if(!items.length){grid.innerHTML='<div class="empty"><b>收藏夹还是空的</b><span>保存一个真正想再看的链接。</span></div>';return}grid.innerHTML=items.map(item=>`<article class="card" data-id="${item.id}"><div class="domain">${esc(domain(item.url))}</div><h2>${esc(item.title)}</h2>${item.note?`<div class="note">${esc(item.note)}</div>`:''}<div class="card-tags">${(item.tags||[]).map(tag=>`<span class="tag">${esc(tag)}</span>`).join('')}</div><div class="card-actions"><a class="open" href="${esc(item.url)}" target="_blank" rel="noopener noreferrer">打开 ↗</a><button class="icon edit" aria-label="编辑">•••</button><button class="icon remove" aria-label="删除">⌫</button></div></article>`).join('')}
19
+ function openEditor(item){$('formTitle').textContent=item?'编辑收藏':'保存链接';$('id').value=item?.id||'';$('url').value=item?.url||'';$('title').value=item?.title||'';$('note').value=item?.note||'';$('tagInput').value=(item?.tags||[]).join(', ');editor.showModal();setTimeout(()=>$('url').focus(),20)}
20
+ $('add').addEventListener('click',()=>openEditor());$('form').addEventListener('submit',async event=>{if(event.submitter?.value==='cancel')return;event.preventDefault();const id=$('id').value,input={url:$('url').value.trim(),title:$('title').value.trim(),note:$('note').value.trim(),tags:$('tagInput').value.split(/[,,]/).map(v=>v.trim()).filter(Boolean)};try{await invoke(id?'favorite_update':'favorite_save',id?{id,...input}:input);editor.close();await load();notify(id?'收藏已更新':'已保存到收藏')}catch(error){notify(error.message||String(error),true)}});grid.addEventListener('click',async event=>{const card=event.target.closest('.card');if(!card)return;const item=items.find(entry=>entry.id===card.dataset.id);if(event.target.closest('.edit'))openEditor(item);if(event.target.closest('.remove')&&confirm(`删除“${item.title}”?`)){try{await invoke('favorite_delete',{id:item.id});await load();notify('收藏已删除')}catch(error){notify(error.message||String(error),true)}}});$('tags').addEventListener('click',event=>{const button=event.target.closest('[data-tag]');if(button){activeTag=button.dataset.tag;load()}});$('search').addEventListener('input',()=>{clearTimeout(load.timer);load.timer=setTimeout(load,180)});load();
21
+ </script>
22
+ </body>
23
+ </html>
@@ -0,0 +1,18 @@
1
+ {
2
+ "id": "nextclaw-personal-organizer-favorites",
3
+ "title": "收藏",
4
+ "titleI18n": { "zh-CN": "收藏", "en-US": "Favorites" },
5
+ "description": "轻量保存值得稍后回看的链接。",
6
+ "descriptionI18n": {
7
+ "zh-CN": "轻量保存值得稍后回看的链接。",
8
+ "en-US": "Save links that are worth coming back to."
9
+ },
10
+ "icon": "◇",
11
+ "entry": "index.html",
12
+ "actions": [
13
+ "nextclaw-personal-organizer-data.favorite_list",
14
+ "nextclaw-personal-organizer-data.favorite_save",
15
+ "nextclaw-personal-organizer-data.favorite_update",
16
+ "nextclaw-personal-organizer-data.favorite_delete"
17
+ ]
18
+ }
@@ -0,0 +1,28 @@
1
+ <!doctype html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>笔记</title>
5
+ <style>
6
+ :root{color-scheme:light dark;--bg:#f1eee7;--paper:#fffdf8;--ink:#2d302e;--muted:#81827c;--line:#dedbd2;--accent:#75679b;--soft:#ebe6f4;--danger:#a95049;font:14px/1.55 Inter,ui-sans-serif,system-ui,-apple-system,"PingFang SC",sans-serif}*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--ink);height:100vh;overflow:hidden}button,input,textarea{font:inherit;color:inherit}button{cursor:pointer}.app{display:grid;grid-template-columns:270px 1fr;height:100vh}.sidebar{border-right:1px solid var(--line);padding:20px 14px;background:color-mix(in srgb,var(--paper) 70%,transparent);display:flex;flex-direction:column;min-width:0}.brand{display:flex;justify-content:space-between;align-items:center;padding:0 6px 14px}.brand h1{font:600 25px/1 Georgia,"Songti SC",serif;margin:0}.new,.save{border:0;border-radius:11px;background:var(--ink);color:var(--paper);font-weight:700;padding:8px 11px}.search{border:1px solid var(--line);background:var(--paper);border-radius:11px;padding:9px 11px;outline:none;width:100%}.notes{overflow:auto;margin-top:12px;display:grid;gap:4px}.note{border:0;background:transparent;text-align:left;padding:10px;border-radius:11px;min-width:0}.note:hover{background:#00000008}.note.active{background:var(--soft)}.note b{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.note small{color:var(--muted)}.empty{padding:34px 12px;color:var(--muted);text-align:center}.main{min-width:0;display:flex;flex-direction:column;background:var(--paper)}.toolbar{display:flex;align-items:center;gap:9px;border-bottom:1px solid var(--line);padding:13px 18px}.title{border:0;background:transparent;outline:none;font:600 23px/1.2 Georgia,"Songti SC",serif;min-width:0;flex:1}.mode{display:flex;background:var(--bg);border-radius:10px;padding:3px}.mode button,.icon{border:0;background:transparent;border-radius:8px;padding:6px 9px}.mode button.active{background:var(--paper);box-shadow:0 1px 5px #0001}.icon:hover{background:#0000000a}.dirty{font-size:12px;color:var(--muted)}.workspace{flex:1;min-height:0;display:grid}.editor,.preview{grid-area:1/1;width:100%;height:100%;border:0;outline:0;padding:28px max(28px,8vw);background:transparent;overflow:auto}.editor{resize:none;font:15px/1.75 ui-monospace,SFMono-Regular,Menlo,monospace}.preview{font-size:16px;line-height:1.75}.preview h1,.preview h2,.preview h3{font-family:Georgia,"Songti SC",serif;line-height:1.25;margin:1.4em 0 .5em}.preview h1{font-size:30px}.preview h2{font-size:24px}.preview code{background:var(--bg);padding:2px 5px;border-radius:5px}.preview pre{background:#282b29;color:#eee;padding:15px;border-radius:12px;overflow:auto}.preview blockquote{border-left:3px solid var(--accent);margin-left:0;padding-left:16px;color:var(--muted)}.preview a{color:var(--accent)}.placeholder{margin:auto;text-align:center;color:var(--muted)}.placeholder b{display:block;color:var(--ink);font:600 25px Georgia,"Songti SC",serif;margin-bottom:8px}.toast{position:fixed;right:18px;bottom:18px;background:var(--ink);color:var(--paper);padding:10px 13px;border-radius:11px}.error{background:#8c3d37}@media(max-width:680px){.app{grid-template-columns:1fr}.sidebar{position:absolute;z-index:3;width:min(85vw,300px);height:100%;transform:translateX(-105%);transition:.2s;box-shadow:10px 0 40px #0002}.sidebar.open{transform:none}.mobile{display:block!important}}.mobile{display:none}@media(prefers-color-scheme:dark){:root{--bg:#202321;--paper:#292d2a;--ink:#eef0eb;--muted:#aaa9a3;--line:#41443f;--soft:#40394e}.note:hover,.icon:hover{background:#ffffff0a}}
7
+ </style>
8
+ </head>
9
+ <body>
10
+ <div class="app"><aside class="sidebar" id="sidebar"><div class="brand"><h1>笔记</h1><button class="new" id="new">+ 新建</button></div><input class="search" id="search" placeholder="搜索标题…" aria-label="搜索笔记"><div class="notes" id="notes"><div class="empty">正在读取 Markdown 文件…</div></div></aside><main class="main"><header class="toolbar"><button class="icon mobile" id="menu" aria-label="打开笔记列表">☰</button><input class="title" id="title" placeholder="无标题" disabled><span class="dirty" id="status"></span><div class="mode"><button id="writeMode" class="active">编辑</button><button id="previewMode">预览</button></div><button class="icon" id="delete" aria-label="删除笔记" disabled>⌫</button><button class="save" id="save" disabled>保存</button></header><section class="workspace" id="workspace"><div class="placeholder"><b>写下一点什么</b><span>每篇笔记都是一个真正的 Markdown 文件。</span></div></section></main></div>
11
+ <div id="toast" class="toast" role="status" hidden></div>
12
+ <script>
13
+ const service='nextclaw-personal-organizer-data.';let index=[],current=null,dirty=false,mode='write';const $=id=>document.getElementById(id),notes=$('notes'),workspace=$('workspace'),toast=$('toast');
14
+ async function invoke(action,input={}){if(!window.nextclaw?.serviceActions)throw new Error('NextClaw 服务桥接不可用');return await window.nextclaw.serviceActions.invoke(service+action,input)}
15
+ function esc(value=''){return String(value).replace(/[&<>"]/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;'}[c]))}
16
+ function notify(message,error=false){toast.textContent=message;toast.classList.toggle('error',error);toast.hidden=false;clearTimeout(notify.timer);notify.timer=setTimeout(()=>toast.hidden=true,2800)}
17
+ function setDirty(value){dirty=value;$('status').textContent=value?'未保存':'';document.title=`${value?'• ':''}笔记`}
18
+ async function loadIndex(query=''){try{index=(await invoke('note_list',{query})).items||[];renderIndex()}catch(error){notes.innerHTML='<div class="empty">无法读取笔记。请检查授权或应用状态。</div>';notify(error.message||String(error),true)}}
19
+ function renderIndex(){notes.innerHTML=index.length?index.map(item=>`<button class="note ${current?.id===item.id?'active':''}" data-id="${item.id}"><b>${esc(item.title)}</b><small>${new Date(item.updatedAt).toLocaleDateString()}</small></button>`).join(''):'<div class="empty">还没有笔记。<br>从一个标题开始。</div>'}
20
+ async function select(id){if(dirty&&!confirm('当前修改尚未保存,仍要切换吗?'))return;try{current=(await invoke('note_read',{id})).item;setDirty(false);renderEditor();renderIndex();$('sidebar').classList.remove('open')}catch(error){notify(error.message||String(error),true)}}
21
+ function renderEditor(){if(!current){workspace.innerHTML='<div class="placeholder"><b>写下一点什么</b><span>每篇笔记都是一个真正的 Markdown 文件。</span></div>';$('title').value='';$('title').disabled=true;$('save').disabled=true;$('delete').disabled=true;return}$('title').disabled=false;$('save').disabled=false;$('delete').disabled=false;$('title').value=current.title;workspace.innerHTML=mode==='write'?'<textarea class="editor" id="content" aria-label="Markdown 内容" spellcheck="true"></textarea>':'<article class="preview" id="preview"></article>';if(mode==='write'){$('content').value=current.content||'';$('content').addEventListener('input',()=>{current.content=$('content').value;setDirty(true)})}else $('preview').innerHTML=markdown(current.content||'');$('writeMode').classList.toggle('active',mode==='write');$('previewMode').classList.toggle('active',mode==='preview')}
22
+ function markdown(raw){let text=esc(raw);const blocks=[];text=text.replace(/```([\s\S]*?)```/g,(_,code)=>{blocks.push(`<pre><code>${code.trim()}</code></pre>`);return `\n@@BLOCK${blocks.length-1}@@\n`});text=text.replace(/^### (.+)$/gm,'<h3>$1</h3>').replace(/^## (.+)$/gm,'<h2>$1</h2>').replace(/^# (.+)$/gm,'<h1>$1</h1>').replace(/^> (.+)$/gm,'<blockquote>$1</blockquote>').replace(/^[-*] (.+)$/gm,'<li>$1</li>').replace(/\*\*(.+?)\*\*/g,'<strong>$1</strong>').replace(/`([^`]+)`/g,'<code>$1</code>').replace(/\[([^\]]+)\]\((https?:\/\/[^\s)]+)\)/g,'<a href="$2" target="_blank" rel="noopener">$1</a>').split(/\n{2,}/).map(part=>/^<(h\d|blockquote|li|pre)/.test(part)||/^@@BLOCK/.test(part)?part:`<p>${part.replace(/\n/g,'<br>')}</p>`).join('');return text.replace(/@@BLOCK(\d+)@@/g,(_,i)=>blocks[Number(i)]||'')}
23
+ async function save(){if(!current)return;const title=$('title').value.trim();if(!title){notify('请先写一个标题',true);$('title').focus();return}try{const payload=await invoke('note_save',{id:current.id||undefined,title,content:current.content||''});current=payload.item;setDirty(false);await loadIndex($('search').value);notify('Markdown 已保存')}catch(error){notify(error.message||String(error),true)}}
24
+ $('new').addEventListener('click',()=>{if(dirty&&!confirm('当前修改尚未保存,仍要新建吗?'))return;current={id:'',title:'',content:'',createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()};mode='write';setDirty(true);renderEditor();$('title').focus();$('sidebar').classList.remove('open')});
25
+ notes.addEventListener('click',event=>{const button=event.target.closest('[data-id]');if(button)select(button.dataset.id)});$('search').addEventListener('input',event=>{clearTimeout(loadIndex.timer);loadIndex.timer=setTimeout(()=>loadIndex(event.target.value),180)});$('title').addEventListener('input',()=>{if(current){current.title=$('title').value;setDirty(true)}});$('save').addEventListener('click',save);$('writeMode').addEventListener('click',()=>{mode='write';renderEditor()});$('previewMode').addEventListener('click',()=>{if(current&&mode==='write'&&$('content'))current.content=$('content').value;mode='preview';renderEditor()});$('delete').addEventListener('click',async()=>{if(!current?.id||!confirm(`删除“${current.title}”?Markdown 文件也会被删除。`))return;try{await invoke('note_delete',{id:current.id});current=null;setDirty(false);renderEditor();await loadIndex();notify('笔记已删除')}catch(error){notify(error.message||String(error),true)}});$('menu').addEventListener('click',()=>$('sidebar').classList.toggle('open'));window.addEventListener('keydown',event=>{if((event.metaKey||event.ctrlKey)&&event.key.toLowerCase()==='s'){event.preventDefault();save()}});window.addEventListener('beforeunload',event=>{if(dirty){event.preventDefault();event.returnValue=''}});loadIndex();
26
+ </script>
27
+ </body>
28
+ </html>
@@ -0,0 +1,18 @@
1
+ {
2
+ "id": "nextclaw-personal-organizer-notes",
3
+ "title": "笔记",
4
+ "titleI18n": { "zh-CN": "笔记", "en-US": "Notes" },
5
+ "description": "以 Markdown 文件沉淀想法和资料。",
6
+ "descriptionI18n": {
7
+ "zh-CN": "以 Markdown 文件沉淀想法和资料。",
8
+ "en-US": "Keep ideas and references in real Markdown files."
9
+ },
10
+ "icon": "✎",
11
+ "entry": "index.html",
12
+ "actions": [
13
+ "nextclaw-personal-organizer-data.note_list",
14
+ "nextclaw-personal-organizer-data.note_read",
15
+ "nextclaw-personal-organizer-data.note_save",
16
+ "nextclaw-personal-organizer-data.note_delete"
17
+ ]
18
+ }
@@ -0,0 +1,43 @@
1
+ <!doctype html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <title>待办</title>
7
+ <style>
8
+ :root{color-scheme:light dark;--bg:#f4f1ea;--card:#fffdf8;--ink:#26302c;--muted:#78817d;--line:#dedbd2;--accent:#5c6f62;--accent2:#dfe7dd;--danger:#a64c45;--shadow:0 18px 50px #28322d12;font:14px/1.5 Inter,ui-sans-serif,system-ui,-apple-system,"PingFang SC",sans-serif}*{box-sizing:border-box}body{margin:0;background:radial-gradient(circle at 90% 0,#dfe8dc 0,transparent 30%),var(--bg);color:var(--ink);min-height:100vh}button,input,textarea,select{font:inherit;color:inherit}button{cursor:pointer}.shell{max-width:860px;margin:auto;padding:30px 28px 80px}.eyebrow{font-size:12px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted);font-weight:700}.header{display:flex;align-items:end;justify-content:space-between;gap:20px;margin:5px 0 24px}h1{font-family:Georgia,"Songti SC",serif;font-size:36px;line-height:1.1;margin:0;font-weight:600}.summary{color:var(--muted);margin-top:7px}.icon-btn,.ghost,.primary,.danger{border:0;border-radius:12px;padding:9px 13px;background:transparent}.icon-btn:hover,.ghost:hover{background:#0000000a}.primary{background:var(--ink);color:var(--card);font-weight:700}.danger{color:var(--danger)}.danger:hover{background:color-mix(in srgb,var(--danger) 10%,transparent)}.composer{display:grid;grid-template-columns:1fr auto;gap:10px;background:var(--card);padding:10px;border:1px solid var(--line);border-radius:18px;box-shadow:var(--shadow)}.composer input{border:0;background:transparent;padding:6px 10px;outline:none;font-size:16px}.tabs{display:flex;gap:4px;margin:22px 0 12px}.tab{border:0;background:transparent;color:var(--muted);padding:8px 12px;border-radius:999px}.tab[aria-selected=true]{background:var(--accent2);color:var(--ink);font-weight:700}.list{display:grid;gap:9px}.item{display:grid;grid-template-columns:auto 1fr auto;gap:13px;align-items:start;background:color-mix(in srgb,var(--card) 94%,transparent);border:1px solid var(--line);border-radius:16px;padding:14px 14px 13px;transition:.18s ease}.item:hover{transform:translateY(-1px);box-shadow:0 10px 30px #28322d0d}.check{appearance:none;width:21px;height:21px;border:1.5px solid #8b948f;border-radius:7px;margin:2px 0 0;display:grid;place-items:center}.check:checked{background:var(--accent);border-color:var(--accent)}.check:checked:after{content:"✓";color:white;font-size:14px;font-weight:800}.title{font-weight:700;font-size:15px;overflow-wrap:anywhere}.completed .title{text-decoration:line-through;color:var(--muted)}.meta{display:flex;gap:8px;align-items:center;flex-wrap:wrap;color:var(--muted);font-size:12px;margin-top:4px}.pill{border-radius:999px;padding:2px 7px;background:#eeeae0}.high{background:#f2dcd8;color:#8d433d}.low{background:#dfe8ed;color:#4d6875}.actions{display:flex}.empty{text-align:center;padding:70px 20px;color:var(--muted)}.empty b{display:block;color:var(--ink);font-family:Georgia,"Songti SC",serif;font-size:22px;margin-bottom:7px}.loading{padding:50px;text-align:center;color:var(--muted)}dialog{border:1px solid var(--line);border-radius:20px;background:var(--card);color:var(--ink);padding:0;width:min(520px,calc(100% - 28px));box-shadow:0 30px 100px #0003}dialog::backdrop{background:#18201d70;backdrop-filter:blur(4px)}form{padding:22px}.form-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:18px}.form-head h2{font-family:Georgia,"Songti SC",serif;margin:0;font-size:24px}.field{display:grid;gap:6px;margin:13px 0}.field label{font-size:12px;color:var(--muted);font-weight:700}.field input,.field textarea,.field select{width:100%;border:1px solid var(--line);border-radius:11px;background:transparent;padding:10px 11px;outline:none}.field textarea{min-height:100px;resize:vertical}.grid{display:grid;grid-template-columns:1fr 1fr;gap:12px}.form-actions{display:flex;justify-content:space-between;gap:8px;margin-top:20px}.form-actions-end{display:flex;gap:8px}.toast{position:fixed;right:20px;bottom:20px;max-width:340px;background:var(--ink);color:var(--card);border-radius:12px;padding:11px 14px;box-shadow:var(--shadow)}.error{background:#f6e0dc;color:#833b35}.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0)}@media(max-width:560px){.shell{padding:22px 16px 70px}h1{font-size:31px}.header{align-items:start}.grid{grid-template-columns:1fr}.item{grid-template-columns:auto 1fr}.actions{grid-column:2}.composer{grid-template-columns:1fr}.composer button{width:100%}}@media(prefers-color-scheme:dark){:root{--bg:#1e2421;--card:#282f2b;--ink:#edf0eb;--muted:#a5ada8;--line:#3d4641;--accent:#8da692;--accent2:#37463c;--danger:#e58b82;--shadow:0 18px 50px #0003}.pill{background:#343b37}.high{background:#5b3431;color:#ffd5d0}.low{background:#30454f;color:#d2effc}}
9
+ </style>
10
+ </head>
11
+ <body>
12
+ <main class="shell">
13
+ <div class="eyebrow">Personal space</div>
14
+ <header class="header"><div><h1>待办</h1><div class="summary" id="summary">把下一步放在眼前。</div></div><button class="ghost" id="detailAdd">+ 详细待办</button></header>
15
+ <form class="composer" id="quickForm"><label class="sr" for="quickTitle">新增待办</label><input id="quickTitle" autocomplete="off" placeholder="接下来要做什么?"><button class="primary" type="submit">添加</button></form>
16
+ <nav class="tabs" aria-label="待办筛选"><button class="tab" data-filter="open" aria-selected="true">未完成</button><button class="tab" data-filter="all">全部</button><button class="tab" data-filter="completed">已完成</button></nav>
17
+ <section class="list" id="list" aria-live="polite"><div class="loading">正在整理待办…</div></section>
18
+ </main>
19
+ <dialog id="editor"><form method="dialog" id="editForm"><div class="form-head"><h2 id="formTitle">新待办</h2><button class="icon-btn" value="cancel" aria-label="关闭">✕</button></div><input type="hidden" id="editId"><div class="field"><label for="editTitle">标题</label><input id="editTitle" required maxlength="180"></div><div class="grid"><div class="field"><label for="editDue">截止时间</label><input id="editDue" type="datetime-local"></div><div class="field"><label for="editPriority">优先级</label><select id="editPriority"><option value="normal">普通</option><option value="high">高</option><option value="low">低</option></select></div></div><div class="field"><label for="editNotes">备注</label><textarea id="editNotes" placeholder="补充必要的上下文,不必写成项目文档。"></textarea></div><div class="form-actions"><button class="danger" id="deleteTodo" type="button" hidden>删除待办</button><div class="form-actions-end"><button class="ghost" value="cancel">取消</button><button class="primary" id="save" value="default">保存</button></div></div></form></dialog>
20
+ <div id="toast" class="toast" role="status" hidden></div>
21
+ <script>
22
+ const service='nextclaw-personal-organizer-data.';let items=[],filter='open';
23
+ const $=id=>document.getElementById(id);const list=$('list'),editor=$('editor'),toast=$('toast');
24
+ async function invoke(action,input={}){if(!window.nextclaw?.serviceActions)throw new Error('NextClaw 服务桥接不可用');return await window.nextclaw.serviceActions.invoke(service+action,input)}
25
+ function notify(message,error=false){toast.textContent=message;toast.classList.toggle('error',error);toast.hidden=false;clearTimeout(notify.timer);notify.timer=setTimeout(()=>toast.hidden=true,3000)}
26
+ function esc(value=''){return String(value).replace(/[&<>"]/g,char=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;'}[char]))}
27
+ function formatDate(value){if(!value)return '';const date=new Date(value);return Number.isFinite(date.getTime())?new Intl.DateTimeFormat(undefined,{month:'short',day:'numeric',hour:'2-digit',minute:'2-digit'}).format(date):value}
28
+ async function load(){list.innerHTML='<div class="loading">正在整理待办…</div>';try{items=(await invoke('todo_list',{status:'all'})).items||[];render()}catch(error){list.innerHTML='<div class="empty"><b>还不能读取待办</b><span>请完成权限授权,或从 Apps 中重新启用个人空间。</span></div>';notify(error.message||String(error),true)}}
29
+ function render(){const visible=items.filter(item=>filter==='all'||(filter==='completed')===!!item.completed);const open=items.filter(item=>!item.completed).length;$('summary').textContent=open?`${open} 件事仍在等待你。`:'眼前暂时没有未完成的事。';if(!visible.length){list.innerHTML=`<div class="empty"><b>${filter==='completed'?'还没有完成记录':'这里很清爽'}</b><span>${filter==='open'?'记下一件真正要做的事。':'换个筛选看看。'}</span></div>`;return}list.innerHTML=visible.map(item=>`<article class="item ${item.completed?'completed':''}" data-id="${item.id}"><input class="check" type="checkbox" ${item.completed?'checked':''} aria-label="${item.completed?'标记为未完成':'完成'}:${esc(item.title)}"><div><div class="title">${esc(item.title)}</div><div class="meta">${item.dueDate?`<span>${formatDate(item.dueDate)}</span>`:''}${item.priority&&item.priority!=='normal'?`<span class="pill ${item.priority}">${item.priority==='high'?'高优先级':'低优先级'}</span>`:''}${item.notes?`<span title="${esc(item.notes)}">有备注</span>`:''}</div></div><div class="actions"><button class="icon-btn edit" aria-label="编辑">•••</button></div></article>`).join('')}
30
+ async function create(title,extra={}){const payload=await invoke('todo_create',{title,...extra});items.unshift(payload.item);render();notify('待办已添加')}
31
+ $('quickForm').addEventListener('submit',async event=>{event.preventDefault();const input=$('quickTitle'),title=input.value.trim();if(!title)return;input.disabled=true;try{await create(title);input.value=''}catch(error){notify(error.message||String(error),true)}finally{input.disabled=false;input.focus()}})
32
+ document.querySelector('.tabs').addEventListener('click',event=>{const button=event.target.closest('[data-filter]');if(!button)return;filter=button.dataset.filter;document.querySelectorAll('.tab').forEach(tab=>tab.setAttribute('aria-selected',String(tab===button)));render()})
33
+ list.addEventListener('change',async event=>{if(!event.target.matches('.check'))return;const id=event.target.closest('.item').dataset.id;try{const payload=await invoke('todo_update',{id,completed:event.target.checked});items=items.map(item=>item.id===id?payload.item:item);render()}catch(error){event.target.checked=!event.target.checked;notify(error.message||String(error),true)}})
34
+ list.addEventListener('click',event=>{const button=event.target.closest('.edit');if(!button)return;openEditor(items.find(item=>item.id===button.closest('.item').dataset.id))})
35
+ function localDate(value){if(!value)return '';const d=new Date(value),pad=n=>String(n).padStart(2,'0');return `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`}
36
+ function openEditor(item){$('formTitle').textContent=item?'编辑待办':'新待办';$('editId').value=item?.id||'';$('editTitle').value=item?.title||'';$('editDue').value=localDate(item?.dueDate);$('editPriority').value=item?.priority||'normal';$('editNotes').value=item?.notes||'';$('deleteTodo').hidden=!item;editor.showModal();setTimeout(()=>$('editTitle').focus(),20)}
37
+ $('detailAdd').addEventListener('click',()=>openEditor());
38
+ $('deleteTodo').addEventListener('click',async()=>{const id=$('editId').value,item=items.find(entry=>entry.id===id);if(!id||!item||!confirm(`删除“${item.title}”?`))return;try{await invoke('todo_delete',{id});items=items.filter(entry=>entry.id!==id);editor.close();render();notify('待办已删除')}catch(error){notify(error.message||String(error),true)}})
39
+ $('editForm').addEventListener('submit',async event=>{if(event.submitter?.value==='cancel')return;event.preventDefault();const id=$('editId').value,input={title:$('editTitle').value.trim(),dueDate:$('editDue').value?new Date($('editDue').value).toISOString():'',priority:$('editPriority').value,notes:$('editNotes').value.trim()};if(!input.title)return;try{if(id){const payload=await invoke('todo_update',{id,...input});items=items.map(item=>item.id===id?payload.item:item)}else await create(input.title,input);editor.close();render();notify('已保存')}catch(error){notify(error.message||String(error),true)}})
40
+ load();
41
+ </script>
42
+ </body>
43
+ </html>
@@ -0,0 +1,18 @@
1
+ {
2
+ "id": "nextclaw-personal-organizer-todos",
3
+ "title": "待办",
4
+ "titleI18n": { "zh-CN": "待办", "en-US": "Todos" },
5
+ "description": "清楚地记下接下来要做的事。",
6
+ "descriptionI18n": {
7
+ "zh-CN": "清楚地记下接下来要做的事。",
8
+ "en-US": "Keep the next things you need to do in view."
9
+ },
10
+ "icon": "✓",
11
+ "entry": "index.html",
12
+ "actions": [
13
+ "nextclaw-personal-organizer-data.todo_list",
14
+ "nextclaw-personal-organizer-data.todo_create",
15
+ "nextclaw-personal-organizer-data.todo_update",
16
+ "nextclaw-personal-organizer-data.todo_delete"
17
+ ]
18
+ }