diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 248cd864..00000000 --- a/Dockerfile +++ /dev/null @@ -1,26 +0,0 @@ -FROM node:22-slim -RUN apt-get update && apt-get install -y \ - bats \ - git \ - python3 \ - make \ - g++ \ - && rm -rf /var/lib/apt/lists/* -WORKDIR /app -# Copy git-warp -COPY git-warp/package*.json ./ -COPY git-warp/scripts ./scripts -COPY git-warp/patches ./patches -RUN npm install -COPY git-warp . -RUN git init -q \ - && git config user.email "container@git-warp.local" \ - && git config user.name "Git Warp Container" \ - && git add -A \ - && git commit --allow-empty -m "seed git-warp" >/dev/null -RUN printf '%s\n' '#!/usr/bin/env bash' 'exec node /app/bin/warp-graph.js "$@"' > /usr/local/bin/warp-graph -RUN chmod +x /usr/local/bin/warp-graph \ - && install -m 0755 /app/bin/git-warp /usr/local/bin/git-warp -ENV GIT_STUNTS_DOCKER=1 -# Default to tests, but can be overridden for benchmark -CMD ["npm", "test"] diff --git a/Dockerfile b/Dockerfile new file mode 120000 index 00000000..1836fdfd --- /dev/null +++ b/Dockerfile @@ -0,0 +1 @@ +docker/Dockerfile.node22-slim \ No newline at end of file diff --git a/FIXUPS.md b/FIXUPS.md deleted file mode 100644 index 742d5e6d..00000000 --- a/FIXUPS.md +++ /dev/null @@ -1,85 +0,0 @@ -# SEEKDIFF Code Review — Fixups - -Deep self-review of `seekdiff` branch (commit `9f3e02a`). -Severity: **BUG** = correctness issue, **PERF** = wasted work, **UX** = user-facing rough edge, **NIT** = code quality / style. - ---- - -## BUG - -- [x] **B1. `--diff-limit=0` produces misleading output.** Rejected `0` at parse time — validation now requires a positive integer (`n < 1`). Added BATS test for `--diff-limit=0`, `--diff-limit=-1`, and missing value. - - **Fix:** `bin/warp-graph.js` — `handleDiffLimitFlag` validation changed from `n < 0` to `n < 1` - ---- - -## PERF - -- [x] **P1. Triple materialization in the `latest` action.** When `--diff` already materialized at `maxTick`, skip the redundant `graph.materialize()` call. Non-diff path now uses `{ ceiling: maxTick }` for consistency. - - **Fix:** `bin/warp-graph.js` — `if (!sdResult) { await graph.materialize({ ceiling: maxTick }); }` - -- [x] **P2. Redundant re-materialization in `tick` and `load` actions.** Same pattern: skip `materialize()` when `computeStructuralDiff` already left the graph at the target tick. - - **Fix:** `bin/warp-graph.js` — `if (!sdResult) { await graph.materialize(...) }` in both paths - -- [x] **P3. No short-circuit when `prevTick === currentTick`.** Added early return with empty diff result when ticks are identical. - - **Fix:** `bin/warp-graph.js` — `computeStructuralDiff` returns empty diff immediately - ---- - -## UX - -- [x] **U1. `--diff` and `--diff-limit` missing from `HELP_TEXT`.** Added both flags to the Seek options section. - - **Fix:** `bin/warp-graph.js` — `HELP_TEXT` - -- [x] **U2. `--diff` silently ignored on `--save`, `--drop`, `--list`, `--clear-cache`.** Added validation at end of `parseSeekArgs`: `--diff` rejects with usage error when combined with non-navigating actions. Allowed on `status`, `tick`, `latest`, `load`. Added BATS test for `--save --diff` rejection. - - **Fix:** `bin/warp-graph.js` — `DIFF_ACTIONS` set check after parse loop - -- [x] **U3. Display truncation hides data-level truncation hint.** Combined message now shown when both display and data truncation are active: `"... and N more changes (N total, use --diff-limit to increase)"`. Added unit test. - - **Fix:** `src/visualization/renderers/ascii/seek.js` — `buildStructuralDiffLines` three-way if/else - -- [x] **U4. Truncation strategy is greedy, not proportional (misleading comment).** Fixed comment to say "greedy in category order." - - **Fix:** `bin/warp-graph.js` — comment at `applyDiffLimit` - ---- - -## NIT - -- [x] **N1. `getStateSnapshot()` JSDoc type in CLI typedef uses `@property {() => Promise<*>}`.** Fixed to reference `WarpStateV5 | null`. - - **Fix:** `bin/warp-graph.js` — `WarpGraphInstance` typedef - -- [x] **N2. `formatStructuralDiff(payload)` on the status render path is dead code.** Removed the dead call; added comment explaining status never carries diff data. - - **Fix:** `bin/warp-graph.js` — `renderSeek` status branch - -- [x] **N3. `applyDiffLimit` comment says "proportionally" — see U4.** Fixed alongside U4. - - **Fix:** `bin/warp-graph.js` - -- [x] **N4. `buildStructuralDiffLines` uses magic number 20 in two places.** Moved `MAX_DIFF_LINES` constant above `buildFooterLines` so both call sites reference the constant. - - **Fix:** `src/visualization/renderers/ascii/seek.js` — hoisted constant - -- [x] **N5. `collectDiffEntries` uses `@param {*}` for the diff parameter.** Changed to `import(...).StateDiffResult`. - - **Fix:** `src/visualization/renderers/ascii/seek.js` - -- [x] **N6. `buildStructuralDiffLines` uses `@param {*}` for the payload parameter.** Changed to `SeekPayload`. - - **Fix:** `src/visualization/renderers/ascii/seek.js` - -- [x] **N7. No unit test for `--diff-limit` argument parsing edge cases.** Added 4 BATS tests: `--diff-limit=0` rejected, `--diff-limit` without value rejected, `--diff-limit=-1` rejected, `--diff --save` rejected. - - **Fix:** `test/bats/cli-seek.bats` - -- [x] **N8. No test for `--diff` combined with `--latest` or `--load`.** Added BATS test for `--latest --diff --json`. Added 2 renderer unit tests for `latest` and `load` action payloads with `structuralDiff`. Added 1 unit test for combined display+data truncation. - - **Fix:** `test/bats/cli-seek.bats`, `test/unit/visualization/ascii-seek-renderer.test.js` - ---- - -## Summary - -| Severity | Count | Fixed | -|----------|-------|-------| -| BUG | 1 | 1 | -| PERF | 3 | 3 | -| UX | 4 | 4 | -| NIT | 8 | 8 | -| **Total**| **16**| **16**| - -### Verification - -- `npx eslint` — clean -- `npx vitest run` — 3209 passed, 0 regressions (8 pre-existing failures: 7 Deno/Docker-only, 1 flaky EPIPE) diff --git a/README.md b/README.md index 56b15b49..c8877e69 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![npm version](https://badge.fury.io/js/%40git-stunts%2Fgit-warp.svg)](https://www.npmjs.com/package/@git-stunts/git-warp)

- git-warp CLI demo + git-warp CLI demo

## The Core Idea diff --git a/bin/cli/shared.js b/bin/cli/shared.js index 9b6394cf..9b3f6e4f 100644 --- a/bin/cli/shared.js +++ b/bin/cli/shared.js @@ -180,7 +180,7 @@ export async function readCheckpointDate(persistence, checkpointSha) { export function createHookInstaller() { const __filename = new URL(import.meta.url).pathname; const __dirname = path.dirname(__filename); - const templateDir = path.resolve(__dirname, '..', '..', 'src', 'hooks'); + const templateDir = path.resolve(__dirname, '..', '..', 'scripts', 'hooks'); const { version } = JSON.parse(fs.readFileSync(path.resolve(__dirname, '..', '..', 'package.json'), 'utf8')); return new HookInstaller({ fs: /** @type {*} */ (fs), // TODO(ts-cleanup): narrow port type diff --git a/docker-compose.yml b/docker-compose.yml index 7bc108ed..834905c9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,14 +2,14 @@ services: test: build: context: .. - dockerfile: git-warp/Dockerfile + dockerfile: git-warp/docker/Dockerfile.node22-slim environment: - GIT_STUNTS_DOCKER=1 benchmark: build: context: .. - dockerfile: git-warp/Dockerfile + dockerfile: git-warp/docker/Dockerfile.benchmark volumes: - ./benchmarks:/app/benchmarks environment: diff --git a/Dockerfile.benchmark b/docker/Dockerfile.benchmark similarity index 100% rename from Dockerfile.benchmark rename to docker/Dockerfile.benchmark diff --git a/docker/Dockerfile.node22-slim b/docker/Dockerfile.node22-slim new file mode 100644 index 00000000..248cd864 --- /dev/null +++ b/docker/Dockerfile.node22-slim @@ -0,0 +1,26 @@ +FROM node:22-slim +RUN apt-get update && apt-get install -y \ + bats \ + git \ + python3 \ + make \ + g++ \ + && rm -rf /var/lib/apt/lists/* +WORKDIR /app +# Copy git-warp +COPY git-warp/package*.json ./ +COPY git-warp/scripts ./scripts +COPY git-warp/patches ./patches +RUN npm install +COPY git-warp . +RUN git init -q \ + && git config user.email "container@git-warp.local" \ + && git config user.name "Git Warp Container" \ + && git add -A \ + && git commit --allow-empty -m "seed git-warp" >/dev/null +RUN printf '%s\n' '#!/usr/bin/env bash' 'exec node /app/bin/warp-graph.js "$@"' > /usr/local/bin/warp-graph +RUN chmod +x /usr/local/bin/warp-graph \ + && install -m 0755 /app/bin/git-warp /usr/local/bin/git-warp +ENV GIT_STUNTS_DOCKER=1 +# Default to tests, but can be overridden for benchmark +CMD ["npm", "test"] diff --git a/TYPESCRIPT_ZERO.md b/docs/TYPESCRIPT_ZERO.md similarity index 100% rename from TYPESCRIPT_ZERO.md rename to docs/TYPESCRIPT_ZERO.md diff --git a/hero.gif b/docs/images/hero.gif similarity index 100% rename from hero.gif rename to docs/images/hero.gif diff --git a/hero.tape b/docs/images/hero.tape similarity index 98% rename from hero.tape rename to docs/images/hero.tape index 926658c7..4e7fd351 100644 --- a/hero.tape +++ b/docs/images/hero.tape @@ -1,7 +1,7 @@ # hero.tape — git-warp hero GIF for README # Record: vhs hero.tape -Output hero.gif +Output docs/images/hero.gif Set Shell "bash" Set FontSize 16 diff --git a/examples/WALKTHROUGH.md b/examples/WALKTHROUGH.md index 0ead3ff3..dcfef486 100644 --- a/examples/WALKTHROUGH.md +++ b/examples/WALKTHROUGH.md @@ -174,7 +174,7 @@ See that tree hash? `4b825dc642cb6eb9a060e54bf8d69288fbee4904` is the **empty tr Still in the container, run: ```bash -node /app/examples/explore.js +node /app/examples/scripts/explore.js ``` Or from your host machine: @@ -413,7 +413,7 @@ This removes the container and volumes. Run `demo:setup` again anytime to start - Read the [ARCHITECTURE.md](../ARCHITECTURE.md) for a technical deep-dive into index sharding and hexagonal design - Check out the [README.md](../README.md) for the full API reference - Look at the source in `src/domain/services/TraversalService.js` to see how algorithms are implemented -- Explore [examples/explore.js](./explore.js) to understand the event projection pattern +- Explore [examples/scripts/explore.js](./scripts/explore.js) to understand the event projection pattern - Try building your own event-sourced application! --- @@ -456,11 +456,11 @@ npm run demo:setup For the curious, here's what happens behind the scenes: -1. **`npm run demo:setup`** runs `docker compose up -d` in the `examples/` directory, then executes `setup.js` inside the container. +1. **`npm run demo:setup`** runs `docker compose up -d` in the `examples/` directory, then executes `scripts/setup.js` inside the container. -2. **`setup.js`** initializes a git repo at `/demo`, creates a chain of event commits using `graph.createNode()`, branches off at `OrderPlaced` to create an alternate timeline, and builds the bitmap index. +2. **`scripts/setup.js`** initializes a git repo at `/demo`, creates a chain of event commits using `graph.createNode()`, branches off at `OrderPlaced` to create an alternate timeline, and builds the bitmap index. -3. **`explore.js`** loads the index, then demonstrates: +3. **`scripts/explore.js`** loads the index, then demonstrates: - `graph.traversal.ancestors()` for event replay - Event projection (reducer pattern) - `graph.traversal.descendants()` for branch comparison diff --git a/examples/html/event-sourcing.html b/examples/html/event-sourcing.html index 9ef6d678..f8bdb0dd 100644 --- a/examples/html/event-sourcing.html +++ b/examples/html/event-sourcing.html @@ -39,14 +39,14 @@