mulmoterminal 7.2.0 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -10
- package/blueprints/adopt/checks/adopt.mjs +106 -0
- package/blueprints/adopt/checks/base.mjs +12 -0
- package/blueprints/adopt/checks/report.mjs +22 -0
- package/blueprints/adopt/checks/setup.d.mts +4 -0
- package/blueprints/adopt/checks/setup.mjs +47 -0
- package/blueprints/adopt/hearing.json +42 -0
- package/blueprints/adopt/kinds.json +18 -0
- package/blueprints/adopt/manifest.json +9 -0
- package/blueprints/adopt/presets/help-pages/export.md +9 -0
- package/blueprints/adopt/presets/help-pages/login.md +9 -0
- package/blueprints/adopt/presets.json +15 -0
- package/blueprints/adopt/skills/apply/SKILL.md +47 -0
- package/blueprints/adopt/skills/survey/SKILL.md +35 -0
- package/blueprints/adopt/steps.json +20 -0
- package/blueprints/adopt/templates/chaff.yml +29 -0
- package/blueprints/compare/checks/articles.d.mts +8 -0
- package/blueprints/compare/checks/articles.mjs +109 -0
- package/blueprints/compare/checks/base.mjs +12 -0
- package/blueprints/compare/checks/comparison.mjs +22 -0
- package/blueprints/compare/checks/comparisonView.d.mts +4 -0
- package/blueprints/compare/checks/comparisonView.mjs +14 -0
- package/blueprints/compare/checks/report.mjs +47 -0
- package/blueprints/compare/checks/versions.mjs +33 -0
- package/blueprints/compare/hearing.json +27 -0
- package/blueprints/compare/manifest.json +9 -0
- package/blueprints/compare/presets/itaku-kaitei/kyu.txt +31 -0
- package/blueprints/compare/presets/itaku-kaitei/shin.txt +31 -0
- package/blueprints/compare/presets.json +11 -0
- package/blueprints/compare/skills/pair/SKILL.md +51 -0
- package/blueprints/compare/skills/report/SKILL.md +33 -0
- package/blueprints/compare/steps.json +20 -0
- package/blueprints/docs/checks/chaff.mjs +2 -1
- package/blueprints/docs/checks/chaff.sh +1 -1
- package/blueprints/docs/checks/config.d.mts +3 -0
- package/blueprints/docs/checks/config.mjs +18 -0
- package/blueprints/docs/checks/markdown.d.mts +10 -0
- package/blueprints/docs/checks/markdown.mjs +30 -0
- package/blueprints/docs/skills/workspace/SKILL.md +1 -1
- package/blueprints/from-collection/skills/acceptance/SKILL.md +3 -0
- package/blueprints/from-collection/skills/acceptance-cloudflare/SKILL.md +3 -0
- package/blueprints/from-collection/skills/acceptance-firebase/SKILL.md +3 -0
- package/blueprints/from-collection/skills/acceptance-supabase/SKILL.md +3 -0
- package/blueprints/from-collection/skills/actions/SKILL.md +2 -1
- package/blueprints/from-collection/skills/actions-cloudflare/SKILL.md +2 -1
- package/blueprints/from-collection/skills/actions-firebase/SKILL.md +2 -1
- package/blueprints/from-collection/skills/actions-supabase/SKILL.md +2 -1
- package/blueprints/from-collection/skills/import-supabase/SKILL.md +7 -3
- package/blueprints/from-collection/spec/conversion.md +2 -2
- package/blueprints/from-collection/spec/requirements.md +2 -2
- package/blueprints/glossary/checks/base.mjs +12 -0
- package/blueprints/glossary/checks/glossary.mjs +106 -0
- package/blueprints/glossary/checks/report.mjs +43 -0
- package/blueprints/glossary/checks/terms.d.mts +11 -0
- package/blueprints/glossary/checks/terms.mjs +140 -0
- package/blueprints/glossary/hearing.json +19 -0
- package/blueprints/glossary/manifest.json +9 -0
- package/blueprints/glossary/presets/shanai-yogo/kitei.txt +14 -0
- package/blueprints/glossary/presets/shanai-yogo/tebiki.md +17 -0
- package/blueprints/glossary/presets.json +11 -0
- package/blueprints/glossary/skills/apply/SKILL.md +50 -0
- package/blueprints/glossary/skills/collect/SKILL.md +51 -0
- package/blueprints/glossary/steps.json +20 -0
- package/blueprints/polish/hearing.json +8 -3
- package/blueprints/polish/kinds.json +5 -2
- package/blueprints/polish/presets/tejun/tejun.md +15 -0
- package/blueprints/polish/presets.json +13 -0
- package/blueprints/polish/viewpoints.json +39 -1
- package/blueprints/style/skills/report/SKILL.md +1 -1
- package/blueprints/style/skills/rules/SKILL.md +4 -3
- package/blueprints/summarize/checks/base.mjs +12 -0
- package/blueprints/summarize/checks/parts.d.mts +13 -0
- package/blueprints/summarize/checks/parts.mjs +101 -0
- package/blueprints/summarize/checks/report.mjs +50 -0
- package/blueprints/summarize/checks/summary.mjs +48 -0
- package/blueprints/summarize/hearing.json +34 -0
- package/blueprints/summarize/manifest.json +9 -0
- package/blueprints/summarize/presets/keihi/keihi.md +19 -0
- package/blueprints/summarize/presets.json +11 -0
- package/blueprints/summarize/skills/report/SKILL.md +26 -0
- package/blueprints/summarize/skills/summarize/SKILL.md +50 -0
- package/blueprints/summarize/steps.json +20 -0
- package/blueprints/supabase/checks/advisors.mjs +26 -3
- package/blueprints/supabase/checks/declared-open.d.mts +3 -0
- package/blueprints/supabase/checks/declared-open.mjs +48 -0
- package/blueprints/supabase/checks/local-stack.sh +25 -1
- package/blueprints/supabase/checks/public-tables.mjs +20 -0
- package/blueprints/supabase/checks/security-probe.mjs +2 -18
- package/blueprints/supabase/skills/auth/SKILL.md +2 -1
- package/blueprints/write/hearing.json +2 -1
- package/common/blueprint/collectionSource.ts +17 -1
- package/common/blueprint/hearing.ts +62 -0
- package/common/blueprint/personalData.ts +80 -0
- package/common/blueprint/refusal.ts +16 -0
- package/common/blueprint/sourceStatus.ts +14 -0
- package/common/dirConfigForm.ts +43 -0
- package/common/dirConfigSource.ts +2 -0
- package/common/headerButtonEntries.ts +115 -14
- package/common/headerButtonFolders.ts +149 -0
- package/common/headerStatusColors.ts +25 -0
- package/common/hiddenCharacters.ts +34 -1
- package/common/keymapPresets.ts +39 -5
- package/common/viewTargets.ts +5 -0
- package/common/whatsNew.ts +18 -0
- package/dist/assets/{abnfDiagram-O67JEVCF-DfYKie1f.js → abnfDiagram-O67JEVCF-CpHo_PZJ.js} +1 -1
- package/dist/assets/architecture-7GRP2DOG-DHGWVJ2h.js +1 -0
- package/dist/assets/{architectureDiagram-NJMV4G6O-vsLzjzQx.js → architectureDiagram-NJMV4G6O-D8O_YCc5.js} +1 -1
- package/dist/assets/{blockDiagram-BEXU5L5S-DssDT1TO.js → blockDiagram-BEXU5L5S-BmAXZW-Y.js} +1 -1
- package/dist/assets/{c4Diagram-YGBWAQC7-P0CrW8QT.js → c4Diagram-YGBWAQC7-BKGWYynD.js} +1 -1
- package/dist/assets/channel-CdJOmIUD.js +1 -0
- package/dist/assets/{chunk-3FUC2YCW-CvTm_ho-.js → chunk-3FUC2YCW-B_IdrlcA.js} +1 -1
- package/dist/assets/{chunk-5DYCD2WN-BVnziItI.js → chunk-5DYCD2WN-B7_1xZmW.js} +1 -1
- package/dist/assets/{chunk-742MDFTN-CccjktcU.js → chunk-742MDFTN-D4qUH6PT.js} +1 -1
- package/dist/assets/{chunk-7INBJB4K-Bf0Shv2-.js → chunk-7INBJB4K-D8CJTq2h.js} +1 -1
- package/dist/assets/{chunk-7M6MHVWA-BtwnZqTt.js → chunk-7M6MHVWA-BzOZvK1S.js} +1 -1
- package/dist/assets/{chunk-7PRAP22T-59aFrPRm.js → chunk-7PRAP22T-Dde-X1de.js} +1 -1
- package/dist/assets/{chunk-GTNCS2PH-CT1kVgRW.js → chunk-GTNCS2PH-BisCzBN2.js} +1 -1
- package/dist/assets/{chunk-GWA4HPMP-C94KrS1K.js → chunk-GWA4HPMP-iu0yn8To.js} +1 -1
- package/dist/assets/{chunk-MBY4JIJT-D9Nn3Npg.js → chunk-MBY4JIJT-DFF6e2Ko.js} +1 -1
- package/dist/assets/{chunk-NETBCI7D-C-jbM8IP.js → chunk-NETBCI7D-CMxBns45.js} +1 -1
- package/dist/assets/{chunk-O7XYJQB3-BQYzKLhh.js → chunk-O7XYJQB3-DmVEmVoY.js} +1 -1
- package/dist/assets/{chunk-UA2S7LBM-D7ovzGAr.js → chunk-UA2S7LBM-Yl2q4Lki.js} +1 -1
- package/dist/assets/{chunk-WEXAMYUT-BmlxOjG3.js → chunk-WEXAMYUT-C8nY9xst.js} +1 -1
- package/dist/assets/{chunk-Z7XXMR3K-BSVBhxk7.js → chunk-Z7XXMR3K-mnRYFb5B.js} +1 -1
- package/dist/assets/{chunk-ZIGJFQKS-x3IHLAdW.js → chunk-ZIGJFQKS-BtOX-Fj1.js} +1 -1
- package/dist/assets/{classDiagram-v2-NBCMYWYE-C6eb81l4.js → classDiagram-v2-NBCMYWYE-DBRiOW2Z.js} +1 -1
- package/dist/assets/{cynefin-OW5HDTMX-CM1PFDYP.js → cynefin-OW5HDTMX-CiJWfOK7.js} +1 -1
- package/dist/assets/{cynefinDiagram-VND7K2PF-CxhcOZTy.js → cynefinDiagram-VND7K2PF-C0ZcEImU.js} +1 -1
- package/dist/assets/{dagre-6A5THRUB-D5O9prrg.js → dagre-6A5THRUB-DKM8AbPc.js} +1 -1
- package/dist/assets/{diagram-22UHCM2B-h7R_GutV.js → diagram-22UHCM2B-DK06OHgR.js} +1 -1
- package/dist/assets/{diagram-3UASUU5V-DPmc5Ai4.js → diagram-3UASUU5V-U9bAFIJ2.js} +1 -1
- package/dist/assets/{diagram-ATOU4E4O-COI1PRUd.js → diagram-ATOU4E4O-DIvQNl6W.js} +1 -1
- package/dist/assets/{diagram-CDSNMT55-ehWBAAIO.js → diagram-CDSNMT55-D1eAUsVC.js} +1 -1
- package/dist/assets/{diagram-MLGK6HIB-CXxA6YAe.js → diagram-MLGK6HIB-CC57iz8g.js} +1 -1
- package/dist/assets/{diagram-MPIPVDR6-B6ANSQ5G.js → diagram-MPIPVDR6-COqJROu_.js} +1 -1
- package/dist/assets/{dist-DeIGO4lT.js → dist-7EayQbvC.js} +1 -1
- package/dist/assets/{dist-Bx7SWRAa.js → dist-BVV-jeSu.js} +1 -1
- package/dist/assets/{dist-BnY3MUXM.js → dist-Bs7ZI9qa.js} +1 -1
- package/dist/assets/{dist-DHjjPgmc.js → dist-DS1ADNp0.js} +1 -1
- package/dist/assets/{dist-Dn4ta1sK.js → dist-vES5R3jF.js} +1 -1
- package/dist/assets/{ebnfDiagram-ZINNZB2B-ByHtvU2q.js → ebnfDiagram-ZINNZB2B-COhiAOcD.js} +1 -1
- package/dist/assets/{elk-276RUBZZ-BF00ltRi.js → elk-276RUBZZ--k9tt4Y8.js} +1 -1
- package/dist/assets/{erDiagram-OPXOYQCR-nW_7R9Lb.js → erDiagram-OPXOYQCR-DogDOlr1.js} +1 -1
- package/dist/assets/eventmodeling-NTZA5JFV-g5Dqr_4m.js +1 -0
- package/dist/assets/flowDiagram-KWPJA3E3-DeQqcwdr.js +1 -0
- package/dist/assets/{ganttDiagram-FUAMR5RP-DaWxnbRm.js → ganttDiagram-FUAMR5RP-DWPN-w10.js} +1 -1
- package/dist/assets/{gitGraph-4MIJSDKK-F7iDxaID.js → gitGraph-4MIJSDKK-IowsEDei.js} +1 -1
- package/dist/assets/{gitGraphDiagram-X574FWY7-D9fTMDaK.js → gitGraphDiagram-X574FWY7-D8IVl7sG.js} +1 -1
- package/dist/assets/index-BcxXAO6O.css +1 -0
- package/dist/assets/{index-ffQ8fSEK.js → index-dQa3y9DP.js} +362 -362
- package/dist/assets/{info-A6RAGUB7-BIvkp14y.js → info-A6RAGUB7-DBswxtIl.js} +1 -1
- package/dist/assets/{infoDiagram-VRGFBTTK-CF3pSadX.js → infoDiagram-VRGFBTTK-Csc0WhdQ.js} +1 -1
- package/dist/assets/{ishikawaDiagram-OU5B5YK6-CnStwZlQ.js → ishikawaDiagram-OU5B5YK6-bAOsB3x8.js} +1 -1
- package/dist/assets/{journeyDiagram-ZHPQQLJL-X6FpP2mU.js → journeyDiagram-ZHPQQLJL-b6lwXh_m.js} +1 -1
- package/dist/assets/{kanban-definition-PNTS6WVX-DGW7MkGx.js → kanban-definition-PNTS6WVX-CZ_njTrU.js} +1 -1
- package/dist/assets/{line-G8J9PhiP.js → line-8Qcg4j_D.js} +1 -1
- package/dist/assets/{mermaid-parser.core-DlsoX-YC.js → mermaid-parser.core-w0jOWYGi.js} +3 -3
- package/dist/assets/{mermaid.core-DPC-93k6.js → mermaid.core-Dfy6e17u.js} +4 -4
- package/dist/assets/{mindmap-definition-NLK3R4M7-D-K5bSnd.js → mindmap-definition-NLK3R4M7-8OEbk66B.js} +1 -1
- package/dist/assets/{packet-AYTQ26CC-CmDsNYF8.js → packet-AYTQ26CC-DvA-gSZ5.js} +1 -1
- package/dist/assets/{pegDiagram-GJSIUBJH-3rBm1VWr.js → pegDiagram-GJSIUBJH-C2yGysK8.js} +1 -1
- package/dist/assets/{pie-WAS4IAKB-DwWpCstp.js → pie-WAS4IAKB-ZI_ZCGoe.js} +1 -1
- package/dist/assets/{pieDiagram-5QR66LMP-IolT-z46.js → pieDiagram-5QR66LMP-13lEAnZe.js} +1 -1
- package/dist/assets/{quadrantDiagram-O4NWA36T-Biq9fhdq.js → quadrantDiagram-O4NWA36T-DFsiAdxS.js} +1 -1
- package/dist/assets/{radar-RG4KPBEZ-DH0gPMqI.js → radar-RG4KPBEZ-CN_2Awtd.js} +1 -1
- package/dist/assets/{railroad-74A4TZTK-SDx9VkwS.js → railroad-74A4TZTK-UQIrDMbW.js} +1 -1
- package/dist/assets/railroad-abnf-HS5TGJTU-BRTRcWzf.js +1 -0
- package/dist/assets/railroad-ebnf-LZEXJU2U-XIH-PVQC.js +1 -0
- package/dist/assets/railroad-peg-WCYAUIDC-k-3lDxXn.js +1 -0
- package/dist/assets/{railroadDiagram-XR7U4H2S-kQzwizD6.js → railroadDiagram-XR7U4H2S-CZUBwfVD.js} +1 -1
- package/dist/assets/{requirementDiagram-PLB6GJNP-B3spDS6j.js → requirementDiagram-PLB6GJNP-Bn-ojhJX.js} +1 -1
- package/dist/assets/{sankeyDiagram-IPEJSGJF-DkXWUHlz.js → sankeyDiagram-IPEJSGJF-SBz95QpG.js} +1 -1
- package/dist/assets/{sequenceDiagram-PO4LG4MO-Dt80gEIt.js → sequenceDiagram-PO4LG4MO-CUN_wu-k.js} +1 -1
- package/dist/assets/{stateDiagram-v2-GCMORJYK-CG5xmXxG.js → stateDiagram-v2-GCMORJYK-C8vRpILT.js} +1 -1
- package/dist/assets/{swimlanes-2SLR337P-B3S4pJ9E.js → swimlanes-2SLR337P-D3Zm60vq.js} +1 -1
- package/dist/assets/swimlanesDiagram-TC7HE7FX-D2g-orla.js +8 -0
- package/dist/assets/{timeline-definition-EJHVYXUP-DuKW3pM-.js → timeline-definition-EJHVYXUP-Dwie9VJr.js} +1 -1
- package/dist/assets/{treeView-Q6P3EWNA-CeeuwKmy.js → treeView-Q6P3EWNA-CEApPye8.js} +1 -1
- package/dist/assets/{treemap-WGGIJYW6-CFK6V3lz.js → treemap-WGGIJYW6-B5jqGfsY.js} +1 -1
- package/dist/assets/{usecaseDiagram-POWQR4AR-CYbKz4kt.js → usecaseDiagram-POWQR4AR-BTWYJn_V.js} +1 -1
- package/dist/assets/{vennDiagram-UO4OBE2U-De8JmnbH.js → vennDiagram-UO4OBE2U-BJ9uRuyh.js} +1 -1
- package/dist/assets/{wardley-WFR3VGLG-BUvlimn0.js → wardley-WFR3VGLG-BF7f7pw5.js} +1 -1
- package/dist/assets/{wardleyDiagram-VNRHLVJA-e3jrcLF3.js → wardleyDiagram-VNRHLVJA-D_XPrKWr.js} +1 -1
- package/dist/assets/{xychartDiagram-PMCCYNJV-C1Q2Y2pt.js → xychartDiagram-PMCCYNJV-CccCedmI.js} +1 -1
- package/dist/index.html +2 -2
- package/docs/guide/en/v7.3.0.md +129 -0
- package/docs/guide/en/v8.0.0.md +119 -0
- package/docs/guide/ja/v7.3.0.md +125 -0
- package/docs/guide/ja/v8.0.0.md +107 -0
- package/package.json +1 -1
- package/server/backends/rawServingPlan.ts +9 -8
- package/server/backends/sharedApp/context.ts +2 -1
- package/server/backends/sharedApp/declare.ts +8 -3
- package/server/backends/sharedApp/headlessPreview.ts +64 -24
- package/server/backends/sharedApp/participate/app.ts +2 -1
- package/server/backends/sharedApp/signInStep.ts +5 -0
- package/server/backends/sharedApp/unpublish.ts +2 -1
- package/server/blueprint/collectionSnapshot.ts +37 -8
- package/server/blueprint/packs.ts +4 -1
- package/server/blueprint/routes.ts +99 -6
- package/server/blueprint/sourceFingerprint.ts +56 -0
- package/server/blueprint/sourceStatus.ts +38 -0
- package/server/config/agent-entry-routes.ts +3 -2
- package/server/config/config-routes.ts +25 -9
- package/server/config/config-schema.ts +9 -3
- package/server/config/dir-config-edit.ts +89 -0
- package/server/config/dir-config-write.ts +66 -0
- package/server/config/dir-config.ts +36 -9
- package/server/config/header-button-routes.ts +14 -25
- package/server/config/header-chip-routes.ts +12 -28
- package/server/config/header-config.ts +1 -1
- package/server/config/header-entry-changes.ts +105 -0
- package/server/files/mdPreviewReporter.ts +10 -2
- package/server/files/pathContainment.ts +12 -3
- package/server/files/tree-ops.ts +14 -3
- package/server/infra/shared-app-tool.ts +9 -1
- package/server/routes/app-routes.ts +15 -8
- package/server/routes/dir-config-entries-route.ts +85 -0
- package/server/routes/dir-config-write-route.ts +83 -0
- package/server/routes/dir-routes.ts +4 -1
- package/server/skills/mulmoterminal-config/SKILL.md +5 -4
- package/server/skills/mulmoterminal-dirs/SKILL.md +6 -1
- package/server/skills/mulmoterminal-header/SKILL.md +3 -3
- package/server/skills/mulmoterminal-keys/SKILL.md +1 -1
- package/server/skills/mulmoterminal-model/SKILL.md +2 -1
- package/server/skills/mulmoterminal-notify/SKILL.md +9 -8
- package/server/whatsNew/routes.ts +45 -3
- package/dist/assets/architecture-7GRP2DOG-BuiSlwXB.js +0 -1
- package/dist/assets/channel-BrsbZpfz.js +0 -1
- package/dist/assets/eventmodeling-NTZA5JFV-C74VV9Z5.js +0 -1
- package/dist/assets/flowDiagram-KWPJA3E3-dKJG6rhg.js +0 -1
- package/dist/assets/index-xE6PHMoe.css +0 -1
- package/dist/assets/railroad-abnf-HS5TGJTU-CCSPvBtI.js +0 -1
- package/dist/assets/railroad-ebnf-LZEXJU2U-DTWbjX18.js +0 -1
- package/dist/assets/railroad-peg-WCYAUIDC--dNY7xHy.js +0 -1
- package/dist/assets/swimlanesDiagram-TC7HE7FX-5BPq1RA-.js +0 -8
package/README.md
CHANGED
|
@@ -183,18 +183,19 @@ than as bytes (files within the session's working directory only):
|
|
|
183
183
|
**A line after the path is followed.** `src/a.ts:42`, `src/a.ts:42:7` (gcc, clang, `eslint -f unix`,
|
|
184
184
|
stack traces) and `src/a.ts(12,5)` (tsc) are one link. In the pane, and in the Files view, the file
|
|
185
185
|
opens as text with the caret on that line and column — an HTML page, an SVG or a table included, and a
|
|
186
|
-
tab reading in Preview switches to Edit.
|
|
186
|
+
tab reading in Preview switches to Edit. An image, a PDF, a video or an audio file has no line to go
|
|
187
|
+
to and simply opens as itself. A route that renders the file in a new tab (`.md`, `.json`,
|
|
187
188
|
`.csv`, `.html` with no cell enlarged) ignores the line. When the pane beside an enlarged cell takes
|
|
188
189
|
the click, the keyboard stays in the terminal; the full-screen Files view, with no terminal beside it,
|
|
189
190
|
puts it in the editor. (ESLint's default output puts the path on a line of its own, with no line number to follow.)
|
|
190
191
|
|
|
191
192
|
**While a grid cell is enlarged, the [Files pane](#files-view-browse--edit) takes the click first** — every
|
|
192
|
-
row above
|
|
193
|
-
|
|
193
|
+
row above, since the pane is the same editor with a Preview for Markdown, HTML and SVG, shows an
|
|
194
|
+
image as a picture and a PDF in a frame, and plays a video or an audio file with the browser's own
|
|
195
|
+
controls (seeking included, whatever the file's size). The file opens *beside* the terminal
|
|
194
196
|
that printed it, and the pane opens itself if it was closed. It declines, leaving the routing
|
|
195
|
-
above untouched, when nothing is enlarged, when the path is not under that cell's own directory
|
|
196
|
-
(the pane cannot walk above its root)
|
|
197
|
-
browser tab can play.
|
|
197
|
+
above untouched, when nothing is enlarged, or when the path is not under that cell's own directory
|
|
198
|
+
(the pane cannot walk above its root). A file too large to edit as text still offers **Open in OS**.
|
|
198
199
|
|
|
199
200
|
Highlighting in the Files view covers the JS/TS family, JSON and Markdown (the modes
|
|
200
201
|
`cmEditor.ts` bundles); other languages open as plain text.
|
|
@@ -823,7 +824,7 @@ The Settings modal (the gear button) persists per-user UI choices to `~/.mulmote
|
|
|
823
824
|
| `autoDirIcon` | Whether a project that sets no `icon` shows the favicon its repository already ships (`public/favicon.svg`, `apple-touch-icon.png`, a web manifest — first hit wins, ordered by how the image survives at 14px). **On by default**; Settings → **Directory appearance** has the switch. A single project opts out with `"icon": false` in its own `.mulmoterminal.json`, which this does not override. A key that was written and got it wrong shows nothing rather than falling back — a broken setting has to look broken. `true` / `false` only. |
|
|
824
825
|
| `cockpitLines` | `{ summary, prompt, response }` — how many lines each **cockpit-roster** row shows before it clamps (default `2` / `2` / `3`, each clamped to `1`–`20`). Raising them trades how many sessions fit on screen for reading a long one in place. Three steppers in Settings → **Waiting rows**. |
|
|
825
826
|
| `showLoadAverage` | Whether the grid header draws this machine's **load average** beside the 5h / 7d usage windows, as a percentage of its cores (`load 334%` = a 20-core machine with 66.8 runnable processes). **On by default**; amber at 100%, red at 200%, hover for the raw 1 / 5 / 15-minute figures. Settings → **Grid header read-outs** has the switch. A host that keeps no load average (Windows) shows nothing rather than `0%`, whatever this says. `true` / `false` only. |
|
|
826
|
-
| `remoteServer` | **Experimental.** The server runs on another machine than your browser (an SSH tunnel — [guide](https://receptron.github.io/mulmoterminal/guide/en/remote.html)): the actions that would act on the server's screen (the file dialog, the file manager, the OS app) are hidden or say why, and a dropped file is always uploaded. **Off unless `true`**; set it in the server's config. |
|
|
827
|
+
| `remoteServer` | **Experimental.** The server runs on another machine than your browser (an SSH tunnel — [guide](https://receptron.github.io/mulmoterminal/guide/en/remote.html)): the actions that would act on the server's screen (the file dialog, the file manager, the OS app) are hidden or say why, and a dropped file is always uploaded. **Off unless `true`**; Settings → **Sessions and background tasks** has the box (or set it in the server's config). |
|
|
827
828
|
| `fontFamily` | The **terminal font** every session renders in — a CSS font-family stack, e.g. `"'Cica', 'MS Gothic', monospace"`. Set it in Settings → **Terminal font**, applied at once; editing the file instead needs a **restart** (this config is read once at startup). Unset uses the built-in stack (JetBrains Mono / Fira Code / Menlo / Consolas, then CJK faces for Japanese, Korean and Chinese). Unlike the per-browser font **size**, this is one value for the whole host — it names fonts, and which fonts exist is a property of the machine. A directory can override it. See the [Configuration guide](https://receptron.github.io/mulmoterminal/guide/en/config.html#font-family). |
|
|
828
829
|
|
|
829
830
|
Every MulmoTerminal on the machine shares this one file, so an older build could save over a key a
|
|
@@ -1058,6 +1059,20 @@ they came from. It also names the keys it **dropped** (a color that isn't `#rrgg
|
|
|
1058
1059
|
of range) and the keys it doesn't read at all (`badgeColour`, a global-only setting) — which is
|
|
1059
1060
|
what tells "I never set that" apart from "I set it and it didn't take".
|
|
1060
1061
|
|
|
1062
|
+
**Changing it there.** Under the values, **Change here** is a form for the name, the seven chrome
|
|
1063
|
+
colors, how the header shows a running session (`headerStatusTint`) and its colour per status
|
|
1064
|
+
(`headerStatusColors`), the terminal theme and palette (`colors`), font size, font family, grid priority, the model its
|
|
1065
|
+
sessions start on (`provider` / `model`), the closing summary (`appendSystemPrompt`) and extra
|
|
1066
|
+
directories (`addDirs`), its icon, terminal background, and attention sounds (`sound` / `sounds`), and its header buttons,
|
|
1067
|
+
chips and command-palette entries (`buttons` / `chips` / `commands`) with the same editors the global
|
|
1068
|
+
lists use, its Skill menu (`skills`, in order), Mulmo menu decks (`decks`) and per-worktree variables
|
|
1069
|
+
(`worktreeEnv`) — every key the file can hold. **This checkout only** moves a key into
|
|
1070
|
+
`.mulmoterminal.local.json` (and **Share** moves it back). A cell's path menu has **This directory's
|
|
1071
|
+
settings**, which opens Settings on that directory. Each change is written to
|
|
1072
|
+
the directory's file at once and applies without a restart; **Use global** takes the key out
|
|
1073
|
+
again. A key `.mulmoterminal.local.json` already holds is written there. Keys the form doesn't
|
|
1074
|
+
show are left as they are, and a file that isn't a JSON object is not touched — fix it in Files.
|
|
1075
|
+
|
|
1061
1076
|
---
|
|
1062
1077
|
|
|
1063
1078
|
## Running
|
|
@@ -1342,11 +1357,13 @@ or changed (amber), and a notch where lines were removed, as VS Code's gutter sh
|
|
|
1342
1357
|
to date as you type. **Changes** in the header also shows the removed lines in place, as a unified
|
|
1343
1358
|
diff. Nothing is marked for a file outside git or one not yet committed.
|
|
1344
1359
|
|
|
1345
|
-
**HTML pages and
|
|
1360
|
+
**HTML pages, images, PDFs, video and audio show in the pane too.** An `.html` file has a **Preview** like a Markdown
|
|
1346
1361
|
file: the page itself, sandboxed as presentHtml pages are — its scripts run on an opaque origin with
|
|
1347
1362
|
no fetch/XHR; images and the curated CDN list still load, and so does an image it links beside it,
|
|
1348
|
-
while a relative stylesheet or script does not. An `.svg` previews as the picture it draws,
|
|
1349
|
-
rather than as "not text"
|
|
1363
|
+
while a relative stylesheet or script does not. An `.svg` previews as the picture it draws, a PNG, JPEG, GIF or WebP opens as the image
|
|
1364
|
+
rather than as "not text", a PDF opens in a frame, and a video or audio file plays with the
|
|
1365
|
+
browser's controls, seeking by range rather than fetching the whole file. A text file too large to edit
|
|
1366
|
+
says so and still offers **Open in OS**. A path to any of these clicked in terminal output opens in the pane when
|
|
1350
1367
|
it is up, so a chart an agent just wrote stays in the grid. They are served only under the workspace
|
|
1351
1368
|
or a terminal's directory, like every other file the app hands to the browser.
|
|
1352
1369
|
|
|
@@ -2080,6 +2097,7 @@ From a shell: `mulmoterminal room read <room>` · `room post <room> <text…> [-
|
|
|
2080
2097
|
| -------- | ------- |
|
|
2081
2098
|
| `GET\|POST /api/config` | User UI config (`cwdPresets`, `soundFile`, `soundKinds`, `sounds`, `prRepos`, `launchers`, `quickCommands`, `userMcpServers`, `providers`). |
|
|
2082
2099
|
| `GET /api/sound?kind=` · `/api/dir-sound?cwd=&kind=` · `/api/sound-preset/:id` · `/api/dir-config?cwd=` | Custom / per-directory / preset attention sound + per-dir config. `kind` selects a config entry, never a path. |
|
|
2100
|
+
| `PUT /api/dir-config` | The Settings form's save: `{ cwd, set: { key: value }, unset: [key] }` for the keys the form edits (`common/dirConfigForm.ts`), each validated like the Files pane's editor. Other keys and their order are kept; a file that isn't a JSON object answers 422 and is not written. Answers with the new `dir-config-detail`. |
|
|
2083
2101
|
| `GET /api/dir-config-detail?cwd=` | The same per-dir config, **plus** the settings a running terminal doesn't need (`provider`, `model`, `skills`, `addDirs`, header button/chip **labels**), **plus** which keys the file set and how each fared (applied / dropped in validation / not a setting at all). Read-only; backs the Settings modal's **Directory settings** preview. Unlike the other `?cwd=` routes this one does **not** fall back to the default workspace — it reports on the directory it was asked about, so a path that no longer exists comes back as `exists:false`. Sound paths and button commands stay server-side. |
|
|
2084
2102
|
| `GET /api/launch-options` | The Anthropic-compatible backends this server can reach, each with its models and — when it can't — the reason. Reports the **name** of the env var a key is read from, never the key. |
|
|
2085
2103
|
| `GET /api/update-status` | What is running and whether anything newer exists: `install` (`npm` / `git`), `version`, `commit` (a checkout's short HEAD sha), `latest` (npm, only when newer) and the one-line `notice`. Backs the header's **Update** badge and the Settings version line. Served from memory, recomputed at startup and every 3 hours — a long-running server started with `npx mulmoterminal@latest` is current when it starts, so only a later check can tell it a release shipped. `ready` is false until the first check lands. |
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// The adopt usecase's two checks. `survey`: .blueprint/adopt.json records the genre the person chose and how many
|
|
2
|
+
// findings chaff reports on the places today, measured again here; nothing in the repository has changed yet.
|
|
3
|
+
// `apply`: chaff.yaml names that genre and keeps what it had, .chaff-baseline.json shelves today's findings so chaff
|
|
4
|
+
// now reports none, and the workflow — when asked for — reports only what is new, with no more rights than that.
|
|
5
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { fromBase } from "./base.mjs";
|
|
8
|
+
import { placesIn, workflowProblems } from "./setup.mjs";
|
|
9
|
+
const { actionable, fail, findingsIn, readJson, runChaff } = await import(fromBase("chaff.mjs"));
|
|
10
|
+
const { lostLines } = await import(fromBase("config.mjs"));
|
|
11
|
+
|
|
12
|
+
const RECORD = ".blueprint/adopt.json";
|
|
13
|
+
const READABLE = ".blueprint/adopt.txt";
|
|
14
|
+
const CHECKED = ".blueprint/.adopt-checked";
|
|
15
|
+
const CONFIG = "chaff.yaml";
|
|
16
|
+
const BASELINE = ".chaff-baseline.json";
|
|
17
|
+
const WORKFLOW = ".github/workflows/chaff.yml";
|
|
18
|
+
const WITH_CI = "GitHub の PR に指摘を出すワークフローを作る";
|
|
19
|
+
|
|
20
|
+
const answers = readJson(".blueprint/answers.json", "the interview answers");
|
|
21
|
+
const { places, refused } = placesIn(answers.places);
|
|
22
|
+
if (refused.length > 0) fail(`these places are outside this folder: ${refused.join(", ")}`);
|
|
23
|
+
if (places.length === 0) fail("the answer names no place to check");
|
|
24
|
+
const absent = places.filter((place) => !existsSync(place));
|
|
25
|
+
if (absent.length > 0) fail(`not in this folder: ${absent.join(", ")}`);
|
|
26
|
+
const kinds = JSON.parse(readFileSync(join(process.env.BLUEPRINT_USECASE, "kinds.json"), "utf8")).kinds;
|
|
27
|
+
const genre = kinds.find((kind) => kind.option === answers.kind)?.genre;
|
|
28
|
+
if (!genre) fail(`the answer kind ${JSON.stringify(answers.kind)} is not one of the kinds in kinds.json`);
|
|
29
|
+
|
|
30
|
+
const textOrNull = (file) => (existsSync(file) ? readFileSync(file, "utf8") : null);
|
|
31
|
+
const findingsNow = (extra) => places.flatMap((place) => findingsIn(place, extra).filter(actionable));
|
|
32
|
+
const byRule = (findings) =>
|
|
33
|
+
Object.entries(findings.reduce((counts, finding) => ({ ...counts, [finding.rule]: (counts[finding.rule] ?? 0) + 1 }), {})).sort(
|
|
34
|
+
([a, x], [b, y]) => y - x || a.localeCompare(b),
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
const survey = () => {
|
|
38
|
+
const record = readJson(RECORD, '{ "genre", "findings" }');
|
|
39
|
+
const measured = findingsNow(["--genre", genre]);
|
|
40
|
+
if (record?.genre !== genre) fail(`${RECORD}: "genre" must be ${genre}, the genre of the kind the person chose`);
|
|
41
|
+
if (record?.findings !== measured.length) fail(`${RECORD}: "findings" is ${record?.findings}, but chaff reports ${measured.length} as ${genre} now`);
|
|
42
|
+
writeFileSync(
|
|
43
|
+
READABLE,
|
|
44
|
+
[`genre: ${genre}`, `findings: ${measured.length}`, ...byRule(measured).map(([rule, count]) => ` ${rule}: ${count}`), ""].join("\n"),
|
|
45
|
+
);
|
|
46
|
+
writeFileSync(CHECKED, JSON.stringify({ config: textOrNull(CONFIG), workflow: existsSync(WORKFLOW), findings: measured.length }) + "\n");
|
|
47
|
+
console.log(`${measured.length} finding(s) today as ${genre}`);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const recorded = () => {
|
|
51
|
+
try {
|
|
52
|
+
return JSON.parse(readFileSync(CHECKED, "utf8"));
|
|
53
|
+
} catch {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const workflowSide = (checked) => {
|
|
59
|
+
if (answers.ci === WITH_CI) {
|
|
60
|
+
if (!existsSync(WORKFLOW)) return [`${WORKFLOW} is missing`];
|
|
61
|
+
const template = readFileSync(join(process.env.BLUEPRINT_USECASE, "templates", "chaff.yml"), "utf8");
|
|
62
|
+
return workflowProblems(readFileSync(WORKFLOW, "utf8"), template, places).map((problem) => `${WORKFLOW}: ${problem}`);
|
|
63
|
+
}
|
|
64
|
+
return !checked.workflow && existsSync(WORKFLOW) ? [`${WORKFLOW} was added, but the person chose no workflow`] : [];
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const apply = () => {
|
|
68
|
+
const checked = existsSync(CHECKED) ? recorded() : null;
|
|
69
|
+
if (checked === null || typeof checked !== "object") fail("the survey step's record is missing: run that step again");
|
|
70
|
+
if (!existsSync(CONFIG)) fail(`${CONFIG} is missing`);
|
|
71
|
+
const run = runChaff(["rules", "--json"]);
|
|
72
|
+
if (run.code !== 0) fail(`chaff could not load ${CONFIG}:\n${run.stderr}`);
|
|
73
|
+
const detected = JSON.parse(run.stdout).detected?.genre;
|
|
74
|
+
const baseline = existsSync(BASELINE) ? readJson(BASELINE, '{ "entries" }') : null;
|
|
75
|
+
const left = findingsNow([]);
|
|
76
|
+
// The shelf is the survey's, taken under this chaff.yaml: shown with what it shelves, chaff reports what was measured.
|
|
77
|
+
const shelved = findingsNow(["--show-baseline"]);
|
|
78
|
+
const problems = [
|
|
79
|
+
...(detected === genre ? [] : [`${CONFIG} gives genre ${detected}, not ${genre}`]),
|
|
80
|
+
...lostLines(checked.config, readFileSync(CONFIG, "utf8"), ["genre"]).map((line) => `${CONFIG} lost a line it had: ${line.trim()}`),
|
|
81
|
+
...(baseline === null ? [`${BASELINE} is missing: run chaff baseline on the places`] : []),
|
|
82
|
+
...(baseline !== null && (baseline.entries?.length ?? 0) < checked.findings
|
|
83
|
+
? [`${BASELINE} shelves ${baseline.entries?.length ?? 0} finding(s), fewer than the ${checked.findings} measured`]
|
|
84
|
+
: []),
|
|
85
|
+
...(shelved.length === checked.findings
|
|
86
|
+
? []
|
|
87
|
+
: [
|
|
88
|
+
`with its baseline shown, chaff reports ${shelved.length} finding(s) under ${CONFIG}, not the ${checked.findings} measured: the settings or the shelf are not the ones the person approved`,
|
|
89
|
+
]),
|
|
90
|
+
...(left.length === 0
|
|
91
|
+
? []
|
|
92
|
+
: [
|
|
93
|
+
`chaff still reports ${left.length} finding(s) the baseline does not shelve: ${byRule(left)
|
|
94
|
+
.map(([rule, count]) => `${rule} ${count}`)
|
|
95
|
+
.join(", ")}`,
|
|
96
|
+
]),
|
|
97
|
+
...workflowSide(checked),
|
|
98
|
+
];
|
|
99
|
+
if (problems.length > 0) fail(problems.join("\n"));
|
|
100
|
+
console.log(`chaff is set up: today's ${checked.findings} finding(s) shelved, only new ones will be reported`);
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const mode = process.argv[2];
|
|
104
|
+
if (mode === "survey") survey();
|
|
105
|
+
else if (mode === "apply") apply();
|
|
106
|
+
else fail(`usage: adopt.mjs survey | apply (got ${JSON.stringify(mode)})`);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// The docs base holds the helpers every usecase on it shares (running chaff, reading Markdown sections).
|
|
2
|
+
// A usecase loads them from BLUEPRINT_BASE, which the executor sets for every check.
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { pathToFileURL } from "node:url";
|
|
5
|
+
|
|
6
|
+
if (!process.env.BLUEPRINT_BASE) {
|
|
7
|
+
console.error("BLUEPRINT_BASE is not set: run this check through the blueprint executor");
|
|
8
|
+
process.exit(1);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** The URL of a module in the docs base's checks/, for `await import(...)`. */
|
|
12
|
+
export const fromBase = (file) => pathToFileURL(join(process.env.BLUEPRINT_BASE, "checks", file)).href;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// The report tells the person what was set up and how chaff behaves from now on: it names chaff.yaml, the baseline,
|
|
2
|
+
// and the workflow when one was made.
|
|
3
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
4
|
+
import { fromBase } from "./base.mjs";
|
|
5
|
+
const { fail, readJson } = await import(fromBase("chaff.mjs"));
|
|
6
|
+
const { missingSections } = await import(fromBase("markdown.mjs"));
|
|
7
|
+
|
|
8
|
+
const REPORT = ".blueprint/adopt-report.md";
|
|
9
|
+
const WITH_CI = "GitHub の PR に指摘を出すワークフローを作る";
|
|
10
|
+
|
|
11
|
+
if (!existsSync(REPORT)) fail(`${REPORT} is missing`);
|
|
12
|
+
const text = readFileSync(REPORT, "utf8");
|
|
13
|
+
const missing = missingSections(text, [
|
|
14
|
+
["入れたもの", "What was set up"],
|
|
15
|
+
["棚に上げた指摘", "Shelved findings"],
|
|
16
|
+
["これから", "From now on"],
|
|
17
|
+
]);
|
|
18
|
+
if (missing.length > 0) fail(`${REPORT} lacks sections: ${missing.join(", ")}`);
|
|
19
|
+
const ci = readJson(".blueprint/answers.json", "the interview answers").ci === WITH_CI;
|
|
20
|
+
const named = ["chaff.yaml", ".chaff-baseline.json", ...(ci ? [".github/workflows/chaff.yml"] : [])].filter((file) => !text.includes(file));
|
|
21
|
+
if (named.length > 0) fail(`${REPORT} does not name: ${named.join(", ")}`);
|
|
22
|
+
console.log("the report names what was set up");
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// Types for setup.mjs, which the pack runs with plain node and the specs import.
|
|
2
|
+
export declare const placesIn: (answer: unknown) => { places: string[]; refused: string[] };
|
|
3
|
+
export declare const workflowFor: (template: string, places: readonly string[]) => string;
|
|
4
|
+
export declare const workflowProblems: (workflow: string, template: string, places: readonly string[]) => string[];
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// What adopting chaff in a folder of documents has to leave behind: the places chaff watches, and the workflow that
|
|
2
|
+
// reports on them. The workflow is the pack's template filled in with the places, exactly: a workflow is judged
|
|
3
|
+
// by being that one known file, not by reading arbitrary YAML for what might be unsafe in it.
|
|
4
|
+
import { posix } from "node:path";
|
|
5
|
+
|
|
6
|
+
// A place goes into the workflow's command line unquoted, so only characters with no meaning to a shell are allowed:
|
|
7
|
+
// letters and digits of any script, and . _ - / — never a leading - (it would read as an option).
|
|
8
|
+
const SAFE = /^[\p{L}\p{N}._/-]+$/u;
|
|
9
|
+
|
|
10
|
+
/** The places the answer names, one a line, as paths inside this folder; a line that leaves it or is unsafe is `refused`. */
|
|
11
|
+
export const placesIn = (answer) => {
|
|
12
|
+
const lines = String(answer ?? "")
|
|
13
|
+
.split("\n")
|
|
14
|
+
.map((line) => line.trim())
|
|
15
|
+
.filter((line) => line !== "");
|
|
16
|
+
const inside = (line) => {
|
|
17
|
+
const path = posix.normalize(line.replaceAll("\\", "/"));
|
|
18
|
+
if (posix.isAbsolute(path) || /^[A-Za-z]:/u.test(path) || path === ".." || path.startsWith("../")) return null;
|
|
19
|
+
const trimmed = path.replace(/\/$/u, "") || ".";
|
|
20
|
+
return SAFE.test(trimmed) && !trimmed.startsWith("-") ? trimmed : null;
|
|
21
|
+
};
|
|
22
|
+
return {
|
|
23
|
+
places: [...new Set(lines.map(inside).filter((path) => path !== null))],
|
|
24
|
+
refused: lines.filter((line) => inside(line) === null),
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/** The workflow the pack writes for `places`: its template with the places in the chaff run. */
|
|
29
|
+
export const workflowFor = (template, places) => String(template).replace("{{PATHS}}", places.join(" "));
|
|
30
|
+
|
|
31
|
+
// Line endings and trailing spaces aside (a line's trailing \r goes with its spaces): an editor's habits are not a different workflow.
|
|
32
|
+
const normalized = (text) =>
|
|
33
|
+
String(text)
|
|
34
|
+
.split("\n")
|
|
35
|
+
.map((line) => line.trimEnd())
|
|
36
|
+
.join("\n")
|
|
37
|
+
.trimEnd();
|
|
38
|
+
|
|
39
|
+
/** What is wrong with `workflow`: anything but the template filled in with `places`. */
|
|
40
|
+
export const workflowProblems = (workflow, template, places) => {
|
|
41
|
+
if (normalized(workflow) === normalized(workflowFor(template, places))) return [];
|
|
42
|
+
const expected = normalized(workflowFor(template, places)).split("\n");
|
|
43
|
+
const actual = normalized(workflow).split("\n");
|
|
44
|
+
const at = expected.findIndex((line, index) => actual[index] !== line);
|
|
45
|
+
const line = at < 0 ? expected.length + 1 : at + 1;
|
|
46
|
+
return [`it is not the pack's template filled in with the places (first difference at line ${line}): copy the template again`];
|
|
47
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"questions": [
|
|
3
|
+
{
|
|
4
|
+
"id": "places",
|
|
5
|
+
"label": "chaff に見させる文書(このフォルダの中のフォルダかファイルを 1 行に 1 つ)",
|
|
6
|
+
"why": "ここにある文書の今の指摘を棚に上げ、以後はここの新しい指摘だけが出る",
|
|
7
|
+
"kind": "text",
|
|
8
|
+
"lines": true,
|
|
9
|
+
"pick": "files"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"id": "kind",
|
|
13
|
+
"label": "どんな文書ですか",
|
|
14
|
+
"why": "文書の種類ごとの物差し(文の長さの上限、どの検査を動かすか)で chaff が測る",
|
|
15
|
+
"kind": "select",
|
|
16
|
+
"options": [
|
|
17
|
+
"手順書・ヘルプ・マニュアル",
|
|
18
|
+
"README・開発者向けの説明",
|
|
19
|
+
"仕様書・設計書",
|
|
20
|
+
"よくある質問",
|
|
21
|
+
"用語集",
|
|
22
|
+
"技術ブログ",
|
|
23
|
+
"会社のサイトの記事(オウンドメディア)",
|
|
24
|
+
"報告書・社内文書",
|
|
25
|
+
"提案書・企画書",
|
|
26
|
+
"議事録",
|
|
27
|
+
"プレスリリース・お知らせ",
|
|
28
|
+
"契約書・利用規約",
|
|
29
|
+
"規程・社内規則",
|
|
30
|
+
"論文"
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "ci",
|
|
35
|
+
"label": "GitHub の PR に指摘を出しますか",
|
|
36
|
+
"why": "作ると、PR を出すたびに chaff が動き、新しい指摘がその行に出る",
|
|
37
|
+
"kind": "select",
|
|
38
|
+
"options": ["GitHub の PR に指摘を出すワークフローを作る", "作らない(手元で npx chaffjs を動かす)"],
|
|
39
|
+
"needsPath": { "GitHub の PR に指摘を出すワークフローを作る": ".git" }
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"kinds": [
|
|
3
|
+
{ "option": "手順書・ヘルプ・マニュアル", "genre": "docs/manual" },
|
|
4
|
+
{ "option": "README・開発者向けの説明", "genre": "technical/readme" },
|
|
5
|
+
{ "option": "仕様書・設計書", "genre": "technical/spec" },
|
|
6
|
+
{ "option": "よくある質問", "genre": "docs/faq" },
|
|
7
|
+
{ "option": "用語集", "genre": "docs/glossary" },
|
|
8
|
+
{ "option": "技術ブログ", "genre": "blog/tech" },
|
|
9
|
+
{ "option": "会社のサイトの記事(オウンドメディア)", "genre": "blog/owned-media" },
|
|
10
|
+
{ "option": "報告書・社内文書", "genre": "business/report" },
|
|
11
|
+
{ "option": "提案書・企画書", "genre": "business/proposal" },
|
|
12
|
+
{ "option": "議事録", "genre": "business/meeting-notes" },
|
|
13
|
+
{ "option": "プレスリリース・お知らせ", "genre": "business/press-release" },
|
|
14
|
+
{ "option": "契約書・利用規約", "genre": "legal/contract" },
|
|
15
|
+
{ "option": "規程・社内規則", "genre": "legal/statute" },
|
|
16
|
+
{ "option": "論文", "genre": "academic/paper" }
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"slug": "adopt",
|
|
3
|
+
"kind": "usecase",
|
|
4
|
+
"title": "文書のフォルダに chaff を入れる(今ある指摘は棚に上げて)",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"description": "既にある文書のフォルダに chaff を入れる。文書の種類に合わせた chaff.yaml を置き、今ある指摘は chaff baseline で棚に上げて、新しい指摘だけが出るようにする。望めば、GitHub の PR の行に指摘が出るワークフローも作る。原本は変えない。",
|
|
7
|
+
"bases": ["docs"],
|
|
8
|
+
"report": ".blueprint/adopt-report.md"
|
|
9
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"presets": [
|
|
3
|
+
{
|
|
4
|
+
"id": "help-pages",
|
|
5
|
+
"title": "ヘルプのページに chaff を入れる",
|
|
6
|
+
"description": "見本のヘルプ(login.md と export.md)を「手順書・ヘルプ・マニュアル」として測り、今ある長すぎる文の指摘を棚に上げて、以後は新しい指摘だけが出るようにする。GitHub の PR に指摘を出すワークフローも作る。原本は変えない。",
|
|
7
|
+
"base": "docs",
|
|
8
|
+
"answers": {
|
|
9
|
+
"places": "login.md\nexport.md",
|
|
10
|
+
"kind": "手順書・ヘルプ・マニュアル",
|
|
11
|
+
"ci": "GitHub の PR に指摘を出すワークフローを作る"
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: blueprint-adopt-apply
|
|
3
|
+
description: "Set chaff up in the folder: chaff.yaml for the chosen genre, today's findings shelved in .chaff-baseline.json, and, when asked, a GitHub workflow that puts new findings on the pull request's lines."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Set chaff up
|
|
7
|
+
|
|
8
|
+
The person approved the setup in `.blueprint/adopt.json`. The documents stay exactly as they are: fixing what is
|
|
9
|
+
shelved is 「文書を整える」's work, later.
|
|
10
|
+
|
|
11
|
+
## 1. chaff.yaml
|
|
12
|
+
|
|
13
|
+
Write the folder's `chaff.yaml` with the genre from `.blueprint/adopt.json` and the documents' `language`
|
|
14
|
+
(`npx chaffjs init --genre <genre>` writes a commented one). If the folder already has one, set its `genre` to the
|
|
15
|
+
chosen one and **keep every other line it has** — the check refuses any other line of the old file that is gone. Add the rule
|
|
16
|
+
levels the person agreed to at the gate, nothing else.
|
|
17
|
+
|
|
18
|
+
## 2. Shelve today's findings
|
|
19
|
+
|
|
20
|
+
Run `sh <base pack>/checks/chaff.sh baseline <place> …` with every place. It writes `.chaff-baseline.json` in the
|
|
21
|
+
folder: the findings there today are not reported again; new ones are. Tell the person to commit it with
|
|
22
|
+
`chaff.yaml`.
|
|
23
|
+
|
|
24
|
+
## 3. The workflow — only when `ci` is 「GitHub の PR に指摘を出すワークフローを作る」
|
|
25
|
+
|
|
26
|
+
Copy `<usecase pack>/templates/chaff.yml` to `.github/workflows/chaff.yml`, replacing `{{PATHS}}` with the places
|
|
27
|
+
separated by spaces, and change nothing else: the check compares the file with the template filled in that way, line
|
|
28
|
+
for line. Its `permissions:` let the workflow read the documents (`contents: read`) and upload findings
|
|
29
|
+
(`security-events: write`), nothing more. A place whose name has a space or a character a shell reads (`$`, `;`, `*`,
|
|
30
|
+
quotes…) cannot go into the workflow: the interview refuses it, so ask the person to name a folder above it instead. When `ci` is 「作らない」, add nothing under `.github/`.
|
|
31
|
+
|
|
32
|
+
## 4. The report
|
|
33
|
+
|
|
34
|
+
Write `.blueprint/adopt-report.md` for the person, in their language and in plain words:
|
|
35
|
+
|
|
36
|
+
- `## 入れたもの` / `## What was set up` — `chaff.yaml` (the genre, and why), `.chaff-baseline.json`, and the
|
|
37
|
+
workflow `.github/workflows/chaff.yml` when one was made. The check looks for each file's name.
|
|
38
|
+
- `## 棚に上げた指摘` / `## Shelved findings` — how many were shelved, by rule, in plain words.
|
|
39
|
+
- `## これから` / `## From now on` — only new findings are reported (run `npx chaffjs <places>` by hand, or see them
|
|
40
|
+
on the pull request's lines); how to lower the shelf later (「文書を整える」, then `chaff baseline` again); that
|
|
41
|
+
the workflow needs code scanning enabled on the repository (a public repository has it; a private one needs
|
|
42
|
+
GitHub Advanced Security).
|
|
43
|
+
|
|
44
|
+
## Done when
|
|
45
|
+
|
|
46
|
+
`node <usecase pack>/checks/adopt.mjs apply` and then `node <usecase pack>/checks/report.mjs` (with `BLUEPRINT_BASE`
|
|
47
|
+
and `BLUEPRINT_USECASE` set) pass.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: blueprint-adopt-survey
|
|
3
|
+
description: "Measure what chaff reports on the named documents today, as the kind the person chose, and propose the setup — changing nothing yet."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Measure what is there today
|
|
7
|
+
|
|
8
|
+
`.blueprint/answers.json` names the places chaff will watch (`places`, a folder or a file a line), what kind of
|
|
9
|
+
documents they are (`kind`) and whether a GitHub workflow is wanted (`ci`). The person may not be an engineer: say
|
|
10
|
+
what you do in plain words.
|
|
11
|
+
|
|
12
|
+
Change nothing in the repository: this step only measures. The person approves the setup before anything is
|
|
13
|
+
written.
|
|
14
|
+
|
|
15
|
+
## Measure
|
|
16
|
+
|
|
17
|
+
The kind maps to a genre in `<usecase pack>/kinds.json`. For each place, run
|
|
18
|
+
`sh <base pack>/checks/chaff.sh <place> --genre <genre> --compact` and count the warnings and errors, by rule. Read a
|
|
19
|
+
few of them: a rule that reports mostly what the documents do on purpose may be worth turning down in `chaff.yaml`
|
|
20
|
+
rather than shelving — say which, and why, for the person to decide at the gate.
|
|
21
|
+
|
|
22
|
+
## Write `.blueprint/adopt.json`
|
|
23
|
+
|
|
24
|
+
```json
|
|
25
|
+
{ "genre": "docs/manual", "findings": 2, "proposal": "chaff.yaml に genre と language を書き、今の 2 件を棚に上げる。" }
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`findings` is the number of warnings and errors chaff reports on all the places together, as that genre, now; the
|
|
29
|
+
check measures it again. If the folder already has a `chaff.yaml` or a `.chaff-baseline.json`, say so in
|
|
30
|
+
`proposal`: the next step keeps what they hold.
|
|
31
|
+
|
|
32
|
+
## Done when
|
|
33
|
+
|
|
34
|
+
`node <usecase pack>/checks/adopt.mjs survey` (with `BLUEPRINT_BASE` and `BLUEPRINT_USECASE` set to the pack folders
|
|
35
|
+
from your prompt) passes. It writes `.blueprint/adopt.txt`, what the person reads before anything changes.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"steps": [
|
|
3
|
+
{
|
|
4
|
+
"id": "survey",
|
|
5
|
+
"title": "今の指摘を測る",
|
|
6
|
+
"description": "選んだ種類で、文書に今どれだけ指摘があるかを測り、入れる設定の案を書く。まだ何も変えない。",
|
|
7
|
+
"skill": "skills/survey",
|
|
8
|
+
"check": "node \"$BLUEPRINT_USECASE/checks/adopt.mjs\" survey"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"id": "apply",
|
|
12
|
+
"title": "chaff を入れる",
|
|
13
|
+
"description": "chaff.yaml を置き、今の指摘を .chaff-baseline.json に棚上げし、望めば PR に指摘を出すワークフローを足す。以後は新しい指摘だけが出ることを機械で確かめる。",
|
|
14
|
+
"skill": "skills/apply",
|
|
15
|
+
"check": "node \"$BLUEPRINT_USECASE/checks/adopt.mjs\" apply && node \"$BLUEPRINT_USECASE/checks/report.mjs\"",
|
|
16
|
+
"gates": ["review"],
|
|
17
|
+
"reads": [".blueprint/adopt.txt"]
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Checks the documents with chaff on every pull request, and puts each new finding on the line it is about.
|
|
2
|
+
# The findings already in the documents are shelved in .chaff-baseline.json, so only new ones appear.
|
|
3
|
+
name: chaff
|
|
4
|
+
|
|
5
|
+
on:
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
chaff:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
permissions:
|
|
15
|
+
contents: read
|
|
16
|
+
security-events: write
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v7
|
|
19
|
+
with:
|
|
20
|
+
persist-credentials: false
|
|
21
|
+
- uses: actions/setup-node@v7
|
|
22
|
+
with:
|
|
23
|
+
node-version: 24
|
|
24
|
+
- run: npx -y chaffjs@0.16 {{PATHS}} --sarif chaff.sarif
|
|
25
|
+
continue-on-error: true
|
|
26
|
+
- uses: github/codeql-action/upload-sarif@1c5b675653bb5c22dbe9b12b556ec555138e09fd # v4.38.1
|
|
27
|
+
with:
|
|
28
|
+
sarif_file: chaff.sarif
|
|
29
|
+
category: chaff
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Types for articles.mjs, which the pack runs with plain node and the specs import.
|
|
2
|
+
export type Article = { readonly address: string; readonly label: string; readonly body: string };
|
|
3
|
+
export type Row = { readonly old?: string | null; readonly new?: string | null; readonly change: string; readonly what?: string };
|
|
4
|
+
|
|
5
|
+
export declare const CHANGES: readonly string[];
|
|
6
|
+
export declare const articlesIn: (tree: unknown, text: string) => Article[];
|
|
7
|
+
export declare const mentions: (text: string, name: string) => boolean;
|
|
8
|
+
export declare const comparisonProblems: (rows: unknown, olds: readonly Article[], news: readonly Article[]) => string[];
|