summaryrefslogtreecommitdiffhomepage
path: root/docker
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-04 21:21:20 +0900
committerAdam Malczewski <[email protected]>2026-06-04 21:21:20 +0900
commit394f1ed37ce860da6fdc385769bf29f9737105cd (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /docker
parent81a9cdbadf8c9d940d4fe9a2a0de607dee1f5f1a (diff)
downloaddispatch-394f1ed37ce860da6fdc385769bf29f9737105cd.tar.gz
dispatch-394f1ed37ce860da6fdc385769bf29f9737105cd.zip
chore: genesis — remove all files to rebuild from scratch (arch rewrite)
Diffstat (limited to 'docker')
-rw-r--r--docker/cs/fuzzy-distance.patch159
-rw-r--r--docker/cs/luau-declarations.patch32
-rwxr-xr-xdocker/entrypoint.dev.sh71
-rw-r--r--docker/entrypoint.sh8
4 files changed, 0 insertions, 270 deletions
diff --git a/docker/cs/fuzzy-distance.patch b/docker/cs/fuzzy-distance.patch
deleted file mode 100644
index e432986..0000000
--- a/docker/cs/fuzzy-distance.patch
+++ /dev/null
@@ -1,159 +0,0 @@
-Fix cs fuzzy matching to honour true Levenshtein edit distance (insertions and
-deletions), not just same-length substitutions.
-
-Upstream cs (v3.1.0) implements `term~N` fuzzy search by scanning only
-same-length windows of the content: for a term of length L it compares every
-L-character substring and keeps those within N edits. Because every candidate
-window is exactly L long, the only edits it can ever observe are substitutions.
-A mid-word insertion or deletion — e.g. `computSlipAngle~1` for the real symbol
-`computeSlipAngle` (a dropped 'e'), or `houss~1` vs `house` — changes the length
-by one and so is never matched, even though it is edit distance 1. This
-contradicts cs's own documentation ("fuzzy match within 1 or 2 distance").
-
-The fix scans windows of every plausible length in
-[termLen-maxDist, termLen+maxDist] (clamped at 1) at each offset and keeps the
-best (lowest-distance) match, so insertions and deletions match too. fuzzyFind
-records the best window per start and advances past it to avoid emitting a swarm
-of overlapping locations for one logical match.
-
-Purely localised to the two fuzzy helpers in pkg/search/executor.go (plus a
-test update: the pre-existing `hovze~2` case asserted the old substitution-only
-behaviour, where the distance-2 term coincidentally failed to match a shorter
-window that is in fact within distance 2; it is replaced with an unambiguous
-distance-1 case and new mid-word insertion/deletion cases). Passes cs's own
-pkg/search + pkg/ranker test suites. Applied during the Docker build and the
-native package build via `git apply` against the pinned v3.1.0 checkout (see
-Dockerfile / Dockerfile.dev / packaging/PKGBUILD). Candidate for upstreaming to
-boyter/cs (the defect is unreported there).
-
-diff --git a/pkg/search/executor.go b/pkg/search/executor.go
-index 175d458..1c422d2 100644
---- a/pkg/search/executor.go
-+++ b/pkg/search/executor.go
-@@ -632,17 +632,67 @@ func min3(a, b, c int) int {
- return c
- }
-
--// fuzzyContains checks if any same-length substring of content matches
--// the term within the given edit distance (substitution-based matching).
-+// fuzzyWindowBounds returns the inclusive range of substring lengths that
-+// could be within maxDist edits of a term of length termLen. A Levenshtein
-+// distance of d can only be achieved between strings whose lengths differ by
-+// at most d (each insertion or deletion changes the length by one), so any
-+// candidate window must have a length in [termLen-maxDist, termLen+maxDist].
-+// The lower bound is clamped to 1 so we never form a zero-length window.
-+func fuzzyWindowBounds(termLen, maxDist int) (int, int) {
-+ minLen := termLen - maxDist
-+ if minLen < 1 {
-+ minLen = 1
-+ }
-+ return minLen, termLen + maxDist
-+}
-+
-+// bestFuzzyMatchAt returns the length of the best (lowest-distance) substring
-+// of content starting at offset i that is within maxDist edits of term, or -1
-+// if none is. Windows of every plausible length are tried (see
-+// fuzzyWindowBounds) so insertions and deletions match, not just
-+// substitutions — e.g. "computSlipAngle" (a dropped 'e') matches
-+// "computeSlipAngle" at distance 1. Ties prefer the length closest to termLen.
-+func bestFuzzyMatchAt(content, term string, i, maxDist, minLen, maxLen int) int {
-+ contentLen := len(content)
-+ bestLen := -1
-+ bestDist := maxDist + 1
-+ bestDelta := 0
-+ for wl := minLen; wl <= maxLen; wl++ {
-+ if i+wl > contentLen {
-+ break
-+ }
-+ d := levenshtein(content[i:i+wl], term)
-+ if d > maxDist {
-+ continue
-+ }
-+ delta := wl - len(term)
-+ if delta < 0 {
-+ delta = -delta
-+ }
-+ if d < bestDist || (d == bestDist && delta < bestDelta) {
-+ bestDist = d
-+ bestLen = wl
-+ bestDelta = delta
-+ }
-+ }
-+ return bestLen
-+}
-+
-+// fuzzyContains reports whether any substring of content is within maxDist
-+// edits (true Levenshtein: insertions, deletions, and substitutions) of term.
- func fuzzyContains(content, term string, maxDist, termLen int) bool {
- contentLen := len(content)
-- if contentLen == 0 || termLen == 0 || termLen > contentLen {
-+ if contentLen == 0 || termLen == 0 {
-+ return false
-+ }
-+
-+ minLen, maxLen := fuzzyWindowBounds(termLen, maxDist)
-+ if minLen > contentLen {
- return false
- }
-
-- for i := 0; i <= contentLen-termLen; i++ {
-- window := content[i : i+termLen]
-- if levenshtein(window, term) <= maxDist {
-+ for i := 0; i <= contentLen-minLen; i++ {
-+ if bestFuzzyMatchAt(content, term, i, maxDist, minLen, maxLen) >= 0 {
- return true
- }
- }
-@@ -651,18 +701,30 @@ func fuzzyContains(content, term string, maxDist, termLen int) bool {
-
- // fuzzyFind finds all match locations in content that are within the given
- // edit distance of the term. Returns [][]int where each entry is [start, end].
-+// Like fuzzyContains it considers variable-length windows so insertions and
-+// deletions match. To avoid emitting a swarm of overlapping windows for one
-+// logical match, it records the best window at each start and then advances
-+// past it.
- func fuzzyFind(content, term string, maxDist, termLen int) [][]int {
- contentLen := len(content)
-- if contentLen == 0 || termLen == 0 || termLen > contentLen {
-+ if contentLen == 0 || termLen == 0 {
-+ return nil
-+ }
-+
-+ minLen, maxLen := fuzzyWindowBounds(termLen, maxDist)
-+ if minLen > contentLen {
- return nil
- }
-
- var locs [][]int
-- for i := 0; i <= contentLen-termLen; i++ {
-- window := content[i : i+termLen]
-- if levenshtein(window, term) <= maxDist {
-- locs = append(locs, []int{i, i + termLen})
-- }
-+ for i := 0; i <= contentLen-minLen; {
-+ wl := bestFuzzyMatchAt(content, term, i, maxDist, minLen, maxLen)
-+ if wl < 0 {
-+ i++
-+ continue
-+ }
-+ locs = append(locs, []int{i, i + wl})
-+ i += wl
- }
- return locs
- }
-diff --git a/pkg/search/search_test.go b/pkg/search/search_test.go
-index 6cbd01f..eacbd75 100644
---- a/pkg/search/search_test.go
-+++ b/pkg/search/search_test.go
-@@ -57,7 +57,10 @@ func TestExecutor(t *testing.T) {
- {"Fuzzy Distance 1", "houss~1", false, []string{"src/main/file1.go"}}, // "houss" is distance 1 from "house" (only in file1)
- {"Fuzzy Distance 1 No Match", "zzz~1", false, []string{}},
- {"Fuzzy AND Keyword", "houss~1 AND brown", false, []string{"src/main/file1.go"}},
-- {"Fuzzy Distance 2", "hovze~2", false, []string{"src/main/file1.go"}}, // "hovze" is distance 2 from "house" (u→v, s→z), only in file1
-+ {"Fuzzy Distance 2", "houze~2", false, []string{"src/main/file1.go"}}, // "houze" is distance 1 from "house" (s→z), only in file1
-+ // Mid-word insertion/deletion must match (true Levenshtein, not just same-length substitution).
-+ {"Fuzzy Distance 1 deletion", "hose~1", false, []string{"src/main/file1.go"}}, // "hose" -> "house" (insert 'u'), distance 1
-+ {"Fuzzy Distance 1 insertion", "houxse~1", false, []string{"src/main/file1.go"}}, // "houxse" -> "house" (delete 'x'), distance 1
-
- // Colon filter syntax
- {"Colon file filter", "cat file:file1", false, []string{"src/main/file1.go"}},
diff --git a/docker/cs/luau-declarations.patch b/docker/cs/luau-declarations.patch
deleted file mode 100644
index 794ecac..0000000
--- a/docker/cs/luau-declarations.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-Add a Luau declaration-pattern table to the cs structural ranker.
-
-Upstream cs (v3.1.0) ships a "Lua" entry in languageDeclarationPatterns but no
-"Luau" entry, even though its bundled scc database recognises ".luau" files as a
-distinct "Luau" language. Without a matching declaration table, every match in a
-.luau file is classified as a plain "usage": --only-declarations returns nothing
-and the structural ranker gives definitions no boost. This is the dominant file
-type in Roblox codebases, so we add a Luau entry that mirrors Lua's function
-prefixes and additionally covers Luau's `type` / `export type` declarations.
-
-This is a purely additive change (one new map entry); it does not alter any
-existing language's behaviour and passes cs's own pkg/ranker test suite. Applied
-during the Docker build via `git apply` against the pinned v3.1.0 checkout
-(see Dockerfile / Dockerfile.dev). Candidate for upstreaming to boyter/cs.
-
-diff --git a/pkg/ranker/declarations.go b/pkg/ranker/declarations.go
-index 42cd934..36f9f68 100644
---- a/pkg/ranker/declarations.go
-+++ b/pkg/ranker/declarations.go
-@@ -187,6 +187,12 @@ var languageDeclarationPatterns = map[string][]DeclarationPattern{
- {Prefix: []byte("function ")},
- {Prefix: []byte("local function ")},
- },
-+ "Luau": {
-+ {Prefix: []byte("function ")},
-+ {Prefix: []byte("local function ")},
-+ {Prefix: []byte("type ")},
-+ {Prefix: []byte("export type ")},
-+ },
- "Scala": {
- {Prefix: []byte("def ")},
- {Prefix: []byte("val ")},
diff --git a/docker/entrypoint.dev.sh b/docker/entrypoint.dev.sh
deleted file mode 100755
index 0feb37a..0000000
--- a/docker/entrypoint.dev.sh
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/bin/bash
-set -euo pipefail
-
-# ─── Match host user inside container ────────────────────────────
-# Ensures the process runs as the host UID/GID with a matching
-# home directory so volume mounts and config paths are consistent.
-
-HOST_UID="${HOST_UID:-1000}"
-HOST_GID="${HOST_GID:-1000}"
-HOST_USER="${HOST_USER:-dispatch}"
-
-USER_HOME="/home/$HOST_USER"
-
-# Create group if it doesn't exist
-if ! getent group "$HOST_GID" > /dev/null 2>&1; then
- groupadd -g "$HOST_GID" "$HOST_USER"
-fi
-
-# Ensure user with this UID has the correct home directory
-if id -u "$HOST_UID" > /dev/null 2>&1; then
- USER_NAME=$(getent passwd "$HOST_UID" | cut -d: -f1)
- usermod -d "$USER_HOME" "$USER_NAME" 2>/dev/null || true
-else
- useradd -u "$HOST_UID" -g "$HOST_GID" -d "$USER_HOME" -m -s /bin/bash "$HOST_USER"
- USER_NAME="$HOST_USER"
-fi
-
-# Ensure home and data directories exist with correct ownership
-mkdir -p "$USER_HOME" "$USER_HOME/.local/share/dispatch"
-chown "$HOST_UID:$HOST_GID" "$USER_HOME"
-chown -R "$HOST_UID:$HOST_GID" "$USER_HOME/.local/share/dispatch"
-
-# Ensure .claude is accessible
-if [ -d "$USER_HOME/.claude" ]; then
- chown -R "$HOST_UID:$HOST_GID" "$USER_HOME/.claude" 2>/dev/null || true
-fi
-
-# Ensure all node_modules are writable (created as root during build)
-find /app -name node_modules -type d -maxdepth 3 -exec chown -R "$HOST_UID:$HOST_GID" {} + 2>/dev/null || true
-
-# Install/update dependencies as the target user (skip with SKIP_INSTALL=1)
-if [ "${SKIP_INSTALL:-}" != "1" ]; then
- su -s /bin/bash - "$USER_NAME" -c "export HOME=$USER_HOME && cd /app && bun install"
-fi
-
-# ─── Env vars that must survive the `su -` login-shell barrier ──
-# `su -` resets the environment to a clean login profile (TERM, PATH,
-# HOME, SHELL, USER, LOGNAME, MAIL only — everything else is wiped).
-# Anything compose/Dockerfile set on PID 1 that the actual app process
-# needs has to be re-exported explicitly here. The
-# `${VAR-}` form (note: NOT `${VAR:-}`) preserves the empty-string case
-# so a deliberately-blank var stays blank instead of going undefined.
-FORWARD_VARS=(
- DISPATCH_DEBUG_LLM
- DISPATCH_DEBUG_LLM_VERBOSITY
- DISPATCH_DEBUG_LLM_DIR
- DISPATCH_DEBUG_USAGE
- DISPATCH_WORKING_DIR
- PORT
-)
-EXPORTS=""
-for var in "${FORWARD_VARS[@]}"; do
- # Use indirect expansion to read the var's current value, default to empty.
- val="${!var-}"
- # Single-quote-escape the value so shell-meaningful chars survive.
- esc=${val//\'/\'\\\'\'}
- EXPORTS+="export $var='$esc'; "
-done
-
-# Execute the main command as the target user
-exec su -s /bin/bash - "$USER_NAME" -c "export HOME=$USER_HOME && $EXPORTS cd /app && exec $*"
diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh
deleted file mode 100644
index 4f35d94..0000000
--- a/docker/entrypoint.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-set -euo pipefail
-
-# Production entrypoint
-# Future phases: add database migrations here
-
-# Execute the main command
-exec "$@"