jsmdcui 0.10.1 → 0.11.2
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 +73 -0
- package/README.md +88 -29
- package/package.json +1 -1
- package/runmd.mjs +51 -7
- package/runtime/help/help.md +88 -29
- package/runtime/jsplugins/example/example.js +3 -1
- package/single-exe/README.md +82 -25
- package/single-exe/README.md-rpc.js +623 -0
- package/single-exe/README.md-server.js +127 -0
- package/single-exe/README.md.back.js +2 -0
- package/single-exe/README.md.front.js +27 -0
- package/single-exe/README.md.html +325 -0
- package/single-exe/compiled.js +59 -1
- package/src/build-args.js +40 -0
- package/src/index.js +237 -22
- package/src/plugins/js-bridge.js +5 -0
- package/tests/compiled-runtime.test.js +132 -1
- package/tests/demo.test.js +136 -1
- package/tests/js-plugin-prompts.test.js +30 -0
- package/tests/wui-responsive-images.test.js +21 -2
- package/tests/wui.test.js +31 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,79 @@
|
|
|
2
2
|
|
|
3
3
|
All notable user-visible changes to jsmdcui are documented here.
|
|
4
4
|
|
|
5
|
+
## [0.11.2] - 2026-07-26
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Add `--build-md-exe <file.md>` as a convenience alias for building a
|
|
10
|
+
current-platform executable with `global.MDCUI_MAIN` set to the specified
|
|
11
|
+
Markdown app.
|
|
12
|
+
- Add `--build-md-for <platform> <file.md>` for the equivalent
|
|
13
|
+
cross-compilation workflow. Both aliases expand into the existing build
|
|
14
|
+
arguments before generated application files are written.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- Fix the final executable existence check for Windows builds by checking the
|
|
19
|
+
`.exe` output path for Windows targets, or for native Windows builds when no
|
|
20
|
+
target is specified.
|
|
21
|
+
|
|
22
|
+
## [0.11.1] - 2026-07-26
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- Accept a bare `global.MDCUI_MAIN` path in forwarded build arguments by
|
|
27
|
+
automatically encoding non-primitive define values as JavaScript strings.
|
|
28
|
+
|
|
29
|
+
## [0.11.0] - 2026-07-26
|
|
30
|
+
|
|
31
|
+
This release adds custom Markdown-app embedding for Bun single-file
|
|
32
|
+
executables, with explicit per-buffer selection between embedded and
|
|
33
|
+
filesystem modules in both TUI and WUI.
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
|
|
37
|
+
- Add the build-time `global.MDCUI_MAIN` string define for embedding a custom
|
|
38
|
+
Markdown app together with its generated front, RPC, back, HTML, and server
|
|
39
|
+
modules. Build preparation resolves and validates the source, copies it into
|
|
40
|
+
the bundled demos, derives `global.MDCUI_MAIN_BASE`, and selects the app on a
|
|
41
|
+
no-argument launch.
|
|
42
|
+
- Add a bundling mode to `extractJs()` and `createWui()`. It emits a
|
|
43
|
+
browser-only `.tmpfs.js` front module and a `.tmpfi.js` installer that exposes
|
|
44
|
+
the front exports on `window`, then makes the bundled HTML load that entry.
|
|
45
|
+
- Add embedded WUI server startup and report whether WUI is starting an
|
|
46
|
+
embedded or external server before launch.
|
|
47
|
+
- Add `micro.CurPane().Buf.MdcuiModuleSource`, returning `embedded` or
|
|
48
|
+
`external`, and show the value in the bundled `showpath` example.
|
|
49
|
+
- Allow Unicode letters and numbers, including Chinese, in custom demo names
|
|
50
|
+
while continuing to reject whitespace and path separators.
|
|
51
|
+
- Show `global.MDCUI_MAIN` and the generated `global.MDCUI_MAIN_BASE` in
|
|
52
|
+
`--version` distribution settings.
|
|
53
|
+
|
|
54
|
+
### Changed
|
|
55
|
+
|
|
56
|
+
- Track embedded-module selection per buffer. The configured demo uses
|
|
57
|
+
embedded TUI front/RPC and WUI server modules when its local byte length
|
|
58
|
+
matches the bundled Markdown. Missing or overwritten copies are written
|
|
59
|
+
first and then use embedded modules; other files and changed-size demos use
|
|
60
|
+
filesystem companions.
|
|
61
|
+
- Document presence-based `MDCUI_*` defines with `=1`, supported build-flag
|
|
62
|
+
combinations, and commands for switching a TUI-default build to WUI or a
|
|
63
|
+
WUI-default build to TUI.
|
|
64
|
+
|
|
65
|
+
### Fixed
|
|
66
|
+
|
|
67
|
+
- Bundle and load the configured app's front, RPC, back, server, and dependency
|
|
68
|
+
graph so custom apps with companion imports can run from a single
|
|
69
|
+
executable.
|
|
70
|
+
- Keep unrelated Markdown buffers on external modules instead of reusing the
|
|
71
|
+
embedded main app's front and RPC modules.
|
|
72
|
+
- Use the bundled file's byte length after `MDCUI_OVERWRITE_DEMO` replaces a
|
|
73
|
+
stale local demo, ensuring that the overwritten app selects embedded
|
|
74
|
+
modules.
|
|
75
|
+
- Install WUI front exports on `window` without relying on the generated front
|
|
76
|
+
module's process-dependent or self-import path.
|
|
77
|
+
|
|
5
78
|
## [0.10.1] - 2026-07-25
|
|
6
79
|
|
|
7
80
|
### Fixed
|
package/README.md
CHANGED
|
@@ -757,54 +757,113 @@ both are equivalent to `-encoding mdcui`.
|
|
|
757
757
|
|
|
758
758
|
### Build-time distribution constants
|
|
759
759
|
|
|
760
|
-
|
|
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.
|
|
761
764
|
|
|
762
|
-
- `MDCUI_DEFAULT_EDIT`: open files as editable text by default.
|
|
763
|
-
- `MDCUI_DEFAULT_DEMO`: add `--demo` when launched without arguments.
|
|
764
|
-
- `MDCUI_DEFAULT_DEMO_WUI`: add `--wui` when launched without arguments.
|
|
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.
|
|
765
777
|
|
|
766
|
-
|
|
767
|
-
`MDCUI_OVERWRITE_DEMO` is an optional modifier for the demo or WUI mode.
|
|
768
|
-
These are presence-based constants, so their build values do not require
|
|
769
|
-
shell-quoted strings:
|
|
778
|
+
For the current platform, build an executable embedding `myapp.md` with:
|
|
770
779
|
|
|
771
|
-
```
|
|
772
|
-
|
|
780
|
+
```shell
|
|
781
|
+
npx jsmdcui --build-md-exe myapp.md
|
|
782
|
+
```
|
|
783
|
+
|
|
784
|
+
This is a convenience alias for
|
|
785
|
+
`--build-exe --define global.MDCUI_MAIN=myapp.md`.
|
|
786
|
+
|
|
787
|
+
For cross-compilation, specify the Bun target before the Markdown file:
|
|
788
|
+
|
|
789
|
+
```shell
|
|
790
|
+
npx jsmdcui --build-md-for bun-linux-x64-v1.3.14 myapp.md
|
|
773
791
|
```
|
|
774
792
|
|
|
775
|
-
|
|
793
|
+
This similarly expands to
|
|
794
|
+
`--build-for bun-linux-x64 --define global.MDCUI_MAIN=myapp.md`. Both aliases
|
|
795
|
+
are expanded before any generated application files are written.
|
|
796
|
+
|
|
797
|
+
Place every build define after `--build-exe`, or after the target argument of
|
|
798
|
+
`--build-for`. Choose at most one of `MDCUI_DEFAULT_EDIT`,
|
|
799
|
+
`MDCUI_DEFAULT_DEMO`, and `MDCUI_DEFAULT_DEMO_WUI`.
|
|
800
|
+
|
|
801
|
+
| Build defines | No-argument launch | Open the same app in the other UI |
|
|
802
|
+
| --- | --- | --- |
|
|
803
|
+
| none | normal CLI/TUI | `./mdcui --wui app.md` |
|
|
804
|
+
| `MDCUI_DEFAULT_EDIT=1` | text editor | `./mdcui --tui app.md` |
|
|
805
|
+
| `MDCUI_DEFAULT_DEMO=1` | `testapp.md` TUI | `./mdcui --wui --demo` |
|
|
806
|
+
| `MDCUI_DEFAULT_DEMO_WUI=1` | `testapp.md` WUI | `./mdcui --tui --demo` |
|
|
807
|
+
| `global.MDCUI_MAIN=../中文工具.md` | embedded custom TUI | `./mdcui --wui --demo-中文工具` |
|
|
808
|
+
| MAIN plus `MDCUI_DEFAULT_DEMO_WUI=1` | embedded custom WUI | `./mdcui --tui --demo-中文工具` |
|
|
809
|
+
|
|
810
|
+
Any explicit runtime argument suppresses the no-argument demo/WUI injection.
|
|
811
|
+
That is why the commands in the last column repeat `--demo` or
|
|
812
|
+
`--demo-中文工具`; `./mdcui --wui` by itself does not implicitly select a custom
|
|
813
|
+
main application.
|
|
776
814
|
|
|
777
|
-
To
|
|
778
|
-
repository-root `testapp.md`, then build with both demo constants:
|
|
815
|
+
To package `../中文工具.md` as a TUI by default:
|
|
779
816
|
|
|
780
817
|
```sh
|
|
781
818
|
bun src/index.js --build-exe \
|
|
782
|
-
--define
|
|
783
|
-
|
|
819
|
+
--define global.MDCUI_MAIN=../中文工具.md
|
|
820
|
+
|
|
821
|
+
./mdcui
|
|
822
|
+
./mdcui --wui --demo-中文工具
|
|
823
|
+
```
|
|
824
|
+
|
|
825
|
+
To package the same application as a WUI by default and explicitly switch back
|
|
826
|
+
to its TUI:
|
|
827
|
+
|
|
828
|
+
```sh
|
|
829
|
+
bun src/index.js --build-exe \
|
|
830
|
+
--define global.MDCUI_MAIN=../中文工具.md \
|
|
831
|
+
--define MDCUI_DEFAULT_DEMO_WUI=1
|
|
832
|
+
|
|
833
|
+
./mdcui
|
|
834
|
+
./mdcui --tui --demo-中文工具
|
|
784
835
|
```
|
|
785
836
|
|
|
786
|
-
The
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
and
|
|
790
|
-
|
|
791
|
-
|
|
837
|
+
The `MDCUI_MAIN` basename must end with lowercase `.md`. Its demo-name portion
|
|
838
|
+
must start with a Unicode letter or number and may contain Unicode
|
|
839
|
+
letters/numbers (including Chinese), combining marks, dots, underscores, and
|
|
840
|
+
hyphens. Whitespace and path separators are not allowed.
|
|
841
|
+
|
|
842
|
+
When the configured custom demo is selected and its local Markdown byte length
|
|
843
|
+
matches the embedded copy, TUI uses the embedded front/RPC modules and WUI uses
|
|
844
|
+
the embedded server. A missing demo, or one selected with
|
|
845
|
+
`MDCUI_OVERWRITE_DEMO=1`, is first written from the embedded copy and then uses
|
|
846
|
+
embedded modules. A different byte length prints a warning and uses filesystem
|
|
847
|
+
companion modules. Directly opening `./mdcui app.md` or
|
|
848
|
+
`./mdcui --wui app.md` has no demo provenance and therefore uses filesystem
|
|
849
|
+
modules even if the basename matches `MDCUI_MAIN`.
|
|
792
850
|
|
|
793
|
-
To
|
|
794
|
-
|
|
851
|
+
To retain the older repository-root `testapp.md` distribution instead, build a
|
|
852
|
+
TUI with:
|
|
795
853
|
|
|
796
854
|
```sh
|
|
797
855
|
bun src/index.js --build-exe \
|
|
798
|
-
--define
|
|
799
|
-
--define MDCUI_OVERWRITE_DEMO=
|
|
856
|
+
--define MDCUI_DEFAULT_DEMO=1 \
|
|
857
|
+
--define MDCUI_OVERWRITE_DEMO=1
|
|
800
858
|
```
|
|
801
859
|
|
|
802
|
-
|
|
860
|
+
For a default WUI, replace `MDCUI_DEFAULT_DEMO` with
|
|
861
|
+
`MDCUI_DEFAULT_DEMO_WUI`.
|
|
803
862
|
|
|
804
863
|
You can rename and distribute the resulting binary. It contains the Bun
|
|
805
|
-
runtime, jsmdcui, the packed runtime assets, and
|
|
806
|
-
directory must remain writable because launching
|
|
807
|
-
|
|
864
|
+
runtime, jsmdcui, the packed runtime assets, and the configured demo or custom
|
|
865
|
+
main application. The target directory must remain writable because launching
|
|
866
|
+
an application creates its Markdown file and generated companion files there.
|
|
808
867
|
|
|
809
868
|
## Development
|
|
810
869
|
|
package/package.json
CHANGED
package/runmd.mjs
CHANGED
|
@@ -54,6 +54,7 @@ export async function main(tuiWidth=30, {
|
|
|
54
54
|
mdpath: requestedMdpath = null,
|
|
55
55
|
overwriteDemo = process.argv.includes("--overwrite-demo"),
|
|
56
56
|
printUi = process.argv.includes("--print-ui"),
|
|
57
|
+
useBundledMdcuiServer = false,
|
|
57
58
|
} = {})
|
|
58
59
|
{
|
|
59
60
|
const explicitMdpath = process.argv.find(i=>i.endsWith('.md'))
|
|
@@ -99,7 +100,20 @@ export async function main(tuiWidth=30, {
|
|
|
99
100
|
|
|
100
101
|
|
|
101
102
|
const serverPath = mdpath + "-server.js"
|
|
102
|
-
const
|
|
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)
|
|
103
117
|
|
|
104
118
|
cse("\n\n"+mda('# Server'))
|
|
105
119
|
svmod.main();
|
|
@@ -109,7 +123,7 @@ export async function main(tuiWidth=30, {
|
|
|
109
123
|
// Exports
|
|
110
124
|
|
|
111
125
|
|
|
112
|
-
export async function extractJs(md,mdpath)
|
|
126
|
+
export async function extractJs(md,mdpath,{ bundling = false } = {})
|
|
113
127
|
{
|
|
114
128
|
const mdb = path.basename(mdpath)
|
|
115
129
|
|
|
@@ -128,16 +142,23 @@ export async function extractJs(md,mdpath)
|
|
|
128
142
|
}
|
|
129
143
|
)
|
|
130
144
|
|
|
145
|
+
const frontSource = sctags
|
|
131
146
|
sctags = "#!/usr/bin/env bun" + `
|
|
132
147
|
|
|
133
148
|
import { rpc as wuiRpcClient } from "./${mdb}-rpc.js";
|
|
134
|
-
let rpc =
|
|
149
|
+
let rpc = null
|
|
135
150
|
if(globalThis.process)
|
|
136
|
-
|
|
151
|
+
{
|
|
152
|
+
rpc = await import(
|
|
153
|
+
"./" +
|
|
154
|
+
(global.MDCUI_MAIN_BASE||"${mdb}") +
|
|
155
|
+
".back.js"
|
|
156
|
+
) ;
|
|
157
|
+
}
|
|
137
158
|
else
|
|
138
159
|
rpc = wuiRpcClient ;
|
|
139
160
|
|
|
140
|
-
` +
|
|
161
|
+
` + frontSource + `
|
|
141
162
|
|
|
142
163
|
if (typeof window !== "undefined")
|
|
143
164
|
{
|
|
@@ -152,6 +173,28 @@ export async function extractJs(md,mdpath)
|
|
|
152
173
|
|
|
153
174
|
await Bun.write(sctagsp,sctags);
|
|
154
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
|
+
}
|
|
155
198
|
|
|
156
199
|
sctagsp = mdpath + ".back.js"
|
|
157
200
|
sctags = "#!/usr/bin/env bun\n\n"
|
|
@@ -354,7 +397,7 @@ export function wrapWuiHeadingSections(html)
|
|
|
354
397
|
return output;
|
|
355
398
|
}
|
|
356
399
|
|
|
357
|
-
export async function createWui(md,mdpath) // HTML
|
|
400
|
+
export async function createWui(md,mdpath,{ bundling = false } = {}) // HTML
|
|
358
401
|
{
|
|
359
402
|
const eventsById = fenceEventMap(md)
|
|
360
403
|
|
|
@@ -397,7 +440,8 @@ img {
|
|
|
397
440
|
height: auto;
|
|
398
441
|
}
|
|
399
442
|
</style>`;
|
|
400
|
-
const
|
|
443
|
+
const moduleEntry = bundling ? `${mdb}.tmpfi.js` : `${mdb}.front.js`;
|
|
444
|
+
const moduleScript = `<scr`+`ipt type="module" src="./${moduleEntry}"></scr`+`ipt>`;
|
|
401
445
|
const isFullHtmlDocument = /^\s*<!doctype html>/i.test(md);
|
|
402
446
|
if (!isFullHtmlDocument) {
|
|
403
447
|
md = `<!doctype html>
|
package/runtime/help/help.md
CHANGED
|
@@ -757,54 +757,113 @@ both are equivalent to `-encoding mdcui`.
|
|
|
757
757
|
|
|
758
758
|
### Build-time distribution constants
|
|
759
759
|
|
|
760
|
-
|
|
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.
|
|
761
764
|
|
|
762
|
-
- `MDCUI_DEFAULT_EDIT`: open files as editable text by default.
|
|
763
|
-
- `MDCUI_DEFAULT_DEMO`: add `--demo` when launched without arguments.
|
|
764
|
-
- `MDCUI_DEFAULT_DEMO_WUI`: add `--wui` when launched without arguments.
|
|
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.
|
|
765
777
|
|
|
766
|
-
|
|
767
|
-
`MDCUI_OVERWRITE_DEMO` is an optional modifier for the demo or WUI mode.
|
|
768
|
-
These are presence-based constants, so their build values do not require
|
|
769
|
-
shell-quoted strings:
|
|
778
|
+
For the current platform, build an executable embedding `myapp.md` with:
|
|
770
779
|
|
|
771
|
-
```
|
|
772
|
-
|
|
780
|
+
```shell
|
|
781
|
+
npx jsmdcui --build-md-exe myapp.md
|
|
782
|
+
```
|
|
783
|
+
|
|
784
|
+
This is a convenience alias for
|
|
785
|
+
`--build-exe --define global.MDCUI_MAIN=myapp.md`.
|
|
786
|
+
|
|
787
|
+
For cross-compilation, specify the Bun target before the Markdown file:
|
|
788
|
+
|
|
789
|
+
```shell
|
|
790
|
+
npx jsmdcui --build-md-for bun-linux-x64-v1.3.14 myapp.md
|
|
773
791
|
```
|
|
774
792
|
|
|
775
|
-
|
|
793
|
+
This similarly expands to
|
|
794
|
+
`--build-for bun-linux-x64 --define global.MDCUI_MAIN=myapp.md`. Both aliases
|
|
795
|
+
are expanded before any generated application files are written.
|
|
796
|
+
|
|
797
|
+
Place every build define after `--build-exe`, or after the target argument of
|
|
798
|
+
`--build-for`. Choose at most one of `MDCUI_DEFAULT_EDIT`,
|
|
799
|
+
`MDCUI_DEFAULT_DEMO`, and `MDCUI_DEFAULT_DEMO_WUI`.
|
|
800
|
+
|
|
801
|
+
| Build defines | No-argument launch | Open the same app in the other UI |
|
|
802
|
+
| --- | --- | --- |
|
|
803
|
+
| none | normal CLI/TUI | `./mdcui --wui app.md` |
|
|
804
|
+
| `MDCUI_DEFAULT_EDIT=1` | text editor | `./mdcui --tui app.md` |
|
|
805
|
+
| `MDCUI_DEFAULT_DEMO=1` | `testapp.md` TUI | `./mdcui --wui --demo` |
|
|
806
|
+
| `MDCUI_DEFAULT_DEMO_WUI=1` | `testapp.md` WUI | `./mdcui --tui --demo` |
|
|
807
|
+
| `global.MDCUI_MAIN=../中文工具.md` | embedded custom TUI | `./mdcui --wui --demo-中文工具` |
|
|
808
|
+
| MAIN plus `MDCUI_DEFAULT_DEMO_WUI=1` | embedded custom WUI | `./mdcui --tui --demo-中文工具` |
|
|
809
|
+
|
|
810
|
+
Any explicit runtime argument suppresses the no-argument demo/WUI injection.
|
|
811
|
+
That is why the commands in the last column repeat `--demo` or
|
|
812
|
+
`--demo-中文工具`; `./mdcui --wui` by itself does not implicitly select a custom
|
|
813
|
+
main application.
|
|
776
814
|
|
|
777
|
-
To
|
|
778
|
-
repository-root `testapp.md`, then build with both demo constants:
|
|
815
|
+
To package `../中文工具.md` as a TUI by default:
|
|
779
816
|
|
|
780
817
|
```sh
|
|
781
818
|
bun src/index.js --build-exe \
|
|
782
|
-
--define
|
|
783
|
-
|
|
819
|
+
--define global.MDCUI_MAIN=../中文工具.md
|
|
820
|
+
|
|
821
|
+
./mdcui
|
|
822
|
+
./mdcui --wui --demo-中文工具
|
|
823
|
+
```
|
|
824
|
+
|
|
825
|
+
To package the same application as a WUI by default and explicitly switch back
|
|
826
|
+
to its TUI:
|
|
827
|
+
|
|
828
|
+
```sh
|
|
829
|
+
bun src/index.js --build-exe \
|
|
830
|
+
--define global.MDCUI_MAIN=../中文工具.md \
|
|
831
|
+
--define MDCUI_DEFAULT_DEMO_WUI=1
|
|
832
|
+
|
|
833
|
+
./mdcui
|
|
834
|
+
./mdcui --tui --demo-中文工具
|
|
784
835
|
```
|
|
785
836
|
|
|
786
|
-
The
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
and
|
|
790
|
-
|
|
791
|
-
|
|
837
|
+
The `MDCUI_MAIN` basename must end with lowercase `.md`. Its demo-name portion
|
|
838
|
+
must start with a Unicode letter or number and may contain Unicode
|
|
839
|
+
letters/numbers (including Chinese), combining marks, dots, underscores, and
|
|
840
|
+
hyphens. Whitespace and path separators are not allowed.
|
|
841
|
+
|
|
842
|
+
When the configured custom demo is selected and its local Markdown byte length
|
|
843
|
+
matches the embedded copy, TUI uses the embedded front/RPC modules and WUI uses
|
|
844
|
+
the embedded server. A missing demo, or one selected with
|
|
845
|
+
`MDCUI_OVERWRITE_DEMO=1`, is first written from the embedded copy and then uses
|
|
846
|
+
embedded modules. A different byte length prints a warning and uses filesystem
|
|
847
|
+
companion modules. Directly opening `./mdcui app.md` or
|
|
848
|
+
`./mdcui --wui app.md` has no demo provenance and therefore uses filesystem
|
|
849
|
+
modules even if the basename matches `MDCUI_MAIN`.
|
|
792
850
|
|
|
793
|
-
To
|
|
794
|
-
|
|
851
|
+
To retain the older repository-root `testapp.md` distribution instead, build a
|
|
852
|
+
TUI with:
|
|
795
853
|
|
|
796
854
|
```sh
|
|
797
855
|
bun src/index.js --build-exe \
|
|
798
|
-
--define
|
|
799
|
-
--define MDCUI_OVERWRITE_DEMO=
|
|
856
|
+
--define MDCUI_DEFAULT_DEMO=1 \
|
|
857
|
+
--define MDCUI_OVERWRITE_DEMO=1
|
|
800
858
|
```
|
|
801
859
|
|
|
802
|
-
|
|
860
|
+
For a default WUI, replace `MDCUI_DEFAULT_DEMO` with
|
|
861
|
+
`MDCUI_DEFAULT_DEMO_WUI`.
|
|
803
862
|
|
|
804
863
|
You can rename and distribute the resulting binary. It contains the Bun
|
|
805
|
-
runtime, jsmdcui, the packed runtime assets, and
|
|
806
|
-
directory must remain writable because launching
|
|
807
|
-
|
|
864
|
+
runtime, jsmdcui, the packed runtime assets, and the configured demo or custom
|
|
865
|
+
main application. The target directory must remain writable because launching
|
|
866
|
+
an application creates its Markdown file and generated companion files there.
|
|
808
867
|
|
|
809
868
|
## Development
|
|
810
869
|
|
|
@@ -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
|
|
package/single-exe/README.md
CHANGED
|
@@ -39,42 +39,58 @@ bun ./src/index.js --build-exe --sourcemap
|
|
|
39
39
|
bun ./src/index.js --build-for <target> --sourcemap
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
42
|
+
Bun expects `--define` values to be JSON-style literals, so strings normally
|
|
43
|
+
need quotes. `stringifyNonPrimitiveDefineValues()` converts a bare value with
|
|
44
|
+
`JSON.stringify()` before it reaches Bun. jsmdcui uses it for
|
|
45
|
+
`global.MDCUI_MAIN`.
|
|
46
|
+
|
|
47
|
+
The switch defines below are presence-based: `=0` and `=false` still enable
|
|
48
|
+
them. Omit a switch define to disable it; examples consistently use `=1`.
|
|
49
|
+
|
|
50
|
+
- `MDCUI_DEFAULT_EDIT=1`: editable-text default.
|
|
51
|
+
- `MDCUI_DEFAULT_DEMO=1`: no-argument `testapp.md` TUI.
|
|
52
|
+
- `MDCUI_DEFAULT_DEMO_WUI=1`: no-argument `testapp.md` WUI.
|
|
53
|
+
- `MDCUI_OVERWRITE_DEMO=1`: overwrite modifier; it does not select a demo.
|
|
54
|
+
- `global.MDCUI_MAIN=<path>.md`: embed a custom Markdown app and its generated
|
|
55
|
+
front, RPC, back, HTML, and server modules.
|
|
56
|
+
- `global.MDCUI_MAIN_BASE`: generated internally from `MDCUI_MAIN`; do not pass
|
|
57
|
+
it manually.
|
|
58
|
+
|
|
59
|
+
Put defines after `--build-exe` (or after the `--build-for` target), and choose
|
|
60
|
+
at most one `MDCUI_DEFAULT_*` mode.
|
|
61
|
+
|
|
62
|
+
| Build defines | No-argument launch | Switch UI |
|
|
63
|
+
| --- | --- | --- |
|
|
64
|
+
| `MDCUI_DEFAULT_EDIT=1` | text editor | `./mdcui --tui app.md` |
|
|
65
|
+
| `MDCUI_DEFAULT_DEMO=1` | `testapp.md` TUI | `./mdcui --wui --demo` |
|
|
66
|
+
| `MDCUI_DEFAULT_DEMO_WUI=1` | `testapp.md` WUI | `./mdcui --tui --demo` |
|
|
67
|
+
| `global.MDCUI_MAIN=../中文工具.md` | custom TUI | `./mdcui --wui --demo-中文工具` |
|
|
68
|
+
| MAIN plus `MDCUI_DEFAULT_DEMO_WUI=1` | custom WUI | `./mdcui --tui --demo-中文工具` |
|
|
69
|
+
|
|
70
|
+
For a custom TUI-default executable:
|
|
52
71
|
|
|
53
72
|
```shell
|
|
54
73
|
bun ./src/index.js --build-exe \
|
|
55
|
-
--define
|
|
74
|
+
--define global.MDCUI_MAIN=../中文工具.md
|
|
56
75
|
```
|
|
57
76
|
|
|
58
|
-
|
|
77
|
+
For a custom WUI-default executable:
|
|
59
78
|
|
|
60
79
|
```shell
|
|
61
80
|
bun ./src/index.js --build-exe \
|
|
62
|
-
--define
|
|
63
|
-
--define
|
|
81
|
+
--define global.MDCUI_MAIN=../中文工具.md \
|
|
82
|
+
--define MDCUI_DEFAULT_DEMO_WUI=1
|
|
64
83
|
```
|
|
65
84
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
For a browser UI that automatically adds `--wui` when launched without
|
|
71
|
-
arguments, use `MDCUI_DEFAULT_DEMO_WUI` instead:
|
|
85
|
+
Explicit runtime arguments suppress automatic demo/WUI selection, so switching
|
|
86
|
+
UI must repeat `--demo` or `--demo-中文工具`. The main basename must end in
|
|
87
|
+
lowercase `.md`; its demo name allows Unicode letters/numbers (including
|
|
88
|
+
Chinese), dots, underscores, and hyphens, but no whitespace.
|
|
72
89
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
```
|
|
90
|
+
The custom demo uses embedded TUI front/RPC or the embedded WUI server when its
|
|
91
|
+
local Markdown byte length matches the embedded asset. Missing or overwritten
|
|
92
|
+
demos use embedded modules after the asset is written. A differing byte length
|
|
93
|
+
warns and selects filesystem companion modules.
|
|
78
94
|
|
|
79
95
|
To perform the same steps manually, run these commands from `single-exe/`:
|
|
80
96
|
|
|
@@ -221,6 +237,47 @@ bun ./packAssets.sh
|
|
|
221
237
|
bun build --format=esm --compile --minify --bytecode ./entry.mjs --outfile=my-bin
|
|
222
238
|
```
|
|
223
239
|
|
|
240
|
+
#### Passing --define to bun build
|
|
241
|
+
|
|
242
|
+
`buildEarlyExit()` forwards build arguments to Bun, whose define parser expects
|
|
243
|
+
strings to be quoted literals. To accept a bare value such as a path, call the below
|
|
244
|
+
helper to normalize it before `buildEarlyExit()`:
|
|
245
|
+
|
|
246
|
+
```js
|
|
247
|
+
import {
|
|
248
|
+
buildEarlyExit,
|
|
249
|
+
stringifyNonPrimitiveDefineValues,
|
|
250
|
+
} from "../single-exe/compiled.js";
|
|
251
|
+
|
|
252
|
+
stringifyNonPrimitiveDefineValues(process.argv, "MY_STRING_DEFINE");
|
|
253
|
+
await buildEarlyExit(process.argv, "my-bin");
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
```shell
|
|
257
|
+
# Wrong: Bun parses the define before the helper runs.
|
|
258
|
+
bun --define MY_STRING_DEFINE=../app.md ./src/index.js --build-exe
|
|
259
|
+
|
|
260
|
+
# Correct
|
|
261
|
+
bun ./src/index.js --build-exe --define MY_STRING_DEFINE=../app.md
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Before normalization:
|
|
265
|
+
|
|
266
|
+
```js
|
|
267
|
+
["--define", "MY_STRING_DEFINE=../app.md"]
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
After normalization:
|
|
271
|
+
|
|
272
|
+
```js
|
|
273
|
+
["--define", 'MY_STRING_DEFINE="../app.md"']
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
The inline form works too:
|
|
277
|
+
`--define=MY_STRING_DEFINE=../app.md` becomes
|
|
278
|
+
`--define=MY_STRING_DEFINE="../app.md"`.
|
|
279
|
+
|
|
280
|
+
|
|
224
281
|
### 6. Verify both execution paths
|
|
225
282
|
|
|
226
283
|
Verify the compiled asset archive and then run the program normally:
|