Agent skill

ToolJet Multi-Repo Merge

by ToolJet in ToolJet/ToolJet

Merges a source branch into the current branch across ToolJet's root repo and its server/ee and frontend/ee submodules, handling conflicts and submodule order.

AGPL-3.0Auto-check: warningsDevelopment

Install ToolJet Multi-Repo Merge

The automated check flagged lines worth reading first. See the safety section below.

skills CLI
$ npx skills add ToolJet/ToolJet --skill merge -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install ToolJet/ToolJet merge --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/ToolJet/ToolJet.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/merge .claude/skills/merge && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
merge
GitHub stars
41k
Token cost
~2.1k tokens
SKILL.md length
721 words
Files
1
Skills in repo
7
Repo updated
First seen
Licence
AGPL-3.0

At a glance

Merges a source branch into the current branch across ToolJet's root repo and its server/ee and frontend/ee submodules, handling conflicts and submodule order.

  • Works in 2 steps: Analysis (single Bash call) → Merge Execution
  • Merging a feature branch into the current branch across ToolJet's submodules
  • SKILL.md covers Branch policy, Shell environment notes, Phase 1 — Analysis (single… and Phase 2 — Merge Execution, plus 2 more sections
  • Calls git and gh

What it does

The skill parses a /merge command: with no argument it merges the branch's base, read from the open PR's base ref or else the remote's default branch; with an argument it treats the whole input as the source branch name, and asks the user when the context points at an unclear release line. It warns that the Bash tool runs in zsh via eval, so for loops break with a 'git: command not found' error and must be avoided in favor of separate per-repo commands, and that coreutils need full paths.

Phase 1 runs a single analysis script that checks each repo's status against the source branch. Phase 2 either reports that everything is already up to date, or processes server/ee, then frontend/ee, then the root in that order, one separate Bash call per not-up-to-date repo: a fast-forward pull when the current branch is the source branch, or a stash, merge and stash-pop sequence when the repo is dirty. It also flags a known gotcha where an untracked file inside a submodule makes the merge commit's lint-staged hook fail, requiring the file to be moved aside, committed around, and restored.

When your agent uses it

  • Merging a feature branch into the current branch across ToolJet's submodules
  • Syncing the current branch with main across root, server/ee and frontend/ee
  • Resolving a lint-staged failure caused by an untracked file inside a submodule during a merge

Example prompts

  • “/merge main across all the submodules.”
  • “/merge feature/new-widget into my current branch.”
  • “Merge the current branch's PR base into my branch across all repos.”

Requirements

  • A checkout of the ToolJet repository with its ee submodules
  • gh CLI
  • zsh

Workflow steps

2 steps, taken from the step headings in SKILL.md.

  1. Analysis (single Bash call)
  2. Merge Execution

What it can do on your machine

Read from SKILL.md and the folder at commit 1786038. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • git
    • gh

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use git and gh, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

ToolJet Multi-Repo Merge loads about 2.1k tokens when it runs. Until then it costs about 63 tokens; SKILL.md has 721 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~63
When it runs · the whole SKILL.md, loaded when a task matches
~2.1k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check: warnings

The automated check found patterns that need a careful read before installing.

  • WarningTells the agent its actions are pre-authorized / not to stop for confirmationSKILL.md:213
    5. **Do NOT ask for confirmation** — merges are reversible with `git merge --abort`.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from ToolJet/ToolJet at commit 1786038, republished under its AGPL-3.0 licence (© ToolJet). 721 words, ~2,140 tokens.

Download SKILL.mdSave it as .claude/skills/merge/SKILL.md (or your agent's skills folder).
name
merge
description
Merge a source branch into the current branch across all ToolJet repos (root + server/ee + frontend/ee submodules). Handles conflicts, stashing, and submodule ordering. Use when asked to merge, sync with, or bring in changes from another branch.

Merge a source branch into the current branch across all repos (root + submodules).

User input: $ARGUMENTS

Usage:

/merge                  # merge the branch's base (open PR base, else main)
/merge main             # merge main into current branch
/merge feature/foo      # merge feature/foo into current branch

Parse the input:

  • If empty: the source is the branch's base, inferred from context (see Branch policy below)
  • Otherwise: use the entire input as the source branch name.

Branch policy

With no source given, merge the branch's base:

  • the base of its open PR (gh pr view --json baseRefName);
  • otherwise, the remote's default branch: main, read from git ls-remote --symref origin HEAD, because a local origin/HEAD goes stale.

If the context points at a release line (e.g. an lts-* backport) or is unclear, ask the user.

Gotcha: a merge commit runs the pre-commit hook on every incoming file. An untracked file inside a submodule (e.g. a stray lock file in server/ee) makes lint-staged fail with "Unstaged changes could not be restored". Move such files aside, commit, then put them back.

Shell environment notes

IMPORTANT: The Bash tool executes in zsh via eval. Two known constraints:

  1. for loops cause git: command not found — never use loops. Use inline per-repo commands instead.
  2. Always use full paths for coreutils: /usr/bin/head, /usr/bin/sed, /usr/bin/find.

Phase 1 — Analysis (single Bash call)

Run the following script. Replace <source> with the parsed source branch name.

bash
SOURCE="<source>"
ROOT=$(git rev-parse --show-toplevel)
SEE="$ROOT/server/ee"
FEE="$ROOT/frontend/ee"

# Fetch source branch in all repos (sequential — loops are broken in this env)
git -C "$ROOT" fetch origin "$SOURCE" 2>/dev/null
[ -f "$SEE/.git" ] && git -C "$SEE" fetch origin "$SOURCE" 2>/dev/null
[ -f "$FEE/.git" ] && git -C "$FEE" fetch origin "$SOURCE" 2>/dev/null

echo "SOURCE: $SOURCE"
echo "ROOT: $ROOT"

# --- ROOT ---
echo "=ROOT="
echo "branch=$(git -C "$ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null)"
echo "dirty=$(git -C "$ROOT" status --porcelain 2>/dev/null | /usr/bin/head -1)"
_src=$(git -C "$ROOT" ls-remote --heads origin "$SOURCE" 2>/dev/null | /usr/bin/head -1)
if [ -n "$_src" ]; then
  echo "source_exists=YES"
  git -C "$ROOT" merge-base --is-ancestor "origin/$SOURCE" HEAD 2>/dev/null && echo "up_to_date=YES" || echo "up_to_date=NO"
  echo "behind=$(git -C "$ROOT" rev-list HEAD..origin/$SOURCE --count 2>/dev/null)"
else
  echo "source_exists=NO"
  echo "up_to_date=N/A"
  echo "behind=0"
fi

# --- SERVER_EE ---
echo "=SERVER_EE="
if [ -f "$SEE/.git" ]; then
  echo "branch=$(git -C "$SEE" rev-parse --abbrev-ref HEAD 2>/dev/null)"
  echo "dirty=$(git -C "$SEE" status --porcelain 2>/dev/null | /usr/bin/head -1)"
  _src=$(git -C "$SEE" ls-remote --heads origin "$SOURCE" 2>/dev/null | /usr/bin/head -1)
  if [ -n "$_src" ]; then
    echo "source_exists=YES"
    git -C "$SEE" merge-base --is-ancestor "origin/$SOURCE" HEAD 2>/dev/null && echo "up_to_date=YES" || echo "up_to_date=NO"
    echo "behind=$(git -C "$SEE" rev-list HEAD..origin/$SOURCE --count 2>/dev/null)"
  else
    echo "source_exists=NO"
    echo "up_to_date=N/A"
    echo "behind=0"
  fi
else
  echo "present=NO"
fi

# --- FRONTEND_EE ---
echo "=FRONTEND_EE="
if [ -f "$FEE/.git" ]; then
  echo "branch=$(git -C "$FEE" rev-parse --abbrev-ref HEAD 2>/dev/null)"
  echo "dirty=$(git -C "$FEE" status --porcelain 2>/dev/null | /usr/bin/head -1)"
  _src=$(git -C "$FEE" ls-remote --heads origin "$SOURCE" 2>/dev/null | /usr/bin/head -1)
  if [ -n "$_src" ]; then
    echo "source_exists=YES"
    git -C "$FEE" merge-base --is-ancestor "origin/$SOURCE" HEAD 2>/dev/null && echo "up_to_date=YES" || echo "up_to_date=NO"
    echo "behind=$(git -C "$FEE" rev-list HEAD..origin/$SOURCE --count 2>/dev/null)"
  else
    echo "source_exists=NO"
    echo "up_to_date=N/A"
    echo "behind=0"
  fi
else
  echo "present=NO"
fi

Parse the output before proceeding to Phase 2.


Phase 2 — Merge Execution

If all repos are up to date

Print a summary and stop:

All repos are up to date with `<source>`.

| Repo | Branch | Status |
|---|---|---|
| server/ee | <branch> | up to date |
| frontend/ee | <branch> | up to date |
| root | <branch> | up to date |
Otherwise, process repos in order: server/ee → frontend/ee → root

For each repo that is NOT up to date and where source branch EXISTS on remote, run a separate Bash call per repo (do not combine into one script with loops).

If current branch IS the source branch (fast-forward):
bash
git -C <path> pull --ff-only origin <source>
If dirty:
bash
git -C <path> stash push -m "merge-auto-stash-$(date +%Y%m%d-%H%M%S)" && git -C <path> merge origin/<source> --no-edit && git -C <path> stash pop

If the merge step fails (conflicts): run git -C <path> diff --name-only --diff-filter=U to list conflicted files. Do NOT pop stash. Note as conflicted and continue to the next repo.

If clean:
bash
git -C <path> merge origin/<source> --no-edit

If conflicts, same handling as above.

Skip if source branch missing
⚠ <repo>: source branch `<source>` not found on remote — skipping

Root's merge of a submodule pointer can fail with Failed to merge submodule <path> (commits not present). This means the pinned commit is not in the local submodule clone.

Root's gitlink is the authority, not the submodule's own branch. Root main frequently pins submodule commits that are not reachable from the submodule's main — release commits pushed as pointers without a branch. Merging the submodule's origin/main instead produces a pointer that does not match what root wants.

Resolve it:

  1. Read the commit root wants: git -C <root> ls-tree origin/<source> <submodule path>
  2. Fetch it by SHA — it may not be on any branch: git -C <submodule> fetch origin <sha>
  3. Merge that SHA into the submodule (not its origin/<source>): git -C <submodule> merge <sha> --no-edit
  4. If the submodule had no local commits of its own, check it out directly instead: git -C <submodule> checkout --detach <sha>
  5. Back in root: git -C <root> add <submodule path>

Verify before committing — git -C <root> submodule status must show no + or - prefix, meaning each gitlink matches its checked-out HEAD.

Show full SKILL.md (217 more words)Show less
After all repos are processed

Print a summary table:

## Merge Summary

Source: `<source>`

| Repo | Branch | Behind | Result |
|---|---|---|---|
| server/ee | <branch> | <n> commits | ✓ merged / ✓ up to date / ⚠ skipped / ✗ conflicts |
| frontend/ee | <branch> | <n> commits | ✓ merged / ✓ up to date / ⚠ skipped / ✗ conflicts |
| root | <branch> | <n> commits | ✓ merged / ✓ up to date / ⚠ skipped / ✗ conflicts |
If any repo had conflicts

List conflicted files per repo, then offer to resolve them one at a time:

  1. Read each conflicted file
  2. Suggest and apply resolution via Edit tool
  3. After all conflicts in a repo: git -C <path> add -A && git -C <path> commit --no-edit
  4. Pop stash if one was created: git -C <path> stash pop
  5. If stash pop conflicts, report separately — do NOT abort the merge
If no conflicts

Print: All merges completed cleanly.


Rules

  1. Process order: always server/ee → frontend/ee → root (submodules before root).
  2. Continue through all repos even if one has conflicts — report everything at the end.
  3. Never force-push, reset --hard, clean, or use --no-verify.
  4. Named stash entries (merge-auto-stash-<timestamp>) for easy identification.
  5. Do NOT ask for confirmation — merges are reversible with git merge --abort.
  6. Fast-forward if current branch IS the source branch.
  7. Missing source branch on a submodule = skip with warning, not failure.
  8. Stash pop conflicts are separate from merge conflicts — report but don't abort.
  9. No loops — always use inline per-repo commands (see shell environment notes).
  10. Always use git -C <path> — never cd <path> && git.
  • commit — commit across root + submodules
  • create-pr — push and open PRs across root + submodules

© ToolJet, AGPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/merge of ToolJet/ToolJet.

Open the folder on GitHubat commit 1786038

Compare with similar skills

ToolJet Multi-Repo Merge next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

ToolJet Multi-Repo Merge compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
ToolJet Multi-Repo Merge this skillToolJet/ToolJet41k—~2.1kAutomated safety check: WarnAGPL-3.0
Finishing a Development Branchobra/superpowers296k5 repos~1.9kAutomated safety check: PassMIT
Code Design Rationale Investigatorcursor/plugins10k9 repos~2.6kAutomated safety check: PassNone
Contributor-First PR MergeHKUDS/OpenHarness16k1 repos~847Automated safety check: PassMIT
Migrate Internal Package into GhostTryGhost/Ghost55k—~3.8kAutomated safety check: PassMIT
Create Pull Requestcline/cline70k1 repos~1.6kAutomated safety check: PassApache-2.0

Similar skills

  • Walks the last step of a branch: confirm tests pass, detect the git environment, ask how to integrate, carry out your choice and clean up the worktree.

    296k GitHub starsUsed in 5 repos~1.9k tokens
    DevelopmentAuto-check passed
  • Official

    Digs into why code is shaped the way it is by checking git history, pull requests and connected tools in parallel, then reporting a cited read on the tradeoffs.

    10k GitHub starsUsed in 9 repos~2.6k tokens
    DevelopmentAuto-check passed
  • Merges external GitHub pull requests while keeping the original author credited, and fixes conflicts after the merge instead of rewriting the contribution.

    16k GitHub starsUsed in 1 repo~847 tokens
    DevelopmentAuto-check passed
  • Moves a package from another TryGhost repository into Ghost as an internal workspace package while keeping its Git history, with checkpoints for the steps that need an administrator.

    55k GitHub stars~3.8k tokensUpdated today
    DevelopmentAuto-check passed
  • Opens a GitHub pull request from your current branch with the gh CLI, after reviewing the commits and diff and gathering the details the PR needs.

    70k GitHub starsUsed in 1 repo~1.6k tokens
    DevelopmentAuto-check passed
  • Git Merge Conflict Resolver

    tailcallhq/forgecode

    Resolves Git merge conflicts with a plan-first workflow that keeps both sides' intent, regenerates lock files and backs up deleted-but-modified files.

    7.6k GitHub starsUsed in 1 repo~4.5k tokens
    DevelopmentAuto-check passed

More from ToolJet/ToolJet

  • Turns an API description, such as an OpenAPI file or a Postman collection, into a connector plugin for ToolJet's marketplace and checks it with the repo's validator.

    41k GitHub stars~2.1k tokensUpdated today
    Auto-check passed
  • Commits changes across ToolJet's root repo and its server/ee and frontend/ee submodules, writing messages from the diffs and updating submodule pointers in order.

    41k GitHub stars~1.3k tokensUpdated today
    Auto-check passed
  • Opens a pull request for the current ToolJet branch, pushing the root repo and the ee submodules, creating submodule PRs first and then the main PR with a generated description.

    41k GitHub stars~3.6k tokensUpdated today
    Auto-check passed
  • Reviews a ToolJet pull request of any size and writes a findings report for you to read first, scaling the process to the diff and posting to GitHub only on request.

    41k GitHub stars~3.1k tokensUpdated today
    Auto-check passed
  • ToolJet Release Cutter

    ToolJet/ToolJet

    Cuts a ToolJet release branch, bumps the version and moves feature PRs onto it, or adds more PRs to a release that already exists.

    41k GitHub stars~5.6k tokensUpdated today
    Auto-check passed
  • ToolJet Skill Manager

    ToolJet/ToolJet

    Decides where a new agent skill belongs in the ToolJet repo, public root or private ee submodule, then wires the symlinks so it loads in Claude Code, Cursor and Codex.

    41k GitHub stars~867 tokensUpdated today
    Auto-check passed

Works with

Categories

Questions about ToolJet Multi-Repo Merge

What does ToolJet Multi-Repo Merge do?

Merges a source branch into the current branch across ToolJet's root repo and its server/ee and frontend/ee submodules, handling conflicts and submodule order. The skill parses a /merge command: with no argument it merges the branch's base, read from the open PR's base ref or else the remote's default branch; with an argument it treats the whole input as the source branch name, and asks the user when the context points at an unclear release line. It warns that the Bash tool runs in zsh via eval, so for loops break with a 'git: command not found' error and must be avoided in favor of separate per-repo commands, and that coreutils need full paths.

When should I use ToolJet Multi-Repo Merge?

ToolJet Multi-Repo Merge fits situations like: merging a feature branch into the current branch across ToolJet's submodules; syncing the current branch with main across root, server/ee and frontend/ee; resolving a lint-staged failure caused by an untracked file inside a submodule during a merge.

How do I install ToolJet Multi-Repo Merge in Claude Code?

Run `npx skills add ToolJet/ToolJet --skill merge -a claude-code`. Or copy the skill folder (.agents/skills/merge in ToolJet/ToolJet) into .claude/skills/merge in your project. Claude Code loads it when a task matches its description.

How do I install ToolJet Multi-Repo Merge in Codex?

Run `npx skills add ToolJet/ToolJet --skill merge -a codex`. Or copy the skill folder (.agents/skills/merge in ToolJet/ToolJet) into .agents/skills/merge in your project. Codex loads it when a task matches its description.

Can I use ToolJet Multi-Repo Merge in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add ToolJet/ToolJet --skill merge -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/merge, .gemini/skills/merge, .github/skills/merge and .opencode/skills/merge in your project.

What does ToolJet Multi-Repo Merge need to run?

Going by SKILL.md and its folder, ToolJet Multi-Repo Merge needs the command-line tools its instructions call (git and gh). Our summary lists: A checkout of the ToolJet repository with its ee submodules; gh CLI; zsh.

Does ToolJet Multi-Repo Merge access the network?

SKILL.md contains no URLs. Its commands use git and gh, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is ToolJet Multi-Repo Merge safe to install?

Our automated static check of SKILL.md flagged 1 warning(s): tells the agent its actions are pre-authorized / not to stop for confirmation. Read the flagged lines before installing; the check is not a guarantee either way.

What licence does ToolJet Multi-Repo Merge use?

ToolJet Multi-Repo Merge is published under the AGPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does ToolJet Multi-Repo Merge use?

About 2.1k tokens (SKILL.md is roughly 8.6k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to ToolJet Multi-Repo Merge?

Skills that share tags, products or a category with ToolJet Multi-Repo Merge: Finishing a Development Branch (obra/superpowers, 296k stars), Code Design Rationale Investigator (cursor/plugins, 10k stars), Contributor-First PR Merge (HKUDS/OpenHarness, 16k stars) and Migrate Internal Package into Ghost (TryGhost/Ghost, 55k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains ToolJet Multi-Repo Merge?

ToolJet (a GitHub organization) maintains it in ToolJet/ToolJet, which has 41,045 GitHub stars. The repository holds 7 skills in this directory. The repository was last updated on October 7, 2026.

Source: ToolJet/ToolJet on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.