feat: Deno worktrunk hooks with lib/ and project surface - #1
Merged
Conversation
- Port 10 bash hooks from systemfsoftware/scripts/tools/worktrunk to Deno TypeScript at repo root (forward-looking, not 1:1 mirror) - Split lib.ts into lib/git.ts, lib/paths.ts, lib/fs.ts, lib/mod.ts - Scripts are plain CLIs (no exports) with exact --allow-* shebangs - dprint config from systemfsoftware, tasks use dprint check + deno lint (non-brittle, no file enumeration) - Remove mod.ts (not a library) and name field Co-Authored-By: internal-model
- README: worktrunk hooks pitch, wt.toml wiring, hooks table, troubleshooting (5+ sections, fenced blocks, comparison table) - CI: dprint check + deno lint on push/PR to main (basic, mirrors systemfsoftware dprint.json) Co-Authored-By: internal-model
Co-Authored-By: internal-model
- Replace hardcoded 9-row hook table with generic pattern description pointing to *.ts at root - Avoid stale README when hooks are added Co-Authored-By: internal-model
- Replace hardcoded script listings and tables with clean architecture overview - Reference generic *.ts CLI execution pattern and lib/ split - Update clone URL to worktrunk-scripts and clarify wt.toml integration Co-Authored-By: internal-model
- Describe root vs lib/ separation conceptually without enumerating individual files - Prevents documentation drift as files are added or refactored Co-Authored-By: internal-model
- LICENSE: Apache 2.0 (matching systemfsoftware) - CONTRIBUTING: setup, structure invariants (standalone CLI root scripts, lib/ helpers), dprint gates, conventional commits Co-Authored-By: internal-model
Co-Authored-By: internal-model
- Remove enumerated file lists, specific version requirements, dprint config values, and example commit listings - Retain only core workflow tasks (deno task fmt/check) and structural conventions Co-Authored-By: internal-model
- differential_test.ts: 7 paired tests running upstream bash (/tmp/upstream-bash) and Deno hooks on identical fixtures, asserting identical transformations: tryRelative vs realpath, resolvePrimaryRepo, convert-to-relative-paths, worktree-to-relative, post-switch, pre-merge, pre-start (symlink targets + gitdir content) - pre-merge.ts: globToRegExp escaped [0-9] character classes, so issue symlink globs never matched; replace with explicit regexes - deno.lock: generated by deno test Co-Authored-By: internal-model
User does not want the differential tests. Co-Authored-By: internal-model
- gate on git add -A exit status: staging failure now fails the hook instead of letting the merge proceed with unstaged symlinks - split lstat race from remove failure: remove errors are logged, not swallowed, so a symlink that fails to delete is never silently merged - single readDir pass (pattern.some) instead of one scan per glob - skip git add entirely when nothing was removed - reuse lib/fs isSymlink and lib/git runGit instead of inline duplicates - CI: drop `2>/dev/null || deno lint` fallback that made the typecheck gate inert (type errors fell through to a green re-lint) Co-Authored-By: internal-model
- install-deps/generate-artifacts: propagate child exit codes (upstream
set -e contract) instead of logging and exiting 0 on build/install
failure; pip fallback now gated too
- pre-merge: run git add -A unconditionally (repairs a partially-failed
prior run) while keeping the exit gate
- codegraph-worktree-mcp: match bash instance sanitization exactly
(non-overlapping -- collapse; bash leaves a--b from a---b) and strip
trailing slash before basename so .mcp.json points at the real volume
- worktree-to-relative: use lib/git.ts resolvePrimaryRepo instead of the
local re-implementation (drops the "not a git repo at null" message)
- deno task check: add deno check so the local gate typechecks like CI
- README: wt.toml variables are {{ primary_worktree_path }}, not
{{ primary_path }} — the undefined variable aborted hook expansion
Co-Authored-By: internal-model
Co-Authored-By: internal-model
- 9 hook CLIs + lib/ moved from repo root to scripts/ (git mv; internal ./lib and ./codegraph-worktree-mcp.ts relative references unchanged) - deno task check and CI typecheck glob updated to scripts/*.ts scripts/lib/*.ts - README/CONTRIBUTING updated: wt.toml paths, design, conventions Co-Authored-By: internal-model
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The worktrunk-config repo becomes the Deno home for worktrunk worktree hooks: the 10 bash hooks from
systemfsoftware/scripts/tools/worktrunkare ported to TypeScript at the repo root, sharing alib/of git/path/fs helpers, with a project surface (README, Apache-2.0 license, contributing guide, CI) and a review-hardening pass.What changed
*.tswith#!/usr/bin/env -S deno run --allow-*shebang scopes). Ported behavior: gitdir absolute-to-relative conversion, shared-dir symlinking (.repos/.issues/wiki), codegraph warm-copy fallback chain (sqlite3 .backup -> reflink -> copy with integrity check), worktree MCP provisioning, lockfile-driven dependency install and build generation, pre-merge issue-symlink cleanup, post-switch GitKraken config unset.lib/git.ts(resolvePrimaryRepo, runGit),lib/paths.ts(tryRelative),lib/fs.ts(isDirectory/File/Symlink). Hooks are plain CLIs with no exports.npm ciorpnpm buildaborts the hook (bashset -eparity) instead of logging and exiting 0. Verified: build failure exits 1.pre-mergerunsgit add -Aunconditionally so a retry repairs a partially-failed prior run, keeping the exit gate.codegraph-worktree-mcpinstance sanitization matches the bash original's non-overlapping dash collapse, and strips trailing slashes so.mcp.jsonpoints at the real volume.worktree-to-relativeuseslib/git.tsinstead of a local re-implementation (fixes "not a git repo at null").deno task checknow typechecks; CI's typecheck step is a real gate (no silent|| lintfallback).Validation
deno task check(dprint + lint + deno check) passes..mcp.jsonprovisioning and the codegraph warm-copy chain skipped gracefully without codegraph/sqlite3 present (best-effort, logs, continues tocodegraph init).