jsmdcui 0.9.0 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,125 @@
2
2
 
3
3
  All notable user-visible changes to jsmdcui are documented here.
4
4
 
5
+ ## [0.11.1] - 2026-07-26
6
+
7
+ ### Changed
8
+
9
+ - Accept a bare `global.MDCUI_MAIN` path in forwarded build arguments by
10
+ automatically encoding non-primitive define values as JavaScript strings.
11
+
12
+ ## [0.11.0] - 2026-07-26
13
+
14
+ This release adds custom Markdown-app embedding for Bun single-file
15
+ executables, with explicit per-buffer selection between embedded and
16
+ filesystem modules in both TUI and WUI.
17
+
18
+ ### Added
19
+
20
+ - Add the build-time `global.MDCUI_MAIN` string define for embedding a custom
21
+ Markdown app together with its generated front, RPC, back, HTML, and server
22
+ modules. Build preparation resolves and validates the source, copies it into
23
+ the bundled demos, derives `global.MDCUI_MAIN_BASE`, and selects the app on a
24
+ no-argument launch.
25
+ - Add a bundling mode to `extractJs()` and `createWui()`. It emits a
26
+ browser-only `.tmpfs.js` front module and a `.tmpfi.js` installer that exposes
27
+ the front exports on `window`, then makes the bundled HTML load that entry.
28
+ - Add embedded WUI server startup and report whether WUI is starting an
29
+ embedded or external server before launch.
30
+ - Add `micro.CurPane().Buf.MdcuiModuleSource`, returning `embedded` or
31
+ `external`, and show the value in the bundled `showpath` example.
32
+ - Allow Unicode letters and numbers, including Chinese, in custom demo names
33
+ while continuing to reject whitespace and path separators.
34
+ - Show `global.MDCUI_MAIN` and the generated `global.MDCUI_MAIN_BASE` in
35
+ `--version` distribution settings.
36
+
37
+ ### Changed
38
+
39
+ - Track embedded-module selection per buffer. The configured demo uses
40
+ embedded TUI front/RPC and WUI server modules when its local byte length
41
+ matches the bundled Markdown. Missing or overwritten copies are written
42
+ first and then use embedded modules; other files and changed-size demos use
43
+ filesystem companions.
44
+ - Document presence-based `MDCUI_*` defines with `=1`, supported build-flag
45
+ combinations, and commands for switching a TUI-default build to WUI or a
46
+ WUI-default build to TUI.
47
+
48
+ ### Fixed
49
+
50
+ - Bundle and load the configured app's front, RPC, back, server, and dependency
51
+ graph so custom apps with companion imports can run from a single
52
+ executable.
53
+ - Keep unrelated Markdown buffers on external modules instead of reusing the
54
+ embedded main app's front and RPC modules.
55
+ - Use the bundled file's byte length after `MDCUI_OVERWRITE_DEMO` replaces a
56
+ stale local demo, ensuring that the overwritten app selects embedded
57
+ modules.
58
+ - Install WUI front exports on `window` without relying on the generated front
59
+ module's process-dependent or self-import path.
60
+
61
+ ## [0.10.1] - 2026-07-25
62
+
63
+ ### Fixed
64
+
65
+ - Resolve and prepare `--demo` and `--demo-*` selections before entering WUI
66
+ mode, so combinations such as `--wui --demo-todo` serve the selected demo
67
+ instead of falling back to `testapp.md`.
68
+
69
+ ## [0.10.0] - 2026-07-24
70
+
71
+ This update adds distribution-oriented defaults for shipping jsmdcui as a text
72
+ editor, terminal application, or browser application; makes WUI startup and
73
+ demo replacement explicit; and improves command-line control over rendering,
74
+ syntax highlighting, and single-executable builds.
75
+
76
+ ### Added
77
+
78
+ - Add `--mdcui` and `--tui` as aliases for `-encoding mdcui`, allowing an
79
+ explicit terminal Markdown UI request to override an editor-oriented
80
+ distribution default.
81
+ - Add `--overwrite-demo` as a modifier for `--demo` and the automatically
82
+ discovered `--demo-*` commands. It replaces an existing local demo with the
83
+ bundled copy before opening it.
84
+ - Add `--print-ui` for WUI launches. The generated TUI preview, raw ANSI, and
85
+ HTML are printed only when this flag is present.
86
+ - Add the `src/MDCUI_DEFAULT_EDIT` distribution marker. When present, Markdown
87
+ files open as editable UTF-8 text by default while `--mdcui` remains
88
+ available explicitly.
89
+ - Add presence-based single-executable build constants:
90
+ `MDCUI_DEFAULT_EDIT`, `MDCUI_DEFAULT_DEMO`, and
91
+ `MDCUI_DEFAULT_DEMO_WUI` select an editor, no-argument TUI demo, or
92
+ no-argument WUI demo default. `MDCUI_OVERWRITE_DEMO` optionally makes a
93
+ bundled demo replace its local copy.
94
+ - Add distribution documentation for shipping a customized root
95
+ `testapp.md` as a standalone terminal or browser application.
96
+ - Add regression coverage for the `--mdcui` alias, forced CLI filetypes,
97
+ non-overwriting and overwriting demos, and WUI demo replacement.
98
+
99
+ ### Changed
100
+
101
+ - Parse `--wui` through the normal command-line argument flow, so it can appear
102
+ before or after the Markdown filename.
103
+ - Make WUI startup quieter by default. It continues to report file generation
104
+ and the server URL, while full generated UI output is opt-in through
105
+ `--print-ui`.
106
+ - Make direct `runmd.mjs` launches recognize `--overwrite-demo` and
107
+ `--print-ui`. Demo replacement is limited to the implicit `testapp.md`;
108
+ explicitly named Markdown files are protected from replacement.
109
+ - Forward every extra argument after `--build-exe`, or after the target passed
110
+ to `--build-for`, to the underlying `bun build` command.
111
+ - Align the `start`, `tui`, and `wui` package scripts with the repository
112
+ launchers, and add a `clean` package script.
113
+ - Recommend choosing only one of the three `MDCUI_DEFAULT_*` distribution
114
+ modes per build, with `MDCUI_OVERWRITE_DEMO` treated as an optional modifier.
115
+ - Show effective `MDCUI_*` distribution settings in `--version` output,
116
+ including `MDCUI_DEFAULT_EDIT` enabled through either its build constant or
117
+ the `src/MDCUI_DEFAULT_EDIT` marker.
118
+
119
+ ### Fixed
120
+
121
+ - Make `-filetype <name>` actually override automatic syntax detection in
122
+ editor buffers and `--cat`, including input read from stdin.
123
+
5
124
  ## [0.9.0] - 2026-07-21
