nextclaw 0.44.1 → 0.45.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.
- package/dist/cli/app/index.js +2 -2
- package/dist/cli/launcher/index.js +1 -1
- package/dist/{nextclaw-cli-app-scOxgGRP.js → nextclaw-cli-app-Bwa2L2Jv.js} +306 -22
- package/dist/nextclaw-cli-app-Bwa2L2Jv.js.map +1 -0
- package/dist/{nextclaw-distribution.utils-BneKclXo.js → nextclaw-distribution.utils-Bba2GRvc.js} +4 -2
- package/dist/nextclaw-distribution.utils-Bba2GRvc.js.map +1 -0
- package/package.json +15 -14
- package/resources/USAGE.md +36 -4
- package/resources/apps/nextclaw-personal-organizer/README.md +1 -1
- package/resources/apps/nextclaw-portable-runtime-lab/README.md +34 -0
- package/resources/apps/nextclaw-portable-runtime-lab/assets/icon.svg +12 -0
- package/resources/apps/nextclaw-portable-runtime-lab/manifest.json +74 -0
- package/resources/apps/nextclaw-portable-runtime-lab/marketplace.json +21 -0
- package/resources/apps/nextclaw-portable-runtime-lab/panels/nextclaw-portable-runtime-lab-contacts.panel/assets/app.js +92 -0
- package/resources/apps/nextclaw-portable-runtime-lab/panels/nextclaw-portable-runtime-lab-contacts.panel/assets/style.css +43 -0
- package/resources/apps/nextclaw-portable-runtime-lab/panels/nextclaw-portable-runtime-lab-contacts.panel/index.html +43 -0
- package/resources/apps/nextclaw-portable-runtime-lab/panels/nextclaw-portable-runtime-lab-contacts.panel/panel-app.json +10 -0
- package/resources/apps/nextclaw-portable-runtime-lab/panels/nextclaw-portable-runtime-lab-focus.panel/assets/app.js +132 -0
- package/resources/apps/nextclaw-portable-runtime-lab/panels/nextclaw-portable-runtime-lab-focus.panel/assets/style.css +39 -0
- package/resources/apps/nextclaw-portable-runtime-lab/panels/nextclaw-portable-runtime-lab-focus.panel/index.html +40 -0
- package/resources/apps/nextclaw-portable-runtime-lab/panels/nextclaw-portable-runtime-lab-focus.panel/panel-app.json +14 -0
- package/resources/apps/nextclaw-portable-runtime-lab/panels/nextclaw-portable-runtime-lab-notes.panel/assets/app.js +117 -0
- package/resources/apps/nextclaw-portable-runtime-lab/panels/nextclaw-portable-runtime-lab-notes.panel/assets/style.css +41 -0
- package/resources/apps/nextclaw-portable-runtime-lab/panels/nextclaw-portable-runtime-lab-notes.panel/index.html +41 -0
- package/resources/apps/nextclaw-portable-runtime-lab/panels/nextclaw-portable-runtime-lab-notes.panel/panel-app.json +12 -0
- package/resources/apps/nextclaw-portable-runtime-lab/panels/nextclaw-portable-runtime-lab-panel.panel/assets/app.js +266 -0
- package/resources/apps/nextclaw-portable-runtime-lab/panels/nextclaw-portable-runtime-lab-panel.panel/assets/style.css +87 -0
- package/resources/apps/nextclaw-portable-runtime-lab/panels/nextclaw-portable-runtime-lab-panel.panel/index.html +154 -0
- package/resources/apps/nextclaw-portable-runtime-lab/panels/nextclaw-portable-runtime-lab-panel.panel/panel-app.json +29 -0
- package/resources/apps/nextclaw-portable-runtime-lab/panels/nextclaw-portable-runtime-lab-todos.panel/assets/app.js +143 -0
- package/resources/apps/nextclaw-portable-runtime-lab/panels/nextclaw-portable-runtime-lab-todos.panel/assets/style.css +48 -0
- package/resources/apps/nextclaw-portable-runtime-lab/panels/nextclaw-portable-runtime-lab-todos.panel/index.html +45 -0
- package/resources/apps/nextclaw-portable-runtime-lab/panels/nextclaw-portable-runtime-lab-todos.panel/panel-app.json +12 -0
- package/resources/apps/nextclaw-portable-runtime-lab/service-components/nextclaw-portable-runtime-lab-capabilities/service-app.json +20 -0
- package/resources/apps/nextclaw-portable-runtime-lab/service-components/nextclaw-portable-runtime-lab-capabilities/service.wasm +0 -0
- package/resources/apps/nextclaw-portable-runtime-lab/service-components/nextclaw-portable-runtime-lab-composition/service-app.json +30 -0
- package/resources/apps/nextclaw-portable-runtime-lab/service-components/nextclaw-portable-runtime-lab-composition/service.wasm +0 -0
- package/resources/apps/nextclaw-portable-runtime-lab/service-components/nextclaw-portable-runtime-lab-provider/service-app.json +30 -0
- package/resources/apps/nextclaw-portable-runtime-lab/service-components/nextclaw-portable-runtime-lab-provider/service.wasm +0 -0
- package/resources/apps/nextclaw-portable-runtime-lab/service-components/nextclaw-portable-runtime-lab-resident/service-app.json +31 -0
- package/resources/apps/nextclaw-portable-runtime-lab/service-components/nextclaw-portable-runtime-lab-resident/service.wasm +0 -0
- package/resources/apps/nextclaw-portable-runtime-lab/service-components/nextclaw-portable-runtime-lab-state/service-app.json +49 -0
- package/resources/apps/nextclaw-portable-runtime-lab/service-components/nextclaw-portable-runtime-lab-state/service.wasm +0 -0
- package/ui-dist/assets/abnfDiagram-VRR7QNED-BcFJp_1X.js.gz +0 -0
- package/ui-dist/assets/aiden0z-pptx-renderer.es-Dp2ezlQn.js.gz +0 -0
- package/ui-dist/assets/{api-iMkU_o5P.js → api-m33O1Kb0.js} +6 -6
- package/ui-dist/assets/api-m33O1Kb0.js.gz +0 -0
- package/ui-dist/assets/{appearance-settings-page-CU5k4b-M.js → appearance-settings-page-x4Vjnfmz.js} +1 -1
- package/ui-dist/assets/appearance-settings-page-x4Vjnfmz.js.gz +0 -0
- package/ui-dist/assets/arc-CkgyPMyW.js.gz +0 -0
- package/ui-dist/assets/architectureDiagram-ZJ3FMSHR-CMd4cIjI.js.gz +0 -0
- package/ui-dist/assets/blockDiagram-677ZJIJ3-Bz3tbhet.js.gz +0 -0
- package/ui-dist/assets/{book-open-nD8gdMhA.js → book-open-BHiasMCg.js} +1 -1
- package/ui-dist/assets/c4Diagram-LMCZKHZV-D9hFNAGv.js.gz +0 -0
- package/ui-dist/assets/{channels-list-page-Drlt62kY.js → channels-list-page-DOxJZeXq.js} +2 -2
- package/ui-dist/assets/channels-list-page-DOxJZeXq.js.gz +0 -0
- package/ui-dist/assets/chunk-32BRIVSS-7NrjEITq.js.gz +0 -0
- package/ui-dist/assets/chunk-52WLFC77-viIcqj9q.js.gz +0 -0
- package/ui-dist/assets/chunk-5JV3BV7I-CuKgJQ4W.js.gz +0 -0
- package/ui-dist/assets/chunk-5TONJI2A-CYeiWZKb.js.gz +0 -0
- package/ui-dist/assets/chunk-7BUUIJ7U-BvydOcm3.js.gz +0 -0
- package/ui-dist/assets/chunk-C7G6YPKG-DAizzYwr.js.gz +0 -0
- package/ui-dist/assets/chunk-DseTPa7n.js.gz +0 -0
- package/ui-dist/assets/chunk-EX3LRPZG-BmlDFIRW.js.gz +0 -0
- package/ui-dist/assets/chunk-FWX5IMBZ-D0ksHZZ9.js.gz +0 -0
- package/ui-dist/assets/chunk-HOUHSVGY-DPkq8FCm.js.gz +0 -0
- package/ui-dist/assets/chunk-ICXQ74PX-FAatv5fC.js.gz +0 -0
- package/ui-dist/assets/chunk-JG7HCLWE-DLkIi4F7.js.gz +0 -0
- package/ui-dist/assets/chunk-KEIR6QF5-f9psyCXK.js.gz +0 -0
- package/ui-dist/assets/chunk-MOJQB5TN-Di52TorW.js.gz +0 -0
- package/ui-dist/assets/chunk-PUDLZKDR-f3IJh3sN.js.gz +0 -0
- package/ui-dist/assets/chunk-Q4XR5HBZ-DQFeUPxZ.js.gz +0 -0
- package/ui-dist/assets/chunk-R7FJI6CG-C3XpZ-2u.js.gz +0 -0
- package/ui-dist/assets/chunk-RYQCIY6F-CAqa5klQ.js.gz +0 -0
- package/ui-dist/assets/chunk-U6XO7XAA-D_WXezeD.js.gz +0 -0
- package/ui-dist/assets/chunk-V7JOEXUC-CZ70oOtp.js.gz +0 -0
- package/ui-dist/assets/chunk-WYO6CB5R-Dn9To_OI.js.gz +0 -0
- package/ui-dist/assets/chunk-ZGVPDNZ5-C6YtZDU0.js.gz +0 -0
- package/ui-dist/assets/chunk-ZIRB5QZD-DMuYtnHF.js.gz +0 -0
- package/ui-dist/assets/{config-split-page-BtJZp1E5.js → config-split-page-DBnMEP1o.js} +1 -1
- package/ui-dist/assets/config-split-page-DBnMEP1o.js.gz +0 -0
- package/ui-dist/assets/{confirm-dialog-k2-Jq_x3.js → confirm-dialog-f5NKLh5I.js} +2 -2
- package/ui-dist/assets/confirm-dialog-f5NKLh5I.js.gz +0 -0
- package/ui-dist/assets/cose-bilkent-JH36ORCC-Bc2Ex5Y3.js.gz +0 -0
- package/ui-dist/assets/{createLucideIcon-DxlwKLr-.js → createLucideIcon-CHALGA42.js} +1 -1
- package/ui-dist/assets/cynefinDiagram-TSTJHNR4-DVysQoGz.js.gz +0 -0
- package/ui-dist/assets/cytoscape.esm-0uDtdD0l.js.gz +0 -0
- package/ui-dist/assets/dagre-CMhQ1cAG.js.gz +0 -0
- package/ui-dist/assets/dagre-VKFMJZFB-RYyWpPJZ.js.gz +0 -0
- package/ui-dist/assets/defaultLocale-DSWXGgt0.js.gz +0 -0
- package/ui-dist/assets/desktop-capabilities-page-DixayAe6.js +1 -0
- package/ui-dist/assets/desktop-capabilities-page-DixayAe6.js.gz +0 -0
- package/ui-dist/assets/desktop-update-config-ChhfeOHj.js +1 -0
- package/ui-dist/assets/desktop-update-config-ChhfeOHj.js.gz +0 -0
- package/ui-dist/assets/diagram-FQU43EPY-BD6KONdF.js.gz +0 -0
- package/ui-dist/assets/diagram-G47NLZAW-CGB2ptRR.js.gz +0 -0
- package/ui-dist/assets/diagram-NH7WQ7WH-DnkOI6cU.js.gz +0 -0
- package/ui-dist/assets/diagram-OA4YK3LP-DF82RZ7P.js.gz +0 -0
- package/ui-dist/assets/diagram-WEI45ONY-Be2v7Ck9.js.gz +0 -0
- package/ui-dist/assets/dist--ta5rX12.js.gz +0 -0
- package/ui-dist/assets/{dist-Cy_e4kNb.js → dist-_UMsWSY0.js} +1 -1
- package/ui-dist/assets/dist-_UMsWSY0.js.gz +0 -0
- package/ui-dist/assets/{dist-m08DUswB.js → dist-sD6V4nHX.js} +1 -1
- package/ui-dist/assets/dist-sD6V4nHX.js.gz +0 -0
- package/ui-dist/assets/doc-browser-Bq7LJsQY.js +1 -0
- package/ui-dist/assets/doc-browser-Bq7LJsQY.js.gz +0 -0
- package/ui-dist/assets/doc-browser-BuDgpY2e.js +1 -0
- package/ui-dist/assets/{doc-browser-context-jiy-O4F8.js → doc-browser-context-Capim3og.js} +1 -1
- package/ui-dist/assets/doc-browser-context-Capim3og.js.gz +0 -0
- package/ui-dist/assets/docx-preview-BqwAjrj3.js.gz +0 -0
- package/ui-dist/assets/ebnfDiagram-CCIWWBDH-CP98OYk8.js.gz +0 -0
- package/ui-dist/assets/erDiagram-Q63AITRT-ZLlx8xfs.js.gz +0 -0
- package/ui-dist/assets/{extensions-CIb17__o.js → extensions-Bdclr3Wr.js} +1 -1
- package/ui-dist/assets/extensions-Bdclr3Wr.js.gz +0 -0
- package/ui-dist/assets/{form-actions-DGf5zUg_.js → form-actions-CH0kWhEt.js} +1 -1
- package/ui-dist/assets/ganttDiagram-NO4QXBWP-DXCDjHR2.js.gz +0 -0
- package/ui-dist/assets/gitGraphDiagram-IHSO6WYX-l2HWrTJp.js.gz +0 -0
- package/ui-dist/assets/graphlib-CQ6QV4yP.js.gz +0 -0
- package/ui-dist/assets/index-BjxnLYE3.js +109 -0
- package/ui-dist/assets/index-BjxnLYE3.js.gz +0 -0
- package/ui-dist/assets/index-CBmwJjwE.css +1 -0
- package/ui-dist/assets/index-CBmwJjwE.css.gz +0 -0
- package/ui-dist/assets/ishikawaDiagram-FXEZZL3T-y_Xy128F.js.gz +0 -0
- package/ui-dist/assets/journeyDiagram-5HDEW3XC-DJn5xYcQ.js.gz +0 -0
- package/ui-dist/assets/jszip.min-8hyJpgpx.js.gz +0 -0
- package/ui-dist/assets/kanban-definition-HUTT4EX6-DJVIOR21.js.gz +0 -0
- package/ui-dist/assets/katex-ARhY9PS1.js.gz +0 -0
- package/ui-dist/assets/linear-BtDLqtzF.js.gz +0 -0
- package/ui-dist/assets/loader-circle-CH_0iPLy.js +1 -0
- package/ui-dist/assets/map-BKnQyvd0.js.gz +0 -0
- package/ui-dist/assets/mcp-marketplace-page-BUsxLVB5.js +10 -0
- package/ui-dist/assets/mcp-marketplace-page-BUsxLVB5.js.gz +0 -0
- package/ui-dist/assets/mcp-marketplace-page-GPRV3fB0.js +1 -0
- package/ui-dist/assets/mermaid-parser.core-XUNZhr2W.js.gz +0 -0
- package/ui-dist/assets/mermaid.core-ySrvolIe.js.gz +0 -0
- package/ui-dist/assets/middleware-DXsbf9xI.js.gz +0 -0
- package/ui-dist/assets/mindmap-definition-LN4V7U3C-BypL9tei.js.gz +0 -0
- package/ui-dist/assets/model-config-page-CIevwqp4.js +1 -0
- package/ui-dist/assets/model-config-page-CIevwqp4.js.gz +0 -0
- package/ui-dist/assets/{navigation-link-DAfwFCj4.js → navigation-link-CAUiM3zS.js} +1 -1
- package/ui-dist/assets/navigation-link-CAUiM3zS.js.gz +0 -0
- package/ui-dist/assets/ordinal-CxxVWxYU.js.gz +0 -0
- package/ui-dist/assets/path-10BjdyLh.js.gz +0 -0
- package/ui-dist/assets/pegDiagram-2B236MQR-D-U2KBGv.js.gz +0 -0
- package/ui-dist/assets/pieDiagram-ENE6RG2P-CBi3GusJ.js.gz +0 -0
- package/ui-dist/assets/plus-B3obD55V.js +1 -0
- package/ui-dist/assets/preload-helper-D4M6sveU.js.gz +0 -0
- package/ui-dist/assets/privacy-settings-page-CNKfZsYH.js +1 -0
- package/ui-dist/assets/privacy-settings-page-CNKfZsYH.js.gz +0 -0
- package/ui-dist/assets/providers-config-page-DAah2NIS.js +1 -0
- package/ui-dist/assets/providers-config-page-DAah2NIS.js.gz +0 -0
- package/ui-dist/assets/quadrantDiagram-ABIIQ3AL-H0ZuvnZL.js.gz +0 -0
- package/ui-dist/assets/railroadDiagram-RFXS5EU6-D7Y2EqSd.js.gz +0 -0
- package/ui-dist/assets/react-Co6JiC1n.js +8 -0
- package/ui-dist/assets/react-Co6JiC1n.js.gz +0 -0
- package/ui-dist/assets/{refresh-cw-D_Eibznw.js → refresh-cw-BG_LX3SS.js} +1 -1
- package/ui-dist/assets/remote-DuscgfvR.js +1 -0
- package/ui-dist/assets/requirementDiagram-TGXJPOKE-BiXNX1NN.js.gz +0 -0
- package/ui-dist/assets/{rotate-cw-QQjmoWuq.js → rotate-cw-Cz7I_m7O.js} +1 -1
- package/ui-dist/assets/rough.esm-DxgC_14r.js.gz +0 -0
- package/ui-dist/assets/runtime-config-page-Cl1RpmSC.js +1 -0
- package/ui-dist/assets/runtime-config-page-Cl1RpmSC.js.gz +0 -0
- package/ui-dist/assets/sankeyDiagram-HTMAVEWB-qzDeLztW.js.gz +0 -0
- package/ui-dist/assets/{save-W2xthJJ2.js → save-BiHnb8ps.js} +1 -1
- package/ui-dist/assets/{search-Vih1R2BD.js → search-C47TyRg0.js} +1 -1
- package/ui-dist/assets/{search-config-page-CtBcL2uc.js → search-config-page-BAIzd6gN.js} +1 -1
- package/ui-dist/assets/search-config-page-BAIzd6gN.js.gz +0 -0
- package/ui-dist/assets/{secrets-config-page-Q6XfIj0h.js → secrets-config-page-Ddi-n43R.js} +2 -2
- package/ui-dist/assets/secrets-config-page-Ddi-n43R.js.gz +0 -0
- package/ui-dist/assets/security-config-C8MHnE1r.js +1 -0
- package/ui-dist/assets/{select-lNdozU4o.js → select-BzQKfW1e.js} +2 -2
- package/ui-dist/assets/select-BzQKfW1e.js.gz +0 -0
- package/ui-dist/assets/sequenceDiagram-DBY2YBRQ-BtRbPQtL.js.gz +0 -0
- package/ui-dist/assets/skeleton-BXFAE9SE.js +1 -0
- package/ui-dist/assets/src-Bw-mzbQb.js.gz +0 -0
- package/ui-dist/assets/stateDiagram-2N3HPSRC-BJ-mFeOz.js.gz +0 -0
- package/ui-dist/assets/swimlanes-5IMT3BWC-BsucVOO2.js.gz +0 -0
- package/ui-dist/assets/{tag-chip-gdaU9bE7.js → tag-chip-C3K814HZ.js} +1 -1
- package/ui-dist/assets/timeline-definition-FHXFAJF6-Bicewlzo.js.gz +0 -0
- package/ui-dist/assets/vennDiagram-L72KCM5P-BxOOnO9x.js.gz +0 -0
- package/ui-dist/assets/wardleyDiagram-EHGQE667-Cl7NltMv.js.gz +0 -0
- package/ui-dist/assets/x-C1r9IXet.js +1 -0
- package/ui-dist/assets/xlsx-DrDuDNAa.js.gz +0 -0
- package/ui-dist/assets/xychartDiagram-FW5EYKEG-DiMIxQ7N.js.gz +0 -0
- package/ui-dist/index.html +29 -21
- package/ui-dist/index.html.gz +0 -0
- package/ui-dist/logos/discord.svg.gz +0 -0
- package/ui-dist/logos/feishu.svg.gz +0 -0
- package/ui-dist/logos/gemini.svg.gz +0 -0
- package/ui-dist/logos/mimo.svg.gz +0 -0
- package/ui-dist/logos/openai.svg.gz +0 -0
- package/ui-dist/logos/slack.svg.gz +0 -0
- package/ui-dist/logos/vllm.svg.gz +0 -0
- package/ui-dist/logos/weixin.svg.gz +0 -0
- package/ui-dist/logos/whatsapp.svg.gz +0 -0
- package/ui-dist/logos/zhipu.svg.gz +0 -0
- package/ui-dist/offline.html.gz +0 -0
- package/ui-dist/runtime-icons/codex-openai.svg.gz +0 -0
- package/ui-dist/sw.js.gz +0 -0
- package/ui-dist/themes/island/island-atmosphere.webp +0 -0
- package/dist/nextclaw-cli-app-scOxgGRP.js.map +0 -1
- package/dist/nextclaw-distribution.utils-BneKclXo.js.map +0 -1
- package/ui-dist/assets/api-iMkU_o5P.js.gz +0 -0
- package/ui-dist/assets/appearance-settings-page-CU5k4b-M.js.gz +0 -0
- package/ui-dist/assets/channels-list-page-Drlt62kY.js.gz +0 -0
- package/ui-dist/assets/config-split-page-BtJZp1E5.js.gz +0 -0
- package/ui-dist/assets/confirm-dialog-k2-Jq_x3.js.gz +0 -0
- package/ui-dist/assets/desktop-update-config-BiZmy7FC.js +0 -1
- package/ui-dist/assets/desktop-update-config-BiZmy7FC.js.gz +0 -0
- package/ui-dist/assets/dist-Cy_e4kNb.js.gz +0 -0
- package/ui-dist/assets/dist-m08DUswB.js.gz +0 -0
- package/ui-dist/assets/doc-browser-CPsPHh12.js +0 -1
- package/ui-dist/assets/doc-browser-context-jiy-O4F8.js.gz +0 -0
- package/ui-dist/assets/doc-browser-npOvWtgf.js +0 -1
- package/ui-dist/assets/doc-browser-npOvWtgf.js.gz +0 -0
- package/ui-dist/assets/extensions-CIb17__o.js.gz +0 -0
- package/ui-dist/assets/index-C86hxgv5.css +0 -1
- package/ui-dist/assets/index-C86hxgv5.css.gz +0 -0
- package/ui-dist/assets/index-CYBXR7zN.js +0 -109
- package/ui-dist/assets/index-CYBXR7zN.js.gz +0 -0
- package/ui-dist/assets/loader-circle-BlLuRFVW.js +0 -1
- package/ui-dist/assets/mcp-marketplace-page-B12JNh7Q.js +0 -1
- package/ui-dist/assets/mcp-marketplace-page-kLWW6kzt.js +0 -9
- package/ui-dist/assets/mcp-marketplace-page-kLWW6kzt.js.gz +0 -0
- package/ui-dist/assets/model-config-page-DSeAjVT_.js +0 -1
- package/ui-dist/assets/model-config-page-DSeAjVT_.js.gz +0 -0
- package/ui-dist/assets/navigation-link-DAfwFCj4.js.gz +0 -0
- package/ui-dist/assets/plus-D4LtWtTk.js +0 -1
- package/ui-dist/assets/privacy-settings-page-tN0Mt15x.js +0 -1
- package/ui-dist/assets/privacy-settings-page-tN0Mt15x.js.gz +0 -0
- package/ui-dist/assets/providers-config-page-CgPrXR1u.js +0 -1
- package/ui-dist/assets/providers-config-page-CgPrXR1u.js.gz +0 -0
- package/ui-dist/assets/react-8iBFECZE.js +0 -8
- package/ui-dist/assets/react-8iBFECZE.js.gz +0 -0
- package/ui-dist/assets/remote-Derr_AQp.js +0 -1
- package/ui-dist/assets/runtime-config-page-Crq96Jjq.js +0 -1
- package/ui-dist/assets/runtime-config-page-Crq96Jjq.js.gz +0 -0
- package/ui-dist/assets/search-config-page-CtBcL2uc.js.gz +0 -0
- package/ui-dist/assets/secrets-config-page-Q6XfIj0h.js.gz +0 -0
- package/ui-dist/assets/security-config-CE9rkQvq.js +0 -1
- package/ui-dist/assets/select-lNdozU4o.js.gz +0 -0
- package/ui-dist/assets/skeleton-B__aTcly.js +0 -1
- package/ui-dist/assets/x-CWdWBu_U.js +0 -1
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
const actionIds = {
|
|
2
|
+
status: "nextclaw-portable-runtime-lab-resident.resident_status",
|
|
3
|
+
reset: "nextclaw-portable-runtime-lab-resident.resident_reset",
|
|
4
|
+
milestone: "nextclaw-portable-runtime-lab-resident.resident_emit_event",
|
|
5
|
+
recordsList: "nextclaw-portable-runtime-lab-state.records_list",
|
|
6
|
+
recordUpsert: "nextclaw-portable-runtime-lab-state.record_upsert",
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const elements = {
|
|
10
|
+
clock: document.querySelector("[data-clock]"),
|
|
11
|
+
caption: document.querySelector("[data-clock-caption]"),
|
|
12
|
+
milestones: document.querySelector("[data-milestones]"),
|
|
13
|
+
notice: document.querySelector("[data-notice]"),
|
|
14
|
+
epoch: document.querySelector("[data-proof-epoch]"),
|
|
15
|
+
events: document.querySelector("[data-proof-events]"),
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
function serviceActions() {
|
|
19
|
+
const bridge = window.nextclaw?.serviceActions;
|
|
20
|
+
if (!bridge) throw new Error("应用还没有连接到 NextClaw,请刷新后重试。");
|
|
21
|
+
return bridge;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async function invoke(actionId, input = {}) {
|
|
25
|
+
return await serviceActions().invoke(actionId, input);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function formatDuration(totalSeconds) {
|
|
29
|
+
const safe = Math.max(0, Number(totalSeconds) || 0);
|
|
30
|
+
const hours = Math.floor(safe / 3600);
|
|
31
|
+
const minutes = Math.floor((safe % 3600) / 60);
|
|
32
|
+
const seconds = safe % 60;
|
|
33
|
+
return hours > 0
|
|
34
|
+
? `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`
|
|
35
|
+
: `${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function milestoneTime(record) {
|
|
39
|
+
const timestamp = Number(String(record.id).replace("focus-", ""));
|
|
40
|
+
return Number.isFinite(timestamp) ? new Date(timestamp) : null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function renderMilestones(records) {
|
|
44
|
+
const items = (Array.isArray(records) ? records : [])
|
|
45
|
+
.filter((record) => Array.isArray(record.tags) && record.tags.includes("focus-milestone"))
|
|
46
|
+
.sort((left, right) => (milestoneTime(right)?.getTime() ?? 0) - (milestoneTime(left)?.getTime() ?? 0));
|
|
47
|
+
elements.milestones.replaceChildren();
|
|
48
|
+
if (items.length === 0) {
|
|
49
|
+
const empty = document.createElement("li");
|
|
50
|
+
empty.className = "empty";
|
|
51
|
+
empty.textContent = "还没有完成点";
|
|
52
|
+
elements.milestones.append(empty);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
for (const item of items) {
|
|
56
|
+
const row = document.createElement("li");
|
|
57
|
+
const dot = document.createElement("i");
|
|
58
|
+
const copy = document.createElement("div");
|
|
59
|
+
const title = document.createElement("strong");
|
|
60
|
+
title.textContent = item.title || "完成了一个阶段";
|
|
61
|
+
const time = document.createElement("span");
|
|
62
|
+
const occurredAt = milestoneTime(item);
|
|
63
|
+
time.textContent = occurredAt
|
|
64
|
+
? occurredAt.toLocaleTimeString("zh-CN", { hour: "2-digit", minute: "2-digit", second: "2-digit" })
|
|
65
|
+
: `数据版本 ${item.version}`;
|
|
66
|
+
copy.append(title, time);
|
|
67
|
+
row.append(dot, copy);
|
|
68
|
+
elements.milestones.append(row);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async function refresh() {
|
|
73
|
+
const [state, records] = await Promise.all([
|
|
74
|
+
invoke(actionIds.status),
|
|
75
|
+
invoke(actionIds.recordsList),
|
|
76
|
+
]);
|
|
77
|
+
elements.clock.textContent = formatDuration(state.eventCount);
|
|
78
|
+
elements.caption.textContent = state.eventCount > 0 ? "本轮专注仍在后台继续" : "准备好后,开始一轮新的专注";
|
|
79
|
+
elements.epoch.textContent = `第 ${state.instanceEpoch} 次运行实例`;
|
|
80
|
+
elements.events.textContent = `${state.eventCount} 个持久事件`;
|
|
81
|
+
renderMilestones(records.records);
|
|
82
|
+
if (elements.notice.dataset.tone === "error") {
|
|
83
|
+
elements.notice.textContent = "";
|
|
84
|
+
elements.notice.dataset.tone = "";
|
|
85
|
+
}
|
|
86
|
+
return state;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async function run(operation, successMessage) {
|
|
90
|
+
elements.notice.textContent = "正在更新…";
|
|
91
|
+
elements.notice.dataset.tone = "";
|
|
92
|
+
try {
|
|
93
|
+
await operation();
|
|
94
|
+
await refresh();
|
|
95
|
+
elements.notice.textContent = successMessage;
|
|
96
|
+
elements.notice.dataset.tone = "success";
|
|
97
|
+
} catch (error) {
|
|
98
|
+
elements.notice.textContent = error instanceof Error ? error.message : String(error);
|
|
99
|
+
elements.notice.dataset.tone = "error";
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
document.querySelector("[data-start]").addEventListener("click", () => {
|
|
104
|
+
void run(() => invoke(actionIds.reset), "新一轮专注已经开始,关闭页面也会继续");
|
|
105
|
+
});
|
|
106
|
+
document.querySelector("[data-milestone]").addEventListener("click", () => {
|
|
107
|
+
const now = new Date();
|
|
108
|
+
const eventId = `focus-${now.getTime()}`;
|
|
109
|
+
void run(async () => {
|
|
110
|
+
await invoke(actionIds.milestone, {
|
|
111
|
+
eventId,
|
|
112
|
+
kind: "focus-milestone",
|
|
113
|
+
triggeredAt: now.toISOString(),
|
|
114
|
+
});
|
|
115
|
+
await invoke(actionIds.recordUpsert, {
|
|
116
|
+
id: eventId,
|
|
117
|
+
title: "完成了一个阶段",
|
|
118
|
+
status: "completed",
|
|
119
|
+
tags: ["focus-milestone", "focus"],
|
|
120
|
+
});
|
|
121
|
+
}, "已经记下这个完成点,并保存到专注历史");
|
|
122
|
+
});
|
|
123
|
+
document.querySelector("[data-refresh]").addEventListener("click", () => void refresh());
|
|
124
|
+
|
|
125
|
+
void refresh().catch((error) => {
|
|
126
|
+
elements.notice.textContent = error instanceof Error ? error.message : String(error);
|
|
127
|
+
elements.notice.dataset.tone = "error";
|
|
128
|
+
});
|
|
129
|
+
const poll = window.setInterval(() => {
|
|
130
|
+
if (document.visibilityState === "visible") void refresh();
|
|
131
|
+
}, 1000);
|
|
132
|
+
window.addEventListener("pagehide", () => window.clearInterval(poll), { once: true });
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
:root { color-scheme: dark; font-family: Inter, "PingFang SC", "Microsoft YaHei", sans-serif; color: #f3f0ff; background: #141124; }
|
|
2
|
+
* { box-sizing: border-box; }
|
|
3
|
+
body { margin: 0; min-width: 320px; background: radial-gradient(circle at 50% 0, #302552 0, #171329 43%, #100e1c 100%); }
|
|
4
|
+
button { font: inherit; cursor: pointer; }
|
|
5
|
+
.app-shell { width: min(800px, calc(100% - 32px)); margin: 0 auto; padding: 38px 0 52px; }
|
|
6
|
+
.hero { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; }
|
|
7
|
+
.eyebrow { margin: 0 0 8px; color: #a993f4; font-size: 12px; font-weight: 800; letter-spacing: .18em; }
|
|
8
|
+
h1 { margin: 0; font-family: Georgia, "Noto Serif SC", serif; font-size: clamp(36px, 7vw, 58px); letter-spacing: -.04em; }
|
|
9
|
+
.hero p:last-child { margin: 8px 0 0; color: #aaa3c1; }
|
|
10
|
+
.live { display: inline-flex; flex: 0 0 auto; align-items: center; gap: 7px; margin-top: 8px; padding: 8px 11px; border: 1px solid rgba(171,155,233,.24); border-radius: 999px; color: #c8bdf2; background: rgba(51,41,83,.7); font-size: 12px; }
|
|
11
|
+
.live i { width: 7px; height: 7px; border-radius: 50%; background: #8ae0ae; box-shadow: 0 0 10px #8ae0ae; }
|
|
12
|
+
.clock-card { margin-top: 30px; padding: clamp(34px, 8vw, 68px) 24px; border: 1px solid rgba(187,169,255,.2); border-radius: 30px; background: linear-gradient(145deg, rgba(62,48,99,.78), rgba(30,25,50,.88)); text-align: center; box-shadow: 0 28px 90px rgba(2,0,12,.35), inset 0 1px rgba(255,255,255,.08); }
|
|
13
|
+
.clock { font-variant-numeric: tabular-nums; font-size: clamp(64px, 15vw, 116px); font-weight: 200; letter-spacing: -.06em; line-height: 1; text-shadow: 0 0 40px rgba(176,153,255,.18); }
|
|
14
|
+
.clock-card > p { margin: 14px 0 0; color: #aca4c5; }
|
|
15
|
+
.actions { display: flex; justify-content: center; gap: 10px; margin-top: 28px; }
|
|
16
|
+
.actions button { border: 0; border-radius: 13px; padding: 12px 20px; color: #201a34; background: #bba9ff; font-weight: 750; }
|
|
17
|
+
.actions .secondary { border: 1px solid rgba(194,177,255,.26); color: #d5cbf6; background: rgba(255,255,255,.05); }
|
|
18
|
+
.timeline { margin-top: 28px; padding: 22px; border: 1px solid rgba(188,174,237,.14); border-radius: 20px; background: rgba(24,20,40,.58); }
|
|
19
|
+
.section-title { display: flex; justify-content: space-between; gap: 16px; }
|
|
20
|
+
.section-title h2 { margin: 0; font-size: 18px; }
|
|
21
|
+
.section-title p { margin: 6px 0 0; color: #928ba8; font-size: 13px; }
|
|
22
|
+
.text-button { border: 0; color: #bba9ff; background: transparent; }
|
|
23
|
+
.timeline ol { display: grid; gap: 10px; margin: 20px 0 0; padding: 0; list-style: none; }
|
|
24
|
+
.timeline li:not(.empty) { display: flex; align-items: center; gap: 13px; padding: 11px 13px; border-radius: 12px; background: rgba(255,255,255,.045); }
|
|
25
|
+
.timeline li i { width: 10px; height: 10px; border: 2px solid #9e87ef; border-radius: 50%; }
|
|
26
|
+
.timeline li div { display: flex; flex: 1; align-items: center; justify-content: space-between; gap: 10px; }
|
|
27
|
+
.timeline li span { color: #938ca8; font-size: 12px; }
|
|
28
|
+
.empty { padding: 24px; color: #7f788f; text-align: center; }
|
|
29
|
+
.notice { min-height: 22px; margin: 14px 2px; color: #a19ab5; font-size: 14px; }
|
|
30
|
+
.notice[data-tone="success"] { color: #8ae0ae; }
|
|
31
|
+
.notice[data-tone="error"] { color: #ff978e; }
|
|
32
|
+
.behind-scenes { margin-top: 25px; padding: 16px 18px; border: 1px solid rgba(187,172,238,.16); border-radius: 16px; color: #9d96af; background: rgba(255,255,255,.025); font-size: 13px; }
|
|
33
|
+
.behind-scenes summary { color: #c9c0e6; cursor: pointer; font-weight: 700; }
|
|
34
|
+
.behind-scenes p { line-height: 1.65; }
|
|
35
|
+
.behind-scenes dl { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin: 12px 0 0; }
|
|
36
|
+
.behind-scenes dl div { padding: 10px; border-radius: 10px; background: rgba(255,255,255,.04); }
|
|
37
|
+
.behind-scenes dt { color: #817a93; font-size: 11px; }
|
|
38
|
+
.behind-scenes dd { margin: 3px 0 0; color: #d2cae7; }
|
|
39
|
+
@media (max-width: 560px) { .app-shell { width: calc(100% - 22px); padding-top: 24px; } .hero { flex-direction: column; } .actions { flex-direction: column; } .section-title { align-items: flex-start; } .behind-scenes dl { grid-template-columns: 1fr; } }
|
|
@@ -0,0 +1,40 @@
|
|
|
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.0" />
|
|
6
|
+
<title>专注小钟</title>
|
|
7
|
+
<link rel="stylesheet" href="assets/style.css" />
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<main class="app-shell">
|
|
11
|
+
<header class="hero">
|
|
12
|
+
<div><p class="eyebrow">FOCUS</p><h1>专注小钟</h1><p>开始后就去做事吧,关掉这个页面,时间也不会停。</p></div>
|
|
13
|
+
<span class="live"><i></i> 后台计时中</span>
|
|
14
|
+
</header>
|
|
15
|
+
|
|
16
|
+
<section class="clock-card">
|
|
17
|
+
<div class="clock" data-clock>00:00</div>
|
|
18
|
+
<p data-clock-caption>正在读取本轮专注时间…</p>
|
|
19
|
+
<div class="actions">
|
|
20
|
+
<button type="button" data-start>开始新一轮</button>
|
|
21
|
+
<button type="button" class="secondary" data-milestone>记下完成点</button>
|
|
22
|
+
</div>
|
|
23
|
+
</section>
|
|
24
|
+
|
|
25
|
+
<section class="timeline">
|
|
26
|
+
<div class="section-title"><div><h2>最近的专注记录</h2><p>完成一个阶段时点一下,记录会被保存下来。</p></div><button type="button" class="text-button" data-refresh>刷新</button></div>
|
|
27
|
+
<ol data-milestones><li class="empty">还没有完成点</li></ol>
|
|
28
|
+
</section>
|
|
29
|
+
|
|
30
|
+
<p class="notice" data-notice></p>
|
|
31
|
+
|
|
32
|
+
<details class="behind-scenes">
|
|
33
|
+
<summary>关闭页面后,为什么计时还会继续?</summary>
|
|
34
|
+
<p>计时不属于这个页面,而是由 NextClaw 宿主持续向一个常驻 Rust/WASM Component 投递事件;完成点同时写入持久数据 Component。Panel 只负责查看和控制,所以页面关闭、重新打开,甚至宿主恢复后都能继续。</p>
|
|
35
|
+
<dl><div><dt>本次实例</dt><dd data-proof-epoch>等待读取</dd></div><div><dt>持久事件</dt><dd data-proof-events>等待读取</dd></div></dl>
|
|
36
|
+
</details>
|
|
37
|
+
</main>
|
|
38
|
+
<script src="assets/app.js"></script>
|
|
39
|
+
</body>
|
|
40
|
+
</html>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "nextclaw-portable-runtime-lab-focus",
|
|
3
|
+
"title": "专注小钟",
|
|
4
|
+
"description": "关掉页面也会继续走的轻量专注计时器。",
|
|
5
|
+
"entry": "index.html",
|
|
6
|
+
"actions": [
|
|
7
|
+
"nextclaw-portable-runtime-lab-resident.resident_status",
|
|
8
|
+
"nextclaw-portable-runtime-lab-resident.resident_reset",
|
|
9
|
+
"nextclaw-portable-runtime-lab-resident.resident_emit_event",
|
|
10
|
+
"nextclaw-portable-runtime-lab-resident.runtime_info",
|
|
11
|
+
"nextclaw-portable-runtime-lab-state.records_list",
|
|
12
|
+
"nextclaw-portable-runtime-lab-state.record_upsert"
|
|
13
|
+
]
|
|
14
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
const actionIds = {
|
|
2
|
+
list: "nextclaw-portable-runtime-lab-state.records_list",
|
|
3
|
+
upsert: "nextclaw-portable-runtime-lab-state.record_upsert",
|
|
4
|
+
remove: "nextclaw-portable-runtime-lab-state.record_delete",
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
const elements = {
|
|
8
|
+
form: document.querySelector("[data-note-form]"),
|
|
9
|
+
input: document.querySelector("[data-note-input]"),
|
|
10
|
+
search: document.querySelector("[data-search]"),
|
|
11
|
+
count: document.querySelector("[data-note-count]"),
|
|
12
|
+
characters: document.querySelector("[data-character-count]"),
|
|
13
|
+
grid: document.querySelector("[data-notes-grid]"),
|
|
14
|
+
notice: document.querySelector("[data-notice]"),
|
|
15
|
+
revision: document.querySelector("[data-proof-revision]"),
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
let notes = [];
|
|
19
|
+
|
|
20
|
+
function serviceActions() {
|
|
21
|
+
const bridge = window.nextclaw?.serviceActions;
|
|
22
|
+
if (!bridge) throw new Error("应用还没有连接到 NextClaw,请刷新后重试。");
|
|
23
|
+
return bridge;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async function invoke(actionId, input = {}) {
|
|
27
|
+
return await serviceActions().invoke(actionId, input);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function setNotice(message, tone = "") {
|
|
31
|
+
elements.notice.textContent = message;
|
|
32
|
+
elements.notice.dataset.tone = tone;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function noteCard(note, index) {
|
|
36
|
+
const card = document.createElement("article");
|
|
37
|
+
card.className = `note-card color-${index % 4}`;
|
|
38
|
+
const content = document.createElement("p");
|
|
39
|
+
content.textContent = note.title;
|
|
40
|
+
const footer = document.createElement("footer");
|
|
41
|
+
const version = document.createElement("span");
|
|
42
|
+
version.textContent = `保存于版本 ${note.version}`;
|
|
43
|
+
const remove = document.createElement("button");
|
|
44
|
+
remove.type = "button";
|
|
45
|
+
remove.dataset.noteRemove = note.id;
|
|
46
|
+
remove.textContent = "删除";
|
|
47
|
+
footer.append(version, remove);
|
|
48
|
+
card.append(content, footer);
|
|
49
|
+
return card;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function render() {
|
|
53
|
+
const query = elements.search.value.trim().toLocaleLowerCase("zh-CN");
|
|
54
|
+
const filtered = [...notes]
|
|
55
|
+
.sort((left, right) => right.version - left.version)
|
|
56
|
+
.filter((note) => !query || note.title.toLocaleLowerCase("zh-CN").includes(query));
|
|
57
|
+
elements.grid.replaceChildren();
|
|
58
|
+
if (filtered.length === 0) {
|
|
59
|
+
const empty = document.createElement("div");
|
|
60
|
+
empty.className = "empty";
|
|
61
|
+
empty.innerHTML = query
|
|
62
|
+
? "<strong>没有找到相关便签</strong><span>换个关键词试试。</span>"
|
|
63
|
+
: "<strong>便签盒还是空的</strong><span>写下刚刚想到的第一句话吧。</span>";
|
|
64
|
+
elements.grid.append(empty);
|
|
65
|
+
} else {
|
|
66
|
+
filtered.forEach((note, index) => elements.grid.append(noteCard(note, index)));
|
|
67
|
+
}
|
|
68
|
+
elements.count.textContent = `${notes.length} 张便签`;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async function refresh() {
|
|
72
|
+
const data = await invoke(actionIds.list);
|
|
73
|
+
notes = (Array.isArray(data.records) ? data.records : [])
|
|
74
|
+
.filter((record) => Array.isArray(record.tags) && record.tags.includes("note"));
|
|
75
|
+
elements.revision.textContent = `revision ${data.revision} · ${data.contentHash}`;
|
|
76
|
+
render();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async function run(operation, successMessage) {
|
|
80
|
+
setNotice("正在保存…");
|
|
81
|
+
try {
|
|
82
|
+
await operation();
|
|
83
|
+
await refresh();
|
|
84
|
+
setNotice(successMessage, "success");
|
|
85
|
+
} catch (error) {
|
|
86
|
+
setNotice(error instanceof Error ? error.message : String(error), "error");
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
elements.input.addEventListener("input", () => {
|
|
91
|
+
elements.characters.textContent = `${elements.input.value.length} / 800`;
|
|
92
|
+
});
|
|
93
|
+
elements.search.addEventListener("input", render);
|
|
94
|
+
|
|
95
|
+
elements.form.addEventListener("submit", (event) => {
|
|
96
|
+
event.preventDefault();
|
|
97
|
+
const content = elements.input.value.trim();
|
|
98
|
+
if (!content) return;
|
|
99
|
+
void run(async () => {
|
|
100
|
+
await invoke(actionIds.upsert, {
|
|
101
|
+
id: `note-${Date.now().toString(36)}`,
|
|
102
|
+
title: content,
|
|
103
|
+
status: "note",
|
|
104
|
+
tags: ["note", "quick-capture"],
|
|
105
|
+
});
|
|
106
|
+
elements.input.value = "";
|
|
107
|
+
elements.characters.textContent = "0 / 800";
|
|
108
|
+
}, "便签已保存");
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
elements.grid.addEventListener("click", (event) => {
|
|
112
|
+
const target = event.target instanceof Element ? event.target : null;
|
|
113
|
+
const id = target?.closest("[data-note-remove]")?.dataset.noteRemove;
|
|
114
|
+
if (id) void run(() => invoke(actionIds.remove, { id }), "便签已删除");
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
void refresh().catch((error) => setNotice(error instanceof Error ? error.message : String(error), "error"));
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
:root { color-scheme: light; font-family: Inter, "PingFang SC", "Microsoft YaHei", sans-serif; color: #3d342b; background: #f7f0df; }
|
|
2
|
+
* { box-sizing: border-box; }
|
|
3
|
+
body { margin: 0; min-width: 320px; background: linear-gradient(135deg, #fffdf5, #f5ecd8 58%, #eee3cf); }
|
|
4
|
+
button, input, textarea { font: inherit; }
|
|
5
|
+
button { cursor: pointer; }
|
|
6
|
+
.app-shell { width: min(900px, calc(100% - 32px)); margin: 0 auto; padding: 38px 0 52px; }
|
|
7
|
+
.hero { margin-bottom: 24px; }
|
|
8
|
+
.eyebrow { margin: 0 0 8px; color: #b36e32; font-size: 12px; font-weight: 800; letter-spacing: .18em; }
|
|
9
|
+
h1 { margin: 0; font-family: Georgia, "Noto Serif SC", serif; font-size: clamp(36px, 7vw, 58px); letter-spacing: -.04em; }
|
|
10
|
+
.hero > p:last-child { margin: 8px 0 0; color: #776b5f; }
|
|
11
|
+
.note-composer { padding: 16px; border: 1px solid #eadcc2; border-radius: 20px; background: rgba(255,255,255,.82); box-shadow: 0 18px 55px rgba(91,68,33,.1); }
|
|
12
|
+
.note-composer textarea { width: 100%; resize: vertical; border: 0; outline: 0; padding: 4px; color: #463b30; background: transparent; font-size: 17px; line-height: 1.65; }
|
|
13
|
+
.note-composer > div { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 10px; }
|
|
14
|
+
.note-composer span { color: #a19483; font-size: 12px; }
|
|
15
|
+
.note-composer button { border: 0; border-radius: 12px; padding: 11px 20px; color: #fff; background: #8e5c32; font-weight: 700; }
|
|
16
|
+
.toolbar { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin: 24px 2px 14px; color: #827668; font-size: 13px; }
|
|
17
|
+
.toolbar label { display: grid; gap: 6px; flex: 1; max-width: 340px; }
|
|
18
|
+
.toolbar input { width: 100%; border: 1px solid #dfd1b9; border-radius: 12px; outline: 0; padding: 10px 12px; color: #473d32; background: rgba(255,255,255,.65); }
|
|
19
|
+
.notes-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 14px; }
|
|
20
|
+
.note-card { display: flex; min-height: 190px; flex-direction: column; justify-content: space-between; padding: 20px; border: 1px solid rgba(105,82,49,.1); border-radius: 5px 18px 18px 18px; box-shadow: 0 10px 22px rgba(70,52,26,.08); transform: rotate(-.25deg); }
|
|
21
|
+
.note-card:nth-child(2n) { transform: rotate(.25deg); }
|
|
22
|
+
.note-card.color-0 { background: #fff0a9; }
|
|
23
|
+
.note-card.color-1 { background: #dff0d7; }
|
|
24
|
+
.note-card.color-2 { background: #f9d8cc; }
|
|
25
|
+
.note-card.color-3 { background: #dce8f6; }
|
|
26
|
+
.note-card p { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; line-height: 1.65; }
|
|
27
|
+
.note-card footer { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 18px; color: rgba(64,51,37,.55); font-size: 11px; }
|
|
28
|
+
.note-card button { border: 0; color: #855243; background: transparent; }
|
|
29
|
+
.empty { display: flex; min-height: 220px; grid-column: 1 / -1; flex-direction: column; align-items: center; justify-content: center; gap: 8px; border: 1px dashed #d8c9af; border-radius: 18px; color: #918574; text-align: center; }
|
|
30
|
+
.empty strong { color: #625749; font-size: 18px; }
|
|
31
|
+
.notice { min-height: 22px; margin: 14px 2px; color: #817567; font-size: 14px; }
|
|
32
|
+
.notice[data-tone="success"] { color: #557546; }
|
|
33
|
+
.notice[data-tone="error"] { color: #ad4c43; }
|
|
34
|
+
.behind-scenes { margin-top: 28px; padding: 16px 18px; border: 1px solid #e4d8c4; border-radius: 16px; color: #756a5d; background: rgba(255,255,255,.5); font-size: 13px; }
|
|
35
|
+
.behind-scenes summary { color: #574c3f; cursor: pointer; font-weight: 700; }
|
|
36
|
+
.behind-scenes p { line-height: 1.65; }
|
|
37
|
+
.behind-scenes dl { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin: 12px 0 0; }
|
|
38
|
+
.behind-scenes dl div { padding: 10px; border-radius: 10px; background: #fffaf0; }
|
|
39
|
+
.behind-scenes dt { color: #9d9182; font-size: 11px; }
|
|
40
|
+
.behind-scenes dd { margin: 3px 0 0; color: #50463b; overflow-wrap: anywhere; }
|
|
41
|
+
@media (max-width: 560px) { .app-shell { width: calc(100% - 22px); padding-top: 24px; } .toolbar { align-items: stretch; flex-direction: column; } .toolbar label { max-width: none; } .behind-scenes dl { grid-template-columns: 1fr; } }
|
|
@@ -0,0 +1,41 @@
|
|
|
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.0" />
|
|
6
|
+
<title>灵感便签</title>
|
|
7
|
+
<link rel="stylesheet" href="assets/style.css" />
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<main class="app-shell">
|
|
11
|
+
<header class="hero">
|
|
12
|
+
<p class="eyebrow">QUICK NOTES</p>
|
|
13
|
+
<h1>灵感便签</h1>
|
|
14
|
+
<p>先记下来,不让刚刚想到的东西溜走。</p>
|
|
15
|
+
</header>
|
|
16
|
+
|
|
17
|
+
<form class="note-composer" data-note-form>
|
|
18
|
+
<textarea data-note-input rows="4" maxlength="800" placeholder="写下一句话、一个想法,或者稍后要查的东西…"></textarea>
|
|
19
|
+
<div><span data-character-count>0 / 800</span><button type="submit">保存便签</button></div>
|
|
20
|
+
</form>
|
|
21
|
+
|
|
22
|
+
<div class="toolbar">
|
|
23
|
+
<label><span>搜索便签</span><input data-search type="search" placeholder="输入关键词" /></label>
|
|
24
|
+
<span data-note-count>0 张便签</span>
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
<section class="notes-grid" data-notes-grid aria-live="polite">
|
|
28
|
+
<div class="empty">正在打开你的便签盒…</div>
|
|
29
|
+
</section>
|
|
30
|
+
|
|
31
|
+
<p class="notice" data-notice></p>
|
|
32
|
+
|
|
33
|
+
<details class="behind-scenes">
|
|
34
|
+
<summary>为什么它也是运行时 Demo?</summary>
|
|
35
|
+
<p>便签和“今日清单”是两个独立 Panel,却复用同一个底层数据 Component。产品可以变,稳定的存储与授权能力不用为每个页面重新实现。</p>
|
|
36
|
+
<dl><div><dt>当前数据版本</dt><dd data-proof-revision>等待读取</dd></div><div><dt>可被 Agent 使用</dt><dd>是,同一 Service Action</dd></div></dl>
|
|
37
|
+
</details>
|
|
38
|
+
</main>
|
|
39
|
+
<script src="assets/app.js"></script>
|
|
40
|
+
</body>
|
|
41
|
+
</html>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "nextclaw-portable-runtime-lab-notes",
|
|
3
|
+
"title": "灵感便签",
|
|
4
|
+
"description": "随手记下一句话,之后还能搜索回来。",
|
|
5
|
+
"entry": "index.html",
|
|
6
|
+
"actions": [
|
|
7
|
+
"nextclaw-portable-runtime-lab-state.records_list",
|
|
8
|
+
"nextclaw-portable-runtime-lab-state.record_upsert",
|
|
9
|
+
"nextclaw-portable-runtime-lab-state.record_delete",
|
|
10
|
+
"nextclaw-portable-runtime-lab-state.data_snapshot"
|
|
11
|
+
]
|
|
12
|
+
}
|