@shawnstack/quickforge 1.7.3 → 1.7.5
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/README.md +1 -1
- package/bin/quickforge.mjs +0 -21
- package/dist/assets/AgentProfilesPage-XNjuqJs7.js +1 -0
- package/dist/assets/ChatPanelHost-CuF-PZpc.js +292 -0
- package/dist/assets/CloudAccountSettingsPage-GJSoi6sO.js +1 -0
- package/dist/assets/PluginsPage-BQgp0qN-.js +1 -0
- package/dist/assets/ScheduledTasksPage-DdekATzq.js +2 -0
- package/dist/assets/SettingsWorkspacePage-Cb54Ic91.js +1639 -0
- package/dist/assets/ShareLinksSettingsPage-C75WJpaF.js +1 -0
- package/dist/assets/SharedConversationPage-CjMtSQTW.js +1 -0
- package/dist/assets/TerminalDock-D4zJBJc4.js +2 -0
- package/dist/assets/WorkspaceInspector-D9kdnLDd.js +36 -0
- package/dist/assets/{abnfDiagram-VRR7QNED-Dl_Fvlqg.js → abnfDiagram-VRR7QNED-CMhVoYUh.js} +1 -1
- package/dist/assets/{arc-Bhg4c0ht.js → arc-w21O0TLn.js} +1 -1
- package/dist/assets/architecture-TIHT7OUA-DMwFMHxq.js +1 -0
- package/dist/assets/{architectureDiagram-ZJ3FMSHR-BuojN27B.js → architectureDiagram-ZJ3FMSHR-C52qL6Hg.js} +1 -1
- package/dist/assets/{blockDiagram-677ZJIJ3-alDLbrR1.js → blockDiagram-677ZJIJ3-CM3XbLol.js} +1 -1
- package/dist/assets/{c4Diagram-LMCZKHZV-D1lKa4VT.js → c4Diagram-LMCZKHZV-D7Bh1ui1.js} +1 -1
- package/dist/assets/channel-Duu1CuH9.js +1 -0
- package/dist/assets/chunk-2Q5K7J3B-B6rHWc4S.js +1 -0
- package/dist/assets/{chunk-32BRIVSS-CwWLNjMZ.js → chunk-32BRIVSS-xgrtbT8e.js} +1 -1
- package/dist/assets/{chunk-52WLFC77-Be569m7d.js → chunk-52WLFC77-CDbaHw80.js} +1 -1
- package/dist/assets/{chunk-5FCAYU7R-BSvoiWV1.js → chunk-5FCAYU7R-CcSvVbPc.js} +1 -1
- package/dist/assets/{chunk-5HE753X5-CRgsy8WS.js → chunk-5HE753X5-erFpzzgx.js} +1 -1
- package/dist/assets/{chunk-5JV3BV7I-CdW477UR.js → chunk-5JV3BV7I-rEhN9F6G.js} +1 -1
- package/dist/assets/{chunk-5TONJI2A-CdtKzSmp.js → chunk-5TONJI2A-D8L-QTwD.js} +1 -1
- package/dist/assets/{chunk-5VM5RSS4-BKjjssLZ.js → chunk-5VM5RSS4-CjlfMBbM.js} +1 -1
- package/dist/assets/{chunk-7BUUIJ7U-ByAXiXdn.js → chunk-7BUUIJ7U-CCcsI9XE.js} +1 -1
- package/dist/assets/{chunk-BIQX33UG-DeG8SCT1.js → chunk-BIQX33UG-FSqFbmb3.js} +1 -1
- package/dist/assets/{chunk-C7G6YPKG-D_zHT68Q.js → chunk-C7G6YPKG-ZMLUvfLy.js} +1 -1
- package/dist/assets/{chunk-CQNSW5MT-CHpHoUSu.js → chunk-CQNSW5MT-DZuBpk25.js} +1 -1
- package/dist/assets/{chunk-CYSBUYHQ-CRP50Vov.js → chunk-CYSBUYHQ-CB26wsG0.js} +1 -1
- package/dist/assets/{chunk-EMLP6XTP-DX6uQQ2v.js → chunk-EMLP6XTP-BbsM8oRw.js} +1 -1
- package/dist/assets/{chunk-EX3LRPZG-DAJRNkHR.js → chunk-EX3LRPZG-BcQhaqt7.js} +1 -1
- package/dist/assets/{chunk-FWX5IMBZ-XbM5yomC.js → chunk-FWX5IMBZ-DrnrdrSu.js} +2 -2
- package/dist/assets/{chunk-HOUHSVGY-Ci0ljnb1.js → chunk-HOUHSVGY-tdc-Z9eW.js} +1 -1
- package/dist/assets/{chunk-ICXQ74PX-Dy2WJ71z.js → chunk-ICXQ74PX-Cd7igVGt.js} +1 -1
- package/dist/assets/{chunk-JG7HCLWE-2PrkzHkt.js → chunk-JG7HCLWE-iXXGW8nf.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-D32uacSM.js → chunk-JWPE2WC7-BZ87mXEv.js} +1 -1
- package/dist/assets/{chunk-MOJQB5TN-DIAFLtiS.js → chunk-MOJQB5TN-CLTjV5ov.js} +1 -1
- package/dist/assets/{chunk-MOZMSUNE-BbscOaEz.js → chunk-MOZMSUNE-B3SCBrRH.js} +1 -1
- package/dist/assets/{chunk-OGEWGWER-ivBVxzKe.js → chunk-OGEWGWER-TgvkXkFX.js} +1 -1
- package/dist/assets/{chunk-OSBZ3O6U-frD0hkdx.js → chunk-OSBZ3O6U-B9E2E5v1.js} +1 -1
- package/dist/assets/{chunk-PUDLZKDR-B-37Rxae.js → chunk-PUDLZKDR-C5GMVYup.js} +1 -1
- package/dist/assets/{chunk-Q4XR5HBZ-Y90m2RTe.js → chunk-Q4XR5HBZ-fo5-HsqY.js} +1 -1
- package/dist/assets/{chunk-QBLGF6JB-DixBqslB.js → chunk-QBLGF6JB-Dwfg8sKc.js} +1 -1
- package/dist/assets/{chunk-R7FJI6CG-DXS1UXn_.js → chunk-R7FJI6CG-DpBrv4ni.js} +1 -1
- package/dist/assets/{chunk-RYQCIY6F-n4JxhNd0.js → chunk-RYQCIY6F-DzzmTl11.js} +1 -1
- package/dist/assets/{chunk-U6XO7XAA-yHlgxMmn.js → chunk-U6XO7XAA-Dw6aviKa.js} +1 -1
- package/dist/assets/{chunk-V7JOEXUC-Z6kuZfbl.js → chunk-V7JOEXUC-CEDazV6w.js} +1 -1
- package/dist/assets/chunk-VAUOI2AC-CWYjg8zE.js +1 -0
- package/dist/assets/{chunk-VR4S4FIN-Cs_SIQma.js → chunk-VR4S4FIN-C_-eEj-9.js} +1 -1
- package/dist/assets/{chunk-WYO6CB5R-CGExYbV-.js → chunk-WYO6CB5R-NF-MsJJR.js} +3 -3
- package/dist/assets/chunk-XXDRQBXY-DzTwx8ZH.js +1 -0
- package/dist/assets/{chunk-YOTPTUD7-DopPXWSl.js → chunk-YOTPTUD7-DqzqtdII.js} +1 -1
- package/dist/assets/{chunk-ZGVPDNZ5-CJHOeqMb.js → chunk-ZGVPDNZ5-CRrAYi4g.js} +1 -1
- package/dist/assets/{chunk-ZIRB5QZD-BBVc5mf6.js → chunk-ZIRB5QZD-Dc1s5bLM.js} +1 -1
- package/dist/assets/classDiagram-OUVF2IWQ-Cc63fLWP.js +1 -0
- package/dist/assets/classDiagram-v2-EOCWNBFH-CoXU0qT6.js +1 -0
- package/dist/assets/{cose-bilkent-JH36ORCC-DLjV-dTm.js → cose-bilkent-JH36ORCC-cL247pHg.js} +1 -1
- package/dist/assets/cynefin-VYW2F7L2-C8yCvH_o.js +1 -0
- package/dist/assets/{cynefinDiagram-TSTJHNR4-BfH3zVS-.js → cynefinDiagram-TSTJHNR4-D4sZ7LYI.js} +1 -1
- package/dist/assets/{dagre-CY3D84Cl.js → dagre-DmHb3Ctt.js} +1 -1
- package/dist/assets/{dagre-VKFMJZFB-BIhwZCIZ.js → dagre-VKFMJZFB-BlsnSh-Q.js} +1 -1
- package/dist/assets/{diagram-FQU43EPY-BHnzNM2w.js → diagram-FQU43EPY-DW1yQiRO.js} +1 -1
- package/dist/assets/{diagram-G47NLZAW-C7-ZlmFT.js → diagram-G47NLZAW-BTUAsFjb.js} +1 -1
- package/dist/assets/{diagram-NH7WQ7WH-C-P9Y7IR.js → diagram-NH7WQ7WH-BcaomqSd.js} +1 -1
- package/dist/assets/{diagram-OA4YK3LP-Ci5lZ_T5.js → diagram-OA4YK3LP-DDLX7Xwr.js} +1 -1
- package/dist/assets/{diagram-WEI45ONY-C1xuK2bs.js → diagram-WEI45ONY-CIave0An.js} +1 -1
- package/dist/assets/dist-DLKC_odd.js +1 -0
- package/dist/assets/{ebnfDiagram-CCIWWBDH-DKQ5NWMD.js → ebnfDiagram-CCIWWBDH-Cr1Y6lPu.js} +1 -1
- package/dist/assets/{erDiagram-Q63AITRT-HAWySadP.js → erDiagram-Q63AITRT-D3EgiVVH.js} +1 -1
- package/dist/assets/esm-Df4edDpj.js +2 -0
- package/dist/assets/eventmodeling-45OFAUF4-DO1vRTM0.js +1 -0
- package/dist/assets/flowDiagram-23GEKE2U-BS7KXcqn.js +1 -0
- package/dist/assets/{ganttDiagram-NO4QXBWP-C1hwIcOA.js → ganttDiagram-NO4QXBWP-B0oyDIqK.js} +1 -1
- package/dist/assets/gitGraph-TEB2WS4Q-m5F5ef09.js +1 -0
- package/dist/assets/{gitGraphDiagram-IHSO6WYX-DYUYxs1R.js → gitGraphDiagram-IHSO6WYX-uQtr6IqK.js} +1 -1
- package/dist/assets/icons-CXPP1fFT.js +1 -0
- package/dist/assets/index-_ZhK6bvp.js +65 -0
- package/dist/assets/index-iVV2bP_f.css +3 -0
- package/dist/assets/info-DKCQHKI2-CZxPlQJ0.js +1 -0
- package/dist/assets/{infoDiagram-FWYZ7A6U-CnIL6tv4.js → infoDiagram-FWYZ7A6U-B_GzlLIM.js} +1 -1
- package/dist/assets/{ishikawaDiagram-FXEZZL3T-B7WXNycQ.js → ishikawaDiagram-FXEZZL3T-CKQIsSdU.js} +1 -1
- package/dist/assets/{journeyDiagram-5HDEW3XC-D4HvioyY.js → journeyDiagram-5HDEW3XC-DrrvzZL1.js} +1 -1
- package/dist/assets/{kanban-definition-HUTT4EX6-CDs763eS.js → kanban-definition-HUTT4EX6-CJQRTdXz.js} +1 -1
- package/dist/assets/{line-ikKkQiFp.js → line-B4DxX7tC.js} +1 -1
- package/dist/assets/{linear-GqPyxQkN.js → linear-U-nKUhyW.js} +1 -1
- package/dist/assets/{map-CJwjCvwr.js → map-BneTM-ri.js} +1 -1
- package/dist/assets/{mcp-servers-dialog-BQbFywVL.js → mcp-servers-dialog-BUSPvaqI.js} +2 -2
- package/dist/assets/{mermaid-parser.core-CoE8cccr.js → mermaid-parser.core-BlKWrEdZ.js} +2 -2
- package/dist/assets/{mermaid-renderer-BmbSAmpG.js → mermaid-renderer-jEbqFaTe.js} +2 -2
- package/dist/assets/{mermaid.core-DlFSL90j.js → mermaid.core-DWpShXCs.js} +3 -3
- package/dist/assets/{mindmap-definition-LN4V7U3C-DLdq0K9C.js → mindmap-definition-LN4V7U3C-CEVwZD78.js} +1 -1
- package/dist/assets/model-identity-CgA6_Pbm.js +1 -0
- package/dist/assets/model-reference-o41fJ6jQ.js +1 -0
- package/dist/assets/{monaco-BTsVCDWS.js → monaco-D6OhXgjg.js} +1 -1
- package/dist/assets/{ordinal-CibZU3PM.js → ordinal-B2r5L1v4.js} +1 -1
- package/dist/assets/{otel-BNGM50C-.js → otel-BFnphzjt.js} +1 -1
- package/dist/assets/packet-7NZHBO7P-zIioIZVN.js +1 -0
- package/dist/assets/{pegDiagram-2B236MQR-Cm1kPRC2.js → pegDiagram-2B236MQR-CBLkBdnQ.js} +1 -1
- package/dist/assets/{pi-ai-Cr3rpCXT.js → pi-ai-Cr2ee4a0.js} +2 -2
- package/dist/assets/{pi-web-ui-DoRGtREc.js → pi-web-ui-DV5jKjSg.js} +1 -1
- package/dist/assets/pie-RZYD4A2V-GGWijBvB.js +1 -0
- package/dist/assets/{pieDiagram-ENE6RG2P-Df05wjjo.js → pieDiagram-ENE6RG2P-8tCnwtWS.js} +1 -1
- package/dist/assets/{quadrantDiagram-ABIIQ3AL-BjCwGxJC.js → quadrantDiagram-ABIIQ3AL-CWd28cHF.js} +1 -1
- package/dist/assets/radar-I7S5WNFK-yvwFH3RV.js +1 -0
- package/dist/assets/railroad-3IZDKUUU-BVadlswB.js +1 -0
- package/dist/assets/railroad-abnf-AHOZXSZD-B7R-p_2-.js +1 -0
- package/dist/assets/railroad-ebnf-EBAXGLYW-BnbJxPug.js +1 -0
- package/dist/assets/railroad-peg-LSFZ7HO6-Ci3DcEuQ.js +1 -0
- package/dist/assets/{railroadDiagram-RFXS5EU6-CTUvpKkv.js → railroadDiagram-RFXS5EU6-CI4ouOBs.js} +1 -1
- package/dist/assets/{react-vendor-Dr5xvL-e.js → react-vendor-1KC5PyRx.js} +1 -1
- package/dist/assets/{requirementDiagram-TGXJPOKE-BU1kvEku.js → requirementDiagram-TGXJPOKE-DtFz7sw4.js} +1 -1
- package/dist/assets/{sankeyDiagram-HTMAVEWB-BHmvxVqH.js → sankeyDiagram-HTMAVEWB--VeOwwk9.js} +1 -1
- package/dist/assets/{sequenceDiagram-DBY2YBRQ-CTpwICgg.js → sequenceDiagram-DBY2YBRQ-B8AHk5Oe.js} +1 -1
- package/dist/assets/{sizeCapture-X5ZJPWSS-BbLhGaa4.js → sizeCapture-X5ZJPWSS-vV_ArM8D.js} +1 -1
- package/dist/assets/{skills-dialog-REBeTFSH.js → skills-dialog-BThnIUBs.js} +3 -1
- package/dist/assets/{src-B4Tvg3gT.js → src-PYsDme0X.js} +1 -1
- package/dist/assets/{stateDiagram-2N3HPSRC-BxuDwIgT.js → stateDiagram-2N3HPSRC-etXnJ8X8.js} +1 -1
- package/dist/assets/stateDiagram-v2-6OUMAXLB-Dms3pICj.js +1 -0
- package/dist/assets/{swimlanes-5IMT3BWC-EkZsiylV.js → swimlanes-5IMT3BWC-pabIKAmn.js} +2 -2
- package/dist/assets/swimlanesDiagram-G3AALYLV-B14aWjv6.js +8 -0
- package/dist/assets/{timeline-definition-FHXFAJF6-C9ewOCTa.js → timeline-definition-FHXFAJF6-C55MKm3L.js} +1 -1
- package/dist/assets/treeView-QDETBFTQ-Cru9B2zv.js +1 -0
- package/dist/assets/treemap-6X3UGDF4-DNOVHFaJ.js +1 -0
- package/dist/assets/{vennDiagram-L72KCM5P-CR49Y4Lp.js → vennDiagram-L72KCM5P-CgNf1Q9W.js} +1 -1
- package/dist/assets/wardley-OPB4EBWU-E3m1BOJQ.js +1 -0
- package/dist/assets/{wardleyDiagram-EHGQE667-Cn0GgwWi.js → wardleyDiagram-EHGQE667-Drt5ytec.js} +1 -1
- package/dist/assets/web-DoV8MSMn.js +1 -0
- package/dist/assets/{xychartDiagram-FW5EYKEG-DlmPNAvd.js → xychartDiagram-FW5EYKEG-hhoEo_Ar.js} +1 -1
- package/dist/index.html +13 -11
- package/dist/mobile-error.html +24 -0
- package/package.json +6 -1
- package/plugins/{openai-documents → documents}/plugin.json +2 -2
- package/plugins/{openai-presentations → presentations}/plugin.json +2 -2
- package/plugins/{openai-spreadsheets → spreadsheets}/plugin.json +2 -2
- package/server/acp/server.mjs +50 -35
- package/server/agent-manager.mjs +343 -46
- package/server/agent-profile-files.mjs +8 -4
- package/server/agent-profile-schema.mjs +47 -23
- package/server/agent-profiles.mjs +1 -1
- package/server/ai-http-logger.mjs +156 -13
- package/server/ai-provider-options.mjs +3 -0
- package/server/channels/channel-logs.mjs +13 -0
- package/server/channels/event-relay.mjs +33 -0
- package/server/channels/process-channel.mjs +29 -0
- package/server/channels/providers/wechat.mjs +9 -3
- package/server/channels/registry.mjs +5 -1
- package/server/cloud/chat-idempotency-store.mjs +96 -0
- package/server/cloud/client.mjs +102 -0
- package/server/cloud/config.mjs +53 -0
- package/server/cloud/credential-store.mjs +193 -0
- package/server/cloud/identity.mjs +355 -0
- package/server/cloud/index.mjs +7 -0
- package/server/cloud/models.mjs +80 -0
- package/server/cloud/runtime.mjs +129 -0
- package/server/cloud/service-config.mjs +77 -0
- package/server/index.mjs +63 -33
- package/server/lan-access-store.mjs +93 -3
- package/server/model-catalog.mjs +262 -0
- package/server/network-proxy.mjs +68 -3
- package/server/plugins/registry.mjs +93 -9
- package/server/public-api.mjs +6 -2
- package/server/routes/agent-profiles.mjs +43 -9
- package/server/routes/agent.mjs +48 -11
- package/server/routes/backup.mjs +7 -1
- package/server/routes/channels.mjs +47 -0
- package/server/routes/cloud.mjs +227 -0
- package/server/routes/lan-access.mjs +246 -21
- package/server/routes/models.mjs +13 -4
- package/server/routes/project.mjs +19 -1
- package/server/routes/scheduled-tasks.mjs +40 -10
- package/server/routes/shared-conversation.mjs +62 -58
- package/server/routes/shares.mjs +76 -1
- package/server/routes/static.mjs +26 -1
- package/server/routes/storage.mjs +24 -1
- package/server/routes/system.mjs +11 -0
- package/server/routes/terminal.mjs +7 -2
- package/server/routes/workspace.mjs +66 -13
- package/server/session-utils.mjs +2 -2
- package/server/share-store.mjs +168 -13
- package/server/skills.mjs +30 -3
- package/server/storage.mjs +7 -1
- package/server/subagents.mjs +4 -4
- package/server/terminal/terminal-manager.mjs +2 -4
- package/server/tools/definitions.mjs +3 -3
- package/server/tools/index.mjs +7 -5
- package/server/utils/network.mjs +9 -0
- package/server/utils/package-update.mjs +70 -47
- package/server/utils/process-env.mjs +7 -0
- package/server/utils/response.mjs +10 -3
- package/skills/skill-creator/LICENSE.txt +202 -0
- package/skills/skill-creator/SKILL.md +485 -0
- package/skills/skill-creator/UPSTREAM.md +6 -0
- package/skills/skill-creator/agents/analyzer.md +274 -0
- package/skills/skill-creator/agents/comparator.md +202 -0
- package/skills/skill-creator/agents/grader.md +223 -0
- package/skills/skill-creator/assets/eval_review.html +146 -0
- package/skills/skill-creator/eval-viewer/generate_review.py +471 -0
- package/skills/skill-creator/eval-viewer/viewer.html +1325 -0
- package/skills/skill-creator/references/schemas.md +430 -0
- package/skills/skill-creator/scripts/__init__.py +0 -0
- package/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/skills/skill-creator/scripts/generate_report.py +326 -0
- package/skills/skill-creator/scripts/improve_description.py +247 -0
- package/skills/skill-creator/scripts/package_skill.py +136 -0
- package/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/skills/skill-creator/scripts/run_eval.py +310 -0
- package/skills/skill-creator/scripts/run_loop.py +328 -0
- package/skills/skill-creator/scripts/utils.py +47 -0
- package/dist/assets/AgentProfilesPage-D7pbg8nm.js +0 -1
- package/dist/assets/ChatPanelHost-wfGCaCzD.js +0 -288
- package/dist/assets/PluginsPage-NAGroBm3.js +0 -1
- package/dist/assets/ScheduledTasksPage-Bp0MNfQD.js +0 -2
- package/dist/assets/SettingsWorkspacePage-BtJZMIsZ.js +0 -1576
- package/dist/assets/SharedConversationPage-Ce3KoVZt.js +0 -1
- package/dist/assets/TerminalDock-4eUuXP7X.js +0 -2
- package/dist/assets/WorkspaceInspector-kM3BRPjY.js +0 -13
- package/dist/assets/architecture-TIHT7OUA-BgP-IMeo.js +0 -1
- package/dist/assets/channel-Rz20dKTK.js +0 -1
- package/dist/assets/chunk-2Q5K7J3B-Cb14ZF_k.js +0 -1
- package/dist/assets/chunk-VAUOI2AC-BOZvd2Sn.js +0 -1
- package/dist/assets/chunk-XXDRQBXY-CD_EGCtT.js +0 -1
- package/dist/assets/classDiagram-OUVF2IWQ-C_ozTKCt.js +0 -1
- package/dist/assets/classDiagram-v2-EOCWNBFH-FOfFbbZF.js +0 -1
- package/dist/assets/cynefin-VYW2F7L2-BzPhLtd5.js +0 -1
- package/dist/assets/eventmodeling-45OFAUF4-BcgGbVJ-.js +0 -1
- package/dist/assets/flowDiagram-23GEKE2U-dtkzcC8E.js +0 -1
- package/dist/assets/gitGraph-TEB2WS4Q-VByWboBU.js +0 -1
- package/dist/assets/icons-BP8YOS-Z.js +0 -1
- package/dist/assets/index-C6k5taeb.js +0 -66
- package/dist/assets/index-CzN8NSKC.css +0 -3
- package/dist/assets/info-DKCQHKI2-CZeDLZxx.js +0 -1
- package/dist/assets/packet-7NZHBO7P-decrrxyX.js +0 -1
- package/dist/assets/pie-RZYD4A2V-J1CasQZl.js +0 -1
- package/dist/assets/radar-I7S5WNFK-B-sZytUA.js +0 -1
- package/dist/assets/railroad-3IZDKUUU-BSaqNPm8.js +0 -1
- package/dist/assets/railroad-abnf-AHOZXSZD-lzZR7PxT.js +0 -1
- package/dist/assets/railroad-ebnf-EBAXGLYW-DQtz1Fh9.js +0 -1
- package/dist/assets/railroad-peg-LSFZ7HO6-CpMsuGY3.js +0 -1
- package/dist/assets/stateDiagram-v2-6OUMAXLB-BGLshxcY.js +0 -1
- package/dist/assets/swimlanesDiagram-G3AALYLV-CqdqxA-b.js +0 -8
- package/dist/assets/treeView-QDETBFTQ-Byb71heW.js +0 -1
- package/dist/assets/treemap-6X3UGDF4-CMV1SJsq.js +0 -1
- package/dist/assets/wardley-OPB4EBWU-DtCHtr2V.js +0 -1
- /package/dist/assets/{array-CYkMkqnU.js → array-B9UHiPd-.js} +0 -0
- /package/dist/assets/{chunk-KEIR6QF5-77hsebd7.js → chunk-KEIR6QF5-jrz1pRUS.js} +0 -0
- /package/dist/assets/{chunk-Y2CYZVJY-CQltPwYk.js → chunk-Y2CYZVJY-D6N-CrJv.js} +0 -0
- /package/dist/assets/{css-utils-rkE68RDy.js → css-utils-31qzCXsk.js} +0 -0
- /package/dist/assets/{cytoscape.esm-DwdZnGOm.js → cytoscape.esm-DyfqweF2.js} +0 -0
- /package/dist/assets/{defaultLocale-Beh6XjaL.js → defaultLocale-5eAKkKJC.js} +0 -0
- /package/dist/assets/{dist-DelZBZpK.js → dist-CLg13NtV.js} +0 -0
- /package/dist/assets/{graphlib-CAISHZh4.js → graphlib-DJkmx0Cq.js} +0 -0
- /package/dist/assets/{init-Rr1s_RiX.js → init-DlZdxViB.js} +0 -0
- /package/dist/assets/{lit-vendor-Dr3cpBGF.js → lit-vendor-DvaQX_UQ.js} +0 -0
- /package/dist/assets/{logger-B65Akg8A.js → logger-8REuLPGK.js} +0 -0
- /package/dist/assets/{path-BAQ3hXlG.js → path-6uRLdFF7.js} +0 -0
- /package/dist/assets/{plugin-api-BbUkYm3Y.js → plugin-api-Uu2xAB4d.js} +0 -0
- /package/dist/assets/{rough.esm-Djo4Abte.js → rough.esm-Bud4g4fh.js} +0 -0
- /package/dist/assets/{xterm-CGiQzDiR.js → xterm-Bm_IbozX.js} +0 -0
- /package/plugins/{openai-documents → documents}/commands/document.md +0 -0
- /package/plugins/{openai-documents → documents}/skills/documents/SKILL.md +0 -0
- /package/plugins/{openai-presentations → presentations}/commands/presentation.md +0 -0
- /package/plugins/{openai-presentations → presentations}/skills/presentations/SKILL.md +0 -0
- /package/plugins/{openai-spreadsheets → spreadsheets}/commands/spreadsheet.md +0 -0
- /package/plugins/{openai-spreadsheets → spreadsheets}/skills/spreadsheets/SKILL.md +0 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { cloudEndpoint } from './config.mjs'
|
|
2
|
+
|
|
3
|
+
export class CloudApiError extends Error {
|
|
4
|
+
constructor(message, { status = 0, code = 'cloud_request_failed', retryable = false, details } = {}) {
|
|
5
|
+
super(message)
|
|
6
|
+
this.name = 'CloudApiError'
|
|
7
|
+
this.status = status
|
|
8
|
+
this.code = code
|
|
9
|
+
this.retryable = retryable
|
|
10
|
+
this.details = details
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async function parseError(response) {
|
|
15
|
+
let payload
|
|
16
|
+
try { payload = await response.json() } catch { payload = undefined }
|
|
17
|
+
const error = payload?.error
|
|
18
|
+
const structured = error && typeof error === 'object' ? error : undefined
|
|
19
|
+
const oauthCode = typeof error === 'string' ? error : undefined
|
|
20
|
+
return new CloudApiError(
|
|
21
|
+
structured?.message || payload?.error_description || `QuickForge Cloud request failed (${response.status}).`,
|
|
22
|
+
{
|
|
23
|
+
status: response.status,
|
|
24
|
+
code: structured?.code || payload?.code || oauthCode || 'cloud_request_failed',
|
|
25
|
+
retryable: Boolean(structured?.retryable || payload?.retryable),
|
|
26
|
+
details: structured?.details || payload?.details,
|
|
27
|
+
},
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function timeoutSignal(timeoutMs, outerSignal) {
|
|
32
|
+
const timeout = AbortSignal.timeout(timeoutMs)
|
|
33
|
+
return outerSignal ? AbortSignal.any([outerSignal, timeout]) : timeout
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export class CloudClient {
|
|
37
|
+
constructor({ baseUrl, timeoutMs = 10_000, fetchImpl = fetch } = {}) {
|
|
38
|
+
if (!(baseUrl instanceof URL)) throw new Error('CloudClient requires a configured base URL.')
|
|
39
|
+
this.baseUrl = baseUrl
|
|
40
|
+
this.timeoutMs = timeoutMs
|
|
41
|
+
this.fetch = fetchImpl
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async request(pathname, { method = 'GET', token, body, headers, signal, raw = false, timeout = true } = {}) {
|
|
45
|
+
const requestHeaders = { Accept: 'application/json', ...headers }
|
|
46
|
+
if (body !== undefined) requestHeaders['Content-Type'] = 'application/json'
|
|
47
|
+
if (token) requestHeaders.Authorization = `Bearer ${token}`
|
|
48
|
+
const response = await this.fetch(cloudEndpoint(this.baseUrl, pathname), {
|
|
49
|
+
method,
|
|
50
|
+
headers: requestHeaders,
|
|
51
|
+
body: body === undefined ? undefined : JSON.stringify(body),
|
|
52
|
+
signal: timeout ? timeoutSignal(this.timeoutMs, signal) : signal,
|
|
53
|
+
redirect: 'error',
|
|
54
|
+
})
|
|
55
|
+
if (!response.ok) throw await parseError(response)
|
|
56
|
+
if (raw) return response
|
|
57
|
+
if (response.status === 204) return undefined
|
|
58
|
+
return response.json()
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
health(signal) { return this.request('healthz', { signal }) }
|
|
62
|
+
ready(signal) { return this.request('readyz', { signal }) }
|
|
63
|
+
registerGuest(input, idempotencyKey, signal) {
|
|
64
|
+
return this.request('v1/guest/installations', {
|
|
65
|
+
method: 'POST', body: input, headers: { 'Idempotency-Key': idempotencyKey }, signal,
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
refresh(refreshToken, signal) {
|
|
69
|
+
return this.request('oauth/token', {
|
|
70
|
+
method: 'POST', body: { grantType: 'refresh_token', refreshToken }, signal,
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
authorizeDevice(token, installationId, clientId = 'quickforge-desktop', signal) {
|
|
74
|
+
return this.request('oauth/device_authorization', {
|
|
75
|
+
method: 'POST', token, body: { installationId, clientId }, signal,
|
|
76
|
+
})
|
|
77
|
+
}
|
|
78
|
+
exchangeDeviceCode(deviceCode, clientId = 'quickforge-desktop', signal) {
|
|
79
|
+
return this.request('oauth/token', {
|
|
80
|
+
method: 'POST',
|
|
81
|
+
body: {
|
|
82
|
+
grantType: 'urn:ietf:params:oauth:grant-type:device_code',
|
|
83
|
+
deviceCode,
|
|
84
|
+
clientId,
|
|
85
|
+
},
|
|
86
|
+
signal,
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
me(token, signal) { return this.request('v1/me', { token, signal }) }
|
|
90
|
+
models(token, signal) { return this.request('v1/models', { token, signal }) }
|
|
91
|
+
usage(token, signal) { return this.request('v1/usage', { token, signal }) }
|
|
92
|
+
installations(token, signal) { return this.request('v1/installations', { token, signal }) }
|
|
93
|
+
revokeInstallation(token, installationId, signal) {
|
|
94
|
+
return this.request(`v1/installations/${encodeURIComponent(installationId)}`, { method: 'DELETE', token, signal })
|
|
95
|
+
}
|
|
96
|
+
chat(token, payload, idempotencyKey, signal) {
|
|
97
|
+
return this.request('v1/chat/completions', {
|
|
98
|
+
method: 'POST', token, body: payload,
|
|
99
|
+
headers: { 'Idempotency-Key': idempotencyKey }, signal, raw: true, timeout: false,
|
|
100
|
+
})
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import net from 'node:net'
|
|
2
|
+
|
|
3
|
+
const DEFAULT_TIMEOUT_MS = 10_000
|
|
4
|
+
|
|
5
|
+
function isLoopbackHost(hostname) {
|
|
6
|
+
const host = String(hostname || '').toLowerCase()
|
|
7
|
+
if (host === 'localhost' || host.endsWith('.localhost')) return true
|
|
8
|
+
const ip = net.isIP(host)
|
|
9
|
+
if (ip === 4) return host.startsWith('127.')
|
|
10
|
+
if (ip === 6) return host === '::1' || host === '0:0:0:0:0:0:0:1'
|
|
11
|
+
return false
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function parseCloudBaseUrl(value, _options = {}) {
|
|
15
|
+
const raw = typeof value === 'string' ? value.trim() : ''
|
|
16
|
+
if (!raw) return undefined
|
|
17
|
+
|
|
18
|
+
let url
|
|
19
|
+
try {
|
|
20
|
+
url = new URL(raw)
|
|
21
|
+
} catch {
|
|
22
|
+
throw new Error('QUICKFORGE_CLOUD_URL must be a valid URL.')
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (url.username || url.password || url.search || url.hash) {
|
|
26
|
+
throw new Error('QUICKFORGE_CLOUD_URL must not contain credentials, query parameters, or fragments.')
|
|
27
|
+
}
|
|
28
|
+
if (url.protocol !== 'https:') {
|
|
29
|
+
if (!(url.protocol === 'http:' && isLoopbackHost(url.hostname))) {
|
|
30
|
+
throw new Error('QUICKFORGE_CLOUD_URL must use HTTPS. HTTP is allowed only for loopback addresses.')
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (url.pathname.includes('..')) throw new Error('QUICKFORGE_CLOUD_URL contains an unsafe path.')
|
|
34
|
+
url.pathname = `${url.pathname.replace(/\/+$/, '')}/`
|
|
35
|
+
return url
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function cloudEndpoint(baseUrl, pathname) {
|
|
39
|
+
if (!(baseUrl instanceof URL)) throw new Error('QuickForge Cloud is not configured.')
|
|
40
|
+
const relative = String(pathname || '').replace(/^\/+/, '')
|
|
41
|
+
if (!relative || relative.split('/').includes('..')) throw new Error('Invalid QuickForge Cloud endpoint.')
|
|
42
|
+
return new URL(relative, baseUrl)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function readCloudConfig(env = process.env) {
|
|
46
|
+
const baseUrl = parseCloudBaseUrl(env.QUICKFORGE_CLOUD_URL)
|
|
47
|
+
const timeoutValue = Number(env.QUICKFORGE_CLOUD_TIMEOUT_MS || DEFAULT_TIMEOUT_MS)
|
|
48
|
+
return {
|
|
49
|
+
enabled: Boolean(baseUrl),
|
|
50
|
+
baseUrl,
|
|
51
|
+
timeoutMs: Number.isFinite(timeoutValue) ? Math.min(60_000, Math.max(1_000, timeoutValue)) : DEFAULT_TIMEOUT_MS,
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { generateKeyPair } from 'node:crypto'
|
|
2
|
+
import { promises as fs } from 'node:fs'
|
|
3
|
+
import os from 'node:os'
|
|
4
|
+
import path from 'node:path'
|
|
5
|
+
import { promisify } from 'node:util'
|
|
6
|
+
import { createRandomToken } from '../utils/password-auth.mjs'
|
|
7
|
+
import { ensureStorage, storageDir } from '../storage.mjs'
|
|
8
|
+
|
|
9
|
+
const generateKeyPairAsync = promisify(generateKeyPair)
|
|
10
|
+
const SCHEMA_VERSION = 1
|
|
11
|
+
const ACCOUNT_FIELDS = ['id', 'email', 'plan']
|
|
12
|
+
|
|
13
|
+
function publicAccount(value) {
|
|
14
|
+
if (!value || typeof value !== 'object') return undefined
|
|
15
|
+
const account = {}
|
|
16
|
+
for (const field of ACCOUNT_FIELDS) {
|
|
17
|
+
const candidate = value[field]
|
|
18
|
+
if (typeof candidate === 'string' && candidate) account[field] = candidate
|
|
19
|
+
}
|
|
20
|
+
return Object.keys(account).length ? account : undefined
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function publicPendingDeviceFlow(value) {
|
|
24
|
+
if (!value || typeof value !== 'object') return undefined
|
|
25
|
+
const expiresAt = Number(value.expiresAt)
|
|
26
|
+
if (!Number.isFinite(expiresAt)) return undefined
|
|
27
|
+
return {
|
|
28
|
+
userCode: String(value.userCode || ''),
|
|
29
|
+
verificationUri: String(value.verificationUri || ''),
|
|
30
|
+
verificationUriComplete: String(value.verificationUriComplete || ''),
|
|
31
|
+
expiresAt,
|
|
32
|
+
interval: Math.max(1, Number(value.interval) || 5),
|
|
33
|
+
status: String(value.status || 'pending'),
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function platformName(platform = process.platform) {
|
|
38
|
+
if (platform === 'win32') return 'windows'
|
|
39
|
+
if (platform === 'darwin') return 'macos'
|
|
40
|
+
return 'linux'
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function defaultRecord({ installationName, platform, clientVersion } = {}) {
|
|
44
|
+
return {
|
|
45
|
+
schemaVersion: SCHEMA_VERSION,
|
|
46
|
+
mode: 'local',
|
|
47
|
+
installationName: installationName || os.hostname() || 'QuickForge',
|
|
48
|
+
platform: platformName(platform),
|
|
49
|
+
clientVersion: clientVersion || 'unknown',
|
|
50
|
+
updatedAt: new Date().toISOString(),
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function normalizeRecord(value, defaults) {
|
|
55
|
+
const input = value && typeof value === 'object' ? value : {}
|
|
56
|
+
const base = defaultRecord(defaults)
|
|
57
|
+
return {
|
|
58
|
+
...base,
|
|
59
|
+
...input,
|
|
60
|
+
schemaVersion: SCHEMA_VERSION,
|
|
61
|
+
mode: ['local', 'guest', 'account'].includes(input.mode) ? input.mode : 'local',
|
|
62
|
+
installationName: String(input.installationName || base.installationName).slice(0, 120),
|
|
63
|
+
platform: ['windows', 'macos', 'linux'].includes(input.platform) ? input.platform : base.platform,
|
|
64
|
+
clientVersion: String(input.clientVersion || base.clientVersion).slice(0, 80),
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function publicRecord(record) {
|
|
69
|
+
return {
|
|
70
|
+
configured: true,
|
|
71
|
+
mode: record.mode,
|
|
72
|
+
installationId: record.installationId,
|
|
73
|
+
installationName: record.installationName,
|
|
74
|
+
platform: record.platform,
|
|
75
|
+
clientVersion: record.clientVersion,
|
|
76
|
+
hasInstallationKey: Boolean(record.publicKey && record.privateKeyPkcs8),
|
|
77
|
+
hasSession: Boolean(record.refreshToken),
|
|
78
|
+
account: publicAccount(record.account),
|
|
79
|
+
pendingDeviceFlow: publicPendingDeviceFlow(record.pendingDeviceFlow),
|
|
80
|
+
updatedAt: record.updatedAt,
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async function generateInstallationKeyPair() {
|
|
85
|
+
const { publicKey, privateKey } = await generateKeyPairAsync('ed25519')
|
|
86
|
+
const publicJwk = publicKey.export({ format: 'jwk' })
|
|
87
|
+
return {
|
|
88
|
+
publicKey: publicJwk.x,
|
|
89
|
+
privateKeyPkcs8: privateKey.export({ format: 'der', type: 'pkcs8' }).toString('base64url'),
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function createCloudCredentialStore({
|
|
94
|
+
filePath = path.join(storageDir, 'security', 'cloud-identity.json'),
|
|
95
|
+
ensureBaseStorage = ensureStorage,
|
|
96
|
+
installationName,
|
|
97
|
+
platform,
|
|
98
|
+
clientVersion,
|
|
99
|
+
} = {}) {
|
|
100
|
+
let queue = Promise.resolve()
|
|
101
|
+
const defaults = { installationName, platform, clientVersion }
|
|
102
|
+
|
|
103
|
+
async function ensureDirectory() {
|
|
104
|
+
await ensureBaseStorage()
|
|
105
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true, mode: 0o700 })
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async function read() {
|
|
109
|
+
await ensureDirectory()
|
|
110
|
+
try {
|
|
111
|
+
const raw = await fs.readFile(filePath, 'utf8')
|
|
112
|
+
return normalizeRecord(raw.trim() ? JSON.parse(raw) : {}, defaults)
|
|
113
|
+
} catch (error) {
|
|
114
|
+
if (error?.code === 'ENOENT') return defaultRecord(defaults)
|
|
115
|
+
throw error
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async function writeNow(record) {
|
|
120
|
+
await ensureDirectory()
|
|
121
|
+
const normalized = normalizeRecord({ ...record, updatedAt: new Date().toISOString() }, defaults)
|
|
122
|
+
const temporary = `${filePath}.${process.pid}.${createRandomToken(8)}.tmp`
|
|
123
|
+
await fs.writeFile(temporary, `${JSON.stringify(normalized, null, 2)}\n`, { encoding: 'utf8', mode: 0o600 })
|
|
124
|
+
try { await fs.chmod(temporary, 0o600) } catch { /* best effort on Windows */ }
|
|
125
|
+
try {
|
|
126
|
+
await fs.rename(temporary, filePath)
|
|
127
|
+
} catch (error) {
|
|
128
|
+
if (!['EEXIST', 'EPERM'].includes(error?.code)) throw error
|
|
129
|
+
await fs.rm(filePath, { force: true })
|
|
130
|
+
await fs.rename(temporary, filePath)
|
|
131
|
+
}
|
|
132
|
+
try { await fs.chmod(filePath, 0o600) } catch { /* best effort on Windows */ }
|
|
133
|
+
return normalized
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function update(mutator) {
|
|
137
|
+
const next = queue.catch(() => undefined).then(async () => {
|
|
138
|
+
const current = await read()
|
|
139
|
+
const result = await mutator({ ...current })
|
|
140
|
+
return writeNow(result || current)
|
|
141
|
+
})
|
|
142
|
+
queue = next
|
|
143
|
+
return next
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async function ensureInstallation() {
|
|
147
|
+
const current = await read()
|
|
148
|
+
if (current.publicKey && current.privateKeyPkcs8) return current
|
|
149
|
+
return update(async (record) => ({ ...record, ...(await generateInstallationKeyPair()) }))
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async function rotateInstallation() {
|
|
153
|
+
const keyPair = await generateInstallationKeyPair()
|
|
154
|
+
return update((record) => ({
|
|
155
|
+
...record,
|
|
156
|
+
...keyPair,
|
|
157
|
+
mode: 'local',
|
|
158
|
+
installationId: undefined,
|
|
159
|
+
refreshToken: undefined,
|
|
160
|
+
sessionCloudUrl: undefined,
|
|
161
|
+
pendingRegistrationKey: undefined,
|
|
162
|
+
pendingRegistrationHash: undefined,
|
|
163
|
+
pendingDeviceFlow: undefined,
|
|
164
|
+
account: undefined,
|
|
165
|
+
rotateInstallationBeforeRegistration: undefined,
|
|
166
|
+
}))
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
filePath,
|
|
171
|
+
read,
|
|
172
|
+
update,
|
|
173
|
+
ensureInstallation,
|
|
174
|
+
rotateInstallation,
|
|
175
|
+
async readPublic() { return publicRecord(await read()) },
|
|
176
|
+
async clearSession({ rotateInstallationBeforeRegistration = false } = {}) {
|
|
177
|
+
return update((record) => ({
|
|
178
|
+
...record,
|
|
179
|
+
mode: 'local',
|
|
180
|
+
installationId: undefined,
|
|
181
|
+
refreshToken: undefined,
|
|
182
|
+
sessionCloudUrl: undefined,
|
|
183
|
+
pendingRegistrationKey: undefined,
|
|
184
|
+
pendingRegistrationHash: undefined,
|
|
185
|
+
pendingDeviceFlow: undefined,
|
|
186
|
+
account: undefined,
|
|
187
|
+
rotateInstallationBeforeRegistration: rotateInstallationBeforeRegistration || undefined,
|
|
188
|
+
}))
|
|
189
|
+
},
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export { publicRecord as publicCloudCredentialRecord }
|