agent-joule/extensions/EXTRACTION.md
David Charlot 88a41bedd3 Rebrand Zed -> Joule across UI, docs, embedded assets, and legal
The fork shipped renamed binary/bundle but the product name "Zed" was still
shown everywhere in the UI. Rename the display name to "Joule" (tagline
"Energy-metered agentic coding") while preserving every load-bearing reference.

Display renames (105 .rs files): release_channel display_name, welcome +
onboarding + ai_onboarding, macOS app menu (About/Hide/Quit), window titles,
About panel, settings UI, notifications, update/collab messages, system specs.
Bundle display name (crates/zed/Cargo.toml) -> "Joule" so CFBundleName / the
menu-bar name and the .app are "Joule" (identifier science.transaction.AgentJoule
and the agent-joule binary are unchanged).

Docs (223 .md): product prose Zed -> Joule, fence-aware (code blocks untouched).
Embedded assets (12 JSONC): // comments only.
Legal (4 files): product -> Joule, entity "Zed Industries, Inc." -> "Transaction
Science, Inc.", domain zed.dev -> openie.dev. NOTE: these are structurally Zed's
inherited terms and need a real legal review, not just a rename.

Deliberately PRESERVED (renaming would break the app): font aliases ("Zed Plex
Sans"/".ZedMono" in text_system + assets), HTTP header names (X-Zed-Predict-*),
zed:: action ids, app/bundle identifiers (dev.zed.Zed*, Zed-Editor-* product ids),
zed.dev URLs, ZED_* env vars, crate/package names, "Zed Industries" in non-legal
attribution, and the {zed,Zed} config-dir glob.

Signed + notarized + stapled as Joule.app, installed to /Applications, verified
(Gatekeeper: Notarized Developer ID, FH93XC2VRR). Caveat: test-code string
literals were renamed too, so some `cargo test` assertions may need updating.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-03 02:23:35 -04:00

5.3 KiB

Extracting an extension to dedicated repo

These are some notes of how to extract an extension from the main zed repository and generate a new repository which preserves the history as best as possible. In the this example we will be extracting the ruby extension, substitute as appropriate.

Pre-requisites

Install git-filter-repo:

brew install git-filter-repo

Process

We are going to use a $LANGNAME variable for all these steps. Make sure it is set correctly.

Note

If you get zsh: command not found: # errors, run: setopt interactive_comments && echo "setopt interactive_comments" >> ~/.zshrc

  1. Create a clean clone the zed repository, delete tags and delete branches.
LANGNAME=your_language_name_here

rm -rf $LANGNAME
git clone --single-branch --no-tags [email protected]:zed-industries/zed.git $LANGNAME
cd $LANGNAME
  1. Create an expressions.txt file somewhere (e.g. ~/projects/$LANGNAME.txt)

This file takes the form of pattern==>replacement, where the replacement is optional. Note whitespace matters so ruby: ==> is removing the ruby: prefix from a commit messages and adding a space after ==> means the replacement begins with a space. Regex capture groups are numbered \1, \2, etc.

See: Git Filter Repo Docs for more.

# Create regex mapping for rewriting commit messages (edit as appropriate)
mkdir -p ~/projects
echo "${LANGNAME}: ==>
extension: ==>
chore: ==>
zed_extension_api: ==>
"'regex:(?<![\[a-zA-Z0-9])(#[0-9]{3,5})==>zed-industries/zed\1' \
  > ~/projects/${LANGNAME}.txt

# This removes the LICENSE symlink
git filter-repo --invert-paths --path extensions/$LANGNAME/LICENSE-APACHE

# This does the work
git filter-repo \
    --use-mailmap \
    --subdirectory-filter extensions/$LANGNAME/ \
    --path LICENSE-APACHE \
    --replace-message ~/projects/${LANGNAME}.txt
  1. Review the commits.

This is your last chance to make any modifications. If you don't fix it now, it'll be wrong forever.

For example, a previous commit message was php/ruby: bump version to 0.0.5 which was replaced with php/bump version to 0.0.5 so I added a new line to expressions.txt with php/==> and next run it became bump version to 0.0.5.

  1. [Optional] Generate tags

You can always add tags later, but it's a nice touch.

Show you all commits that mention a version number:

git log --grep="(\d+\.\d+\.\d+)" --perl-regexp --oneline --reverse

Then just:

git tag v0.0.2 abcd1234
git tag v0.0.3 deadbeef

Usually the initial extraction didn't mention a version number so you can just do that one manually.

  1. [Optional] Add a README.md and commit.

  2. Push to the new repo

Create a new empty repo on github under the zed-extensions organization.

git remote add origin [email protected]:zed-extensions/$LANGNAME
git push origin main --tags
git branch --set-upstream-to=origin/main main
  1. Setup the new repository:
  • Go to the repository settings:
    • Disable Wikis
    • Uncheck "Allow Merge Commits"
    • Check "Allow Squash Merging"
      • Default commit message: "Pull request title and description"
  1. Publish a new version of the extension.
OLD_VERSION=$(grep '^version = ' extension.toml | cut -d'"' -f2)
NEW_VERSION=$(echo "$OLD_VERSION" | awk -F. '{$NF = $NF + 1;} 1' OFS=.)
echo $OLD_VERSION $NEW_VERSION
perl -i -pe "s/$OLD_VERSION/$NEW_VERSION/" extension.toml
perl -i -pe "s#https://github.com/zed-industries/zed#https://github.com/zed-extensions/${LANGNAME}#g" extension.toml

# if there's rust code, update this too.
test -f Cargo.toml && perl -i -pe "s/$OLD_VERSION/$NEW_VERSION/" Cargo.toml
# remove workspace Cargo.toml lines
test -f Cargo.toml && perl -ni -e 'print unless /^.*(workspace\s*=\s*true|\[lints\])\s*$/' Cargo.toml
test -f Cargo.toml && cargo check

# add a .gitignore
echo "target/
grammars/
*.wasm" > .gitignore

# commit and push
git add -u
git checkout -b "bump_${NEW_VERSION}"
git commit -m "Bump to v${NEW_VERSION}"
git push
gh pr create --title "Bump to v${NEW_VERSION}" --web

# merge PR in web interface
git checkout main
git pull
git tag v${NEW_VERSION}
git push origin v${NEW_VERSION}
  1. In zed repository, remove the old extension and push a PR.
rm -rf extensions/$LANGNAME
sed -i '' "/extensions\/$LANGNAME/d" Cargo.toml
cargo check
git checkout -b remove_$LANGNAME
git add extensions/$LANGNAME
git add Cargo.toml Cargo.lock extensions/$LANGNAME
git commit -m "Migrate to $LANGNAME extension to zed-extensions/$LANGNAME"
git push
gh pr create --web
  1. Update extensions repository:
cd ../extensions
git checkout main
git pull
git submodule init
git submodule update
git status

git checkout -b ${LANGNAME}_v${NEW_VERSION}
git submodule add https://github.com/zed-extensions/${LANGNAME}.git extensions/${LANGNAME}
pnpm sort-extensions

# edit extensions.toml:
# - bump version
# - change `submodule` from `extensions/zed` to new path
# - remove `path` line all together

git add extensions.toml .gitmodules extensions/${LANGNAME}
git diff --cached
git commit -m "Bump ${LANGNAME} to v${NEW_VERSION}"
git push

Create PR and reference the Joule PR with removal from tree.