6
125
 
7
126
  This update expands Chrome DevTools Protocol automation for the terminal UI,
package/README.md CHANGED
@@ -163,6 +163,7 @@ bun src/index.js --wui testapp.md
163
163
  | `bun src/index.js --export-cdp-maze` | Write or overwrite `./cdp-maze.js` with the bundled CDP maze solver and exit. |
164
164
  | `bun src/index.js --demo-list` | List `testapp.md` and every bundled `demos/*.md` example with its command-line option, then exit. |
165
165
  | `bun src/index.js --demo` | Use local `testapp.md` when present, otherwise write the bundled demo; open it in the terminal UI and write five generated files beside it. |
166
+ | `bun src/index.js --overwrite-demo --demo` | Replace an existing local `testapp.md` with the bundled copy before opening it. `--overwrite-demo` can modify any `--demo-*` option. |
166
167
  | `bun src/index.js --demo-<filename>` | Load `demos/<filename>.md`; preserve an existing local copy or write the bundled copy, then open it and generate its five companion files. New files added under `demos/` work automatically. |
167
168
  | `bun src/index.js --demo-imgtool` | Compatibility alias for `--demo-image-processor`. |
168
169
  | `bun src/index.js --demo-imgtool-zh` | Compatibility alias for `--demo-image-processor.zh-TW`. |
