mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-10-21 05:59:35 +08:00
Add Explore, Galaxy, Architecture, Agents, and System workspaces with a persistent, resizable local chat dock. Attach exact source selections and graph context, render Markdown, and offer pinned opt-in browser models. Keep the galaxy visible below chat and focused on the active file or code selection. Restore hierarchy root selection, resolve projection identities by symbol, and retain loaded search matches after an empty index reply. Expose process measurement units, embed browser runtime MJS/WASM assets, and constrain binary-audit exceptions to reviewed dependency strings. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
196 lines
5.9 KiB
Bash
Executable File
196 lines
5.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# embed-frontend.sh — Convert built frontend assets into linkable object files.
|
|
#
|
|
# Usage: scripts/embed-frontend.sh <dist_dir> <output_dir>
|
|
#
|
|
# For each file in dist_dir, creates:
|
|
# 1. An object file via `ld -r -b binary` (raw bytes, zero bloat)
|
|
# 2. A generated embedded_assets.c with a lookup table
|
|
#
|
|
# Symbols created per file: _binary_<mangled_name>_start, _binary_<mangled_name>_end
|
|
# On macOS, these get a leading underscore: __binary_<mangled_name>_start
|
|
|
|
set -euo pipefail
|
|
|
|
DIST_DIR="${1:?Usage: embed-frontend.sh <dist_dir> <output_dir>}"
|
|
OUTPUT_DIR="${2:?Usage: embed-frontend.sh <dist_dir> <output_dir>}"
|
|
|
|
# Clean old embedded objects (asset hashes change on each build)
|
|
rm -rf "$OUTPUT_DIR"
|
|
mkdir -p "$OUTPUT_DIR"
|
|
|
|
# Detect platform — Linux uses ld -r -b binary, everything else uses xxd+cc
|
|
IS_LINUX=false
|
|
if [[ "$(uname -s)" == "Linux" ]] && ! [[ "$(uname -s)" =~ MINGW|MSYS ]]; then
|
|
IS_LINUX=true
|
|
fi
|
|
|
|
# Content-type detection
|
|
content_type_for() {
|
|
local f="$1"
|
|
case "$f" in
|
|
*.html) echo "text/html" ;;
|
|
*.js|*.mjs) echo "application/javascript" ;;
|
|
*.wasm) echo "application/wasm" ;;
|
|
*.css) echo "text/css" ;;
|
|
*.json) echo "application/json" ;;
|
|
*.svg) echo "image/svg+xml" ;;
|
|
*.png) echo "image/png" ;;
|
|
*.ico) echo "image/x-icon" ;;
|
|
*.woff2) echo "font/woff2" ;;
|
|
*.woff) echo "font/woff" ;;
|
|
*.map) echo "application/json" ;;
|
|
*) echo "application/octet-stream" ;;
|
|
esac
|
|
}
|
|
|
|
# Mangle filename to valid C symbol: replace non-alnum with _
|
|
mangle() {
|
|
echo "$1" | sed 's/[^a-zA-Z0-9]/_/g'
|
|
}
|
|
|
|
# Collect all files
|
|
FILES=()
|
|
while IFS= read -r -d '' file; do
|
|
FILES+=("$file")
|
|
done < <(find "$DIST_DIR" -type f -print0 | sort -z)
|
|
|
|
if [[ ${#FILES[@]} -eq 0 ]]; then
|
|
echo "Error: no files found in $DIST_DIR" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "Embedding ${#FILES[@]} files from $DIST_DIR"
|
|
|
|
# Generate object files
|
|
OBJ_FILES=()
|
|
for file in "${FILES[@]}"; do
|
|
rel="${file#$DIST_DIR/}"
|
|
mangled=$(mangle "$rel")
|
|
obj="$OUTPUT_DIR/embed_${mangled}.o"
|
|
|
|
if $IS_LINUX; then
|
|
# Linux: ld -r -b binary (zero bloat, ELF only)
|
|
abs_obj="$(cd "$(dirname "$0")/.." && pwd)/$obj"
|
|
(cd "$DIST_DIR" && ld -r -b binary -o "$abs_obj" "$rel")
|
|
else
|
|
# macOS/Windows/MSYS2: generate C byte array + cc (no xxd dependency)
|
|
local_c="$OUTPUT_DIR/embed_${mangled}.c"
|
|
local_sym="_binary_${mangled}"
|
|
|
|
echo "/* Generated from $rel */" > "$local_c"
|
|
echo "const unsigned char ${local_sym}_data[] = {" >> "$local_c"
|
|
# Use od (POSIX) to generate hex bytes — works everywhere without xxd/vim
|
|
od -An -tx1 -v < "$file" | tr -s ' ' '\n' | grep -v '^$' | sed 's/^/0x/; s/$/,/' | paste -sd' ' - | fold -s -w 76 | sed 's/^/ /' >> "$local_c"
|
|
echo "};" >> "$local_c"
|
|
echo "const unsigned int ${local_sym}_size = sizeof(${local_sym}_data);" >> "$local_c"
|
|
|
|
${CC:-cc} -c -O2 -o "$obj" "$local_c"
|
|
rm -f "$local_c"
|
|
fi
|
|
|
|
OBJ_FILES+=("$obj")
|
|
echo " $rel -> $obj"
|
|
done
|
|
|
|
# Generate embedded_assets.c
|
|
ASSETS_C="src/ui/embedded_assets.c"
|
|
cat > "$ASSETS_C" <<'HEADER'
|
|
/*
|
|
* embedded_assets.c — Generated file mapping URL paths to embedded bytes.
|
|
* DO NOT EDIT — regenerated by scripts/embed-frontend.sh
|
|
*/
|
|
#include "ui/embedded_assets.h"
|
|
#include <string.h>
|
|
|
|
HEADER
|
|
|
|
# Declare extern symbols
|
|
for file in "${FILES[@]}"; do
|
|
rel="${file#$DIST_DIR/}"
|
|
mangled=$(mangle "$rel")
|
|
sym="_binary_${mangled}"
|
|
|
|
if ! $IS_LINUX; then
|
|
echo "extern const unsigned char ${sym}_data[];" >> "$ASSETS_C"
|
|
echo "extern const unsigned int ${sym}_size;" >> "$ASSETS_C"
|
|
else
|
|
echo "extern const unsigned char ${sym}_start[];" >> "$ASSETS_C"
|
|
echo "extern const unsigned char ${sym}_end[];" >> "$ASSETS_C"
|
|
fi
|
|
done
|
|
|
|
echo "" >> "$ASSETS_C"
|
|
echo "cbm_embedded_file_t CBM_EMBEDDED_FILES[] = {" >> "$ASSETS_C"
|
|
|
|
for file in "${FILES[@]}"; do
|
|
rel="${file#$DIST_DIR/}"
|
|
mangled=$(mangle "$rel")
|
|
sym="_binary_${mangled}"
|
|
ct=$(content_type_for "$rel")
|
|
|
|
# URL path: /index.html for root, /assets/... for assets
|
|
url_path="/$rel"
|
|
|
|
if ! $IS_LINUX; then
|
|
echo " {\"$url_path\", ${sym}_data, 0, \"$ct\"}," >> "$ASSETS_C"
|
|
else
|
|
echo " {\"$url_path\", ${sym}_start, 0, \"$ct\"}," >> "$ASSETS_C"
|
|
fi
|
|
done
|
|
|
|
echo "};" >> "$ASSETS_C"
|
|
echo "const int CBM_EMBEDDED_FILE_COUNT = ${#FILES[@]};" >> "$ASSETS_C"
|
|
|
|
# Generate size fixup
|
|
if $IS_LINUX; then
|
|
# Linux: compute size from start/end pointers (ld -r -b binary symbols)
|
|
cat >> "$ASSETS_C" <<'SIZEINIT'
|
|
|
|
static void __attribute__((constructor)) init_embedded_sizes(void) {
|
|
cbm_embedded_file_t *files = CBM_EMBEDDED_FILES;
|
|
SIZEINIT
|
|
|
|
for i in "${!FILES[@]}"; do
|
|
rel="${FILES[$i]#$DIST_DIR/}"
|
|
mangled=$(mangle "$rel")
|
|
sym="_binary_${mangled}"
|
|
echo " files[$i].size = (unsigned int)(${sym}_end - ${sym}_start);" >> "$ASSETS_C"
|
|
done
|
|
|
|
echo "}" >> "$ASSETS_C"
|
|
else
|
|
# macOS/Windows: use explicit _size vars from xxd-generated C arrays
|
|
cat >> "$ASSETS_C" <<'SIZEINIT'
|
|
|
|
static void __attribute__((constructor)) init_embedded_sizes(void) {
|
|
cbm_embedded_file_t *files = CBM_EMBEDDED_FILES;
|
|
SIZEINIT
|
|
|
|
for i in "${!FILES[@]}"; do
|
|
rel="${FILES[$i]#$DIST_DIR/}"
|
|
mangled=$(mangle "$rel")
|
|
sym="_binary_${mangled}"
|
|
echo " files[$i].size = ${sym}_size;" >> "$ASSETS_C"
|
|
done
|
|
|
|
echo "}" >> "$ASSETS_C"
|
|
fi
|
|
|
|
# Add lookup function
|
|
cat >> "$ASSETS_C" <<'LOOKUP'
|
|
|
|
const cbm_embedded_file_t *cbm_embedded_lookup(const char *path) {
|
|
for (int i = 0; i < CBM_EMBEDDED_FILE_COUNT; i++) {
|
|
if (strcmp(CBM_EMBEDDED_FILES[i].path, path) == 0) {
|
|
return &CBM_EMBEDDED_FILES[i];
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
LOOKUP
|
|
|
|
echo "Generated $ASSETS_C with ${#FILES[@]} embedded files"
|
|
echo "Object files in $OUTPUT_DIR:"
|
|
printf ' %s\n' "${OBJ_FILES[@]}"
|