agentleFS
p10ns11yp10ns11y/skills/project-editor-profile/SKILL.md

project-editor-profile

Skill2 starsChanged 40 days agoMITView on GitHub

Generates editor-agnostic workspace settings from a .editor/profile.json manifest: .vscode/settings.json, extensions.json, and Cursor workspaceOpen plugin loading. Use when setting up per-project extensions, Cursor plugins, editor defaults, or porting workspace config to new repos.

The file

We split this skill into the rules it gives an agent

5 rules. About 0 are common, 1 is distinctive, and 4 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  • could be automatic: a setting could enforce it
  1. Distinctive:

    Do not recommend extensions for stacks the repo does not use — reduces attack surface and UI noise (audit-ide-dependencies).

    line 63
  2. Very specific:

    Never hand-edit generated .vscode/settings.json long-term — change profile.json and re-sync.

    line 104
  3. Very specific:

    Put extension-only keys in .editor/profile.extensions.json (merged by editor:sync only when that extension exists under …

    line 113
  4. Very specific:

    Add "editor:sync": "node scripts/sync-editor-profile.mjs" to package.json.

    line 148
  5. Very specific:

    Run pnpm editor:sync and commit outputs.

    line 150

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Project editor profile

Maintain a single manifest (.editor/profile.json) and generate editor files that VS Code, Cursor, and VSCodium all understand. Keeps extensions/plugins scoped to the stack instead of loading every global install.

Example in this repo: .editor/profile.json → run pnpm editor:sync.


Layout

.editor/
  profile.json           # Project manifest (stack, extensions, cursor plugins, settings)
  defaults.settings.json # Shared baseline merged into every project
.vscode/                 # Generated — commit to git
  settings.json
  extensions.json
.cursor/                 # Generated — commit to git
  hooks.json             # workspaceOpen → load-workspace-plugins.mjs
scripts/
  sync-editor-profile.mjs   # Regenerate .vscode + .cursor/hooks.json
  load-workspace-plugins.mjs  # Hook: emit pluginPaths from profile

Workflow checklist

- [ ] 1. Detect stack (package.json, configs, test runners)
- [ ] 2. Edit .editor/profile.json (extensions, cursor.plugins, settings overrides)
- [ ] 3. Run: pnpm editor:sync (or node scripts/sync-editor-profile.mjs)
- [ ] 4. Reload window; accept recommended extensions when prompted
- [ ] 5. Confirm Cursor plugins load (hooks) or install missing marketplace plugins
- [ ] 6. Commit .editor/, .vscode/, .cursor/hooks.json

Step 1: Detect stack

SignalFile / depTypical extensionsUnwanted (other stacks)
Next.jsnext, next.config.*Biome, Tailwind CSS IntelliSenseESLint, Prettier (legacy)
Reactreact, react-domESLint—
TypeScripttypescript, tsconfig.jsonBiome; use workspace typescript.tsdk—
Tailwindtailwindcss, @tailwindcss/postcssTailwind CSS IntelliSense—
Playwright@playwright/test, playwright.config.*PlaywrightPrefer host browser when project documents that pattern
pnpmpnpm-lock.yaml, packageManager—npm-only tooling
Pythonpyproject.toml, requirements.txtPython, Pylance(if absent, unwanted Python)
RustCargo.tomlrust-analyzer(if absent, unwanted Rust)
Sveltesvelte, .svelteSvelte + Cursor svelte plugin—

Do not recommend extensions for stacks the repo does not use — reduces attack surface and UI noise (audit-ide-dependencies).


Step 2: Edit profile.json

Minimal shape:

{
  "name": "my-app",
  "stack": ["next", "typescript", "pnpm"],
  "extensions": {
    "recommend": ["dbaeumer.vscode-eslint"],
    "unwanted": ["rust-lang.rust-analyzer"]
  },
  "cursor": {
    "plugins": [
      { "name": "shadcn", "publisher": "cursor-public", "optional": true }
    ]
  },
  "settings": {
    "eslint.useFlatConfig": true
  }
}
  • extensions.recommend → .vscode/extensions.json recommendations (VS Code/Cursor prompt to install).
  • extensions.unwanted → unwantedRecommendations (discourage irrelevant global extensions).
  • cursor.plugins → resolved under $CURSOR_HOME/plugins/cache/<publisher>/<name>/<hash>/ by load-workspace-plugins.mjs on workspaceOpen (Cursor hooks).
  • settings → merged over .editor/defaults.settings.json into .vscode/settings.json.

Step 3: Generate

pnpm editor:sync
# or: node scripts/sync-editor-profile.mjs

Never hand-edit generated .vscode/settings.json long-term — change profile.json and re-sync.

Formatter / extension settings (important)

Cursor validates editor.defaultFormatter against installed extensions only. If ESLint is only recommended but not installed, use built-ins in profile.settings:

  • vscode.typescript-language-features — TS/JS format
  • vscode.json-language-features — JSON

Put extension-only keys in .editor/profile.extensions.json (merged by editor:sync only when that extension exists under ~/.cursor/extensions/). Example: Biome (biomejs.biome) for lint + format instead of ESLint.


Step 4: Good defaults (baseline)

defaults.settings.json already sets:

  • 2-space indent, final newline, trim whitespace
  • File nesting for package.json / lockfiles / configs
  • TypeScript import preferences and move-update-imports
  • Sensible git/terminal defaults

Override per project in profile.settings only when needed (e.g. eslint.useFlatConfig, Tailwind v4 experimental.configFile, Playwright reuse browser).

Override per project in profile.settings (e.g. Biome formatter, workspace TypeScript SDK, .next excludes, Tailwind v4 config path).


Step 5: Cursor vs VS Code

FeatureVS Code / CursorNotes
Workspace settings.vscode/settings.jsonSame JSON schema
Extension recommendations.vscode/extensions.jsonCursor uses same file
Cursor marketplace plugins.cursor/hooks.json + load-workspace-plugins.mjsRequires plugin installed in Cursor once; hook loads cache path per workspace
User settings~/.config/Cursor/User/settings.jsonGlobal — do not duplicate project overrides here

Optional: symlink agent skills into .cursor/skills/ or .agents/skills/ per your project's agent docs.


Step 6: New project / extend

  1. Copy .editor/defaults.settings.json and scripts/sync-editor-profile.mjs, scripts/load-workspace-plugins.mjs.
  2. Add "editor:sync": "node scripts/sync-editor-profile.mjs" to package.json.
  3. Author .editor/profile.json from stack table above.
  4. Run pnpm editor:sync and commit outputs.

For monorepos, use one profile at the root or per-package profiles with separate sync invocations (node scripts/sync-editor-profile.mjs from each package after adjusting paths — extend script if needed).


Anti-patterns

  • Putting project-only settings in global Cursor settings.json
  • Recommending every extension you personally use globally
  • Hand-editing .vscode/settings.json without updating profile.json
  • Listing Cursor plugins in profile.json that were never installed from the marketplace (use "optional": true or install first)
  • Running npm audit fix inside ~/.cursor/extensions (audit-ide-dependencies)

Related skills

  • audit-ide-dependencies — audit extension/plugin CVEs under ~/.cursor
  • fix-dependency-security — project pnpm audit, SFW installs

References

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.