@mx-space/cli 0.15.0 → 0.15.1
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/dist/{Lexical.dev-Cck4n26y.mjs → Lexical.dev-BSvx45_E.mjs} +127 -94
- package/dist/{Lexical.node-D6wf2D5M.mjs → Lexical.node-kAh5GM2n.mjs} +1 -1
- package/dist/{Lexical.prod-DCwS1oTq.mjs → Lexical.prod-Bqwgb3ez.mjs} +4 -2
- package/dist/{LexicalClipboard.dev-CMkPHV7O.mjs → LexicalClipboard.dev-BWU3KXIa.mjs} +18 -14
- package/dist/{LexicalClipboard.node-m4nZ7IYw.mjs → LexicalClipboard.node-BygAdNdF.mjs} +1 -1
- package/dist/{LexicalClipboard.prod-B_rN1vE1.mjs → LexicalClipboard.prod-BtMuKNyT.mjs} +10 -10
- package/dist/{LexicalCodeCore.dev-DyJw3i8V.mjs → LexicalCodeCore.dev-CD2xgvDs.mjs} +43 -25
- package/dist/{LexicalCodeCore.prod-DPXLHQLF.mjs → LexicalCodeCore.prod-Bl6FFMc7.mjs} +6 -6
- package/dist/{LexicalDragon.dev-ZkNfMwrE.mjs → LexicalDragon.dev-BwdYhm4K.mjs} +2 -2
- package/dist/{LexicalDragon.node-Ds9oLUFh.mjs → LexicalDragon.node-CpJhkCVV.mjs} +1 -1
- package/dist/{LexicalDragon.prod-B58ic2av.mjs → LexicalDragon.prod-CvXmWwo1.mjs} +2 -2
- package/dist/{LexicalExtension.dev-DvwHs1Xv.mjs → LexicalExtension.dev-LcRLXI5Z.mjs} +25 -13
- package/dist/{LexicalExtension.node-5OymZQfy.mjs → LexicalExtension.node-BwJt2LXV.mjs} +1 -1
- package/dist/{LexicalExtension.prod-Ce0T5smQ.mjs → LexicalExtension.prod-lg8_33-H.mjs} +16 -13
- package/dist/{LexicalHeadless.dev-DA0WldSR.mjs → LexicalHeadless.dev-BeUbKBes.mjs} +1 -1
- package/dist/{LexicalHeadless.prod-1kQgKB6c.mjs → LexicalHeadless.prod-4gbIA8HM.mjs} +1 -1
- package/dist/{LexicalHtml.dev-BDB7CUrx.mjs → LexicalHtml.dev-BLdZWTCJ.mjs} +20 -14
- package/dist/{LexicalHtml.node-DpVNt7It.mjs → LexicalHtml.node-BeuJMvvt.mjs} +1 -1
- package/dist/{LexicalHtml.prod-HkxM5scw.mjs → LexicalHtml.prod-CHUyCocN.mjs} +4 -4
- package/dist/{LexicalLink.dev-C5zNJlrm.mjs → LexicalLink.dev-DgsFRqw0.mjs} +28 -21
- package/dist/{LexicalLink.prod-Bkt9hQAt.mjs → LexicalLink.prod-CkXkeKY2.mjs} +6 -5
- package/dist/{LexicalList.dev-B7VgME-m.mjs → LexicalList.dev-OOms3kQi.mjs} +4 -4
- package/dist/{LexicalList.prod-B8c7TDjH.mjs → LexicalList.prod-DzMBeqHn.mjs} +4 -4
- package/dist/{LexicalMarkdown.dev-B5z9kLbV.mjs → LexicalMarkdown.dev-DJLKbZtD.mjs} +40 -29
- package/dist/{LexicalMarkdown.prod-wKzw7FFH.mjs → LexicalMarkdown.prod-Cp21kDCU.mjs} +10 -7
- package/dist/{LexicalRichText.dev-CUd6Li5F.mjs → LexicalRichText.dev-0rkAGjUf.mjs} +15 -11
- package/dist/{LexicalRichText.node-BKfaQ-CH.mjs → LexicalRichText.node-Cd-BySPE.mjs} +4 -4
- package/dist/{LexicalRichText.prod-SBewjJHx.mjs → LexicalRichText.prod-DTQiEr8C.mjs} +17 -11
- package/dist/{LexicalSelection.dev-D27JOCqj.mjs → LexicalSelection.dev-Bi0VlUEv.mjs} +28 -24
- package/dist/{LexicalSelection.node-DBEwPjBu.mjs → LexicalSelection.node-t2U46EF_.mjs} +1 -1
- package/dist/{LexicalSelection.prod-OaYhXHOL.mjs → LexicalSelection.prod-CrFG111g.mjs} +2 -2
- package/dist/{LexicalTable.dev-6IFFOAE0.mjs → LexicalTable.dev-D-sFhO-o.mjs} +33 -28
- package/dist/{LexicalTable.prod-2CaLZ7fH.mjs → LexicalTable.prod-DwYaa_dN.mjs} +10 -9
- package/dist/{LexicalUtils.dev-DJA7J_7v.mjs → LexicalUtils.dev-Q2q3-UDM.mjs} +8 -5
- package/dist/{LexicalUtils.node-Df9oPTlA.mjs → LexicalUtils.node-Dl7OvqJV.mjs} +1 -1
- package/dist/{LexicalUtils.prod-Bb7V4Ewg.mjs → LexicalUtils.prod-CBnq_iEV.mjs} +7 -6
- package/dist/bin/mxs.mjs +1 -1
- package/dist/esm-CNZ7kdTg.mjs +2 -0
- package/dist/{esm-DLzrv7gD.mjs → esm-ZXjJmLEC.mjs} +257 -260
- package/dist/index.mjs +1 -1
- package/dist/{mxs-BIRW5Axj.mjs → mxs-DC9zR3f2.mjs} +759 -539
- package/dist/{rolldown-runtime-JspESFgx.mjs → rolldown-runtime-B4iAMlE-.mjs} +1 -1
- package/dist/src/bin/mxs.d.ts +2 -0
- package/dist/src/bin/mxs.js +310 -0
- package/dist/src/cli/ai/_poll.d.ts +12 -0
- package/dist/src/cli/ai/_poll.js +38 -0
- package/dist/src/cli/ai/_resolve.d.ts +8 -0
- package/dist/src/cli/ai/_resolve.js +27 -0
- package/dist/src/cli/ai/index.d.ts +127 -0
- package/dist/src/cli/ai/index.js +46 -0
- package/dist/src/cli/ai/insights/by-article.d.ts +10 -0
- package/dist/src/cli/ai/insights/by-article.js +21 -0
- package/dist/src/cli/ai/insights/delete.d.ts +7 -0
- package/dist/src/cli/ai/insights/delete.js +18 -0
- package/dist/src/cli/ai/insights/edit.d.ts +8 -0
- package/dist/src/cli/ai/insights/edit.js +54 -0
- package/dist/src/cli/ai/insights/get.d.ts +6 -0
- package/dist/src/cli/ai/insights/get.js +11 -0
- package/dist/src/cli/ai/insights/index.d.ts +30 -0
- package/dist/src/cli/ai/insights/index.js +17 -0
- package/dist/src/cli/ai/insights/list.d.ts +10 -0
- package/dist/src/cli/ai/insights/list.js +20 -0
- package/dist/src/cli/ai/insights/refresh.d.ts +10 -0
- package/dist/src/cli/ai/insights/refresh.js +25 -0
- package/dist/src/cli/ai/insights/translate.d.ts +10 -0
- package/dist/src/cli/ai/insights/translate.js +25 -0
- package/dist/src/cli/ai/overview/by-article.d.ts +7 -0
- package/dist/src/cli/ai/overview/by-article.js +15 -0
- package/dist/src/cli/ai/overview/index.d.ts +11 -0
- package/dist/src/cli/ai/overview/index.js +4 -0
- package/dist/src/cli/ai/overview/list.d.ts +10 -0
- package/dist/src/cli/ai/overview/list.js +20 -0
- package/dist/src/cli/ai/summary/by-article.d.ts +10 -0
- package/dist/src/cli/ai/summary/by-article.js +21 -0
- package/dist/src/cli/ai/summary/delete.d.ts +7 -0
- package/dist/src/cli/ai/summary/delete.js +18 -0
- package/dist/src/cli/ai/summary/edit.d.ts +8 -0
- package/dist/src/cli/ai/summary/edit.js +54 -0
- package/dist/src/cli/ai/summary/get.d.ts +6 -0
- package/dist/src/cli/ai/summary/get.js +11 -0
- package/dist/src/cli/ai/summary/index.d.ts +30 -0
- package/dist/src/cli/ai/summary/index.js +9 -0
- package/dist/src/cli/ai/summary/list.d.ts +10 -0
- package/dist/src/cli/ai/summary/list.js +20 -0
- package/dist/src/cli/ai/summary/regen.d.ts +10 -0
- package/dist/src/cli/ai/summary/regen.js +25 -0
- package/dist/src/cli/ai/summary/translate.d.ts +10 -0
- package/dist/src/cli/ai/summary/translate.js +25 -0
- package/dist/src/cli/ai/translate/by-article.d.ts +9 -0
- package/dist/src/cli/ai/translate/by-article.js +19 -0
- package/dist/src/cli/ai/translate/delete.d.ts +7 -0
- package/dist/src/cli/ai/translate/delete.js +18 -0
- package/dist/src/cli/ai/translate/edit.d.ts +8 -0
- package/dist/src/cli/ai/translate/edit.js +97 -0
- package/dist/src/cli/ai/translate/entries/delete.d.ts +7 -0
- package/dist/src/cli/ai/translate/entries/delete.js +18 -0
- package/dist/src/cli/ai/translate/entries/edit.d.ts +8 -0
- package/dist/src/cli/ai/translate/entries/edit.js +73 -0
- package/dist/src/cli/ai/translate/entries/generate.d.ts +7 -0
- package/dist/src/cli/ai/translate/entries/generate.js +15 -0
- package/dist/src/cli/ai/translate/entries/index.d.ts +17 -0
- package/dist/src/cli/ai/translate/entries/index.js +6 -0
- package/dist/src/cli/ai/translate/entries/list.d.ts +10 -0
- package/dist/src/cli/ai/translate/entries/list.js +20 -0
- package/dist/src/cli/ai/translate/get.d.ts +6 -0
- package/dist/src/cli/ai/translate/get.js +11 -0
- package/dist/src/cli/ai/translate/index.d.ts +40 -0
- package/dist/src/cli/ai/translate/index.js +19 -0
- package/dist/src/cli/ai/translate/languages.d.ts +7 -0
- package/dist/src/cli/ai/translate/languages.js +15 -0
- package/dist/src/cli/ai/translate/list.d.ts +9 -0
- package/dist/src/cli/ai/translate/list.js +19 -0
- package/dist/src/cli/ai/translate/run.d.ts +10 -0
- package/dist/src/cli/ai/translate/run.js +31 -0
- package/dist/src/cli/ai/tts/by-article.d.ts +7 -0
- package/dist/src/cli/ai/tts/by-article.js +15 -0
- package/dist/src/cli/ai/tts/delete.d.ts +7 -0
- package/dist/src/cli/ai/tts/delete.js +18 -0
- package/dist/src/cli/ai/tts/index.d.ts +22 -0
- package/dist/src/cli/ai/tts/index.js +7 -0
- package/dist/src/cli/ai/tts/list.d.ts +10 -0
- package/dist/src/cli/ai/tts/list.js +20 -0
- package/dist/src/cli/ai/tts/run.d.ts +10 -0
- package/dist/src/cli/ai/tts/run.js +25 -0
- package/dist/src/cli/ai/tts/voices.d.ts +7 -0
- package/dist/src/cli/ai/tts/voices.js +12 -0
- package/dist/src/cli/ai/views.d.ts +3 -0
- package/dist/src/cli/ai/views.js +45 -0
- package/dist/src/cli/auth/index.d.ts +6 -0
- package/dist/src/cli/auth/index.js +22 -0
- package/dist/src/cli/auth/login.d.ts +11 -0
- package/dist/src/cli/auth/login.js +168 -0
- package/dist/src/cli/auth/logout.d.ts +6 -0
- package/dist/src/cli/auth/logout.js +21 -0
- package/dist/src/cli/auth/status.d.ts +4 -0
- package/dist/src/cli/auth/status.js +31 -0
- package/dist/src/cli/auth/view.d.ts +25 -0
- package/dist/src/cli/auth/view.js +46 -0
- package/dist/src/cli/auth/whoami.d.ts +7 -0
- package/dist/src/cli/auth/whoami.js +44 -0
- package/dist/src/cli/category/create.d.ts +10 -0
- package/dist/src/cli/category/create.js +24 -0
- package/dist/src/cli/category/delete.d.ts +8 -0
- package/dist/src/cli/category/delete.js +21 -0
- package/dist/src/cli/category/get.d.ts +6 -0
- package/dist/src/cli/category/get.js +11 -0
- package/dist/src/cli/category/index.d.ts +20 -0
- package/dist/src/cli/category/index.js +41 -0
- package/dist/src/cli/category/list.d.ts +4 -0
- package/dist/src/cli/category/list.js +10 -0
- package/dist/src/cli/category/update.d.ts +12 -0
- package/dist/src/cli/category/update.js +34 -0
- package/dist/src/cli/comment/_flags.d.ts +28 -0
- package/dist/src/cli/comment/_flags.js +48 -0
- package/dist/src/cli/comment/approve.d.ts +9 -0
- package/dist/src/cli/comment/approve.js +23 -0
- package/dist/src/cli/comment/delete.d.ts +9 -0
- package/dist/src/cli/comment/delete.js +24 -0
- package/dist/src/cli/comment/get.d.ts +6 -0
- package/dist/src/cli/comment/get.js +12 -0
- package/dist/src/cli/comment/index.d.ts +34 -0
- package/dist/src/cli/comment/index.js +53 -0
- package/dist/src/cli/comment/list.d.ts +9 -0
- package/dist/src/cli/comment/list.js +20 -0
- package/dist/src/cli/comment/reject.d.ts +9 -0
- package/dist/src/cli/comment/reject.js +23 -0
- package/dist/src/cli/comment/reply.d.ts +9 -0
- package/dist/src/cli/comment/reply.js +31 -0
- package/dist/src/cli/comment/unread.d.ts +7 -0
- package/dist/src/cli/comment/unread.js +21 -0
- package/dist/src/cli/comment/view.d.ts +3 -0
- package/dist/src/cli/comment/view.js +197 -0
- package/dist/src/cli/config/edit.d.ts +5 -0
- package/dist/src/cli/config/edit.js +36 -0
- package/dist/src/cli/config/get.d.ts +6 -0
- package/dist/src/cli/config/get.js +11 -0
- package/dist/src/cli/config/index.d.ts +10 -0
- package/dist/src/cli/config/index.js +22 -0
- package/dist/src/cli/config/list.d.ts +4 -0
- package/dist/src/cli/config/list.js +10 -0
- package/dist/src/cli/config/set.d.ts +9 -0
- package/dist/src/cli/config/set.js +48 -0
- package/dist/src/cli/draft/_shared.d.ts +27 -0
- package/dist/src/cli/draft/_shared.js +85 -0
- package/dist/src/cli/draft/create.d.ts +21 -0
- package/dist/src/cli/draft/create.js +34 -0
- package/dist/src/cli/draft/delete.d.ts +7 -0
- package/dist/src/cli/draft/delete.js +20 -0
- package/dist/src/cli/draft/get.d.ts +6 -0
- package/dist/src/cli/draft/get.js +11 -0
- package/dist/src/cli/draft/index.d.ts +54 -0
- package/dist/src/cli/draft/index.js +42 -0
- package/dist/src/cli/draft/list.d.ts +11 -0
- package/dist/src/cli/draft/list.js +23 -0
- package/dist/src/cli/draft/publish.d.ts +8 -0
- package/dist/src/cli/draft/publish.js +64 -0
- package/dist/src/cli/draft/update.d.ts +22 -0
- package/dist/src/cli/draft/update.js +29 -0
- package/dist/src/cli/file/_shared.d.ts +6 -0
- package/dist/src/cli/file/_shared.js +5 -0
- package/dist/src/cli/file/delete.d.ts +8 -0
- package/dist/src/cli/file/delete.js +21 -0
- package/dist/src/cli/file/index.d.ts +19 -0
- package/dist/src/cli/file/index.js +33 -0
- package/dist/src/cli/file/list.d.ts +6 -0
- package/dist/src/cli/file/list.js +11 -0
- package/dist/src/cli/file/rename.d.ts +8 -0
- package/dist/src/cli/file/rename.js +16 -0
- package/dist/src/cli/file/upload.d.ts +9 -0
- package/dist/src/cli/file/upload.js +32 -0
- package/dist/src/cli/help/index.d.ts +62 -0
- package/dist/src/cli/help/index.js +276 -0
- package/dist/src/cli/help/registry.d.ts +28 -0
- package/dist/src/cli/help/registry.js +29 -0
- package/dist/src/cli/note/_flags.d.ts +66 -0
- package/dist/src/cli/note/_flags.js +73 -0
- package/dist/src/cli/note/create.d.ts +23 -0
- package/dist/src/cli/note/create.js +25 -0
- package/dist/src/cli/note/delete.d.ts +8 -0
- package/dist/src/cli/note/delete.js +21 -0
- package/dist/src/cli/note/edit.d.ts +28 -0
- package/dist/src/cli/note/edit.js +114 -0
- package/dist/src/cli/note/get.d.ts +6 -0
- package/dist/src/cli/note/get.js +29 -0
- package/dist/src/cli/note/index.d.ts +77 -0
- package/dist/src/cli/note/index.js +63 -0
- package/dist/src/cli/note/list.d.ts +10 -0
- package/dist/src/cli/note/list.js +22 -0
- package/dist/src/cli/note/publish.d.ts +7 -0
- package/dist/src/cli/note/publish.js +17 -0
- package/dist/src/cli/note/unpublish.d.ts +7 -0
- package/dist/src/cli/note/unpublish.js +17 -0
- package/dist/src/cli/note/update.d.ts +25 -0
- package/dist/src/cli/note/update.js +36 -0
- package/dist/src/cli/note/view.d.ts +3 -0
- package/dist/src/cli/note/view.js +162 -0
- package/dist/src/cli/page/create.d.ts +41 -0
- package/dist/src/cli/page/create.js +56 -0
- package/dist/src/cli/page/delete.d.ts +7 -0
- package/dist/src/cli/page/delete.js +37 -0
- package/dist/src/cli/page/edit.d.ts +19 -0
- package/dist/src/cli/page/edit.js +117 -0
- package/dist/src/cli/page/get.d.ts +6 -0
- package/dist/src/cli/page/get.js +16 -0
- package/dist/src/cli/page/index.d.ts +44 -0
- package/dist/src/cli/page/index.js +38 -0
- package/dist/src/cli/page/list.d.ts +4 -0
- package/dist/src/cli/page/list.js +10 -0
- package/dist/src/cli/page/update.d.ts +16 -0
- package/dist/src/cli/page/update.js +48 -0
- package/dist/src/cli/page/view.d.ts +2 -0
- package/dist/src/cli/page/view.js +79 -0
- package/dist/src/cli/post/_flags.d.ts +66 -0
- package/dist/src/cli/post/_flags.js +96 -0
- package/dist/src/cli/post/apply.d.ts +7 -0
- package/dist/src/cli/post/apply.js +70 -0
- package/dist/src/cli/post/create.d.ts +21 -0
- package/dist/src/cli/post/create.js +24 -0
- package/dist/src/cli/post/delete.d.ts +8 -0
- package/dist/src/cli/post/delete.js +21 -0
- package/dist/src/cli/post/edit.d.ts +26 -0
- package/dist/src/cli/post/edit.js +115 -0
- package/dist/src/cli/post/get.d.ts +7 -0
- package/dist/src/cli/post/get.js +15 -0
- package/dist/src/cli/post/index.d.ts +91 -0
- package/dist/src/cli/post/index.js +73 -0
- package/dist/src/cli/post/list.d.ts +10 -0
- package/dist/src/cli/post/list.js +23 -0
- package/dist/src/cli/post/publish.d.ts +7 -0
- package/dist/src/cli/post/publish.js +17 -0
- package/dist/src/cli/post/stage.d.ts +23 -0
- package/dist/src/cli/post/stage.js +55 -0
- package/dist/src/cli/post/unpublish.d.ts +7 -0
- package/dist/src/cli/post/unpublish.js +17 -0
- package/dist/src/cli/post/update.d.ts +23 -0
- package/dist/src/cli/post/update.js +38 -0
- package/dist/src/cli/post/view.d.ts +3 -0
- package/dist/src/cli/post/view.js +150 -0
- package/dist/src/cli/preview/index.d.ts +13 -0
- package/dist/src/cli/preview/index.js +226 -0
- package/dist/src/cli/profile/index.d.ts +14 -0
- package/dist/src/cli/profile/index.js +36 -0
- package/dist/src/cli/profile/ls.d.ts +5 -0
- package/dist/src/cli/profile/ls.js +26 -0
- package/dist/src/cli/profile/mark.d.ts +9 -0
- package/dist/src/cli/profile/mark.js +23 -0
- package/dist/src/cli/profile/rm.d.ts +12 -0
- package/dist/src/cli/profile/rm.js +50 -0
- package/dist/src/cli/profile/show.d.ts +9 -0
- package/dist/src/cli/profile/show.js +40 -0
- package/dist/src/cli/profile/use.d.ts +6 -0
- package/dist/src/cli/profile/use.js +11 -0
- package/dist/src/cli/profile/view.d.ts +8 -0
- package/dist/src/cli/profile/view.js +21 -0
- package/dist/src/cli/project/_flags.d.ts +56 -0
- package/dist/src/cli/project/_flags.js +130 -0
- package/dist/src/cli/project/create.d.ts +17 -0
- package/dist/src/cli/project/create.js +25 -0
- package/dist/src/cli/project/delete.d.ts +8 -0
- package/dist/src/cli/project/delete.js +22 -0
- package/dist/src/cli/project/edit.d.ts +11 -0
- package/dist/src/cli/project/edit.js +61 -0
- package/dist/src/cli/project/get.d.ts +7 -0
- package/dist/src/cli/project/get.js +14 -0
- package/dist/src/cli/project/index.d.ts +43 -0
- package/dist/src/cli/project/index.js +52 -0
- package/dist/src/cli/project/list.d.ts +8 -0
- package/dist/src/cli/project/list.js +19 -0
- package/dist/src/cli/project/update.d.ts +18 -0
- package/dist/src/cli/project/update.js +24 -0
- package/dist/src/cli/project/view-cmd.d.ts +7 -0
- package/dist/src/cli/project/view-cmd.js +15 -0
- package/dist/src/cli/project/view.d.ts +3 -0
- package/dist/src/cli/project/view.js +102 -0
- package/dist/src/cli/render/codehighlight.d.ts +8 -0
- package/dist/src/cli/render/codehighlight.js +264 -0
- package/dist/src/cli/render/envelope.d.ts +7 -0
- package/dist/src/cli/render/envelope.js +23 -0
- package/dist/src/cli/render/frontmatter.d.ts +8 -0
- package/dist/src/cli/render/frontmatter.js +50 -0
- package/dist/src/cli/render/helpers.d.ts +2 -0
- package/dist/src/cli/render/helpers.js +11 -0
- package/dist/src/cli/render/index.d.ts +7 -0
- package/dist/src/cli/render/index.js +10 -0
- package/dist/src/cli/render/lexical/blocks.d.ts +19 -0
- package/dist/src/cli/render/lexical/blocks.js +208 -0
- package/dist/src/cli/render/lexical/code.d.ts +2 -0
- package/dist/src/cli/render/lexical/code.js +22 -0
- package/dist/src/cli/render/lexical/embeds.d.ts +6 -0
- package/dist/src/cli/render/lexical/embeds.js +51 -0
- package/dist/src/cli/render/lexical/index.d.ts +9 -0
- package/dist/src/cli/render/lexical/index.js +25 -0
- package/dist/src/cli/render/lexical/inlines.d.ts +17 -0
- package/dist/src/cli/render/lexical/inlines.js +76 -0
- package/dist/src/cli/render/lexical/parser.d.ts +10 -0
- package/dist/src/cli/render/lexical/parser.js +64 -0
- package/dist/src/cli/render/lexical/walker.d.ts +21 -0
- package/dist/src/cli/render/lexical/walker.js +51 -0
- package/dist/src/cli/render/markdown.d.ts +18 -0
- package/dist/src/cli/render/markdown.js +196 -0
- package/dist/src/cli/render/metadata-block.d.ts +14 -0
- package/dist/src/cli/render/metadata-block.js +50 -0
- package/dist/src/cli/skill/all.d.ts +4 -0
- package/dist/src/cli/skill/all.js +11 -0
- package/dist/src/cli/skill/get.d.ts +6 -0
- package/dist/src/cli/skill/get.js +12 -0
- package/dist/src/cli/skill/index.d.ts +10 -0
- package/dist/src/cli/skill/index.js +34 -0
- package/dist/src/cli/skill/list.d.ts +4 -0
- package/dist/src/cli/skill/list.js +11 -0
- package/dist/src/cli/skill/search.d.ts +6 -0
- package/dist/src/cli/skill/search.js +12 -0
- package/dist/src/cli/skill/views.d.ts +6 -0
- package/dist/src/cli/skill/views.js +90 -0
- package/dist/src/cli/snippet/_flags.d.ts +57 -0
- package/dist/src/cli/snippet/_flags.js +123 -0
- package/dist/src/cli/snippet/_resolve.d.ts +4 -0
- package/dist/src/cli/snippet/_resolve.js +32 -0
- package/dist/src/cli/snippet/_sync.d.ts +5 -0
- package/dist/src/cli/snippet/_sync.js +54 -0
- package/dist/src/cli/snippet/create.d.ts +19 -0
- package/dist/src/cli/snippet/create.js +35 -0
- package/dist/src/cli/snippet/delete.d.ts +8 -0
- package/dist/src/cli/snippet/delete.js +28 -0
- package/dist/src/cli/snippet/edit.d.ts +7 -0
- package/dist/src/cli/snippet/edit.js +29 -0
- package/dist/src/cli/snippet/get.d.ts +6 -0
- package/dist/src/cli/snippet/get.js +12 -0
- package/dist/src/cli/snippet/index.d.ts +43 -0
- package/dist/src/cli/snippet/index.js +58 -0
- package/dist/src/cli/snippet/list.d.ts +9 -0
- package/dist/src/cli/snippet/list.js +20 -0
- package/dist/src/cli/snippet/pull.d.ts +8 -0
- package/dist/src/cli/snippet/pull.js +33 -0
- package/dist/src/cli/snippet/push.d.ts +10 -0
- package/dist/src/cli/snippet/push.js +31 -0
- package/dist/src/cli/snippet/update.d.ts +8 -0
- package/dist/src/cli/snippet/update.js +16 -0
- package/dist/src/cli/topic/create.d.ts +10 -0
- package/dist/src/cli/topic/create.js +24 -0
- package/dist/src/cli/topic/delete.d.ts +7 -0
- package/dist/src/cli/topic/delete.js +37 -0
- package/dist/src/cli/topic/get.d.ts +6 -0
- package/dist/src/cli/topic/get.js +15 -0
- package/dist/src/cli/topic/index.d.ts +20 -0
- package/dist/src/cli/topic/index.js +32 -0
- package/dist/src/cli/topic/list.d.ts +4 -0
- package/dist/src/cli/topic/list.js +10 -0
- package/dist/src/cli/topic/update.d.ts +11 -0
- package/dist/src/cli/topic/update.js +51 -0
- package/dist/src/cli/ui/index.d.ts +24 -0
- package/dist/src/cli/ui/index.js +83 -0
- package/dist/src/cli/update/index.d.ts +10 -0
- package/dist/src/cli/update/index.js +142 -0
- package/dist/src/domain/admin-link.d.ts +12 -0
- package/dist/src/domain/admin-link.js +45 -0
- package/dist/src/domain/content-spec.d.ts +20 -0
- package/dist/src/domain/content-spec.js +78 -0
- package/dist/src/domain/envelope-compat.d.ts +68 -0
- package/dist/src/domain/envelope-compat.js +121 -0
- package/dist/src/domain/envelope.d.ts +34 -0
- package/dist/src/domain/envelope.js +355 -0
- package/dist/src/domain/errors.d.ts +336 -0
- package/dist/src/domain/errors.js +239 -0
- package/dist/src/domain/gate.d.ts +14 -0
- package/dist/src/domain/gate.js +18 -0
- package/dist/src/domain/payload.d.ts +64 -0
- package/dist/src/domain/payload.js +237 -0
- package/dist/src/domain/preflight-guards.d.ts +54 -0
- package/dist/src/domain/preflight-guards.js +130 -0
- package/dist/src/domain/runtime-flags.d.ts +33 -0
- package/dist/src/domain/runtime-flags.js +166 -0
- package/dist/src/domain/schema/api-envelope.d.ts +67 -0
- package/dist/src/domain/schema/api-envelope.js +65 -0
- package/dist/src/domain/schema/category.d.ts +23 -0
- package/dist/src/domain/schema/category.js +19 -0
- package/dist/src/domain/schema/config.d.ts +13 -0
- package/dist/src/domain/schema/config.js +18 -0
- package/dist/src/domain/schema/note.d.ts +76 -0
- package/dist/src/domain/schema/note.js +35 -0
- package/dist/src/domain/schema/page.d.ts +40 -0
- package/dist/src/domain/schema/page.js +22 -0
- package/dist/src/domain/schema/post.d.ts +68 -0
- package/dist/src/domain/schema/post.js +35 -0
- package/dist/src/domain/schema/profile.d.ts +14 -0
- package/dist/src/domain/schema/profile.js +22 -0
- package/dist/src/domain/schema/topic.d.ts +24 -0
- package/dist/src/domain/schema/topic.js +16 -0
- package/dist/src/domain/version.d.ts +15 -0
- package/dist/src/domain/version.js +43 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.js +8 -0
- package/dist/src/layers/App.d.ts +30 -0
- package/dist/src/layers/App.js +39 -0
- package/dist/src/services/Ai/index.d.ts +13 -0
- package/dist/src/services/Ai/index.js +127 -0
- package/dist/src/services/Ai/overview.d.ts +7 -0
- package/dist/src/services/Ai/overview.js +11 -0
- package/dist/src/services/Ai/resources.d.ts +7 -0
- package/dist/src/services/Ai/resources.js +59 -0
- package/dist/src/services/Ai/shared.d.ts +2 -0
- package/dist/src/services/Ai/shared.js +11 -0
- package/dist/src/services/Ai/tasks.d.ts +8 -0
- package/dist/src/services/Ai/tasks.js +144 -0
- package/dist/src/services/Ai/types.d.ts +130 -0
- package/dist/src/services/Ai/types.js +1 -0
- package/dist/src/services/Api.d.ts +67 -0
- package/dist/src/services/Api.js +348 -0
- package/dist/src/services/Auth.d.ts +101 -0
- package/dist/src/services/Auth.js +402 -0
- package/dist/src/services/Backup.d.ts +8 -0
- package/dist/src/services/Backup.js +4 -0
- package/dist/src/services/Cache.d.ts +8 -0
- package/dist/src/services/Cache.js +4 -0
- package/dist/src/services/Comment.d.ts +48 -0
- package/dist/src/services/Comment.js +102 -0
- package/dist/src/services/Config.d.ts +95 -0
- package/dist/src/services/Config.js +359 -0
- package/dist/src/services/Editor.d.ts +28 -0
- package/dist/src/services/Editor.js +95 -0
- package/dist/src/services/Lexical.d.ts +27 -0
- package/dist/src/services/Lexical.js +56 -0
- package/dist/src/services/Migration.d.ts +31 -0
- package/dist/src/services/Migration.js +177 -0
- package/dist/src/services/Profile.d.ts +29 -0
- package/dist/src/services/Profile.js +115 -0
- package/dist/src/services/Renderer/content.d.ts +16 -0
- package/dist/src/services/Renderer/content.js +110 -0
- package/dist/src/services/Renderer/datetime.d.ts +38 -0
- package/dist/src/services/Renderer/datetime.js +147 -0
- package/dist/src/services/Renderer/errors.d.ts +3 -0
- package/dist/src/services/Renderer/errors.js +59 -0
- package/dist/src/services/Renderer/index.d.ts +13 -0
- package/dist/src/services/Renderer/index.js +11 -0
- package/dist/src/services/Renderer/lists.d.ts +1 -0
- package/dist/src/services/Renderer/lists.js +101 -0
- package/dist/src/services/Renderer/options.d.ts +10 -0
- package/dist/src/services/Renderer/options.js +13 -0
- package/dist/src/services/Renderer/primitives.d.ts +4 -0
- package/dist/src/services/Renderer/primitives.js +12 -0
- package/dist/src/services/Renderer/service.d.ts +35 -0
- package/dist/src/services/Renderer/service.js +123 -0
- package/dist/src/services/Renderer/view.d.ts +16 -0
- package/dist/src/services/Renderer/view.js +1 -0
- package/dist/src/services/Resolver.d.ts +47 -0
- package/dist/src/services/Resolver.js +269 -0
- package/dist/src/services/Skill.d.ts +29 -0
- package/dist/src/services/Skill.js +421 -0
- package/dist/src/services/UpdateNotifier.d.ts +162 -0
- package/dist/src/services/UpdateNotifier.js +572 -0
- package/dist/test/cli/ai/ai.test.d.ts +1 -0
- package/dist/test/cli/ai/ai.test.js +507 -0
- package/dist/test/cli/ai/verbs.test.d.ts +1 -0
- package/dist/test/cli/ai/verbs.test.js +235 -0
- package/dist/test/cli/auth/login.test.d.ts +1 -0
- package/dist/test/cli/auth/login.test.js +236 -0
- package/dist/test/cli/auth/logout-whoami.test.d.ts +1 -0
- package/dist/test/cli/auth/logout-whoami.test.js +124 -0
- package/dist/test/cli/auth/status.test.d.ts +1 -0
- package/dist/test/cli/auth/status.test.js +90 -0
- package/dist/test/cli/category/category.test.d.ts +1 -0
- package/dist/test/cli/category/category.test.js +175 -0
- package/dist/test/cli/comment/comment.test.d.ts +1 -0
- package/dist/test/cli/comment/comment.test.js +445 -0
- package/dist/test/cli/config/config.test.d.ts +1 -0
- package/dist/test/cli/config/config.test.js +281 -0
- package/dist/test/cli/edit-roundtrip.test.d.ts +1 -0
- package/dist/test/cli/edit-roundtrip.test.js +259 -0
- package/dist/test/cli/file/file.test.d.ts +1 -0
- package/dist/test/cli/file/file.test.js +185 -0
- package/dist/test/cli/help.test.d.ts +1 -0
- package/dist/test/cli/help.test.js +289 -0
- package/dist/test/cli/note/create.test.d.ts +1 -0
- package/dist/test/cli/note/create.test.js +155 -0
- package/dist/test/cli/note/list.test.d.ts +1 -0
- package/dist/test/cli/note/list.test.js +115 -0
- package/dist/test/cli/note/publish.test.d.ts +1 -0
- package/dist/test/cli/note/publish.test.js +123 -0
- package/dist/test/cli/page/page.test.d.ts +1 -0
- package/dist/test/cli/page/page.test.js +185 -0
- package/dist/test/cli/post/create.test.d.ts +1 -0
- package/dist/test/cli/post/create.test.js +172 -0
- package/dist/test/cli/post/list.test.d.ts +1 -0
- package/dist/test/cli/post/list.test.js +133 -0
- package/dist/test/cli/post/publish.test.d.ts +1 -0
- package/dist/test/cli/post/publish.test.js +139 -0
- package/dist/test/cli/post/stage-apply.test.d.ts +1 -0
- package/dist/test/cli/post/stage-apply.test.js +215 -0
- package/dist/test/cli/post/update.test.d.ts +1 -0
- package/dist/test/cli/post/update.test.js +160 -0
- package/dist/test/cli/post-note-crud.test.d.ts +1 -0
- package/dist/test/cli/post-note-crud.test.js +362 -0
- package/dist/test/cli/profile/ls.test.d.ts +1 -0
- package/dist/test/cli/profile/ls.test.js +93 -0
- package/dist/test/cli/profile/mark-use.test.d.ts +1 -0
- package/dist/test/cli/profile/mark-use.test.js +216 -0
- package/dist/test/cli/project-crud.test.d.ts +1 -0
- package/dist/test/cli/project-crud.test.js +315 -0
- package/dist/test/cli/render/lexical.test.d.ts +1 -0
- package/dist/test/cli/render/lexical.test.js +216 -0
- package/dist/test/cli/render/markdown.test.d.ts +1 -0
- package/dist/test/cli/render/markdown.test.js +39 -0
- package/dist/test/cli/snippet-crud.test.d.ts +1 -0
- package/dist/test/cli/snippet-crud.test.js +293 -0
- package/dist/test/cli/topic/topic.test.d.ts +1 -0
- package/dist/test/cli/topic/topic.test.js +181 -0
- package/dist/test/cli/update.test.d.ts +1 -0
- package/dist/test/cli/update.test.js +395 -0
- package/dist/test/domain/content-spec.test.d.ts +1 -0
- package/dist/test/domain/content-spec.test.js +126 -0
- package/dist/test/domain/envelope-compat.test.d.ts +1 -0
- package/dist/test/domain/envelope-compat.test.js +126 -0
- package/dist/test/domain/envelope.test.d.ts +1 -0
- package/dist/test/domain/envelope.test.js +149 -0
- package/dist/test/domain/errors.test.d.ts +1 -0
- package/dist/test/domain/errors.test.js +127 -0
- package/dist/test/domain/gate.test.d.ts +1 -0
- package/dist/test/domain/gate.test.js +128 -0
- package/dist/test/domain/payload.test.d.ts +1 -0
- package/dist/test/domain/payload.test.js +259 -0
- package/dist/test/helper/test-fs.d.ts +24 -0
- package/dist/test/helper/test-fs.js +161 -0
- package/dist/test/helper/test-http.d.ts +31 -0
- package/dist/test/helper/test-http.js +66 -0
- package/dist/test/integration/_helpers.d.ts +5 -0
- package/dist/test/integration/_helpers.js +24 -0
- package/dist/test/integration/cli-error-envelope.test.d.ts +1 -0
- package/dist/test/integration/cli-error-envelope.test.js +137 -0
- package/dist/test/integration/cli-help-render.test.d.ts +1 -0
- package/dist/test/integration/cli-help-render.test.js +149 -0
- package/dist/test/integration/cli-help.test.d.ts +1 -0
- package/dist/test/integration/cli-help.test.js +67 -0
- package/dist/test/integration/cli-post-list.test.d.ts +1 -0
- package/dist/test/integration/cli-post-list.test.js +140 -0
- package/dist/test/integration/cli-skill.test.d.ts +1 -0
- package/dist/test/integration/cli-skill.test.js +74 -0
- package/dist/test/integration/cli-version.test.d.ts +1 -0
- package/dist/test/integration/cli-version.test.js +37 -0
- package/dist/test/services/Api.test.d.ts +1 -0
- package/dist/test/services/Api.test.js +553 -0
- package/dist/test/services/Auth.test.d.ts +1 -0
- package/dist/test/services/Auth.test.js +650 -0
- package/dist/test/services/Config.test.d.ts +1 -0
- package/dist/test/services/Config.test.js +510 -0
- package/dist/test/services/Datetime.test.d.ts +1 -0
- package/dist/test/services/Datetime.test.js +113 -0
- package/dist/test/services/Editor.test.d.ts +1 -0
- package/dist/test/services/Editor.test.js +205 -0
- package/dist/test/services/Lexical.errors.test.d.ts +1 -0
- package/dist/test/services/Lexical.errors.test.js +60 -0
- package/dist/test/services/Lexical.test.d.ts +1 -0
- package/dist/test/services/Lexical.test.js +68 -0
- package/dist/test/services/Migration.test.d.ts +1 -0
- package/dist/test/services/Migration.test.js +376 -0
- package/dist/test/services/Profile.test.d.ts +1 -0
- package/dist/test/services/Profile.test.js +277 -0
- package/dist/test/services/Renderer.test.d.ts +1 -0
- package/dist/test/services/Renderer.test.js +538 -0
- package/dist/test/services/Resolver.test.d.ts +1 -0
- package/dist/test/services/Resolver.test.js +320 -0
- package/dist/test/services/Skill.test.d.ts +1 -0
- package/dist/test/services/Skill.test.js +261 -0
- package/dist/test/services/UpdateNotifier.spawn.test.d.ts +1 -0
- package/dist/test/services/UpdateNotifier.spawn.test.js +73 -0
- package/dist/test/services/UpdateNotifier.test.d.ts +1 -0
- package/dist/test/services/UpdateNotifier.test.js +912 -0
- package/dist/vendor/litexml/cli.mjs +19 -4
- package/dist/vendor/litexml/litexml-html-preview-client.css +98 -13
- package/dist/vendor/litexml/litexml-html-preview-client.js +5794 -4976
- package/dist/vendor/litexml/style.css +5 -5
- package/package.json +29 -26
- package/skills/safety.md +1 -1
- package/LICENSE +0 -33
- package/dist/esm-CDcJmHkG.mjs +0 -2
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
import { HttpClient, HttpClientRequest } from '@effect/platform';
|
|
2
|
+
import { Context, Effect, Layer, Ref } from 'effect';
|
|
3
|
+
import { detectWireVersion, normalizeErrorBody, normalizeSuccessBody, } from '../domain/envelope-compat';
|
|
4
|
+
import { AuthDenied, AuthExpired, Generic, NetworkDns, NetworkRefused, NetworkTimeout, ResourceNotFound, ServerError, ValidationFailed, WriteRequiresExplicit, } from '../domain/errors';
|
|
5
|
+
import { decideWriteGate, } from '../domain/gate';
|
|
6
|
+
import { USER_AGENT } from '../domain/version';
|
|
7
|
+
import { Auth } from './Auth';
|
|
8
|
+
import { Config } from './Config';
|
|
9
|
+
export class Api extends Context.Tag('Api')() {
|
|
10
|
+
/**
|
|
11
|
+
* Default Layer: no overrides, banner + verbose enabled per env / config.
|
|
12
|
+
* Wave 2 entry-point (`bin/mxs.ts`) should use `Api.layer({...})` to wire
|
|
13
|
+
* flag-derived overrides through.
|
|
14
|
+
*/
|
|
15
|
+
static Default = Api.layer({});
|
|
16
|
+
/** Build an Api Layer with command-specified overrides + UX flags. */
|
|
17
|
+
static layer(opts) {
|
|
18
|
+
return Layer.effect(Api, Effect.gen(function* () {
|
|
19
|
+
const http = yield* HttpClient.HttpClient;
|
|
20
|
+
const config = yield* Config;
|
|
21
|
+
const auth = yield* Auth;
|
|
22
|
+
return yield* makeApiService(http, config, auth, opts);
|
|
23
|
+
}));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// Internal: construct an `ApiService` given resolved deps.
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
function makeApiService(http, config, auth, opts) {
|
|
30
|
+
return Effect.gen(function* () {
|
|
31
|
+
const bannerEmitted = yield* Ref.make(false);
|
|
32
|
+
// COMPAT:envelope — diagnostic-only cache of the detected wire version.
|
|
33
|
+
// Used to enrich the `--verbose` log line. Drop with envelope-compat.ts.
|
|
34
|
+
const detectedWire = yield* Ref.make(null);
|
|
35
|
+
/**
|
|
36
|
+
* Resolved config is cached per `ApiService` instance. This matches
|
|
37
|
+
* today's `ApiClient` which is constructed once per command run.
|
|
38
|
+
*/
|
|
39
|
+
const resolvedEffect = config.resolve(opts.overrides).pipe(Effect.mapError((err) => err._tag === 'Generic'
|
|
40
|
+
? err
|
|
41
|
+
: new Generic({
|
|
42
|
+
message: 'failed to resolve config',
|
|
43
|
+
cause: err,
|
|
44
|
+
})));
|
|
45
|
+
const maybeEmitBanner = (resolved) => Effect.gen(function* () {
|
|
46
|
+
if (!resolved.isProduction || opts.quiet)
|
|
47
|
+
return;
|
|
48
|
+
const already = yield* Ref.get(bannerEmitted);
|
|
49
|
+
if (already)
|
|
50
|
+
return;
|
|
51
|
+
yield* Ref.set(bannerEmitted, true);
|
|
52
|
+
yield* Effect.sync(() => {
|
|
53
|
+
process.stderr.write(`mxs: profile=${resolved.profileName} (production) → ${resolved.apiUrl}\n`);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
const request = (path, options = {}) => Effect.gen(function* () {
|
|
57
|
+
const resolved = yield* resolvedEffect;
|
|
58
|
+
yield* maybeEmitBanner(resolved);
|
|
59
|
+
const method = (options.method ?? 'GET');
|
|
60
|
+
// ---- 1. write-gate (pure decision; runs BEFORE network) ---------
|
|
61
|
+
const gateInput = {
|
|
62
|
+
apiUrl: resolved.apiUrl,
|
|
63
|
+
profileName: resolved.profileName,
|
|
64
|
+
isProduction: resolved.isProduction,
|
|
65
|
+
profileExplicit: resolved.profileExplicit,
|
|
66
|
+
urlOverridden: resolved.urlOverridden,
|
|
67
|
+
};
|
|
68
|
+
const decision = decideWriteGate(gateInput, method);
|
|
69
|
+
if (!decision.allow) {
|
|
70
|
+
return yield* Effect.fail(new WriteRequiresExplicit({
|
|
71
|
+
message: decision.message,
|
|
72
|
+
hint: decision.hint,
|
|
73
|
+
profile: resolved.profileName ?? undefined,
|
|
74
|
+
apiUrl: resolved.apiUrl,
|
|
75
|
+
details: {
|
|
76
|
+
profile: resolved.profileName,
|
|
77
|
+
api_url: resolved.apiUrl,
|
|
78
|
+
},
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
// ---- 1b. --dry-run short-circuit (writes only; reads pass through)
|
|
82
|
+
if (opts.dryRun && method !== 'GET') {
|
|
83
|
+
if (opts.verbose && !opts.quiet) {
|
|
84
|
+
process.stderr.write(`mxs: dry-run — would send ${method} ${buildUrl(resolved.apiBase, path)}\n`);
|
|
85
|
+
}
|
|
86
|
+
// Return a synthetic envelope so command handlers stay uniform.
|
|
87
|
+
// No schema decoding — handlers that emit via Renderer treat this
|
|
88
|
+
// as a passthrough payload.
|
|
89
|
+
return {
|
|
90
|
+
ok: true,
|
|
91
|
+
status: 200,
|
|
92
|
+
data: {
|
|
93
|
+
dryRun: true,
|
|
94
|
+
method,
|
|
95
|
+
path,
|
|
96
|
+
query: options.query ?? null,
|
|
97
|
+
body: options.body ?? null,
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
// ---- 2. auto-refresh near-expiry tokens -------------------------
|
|
102
|
+
let token = resolved.token;
|
|
103
|
+
if (token && resolved.profileName) {
|
|
104
|
+
const fresh = yield* auth
|
|
105
|
+
.ensureFresh(resolved)
|
|
106
|
+
.pipe(Effect.catchAll(() => Effect.succeed(null)));
|
|
107
|
+
if (fresh)
|
|
108
|
+
token = fresh.access_token;
|
|
109
|
+
}
|
|
110
|
+
// ---- 3. send (with single 401-retry) ----------------------------
|
|
111
|
+
// Inject `lang` into the query for read-only requests when the bin
|
|
112
|
+
// has set a global `--lang` flag and the caller didn't already
|
|
113
|
+
// specify one.
|
|
114
|
+
const effectiveQuery = opts.lang && method === 'GET'
|
|
115
|
+
? { lang: opts.lang, ...options.query }
|
|
116
|
+
: options.query;
|
|
117
|
+
const url = buildUrl(resolved.apiBase, path, effectiveQuery);
|
|
118
|
+
const baseHeaders = {
|
|
119
|
+
accept: 'application/json',
|
|
120
|
+
'user-agent': USER_AGENT,
|
|
121
|
+
...options.headers,
|
|
122
|
+
};
|
|
123
|
+
if (token)
|
|
124
|
+
baseHeaders.authorization = `Bearer ${token}`;
|
|
125
|
+
if (resolved.apiKey)
|
|
126
|
+
baseHeaders['x-api-key'] = resolved.apiKey;
|
|
127
|
+
if (options.body !== undefined && !(options.body instanceof FormData)) {
|
|
128
|
+
baseHeaders['content-type'] ??= 'application/json';
|
|
129
|
+
}
|
|
130
|
+
const send = (headers) => Effect.gen(function* () {
|
|
131
|
+
const startedAt = Date.now();
|
|
132
|
+
let req = HttpClientRequest.make(method)(url, {
|
|
133
|
+
headers,
|
|
134
|
+
});
|
|
135
|
+
if (options.body instanceof FormData) {
|
|
136
|
+
req = HttpClientRequest.bodyFormData(req, options.body);
|
|
137
|
+
}
|
|
138
|
+
else if (options.body !== undefined) {
|
|
139
|
+
req = yield* HttpClientRequest.bodyJson(req, options.body).pipe(Effect.mapError((err) => new Generic({
|
|
140
|
+
message: 'failed to encode body',
|
|
141
|
+
cause: err,
|
|
142
|
+
})));
|
|
143
|
+
}
|
|
144
|
+
const res = yield* http.execute(req).pipe(Effect.mapError((err) => {
|
|
145
|
+
if (err._tag === 'ResponseError') {
|
|
146
|
+
// Non-2xx is not surfaced through here because we
|
|
147
|
+
// don't apply filterStatusOk; if a custom layer does
|
|
148
|
+
// raise ResponseError we fall through to Generic.
|
|
149
|
+
return new Generic({
|
|
150
|
+
message: 'unexpected response error',
|
|
151
|
+
cause: err,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
return mapTransportError(err.cause ?? err, url);
|
|
155
|
+
}));
|
|
156
|
+
if (opts.verbose) {
|
|
157
|
+
process.stderr.write(`${method} ${url} → ${res.status} (${Date.now() - startedAt}ms)\n`);
|
|
158
|
+
}
|
|
159
|
+
return res;
|
|
160
|
+
});
|
|
161
|
+
let headers = { ...baseHeaders };
|
|
162
|
+
let res = yield* send(headers);
|
|
163
|
+
if (res.status === 401 && token && resolved.profileName) {
|
|
164
|
+
const refreshed = yield* refreshOnce(auth, config, resolved, token).pipe(Effect.catchAll(() => Effect.succeed(null)));
|
|
165
|
+
if (refreshed) {
|
|
166
|
+
token = refreshed.access_token;
|
|
167
|
+
headers = { ...headers, authorization: `Bearer ${token}` };
|
|
168
|
+
res = yield* send(headers);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// ---- 4. parse + status mapping ---------------------------------
|
|
172
|
+
const body = yield* parseBody(res);
|
|
173
|
+
// COMPAT:envelope — sniff wire version once per ApiService instance
|
|
174
|
+
// for verbose diagnostics. Normalizers below are shape-tolerant and
|
|
175
|
+
// do not consume this verdict. Drop with envelope-compat.ts.
|
|
176
|
+
if (opts.verbose) {
|
|
177
|
+
const cached = yield* Ref.get(detectedWire);
|
|
178
|
+
if (!cached) {
|
|
179
|
+
const sniffed = detectWireVersion(body);
|
|
180
|
+
if (sniffed) {
|
|
181
|
+
yield* Ref.set(detectedWire, sniffed);
|
|
182
|
+
process.stderr.write(`mxs: detected wire version: ${sniffed}\n`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
if (res.status >= 200 && res.status < 300) {
|
|
187
|
+
// COMPAT:envelope — lift V2 root `pagination` to V3 `meta.pagination`.
|
|
188
|
+
const normalized = normalizeSuccessBody(body);
|
|
189
|
+
if (!options.schema)
|
|
190
|
+
return normalized;
|
|
191
|
+
return yield* decodeWithSchema(options.schema, normalized);
|
|
192
|
+
}
|
|
193
|
+
return yield* Effect.fail(mapHttpStatusToError(res.status, body));
|
|
194
|
+
});
|
|
195
|
+
const raw = (path, options) => request(path, options);
|
|
196
|
+
return {
|
|
197
|
+
request,
|
|
198
|
+
raw,
|
|
199
|
+
};
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
// ---------------------------------------------------------------------------
|
|
203
|
+
// Helpers
|
|
204
|
+
// ---------------------------------------------------------------------------
|
|
205
|
+
function buildUrl(base, path, query) {
|
|
206
|
+
const url = new URL(path.startsWith('/') ? path.slice(1) : path, base.endsWith('/') ? base : `${base}/`);
|
|
207
|
+
if (query) {
|
|
208
|
+
for (const [k, v] of Object.entries(query)) {
|
|
209
|
+
if (v === undefined || v === null)
|
|
210
|
+
continue;
|
|
211
|
+
url.searchParams.set(k, String(v));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return url.toString();
|
|
215
|
+
}
|
|
216
|
+
function parseBody(res) {
|
|
217
|
+
const ct = res.headers['content-type'] ?? '';
|
|
218
|
+
if (ct.includes('application/json')) {
|
|
219
|
+
return res.json.pipe(Effect.catchAll(() => Effect.succeed(undefined)));
|
|
220
|
+
}
|
|
221
|
+
return res.text.pipe(Effect.catchAll(() => Effect.succeed('')));
|
|
222
|
+
}
|
|
223
|
+
function decodeWithSchema(schema, body) {
|
|
224
|
+
// We use the platform `Schema.decodeUnknown` to validate at runtime.
|
|
225
|
+
// `effect/Schema` exposes the same API surface, so we import it lazily
|
|
226
|
+
// to keep the static `Api.ts` dep graph minimal.
|
|
227
|
+
return Effect.tryPromise({
|
|
228
|
+
try: async () => {
|
|
229
|
+
const { Schema: SchemaMod } = await import('effect');
|
|
230
|
+
return SchemaMod.decodeUnknownPromise(schema)(body);
|
|
231
|
+
},
|
|
232
|
+
catch: (err) => new ServerError({
|
|
233
|
+
status: 200,
|
|
234
|
+
message: 'response shape mismatch',
|
|
235
|
+
details: serializeParseError(err),
|
|
236
|
+
}),
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
function serializeParseError(err) {
|
|
240
|
+
if (err && typeof err === 'object') {
|
|
241
|
+
const message = err.message;
|
|
242
|
+
if (typeof message === 'string')
|
|
243
|
+
return message;
|
|
244
|
+
}
|
|
245
|
+
return err;
|
|
246
|
+
}
|
|
247
|
+
function mapHttpStatusToError(status, body) {
|
|
248
|
+
// COMPAT:envelope — flatten V2/V3 error body shapes to one tuple. Drop with
|
|
249
|
+
// envelope-compat.ts when V2 support ends; replace with direct
|
|
250
|
+
// `body.error?.message` reads.
|
|
251
|
+
const { code, message: serverMsg, details: serverDetails, } = normalizeErrorBody(body);
|
|
252
|
+
const details = serverDetails ?? body;
|
|
253
|
+
// Code-driven mapping wins over status-derived classification when the V3
|
|
254
|
+
// server emits a stable SCREAMING_SNAKE error code.
|
|
255
|
+
if (code === 'NOT_FOUND' || code?.endsWith('_NOT_FOUND')) {
|
|
256
|
+
return new ResourceNotFound({
|
|
257
|
+
message: serverMsg ?? 'resource not found',
|
|
258
|
+
details,
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
if (code === 'VALIDATION_FAILED') {
|
|
262
|
+
return new ValidationFailed({
|
|
263
|
+
message: serverMsg ?? 'validation failed',
|
|
264
|
+
details,
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
if (status === 401) {
|
|
268
|
+
return new AuthExpired({
|
|
269
|
+
message: serverMsg ?? 'authentication required',
|
|
270
|
+
hint: 'run `mxs auth login`',
|
|
271
|
+
details,
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
if (status === 403) {
|
|
275
|
+
return new AuthDenied({
|
|
276
|
+
message: serverMsg ?? 'permission denied',
|
|
277
|
+
details,
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
if (status === 404) {
|
|
281
|
+
return new ResourceNotFound({
|
|
282
|
+
message: serverMsg ?? 'resource not found',
|
|
283
|
+
details,
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
if (status === 400 || status === 422) {
|
|
287
|
+
return new ValidationFailed({
|
|
288
|
+
message: serverMsg ?? 'validation failed',
|
|
289
|
+
details,
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
if (status >= 500) {
|
|
293
|
+
return new ServerError({
|
|
294
|
+
status,
|
|
295
|
+
message: serverMsg ?? `server error (${status})`,
|
|
296
|
+
details,
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
return new Generic({
|
|
300
|
+
message: serverMsg ?? `request failed (${status})`,
|
|
301
|
+
details,
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
function mapTransportError(err, url) {
|
|
305
|
+
const cause = err;
|
|
306
|
+
const code = cause?.code ?? cause?.cause?.code;
|
|
307
|
+
if (cause?.name === 'AbortError' || code === 'ABORT_ERR') {
|
|
308
|
+
return new Generic({ message: 'request aborted', details: { url } });
|
|
309
|
+
}
|
|
310
|
+
if (code === 'ENOTFOUND' || code === 'EAI_AGAIN') {
|
|
311
|
+
let host = url;
|
|
312
|
+
try {
|
|
313
|
+
host = new URL(url).host;
|
|
314
|
+
}
|
|
315
|
+
catch { }
|
|
316
|
+
return new NetworkDns({
|
|
317
|
+
host,
|
|
318
|
+
message: 'dns lookup failed',
|
|
319
|
+
details: { url },
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
if (code === 'ECONNREFUSED') {
|
|
323
|
+
return new NetworkRefused({ url, message: 'connection refused' });
|
|
324
|
+
}
|
|
325
|
+
if (code === 'ETIMEDOUT' || code === 'UND_ERR_CONNECT_TIMEOUT') {
|
|
326
|
+
return new NetworkTimeout({ url, message: 'network request timed out' });
|
|
327
|
+
}
|
|
328
|
+
return new Generic({
|
|
329
|
+
message: cause?.message ?? `request failed: ${url}`,
|
|
330
|
+
details: { url, cause: code },
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
function refreshOnce(auth, config, resolved, currentToken) {
|
|
334
|
+
return Effect.gen(function* () {
|
|
335
|
+
if (!resolved.profileName)
|
|
336
|
+
return null;
|
|
337
|
+
const cred = yield* config.readProfileCredentials(resolved.profileName);
|
|
338
|
+
if (!cred)
|
|
339
|
+
return null;
|
|
340
|
+
if (cred.access_token !== currentToken)
|
|
341
|
+
return null;
|
|
342
|
+
const refreshed = yield* auth.refresh(resolved.authBase, resolved.clientId, cred);
|
|
343
|
+
if (!refreshed)
|
|
344
|
+
return null;
|
|
345
|
+
yield* config.writeProfileCredentials(resolved.profileName, refreshed);
|
|
346
|
+
return refreshed;
|
|
347
|
+
});
|
|
348
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { HttpClient } from '@effect/platform';
|
|
2
|
+
import { Context, Effect, Layer } from 'effect';
|
|
3
|
+
import { AuthDenied, AuthExpired, AuthMissing, AuthProbe, Generic, NetworkDns, NetworkRefused, NetworkTimeout } from '../domain/errors';
|
|
4
|
+
import { Config, type CredentialsShape, type ResolvedConfig } from './Config';
|
|
5
|
+
export interface AuthProbeResult {
|
|
6
|
+
readonly apiUrl: string;
|
|
7
|
+
readonly apiBase: string;
|
|
8
|
+
readonly authBase: string;
|
|
9
|
+
readonly apiVersion: number;
|
|
10
|
+
}
|
|
11
|
+
export interface WhoamiInfo {
|
|
12
|
+
readonly id?: string;
|
|
13
|
+
readonly email?: string;
|
|
14
|
+
readonly name?: string;
|
|
15
|
+
readonly expiresAt: number;
|
|
16
|
+
}
|
|
17
|
+
export interface AuthStatusInfo {
|
|
18
|
+
readonly authenticated: boolean;
|
|
19
|
+
readonly apiUrl: string;
|
|
20
|
+
readonly profile: string | null;
|
|
21
|
+
readonly expiresAt?: number;
|
|
22
|
+
readonly user?: WhoamiInfo;
|
|
23
|
+
}
|
|
24
|
+
export interface LoginOptions {
|
|
25
|
+
readonly profile?: string;
|
|
26
|
+
readonly apiUrl?: string;
|
|
27
|
+
readonly production?: boolean;
|
|
28
|
+
readonly signal?: AbortSignal;
|
|
29
|
+
}
|
|
30
|
+
export interface DeviceCodeResponse {
|
|
31
|
+
readonly device_code: string;
|
|
32
|
+
readonly user_code: string;
|
|
33
|
+
readonly verification_uri: string;
|
|
34
|
+
readonly verification_uri_complete?: string;
|
|
35
|
+
readonly expires_in: number;
|
|
36
|
+
readonly interval: number;
|
|
37
|
+
}
|
|
38
|
+
export interface DeviceTokenResponse {
|
|
39
|
+
readonly access_token: string;
|
|
40
|
+
readonly token_type: string;
|
|
41
|
+
readonly expires_in: number;
|
|
42
|
+
readonly refresh_token?: string;
|
|
43
|
+
readonly scope?: string;
|
|
44
|
+
readonly user?: {
|
|
45
|
+
readonly id?: string;
|
|
46
|
+
readonly email?: string;
|
|
47
|
+
readonly name?: string;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export interface PollDeviceTokenOptions {
|
|
51
|
+
readonly intervalSec: number;
|
|
52
|
+
readonly expiresInSec: number;
|
|
53
|
+
readonly signal?: AbortSignal;
|
|
54
|
+
readonly onTick?: (state: 'pending' | 'slow_down') => void;
|
|
55
|
+
}
|
|
56
|
+
export declare const SUPPORTED_API_VERSIONS: readonly [3, 2];
|
|
57
|
+
export interface AuthService {
|
|
58
|
+
/** Probe the auth endpoint, walking `/api/v{n}/auth` then `/auth`. */
|
|
59
|
+
readonly probe: (apiUrl: string) => Effect.Effect<AuthProbeResult, AuthProbe | NetworkTimeout | NetworkDns | NetworkRefused>;
|
|
60
|
+
/**
|
|
61
|
+
* Request a device-code grant. Wave 2 commands drive the full UX flow
|
|
62
|
+
* (info lines, `open()`, polling). Wave 1 exposes the primitives.
|
|
63
|
+
*/
|
|
64
|
+
readonly requestDeviceCode: (authBase: string, clientId: string, scope?: string) => Effect.Effect<DeviceCodeResponse, AuthDenied | Generic>;
|
|
65
|
+
/** Poll the token endpoint until completion or expiry. */
|
|
66
|
+
readonly pollDeviceToken: (authBase: string, clientId: string, deviceCode: string, opts: PollDeviceTokenOptions) => Effect.Effect<DeviceTokenResponse, AuthDenied | AuthExpired | Generic>;
|
|
67
|
+
/** Refresh `cred` via either `refresh_token` grant or `get-session`. */
|
|
68
|
+
readonly refresh: (authBase: string, clientId: string, cred: CredentialsShape) => Effect.Effect<CredentialsShape | null, Generic>;
|
|
69
|
+
/**
|
|
70
|
+
* High-level login (placeholder for Wave 2). The Wave 1 contract returns
|
|
71
|
+
* `Generic` and is intentionally a thin wrapper so command code can
|
|
72
|
+
* orchestrate UX (banners, `open`, prompts) explicitly.
|
|
73
|
+
*/
|
|
74
|
+
readonly login: (opts: LoginOptions) => Effect.Effect<CredentialsShape, AuthDenied | AuthExpired | AuthProbe | Generic>;
|
|
75
|
+
/** Clear credentials for the named profile (or active profile when null). */
|
|
76
|
+
readonly logout: (name: string | null) => Effect.Effect<void, Generic>;
|
|
77
|
+
/** Read the active credentials and return whoami summary. */
|
|
78
|
+
readonly whoami: Effect.Effect<WhoamiInfo, AuthMissing | AuthExpired | Generic>;
|
|
79
|
+
/** Read auth status without throwing on missing credentials. */
|
|
80
|
+
readonly status: Effect.Effect<AuthStatusInfo, Generic>;
|
|
81
|
+
/**
|
|
82
|
+
* If the active credential is within 60s of expiry, refresh it and
|
|
83
|
+
* write back via `Config.writeProfileCredentials`. Returns the freshest
|
|
84
|
+
* credentials, or fails with `AuthMissing` when none are stored.
|
|
85
|
+
*/
|
|
86
|
+
readonly ensureFresh: (resolved: ResolvedConfig) => Effect.Effect<CredentialsShape, AuthMissing | AuthExpired | Generic>;
|
|
87
|
+
/**
|
|
88
|
+
* Fill in `cred.user` via `GET /get-session` when missing, persisting the
|
|
89
|
+
* enriched credentials. Returns the input unchanged when the user is
|
|
90
|
+
* already known or when the upstream call fails — never errors.
|
|
91
|
+
*/
|
|
92
|
+
readonly enrichUser: (profileName: string, authBase: string, cred: CredentialsShape) => Effect.Effect<CredentialsShape, Generic>;
|
|
93
|
+
}
|
|
94
|
+
declare const Auth_base: Context.TagClass<Auth, "Auth", AuthService>;
|
|
95
|
+
export declare class Auth extends Auth_base {
|
|
96
|
+
/** Build the Auth Layer; depends on `Config` and `HttpClient`. */
|
|
97
|
+
static Default: Layer.Layer<Auth, never, Config | HttpClient.HttpClient>;
|
|
98
|
+
}
|
|
99
|
+
export declare const isExpiringSoon: (cred: CredentialsShape, bufferMs?: number) => boolean;
|
|
100
|
+
export declare const toCredentials: (resp: DeviceTokenResponse) => CredentialsShape;
|
|
101
|
+
export {};
|