@@ -170,6 +171,8 @@ bun src/index.js --wui testapp.md
170
171
  | `bun src/index.js --allow-url URL.md` | Download HTTP(S) Markdown to the current directory and, with Kitty mode enabled, download its HTTP(S) images; write 5 generated files and allow embedded code to run. Only use trusted URLs. |
171
172
  | `bun src/index.js --wui` | Use local `testapp.md` when present, otherwise write the bundled demo; write five generated files in the current directory, then print and serve a random URL. |
172
173
  | `bun src/index.js --wui app.md` | Write five generated files beside `app.md`, then print and serve a random URL. |
174
+ | `bun src/index.js --wui --demo-<filename>` | Load the selected bundled demo and serve it as a Web UI. |
175
+ | `bun src/index.js --wui --print-ui app.md` | Also print the generated TUI, raw ANSI, and HTML before starting the WUI server. |
173
176
  | `PORT=8080 bun src/index.js --wui app.md` | Start the browser UI on another port. |
174
177
  | `bun src/index.js` | Open the normal terminal editor with an empty buffer. |
175
178
 
@@ -742,6 +745,107 @@ or serve Markdown UI files that you trust.
742
745
  calls, but it does not protect the backend module from trusted local code and
743
746
  is not a substitute for authentication.
744
747
 
