This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Salesforce Inspector Advanced is a Chrome/Firefox browser extension (fork of Salesforce Inspector Reloaded) that adds a metadata/productivity layer on top of the standard Salesforce UI: SOQL/SOSL data export, data import, Apex runner, log viewer/profiler, streaming/platform event monitor, flow analyzer, metadata retrieve, dependency viewer, org analyzer, etc.
All extension source lives in addon/ as plain, unbundled JS/HTML/CSS — there is no bundler, no JSX compilation step, and no framework beyond React loaded via <script> tags (react.js/react-dom.js, .min.js for release). UI code calls React.createElement directly (no JSX). Most feature modules are ES modules imported with import/export (type="module" in HTML/manifest); a few files that can't be modules (content scripts, background page, the React UMD bundles) are listed as exceptions in .eslintrc.js.
npm install # install devDependencies (eslint, fs-extra, replace-in-file, zip-dir)
npm run eslint # lint the whole repo (must pass; CI/Travis runs this)
npm run chrome-dev-build # generate addon/manifest.json for Chrome (MV3) from manifest-template.json
npm run firefox-dev-build # generate addon/manifest.json for Firefox (MV2) from manifest-template.json
npm run chrome-release-build # full release zip in target/chrome/
npm run firefox-release-build # full release zip in target/firefox/
There is no npm test script — see "Unit tests" below, they run in-browser, not via Node.
- Run
npm run chrome-dev-build(orfirefox-dev-build) to regenerateaddon/manifest.json— it's generated fromaddon/manifest-template.jsonbyscripts/dev-build.jsand is gitignored, so it must be rebuilt after pulling changes to the template or before first load. - Chrome:
chrome://extensions/→ enable Developer mode → Load unpacked → selectaddon/. - Firefox:
about:debugging→ Load Temporary Add-on → selectaddon/manifest.json.
Tests run inside a real Salesforce org via the browser, not Node/Jest/etc.
- Set up a Developer Edition org: deploy
test/metadata (sf deploy metadata -d test/ -o [org-alias]), set user language to English, enable "Allow users to relate a contact to multiple accounts", ensure no namespace prefix, assign theSfInspectorpermission set. - Navigate to
chrome-extension://<id>/test-framework.html?host=<org-domain>(replace the filename of any extension page withtest-framework.html). test-framework.js(addon/test-framework.js) auto-runs every suite registered in itsavailableTestsmap (currentlypopupTest,csvParseTest,dataImportTest,dataExportTest,flowAnalyzeTest, from the sibling*-test.jsfiles) unless a?test=/?tests=query param names a subset. Watch the browser devtools console for failures; success prints "Salesforce Inspector unit test finished successfully".*-test.jsfiles are stripped out of release builds (see filter inscripts/release-build.js) — they only ship in dev builds.
When adding a feature, add/extend the matching <feature>-test.js file and register it in test-framework.js's availableTests map if it's a new suite.
ESLint config is in .eslintrc.js (ES2020/module, 2-space indent, double quotes, required semicolons, eslint:recommended plus a large custom style rule set — read the file before writing code so new code matches). .eslintignore excludes the vendored React bundles and target/.
Each top-level feature is its own HTML page + same-named .js controller loaded as a content-script-invoked popup tab, e.g. data-export.html/.js (SOQL/SOSL export), data-import.html/.js (CSV import), apex-runner.html/.js, log.html/.js, streaming.html/.js, inspect.html/.js, metadata-retrieve.html/.js, explore-api.html/.js, limits.html/.js, dependency.html/.js, org-analyzer.html/.js, options.html/.js, flow-analyze.html/.js. These are opened as extension tabs (web_accessible_resources in the manifest), not iframes/SPA routes.
Each page follows the same internal shape: a Model class holding all UI state + business logic (constructed with {sfHost, args}), a didUpdate callback wired to ReactDOM.render, and a React component tree built with React.createElement. There's no shared state-management library — each page's Model is self-contained.
button.js+button.css: injected into every Salesforce tab (content_scriptsin the manifest). Detects it's inside a Salesforce org (checks forbody.sfdcBody,ApexCSIPage,#auraLoadingBox, etc.), asks the background page for the session viagetSfHost/getSessionmessages, then callsinitButton(ininspect-inline.js) to inject the floating Inspector button/UI into the page.background.js: MV2 background page / MV3 service worker. Owns allchrome.cookiesaccess (foreground pages can't reliably read thesidcookie across domains/incognito), resolves the right Salesforce session across the various*.salesforce.com/*.force.com/etc. domains, and proxies outbound AI API calls (callAIAPImessage) to avoid CORS from page contexts. Also handles the extension toolbar icon click and keyboard shortcuts (chrome.commands) which open the relevant tool page.background.jsandbutton.js/inspect-inline.jsare plain scripts (not ES modules) — see the.eslintrc.jsoverrides — because content scripts / MV2 background scripts can't be loaded as modules.
Exports sfConn, the single Salesforce API client used by every page:
sfConn.authenticate/sfConn.getSession: OAuth2 PKCE flow and session bootstrap (reads the session either from the background-page cookie lookup or from a completed OAuth redirect); persists tokens inlocalStoragekeyed bysfHost.sfConn.rest(url, options): raw REST API call viaXMLHttpRequest(supportsnormalandbulkauth headers, json/raw/csv/xml bodies, progress/abort handling, and centralized error classification —Unauthorized,SalesforceRestError, etc.).sfConn.soap(wsdl, method, args)+ theXMLhelper class: builds/parses SOAP envelopes for the Enterprise/Partner/Apex/Metadata/Tooling WSDLs (sfConn.wsdl(apiVersion, apiName)).- Also exports the current
apiVersion(persisted per-install inlocalStorage, with alastApiVersionbump mechanism).
Any code that talks to Salesforce should go through sfConn, not raw fetch/XMLHttpRequest, to stay consistent with session/error handling.
data-load.js: shared low-level helpers used by both export and import (Enumerable helpers,DescribeInfometadata cache, clipboard/table utilities).record-table.js: the reusable results-grid component (ScrollTable,TableModel,RecordTable) used by data export and inspect pages.editor.js: the custom code/query editor component (autocomplete, syntax highlighting) shared by SOQL/SOSL/Apex inputs — not a third-party editor library.history-box.js: reusable query/apex history dropdown (QueryHistory,HistoryBox), backed bylocalStorage.csv-parse.js: CSV parsing used by data import/export.ai-assistant.js: wraps calls to OpenAI/Mistral/Anthropic (seehost_permissionsin the manifest) via the background page'scallAIAPIproxy, used for AI-assisted query/code generation.flamechart/: a vendored flame-chart-js style library (color utilities, rendering engine) used by the Apex/log profiler view — treat as third-party code.links.js/setup-links.js: builders for deep links into standard Salesforce Setup pages.
addon/manifest-template.json is the source of truth; addon/manifest.json is generated and gitignored. scripts/dev-build.js branches on Chrome (MV3, service worker, split incognito) vs Firefox (MV2, background scripts, spanning incognito, includes applications.gecko) — check that script before hand-editing manifest behavior. scripts/release-build.js reuses dev-build.js, copies addon/ to target/<browser>/dist, strips test files, swaps in minified React, and zips the result. CI (.circleci/config.yml) auto-publishes the Chrome build via scripts/deploy_to_chrome_web_store.sh; .travis.yml runs lint + both release builds as a check; .github/workflows/ci.yml deploys the docs/ site (mkdocs-material) to GitHub Pages on push to master/main/beta.
- Stay completely inactive until the user explicitly interacts with it — never alter Salesforce's own behavior just from having the extension installed.
- Manual, ad-hoc tool only — not an automation framework.
- Efficiency over discoverability; advanced features can be hidden, primary features stay central; performance matters.
- Auto-provide contextual info (e.g. autocomplete everywhere) without overwhelming the user.
- Always provide a path to the raw Salesforce API result even if higher-level parsing/enhancement fails.
- Support the widest reasonable range of users/orgs: admins and standard users, person accounts, multi-currency, large data volumes, Professional Edition, slow networks.
- Be conservative with the number/complexity of Salesforce API calls, without sacrificing the above.
- Branch from
master; PRs targetmaster. - Update
CHANGES.mddescribing the fix/improvement as part of any user-facing change. - If a change adds/alters user-facing functionality, update the corresponding page in
docs/how-to.md(published via mkdocs to the GitHub Pages docs site).