commit aa52c923599ecc0e9865e2dacfd8ec4a9af74f25 Author: EFLKumo <96906415+EFLKumo@users.noreply.github.com> Date: Fri Sep 18 17:43:24 2026 +0800 init diff --git a/.agents/skills/jj-vcs/SKILL.md b/.agents/skills/jj-vcs/SKILL.md new file mode 100644 index 0000000..98e0b31 --- /dev/null +++ b/.agents/skills/jj-vcs/SKILL.md @@ -0,0 +1,155 @@ +--- +name: jj-vcs +description: Using jj (Jujutsu) for version control. Make sure to use this skill whenever the user mentions jj, jujutsu, version control, commits, branches/bookmarks, rebasing, history rewriting, cloning/pushing/pulling, or any VCS workflow — even when they don't explicitly say "jj." This skill covers daily editing, history restructuring, collaboration with remotes, and recovery from mistakes. When the user's repository uses jj (look for a .jj/ directory), ALWAYS use jj commands instead of git commands. +allowed-tools: Bash(jj:*) +license: MIT +metadata: + author: OpticLM + version: "0.41.0.2" +--- + +## Core mental model + +jj is a Git-compatible version control system built around *changes* (revisions) that evolve over time. Each change has a **change ID** (stable — follows the change across rebases) and a **commit hash** (changes whenever the commit content changes). Refer to changes by their change ID (short prefix form) when you want to track a logical change, or by commit hash when pinning exact content. + +Key differences from Git: +- **No staging area.** The working copy (`@`) is itself a commit. `jj status` compares `@` to its parent. Changes to tracked files are automatically part of `@`. +- **Change IDs**, not branch names, are the primary way history is organized. A commit's change ID survives rebase, squash, and split. +- **Operation log.** Every jj command creates an operation. `jj undo` simply undoes the last operation. `jj op log` shows the full history of commands run. Nothing is lost unless you explicitly garbage-collect. +- **Bookmarks, not branches.** Bookmarks are labels on revisions. To move a bookmark to point at a different revision, use `jj bookmark move`. Git branches are just bookmarks that jj syncs to the remote. +- **Revsets.** jj's revision selection language. Used everywhere commands accept revisions. Learn the common patterns (see core-concepts.md). + +--- + +## Finding the right command + +### Daily work loop + +The core cycle is: **start a change → make edits → describe → (optionally) start the next change.** + +| Intent | Command | +|---|---| +| See what's changed in `@` | `jj status` (aliases: `st`) | +| See file-level diff | `jj diff` (use `--git` for git-style output, `-s` for summary) | +| Start a new change on top of `@` | `jj new [REVISION]` (defaults to `@`) | +| Describe/set the commit message | `jj describe -m "msg"` or `jj describe` (opens editor) | +| Describe + start next change | `jj commit -m "msg"` (equivalent to `describe -m && new`) | +| View revision graph | `jj log` (use `-r` with a revset to filter, `-p` for patch) | +| Browse file in older revision | `jj file show -r REV PATH` | + +`jj new` is the primary way to create changes. It creates an empty child of the given revision and makes it the new `@`. Unlike `git checkout -b`, it does not need a branch name. + +When the user says "commit my changes" they almost always mean `jj describe -m "message"` to record a message on the current change, or `jj commit -m "message"` to record and start a new empty change on top. + +### History restructuring + +jj makes rewriting history safe because nothing is truly lost (the operation log preserves everything). + +| Intent | Command | +|---|---| +| Move a change to a different parent | `jj rebase -r REV -o NEW_PARENT` | +| Move a whole branch of changes | `jj rebase -b REV -o NEW_PARENT` | +| Absorb changes from `@` into parent | `jj squash` (moves `@`'s diff into its parent) | +| Squash specific changes into sibling | `jj squash -f FROM_REV -t INTO_REV` | +| Split a revision in two | `jj split [-r REV]` (interactive by default) | +| Drop a change entirely | `jj abandon [-r REV]` (defaults to `@` if empty) | +| Rename/edit a change's description | `jj describe -r REV -m "new message"` | +| Edit a change's metadata (author, etc.) | `jj metaedit -r REV` | +| Pull edits from child into parent | `jj absorb` (auto-detects where changes belong) | +| Reorder siblings into a chain | `jj parallelize -r REVS...` | +| Interactive graph rearrangement | `jj arrange` | +| Touch up a change's content diff | `jj diffedit -r REV` | + +**Common squash patterns:** +- `jj squash` — squash `@` into its parent (the most common: you made a small fix that belongs in the previous commit) +- `jj squash -f FEATURE_REV -t MAIN` — move changes from a feature revision into main + +**Common rebase patterns:** +- `jj rebase -r REV -o DEST` — rebase a single revision onto DEST +- `jj rebase -b REV -o DEST` — rebase REV and all its descendants onto DEST +- `jj rebase -r REV --insert-after ANCHOR` — reorder REV to come after ANCHOR (useful for reordering commits in a stack) +- `jj rebase -r REV --insert-before ANCHOR` + +When rebasing after a squash/split/abandon, jj automatically rebases descendants. You rarely need to manually restack. + +### Collaboration + +jj interoperates with Git remotes. The workflow is: fetch → rebase → push. + +| Intent | Command | +|---|---| +| Clone a remote repo | `jj git clone ` | +| Fetch from remote | `jj git fetch [--remote NAME]` | +| Push to remote | `jj git push [--remote NAME]` | +| List bookmarks and their targets | `jj bookmark list` (aliases: `b l`) | +| Track a remote bookmark as local | `jj bookmark track NAME --remote origin` | +| Move a bookmark to point at a revision | `jj bookmark move --to REV BOOKMARK` (aliases: `b m -t REV BOOKMARK`) | +| Create a new bookmark | `jj bookmark create NAME` | +| List remotes | `jj git remote list` | +| Add a remote | `jj git remote add NAME URL` | + +**Push workflow:** +1. Ensure the bookmark you want to push points at your revision: `jj bookmark move --to=@ BOOKMARK` +2. Push: `jj git push` +3. If the remote has new commits: `jj git fetch` then `jj rebase -b BOOKMARK -o BOOKMARK@origin` + +**Important:** Before pushing, always check the change has a description. `jj git push` will fail or warn you if a change lacks a description. Use `jj describe -m "msg"` first. + +### Recovery + +| Intent | Command | +|---|---| +| Undo the last operation | `jj undo` | +| Redo an undo | `jj redo` | +| See operation history | `jj op log` | +| Restore repo to a past state | `jj op restore OPERATION_ID` | +| Restore files in `@` (undo edits in wd) | `jj restore` (restores all files from parent) | +| Restore specific paths from another revision | `jj restore --from SOURCE_REV PATH...` | +| Undo the changes introduced by a commit | `jj restore --changes-in REV` (creates a reverse of REV on top of @, effectively undoing its changes) | +| Resolve conflicts | `jj resolve PATH...` (opens external merge tool) | +| Inspect old repo state without restoring | `jj --at-op OPERATION_ID status` | + +`jj undo` is the first thing to reach for when something goes wrong. If you need to undo farther back, `jj op log` + `jj op restore` can take you to any previous state. + +--- + +## Git-to-jj translation + +When a user asks for a git command, translate to the equivalent jj command: + +| Git | jj | +|---|---| +| `git add FILE` | Edit FILE (no staging needed — tracked files auto-included) | +| `git commit -m "msg"` | `jj describe -m "msg"` (or `jj commit -m "msg"` to also start a new change) | +| `git commit --amend` | `jj squash` (move `@`'s changes into its parent) | +| `git checkout BRANCH` | `jj new BOOKMARK` | +| `git checkout -b BRANCH` | `jj new` then `jj bookmark create NAME` | +| `git branch -d BRANCH` | `jj bookmark delete NAME` | +| `git rebase main` | `jj rebase -b @ -o MAIN` | +| `git reset HEAD~1` | `jj restore` then `jj abandon @` | +| `git revert COMMIT` | `jj restore --changes-in COMMIT` | +| `git log --oneline` | `jj log --no-graph` | +| `git stash` | Not needed — just `jj new` to start fresh on top, or `jj bookmark create` to save the current state | + +--- + +## Choosing the right ancestor (`-o`) vs insert-after (`-A`) vs insert-before (`-B`) + +- `-o` / `--onto`: makes the source revision(s) children of the target. Most common. +- `-A` / `--insert-after`: inserts the source revision(s) *after* the target, making them siblings of the target's current children. Use when reordering within a stack. +- `-B` / `--insert-before`: inserts the source revision(s) *before* the target, making them parents of the target. Use when you want to add a step before an existing commit. + +These options appear on `rebase`, `new`, `split`, `squash`, and `restore`. + +--- + +## Reference files + +Read these for deeper guidance on specific workflows: + +- **references/core-concepts.md** — Revsets, change IDs, working copy mechanics, configuration +- **references/daily-work.md** — Commands and patterns for the daily edit/describe/log loop +- **references/history-rewriting.md** — Detailed squash, rebase, split, abandon, and absorb patterns +- **references/collaboration.md** — Pushing, pulling, bookmark management, Gerrit +- **references/recovery.md** — Undo, operation log, conflict resolution, and restore +- **references/commands.md** — Quick reference for every jj command with key flags diff --git a/.agents/skills/jj-vcs/references/collaboration.md b/.agents/skills/jj-vcs/references/collaboration.md new file mode 100644 index 0000000..dc71077 --- /dev/null +++ b/.agents/skills/jj-vcs/references/collaboration.md @@ -0,0 +1,125 @@ +# Collaboration + +Commands for working with Git remotes, bookmarks, and pushing/pulling changes. + +## jj git clone + +Clone a remote Git repository into a jj-backed repo. + +``` +jj git clone # clone and checkout default branch +jj git clone --colocate # clone as a colocated repo (works with git commands too) +``` + +## jj git fetch + +Fetch changes from a remote. Unlike `git fetch`, this fetches all bookmarks by default and can automatically track new bookmarks based on config. + +``` +jj git fetch # fetch all remotes +jj git fetch --remote origin # fetch only origin +jj git fetch --remote origin main # fetch specific bookmark(s) +``` + +After fetch, new remote bookmarks appear as `BOOKMARK@remote`. They aren't automatically tracked — you must explicitly `jj bookmark track` them. + +## jj git push + +Push changes to a remote. By default, pushes all bookmarks that have a remote counterpart. + +``` +jj git push # push all tracked bookmarks +jj git push --remote origin # push to specific remote +jj git push --bookmark main # push only specific bookmark(s) +jj git push --deleted BOOKMARK # propagate a bookmark deletion +jj git push --change CHANGE_ID # push a specific change by change ID +``` + +- `--bookmark` / `-b`: specify which bookmarks to push +- `--change`: push a single change to the remote as a draft PR (creates a bookmark on the remote) +- `--remote`: specify the remote +- `--deleted`: confirm you want to push a bookmark deletion to the remote + +**Push checklist:** +1. The revision has a description: `jj describe -m "msg"` +2. The bookmark points at the right revision: `jj bookmark move --to=REV BOOKMARK` or use `jj bookmark set BOOKMARK` (creates or moves) +3. The revision does not have conflicts: `jj status` will show them +4. You're not upstream of others' work (if collaborating) +5. Push: `jj git push` + +## jj bookmark + +Bookmark management. Short alias: `jj b`. + +``` +jj bookmark list # list all bookmarks and their targets (aliases: l) +jj bookmark create NAME # create a new bookmark at @ (aliases: c) +jj bookmark move --to REV NAME # move bookmark NAME to point at REV (aliases: m) +jj bookmark set NAME # create or update bookmark NAME at @ (aliases: s) +jj bookmark track NAME --remote R # track a remote bookmark locally (aliases: t) +jj bookmark untrack NAME # stop tracking a remote bookmark +jj bookmark delete NAME # delete a local bookmark (aliases: d) +jj bookmark forget NAME # forget a bookmark without pushing deletion +jj bookmark advance NAME # advance bookmark to nearest descendant of current target +jj bookmark rename OLD NEW # rename a bookmark +``` + +**Bookmark workflow for pushing changes:** +1. Work in `@` (on top of main) +2. When ready: `jj bookmark move --to=@ main` (move the main bookmark to `@`) +3. `jj git push` (pushes main to origin/main) + +Or use a feature-branch workflow: +1. `jj bookmark create my-feature` (creates bookmark at `@`) +2. Work, describe, etc. +3. `jj git push -b my-feature` (pushes just `my-feature`) + +**Tracking:** When you clone a repo, remote bookmarks like `main@origin` exist but aren't automatically tracked. `jj bookmark track main --remote origin` creates a local `main` bookmark that follows `main@origin`. Without this, `jj git push` may not know which local bookmark corresponds to which remote bookmark. + +## jj git remote + +Manage Git remotes. + +``` +jj git remote list # list remotes +jj git remote add NAME URL # add a remote +jj git remote remove NAME # remove a remote +jj git remote set-url NAME URL # change a remote's URL +``` + +## jj git colocation + +Manage colocation with an underlying Git repo. Colocation means the `.jj` repo works on the same working copy as a `.git` repo, allowing both `jj` and `git` commands. + +``` +jj git colocation init # initialize colocation +jj git colocation deinit # remove colocation +jj git export # manually sync jj changes to git +jj git import # manually sync git changes to jj +``` + +With colocation, export/import happens automatically on most commands. Use manual `jj git export` or `jj git import` if you've made changes in git that jj doesn't see yet. + +## jj gerrit + +Interact with Gerrit Code Review. + +``` +jj gerrit submit CHANGE_ID # submit a change to Gerrit +jj gerrit abandon CHANGE_ID # abandon a change in Gerrit +``` + +## Working with stacks + +jj excels at stacking changes. Common pattern: + +1. `jj new main` — start from main +2. `jj describe -m "part 1"` — describe first change +3. `jj new` — start second change +4. `jj describe -m "part 2"` — describe second change +5. `jj bookmark create stack-1` — save both (bookmark on latest) +6. `jj bookmark create stack-2` — or just push with `jj git push -b stack-1` + +To restack after reviews: +1. `jj rebase -b stack-1 -o main` — move whole stack +2. `jj git push` — update remote diff --git a/.agents/skills/jj-vcs/references/commands.md b/.agents/skills/jj-vcs/references/commands.md new file mode 100644 index 0000000..0ea2444 --- /dev/null +++ b/.agents/skills/jj-vcs/references/commands.md @@ -0,0 +1,51 @@ +# Command quick reference + +Every jj command with a one-line description and key flags. Read this when you need a quick overview of what commands are available. + +| Command | Description | Key flags | +|---|---|---| +| `jj abandon [-r REV]` | Drop a revision from history | `-r` revision to drop (default: `@`) | +| `jj absorb` | Auto-merge changes into their logical parent revisions | — | +| `jj arrange` | Interactively rearrange the commit graph | — | +| `jj bisect -r GOOD..BAD` | Binary search for a bad revision | Standard bisect: start, good, bad, skip | +| `jj bookmark ` | Manage bookmarks | Subcommands: list, create, delete, move, set, track, untrack, forget, advance, rename | +| `jj commit -m "msg"` | Describe `@` and create a new empty change on top | `-m`, `-i` interactive | +| `jj config ` | Manage configuration | Subcommands: get, set, edit, list, default | +| `jj describe -r REV -m "msg"` | Set or edit a revision's description | `-r` revision, `-m` message, `--stdin`, `--editor` | +| `jj diff [-r REV]` | Show diff of a revision | `-r`, `--git`, `-s` summary, `--stat`, `--name-only`, `--color-words` | +| `jj diffedit -r REV` | Edit a revision's content diff interactively | `-r`, `-i` | +| `jj duplicate -r REV` | Copy a revision's content to a new change ID | `-r` | +| `jj edit REV` | Switch working copy to an existing revision | — | +| `jj evolog -r REV` | Show how a change's content evolved over time | `-r`, `-p` patch | +| `jj file ` | File operations | Subcommands: list, show, chmod, track, untrack | +| `jj fix [-r REV]` | Apply formatting/linting tools to files in a revision | `-r`, `-s` source revsets, `--tool`, `-i` | +| `jj git ` | Git remote operations | Subcommands: clone, fetch, push, remote, init, export, import, colocation | +| `jj gerrit ` | Interact with Gerrit Code Review | Subcommands: submit, abandon | +| `jj help [CMD]` | Show help for jj or a specific command | — | +| `jj interdiff --from A --to B` | Show differences between two revisions' diffs | `--from`, `--to` | +| `jj log [-r REVSET]` | Show revision history graph | `-r`, `-n`, `--no-graph`, `-p`, `--reversed`, `--count`, `-T` template | +| `jj metaedit -r REV` | Edit revision metadata (author, date, description) | `-r`, `--reset-author` | +| `jj new [REV]...` | Create a new empty change (child of given revision) | `-m`, `--no-edit`, `--insert-after`, `--insert-before` | +| `jj next` | Move working copy to the child revision | `-e` edit the destination | +| `jj op ` | Operation log commands | Subcommands: log, restore, undo, discard, integrate | +| `jj parallelize -r REVS` | Make sibling revisions into parallel branches | `-r` | +| `jj prev` | Move working copy to the parent revision | `-e` edit the destination | +| `jj rebase -r REV -o DEST` | Move revisions to different parent(s) | `-r`, `-s`, `-b`, `-o/\!--onto`, `--insert-after`, `--insert-before`, `--skip-emptied` | +| `jj redo` | Redo the last undone operation | — | +| `jj resolve PATH...` | Resolve merge conflicts | `--list` | +| `jj restore [PATH]...` | Restore file contents (undo changes to a path or revision) | `--from`, `--into`, `--changes-in`, `-i` | +| `jj revert [-r REV]` | Apply reverse of the given revision(s) | `-r` (same as `jj restore --changes-in REV`) | +| `jj root` | Show workspace root directory | — | +| `jj show [-r REV]` | Show revision description and its diff | `-r` | +| `jj sign -r REV` | Cryptographically sign a revision | `-r` | +| `jj simplify-parents -r REV` | Remove redundant parent edges | `-r` | +| `jj sparse ` | Manage sparse checkout patterns | Subcommands: set, edit, list, clear, reset | +| `jj split [-r REV]` | Split a revision into two | `-r`, `-i`, `-m`, `--parallel`, `--insert-after`, `--insert-before` | +| `jj squash [-f FROM -t INTO]` | Move changes between revisions | `-f` from, `-t` into, `-i`, `-k` keep-emptied, `-m`, `--insert-after` | +| `jj status` | Show working copy status (aliases: `st`) | — | +| `jj tag ` | Manage tags | Subcommands: list, set, delete | +| `jj undo` | Undo the last operation | `--undo` (un-undo) | +| `jj unsign -r REV` | Drop cryptographic signature from a revision | `-r` | +| `jj util ` | Infrequently used utilities | Subcommands: gc, completion, config-schema, etc. | +| `jj version` | Show version information | — | +| `jj workspace ` | Manage workspaces | Subcommands: root, list, add, forget, upgrade | diff --git a/.agents/skills/jj-vcs/references/core-concepts.md b/.agents/skills/jj-vcs/references/core-concepts.md new file mode 100644 index 0000000..07a02b4 --- /dev/null +++ b/.agents/skills/jj-vcs/references/core-concepts.md @@ -0,0 +1,95 @@ +# Core concepts + +Understanding these concepts is essential for using jj correctly. Read this when the user seems new to jj, or when you need to reason about jj behavior beyond simple commands. + +## Change IDs vs commit hashes + +Every revision in jj has two identifiers: + +- **Change ID** — A stable identifier (e.g., `abc12345`) that follows the revision across rebases, squashes, and splits. Use this when referring to a logical change over time. +- **Commit hash** — A hash of the commit content (like Git). Changes every time the diff changes. Use this when you need to reference exact content. + +Commands that take revisions (almost all of them) accept change IDs, commit hashes, or revset expressions. Prefer change IDs for user-facing references since they're stable. + +## The working copy (`@`) + +The `@` symbol represents the working copy revision. Unlike Git's detached HEAD or branch-based model: + +- `@` is always a regular commit. It can have a description, parent(s), and children. +- When you edit files, those changes belong to `@`. +- `jj new` creates a new *empty* commit on top of `@` and makes that the new `@`. The old `@` becomes `@-` (parent of working copy). +- `jj edit REV` sets the working copy to revision REV. Edits go directly into that revision's diff. Use `jj new` instead unless you specifically need to amend an existing change. +- `jj status` shows the diff between `@` and its parent (`@-`). + +## Operation log + +Every jj command creates an **operation** in the operation log. This is jj's safety net: + +- `jj op log` shows the history of commands (like shell history but richer) +- `jj undo` creates a new operation that reverses the last one +- `jj op restore OP_ID` restores the repo to the state after a given operation +- `jj --at-op OP_ID ` runs a command as if the repo were at that operation (read-only inspection) + +Nothing is permanently lost unless you run `jj util gc` (garbage collection). The operation log is append-only. + +## Revsets + +Revsets are jj's query language for selecting revisions. They appear everywhere a command accepts revisions. Key patterns: + +| Expression | Meaning | +|---|---| +| `@` | The working copy revision | +| `main` | The revision pointed to by bookmark `main` | +| `main@origin` | The revision pointed to by `main` on the `origin` remote | +| `root()` | The root revision (virtual, all repos share it) | +| `all()` | Every revision in the repo | +| `mine()` | Revisions authored by the current user | +| `none()` | Empty set | +| `parents(REVSET)` | Parents of revisions in the set | +| `children(REVSET)` | Children of revisions in the set | +| `ancestors(REVSET)` | All ancestors (recursive parents) | +| `descendants(REVSET)` | All descendants (recursive children) | +| `::` | DAG range — `A::B` means "A and B and everything between them" | +| `..` | Reachable from B but not from A — `A..B` means "B and ancestors of B not also ancestors of jj" | +| `X \ Y` | Set difference | +| `X + Y` | Set union | +| `X & Y` | Set intersection | +| `empty()` | Revisions with no diff from their parent | +| `description(REGEX)` | Revisions whose description matches REGEX | +| `author("NAME")` | Revisions authored by NAME (partial match) | +| `bookmarks()` | Revisions that have bookmarks | +| `immutable_heads()` | The configured immutable set | +| `latest(N, REVSET)` | The latest N revisions in the set | +| `merged()` | Merge commits | + +**Practical examples:** +- `main..@` — revisions in `@`'s ancestors that aren't in main (what you changed since main) +- `ancestors(@) & ~immutable_heads()` — everything you can safely rewrite +- `@-` — the parent of the working copy (one commit back) +- `@--` — grandparent of the working copy +- `description("fix.*")` — revisions with descriptions starting with "fix" +- `empty() & ~@` — revisions that are empty but not the working copy (candidates for abandonment) + +## Bookmarks + +Bookmarks are labels attached to revisions. They serve the same conceptual role as Git branches but behave differently: + +- Bookmarks can coexist at the same revision (no conflict) +- Moving a bookmark doesn't affect the revision it points to — the revision keeps its change ID +- Tracking a remote bookmark (`jj bookmark track NAME --remote origin`) creates a local bookmark that follows the remote's updates +- Git branches are represented as bookmarks with `@remote` suffixes (e.g., `main@origin`) +- `jj bookmark list` shows all bookmarks; the output format is `BOOKMARK: CHANGE_ID commit_hash` + +## The immutable set + +By default, jj prevents rewriting commits that are ancestors of any remote-tracking bookmark. This is configured by `revsets.immutable_heads` in the config (typically `immutable_heads() & ~@` plus `bookmarks()@remote`). Use `--ignore-immutable` to bypass this check (e.g., `jj rebase --ignore-immutable -r OLD_REV`). + +## Global flags + +These work with any jj command: + +- `--at-op OP` — run as if repo were at a past operation (read-only) +- `--ignore-immutable` — allow rewriting protected commits +- `--ignore-working-copy` — skip snapshotting the working copy (faster, but may show stale state) +- `-R PATH` — operate on a different repository +- `--config NAME=VAL` — set config options inline (TOML syntax) diff --git a/.agents/skills/jj-vcs/references/daily-work.md b/.agents/skills/jj-vcs/references/daily-work.md new file mode 100644 index 0000000..fa6bb10 --- /dev/null +++ b/.agents/skills/jj-vcs/references/daily-work.md @@ -0,0 +1,117 @@ +# Daily work + +Commands and patterns for the core edit/describe/log cycle. + +## jj status + +Shows the diff between the working copy (`@`) and its parent. This is the first thing to run when a user asks "what's going on?" or "what have I changed?". + +Key alias: `jj st` (the most common form used in practice). + +Output shows: +- Which revision you're on (change ID, commit hash, bookmark) +- Whether `@` is empty or has changes +- The diff (added/modified/deleted files) +- Any conflicts + +## jj new + +Creates a new empty revision as a child of the given revision (default: `@`) and makes it the working copy. This is the closest jj equivalent to starting a new branch of work. + +``` +jj new # new child of @, empty, becomes new @ +jj new REV # new child of REV +jj new A B # new merge revision with parents A and B +``` + +- `--insert-after REV` — insert the new revision after REV (between REV and its children) +- `--insert-before REV` — insert before REV (between REV and its parents) +- `-m "msg"` — set description immediately +- `--no-edit` — create the revision but don't switch working copy to it + +## jj describe + +Sets or edits the description (commit message) of a revision. + +``` +jj describe # opens editor to edit @'s description +jj describe -m "msg" # set description of @ inline +jj describe -r REV # describe a specific revision +``` + +- `-m "msg"` — set description from command line (no editor) +- `--stdin` — read description from stdin +- `-r REV` — describe a different revision (default: `@`) + +**Important:** A revision needs a description before it can be pushed. Always use `jj describe` (not `jj commit`) when the user says "write a commit message." + +## jj commit + +Combines `jj describe -m "msg"` followed by `jj new`. Records the current change's description and immediately starts a fresh empty revision on top. + +``` +jj commit -m "feat: add user auth" +``` + +This is the jj equivalent of git's `commit` but note: there's no staging step. Any changes to tracked files are included. + +## jj log + +Shows the revision graph. This is your primary tool for understanding history. + +``` +jj log # default view (configurable via revsets.log) +jj log -r "main..@" # changes you've made since main +jj log -r "author(me)" # your changes +jj log -r "all()" # everything +jj log -r REV # log starting from REV +``` + +Key flags: +- `-r REVSET` — which revisions to show (revset) +- `-n N` / `--limit N` — limit to N results +- `--no-graph` — flat list (good for scripting) +- `--reversed` — oldest first +- `-p` / `--patch` — show the diff for each revision +- `-T TEMPLATE` — custom template +- `--count` — just print the count + +## jj diff + +Shows the diff of a revision. Unlike `jj log -p`, this focuses purely on the content diff. + +``` +jj diff # diff of @ vs its parent +jj diff -r REV # diff of REV vs its parent +jj diff --from A --to B # diff between two specific revisions +``` + +Key flags: +- `--git` — git-format diff (good for piping or review) +- `-s` / `--summary` — just show which files changed +- `--stat` — histogram of changes +- `--name-only` — just file paths +- `--color-words` — word-level diff +- `--context N` — lines of context + +## jj edit + +Sets the working copy to an existing revision. Edits go directly into that revision's diff — this rewrites history. + +``` +jj edit REV # switch working copy to REV +``` + +Prefer `jj new REV` over `jj edit REV` in most cases: `jj new` creates a child so you can't accidentally rewrite the parent. Use `jj edit` when you intentionally want to amend an existing change (e.g., you forgot to include a file). + +## jj file + +File-level operations. + +``` +jj file list [-r REV] # list tracked files in REV +jj file show -r REV PATH # show file contents from REV +jj file chmod MODE PATH # change file mode (e.g., +x, -x) +jj file untrack PATH # stop tracking a file (adds to .gitignore automatically) +jj file track PATH # start tracking a file (reverses untrack) +``` diff --git a/.agents/skills/jj-vcs/references/history-rewriting.md b/.agents/skills/jj-vcs/references/history-rewriting.md new file mode 100644 index 0000000..681a420 --- /dev/null +++ b/.agents/skills/jj-vcs/references/history-rewriting.md @@ -0,0 +1,130 @@ +# History rewriting + +Commands for restructuring the commit graph. jj's operation log makes history rewriting safe — nothing is permanently lost. + +## jj rebase + +Move revisions to different parent(s). The most fundamental history-rewriting command. + +``` +jj rebase -r REV -o DEST # rebase single revision REV onto DEST +jj rebase -b REV -o DEST # rebase REV and all its descendants onto DEST +jj rebase -r REV --insert-after ANCHOR # reorder: put REV after ANCHOR +jj rebase -r REV --insert-before ANCHOR # reorder: put REV before ANCHOR +``` + +Moving `-r` vs `-b`: +- `-r REV` — rebase only REV; its descendants follow because jj automatically rebases them on top +- `-b REV` — rebase the entire branch (REV and all its descendants) to a new location. Equivalent to `-s roots(dest..REV)` + +Note: jj automatically rebases descendants so you don't need to manually restack after a rebase. However, this can create duplicate commits if the destination already has commits with the same change IDs. `--keep-divergent` controls this behavior. + +## jj squash + +Move changes from one revision into another. The most common pattern is moving `@`'s changes into its parent (the jj equivalent of amending). + +``` +jj squash # squash @ into its parent +jj squash -f SOURCE -t DEST # move SOURCE's changes into DEST +``` + +- Without flags: squash `@` into `@-` (the parent). After this, `@` becomes empty and `@-` now includes the changes. +- `-f` / `--from`: which revision to take changes from (default: `@`) +- `-t` / `--into`: which revision to put changes into (default: `@`) +- `-i` / `--interactive`: choose which parts of the diff to squash +- `-k` / `--keep-emptied`: don't abandon the source revision after squashing +- `-m "msg"`: set description on the result + +The `-o` (experimental), `--insert-after`, and `--insert-before` flags control where the resulting revision goes in the graph, similar to `jj rebase`. + +## jj split + +Split one revision into two. Changes in the original revision are partitioned into two new revisions. + +``` +jj split -r REV # interactively choose which files go into the first split +jj split FILE... # put specified files into the new first revision +``` + +- `-r REV`: the revision to split (default: `@`) +- `-i`: force interactive mode (choose which hunks go where) +- `-m "msg"`: description for the new (first) revision +- `--parallel`: split into two parallel revisions (same parent) instead of parent-child +- `--insert-after` / `--insert-before` / `-o`: control where the new revision goes + +## jj abandon + +Drop a revision. The revision is removed from the graph and its descendants are rebased onto its parent(s). + +``` +jj abandon -r REV # abandon a specific revision +jj abandon # abandon @ (only works if @ is empty) +``` + +Common use: clean up empty revisions after squash/restructuring. `jj abandon -r empty()` is a batch cleanup pattern. + +## jj absorb + +Automatically moves changes from child revisions into the parent revisions they logically belong to. It detects which changes should have been made in which parent by analyzing the diff. + +``` +jj absorb +``` + +Runs on `@` by default. Useful when you make a fix that should belong to a lower commit in your stack — instead of manually squashing, `jj absorb` figures out where each hunk belongs. + +## jj parallelize + +Make sibling revisions into a linear chain or vice versa. + +``` +jj parallelize -r REVS... +``` + +Takes a set of revisions and makes them siblings (all children of the same parent), rebasing their descendants as needed. + +## jj arrange + +Interactive graph rearrangement. Opens a diff editor where you can drag and drop revisions to reorder them. More visual than command-line rebase operations. + +``` +jj arrange +``` + +## jj diffedit + +Touch up the content changes in a revision. Opens an editor showing the revision's diff and lets you modify it directly. + +``` +jj diffedit -r REV +``` + +Use this when you need to change what a specific revision does, rather than adding a fix on top. + +## jj metaedit + +Modify a revision's metadata (author, author date, committer, description) without changing its content. + +``` +jj metaedit -r REV +``` + +## jj restack + +This is not a real command — jj restacks automatically. You should never need to manually restack after rebase, squash, etc. If a rebase leaves empty commits, `jj abandon` them. + +## jj squash/absorb vs jj squash + +- Use `jj squash` when you want to explicitly move changes between revisions +- Use `jj absorb` when you want jj to figure out where changes belong automatically + +## jj squash vs git commit --amend + +- `jj squash` without arguments is jj's equivalent of `git commit --amend`: it takes `@`'s changes and merges them into `@-`, leaving `@` empty +- Unlike git, the old `@`'s change ID still exists (as an empty revision) — you can `jj abandon` it afterwards + +## jj split + jj rebase + +A common pattern: split a large revision into two, then rebase one of them to a different parent: +1. `jj split -r BIG_COMMIT` — split into two +2. `jj rebase -r NEW_REV -o DIFFERENT_PARENT` — move the new revision elsewhere diff --git a/.agents/skills/jj-vcs/references/recovery.md b/.agents/skills/jj-vcs/references/recovery.md new file mode 100644 index 0000000..072cbbc --- /dev/null +++ b/.agents/skills/jj-vcs/references/recovery.md @@ -0,0 +1,119 @@ +# Recovery + +Commands for undoing mistakes, resolving conflicts, and restoring lost work. + +## jj undo + +Undoes the most recent operation. This is the first recovery command to reach for. + +``` +jj undo # undo last operation +jj undo --undo # undo the undo (same as jj redo) +``` + +Any operation can be undone — commit, rebase, push, etc. The undo itself creates a new operation, so it can also be undone. + +## jj redo + +Redo the most recently undone operation. + +``` +jj redo # redo last undo +``` + +## jj op log / jj operation + +View the operation log — the history of all jj commands run in this repo. This is jj's equivalent of shell history but tied to repo state. + +``` +jj op log # show all operations +jj op log -n 20 # show last 20 operations +``` + +Each operation has an ID (hash). The most recent operation is shown at the top with `@`. The snapshot of the working copy is also an operation. + +## jj op restore + +Restore the repo to a previous state by operation. Unlike `jj undo` (which only undoes the last operation), this can jump to any point in the operation log. + +``` +jj op restore OP_ID # restore repo to state after OP_ID +jj op restore --what undo # restore just the undo history (not working copy) +``` + +This is *not* a revert — it moves the entire repo state backward (or forward). Changes made after that operation will appear as divergent changes. Use `jj --at-op` for read-only inspection first. + +## jj restore (content restore) + +Restore file contents within a revision. This is NOT the same as `jj op restore`. + +``` +jj restore # restore all files in @ from its parent +jj restore PATH # restore specific files in @ from its parent +jj restore --from SOURCE # restore from a specific source revision +jj restore --changes-in REV # undo the changes introduced by REV (creates reverse diff on @) +``` + +- Without `--from`: restores from the parent of the target revision +- Without `--into`: restores into `@` +- `--changes-in REV` is the closest equivalent to `git revert REV` — it applies the reverse of REV's diff to `@` +- `--restore-descendants`: when rebasing descendants, preserve their content (not their diff) + +To "unstage" files (there's no real staging area in jj, but for git users who ask): use `jj restore PATH` to undo changes to specific files in `@`. + +## jj resolve + +Resolve merge conflicts. jj tracks conflicts natively (unlike git, which leaves conflict markers in files and lets you handle them). + +``` +jj resolve PATH... # resolve conflicts in specific files +jj resolve --list # list all unresolved conflicts +``` + +When you run `jj resolve`, jj opens the external merge tool (configured in `merge-tools`). If no tool is configured, it falls back to leaving conflict markers in the file, which you can edit manually. + +After resolving conflicts manually (by editing the file), mark them as resolved with `jj resolve PATH`. + +## jj --at-op (read-only inspection) + +Run any jj command as if the repo were at a past operation. Read-only — useful for inspecting old state before deciding whether to restore. + +``` +jj --at-op OP_ID log # log from past state +jj --at-op OP_ID status # status from past state +jj --at-op OP_ID diff -r REV # diff from past state +``` + +## Divergent changes + +When the operation log has diverged (e.g., two concurrent operations), `jj status` will warn about divergent operations. This happens when you run jj commands from different terminals or after `jj op restore`. + +To resolve divergence: +1. `jj --at-op OP_ID status` for each divergent operation to understand the state +2. `jj op restore` to pick one side +3. Or use `jj new` to create a merge of the divergent states + +## Common recovery scenarios + +**"I rebased and lost changes"** +- `jj undo` — undoes the rebase +- If `jj undo` isn't enough: `jj op log` to find the pre-rebase operation, then `jj op restore OP_ID` + +**"I pushed the wrong thing"** +- You can't unpush (remote doesn't support it), but you can: + 1. Fix the local revision + 2. `jj bookmark move --to=FIXED BOOKMARK` + 3. `jj git push --force` or `jj git push` with a new commit + +**"I accidentally squashed the wrong files"** +- `jj undo` immediately +- If too late: use the operation log to find the pre-squash state + +**"I want to get old version of a file back"** +- `jj restore --from OLD_REV PATH` — restore PATH from OLD_REV into `@` +- Or: `jj file show -r OLD_REV PATH > PATH` to extract it as a file + +**"jj status shows conflicts"** +- `jj resolve --list` to see which files have conflicts +- Resolve them individually: `jj resolve PATH` +- After resolving all, `jj status` will clear diff --git a/.claude/skills/jj-vcs b/.claude/skills/jj-vcs new file mode 120000 index 0000000..7deb27b --- /dev/null +++ b/.claude/skills/jj-vcs @@ -0,0 +1 @@ +../../.agents/skills/jj-vcs \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4352faa --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +repos/ diff --git a/.mcp.json b/.mcp.json new file mode 100644 index 0000000..944f675 --- /dev/null +++ b/.mcp.json @@ -0,0 +1,8 @@ +{ + "mcpServers": { + "exa": { + "type": "http", + "url": "https://mcp.exa.ai/mcp?tools=web_search_exa,web_search_advanced_exa" + } + } +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..f5be61c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "js/ts.experimental.useTsgo": true, + "js/ts.tsdk.path": "./node_modules/typescript/bin", + "js/ts.tsdk.promptToUseWorkspaceVersion": true, + "js/ts.tsdk.additionalLocations": ["./node_modules/typescript/bin"] +} diff --git a/biome.jsonc b/biome.jsonc new file mode 100644 index 0000000..97321c3 --- /dev/null +++ b/biome.jsonc @@ -0,0 +1,34 @@ +{ + "$schema": "https://biomejs.dev/schemas/2.5.14/schema.json", + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + }, + "files": { + "ignoreUnknown": false + }, + "formatter": { + "enabled": true, + "indentStyle": "space" + }, + "linter": { + "enabled": true, + "rules": { + "preset": "recommended" + } + }, + "javascript": { + "formatter": { + "quoteStyle": "double" + } + }, + "assist": { + "enabled": true, + "actions": { + "source": { + "organizeImports": "on" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..1769385 --- /dev/null +++ b/package.json @@ -0,0 +1,31 @@ +{ + "name": "lsp-mcp", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "prepare": "effect-tsgo patch --typescript --no-oxlint" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devEngines": { + "packageManager": { + "name": "pnpm", + "version": "12.4.2", + "onFail": "download" + } + }, + "packageManager": "pnpm@12.4.2", + "type": "module", + "dependencies": { + "@effect/platform-node": "4.0.0-rc.115", + "effect": "4.0.0-rc.115" + }, + "devDependencies": { + "@biomejs/biome": "2.5.14", + "@effect/tsgo": "0.45.0", + "typescript": "^7.0.2" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..425c03d --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,711 @@ +--- +lockfileVersion: '9.0' + +importers: + + .: + configDependencies: {} + packageManagerDependencies: + pnpm: + specifier: 12.4.2 + version: 12.4.2 + +packages: + + '@pnpm/exe.android-arm64@12.4.2': + resolution: {integrity: sha512-E255MbcQ0V1577M2BV0ajWuP7KmTPYA0jqZnk3rK6Lq3kTvZWulMMb7iqRmnLsQbyWTkMEB2CfyM70loVDA8xg==} + cpu: [arm64] + os: [android] + + '@pnpm/exe.android-x64@12.4.2': + resolution: {integrity: sha512-J1pSeCUwuKxMG70ZzpWn8JzElxiEa8NN/3N0SlZRtU2xbztChaJCKF3HaBNIj9yPfeofWzJo/lwNvDDjraQuZw==} + cpu: [x64] + os: [android] + + '@pnpm/exe.darwin-arm64@12.4.2': + resolution: {integrity: sha512-A0WDo8iErfZBXgrLseQxw8i8Y9ctUpOEl/Uu+cubnTzpD8tT9ykIB548L8YTM2WD4OS+ZOHSxy8aGZcvKq8PaQ==} + cpu: [arm64] + os: [darwin] + + '@pnpm/exe.darwin-x64@12.4.2': + resolution: {integrity: sha512-MSgJdovBWHcb5DEOvfPH9yNi/T5O1Xa4ess+E1ESGo/5yuty7S4JoiIjami+fsNXfnoQMlwsMUqYU4zAvBcNCw==} + cpu: [x64] + os: [darwin] + + '@pnpm/exe.freebsd-x64@12.4.2': + resolution: {integrity: sha512-h2YumlQSNvgbRPv+RXwABohX65f9bOBZn+jMIt7bFDISZPCzQ+Nvpt6Awbp4ip5PwQgYxbu5iREJ1fHE39Fm8A==} + cpu: [x64] + os: [freebsd] + + '@pnpm/exe.linux-arm64-musl@12.4.2': + resolution: {integrity: sha512-LwSEtSEDTv6S51YLs3YvSkPyun/QmfMic1UGICUkPWFu6ByP43RdMlkKvmVkfGhAYCpnxO057vrmyJqtfZrPCA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@pnpm/exe.linux-arm64@12.4.2': + resolution: {integrity: sha512-2dSiDXyhx+RTHsewxex8f/jVjqQXWJ2oow4kCVHEWdZKeBpgMxvZ6fHkTAUBJXgqhbKIDHvuNlZBP7gJfUWL5A==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@pnpm/exe.linux-ppc64@12.4.2': + resolution: {integrity: sha512-8Itc+jQk+MTz04LS9D1RcH+VctAWmzM4l1cJQ+Sx7pAJNo7EKHdRMbC0Tok1jyQ7eEHNJZD5EleYneZqWfZM+g==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@pnpm/exe.linux-riscv64@12.4.2': + resolution: {integrity: sha512-hleOeqhTVpH+z9RVMGnxvU4ZnrkBUClWjCbHD9u6kwyqhGSpevoU1wTGish+CBRhmIgMAy9pAfFpqhbAKOKNfw==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@pnpm/exe.linux-s390x@12.4.2': + resolution: {integrity: sha512-LAsQRRdP9aToENR6dtcIJ9l+e1zMYOX0tQcLGpRyLPVBQcYRLlvAPcmDshsiIHQjp05SDa9FI0czX1ZQ1a7a/A==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@pnpm/exe.linux-x64-musl@12.4.2': + resolution: {integrity: sha512-kzfzH2/0BWdTABK14Yj5a1xsdkTEQUp2eXEPNakaD9jKL025lq3hyaKHIz/gIZaPDMe/1bFFK/En4ztFlbBJxw==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@pnpm/exe.linux-x64@12.4.2': + resolution: {integrity: sha512-/pbt0UVTa8NMDhzOWLQRfZ6G9ROKXlJPZtx845BqyWfc7hCrWXhTLBd70yO2y8+E+IWN3oHM1s/JsIQNGk1yvg==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@pnpm/exe.win32-arm64@12.4.2': + resolution: {integrity: sha512-PsW19e4dAUNpZ0cS9flaxFuAmpt2dKlH/Vvi8TZ4qyJjjQzue/CEsWm+6wKVP4CJ7IT8RdL4qh+soOPWIgF2Zw==} + cpu: [arm64] + os: [win32] + + '@pnpm/exe.win32-x64@12.4.2': + resolution: {integrity: sha512-+xGoeE0g55ztWvl8i5QqdmNfW3nIrTVcoQrNshEOwxthm9Ag48oXton3uxOA3/SANyz5AXexEjj2KO20NnOrEw==} + cpu: [x64] + os: [win32] + + pnpm@12.4.2: + resolution: {integrity: sha512-CK3GYTGAJ1x8ntraOdzwjJxhrU5+rzMKTzRh8QKw+QdCNFTRF/mOctR/7wYWBwZE17/8lzpqV/UJCm18NosHyQ==} + engines: {node: '>=18.*'} + hasBin: true + +snapshots: + + '@pnpm/exe.android-arm64@12.4.2': + optional: true + + '@pnpm/exe.android-x64@12.4.2': + optional: true + + '@pnpm/exe.darwin-arm64@12.4.2': + optional: true + + '@pnpm/exe.darwin-x64@12.4.2': + optional: true + + '@pnpm/exe.freebsd-x64@12.4.2': + optional: true + + '@pnpm/exe.linux-arm64-musl@12.4.2': + optional: true + + '@pnpm/exe.linux-arm64@12.4.2': + optional: true + + '@pnpm/exe.linux-ppc64@12.4.2': + optional: true + + '@pnpm/exe.linux-riscv64@12.4.2': + optional: true + + '@pnpm/exe.linux-s390x@12.4.2': + optional: true + + '@pnpm/exe.linux-x64-musl@12.4.2': + optional: true + + '@pnpm/exe.linux-x64@12.4.2': + optional: true + + '@pnpm/exe.win32-arm64@12.4.2': + optional: true + + '@pnpm/exe.win32-x64@12.4.2': + optional: true + + pnpm@12.4.2: + optionalDependencies: + '@pnpm/exe.android-arm64': 12.4.2 + '@pnpm/exe.android-x64': 12.4.2 + '@pnpm/exe.darwin-arm64': 12.4.2 + '@pnpm/exe.darwin-x64': 12.4.2 + '@pnpm/exe.freebsd-x64': 12.4.2 + '@pnpm/exe.linux-arm64': 12.4.2 + '@pnpm/exe.linux-arm64-musl': 12.4.2 + '@pnpm/exe.linux-ppc64': 12.4.2 + '@pnpm/exe.linux-riscv64': 12.4.2 + '@pnpm/exe.linux-s390x': 12.4.2 + '@pnpm/exe.linux-x64': 12.4.2 + '@pnpm/exe.linux-x64-musl': 12.4.2 + '@pnpm/exe.win32-arm64': 12.4.2 + '@pnpm/exe.win32-x64': 12.4.2 + +--- +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@effect/platform-node': + specifier: 4.0.0-rc.115 + version: 4.0.0-rc.115(effect@4.0.0-rc.115)(redis@6.2.1) + effect: + specifier: 4.0.0-rc.115 + version: 4.0.0-rc.115 + devDependencies: + '@biomejs/biome': + specifier: 2.5.14 + version: 2.5.14 + '@effect/tsgo': + specifier: 0.45.0 + version: 0.45.0 + typescript: + specifier: ^7.0.2 + version: 7.0.2 + +packages: + + '@biomejs/biome@2.5.14': + resolution: {integrity: sha512-0FabLIjd4M/dm8VFI86RMaLLdgepzbdfiAL2R8cr7V81OYYrP1w7Z73KfAwPK5h9SrEBXTzNG2y+mBwPo9xRnw==} + engines: {node: '>=14.21.3'} + hasBin: true + + '@biomejs/cli-darwin-arm64@2.5.14': + resolution: {integrity: sha512-UnzaXO65L4tsZimFITFP2M121GyhDcWFrT3pL5ZJ5U4XcS/0L5VHYytVohdCf/gnDUFHgl2I9xnt5bV/J1kxHQ==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + + '@biomejs/cli-darwin-x64@2.5.14': + resolution: {integrity: sha512-kiy8qA16K93J7uvFfWi4LgjqDpnRKyePAna6A0Y4jxyUga35SYpIZ2cNWlhy0lsfgqRenCpfymnJWEZ6mgpRgA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + + '@biomejs/cli-linux-arm64-musl@2.5.14': + resolution: {integrity: sha512-SJ9PrZkBnnH9dHJDnxk34vKs0GB2dbsioaft6/hPhWJ7AHpwYH83Isnhj0FSRpFkGgpVfJ1lds23ApB2czUDLQ==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@biomejs/cli-linux-arm64@2.5.14': + resolution: {integrity: sha512-vO/9BaU1n30CiFNLx49gMTMtbCAAqlo/EqFoG0BU3deQInTbJrmXSmTQ9e3FoDZIKQnvSLDVNL4lx1ci7y1T1Q==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@biomejs/cli-linux-x64-musl@2.5.14': + resolution: {integrity: sha512-2kI5PrMgW5dcEZYrstLPmUmCwkUwZY39rP4BN93Vxbwcs2O57LDQOktUZZYPvvspN5i0mhGr3TJtF5sU26NUWg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@biomejs/cli-linux-x64@2.5.14': + resolution: {integrity: sha512-VHZRa7CCQBUWKxNwUvHJeuW03WFRgN5NWO//SDGOitc9QIeNyfA42V9zlKm+x82xFSG9Bzi5fi+hbhm9anO8yA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@biomejs/cli-win32-arm64@2.5.14': + resolution: {integrity: sha512-pHgAFffmZtaYoxavEsWEYNvcA7NwOIjLyqw2HXyLbt16xYryX0L4fMV2u0G9ag6LNYPIoqWaWqzUcnc6rLGGXg==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + + '@biomejs/cli-win32-x64@2.5.14': + resolution: {integrity: sha512-oJWmBhoHsnhUKIke+0gXDX0mltJrWHA1UyHsrTlXwX0TL64ilVZAo+TYZm97baecV0esBdpzy3k96q+09JaZUQ==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + + '@effect/platform-node-shared@4.0.0-rc.115': + resolution: {integrity: sha512-rcBwhDIfb82akJoTv7Vwh8K5x9vC/XfuePS7JjOr+z+dORXzsmKqI1BUQF27ARCN9fTAbDh7I6YvBlWhLjnqNg==} + engines: {node: '>=18.0.0'} + peerDependencies: + effect: ^4.0.0-rc.115 + + '@effect/platform-node@4.0.0-rc.115': + resolution: {integrity: sha512-mW03Wjq2FiTL5oi9yOkaKpCyUNBaduKgTk7qMHNELvC21Jq2qOAfdsfH+p+s2zmpB9w2RSa+ApODv4WjO9wQfw==} + engines: {node: '>=18.0.0'} + peerDependencies: + effect: ^4.0.0-rc.115 + redis: '>=5.0.0 <7.0.0' + + '@effect/tsgo-darwin-arm64@0.45.0': + resolution: {integrity: sha512-WUoiEVcm8E19QK6fl63lsssM4dkT9IFnULbmqQ6LBfv7H9uRkpE9S3thj8ZtZ+vl/QY8atwfuaTf+3A1m/kGtQ==} + cpu: [arm64] + os: [darwin] + + '@effect/tsgo-darwin-x64@0.45.0': + resolution: {integrity: sha512-s3yz7ZfIzvObXJ/r5xd9sEPxHKC3L+D+yedS1BV2Kpn47Je2svYCNYKxzXIpqFLkNjK+RcOQrcfYbYEpKZZa6g==} + cpu: [x64] + os: [darwin] + + '@effect/tsgo-linux-arm64@0.45.0': + resolution: {integrity: sha512-N+lyzixtylOOn49demDaqg0kb/U8ISxM10Gphs1pIMSGlqlfqC4inYEoFpYej+f4T/cRlkA11Ue7wJzNz83ePA==} + cpu: [arm64] + os: [linux] + + '@effect/tsgo-linux-arm@0.45.0': + resolution: {integrity: sha512-f6zL6YbWA9lXdfJ//KOjUz/U3CdGtajKi5NsR/lcQaKfZiJwHfeeLBB3yetF3qbPGSA149/kuMoDMWL13RUH3A==} + cpu: [arm] + os: [linux] + + '@effect/tsgo-linux-x64@0.45.0': + resolution: {integrity: sha512-aWt0G8celAxJOis4+xiILkyMP/3J+vukimUhSoCmUAPt8zoT9qhZcN64XYZE7jfqp88ByRdgN9GK1/C7YfPtcQ==} + cpu: [x64] + os: [linux] + + '@effect/tsgo-win32-arm64@0.45.0': + resolution: {integrity: sha512-EAdeV366ja+M4XCx6xjXMv4Xkc0Fgzy4bapa0saDWcGhllNLqJDfOk4lk0BgAEjBUI8+0xC+PXKVB5SMz4EpVA==} + cpu: [arm64] + os: [win32] + + '@effect/tsgo-win32-x64@0.45.0': + resolution: {integrity: sha512-1Hsr/sT5dmIafoY9L0ASJo4VqGyPNzM1nwTb4Wj1Lmjq6kGuwO/PVozFg3WZZ0piChFmgiU3nx1AKZfyqgjGUw==} + cpu: [x64] + os: [win32] + + '@effect/tsgo@0.45.0': + resolution: {integrity: sha512-gPG0ixVHgtYBUe5DbKX9vzHlhqd9+ZEfs4m/XWy0808av0A2XqMzaG3F5rnPBN7EUJRPlo9TluIi8WHx/pBV+A==} + hasBin: true + + '@redis/bloom@6.2.1': + resolution: {integrity: sha512-huQgNLaCIZfQ9SeLn4q9124uOUd8HbZDYHwwUzNcRgHqCHiHKl2dDxMqJCeWh8cMqZAoWuHR8XnWbDMIf+o7ag==} + engines: {node: '>= 20.0.0'} + peerDependencies: + '@redis/client': ^6.2.1 + + '@redis/client@6.2.1': + resolution: {integrity: sha512-LzxBY7SIBvvJiyCgcaJZZakE3fJrZZ++i24+EDW9fKpCl68D35uJcKFpZZwCfOoG9WZTbyZlMzMeM0gtOAMU9Q==} + engines: {node: '>= 20.0.0'} + peerDependencies: + '@node-rs/xxhash': ^1.1.0 + '@opentelemetry/api': '>=1 <2' + peerDependenciesMeta: + '@node-rs/xxhash': + optional: true + '@opentelemetry/api': + optional: true + + '@redis/json@6.2.1': + resolution: {integrity: sha512-AFIUJ8Gj0DaaSBHYuSt8+O0oYWM+50OK1c0OmodB7XERIA8+BbyV3O4v76f9iccWasd1/7qjfZTpuzexUaZtrQ==} + engines: {node: '>= 20.0.0'} + peerDependencies: + '@redis/client': ^6.2.1 + + '@redis/search@6.2.1': + resolution: {integrity: sha512-2vfOAOyYFE7UUw3sBBlkqqruBtOUS4HRY5MtW4hp83llrwvtrTE4r22CEqXddlV+54zkLxBE4nmsIJ/dpezQrQ==} + engines: {node: '>= 20.0.0'} + peerDependencies: + '@redis/client': ^6.2.1 + + '@redis/time-series@6.2.1': + resolution: {integrity: sha512-kiYniph04dJOole+L359B6C9E+jYS2uDP7hca6Onj0xF38ZIpyxARO0Iq0W4ZRn1e8Q6vqW00QFZVSMRA/2Ijw==} + engines: {node: '>= 20.0.0'} + peerDependencies: + '@redis/client': ^6.2.1 + + '@types/node@26.6.1': + resolution: {integrity: sha512-VqGJBMCtdhqkBUCcBLvywI0NJ+KLuVzgNnlBUNFOQjqVxzo2lxLUNg1DSey8+u2u6ktswSAxg+s68QLzWHNOuA==} + + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + + '@typescript/typescript-aix-ppc64@7.0.2': + resolution: {integrity: sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [aix] + + '@typescript/typescript-darwin-arm64@7.0.2': + resolution: {integrity: sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [darwin] + + '@typescript/typescript-darwin-x64@7.0.2': + resolution: {integrity: sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [darwin] + + '@typescript/typescript-freebsd-arm64@7.0.2': + resolution: {integrity: sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [freebsd] + + '@typescript/typescript-freebsd-x64@7.0.2': + resolution: {integrity: sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [freebsd] + + '@typescript/typescript-linux-arm64@7.0.2': + resolution: {integrity: sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [linux] + + '@typescript/typescript-linux-arm@7.0.2': + resolution: {integrity: sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==} + engines: {node: '>=16.20.0'} + cpu: [arm] + os: [linux] + + '@typescript/typescript-linux-loong64@7.0.2': + resolution: {integrity: sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==} + engines: {node: '>=16.20.0'} + cpu: [loong64] + os: [linux] + + '@typescript/typescript-linux-mips64el@7.0.2': + resolution: {integrity: sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==} + engines: {node: '>=16.20.0'} + cpu: [mips64el] + os: [linux] + + '@typescript/typescript-linux-ppc64@7.0.2': + resolution: {integrity: sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [linux] + + '@typescript/typescript-linux-riscv64@7.0.2': + resolution: {integrity: sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==} + engines: {node: '>=16.20.0'} + cpu: [riscv64] + os: [linux] + + '@typescript/typescript-linux-s390x@7.0.2': + resolution: {integrity: sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==} + engines: {node: '>=16.20.0'} + cpu: [s390x] + os: [linux] + + '@typescript/typescript-linux-x64@7.0.2': + resolution: {integrity: sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [linux] + + '@typescript/typescript-netbsd-arm64@7.0.2': + resolution: {integrity: sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [netbsd] + + '@typescript/typescript-netbsd-x64@7.0.2': + resolution: {integrity: sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [netbsd] + + '@typescript/typescript-openbsd-arm64@7.0.2': + resolution: {integrity: sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [openbsd] + + '@typescript/typescript-openbsd-x64@7.0.2': + resolution: {integrity: sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [openbsd] + + '@typescript/typescript-sunos-x64@7.0.2': + resolution: {integrity: sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [sunos] + + '@typescript/typescript-win32-arm64@7.0.2': + resolution: {integrity: sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [win32] + + '@typescript/typescript-win32-x64@7.0.2': + resolution: {integrity: sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [win32] + + cluster-key-slot@1.1.2: + resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} + engines: {node: '>=0.10.0'} + + effect@4.0.0-rc.115: + resolution: {integrity: sha512-ogYulZ5ffeOzrJqQrG0XOkDO5lKn2s9KNHhoxJy/6wKUkF0i12dlVXWA9TgsgQ+zV/JzizyG0+XMPepZEQX6vw==} + + redis@6.2.1: + resolution: {integrity: sha512-Z9VHtgYs48PiQC77X9O2Er8Hj4T+5BtFjT91/vi5Is1D04N72cA946ZslM1ImJw8ZctFBZWAVjM7S5wJNeHMpg==} + engines: {node: '>= 20.0.0'} + + typescript@7.0.2: + resolution: {integrity: sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==} + engines: {node: '>=16.20.0'} + hasBin: true + + undici-types@8.9.0: + resolution: {integrity: sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==} + + undici@8.10.2: + resolution: {integrity: sha512-/y4/bH9YNU5hi9NIrpOuvGXFcxrj3CMrV+/AYpowAYTpHn8gX/XPFjNy766FPoYY0miQhdW977JFWKGNhBdwyQ==} + engines: {node: '>=22.19.0'} + + ws@8.21.3: + resolution: {integrity: sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + +snapshots: + + '@biomejs/biome@2.5.14': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 2.5.14 + '@biomejs/cli-darwin-x64': 2.5.14 + '@biomejs/cli-linux-arm64': 2.5.14 + '@biomejs/cli-linux-arm64-musl': 2.5.14 + '@biomejs/cli-linux-x64': 2.5.14 + '@biomejs/cli-linux-x64-musl': 2.5.14 + '@biomejs/cli-win32-arm64': 2.5.14 + '@biomejs/cli-win32-x64': 2.5.14 + + '@biomejs/cli-darwin-arm64@2.5.14': + optional: true + + '@biomejs/cli-darwin-x64@2.5.14': + optional: true + + '@biomejs/cli-linux-arm64-musl@2.5.14': + optional: true + + '@biomejs/cli-linux-arm64@2.5.14': + optional: true + + '@biomejs/cli-linux-x64-musl@2.5.14': + optional: true + + '@biomejs/cli-linux-x64@2.5.14': + optional: true + + '@biomejs/cli-win32-arm64@2.5.14': + optional: true + + '@biomejs/cli-win32-x64@2.5.14': + optional: true + + '@effect/platform-node-shared@4.0.0-rc.115(effect@4.0.0-rc.115)': + dependencies: + '@types/ws': 8.18.1 + effect: 4.0.0-rc.115 + ws: 8.21.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@effect/platform-node@4.0.0-rc.115(effect@4.0.0-rc.115)(redis@6.2.1)': + dependencies: + '@effect/platform-node-shared': 4.0.0-rc.115(effect@4.0.0-rc.115) + effect: 4.0.0-rc.115 + redis: 6.2.1 + undici: 8.10.2 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@effect/tsgo-darwin-arm64@0.45.0': + optional: true + + '@effect/tsgo-darwin-x64@0.45.0': + optional: true + + '@effect/tsgo-linux-arm64@0.45.0': + optional: true + + '@effect/tsgo-linux-arm@0.45.0': + optional: true + + '@effect/tsgo-linux-x64@0.45.0': + optional: true + + '@effect/tsgo-win32-arm64@0.45.0': + optional: true + + '@effect/tsgo-win32-x64@0.45.0': + optional: true + + '@effect/tsgo@0.45.0': + optionalDependencies: + '@effect/tsgo-darwin-arm64': 0.45.0 + '@effect/tsgo-darwin-x64': 0.45.0 + '@effect/tsgo-linux-arm': 0.45.0 + '@effect/tsgo-linux-arm64': 0.45.0 + '@effect/tsgo-linux-x64': 0.45.0 + '@effect/tsgo-win32-arm64': 0.45.0 + '@effect/tsgo-win32-x64': 0.45.0 + + '@redis/bloom@6.2.1(@redis/client@6.2.1)': + dependencies: + '@redis/client': 6.2.1 + + '@redis/client@6.2.1': + dependencies: + cluster-key-slot: 1.1.2 + + '@redis/json@6.2.1(@redis/client@6.2.1)': + dependencies: + '@redis/client': 6.2.1 + + '@redis/search@6.2.1(@redis/client@6.2.1)': + dependencies: + '@redis/client': 6.2.1 + + '@redis/time-series@6.2.1(@redis/client@6.2.1)': + dependencies: + '@redis/client': 6.2.1 + + '@types/node@26.6.1': + dependencies: + undici-types: 8.9.0 + + '@types/ws@8.18.1': + dependencies: + '@types/node': 26.6.1 + + '@typescript/typescript-aix-ppc64@7.0.2': + optional: true + + '@typescript/typescript-darwin-arm64@7.0.2': + optional: true + + '@typescript/typescript-darwin-x64@7.0.2': + optional: true + + '@typescript/typescript-freebsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-freebsd-x64@7.0.2': + optional: true + + '@typescript/typescript-linux-arm64@7.0.2': + optional: true + + '@typescript/typescript-linux-arm@7.0.2': + optional: true + + '@typescript/typescript-linux-loong64@7.0.2': + optional: true + + '@typescript/typescript-linux-mips64el@7.0.2': + optional: true + + '@typescript/typescript-linux-ppc64@7.0.2': + optional: true + + '@typescript/typescript-linux-riscv64@7.0.2': + optional: true + + '@typescript/typescript-linux-s390x@7.0.2': + optional: true + + '@typescript/typescript-linux-x64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-sunos-x64@7.0.2': + optional: true + + '@typescript/typescript-win32-arm64@7.0.2': + optional: true + + '@typescript/typescript-win32-x64@7.0.2': + optional: true + + cluster-key-slot@1.1.2: {} + + effect@4.0.0-rc.115: {} + + redis@6.2.1: + dependencies: + '@redis/bloom': 6.2.1(@redis/client@6.2.1) + '@redis/client': 6.2.1 + '@redis/json': 6.2.1(@redis/client@6.2.1) + '@redis/search': 6.2.1(@redis/client@6.2.1) + '@redis/time-series': 6.2.1(@redis/client@6.2.1) + transitivePeerDependencies: + - '@node-rs/xxhash' + - '@opentelemetry/api' + + typescript@7.0.2: + optionalDependencies: + '@typescript/typescript-aix-ppc64': 7.0.2 + '@typescript/typescript-darwin-arm64': 7.0.2 + '@typescript/typescript-darwin-x64': 7.0.2 + '@typescript/typescript-freebsd-arm64': 7.0.2 + '@typescript/typescript-freebsd-x64': 7.0.2 + '@typescript/typescript-linux-arm': 7.0.2 + '@typescript/typescript-linux-arm64': 7.0.2 + '@typescript/typescript-linux-loong64': 7.0.2 + '@typescript/typescript-linux-mips64el': 7.0.2 + '@typescript/typescript-linux-ppc64': 7.0.2 + '@typescript/typescript-linux-riscv64': 7.0.2 + '@typescript/typescript-linux-s390x': 7.0.2 + '@typescript/typescript-linux-x64': 7.0.2 + '@typescript/typescript-netbsd-arm64': 7.0.2 + '@typescript/typescript-netbsd-x64': 7.0.2 + '@typescript/typescript-openbsd-arm64': 7.0.2 + '@typescript/typescript-openbsd-x64': 7.0.2 + '@typescript/typescript-sunos-x64': 7.0.2 + '@typescript/typescript-win32-arm64': 7.0.2 + '@typescript/typescript-win32-x64': 7.0.2 + + undici-types@8.9.0: {} + + undici@8.10.2: {} + + ws@8.21.3: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..10188a9 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +allowBuilds: + msgpackr-extract: true diff --git a/scripts/repos/repos.json b/scripts/repos/repos.json new file mode 100644 index 0000000..11ce6fd --- /dev/null +++ b/scripts/repos/repos.json @@ -0,0 +1,12 @@ +[ + { + "url": "https://github.com/Effect-TS/effect", + "name": "effect", + "ref": "effect@4.0.0-rc.115" + }, + { + "url": "https://github.com/microsoft/language-server-protocol", + "name": "lsp", + "ref": "gh-pages" + } +] diff --git a/scripts/repos/update.cjs b/scripts/repos/update.cjs new file mode 100644 index 0000000..4a9fa79 --- /dev/null +++ b/scripts/repos/update.cjs @@ -0,0 +1,123 @@ +const fs = require("node:fs"); +const path = require("node:path"); +const { spawnSync } = require("node:child_process"); + +const REPOS_FILE = path.join(process.cwd(), "scripts", "repos", "repos.json"); +const TARGET_PARENT_DIR = path.join(process.cwd(), "repos"); + +function main() { + if (!fs.existsSync(REPOS_FILE)) { + console.error( + `Error: Cannot find '${REPOS_FILE}'. Please make sure it exists.`, + ); + process.exit(1); + } + + let repos; + try { + const content = fs.readFileSync(REPOS_FILE, "utf8"); + repos = JSON.parse(content); + } catch (err) { + console.error(`Error: Failed to parse '${REPOS_FILE}'.`, err.message); + process.exit(1); + } + + if (!Array.isArray(repos)) { + console.error(`Error: 'repos.json' must contain an array of repositories.`); + process.exit(1); + } + + if (!fs.existsSync(TARGET_PARENT_DIR)) { + fs.mkdirSync(TARGET_PARENT_DIR, { recursive: true }); + } + + for (const repo of repos) { + if (!repo.url || !repo.name) { + console.warn(`Skipping invalid repo entry:`, repo); + continue; + } + + const repoDir = path.join(TARGET_PARENT_DIR, repo.name); + + const tempDir = path.join(TARGET_PARENT_DIR, `.tmp-${repo.name}`); + + fs.rmSync(tempDir, { recursive: true, force: true }); + + console.log(`\n==================================================`); + console.log(`Processing [${repo.name}]...`); + + const isSha = repo.ref && /^[0-9a-f]{40}$/i.test(repo.ref); + let success = false; + + if (isSha) { + console.log(`Targeting Commit SHA: ${repo.ref}`); + fs.mkdirSync(tempDir, { recursive: true }); + + const init = spawnSync("git", ["init"], { + cwd: tempDir, + stdio: "inherit", + }); + const remote = spawnSync("git", ["remote", "add", "origin", repo.url], { + cwd: tempDir, + stdio: "inherit", + }); + const fetch = spawnSync( + "git", + ["fetch", "--depth", "1", "origin", repo.ref], + { cwd: tempDir, stdio: "inherit" }, + ); + const checkout = spawnSync("git", ["checkout", "FETCH_HEAD"], { + cwd: tempDir, + stdio: "inherit", + }); + + if ( + init.status === 0 && + remote.status === 0 && + fetch.status === 0 && + checkout.status === 0 + ) { + success = true; + } + } else { + console.log(`Targeting Branch/Tag: ${repo.ref || "default branch"}`); + const args = ["clone", "--depth", "1"]; + if (repo.ref) { + args.push("-b", repo.ref); + } + args.push(repo.url, tempDir); + + const clone = spawnSync("git", args, { stdio: "inherit" }); + if (clone.status === 0) { + success = true; + } + } + + if (success) { + try { + const gitFolder = path.join(tempDir, ".git"); + fs.rmSync(gitFolder, { recursive: true, force: true }); + console.log(`Removed '.git' metadata to keep files plain.`); + + fs.rmSync(repoDir, { recursive: true, force: true }); + fs.renameSync(tempDir, repoDir); + console.log(`[Success] Updated ${repo.name} at: ${repoDir}`); + } catch (err) { + console.error( + `[Error] Failed to swap directories for ${repo.name}. File might be locked by another process (e.g. IDE or AI Agent).`, + err.message, + ); + fs.rmSync(tempDir, { recursive: true, force: true }); + } + } else { + console.error( + `[Error] Failed to download ${repo.name}. Cleaning up temp files...`, + ); + fs.rmSync(tempDir, { recursive: true, force: true }); + } + } + + console.log("All repositories processed."); +} + +main(); diff --git a/skills-lock.json b/skills-lock.json new file mode 100644 index 0000000..fd4d7ee --- /dev/null +++ b/skills-lock.json @@ -0,0 +1,17 @@ +{ + "version": 1, + "skills": { + "improve": { + "source": "shadcn/improve", + "sourceType": "github", + "skillPath": "skills/improve/SKILL.md", + "computedHash": "39a9358732dcff385e9e4d3e60b4547856f834e54a58b35e455aa9bd49928c13" + }, + "jj-vcs": { + "source": "OpticLM/jj-skill", + "sourceType": "github", + "skillPath": "skills/jj-vcs/SKILL.md", + "computedHash": "a263e9fdd927e53870ee1916a7b7b6f6c9a5408d78ce7ebf94477593c5ee3b69" + } + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..b466d7f --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,51 @@ +{ + "$schema": "./node_modules/@effect/tsgo/schema.json", + "compilerOptions": { + "noEmit": true, + // File Layout + // "rootDir": "./src", + // "outDir": "./dist", + + // Environment Settings + // See also https://aka.ms/tsconfig/module + "module": "nodenext", + "target": "esnext", + "types": [], + // For nodejs: + // "lib": ["esnext"], + // "types": ["node"], + // and npm install -D @types/node + + // Other Outputs + "sourceMap": true, + "declaration": true, + "declarationMap": true, + + // Stricter Typechecking Options + "noUncheckedIndexedAccess": true, + "exactOptionalPropertyTypes": true, + + // Style Options + "noImplicitReturns": true, + "noImplicitOverride": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noPropertyAccessFromIndexSignature": true, + + // Recommended Options + "strict": true, + "jsx": "react-jsx", + "verbatimModuleSyntax": true, + "isolatedModules": true, + "noUncheckedSideEffectImports": true, + "moduleDetection": "force", + "skipLibCheck": true, + "plugins": [ + { + "name": "@effect/language-service" + } + ] + }, + "exclude": ["node_modules", "repos"] +}