748
+ ## Distribution
749
+
750
+ ### Text editor distribution
751
+
752
+ Distributions intended primarily as text editors can include an empty
753
+ `src/MDCUI_DEFAULT_EDIT` file. When this marker exists, opening a `.md` file uses the
754
+ normal editable UTF-8 view instead of automatically entering `mdcui` mode.
755
+ Markdown UI support remains available explicitly with `--mdcui` or `--tui`;
756
+ both are equivalent to `-encoding mdcui`.
757
+
758
+ ### Build-time distribution constants
759
+
760
+ The following switch defines are presence-based: the program checks whether
761
+ they were passed, not whether their values are true. Consequently, `=0` and
762
+ `=false` still enable a switch. Omit a define entirely to disable it. Examples
763
+ use `=1` to make this explicit.
764
+
765
+ - `MDCUI_DEFAULT_EDIT=1`: open files as editable text by default.
766
+ - `MDCUI_DEFAULT_DEMO=1`: add `--demo` when launched without arguments.
767
+ - `MDCUI_DEFAULT_DEMO_WUI=1`: add `--wui` when launched without arguments.
768
+ - `MDCUI_OVERWRITE_DEMO=1`: add `--overwrite-demo`; this modifies a selected
769
+ demo but does not select one by itself.
770
+ - `global.MDCUI_MAIN=<path>.md`: embed a custom Markdown application and its
771
+ generated front, RPC, back, HTML, and server modules. When this define is
772
+ forwarded after `--build-exe` or `--build-for`, a non-primitive value such as
773
+ a bare path is automatically encoded as a JavaScript string. An explicitly
774
+ quoted string remains supported.
775
+ - `global.MDCUI_MAIN_BASE`: internal define generated automatically from
776
+ `global.MDCUI_MAIN`; do not pass it manually.
777
+
778
+ Place every build define after `--build-exe`, or after the target argument of
779
+ `--build-for`. Choose at most one of `MDCUI_DEFAULT_EDIT`,
780
+ `MDCUI_DEFAULT_DEMO`, and `MDCUI_DEFAULT_DEMO_WUI`.
781
+
782
+ | Build defines | No-argument launch | Open the same app in the other UI |
783
+ | --- | --- | --- |
784
+ | none | normal CLI/TUI | `./mdcui --wui app.md` |
785
+ | `MDCUI_DEFAULT_EDIT=1` | text editor | `./mdcui --tui app.md` |
786
+ | `MDCUI_DEFAULT_DEMO=1` | `testapp.md` TUI | `./mdcui --wui --demo` |
787
+ | `MDCUI_DEFAULT_DEMO_WUI=1` | `testapp.md` WUI | `./mdcui --tui --demo` |
788
+ | `global.MDCUI_MAIN=../中文工具.md` | embedded custom TUI | `./mdcui --wui --demo-中文工具` |
789
+ | MAIN plus `MDCUI_DEFAULT_DEMO_WUI=1` | embedded custom WUI | `./mdcui --tui --demo-中文工具` |
790
+
791
+ Any explicit runtime argument suppresses the no-argument demo/WUI injection.
792
+ That is why the commands in the last column repeat `--demo` or
793
+ `--demo-中文工具`; `./mdcui --wui` by itself does not implicitly select a custom
794
+ main application.
795
+
796
+ To package `../中文工具.md` as a TUI by default:
797
+
798
+ ```sh
799
+ bun src/index.js --build-exe \
800
+ --define global.MDCUI_MAIN=../中文工具.md
801
+
802
+ ./mdcui
803
+ ./mdcui --wui --demo-中文工具
804
+ ```
805
+
806
+ To package the same application as a WUI by default and explicitly switch back
807
+ to its TUI:
808
+
809
+ ```sh
810
+ bun src/index.js --build-exe \
811
+ --define global.MDCUI_MAIN=../中文工具.md \
812
+ --define MDCUI_DEFAULT_DEMO_WUI=1
813
+
814
+ ./mdcui
815
+ ./mdcui --tui --demo-中文工具
816
+ ```
817
+
818
+ The `MDCUI_MAIN` basename must end with lowercase `.md`. Its demo-name portion
819
+ must start with a Unicode letter or number and may contain Unicode
820
+ letters/numbers (including Chinese), combining marks, dots, underscores, and
821
+ hyphens. Whitespace and path separators are not allowed.
822
+
823
+ When the configured custom demo is selected and its local Markdown byte length
824
+ matches the embedded copy, TUI uses the embedded front/RPC modules and WUI uses
825
+ the embedded server. A missing demo, or one selected with
826
+ `MDCUI_OVERWRITE_DEMO=1`, is first written from the embedded copy and then uses
827
+ embedded modules. A different byte length prints a warning and uses filesystem
828
+ companion modules. Directly opening `./mdcui app.md` or
829
+ `./mdcui --wui app.md` has no demo provenance and therefore uses filesystem
830
+ modules even if the basename matches `MDCUI_MAIN`.
831
+
832
+ To retain the older repository-root `testapp.md` distribution instead, build a
833
+ TUI with:
834
+
835
+ ```sh
836
+ bun src/index.js --build-exe \
837
+ --define MDCUI_DEFAULT_DEMO=1 \
838
+ --define MDCUI_OVERWRITE_DEMO=1
839
+ ```
840
+
841
+ For a default WUI, replace `MDCUI_DEFAULT_DEMO` with
842
+ `MDCUI_DEFAULT_DEMO_WUI`.
843
+
844
+ You can rename and distribute the resulting binary. It contains the Bun
845
+ runtime, jsmdcui, the packed runtime assets, and the configured demo or custom
846
+ main application. The target directory must remain writable because launching
847
+ an application creates its Markdown file and generated companion files there.
848
+
745
849
  ## Development
746
850
 
