@freshworks/shiftleft-tools
v1.1.15
Published
CLI for managing Cursor rules/skills and Postman test infrastructure across Java Spring Boot and Node.js/Express projects
Readme
shiftleft-tools
CLI for setting up Cursor rules, AI skills, and Postman/Newman test infrastructure across Freshworks Java Spring Boot and Node.js/Express services.
Works with both Cursor IDE and Claude Code.
Quick Start
# 1. Install the CLI (one-time) — see Installation below
npm install -g @freshworks/shiftleft-tools
# 2. Navigate to your service repo
cd /path/to/your-service
# 3. Initialize rules and skills (auto-detects Java or Node)
shiftleft init-rules
# 4. Initialize Postman tests (auto-detects stack from pom.xml or package.json)
shiftleft init-postman --name your-service --with-stagingAfter setup, use skills in Cursor or Claude Code:
/setup-test-pipeline— full test pipeline from scratch/setup-api-tests— set up Postman test infrastructure/write-api-tests GET /apps— write tests for a specific endpoint/run-test-suite— run unit, mutation, or API tests/review-test-suite— validate test suite quality
Installation
Requirements: Node.js ≥ 18 and bash ≥ 4 (shiftleft test runs scripts
that use associative arrays / ${x^^} / mapfile). macOS ships bash 3.2 — install
a newer one with brew install bash. shiftleft test locates a bash ≥ 4
automatically and fails with a clear message if none is found.
The CLI is published to the public npm registry as the scoped package
@freshworks/shiftleft-tools:
npm install -g @freshworks/shiftleft-toolsCI / build agents need the package installed globally too (the
run-all.shshim execsshiftleft test). Bake it into the agent image, or install it in the pipeline. The providedJenkinsfile-{java,node}templates include an idempotentensureShiftleftCli()step. Example pipeline step:sh '''#!/bin/bash --login command -v shiftleft >/dev/null 2>&1 || npm install -g @freshworks/shiftleft-tools '''Run this before any stage that calls
run-all.sh/shiftleft test/stage-scripts.
Local development
git clone https://github.com/freshdesk/shiftleft-tools.git
cd dev-tools
npm install
npm linkVerify installation
shiftleft --versionUsage
Claude Code skills: install the plugin (once per machine)
Claude Code skills are delivered as a plugin, not copied into each repo — so they update everywhere when you update the plugin, with no per-repo step.
# in Claude Code
/plugin install https://github.com/freshdesk/shiftleft-toolsInitialize Cursor Rules & Skills
Cursor reads .cursor/, so init-rules symlinks that repo's Cursor skills
and rules to the installed @freshworks/shiftleft-tools package. A
npm i -g @freshworks/shiftleft-tools@latest then updates every linked repo at once.
The symlinks are gitignored (machine-local pointers), so each developer runs
shiftleft link (or init-rules) once after cloning.
cd your-service
shiftleft init-rulesOptions:
--force, -f- Overwrite existing managed files--skip-skills- Link rules only, not Cursor skills--stack <java|node>- Project stack (auto-detected frompom.xmlorpackage.json)--copy- Copy assets instead of symlinking (locked-down environments / Windows without symlink permission)
This creates:
.cursor/
├── rules/
│ ├── testing.mdc -> (symlink) package rule for your stack
│ └── local-test-setup.mdc -> (symlink) Java only
└── skills/ -> (symlink) package skills directory
.gitignore # symlink paths added here (not committed)Skill routing and security guardrails live in the skills themselves
(skills/_shared/guardrails.md) — no per-repo CLAUDE.md / AGENTS.md is written.
Migrating from an older version? A committed
.claude/skills/directory is no longer needed — install the plugin and delete it.shiftleft doctorflags it.
Link / relink Cursor assets
shiftleft link # (re)create the Cursor symlinks
shiftleft link --copy # copy instead of symlinkInitialize Postman Test Infrastructure
Set up Postman/Newman testing for your project:
cd your-service
# Auto-detect stack (pom.xml → Java, package.json → Node)
shiftleft init-postman
# Explicit stack
shiftleft init-postman --stack java --with-staging
shiftleft init-postman --stack node --with-stagingOptions:
--force, -f- Overwrite existing files--name, -n <name>- Service name (inferred frompom.xmlorpackage.jsonif not provided)--stack <java|node>- Project stack (auto-detected if omitted)--with-staging- Include staging environment, JWT scripts, and AWS config
Committed (repo-owned scaffold + entrypoint):
postman/
├── package.json
├── collections/ # your test collections
├── config/local.json # URLs, ports, auth — yours to edit
├── environments/
├── mocks/ # Node: nock stubs (repo-owned)
└── scripts/
├── run-all.sh # thin shim → `shiftleft test` (do not edit)
├── setup-mocks.js # Node: app-runtime mocks (repo-owned)
└── wiremock/mappings/ # Java: your WireMock stubsStaged from the package (gitignored, machine-local cache):
postman/scripts/
├── .run-all-impl.sh # the real orchestrator
├── lib/ runners/ report-generators/
├── auth/ infra/ # Java
└── database/ # NodeThe library scripts are not vendored: shiftleft test (and the run-all.sh
shim) re-stages them from the installed package before every run, so
npm i -g @freshworks/shiftleft-tools@latest changes test behavior in every repo
with no repo commits. CI agents need the package installed globally.
Also at repo root for Node: stryker.config.js, requirements.txt
Reference Node implementation: freshapps_api_node
Run the test suite
shiftleft test # stage latest scripts + run everything
shiftleft test --skip-unit --no-delay # all orchestrator flags pass through
postman/scripts/run-all.sh --env local # same thing, via the committed shim
shiftleft stage-scripts # stage only (before calling staged scripts directly)Protect a customized library script
Staging overwrites library scripts from the package on every run. If your repo
has customized one (e.g. a service-specific runners/run-tests-local.sh), mark
it protected so staging leaves it alone:
shiftleft protect runners/run-tests-local.sh runners/run-tests-staging.sh
shiftleft protect --list # show protected paths
shiftleft protect --remove runners/run-tests-local.shProtected paths (relative to postman/scripts/) are recorded under protected
in .shiftleft.json and excluded from shiftleft test / stage-scripts. Keep
the protected files committed (or gitignore-excepted) so they survive a fresh
clone — staging won't recreate them. shiftleft doctor lists them.
Update to Latest Version
shiftleft update # Update everything
shiftleft update --rules # Rules only
shiftleft update --skills # Skills only
shiftleft update --postman # Postman scripts only
shiftleft update --force # Overwrite locally-edited files tooUpdates are tracked in a .shiftleft.json manifest (committed). Files you've
edited locally are never silently overwritten — update writes a
<file>.shiftleft-new beside them instead. Repo-owned scaffold (config,
collections, environments) is left untouched unless you pass --force.
For repos set up before the staged-scripts model, update --postman converts
the committed run-all.sh to the shim, prunes the now-unvendored library
scripts from the manifest, and adds the cache paths to postman/.gitignore.
The old committed library files keep working until you git rm -r them.
Check for drift
shiftleft doctor # Report version/file drift vs. latest
shiftleft doctor --check # Exit 1 if stale/drifted (for CI)
shiftleft doctor --json # Machine-readable reportAudit & Scaffold Pipeline
shiftleft setup-pipeline # Audit gaps and copy missing scripts
shiftleft setup-pipeline -y # Skip confirmationWhat's Included
Cursor Rules
| Rule | Stack | Description |
|------|-------|-------------|
| testing.mdc | Java | PIT mutation survival, strong JUnit assertions |
| testing.mdc | Node | Stryker survival, strong Chai assertions (from testing-node.mdc) |
| local-test-setup.mdc | Java | H2 config, WireMock, Flyway for local tests |
Skills (Cursor IDE + Claude Code)
| Skill | Invoke | Description |
|-------|--------|-------------|
| setup-test-pipeline | /setup-test-pipeline | Full pipeline: unit, coverage, mutation, Postman, Jenkins |
| setup-api-tests | /setup-api-tests | Postman/Newman infrastructure from scratch |
| write-api-tests | /write-api-tests [METHOD /path] | Write Postman tests for specific endpoints |
| setup-mutation-tests | /setup-mutation-tests | PIT (Java) or Stryker (Node) |
| run-test-suite | /run-test-suite | Run unit, mutation, Postman, or API coverage |
| review-test-suite | /review-test-suite | 20-point test maturity checklist |
| enhance-test-pipeline | /enhance-test-pipeline | Audit existing repo and fill gaps |
Skills auto-detect stack from pom.xml (Java) or package.json (Node).
Test Commands
Java (Spring Boot)
| Command | Description |
|---------|-------------|
| mvn test | Unit tests |
| cd postman/scripts && ./runners/run-tests-local.sh | Postman API tests (local) |
| ./postman/scripts/report-generators/java-api-coverage-matrix.sh | API coverage report |
| ./postman/scripts/report-generators/mutation-report.sh | PIT mutation testing (target: 80%+) |
| cd postman/scripts && ./run-all.sh | Full test suite |
Node.js (Express)
| Command | Description |
|---------|-------------|
| yarn unit-tests | Unit tests + nyc coverage |
| yarn mutation-tests | Stryker (changed files vs origin/master) |
| yarn mutation-tests:full | Stryker full scan (CI) |
| cd postman/scripts && ./runners/run-tests.sh local | Postman API tests (local) |
| ./postman/scripts/report-generators/node-api-coverage-matrix.sh ./src/controllers ./postman | API coverage |
| cd postman/scripts && ./run-all.sh | Full test suite |
Before Merge Checklist
Java:
mvn test
cd postman/scripts && ./runners/run-tests-local.sh
./postman/scripts/report-generators/java-api-coverage-matrix.sh
./postman/scripts/report-generators/mutation-report.shNode:
yarn unit-tests
cd postman/scripts && ./runners/run-tests.sh local
./postman/scripts/report-generators/node-api-coverage-matrix.sh ./src/controllers ./postman
yarn mutation-tests:fullOr run everything at once (either stack):
cd postman/scripts && ./run-all.shWhat Cursor Learns from Rules
The rules teach Cursor to:
- Write strong unit tests — No weak assertions (
assertNotNull(),expect(x).to.existwithout value checks) - Survive mutation testing — PIT (Java) or Stryker (Node); weak tests that pass with mutated code are flagged
- Test all output fields — If a method returns 5 fields, assert on all 5
- Follow Postman best practices — Single status assertion per test, cover query params, document skips
Development
Building
npm installTesting Locally
npm link
cd /path/to/test/project
shiftleft init-rules
shiftleft init-postmanDistributing a new version
npm version patch|minor|major
npm pack
# Generates: freshworks-shiftleft-tools-x.x.x.tgzRequirements
- Node.js 18+ and npm 8.4+ (for the CLI and Postman/Newman runner)
- Java projects: Java 21+, Maven
- Node projects: Yarn (recommended), Mocha, nyc, Stryker
- AWS CLI (for staging Postman tests with JWT from Secrets Manager)
License
UNLICENSED - Internal use only
