1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
|
#!/usr/bin/env bash
: <<'COMMENT'
Download the front-end libraries the web UI embeds, into web/vendor/.
Usage:
./vendor.sh download the versions pinned below into web/vendor/
./vendor.sh --outdated compare the pinned versions with the published ones
(changes nothing)
To update a library: run --outdated, change its version below, run
./vendor.sh, check the UI (go run ./cmd/server …), then commit web/vendor/.
web/vendor/ is committed: go:embed needs it at build time, and a checkout
(or a CI job) must build without network access to npm. The page loads
nothing from the network: everything it uses is in the binary.
web/vendor/monaco/vs/ the Monaco editor (AMD build), without its UI
translations and source maps
web/vendor/xterm/ xterm.js and its fit addon, for the terminal
web/vendor/material-icons/ the file and folder icons of the explorer
(VS Code's Material Icon Theme) and their manifest
web/vendor/tailwind/ Tailwind CSS 3, the "Play CDN" build: it generates
the CSS of the classes the page uses, in the browser
web/vendor/marked/ Markdown -> HTML, for the chat
web/vendor/highlight/ code highlighting in the chat, and its two themes
web/vendor/dompurify/ HTML sanitizer: what the agent writes is Markdown,
but the HTML marked makes of it is filtered
before it enters the page
web/vendor/asciidoctor/ AsciiDoc -> HTML, for the editor's preview; loaded
on the first .adoc preview (750 KB)
web/vendor/drawio/ the draw.io viewer, for the preview of .drawio
files; loaded on the first one (4 MB). Not on npm:
taken from the jgraph/drawio repository, at a tag
COMMENT
set -euo pipefail
# Each version is pinned; the comment says why a newer one may not simply be
# dropped in (what --outdated reminds too).
MONACO_VERSION="0.52.2" # the last release with the AMD build and workerMain.js
XTERM_VERSION="5.5.0" # 6.x: API changes, and needs addon-fit 0.11
XTERM_FIT_VERSION="0.10.0" # the last one for xterm 5
MATERIAL_ICONS_VERSION="5.38.1"
TAILWIND_VERSION="3.4.17" # v4 has no Play CDN build; its classes differ
MARKED_VERSION="9.1.2" # later majors: check renderMarkdown in app.js
HIGHLIGHT_VERSION="11.8.0"
DOMPURIFY_VERSION="3.4.16" # a security filter: keep it current
ASCIIDOCTOR_VERSION="3.0.4" # 4.x is an ESM rewrite with an async API: see renderAsciidoc in app.js
DRAWIO_VERSION="31.5.3" # a tag of github.com/jgraph/drawio; check the preview of a .drawio after a bump
cd "$(dirname "${BASH_SOURCE[0]}")"
VENDOR="web/vendor"
# --outdated: the npm registry's "latest" (for Tailwind, the v3 line) next to
# the pinned version. Only a report: an update is a decision, see above.
if [ "${1:-}" = "--outdated" ]; then
latest() { # package [dist-tag]
curl -fsSL "https://registry.npmjs.org/$1" -H "Accept: application/vnd.npm.install-v1+json" |
grep -o "\"${2:-latest}\":\"[^\"]*\"" | head -1 | cut -d'"' -f4
}
printf '%-24s %-10s %-10s\n' "package" "pinned" "published"
while read -r pkg pinned tag; do
published="$(latest "${pkg}" "${tag}" || echo '?')"
mark=""
[ "${published}" != "${pinned}" ] && mark=" ⬆"
printf '%-24s %-10s %-10s%s\n' "${pkg}" "${pinned}" "${published}" "${mark}"
done <<EOF
monaco-editor ${MONACO_VERSION} latest
@xterm/xterm ${XTERM_VERSION} latest
@xterm/addon-fit ${XTERM_FIT_VERSION} latest
material-icon-theme ${MATERIAL_ICONS_VERSION} latest
tailwindcss ${TAILWIND_VERSION} v3-lts
marked ${MARKED_VERSION} latest
@highlightjs/cdn-assets ${HIGHLIGHT_VERSION} latest
dompurify ${DOMPURIFY_VERSION} latest
@asciidoctor/core ${ASCIIDOCTOR_VERSION} latest
EOF
drawio="$(curl -fsSL https://api.github.com/repos/jgraph/drawio/releases/latest | grep -o '"tag_name": *"v[^"]*"' | cut -d'"' -f4 | tr -d v || echo '?')"
mark=""
[ "${drawio}" != "${DRAWIO_VERSION}" ] && mark=" ⬆"
printf '%-24s %-10s %-10s%s\n' "jgraph/drawio (GitHub)" "${DRAWIO_VERSION}" "${drawio}" "${mark}"
echo ""
echo "The comments next to the versions in $0 say which updates need more than a version bump."
exit 0
fi
TMP="$(mktemp -d)"
trap 'rm -rf "${TMP}"' EXIT
# fetch downloads an npm package tarball and unpacks it into $TMP/<name>.
fetch() {
local pkg=$1 version=$2 name=$3
local base="${pkg##*/}"
echo "📥 ${pkg}@${version}"
mkdir -p "${TMP}/${name}"
curl -fsSL "https://registry.npmjs.org/${pkg}/-/${base}-${version}.tgz" |
tar xz -C "${TMP}/${name}" --strip-components=1
}
fetch monaco-editor "${MONACO_VERSION}" monaco
fetch @xterm/xterm "${XTERM_VERSION}" xterm
fetch @xterm/addon-fit "${XTERM_FIT_VERSION}" xterm-fit
fetch material-icon-theme "${MATERIAL_ICONS_VERSION}" material-icons
fetch tailwindcss "${TAILWIND_VERSION}" tailwind # for its LICENSE only
fetch marked "${MARKED_VERSION}" marked
fetch @highlightjs/cdn-assets "${HIGHLIGHT_VERSION}" highlight
fetch dompurify "${DOMPURIFY_VERSION}" dompurify
fetch @asciidoctor/core "${ASCIIDOCTOR_VERSION}" asciidoctor
# The Play CDN build of Tailwind is not in the npm package: it is only
# published on cdn.tailwindcss.com, one URL per version.
echo "📥 cdn.tailwindcss.com/${TAILWIND_VERSION}"
curl -fsSL "https://cdn.tailwindcss.com/${TAILWIND_VERSION}" -o "${TMP}/tailwind.js"
# The draw.io viewer is not published on npm: it is a file of the jgraph/drawio
# repository, taken at a release tag.
DRAWIO_RAW="https://raw.githubusercontent.com/jgraph/drawio/v${DRAWIO_VERSION}"
echo "📥 jgraph/drawio v${DRAWIO_VERSION}"
curl -fsSL "${DRAWIO_RAW}/src/main/webapp/js/viewer-static.min.js" -o "${TMP}/viewer-static.min.js"
curl -fsSL "${DRAWIO_RAW}/LICENSE" -o "${TMP}/drawio-LICENSE"
rm -rf "${VENDOR}"
mkdir -p "${VENDOR}"/{monaco,xterm,material-icons,tailwind,marked,highlight,dompurify,asciidoctor,drawio/nomath}
cp -R "${TMP}/monaco/min/vs" "${VENDOR}/monaco/vs"
# English only: the other UI languages weigh 2 MB and are never loaded.
rm -f "${VENDOR}"/monaco/vs/nls.messages.*.js
find "${VENDOR}" -name '*.map' -delete
cp "${TMP}/monaco/LICENSE" "${VENDOR}/monaco/LICENSE"
cp "${TMP}/xterm/lib/xterm.js" "${TMP}/xterm/css/xterm.css" "${TMP}/xterm/LICENSE" "${VENDOR}/xterm/"
cp "${TMP}/xterm-fit/lib/addon-fit.js" "${VENDOR}/xterm/"
# The manifest maps extensions, file and folder names to icons, as VS Code
# reads it; the explorer applies the same rules (see iconFor in app.js).
cp -R "${TMP}/material-icons/icons" "${VENDOR}/material-icons/icons"
cp "${TMP}/material-icons/dist/material-icons.json" "${TMP}/material-icons/LICENSE" "${VENDOR}/material-icons/"
cp "${TMP}/tailwind.js" "${TMP}/tailwind/LICENSE" "${VENDOR}/tailwind/"
cp "${TMP}/marked/marked.min.js" "${TMP}/marked/LICENSE.md" "${VENDOR}/marked/"
cp "${TMP}/highlight/highlight.min.js" "${TMP}/highlight/LICENSE" \
"${TMP}/highlight/styles/github.min.css" "${TMP}/highlight/styles/github-dark.min.css" \
"${VENDOR}/highlight/"
cp "${TMP}/dompurify/dist/purify.min.js" "${TMP}/dompurify/LICENSE" "${VENDOR}/dompurify/"
# The browser build of Asciidoctor.js 3 (Opal, compiled by Closure): a classic
# script that defines the global module$build$asciidoctor_browser, and needs
# no eval under the page's CSP (checked in Chromium).
cp "${TMP}/asciidoctor/dist/browser/asciidoctor.min.js" "${TMP}/asciidoctor/LICENSE" "${VENDOR}/asciidoctor/"
# The viewer loads MathJax's startup.js on every diagram, from the network by
# default; app.js points it here instead (DRAW_MATH_URL), at an empty stand-in:
# MathJax is not embedded, so a formula shows as its source. It needs no eval
# under the page's CSP (checked in Chromium).
cp "${TMP}/viewer-static.min.js" "${VENDOR}/drawio/"
cp "${TMP}/drawio-LICENSE" "${VENDOR}/drawio/LICENSE"
echo "// MathJax is not embedded (see vendor.sh): a formula in a diagram shows as its source." >"${VENDOR}/drawio/nomath/startup.js"
cat >"${VENDOR}/VERSIONS" <<EOF
monaco-editor ${MONACO_VERSION}
@xterm/xterm ${XTERM_VERSION}
@xterm/addon-fit ${XTERM_FIT_VERSION}
material-icon-theme ${MATERIAL_ICONS_VERSION}
tailwindcss ${TAILWIND_VERSION} (Play CDN build)
marked ${MARKED_VERSION}
@highlightjs/cdn-assets ${HIGHLIGHT_VERSION}
dompurify ${DOMPURIFY_VERSION}
@asciidoctor/core ${ASCIIDOCTOR_VERSION}
jgraph/drawio ${DRAWIO_VERSION} (viewer-static.min.js, from GitHub)
EOF
echo "✅ ${VENDOR}: $(du -sh "${VENDOR}" | cut -f1)"
|