747
851
  ```sh
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jsmdcui",
3
- "version": "0.9.0",
3
+ "version": "0.11.1",
4
4
  "description": "Markdown as a Common UI for Terminals and Web Browsers",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -9,9 +9,11 @@
9
9
  "jsmdcui": "./src/index.js"
10
10
  },
11
11
  "scripts": {
12
- "start": "bun ./src/index.js",
13
- "tui": "bun ./src/index.js ./testapp.md",
14
- "wui": "bun ./runmd.mjs",
15
- "check": "node --check ./src/index.js"
12
+ "start": "bun ./src/index.js --demo",
13
+ "tui": "bun ./tui",
14
+ "wui": "bun ./wui",
15
+ "edit": "bun ./edit",
16
+ "check": "bun ./src/index.js --check",
17
+ "clean": "bun ./clean.sh"
16
18
  }
17
19
  }
package/runmd.mjs CHANGED
@@ -29,10 +29,10 @@ async function readTemplate(pathname)
29
29
  await Bun.file(path.join(REPO_ROOT, pathname)).text()
30
30
  }
31
31
 
32
- export async function readMarkdownInput(mdpath)
32
+ export async function readMarkdownInput(mdpath, overwriteDemo = false)
33
33
  {
34
34
  const file = Bun.file(mdpath);
35
- if (await file.exists()) return await file.text();
35
+ if (!overwriteDemo && await file.exists()) return await file.text();
36
36
  const assetName = path.basename(mdpath);
37
37
  const internalText = readInternalAssetText(assetName);
38
38
  if (internalText != null) {
@@ -50,30 +50,40 @@ export async function readMarkdownInput(mdpath)
50
50
  }
51
51
 
52
52
 
53
- export async function main(tuiWidth=30)
53
+ export async function main(tuiWidth=30, {
54
+ mdpath: requestedMdpath = null,
55
+ overwriteDemo = process.argv.includes("--overwrite-demo"),
56
+ printUi = process.argv.includes("--print-ui"),
57
+ useBundledMdcuiServer = false,
58
+ } = {})
54
59
  {
55
- const mdpath = process.argv.filter(i=>i.endsWith('.md'))[0] || 'testapp.md'
60
+ const explicitMdpath = process.argv.find(i=>i.endsWith('.md'))
61
+ const mdpath = requestedMdpath || explicitMdpath || 'testapp.md'
56
62
 
57
63
 
58
64
  // 1. Read markdown file
59
65
  console.error('Reading:',mdpath)
60
- let md = await readMarkdownInput(mdpath)
66
+ let md = await readMarkdownInput(mdpath, overwriteDemo && !requestedMdpath && !explicitMdpath)
61
67
 
62
68
  // 2. Extract js files
63
69
  md = await extractJs(md,mdpath);
64
70
 
65
71
  // 3. Create Terminal UI
66
72
  let tui = createTui(md,tuiWidth)
67
- cse(mda("\n# TUI"))
68
- cse(tui)
69
- cse(mda('## TUI raw'))
70
- cse(jss(tui))
73
+ if (printUi) {
74
+ cse(mda("\n# TUI"))
75
+ cse(tui)
76
+ cse(mda('## TUI raw'))
77
+ cse(jss(tui))
78
+ }
71
79
 
72
80
 
73
81
  // 4. Create Web UI
74
82
  let wui = await createWui(md,mdpath)
75
- cse(mda('\n# HTML'))
76
- cse(wui)
83
+ if (printUi) {
84
+ cse(mda('\n# HTML'))
85
+ cse(wui)
86
+ }
77
87
 
78
88
 
79
89
  /*
@@ -90,7 +100,20 @@ export async function main(tuiWidth=30)
90
100
 
91
101
 
92
102
  const serverPath = mdpath + "-server.js"
93
- const svmod = await import(pathToFileURL(path.resolve(serverPath)).href)
103
+ const useEmbeddedMdcuiServer = Boolean(
104
+ global.MDCUI_MAIN && useBundledMdcuiServer
105
+ )
106
+ cse(
107
+ `[mdcui] Starting ${useEmbeddedMdcuiServer ? "embedded" : "external"} `
108
+ + `WUI server: ${
109
+ useEmbeddedMdcuiServer
110
+ ? String(global.MDCUI_MAIN)
111
+ : path.resolve(serverPath)
112
+ }`
113
+ )
114
+ const svmod = useEmbeddedMdcuiServer
115
+ ? await import(global.MDCUI_MAIN + "-server.js")
116
+ : await import(pathToFileURL(path.resolve(serverPath)).href)
94
117
 
95
118
  cse("\n\n"+mda('# Server'))
96
119
  svmod.main();
@@ -100,7 +123,7 @@ export async function main(tuiWidth=30)
100
123
  // Exports
101
124
 
102
125
 
103
- export async function extractJs(md,mdpath)
126
+ export async function extractJs(md,mdpath,{ bundling = false } = {})
104
127
  {
105
128
  const mdb = path.basename(mdpath)
106
129
 
@@ -119,16 +142,23 @@ export async function extractJs(md,mdpath)
119
142
  }
120
143
  )
121
144
 
145
+ const frontSource = sctags
122
146
  sctags = "#!/usr/bin/env bun" + `
