원클릭으로
vendor-local
Vendor code from a local repository into Firefox's third_party/rust directory.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Vendor code from a local repository into Firefox's third_party/rust directory.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Firefox bug triage assistant — fetches a Bugzilla bug via MCP, classifies signals, scopes searches to a media/web-conferencing/graphics/android profile, drafts a response, optionally generates a test page, and stages a pending draft you can apply to BMO via REST.
Firefox Bugzilla triage workflow for Codex. Use for polling or processing Bugzilla triage scopes, drafting comments, applying canned responses, and tracking pending triage actions.
Root cause analysis for Firefox bugs with evidence-based code tracing, permanent source links, and proof tests. Two phases: diagnose, then discuss solutions.
Firefox bug root-cause analysis for Codex. Use for Bugzilla bugs or Firefox failures where you need evidence-based diagnosis, revision-pinned source links, code-path tracing, proof tests, resumable run directories, and later solution discussion.
Hypothesis-driven Firefox investigation: given a freeform suspicion that some code is buggy, unsafe, mis-behaving, or non-spec, blindspot validates the claim, finds real user-facing or security consequences (or proves there are none), and writes a bug-style report with revision-pinned code traces, original design intention from git history, and end-to-end proof tests. Triggers on: "/blindspot", "investigate this claim", "is this a real bug", "prove this is a bug", "find issues in <code>", "is this code safe", "what could go wrong with <code>".
Hypothesis-driven Firefox investigation for Codex. Use when a user has a suspicious code pattern, potential security issue, suspected spec violation, or vague claim and wants to prove whether it is a real bug, find consequences, and write proof tests.
| name | vendor-local |
| description | Vendor code from a local repository into Firefox's third_party/rust directory. |
| context | fork |
If you want to update a Rust crate to the latest upstream release (not local changes), use /update-media-lib instead. This skill (/vendor-local) is for testing local changes from a repository on your machine before they're merged upstream.
When the user invokes this skill, follow these steps in order:
First, ask the user how they want to specify their repository location:
Use AskUserQuestion with options:
$PWD.git, and contains Cargo.tomlStart at the current working directory ($PWD)
Run ls -d */ to list subdirectories, and check if current directory is a git repo with test -d .git
Use AskUserQuestion to present navigation options:
Repeat navigation until user either:
.git and Cargo.tomlValidate the selected path:
.gitCargo.toml (for Rust crates)git branch -a in the user's local repo to get all branches (local and remote)AskUserQuestion to present the branches as options, with:
main, master at the top if they existAfter the user selects a branch, ask how many commits to vendor:
Use AskUserQuestion with options:
Ask what to vendor:
If "Branch HEAD": Proceed to Step 3 using the branch name for checkout
If "Specific commit":
git log <branch> --oneline -n 10 to show recent commits<hash> <commit message>)AskUserQuestion to present commits as options:
<short-hash>: <message>Then proceed to Step 3.
Go to Step 2c to specify which commits.
Ask the user how they want to specify the commits:
Use AskUserQuestion with options:
If "List commit hashes":
If "Commit range":
cd <local-repo> && git log <range> --format=%H --reverse to get commits in order--reverse ensures oldest commits are processed firstIf "Last N commits":
cd <local-repo> && git log -n <N> <branch> --format=%H --reverse to get last N commitsFor each commit hash in the array, get commit info:
cd <local-repo> && git log -1 --format="%H %s" <commit-hash>
Display all commits that will be vendored:
The following commits will be vendored in sequence:
1. abc123: Fix memory leak in audio callback
2. def456: Add support for spatial audio
3. ghi789: Update documentation
Use AskUserQuestion to confirm:
If user cancels, return to Step 2b.
Store the array of commit hashes and proceed to Step 2d to save the current HEAD.
Before checking out commits, save the current branch or commit so we can restore it later:
cd <local-repo> && git symbolic-ref -q HEAD || git rev-parse HEAD
This command:
refs/heads/coreaudio-behavior) if on a branchStore this value as original_head to restore at the end.
Cargo.toml in the user's local repo to get the crate nametoolkit/library/rust/shared/Cargo.toml to find where this crate is referenced as a git dependencyhttps://github.com/mozilla/cubeb-coreaudio-rs)third_party/rust/CRITICAL REMINDERS:
./mach build are run from the Firefox root directory.cargo update from the Firefox root directory before building. The build system uses --frozen and will fail if Cargo.lock is out of sync.For Multiple Commits: If the user chose to vendor multiple commits in Step 2b, you will loop through the commit array. For each commit, follow the steps below, then pause for user to commit before continuing to the next.
Steps (repeat for each commit if multiple):
At the start of each commit iteration (for multiple commits only):
Get the commit hash:
cd <local-repo> && git rev-parse <branch>Check if the commit exists on origin remote (the main upstream repo):
cd <local-repo> && git branch -r --contains <commit-hash> | grep "^ origin/"
If commit IS on origin: Use standard vendoring
rev field in Firefox's toolkit/library/rust/shared/Cargo.tomlcd <firefox> && cargo update -p <crate-name> (from Firefox root directory)cd <firefox> && ./mach vendor rust --force (from Firefox root directory)If commit is NOT on origin: Ask user how to proceed
For multiple commits: Only ask this question once at the beginning. Use the same approach (fork or path dependency) for all commits in the sequence.
Use AskUserQuestion with options:
IMPORTANT: If the user mentions this is a security-sensitive fix or they don't want to expose code publicly, recommend the Path dependency option. This embeds the code in Firefox without any external references - only the try server and Phabricator reviewers will see the changes.
This is the recommended approach because it works on Mozilla's try server.
For multiple commits: All commits must be pushed to the fork before vendoring begins. Either push the branch containing all commits, or push each commit individually and vendor from fork.
Ask user for their fork's remote name (e.g., myfork)
Ask user for the branch name to push (default: current branch name)
Push the commits to the fork:
cd <local-repo> && git push <remote> <branch>:<target-branch-name>
For multiple commits, this pushes the entire branch. Alternatively, if using specific commit hashes, ensure they're all pushed.
Get the fork's URL:
cd <local-repo> && git remote get-url <remote>
Convert SSH URLs to HTTPS if needed (e.g., git@github.com:user/repo.git → https://github.com/user/repo)
Update Firefox's toolkit/library/rust/shared/Cargo.toml:
git URL to point to the forkrev to the new commit hashUpdate root Cargo.lock (from Firefox root directory):
cd <firefox> && cargo update -p <crate-name>
Vendor the crates (from Firefox root directory):
cd <firefox> && ./mach vendor rust --force
Build to verify (from Firefox root directory):
cd <firefox> && ./mach build
This approach embeds the code directly in Firefox using path dependencies. No code is pushed to any public repository - only the try server and Phabricator reviewers will see the changes.
Best for:
How it works:
git = "..." to path = "..."Steps:
IMPORTANT: All commands below (unless explicitly noted) should be run from the Firefox root directory. Use absolute paths to avoid working directory issues.
Checkout the selected branch or commit in the local repo:
cd <local-repo> && git checkout <branch-or-commit-hash>
Verify the checkout was successful before proceeding.
Copy source files from local repo to vendored location:
rsync -av --delete \
--exclude='.git' \
--exclude='target' \
--exclude='.gitignore' \
--exclude='<nested-crate-dirs>' \
<local-repo>/ <firefox>/third_party/rust/<crate-name>/
Note: Use absolute paths for both source and destination to avoid directory confusion.
Handle nested crates/workspaces if present:
third_party/rust/ using absolute pathsCargo.toml to fix internal path references:
# Change from:
nested-crate = { path = "nested-crate" }
# To:
nested-crate = { path = "../nested-crate" }
Update Firefox's toolkit/library/rust/shared/Cargo.toml to use path dependency:
# Change from:
my-crate = { git = "https://github.com/...", rev = "...", ... }
# To:
my-crate = { path = "../../../../third_party/rust/my-crate", ... }
Note: The path is relative to the Cargo.toml location (toolkit/library/rust/shared/)
CRITICAL: Remove vendored Cargo.lock files and generate .cargo-checksum.json:
Path dependencies in Firefox still require .cargo-checksum.json files. Without them, you'll get "failed to load source for dependency" errors.
# Remove vendored Cargo.lock files (not needed for path deps)
# Use absolute paths to Firefox root directory
rm -f <firefox>/third_party/rust/<crate-name>/Cargo.lock
rm -f <firefox>/third_party/rust/<nested-crate-name>/Cargo.lock
# Generate .cargo-checksum.json for main crate
cd <firefox>/third_party/rust/<crate-name> && python3 << 'EOF'
import hashlib, json, os files = {} for root, dirs, filenames in os.walk('.'): dirs[:] = [d for d in dirs if not d.startswith('.')] for filename in filenames: if filename.startswith('.'): continue filepath = os.path.join(root, filename) relpath = os.path.relpath(filepath, '.') with open(filepath, 'rb') as f: files[relpath] = hashlib.sha256(f.read()).hexdigest() with open('.cargo-checksum.json', 'w') as f: json.dump({"files": files, "package": ""}, f) EOF
cd /third_party/rust/ && python3 << 'EOF' import hashlib, json, os files = {} for root, dirs, filenames in os.walk('.'): dirs[:] = [d for d in dirs if not d.startswith('.')] for filename in filenames: if filename.startswith('.'): continue filepath = os.path.join(root, filename) relpath = os.path.relpath(filepath, '.') with open(filepath, 'rb') as f: files[relpath] = hashlib.sha256(f.read()).hexdigest() with open('.cargo-checksum.json', 'w') as f: json.dump({"files": files, "package": ""}, f) EOF
6. **CRITICAL**: Update root Cargo.lock (from Firefox root directory):
```bash
cd <firefox> && cargo update -p <crate-name>
If there are nested crates, update them too:
cd <firefox> && cargo update -p <crate-name> -p <nested-crate-name>
This step is essential - the build system requires the root Cargo.lock to be updated before building. If you skip this step, the build will fail with a "--frozen" error.
Build to verify (from Firefox root directory):
cd <firefox> && ./mach build
For multiple commits: You can ask the user if they want to:
After vendoring each commit (for multiple commits only):
Show a summary of what was vendored:
✓ Commit vendored successfully!
Commit: <commit-hash>
Message: <commit-message>
Files updated:
- third_party/rust/<crate-name>/
- toolkit/library/rust/shared/Cargo.toml
- Cargo.lock
Suggest a Firefox commit message:
Suggested Firefox commit message:
Update <crate-name> to <short-hash>
<upstream-commit-message>
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Ask the user if they want to commit now (using AskUserQuestion):
If user chooses "Yes, commit now":
git add Cargo.lock toolkit/library/rust/shared/Cargo.toml third_party/rust/<crate-name>/ third_party/rust/<nested-crate-name>/git status to confirm clean working treeIf this is NOT the last commit, ask the user:
Use AskUserQuestion:
If user chooses "Continue", loop back to the beginning of Step 4 with the next commit. If user chooses "Stop", exit the multi-commit loop and proceed to Step 5.
If this IS the last commit:
a. Show success message:
✓ All commits vendored successfully!
Vendored X commits total.
b. Restore the local repo HEAD to its original state:
cd <local-repo> && git checkout <original_head>
Where <original_head> is the value saved in Step 2d (either a branch name like refs/heads/coreaudio-behavior or a commit hash).
If original_head starts with refs/heads/, extract just the branch name (e.g., refs/heads/main → main) before checking out.
c. Then proceed to Step 5 of the main workflow.
Before landing: When the upstream PR is merged and ready to land in Firefox:
./mach vendor rust --force to restore normal vendoringFor multiple commits: Only offer this after ALL commits have been vendored and committed by the user.
Ask the user: "Do you want to run tests on try?" with options:
Note: Must commit all changes before pushing to try. For multiple commits, this means all Firefox commits should be created first.
Recommended tests for audio/cubeb crates:
./mach try fuzzy -q 'cubeb' - cubeb-specific tests./mach try fuzzy -q 'audio' - broader audio tests./mach try auto - let the system pick relevant testsFor other crates, recommend:
./mach try auto - automatic test selection based on changesIf the user selects yes:
./mach vendor rust fails, show the error and suggest using --force flag[patch] sections with local filesystem paths for try testing - these paths don't exist on try machinesmozilla/) before landing the final patch--force flag for ./mach vendor rust bypasses cargo-vet errors that may be unrelated to your changes