langstage-codraft 0.1.0__tar.gz
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.
- langstage_codraft-0.1.0/.gitattributes +3 -0
- langstage_codraft-0.1.0/.github/workflows/test.yml +100 -0
- langstage_codraft-0.1.0/.gitignore +15 -0
- langstage_codraft-0.1.0/CHANGELOG.md +18 -0
- langstage_codraft-0.1.0/LICENSE +21 -0
- langstage_codraft-0.1.0/PKG-INFO +222 -0
- langstage_codraft-0.1.0/README.md +177 -0
- langstage_codraft-0.1.0/docs/assets/editor.png +0 -0
- langstage_codraft-0.1.0/docs/assets/newsletter-page.png +0 -0
- langstage_codraft-0.1.0/docs/brainstorms/2026-10-17-langstage-codraft-requirements.md +247 -0
- langstage_codraft-0.1.0/examples/byo_agent.py +36 -0
- langstage_codraft-0.1.0/frontend/index.html +13 -0
- langstage_codraft-0.1.0/frontend/package-lock.json +4764 -0
- langstage_codraft-0.1.0/frontend/package.json +44 -0
- langstage_codraft-0.1.0/frontend/public/favicon.svg +1 -0
- langstage_codraft-0.1.0/frontend/src/api.ts +109 -0
- langstage_codraft-0.1.0/frontend/src/editor/App.tsx +173 -0
- langstage_codraft-0.1.0/frontend/src/editor/BlockPanel.tsx +392 -0
- langstage_codraft-0.1.0/frontend/src/editor/Canvas.tsx +434 -0
- langstage_codraft-0.1.0/frontend/src/editor/ChatPanel.tsx +182 -0
- langstage_codraft-0.1.0/frontend/src/editor/CommentsPanel.tsx +118 -0
- langstage_codraft-0.1.0/frontend/src/editor/Diff.tsx +29 -0
- langstage_codraft-0.1.0/frontend/src/editor/DocEditor.tsx +256 -0
- langstage_codraft-0.1.0/frontend/src/editor/DocPanel.tsx +158 -0
- langstage_codraft-0.1.0/frontend/src/editor/NewDocDialog.tsx +135 -0
- langstage_codraft-0.1.0/frontend/src/editor/ReviewPanel.tsx +75 -0
- langstage_codraft-0.1.0/frontend/src/editor/TextEditor.tsx +84 -0
- langstage_codraft-0.1.0/frontend/src/editor/context.ts +34 -0
- langstage_codraft-0.1.0/frontend/src/layout/paginate.test.ts +174 -0
- langstage_codraft-0.1.0/frontend/src/layout/paginate.ts +401 -0
- langstage_codraft-0.1.0/frontend/src/layout/units.ts +42 -0
- langstage_codraft-0.1.0/frontend/src/main.tsx +23 -0
- langstage_codraft-0.1.0/frontend/src/print/PrintView.tsx +93 -0
- langstage_codraft-0.1.0/frontend/src/render/BlockView.tsx +150 -0
- langstage_codraft-0.1.0/frontend/src/render/Chart.tsx +61 -0
- langstage_codraft-0.1.0/frontend/src/render/Page.tsx +36 -0
- langstage_codraft-0.1.0/frontend/src/render/markdown.ts +37 -0
- langstage_codraft-0.1.0/frontend/src/render/theme.ts +44 -0
- langstage_codraft-0.1.0/frontend/src/render/useDocLayout.tsx +154 -0
- langstage_codraft-0.1.0/frontend/src/styles.css +170 -0
- langstage_codraft-0.1.0/frontend/src/types.ts +155 -0
- langstage_codraft-0.1.0/frontend/tsconfig.json +19 -0
- langstage_codraft-0.1.0/frontend/vite.config.ts +19 -0
- langstage_codraft-0.1.0/hatch_build.py +138 -0
- langstage_codraft-0.1.0/langstage_codraft/__init__.py +42 -0
- langstage_codraft-0.1.0/langstage_codraft/agent.py +301 -0
- langstage_codraft-0.1.0/langstage_codraft/cli.py +237 -0
- langstage_codraft-0.1.0/langstage_codraft/config.py +58 -0
- langstage_codraft-0.1.0/langstage_codraft/middleware.py +133 -0
- langstage_codraft-0.1.0/langstage_codraft/pages.py +46 -0
- langstage_codraft-0.1.0/langstage_codraft/render.py +243 -0
- langstage_codraft-0.1.0/langstage_codraft/server.py +465 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/embed-DBsb0C1n.js +201 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/index-aAs5o0Qg.js +280 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/index-yhQ7mwPb.css +1 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-cyrillic-400-normal-HOLc17fK.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-cyrillic-400-normal-obahsSVq.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-cyrillic-500-normal-BasfLYem.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-cyrillic-500-normal-CxZf_p3X.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-cyrillic-600-normal-4D_pXhcN.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-cyrillic-600-normal-CWCymEST.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-cyrillic-700-normal-CjBOestx.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-cyrillic-700-normal-DrXBdSj3.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-cyrillic-800-normal-C7MGvYyJ.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-cyrillic-800-normal-CCHyn08d.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-cyrillic-ext-400-normal-BQZuk6qB.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-cyrillic-ext-400-normal-DQukG94-.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-cyrillic-ext-500-normal-B0yAr1jD.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-cyrillic-ext-500-normal-BmqWE9Dz.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-cyrillic-ext-600-normal-Bcila6Z-.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-cyrillic-ext-600-normal-Dfes3d0z.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-cyrillic-ext-700-normal-BjwYoWNd.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-cyrillic-ext-700-normal-LO58E6JB.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-cyrillic-ext-800-normal-BZOjs1Xv.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-cyrillic-ext-800-normal-Ca-gJeZY.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-greek-400-normal-B4URO6DV.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-greek-400-normal-q2sYcFCs.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-greek-500-normal-BIZE56-Y.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-greek-500-normal-Xzm54t5V.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-greek-600-normal-BZpKdvQh.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-greek-600-normal-plRanbMR.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-greek-700-normal-BUv2fZ6O.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-greek-700-normal-C3JjAnD8.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-greek-800-normal-BU00tryP.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-greek-800-normal-CLIouy3y.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-greek-ext-400-normal-DGGRlc-M.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-greek-ext-400-normal-KugGGMne.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-greek-ext-500-normal-2j5mBUwD.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-greek-ext-500-normal-C4iEst2y.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-greek-ext-600-normal-B8X0CLgF.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-greek-ext-600-normal-DRtmH8MT.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-greek-ext-700-normal-BoQ6DsYi.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-greek-ext-700-normal-qfdV9bQt.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-greek-ext-800-normal-B--PVpEC.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-greek-ext-800-normal-DUe57HfS.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-latin-400-normal-C38fXH4l.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-latin-400-normal-CyCys3Eg.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-latin-500-normal-BL9OpVg8.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-latin-500-normal-Cerq10X2.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-latin-600-normal-CiBQ2DWP.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-latin-600-normal-LgqL8muc.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-latin-700-normal-BLAVimhd.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-latin-700-normal-Yt3aPRUw.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-latin-800-normal-BYj_oED-.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-latin-800-normal-D1mf63XC.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-latin-ext-400-normal-77YHD8bZ.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-latin-ext-400-normal-C1nco2VV.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-latin-ext-500-normal-BxGbmqWO.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-latin-ext-500-normal-CV4jyFjo.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-latin-ext-600-normal-CIVaiw4L.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-latin-ext-600-normal-D2bJ5OIk.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-latin-ext-700-normal-Ca8adRJv.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-latin-ext-700-normal-TidjK2hL.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-latin-ext-800-normal-BOMpwxm3.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-latin-ext-800-normal-DZJjya6U.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-vietnamese-400-normal-Bbgyi5SW.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-vietnamese-400-normal-DMkecbls.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-vietnamese-500-normal-DOriooB6.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-vietnamese-500-normal-mJboJaSs.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-vietnamese-600-normal-BuLX-rYi.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-vietnamese-600-normal-Cc8MFFhd.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-vietnamese-700-normal-BZaoP0fm.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-vietnamese-700-normal-DlLaEgI2.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-vietnamese-800-normal-Cm7tD1pz.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/inter-vietnamese-800-normal-DDlpr_Ee.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-cyrillic-400-italic-BLN19cOa.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-cyrillic-400-italic-C-sRFhvU.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-cyrillic-400-normal-C44pakCn.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-cyrillic-400-normal-DEwCKrdL.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-cyrillic-600-normal-BDP5YDHD.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-cyrillic-600-normal-CHh5eQWW.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-cyrillic-700-normal-BK249n6E.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-cyrillic-700-normal-BmBwwUw2.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-cyrillic-ext-400-italic-Drp6JL_V.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-cyrillic-ext-400-italic-zoDFlEzN.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-cyrillic-ext-400-normal-CWV284fw.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-cyrillic-ext-400-normal-CYkrUebz.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-cyrillic-ext-600-normal-D_E8FDgP.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-cyrillic-ext-600-normal-h2VnbV3V.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-cyrillic-ext-700-normal-B9R79AaY.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-cyrillic-ext-700-normal-K0LivNVE.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-greek-400-italic-C7D4Dq0H.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-greek-400-italic-Ce3U_qGW.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-greek-400-normal-Cw5-AHNN.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-greek-400-normal-D_DO3bho.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-greek-600-normal-DdRkKr-1.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-greek-600-normal-OkzgCkGB.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-greek-700-normal-BrLlvq6D.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-greek-700-normal-BzuEQSqJ.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-latin-400-italic-0j97Jm6B.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-latin-400-italic-DZulBB6l.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-latin-400-normal-C1O10bxN.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-latin-400-normal-DJ5YJwmz.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-latin-600-normal-DeJomR3S.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-latin-600-normal-DouSKlru.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-latin-700-normal-C30JPKlG.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-latin-700-normal-CGGdTIBe.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-latin-ext-400-italic-Cj8BerOQ.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-latin-ext-400-italic-Cttr6ITu.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-latin-ext-400-normal-B5LksYz5.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-latin-ext-400-normal-DKmgyNre.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-latin-ext-600-normal-B2fExS53.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-latin-ext-600-normal-pa-C5Dkf.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-latin-ext-700-normal-D0Q30MFM.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-latin-ext-700-normal-PGcHY9mz.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-vietnamese-400-italic-7zG0SGDK.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-vietnamese-400-italic-B7_QYl3c.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-vietnamese-400-normal-9XEw6Pmr.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-vietnamese-400-normal-DFDfvBrN.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-vietnamese-600-normal-B33FcZBi.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-vietnamese-600-normal-CKUOBVO_.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-vietnamese-700-normal-CAL-i-xy.woff2 +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/assets/source-serif-4-vietnamese-700-normal-DTkW1D86.woff +0 -0
- langstage_codraft-0.1.0/langstage_codraft/static/favicon.svg +1 -0
- langstage_codraft-0.1.0/langstage_codraft/static/index.html +14 -0
- langstage_codraft-0.1.0/langstage_codraft/store.py +801 -0
- langstage_codraft-0.1.0/langstage_codraft/templates.py +143 -0
- langstage_codraft-0.1.0/langstage_codraft/textutil.py +95 -0
- langstage_codraft-0.1.0/langstage_codraft/themes.py +95 -0
- langstage_codraft-0.1.0/langstage_codraft/tools.py +574 -0
- langstage_codraft-0.1.0/pyproject.toml +81 -0
- langstage_codraft-0.1.0/tests/conftest.py +20 -0
- langstage_codraft-0.1.0/tests/e2e/test_ui.py +227 -0
- langstage_codraft-0.1.0/tests/live/test_live_model.py +117 -0
- langstage_codraft-0.1.0/tests/test_agent.py +88 -0
- langstage_codraft-0.1.0/tests/test_server.py +108 -0
- langstage_codraft-0.1.0/tests/test_store.py +175 -0
- langstage_codraft-0.1.0/tests/test_tools.py +133 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches: [main]
|
|
6
|
+
push:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
python:
|
|
11
|
+
runs-on: ${{ matrix.os }}
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
os: [ubuntu-latest]
|
|
16
|
+
python-version: ['3.11', '3.12', '3.13', '3.14']
|
|
17
|
+
include:
|
|
18
|
+
- os: windows-latest
|
|
19
|
+
python-version: '3.13'
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
- uses: actions/setup-python@v5
|
|
23
|
+
with:
|
|
24
|
+
python-version: ${{ matrix.python-version }}
|
|
25
|
+
- name: Install
|
|
26
|
+
run: |
|
|
27
|
+
python -m pip install --upgrade pip
|
|
28
|
+
pip install -e ".[dev]"
|
|
29
|
+
- name: Lint
|
|
30
|
+
run: ruff check langstage_codraft tests
|
|
31
|
+
- name: Unit + API tests
|
|
32
|
+
run: pytest -q --ignore=tests/e2e
|
|
33
|
+
|
|
34
|
+
frontend:
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
defaults:
|
|
37
|
+
run:
|
|
38
|
+
working-directory: frontend
|
|
39
|
+
steps:
|
|
40
|
+
- uses: actions/checkout@v4
|
|
41
|
+
- uses: actions/setup-node@v4
|
|
42
|
+
with:
|
|
43
|
+
node-version: '22'
|
|
44
|
+
cache: npm
|
|
45
|
+
cache-dependency-path: frontend/package-lock.json
|
|
46
|
+
- run: npm ci
|
|
47
|
+
- name: Paginator unit tests
|
|
48
|
+
run: npm test
|
|
49
|
+
- name: Typecheck + build
|
|
50
|
+
run: npm run build
|
|
51
|
+
- uses: actions/upload-artifact@v4
|
|
52
|
+
with:
|
|
53
|
+
name: static
|
|
54
|
+
path: langstage_codraft/static
|
|
55
|
+
|
|
56
|
+
e2e:
|
|
57
|
+
# Real browser against a live keyless demo server, including the
|
|
58
|
+
# editor-vs-export pixel parity gate.
|
|
59
|
+
needs: frontend
|
|
60
|
+
runs-on: ubuntu-latest
|
|
61
|
+
steps:
|
|
62
|
+
- uses: actions/checkout@v4
|
|
63
|
+
- uses: actions/setup-python@v5
|
|
64
|
+
with:
|
|
65
|
+
python-version: '3.12'
|
|
66
|
+
- uses: actions/download-artifact@v4
|
|
67
|
+
with:
|
|
68
|
+
name: static
|
|
69
|
+
path: langstage_codraft/static
|
|
70
|
+
- name: Install
|
|
71
|
+
run: |
|
|
72
|
+
python -m pip install --upgrade pip
|
|
73
|
+
pip install -e ".[dev]"
|
|
74
|
+
python -m playwright install --with-deps chromium
|
|
75
|
+
- name: Browser end-to-end tests
|
|
76
|
+
run: pytest -q tests/e2e
|
|
77
|
+
|
|
78
|
+
minimal-install:
|
|
79
|
+
# A user's install: declared deps only, no dev extras, real wheel build.
|
|
80
|
+
needs: frontend
|
|
81
|
+
runs-on: ubuntu-latest
|
|
82
|
+
steps:
|
|
83
|
+
- uses: actions/checkout@v4
|
|
84
|
+
- uses: actions/setup-python@v5
|
|
85
|
+
with:
|
|
86
|
+
python-version: '3.12'
|
|
87
|
+
- uses: actions/download-artifact@v4
|
|
88
|
+
with:
|
|
89
|
+
name: static
|
|
90
|
+
path: langstage_codraft/static
|
|
91
|
+
- name: Install (no extras)
|
|
92
|
+
run: |
|
|
93
|
+
python -m pip install --upgrade pip
|
|
94
|
+
pip install .
|
|
95
|
+
- name: Smoke
|
|
96
|
+
run: |
|
|
97
|
+
python -c "from langstage_codraft import CODRAFT_TOOLS, CodraftMiddleware; print(len(CODRAFT_TOOLS), 'tools')"
|
|
98
|
+
langstage-codraft --version
|
|
99
|
+
langstage-codraft run --demo --show-config
|
|
100
|
+
langstage-codraft check --demo
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.pyc
|
|
3
|
+
.venv/
|
|
4
|
+
dist/
|
|
5
|
+
build/
|
|
6
|
+
*.egg-info/
|
|
7
|
+
.pytest_cache/
|
|
8
|
+
.ruff_cache/
|
|
9
|
+
langstage_codraft/static/
|
|
10
|
+
frontend/node_modules/
|
|
11
|
+
frontend/test-results/
|
|
12
|
+
frontend/playwright-report/
|
|
13
|
+
frontend/tsconfig.tsbuildinfo
|
|
14
|
+
.codraft/
|
|
15
|
+
.env
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0 — 2026-10-18
|
|
4
|
+
|
|
5
|
+
The first release ("Paged core").
|
|
6
|
+
|
|
7
|
+
- Block editor with paged and pageless documents. Paged documents support page sizes, orientation, margins, 1–3 columns, pinned and repeating blocks, and cover and back pages.
|
|
8
|
+
- Block types: text, heading, image, table, Vega-Lite chart, callout, divider, references, and page break.
|
|
9
|
+
- Agent collaboration:
|
|
10
|
+
- Edits arrive as suggestions with diffs, behind an approval gate with an optional auto-apply.
|
|
11
|
+
- Comments tag the agent; "address all comments" handles them top to bottom.
|
|
12
|
+
- Each block keeps a version tree with branches and a list of sources.
|
|
13
|
+
- `view_pages` gives vision models screenshots of the rendered pages.
|
|
14
|
+
- `CODRAFT_TOOLS` (15 tools) and `CodraftMiddleware`. Agents can be brought in as a graph or a factory. Includes a default agent and a keyless `--demo` agent.
|
|
15
|
+
- Export to PDF, PNG/JPG, and an HTML zip, rendered by the same React renderer as the editor.
|
|
16
|
+
- The new-document form takes the seven brief inputs, plus uploads used as references or templates.
|
|
17
|
+
- Deployers can set themes, templates and a default approval mode in `langstage.toml`.
|
|
18
|
+
- CLI commands: `run`, `check [--live]`, `new`, `list`, `export`, `install-browser`.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kedar Dabhadkar
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: langstage-codraft
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: The document stage for your LangGraph agent: co-author paged documents block by block, with approval-gated agent edits, per-block version history, and PDF/HTML/PNG export.
|
|
5
|
+
Project-URL: Homepage, https://github.com/dkedar7/langstage-codraft
|
|
6
|
+
Project-URL: Documentation, https://dkedar7.github.io/langstage-docs/codraft/
|
|
7
|
+
Project-URL: Issues, https://github.com/dkedar7/langstage-codraft/issues
|
|
8
|
+
Author-email: Kedar Dabhadkar <kdabhadk@gmail.com>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: ag-ui,agents,ai-writing,document-editor,langgraph,langstage
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Framework :: FastAPI
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Topic :: Text Processing
|
|
22
|
+
Requires-Python: >=3.11
|
|
23
|
+
Requires-Dist: click>=8.0
|
|
24
|
+
Requires-Dist: fastapi>=0.115
|
|
25
|
+
Requires-Dist: httpx>=0.27
|
|
26
|
+
Requires-Dist: langchain-openai>=1.0
|
|
27
|
+
Requires-Dist: langchain>=1.0
|
|
28
|
+
Requires-Dist: langgraph-checkpoint-sqlite>=2.0
|
|
29
|
+
Requires-Dist: langgraph>=1.0
|
|
30
|
+
Requires-Dist: langstage-core[agui]>=1.0.50
|
|
31
|
+
Requires-Dist: playwright>=1.45
|
|
32
|
+
Requires-Dist: pydantic>=2.0
|
|
33
|
+
Requires-Dist: pypdf>=4.0
|
|
34
|
+
Requires-Dist: python-docx>=1.1
|
|
35
|
+
Requires-Dist: python-multipart>=0.0.12
|
|
36
|
+
Requires-Dist: uvicorn[standard]>=0.30
|
|
37
|
+
Provides-Extra: dev
|
|
38
|
+
Requires-Dist: pillow>=10; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
40
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
41
|
+
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
42
|
+
Provides-Extra: search
|
|
43
|
+
Requires-Dist: ddgs>=9.0; extra == 'search'
|
|
44
|
+
Description-Content-Type: text/markdown
|
|
45
|
+
|
|
46
|
+
# langstage-codraft
|
|
47
|
+
|
|
48
|
+
**The document stage for your LangGraph agent.** Draft a document block by block on real pages.
|
|
49
|
+
Tag your agent in comments, approve every change it suggests, and export exactly what you see.
|
|
50
|
+
|
|
51
|
+
[](https://github.com/dkedar7/langstage-codraft/actions/workflows/test.yml)
|
|
52
|
+
[](https://pypi.org/project/langstage-codraft/)
|
|
53
|
+
[](https://pypi.org/project/langstage-codraft/)
|
|
54
|
+
|
|
55
|
+

|
|
56
|
+
|
|
57
|
+
You own the thinking. Your agent owns the styling, and helps with drafting and research when
|
|
58
|
+
you ask it to.
|
|
59
|
+
|
|
60
|
+
- **Blocks on pages.** Text, headings, images, tables, Vega-Lite charts, callouts and an
|
|
61
|
+
automatic references list. Pages come in Letter, A4, Legal, A5 or 16:9 slide, with 1–3
|
|
62
|
+
columns. You can also pin blocks so other blocks flow around them, repeat headers and logos
|
|
63
|
+
on every page, and add cover and back pages. Pageless mode is available too.
|
|
64
|
+
- **The agent edits by suggestion.** Every change the agent makes to your text arrives as a
|
|
65
|
+
diff you accept or reject. A per-document switch turns on auto-apply.
|
|
66
|
+
- **Comments tag the agent.** Queue comments for later or ask now. "Address all comments"
|
|
67
|
+
handles them strictly top to bottom.
|
|
68
|
+
- **Nothing is overwritten.** Each block keeps a version tree. Step back, step forward, and
|
|
69
|
+
edit an old version to start a new branch.
|
|
70
|
+
- **Sources stay with each block.** The agent cites as it writes, and a `references` block
|
|
71
|
+
compiles them.
|
|
72
|
+
- **The agent sees the page.** `view_pages` gives a vision model screenshots of the rendered
|
|
73
|
+
pages, so it can fix layout problems you'd spot by eye.
|
|
74
|
+
- **Export matches the screen.** PDF, PNG/JPG per page, or a self-contained HTML zip. All of
|
|
75
|
+
them are rendered by the same component as the editor, and CI checks them pixel for pixel
|
|
76
|
+
against it.
|
|
77
|
+
|
|
78
|
+
## Quick start
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
pip install langstage-codraft
|
|
82
|
+
langstage-codraft install-browser # Chromium for export and the agent's eyes (once)
|
|
83
|
+
langstage-codraft run --demo # keyless scripted co-author, opens http://localhost:8060
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
With a real model:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
export OPENROUTER_API_KEY=... # or OPENAI_API_KEY / ANTHROPIC_API_KEY
|
|
90
|
+
langstage-codraft run # default agent: claude-haiku-5.5 via OpenRouter
|
|
91
|
+
langstage-codraft run -m openai:gpt-5-mini # any LangChain model spec
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Bring your own agent
|
|
95
|
+
|
|
96
|
+
Codraft is a LangStage stage: you bring the LangGraph agent and Codraft adds what it needs to
|
|
97
|
+
work on documents. There are three ways to plug one in.
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
# my_agent.py
|
|
101
|
+
from langchain.agents import create_agent
|
|
102
|
+
from langstage_codraft import CodraftMiddleware
|
|
103
|
+
|
|
104
|
+
# 1. A graph that includes the middleware (it registers the tools and the co-author prompt,
|
|
105
|
+
# and attaches page screenshots for vision models).
|
|
106
|
+
graph = create_agent("openai:gpt-5-mini", tools=[my_search], middleware=[CodraftMiddleware()])
|
|
107
|
+
|
|
108
|
+
# 2. Or a factory: Codraft calls it with its tools and middleware.
|
|
109
|
+
def make(tools, middleware):
|
|
110
|
+
return create_agent(my_model, tools=[*tools, my_search], middleware=middleware)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
langstage-codraft run --agent my_agent.py:graph # or my_agent.py:make
|
|
115
|
+
langstage-codraft check --agent my_agent.py:graph # preflight; --live runs one real turn
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
A graph built without the Codraft tools still chats, but it can't touch the document. `check`
|
|
119
|
+
tells you when that's the case.
|
|
120
|
+
|
|
121
|
+
The agent's toolset (`CODRAFT_TOOLS`) has 15 tools. Each one reads and writes through the same
|
|
122
|
+
API the editor uses, so the agent has no private path, and nothing the agent can do is out of
|
|
123
|
+
the author's reach:
|
|
124
|
+
|
|
125
|
+
| Read | Write (suggestions) | Style (applies directly) | Other |
|
|
126
|
+
|---|---|---|---|
|
|
127
|
+
| `get_document`, `read_blocks`, `search_document`, `read_upload`, `list_comments`, `get_block_history` | `propose_edit`, `propose_insert`, `propose_delete`, `propose_move` | `set_block_layout`, `set_document_style` | `reply_to_comment`, `compile_references`, `view_pages` |
|
|
128
|
+
|
|
129
|
+
Each document has its own agent thread (the AG-UI thread id is the document id). Conversations
|
|
130
|
+
are stored in SQLite and survive restarts. The same agent is also served at `POST /agui` for any
|
|
131
|
+
AG-UI client.
|
|
132
|
+
|
|
133
|
+
## For deployers
|
|
134
|
+
|
|
135
|
+
Configuration follows the LangStage chain: defaults < `langstage.toml` < `LANGSTAGE_*` env < CLI
|
|
136
|
+
flags.
|
|
137
|
+
|
|
138
|
+
```toml
|
|
139
|
+
# langstage.toml
|
|
140
|
+
[agent]
|
|
141
|
+
spec = "my_agent.py:graph"
|
|
142
|
+
|
|
143
|
+
[codraft]
|
|
144
|
+
model = "openrouter:anthropic/claude-haiku-5.5" # used when no agent spec is set
|
|
145
|
+
approval = "required" # or "auto" for new documents
|
|
146
|
+
default_theme = "acme"
|
|
147
|
+
allowed_themes = ["acme", "academic"]
|
|
148
|
+
templates_dir = "templates" # *.json: settings + a block skeleton
|
|
149
|
+
data_dir = ".codraft"
|
|
150
|
+
|
|
151
|
+
[codraft.themes.acme]
|
|
152
|
+
label = "Acme"
|
|
153
|
+
font_body = "Inter, system-ui, sans-serif"
|
|
154
|
+
font_heading = "Inter, system-ui, sans-serif"
|
|
155
|
+
color_accent = "#d9480f"
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
`langstage-codraft run --show-config` prints the resolved values and where each one came from.
|
|
159
|
+
|
|
160
|
+
There are seven built-in templates: blank, report, proposal, memo, two-column academic paper,
|
|
161
|
+
marketing one-pager, and a three-column newsletter with a repeating masthead. Each new document
|
|
162
|
+
records the author's brief (writing style, objective, platform, audience, language, output
|
|
163
|
+
format), and the agent reads it before writing.
|
|
164
|
+
|
|
165
|
+
## CLI
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
langstage-codraft run [--agent SPEC | --model SPEC | --demo] [--port 8060] [--approval auto]
|
|
169
|
+
langstage-codraft check [--live] [--json]
|
|
170
|
+
langstage-codraft new "Title" --template report
|
|
171
|
+
langstage-codraft list
|
|
172
|
+
langstage-codraft export DOC_ID -f pdf|png|jpg|html -o out.pdf
|
|
173
|
+
langstage-codraft install-browser
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## How the layout works
|
|
177
|
+
|
|
178
|
+
Blocks are measured in the browser at the width they'll occupy. A pure function then paginates
|
|
179
|
+
them (see `frontend/src/layout/paginate.ts`, which has its own unit tests):
|
|
180
|
+
|
|
181
|
+
- Blocks flow column-major. A full-width block balances the columns above it.
|
|
182
|
+
- A pinned block reserves a rectangle on the page instead of wrapping text around it.
|
|
183
|
+
- Text splits only at paragraph or line boundaries, keeping at least two lines on each side.
|
|
184
|
+
- A block taller than a page is flagged rather than looping forever.
|
|
185
|
+
|
|
186
|
+
The preview, the export and the agent's screenshots all print that same layout in headless
|
|
187
|
+
Chromium. Chromium never paginates anything again, so the editor and the PDF can't disagree.
|
|
188
|
+
|
|
189
|
+

|
|
190
|
+
|
|
191
|
+
## Part of LangStage
|
|
192
|
+
|
|
193
|
+
| Stage | Package |
|
|
194
|
+
|---|---|
|
|
195
|
+
| Web workspace | [`langstage`](https://github.com/dkedar7/langstage) |
|
|
196
|
+
| Terminal | [`langstage-cli`](https://github.com/dkedar7/langstage-cli) |
|
|
197
|
+
| JupyterLab | [`langstage-jupyter`](https://github.com/dkedar7/langstage-jupyter) |
|
|
198
|
+
| VS Code | [`langstage-vscode`](https://github.com/dkedar7/langstage-vscode) |
|
|
199
|
+
| Hermes | [`langstage-hermes`](https://github.com/dkedar7/langstage-hermes) |
|
|
200
|
+
| **Documents** | **`langstage-codraft`** |
|
|
201
|
+
| Shared host + AG-UI bridge | [`langstage-core`](https://github.com/dkedar7/langstage-core) |
|
|
202
|
+
|
|
203
|
+
Docs: https://dkedar7.github.io/langstage-docs/codraft/
|
|
204
|
+
|
|
205
|
+
## Development
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
uv venv && uv pip install -e ".[dev]"
|
|
209
|
+
cd frontend && npm ci && npm test && npm run build && cd ..
|
|
210
|
+
pytest # unit + API + browser e2e (needs the built UI)
|
|
211
|
+
CODRAFT_LIVE=1 OPENROUTER_API_KEY=... pytest tests/live -s # opt-in real-model checks
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Run `npm run dev` in `frontend/` alongside `langstage-codraft run --demo --no-browser` to get
|
|
215
|
+
hot reload; Vite proxies `/api` to port 8060.
|
|
216
|
+
|
|
217
|
+
The design notes this started from are in `docs/notes/`, and the requirements are in
|
|
218
|
+
`docs/brainstorms/`.
|
|
219
|
+
|
|
220
|
+
## License
|
|
221
|
+
|
|
222
|
+
MIT
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# langstage-codraft
|
|
2
|
+
|
|
3
|
+
**The document stage for your LangGraph agent.** Draft a document block by block on real pages.
|
|
4
|
+
Tag your agent in comments, approve every change it suggests, and export exactly what you see.
|
|
5
|
+
|
|
6
|
+
[](https://github.com/dkedar7/langstage-codraft/actions/workflows/test.yml)
|
|
7
|
+
[](https://pypi.org/project/langstage-codraft/)
|
|
8
|
+
[](https://pypi.org/project/langstage-codraft/)
|
|
9
|
+
|
|
10
|
+

|
|
11
|
+
|
|
12
|
+
You own the thinking. Your agent owns the styling, and helps with drafting and research when
|
|
13
|
+
you ask it to.
|
|
14
|
+
|
|
15
|
+
- **Blocks on pages.** Text, headings, images, tables, Vega-Lite charts, callouts and an
|
|
16
|
+
automatic references list. Pages come in Letter, A4, Legal, A5 or 16:9 slide, with 1–3
|
|
17
|
+
columns. You can also pin blocks so other blocks flow around them, repeat headers and logos
|
|
18
|
+
on every page, and add cover and back pages. Pageless mode is available too.
|
|
19
|
+
- **The agent edits by suggestion.** Every change the agent makes to your text arrives as a
|
|
20
|
+
diff you accept or reject. A per-document switch turns on auto-apply.
|
|
21
|
+
- **Comments tag the agent.** Queue comments for later or ask now. "Address all comments"
|
|
22
|
+
handles them strictly top to bottom.
|
|
23
|
+
- **Nothing is overwritten.** Each block keeps a version tree. Step back, step forward, and
|
|
24
|
+
edit an old version to start a new branch.
|
|
25
|
+
- **Sources stay with each block.** The agent cites as it writes, and a `references` block
|
|
26
|
+
compiles them.
|
|
27
|
+
- **The agent sees the page.** `view_pages` gives a vision model screenshots of the rendered
|
|
28
|
+
pages, so it can fix layout problems you'd spot by eye.
|
|
29
|
+
- **Export matches the screen.** PDF, PNG/JPG per page, or a self-contained HTML zip. All of
|
|
30
|
+
them are rendered by the same component as the editor, and CI checks them pixel for pixel
|
|
31
|
+
against it.
|
|
32
|
+
|
|
33
|
+
## Quick start
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pip install langstage-codraft
|
|
37
|
+
langstage-codraft install-browser # Chromium for export and the agent's eyes (once)
|
|
38
|
+
langstage-codraft run --demo # keyless scripted co-author, opens http://localhost:8060
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
With a real model:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
export OPENROUTER_API_KEY=... # or OPENAI_API_KEY / ANTHROPIC_API_KEY
|
|
45
|
+
langstage-codraft run # default agent: claude-haiku-5.5 via OpenRouter
|
|
46
|
+
langstage-codraft run -m openai:gpt-5-mini # any LangChain model spec
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Bring your own agent
|
|
50
|
+
|
|
51
|
+
Codraft is a LangStage stage: you bring the LangGraph agent and Codraft adds what it needs to
|
|
52
|
+
work on documents. There are three ways to plug one in.
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
# my_agent.py
|
|
56
|
+
from langchain.agents import create_agent
|
|
57
|
+
from langstage_codraft import CodraftMiddleware
|
|
58
|
+
|
|
59
|
+
# 1. A graph that includes the middleware (it registers the tools and the co-author prompt,
|
|
60
|
+
# and attaches page screenshots for vision models).
|
|
61
|
+
graph = create_agent("openai:gpt-5-mini", tools=[my_search], middleware=[CodraftMiddleware()])
|
|
62
|
+
|
|
63
|
+
# 2. Or a factory: Codraft calls it with its tools and middleware.
|
|
64
|
+
def make(tools, middleware):
|
|
65
|
+
return create_agent(my_model, tools=[*tools, my_search], middleware=middleware)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
langstage-codraft run --agent my_agent.py:graph # or my_agent.py:make
|
|
70
|
+
langstage-codraft check --agent my_agent.py:graph # preflight; --live runs one real turn
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
A graph built without the Codraft tools still chats, but it can't touch the document. `check`
|
|
74
|
+
tells you when that's the case.
|
|
75
|
+
|
|
76
|
+
The agent's toolset (`CODRAFT_TOOLS`) has 15 tools. Each one reads and writes through the same
|
|
77
|
+
API the editor uses, so the agent has no private path, and nothing the agent can do is out of
|
|
78
|
+
the author's reach:
|
|
79
|
+
|
|
80
|
+
| Read | Write (suggestions) | Style (applies directly) | Other |
|
|
81
|
+
|---|---|---|---|
|
|
82
|
+
| `get_document`, `read_blocks`, `search_document`, `read_upload`, `list_comments`, `get_block_history` | `propose_edit`, `propose_insert`, `propose_delete`, `propose_move` | `set_block_layout`, `set_document_style` | `reply_to_comment`, `compile_references`, `view_pages` |
|
|
83
|
+
|
|
84
|
+
Each document has its own agent thread (the AG-UI thread id is the document id). Conversations
|
|
85
|
+
are stored in SQLite and survive restarts. The same agent is also served at `POST /agui` for any
|
|
86
|
+
AG-UI client.
|
|
87
|
+
|
|
88
|
+
## For deployers
|
|
89
|
+
|
|
90
|
+
Configuration follows the LangStage chain: defaults < `langstage.toml` < `LANGSTAGE_*` env < CLI
|
|
91
|
+
flags.
|
|
92
|
+
|
|
93
|
+
```toml
|
|
94
|
+
# langstage.toml
|
|
95
|
+
[agent]
|
|
96
|
+
spec = "my_agent.py:graph"
|
|
97
|
+
|
|
98
|
+
[codraft]
|
|
99
|
+
model = "openrouter:anthropic/claude-haiku-5.5" # used when no agent spec is set
|
|
100
|
+
approval = "required" # or "auto" for new documents
|
|
101
|
+
default_theme = "acme"
|
|
102
|
+
allowed_themes = ["acme", "academic"]
|
|
103
|
+
templates_dir = "templates" # *.json: settings + a block skeleton
|
|
104
|
+
data_dir = ".codraft"
|
|
105
|
+
|
|
106
|
+
[codraft.themes.acme]
|
|
107
|
+
label = "Acme"
|
|
108
|
+
font_body = "Inter, system-ui, sans-serif"
|
|
109
|
+
font_heading = "Inter, system-ui, sans-serif"
|
|
110
|
+
color_accent = "#d9480f"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
`langstage-codraft run --show-config` prints the resolved values and where each one came from.
|
|
114
|
+
|
|
115
|
+
There are seven built-in templates: blank, report, proposal, memo, two-column academic paper,
|
|
116
|
+
marketing one-pager, and a three-column newsletter with a repeating masthead. Each new document
|
|
117
|
+
records the author's brief (writing style, objective, platform, audience, language, output
|
|
118
|
+
format), and the agent reads it before writing.
|
|
119
|
+
|
|
120
|
+
## CLI
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
langstage-codraft run [--agent SPEC | --model SPEC | --demo] [--port 8060] [--approval auto]
|
|
124
|
+
langstage-codraft check [--live] [--json]
|
|
125
|
+
langstage-codraft new "Title" --template report
|
|
126
|
+
langstage-codraft list
|
|
127
|
+
langstage-codraft export DOC_ID -f pdf|png|jpg|html -o out.pdf
|
|
128
|
+
langstage-codraft install-browser
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## How the layout works
|
|
132
|
+
|
|
133
|
+
Blocks are measured in the browser at the width they'll occupy. A pure function then paginates
|
|
134
|
+
them (see `frontend/src/layout/paginate.ts`, which has its own unit tests):
|
|
135
|
+
|
|
136
|
+
- Blocks flow column-major. A full-width block balances the columns above it.
|
|
137
|
+
- A pinned block reserves a rectangle on the page instead of wrapping text around it.
|
|
138
|
+
- Text splits only at paragraph or line boundaries, keeping at least two lines on each side.
|
|
139
|
+
- A block taller than a page is flagged rather than looping forever.
|
|
140
|
+
|
|
141
|
+
The preview, the export and the agent's screenshots all print that same layout in headless
|
|
142
|
+
Chromium. Chromium never paginates anything again, so the editor and the PDF can't disagree.
|
|
143
|
+
|
|
144
|
+

|
|
145
|
+
|
|
146
|
+
## Part of LangStage
|
|
147
|
+
|
|
148
|
+
| Stage | Package |
|
|
149
|
+
|---|---|
|
|
150
|
+
| Web workspace | [`langstage`](https://github.com/dkedar7/langstage) |
|
|
151
|
+
| Terminal | [`langstage-cli`](https://github.com/dkedar7/langstage-cli) |
|
|
152
|
+
| JupyterLab | [`langstage-jupyter`](https://github.com/dkedar7/langstage-jupyter) |
|
|
153
|
+
| VS Code | [`langstage-vscode`](https://github.com/dkedar7/langstage-vscode) |
|
|
154
|
+
| Hermes | [`langstage-hermes`](https://github.com/dkedar7/langstage-hermes) |
|
|
155
|
+
| **Documents** | **`langstage-codraft`** |
|
|
156
|
+
| Shared host + AG-UI bridge | [`langstage-core`](https://github.com/dkedar7/langstage-core) |
|
|
157
|
+
|
|
158
|
+
Docs: https://dkedar7.github.io/langstage-docs/codraft/
|
|
159
|
+
|
|
160
|
+
## Development
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
uv venv && uv pip install -e ".[dev]"
|
|
164
|
+
cd frontend && npm ci && npm test && npm run build && cd ..
|
|
165
|
+
pytest # unit + API + browser e2e (needs the built UI)
|
|
166
|
+
CODRAFT_LIVE=1 OPENROUTER_API_KEY=... pytest tests/live -s # opt-in real-model checks
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Run `npm run dev` in `frontend/` alongside `langstage-codraft run --demo --no-browser` to get
|
|
170
|
+
hot reload; Vite proxies `/api` to port 8060.
|
|
171
|
+
|
|
172
|
+
The design notes this started from are in `docs/notes/`, and the requirements are in
|
|
173
|
+
`docs/brainstorms/`.
|
|
174
|
+
|
|
175
|
+
## License
|
|
176
|
+
|
|
177
|
+
MIT
|
|
Binary file
|
|
Binary file
|