123
147
 
124
148
  import { rpc as wuiRpcClient } from "./${mdb}-rpc.js";
125
- let rpc = "${mdb}"
149
+ let rpc = null
126
150
  if(globalThis.process)
127
- rpc = await import("./"+rpc+".back.js") ;
151
+ {
152
+ rpc = await import(
153
+ "./" +
154
+ (global.MDCUI_MAIN_BASE||"${mdb}") +
155
+ ".back.js"
156
+ ) ;
157
+ }
128
158
  else
129
159
  rpc = wuiRpcClient ;
130
160
 
131
- ` + sctags + `
161
+ ` + frontSource + `
132
162
 
133
163
  if (typeof window !== "undefined")
134
164
  {
@@ -143,6 +173,28 @@ export async function extractJs(md,mdpath)
143
173
 
144
174
  await Bun.write(sctagsp,sctags);
145
175
  logWroteFile("front", sctagsp)
176
+
177
+ if (bundling) {
178
+ const bundledFrontSource = "#!/usr/bin/env bun" + `
179
+
180
+ import { rpc as wuiRpcClient } from "./${mdb}-rpc.js";
181
+ const rpc = wuiRpcClient;
182
+
183
+ ` + frontSource
184
+ const bundledFrontPath = mdpath + ".tmpfs.js"
185
+ await Bun.write(bundledFrontPath, bundledFrontSource)
186
+ logWroteFile("bundling front", bundledFrontPath)
187
+
188
+ const bundledImportPath = mdpath + ".tmpfi.js"
189
+ await Bun.write(
190
+ bundledImportPath,
191
+ `import * as frontMod from "./${mdb}.tmpfs.js";
192
+
193
+ Object.assign(window, frontMod);
194
+ `,
195
+ )
196
+ logWroteFile("bundling import", bundledImportPath)
197
+ }
146
198
 
147
199
  sctagsp = mdpath + ".back.js"
148
200
  sctags = "#!/usr/bin/env bun\n\n"
@@ -345,7 +397,7 @@ export function wrapWuiHeadingSections(html)
345
397
  return output;
346
398
  }
347
399
 
348
- export async function createWui(md,mdpath) // HTML
400
+ export async function createWui(md,mdpath,{ bundling = false } = {}) // HTML
349
401
  {
350
402
  const eventsById = fenceEventMap(md)
351
403
 
@@ -388,7 +440,8 @@ img {
388
440
  height: auto;
389
441
  }
390
442
  </style>`;
391
- const moduleScript = `<scr`+`ipt type="module" src="./${mdb}.front.js"></scr`+`ipt>`;
443
+ const moduleEntry = bundling ? `${mdb}.tmpfi.js` : `${mdb}.front.js`;
444
+ const moduleScript = `<scr`+`ipt type="module" src="./${moduleEntry}"></scr`+`ipt>`;
392
445
  const isFullHtmlDocument = /^\s*<!doctype html>/i.test(md);
393
446
  if (!isFullHtmlDocument) {
394
447
  md = `<!doctype html>
@@ -163,6 +163,7 @@ bun src/index.js --wui testapp.md
163
163
  | `bun src/index.js --export-cdp-maze` | Write or overwrite `./cdp-maze.js` with the bundled CDP maze solver and exit. |
164
164
  | `bun src/index.js --demo-list` | List `testapp.md` and every bundled `demos/*.md` example with its command-line option, then exit. |
165
165
  | `bun src/index.js --demo` | Use local `testapp.md` when present, otherwise write the bundled demo; open it in the terminal UI and write five generated files beside it. |
166
+ | `bun src/index.js --overwrite-demo --demo` | Replace an existing local `testapp.md` with the bundled copy before opening it. `--overwrite-demo` can modify any `--demo-*` option. |
166
167
  | `bun src/index.js --demo-<filename>` | Load `demos/<filename>.md`; preserve an existing local copy or write the bundled copy, then open it and generate its five companion files. New files added under `demos/` work automatically. |
167
168
  | `bun src/index.js --demo-imgtool` | Compatibility alias for `--demo-image-processor`. |
168
169
  | `bun src/index.js --demo-imgtool-zh` | Compatibility alias for `--demo-image-processor.zh-TW`. |
@@ -170,6 +171,8 @@ bun src/index.js --wui testapp.md
170
171
  | `bun src/index.js --allow-url URL.md` | Download HTTP(S) Markdown to the current directory and, with Kitty mode enabled, download its HTTP(S) images; write 5 generated files and allow embedded code to run. Only use trusted URLs. |
171
172
  | `bun src/index.js --wui` | Use local `testapp.md` when present, otherwise write the bundled demo; write five generated files in the current directory, then print and serve a random URL. |
172
173
  | `bun src/index.js --wui app.md` | Write five generated files beside `app.md`, then print and serve a random URL. |
174
+ | `bun src/index.js --wui --demo-<filename>` | Load the selected bundled demo and serve it as a Web UI. |
175
+ | `bun src/index.js --wui --print-ui app.md` | Also print the generated TUI, raw ANSI, and HTML before starting the WUI server. |
173
176
  | `PORT=8080 bun src/index.js --wui app.md` | Start the browser UI on another port. |
174
177
  | `bun src/index.js` | Open the normal terminal editor with an empty buffer. |
175
178
 
@@ -742,6 +745,107 @@ or serve Markdown UI files that you trust.
742
745
  calls, but it does not protect the backend module from trusted local code and
743
746
  is not a substitute for authentication.
744
747
 
748
+ ## Distribution
749
+
750
+ ### Text editor distribution
751
+
752
+ Distributions intended primarily as text editors can include an empty
753
+ `src/MDCUI_DEFAULT_EDIT` file. When this marker exists, opening a `.md` file uses the
754
+ normal editable UTF-8 view instead of automatically entering `mdcui` mode.
755
+ Markdown UI support remains available explicitly with `--mdcui` or `--tui`;
756
+ both are equivalent to `-encoding mdcui`.
757
+
758
+ ### Build-time distribution constants
759
+
760
+ The following switch defines are presence-based: the program checks whether
761
+ they were passed, not whether their values are true. Consequently, `=0` and
762
+ `=false` still enable a switch. Omit a define entirely to disable it. Examples
763
+ use `=1` to make this explicit.
764
+
765
+ - `MDCUI_DEFAULT_EDIT=1`: open files as editable text by default.
766
+ - `MDCUI_DEFAULT_DEMO=1`: add `--demo` when launched without arguments.
767
+ - `MDCUI_DEFAULT_DEMO_WUI=1`: add `--wui` when launched without arguments.
768
+ - `MDCUI_OVERWRITE_DEMO=1`: add `--overwrite-demo`; this modifies a selected
769
+ demo but does not select one by itself.
770
+ - `global.MDCUI_MAIN=<path>.md`: embed a custom Markdown application and its
771
+ generated front, RPC, back, HTML, and server modules. When this define is
772
+ forwarded after `--build-exe` or `--build-for`, a non-primitive value such as
773
+ a bare path is automatically encoded as a JavaScript string. An explicitly
774
+ quoted string remains supported.
775
+ - `global.MDCUI_MAIN_BASE`: internal define generated automatically from
776
+ `global.MDCUI_MAIN`; do not pass it manually.
777
+
778
+ Place every build define after `--build-exe`, or after the target argument of
779
+ `--build-for`. Choose at most one of `MDCUI_DEFAULT_EDIT`,
780
+ `MDCUI_DEFAULT_DEMO`, and `MDCUI_DEFAULT_DEMO_WUI`.
781
+
782
+ | Build defines | No-argument launch | Open the same app in the other UI |
783
+ | --- | --- | --- |
784
+ | none | normal CLI/TUI | `./mdcui --wui app.md` |
785
+ | `MDCUI_DEFAULT_EDIT=1` | text editor | `./mdcui --tui app.md` |
786
+ | `MDCUI_DEFAULT_DEMO=1` | `testapp.md` TUI | `./mdcui --wui --demo` |
787
+ | `MDCUI_DEFAULT_DEMO_WUI=1` | `testapp.md` WUI | `./mdcui --tui --demo` |
788
+ | `global.MDCUI_MAIN=../中文工具.md` | embedded custom TUI | `./mdcui --wui --demo-中文工具` |
789
+ | MAIN plus `MDCUI_DEFAULT_DEMO_WUI=1` | embedded custom WUI | `./mdcui --tui --demo-中文工具` |
790
+
791
+ Any explicit runtime argument suppresses the no-argument demo/WUI injection.
792
+ That is why the commands in the last column repeat `--demo` or
793
+ `--demo-中文工具`; `./mdcui --wui` by itself does not implicitly select a custom
794
+ main application.
795
+
796
+ To package `../中文工具.md` as a TUI by default:
797
+
798
+ ```sh
799
+ bun src/index.js --build-exe \
800
+ --define global.MDCUI_MAIN=../中文工具.md
801
+
802
+ ./mdcui
803
+ ./mdcui --wui --demo-中文工具
804
+ ```
805
+
806
+ To package the same application as a WUI by default and explicitly switch back
807
+ to its TUI:
808
+
809
+ ```sh
810
+ bun src/index.js --build-exe \
811
+ --define global.MDCUI_MAIN=../中文工具.md \
812
+ --define MDCUI_DEFAULT_DEMO_WUI=1
813
+
814
+ ./mdcui
815
+ ./mdcui --tui --demo-中文工具
816
+ ```
817
+
818
+ The `MDCUI_MAIN` basename must end with lowercase `.md`. Its demo-name portion
819
+ must start with a Unicode letter or number and may contain Unicode
820
+ letters/numbers (including Chinese), combining marks, dots, underscores, and
821
+ hyphens. Whitespace and path separators are not allowed.
822
+
823
+ When the configured custom demo is selected and its local Markdown byte length
824
+ matches the embedded copy, TUI uses the embedded front/RPC modules and WUI uses
825
+ the embedded server. A missing demo, or one selected with
826
+ `MDCUI_OVERWRITE_DEMO=1`, is first written from the embedded copy and then uses
827
+ embedded modules. A different byte length prints a warning and uses filesystem
828
+ companion modules. Directly opening `./mdcui app.md` or
829
+ `./mdcui --wui app.md` has no demo provenance and therefore uses filesystem
830
+ modules even if the basename matches `MDCUI_MAIN`.
831
+
832
+ To retain the older repository-root `testapp.md` distribution instead, build a
833
+ TUI with:
834
+
835
+ ```sh
836
+ bun src/index.js --build-exe \
837
+ --define MDCUI_DEFAULT_DEMO=1 \
838
+ --define MDCUI_OVERWRITE_DEMO=1
839
+ ```
840
+
841
+ For a default WUI, replace `MDCUI_DEFAULT_DEMO` with
842
+ `MDCUI_DEFAULT_DEMO_WUI`.
843
+
844
+ You can rename and distribute the resulting binary. It contains the Bun
845
+ runtime, jsmdcui, the packed runtime assets, and the configured demo or custom
846
+ main application. The target directory must remain writable because launching
847
+ an application creates its Markdown file and generated companion files there.
848
+
745
849
  ## Development
746
850
 
747
851
  ```sh
@@ -69,8 +69,10 @@ micro.on("init", () => {
69
69
 
70
70
  //micro.alert(micro.getLine())
71
71
  const path = bp?.Buf?.Path || "(no path)";
72
+ const moduleSource =
73
+ micro.CurPane()?.Buf?.MdcuiModuleSource || "external";
72
74
  const loc = bp?.CursorLocation?.() || "+1.0:1";
73
- micro.alert(`${path}\n${loc}`)
75
+ micro.alert(`${path}\nMdcuiModuleSource: ${moduleSource}\n${loc}`)
74
76
 
75
77
  });
76
78