@freshworks/shiftleft-tools 1.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/README.md +351 -0
  2. package/bin/shiftleft.js +95 -0
  3. package/package.json +57 -0
  4. package/src/commands/doctor.js +208 -0
  5. package/src/commands/init-postman.js +298 -0
  6. package/src/commands/init-rules.js +78 -0
  7. package/src/commands/link.js +172 -0
  8. package/src/commands/protect.js +61 -0
  9. package/src/commands/run-tests.js +182 -0
  10. package/src/commands/setup-pipeline.js +209 -0
  11. package/src/commands/update.js +203 -0
  12. package/src/index.js +4 -0
  13. package/src/utils/copy-tree.js +98 -0
  14. package/src/utils/gitignore.js +26 -0
  15. package/src/utils/logger.js +9 -0
  16. package/src/utils/manifest.js +145 -0
  17. package/src/utils/stack.js +80 -0
  18. package/src/utils/template.js +135 -0
  19. package/templates/AGENTS.md +109 -0
  20. package/templates/CLAUDE.md +3 -0
  21. package/templates/jenkins/Jenkinsfile-java.groovy +432 -0
  22. package/templates/jenkins/Jenkinsfile-node.groovy +450 -0
  23. package/templates/postman/.husky/pre-commit +19 -0
  24. package/templates/postman/.prettierrc.json +5 -0
  25. package/templates/postman/README.md.ejs +147 -0
  26. package/templates/postman/collections/01-core.json.ejs +91 -0
  27. package/templates/postman/config/local.json.ejs +12 -0
  28. package/templates/postman/config/staging.json.ejs +26 -0
  29. package/templates/postman/environments/local.postman_environment.json.ejs +31 -0
  30. package/templates/postman/environments/staging.postman_environment.json.ejs +31 -0
  31. package/templates/postman/gitignore +16 -0
  32. package/templates/postman/npmrc +31 -0
  33. package/templates/postman/package.json.ejs +66 -0
  34. package/templates/postman/run-all-shim.sh +16 -0
  35. package/templates/postman/scripts/auth/generate-jwt.sh +113 -0
  36. package/templates/postman/scripts/auth/get-issuer-secret.sh +140 -0
  37. package/templates/postman/scripts/infra/start-mocks.sh +138 -0
  38. package/templates/postman/scripts/infra/stop-mocks.sh +43 -0
  39. package/templates/postman/scripts/lib/api_coverage.py +1122 -0
  40. package/templates/postman/scripts/lib/cleanup-reports.sh +101 -0
  41. package/templates/postman/scripts/lib/cleanup-stryker.sh +44 -0
  42. package/templates/postman/scripts/lib/report_combined.py +527 -0
  43. package/templates/postman/scripts/lib/report_consolidated.py +363 -0
  44. package/templates/postman/scripts/lib/report_generator.py +121 -0
  45. package/templates/postman/scripts/lib/report_migration.py +156 -0
  46. package/templates/postman/scripts/lib/report_mutation.py +110 -0
  47. package/templates/postman/scripts/lib/report_unit.py +353 -0
  48. package/templates/postman/scripts/lib/report_utils.py +973 -0
  49. package/templates/postman/scripts/report-generators/generate-consolidated-report.sh +445 -0
  50. package/templates/postman/scripts/report-generators/java-api-coverage-matrix.sh +257 -0
  51. package/templates/postman/scripts/report-generators/mutation-report.sh +672 -0
  52. package/templates/postman/scripts/report-generators/node-api-coverage-matrix.sh +167 -0
  53. package/templates/postman/scripts/report-generators/stage-report-artifacts.sh +27 -0
  54. package/templates/postman/scripts/run-all.sh +452 -0
  55. package/templates/postman/scripts/runners/run-mutation-tests.sh +113 -0
  56. package/templates/postman/scripts/runners/run-tests-local.sh +936 -0
  57. package/templates/postman/scripts/runners/run-tests-staging.sh +741 -0
  58. package/templates/postman-node/README.md.ejs +26 -0
  59. package/templates/postman-node/collections/crud/01-bootstrap.json.ejs +34 -0
  60. package/templates/postman-node/config/local.json.ejs +46 -0
  61. package/templates/postman-node/config/staging.json.ejs +31 -0
  62. package/templates/postman-node/local.test.env.ejs +3 -0
  63. package/templates/postman-node/mocks/external.js +14 -0
  64. package/templates/postman-node/package.json.ejs +39 -0
  65. package/templates/postman-node/requirements.txt +1 -0
  66. package/templates/postman-node/scripts/database/cleanup-mysql.sh +12 -0
  67. package/templates/postman-node/scripts/database/run-migrations.js +29 -0
  68. package/templates/postman-node/scripts/database/start-mysql.sh +34 -0
  69. package/templates/postman-node/scripts/database/wait-for-mysql.sh +36 -0
  70. package/templates/postman-node/scripts/lib/api_coverage_node.py +1137 -0
  71. package/templates/postman-node/scripts/lib/fetch-jwt.sh +86 -0
  72. package/templates/postman-node/scripts/lib/run-newman.sh +104 -0
  73. package/templates/postman-node/scripts/lib/setup-database.sh +55 -0
  74. package/templates/postman-node/scripts/lib/start-app.sh +48 -0
  75. package/templates/postman-node/scripts/lib/utils.sh +114 -0
  76. package/templates/postman-node/scripts/report-generators/stage-report-artifacts.sh +26 -0
  77. package/templates/postman-node/scripts/run-all.sh +303 -0
  78. package/templates/postman-node/scripts/runners/run-tests.sh +123 -0
  79. package/templates/postman-node/scripts/setup-mocks.js.ejs +29 -0
  80. package/templates/postman-node/stryker.config.js.ejs +51 -0
  81. package/templates/rules/local-test-setup.mdc +420 -0
  82. package/templates/rules/testing-node.mdc +66 -0
  83. package/templates/rules/testing.mdc +248 -0
  84. package/templates/skills/_shared/postman-standards.md +380 -0
  85. package/templates/skills/enhance-test-pipeline/SKILL-java.md +483 -0
  86. package/templates/skills/enhance-test-pipeline/SKILL-node.md +431 -0
  87. package/templates/skills/enhance-test-pipeline/SKILL.md +9 -0
  88. package/templates/skills/review-test-suite/SKILL-java.md +137 -0
  89. package/templates/skills/review-test-suite/SKILL-node.md +78 -0
  90. package/templates/skills/review-test-suite/SKILL.md +9 -0
  91. package/templates/skills/run-test-suite/SKILL-java.md +186 -0
  92. package/templates/skills/run-test-suite/SKILL-node.md +191 -0
  93. package/templates/skills/run-test-suite/SKILL.md +9 -0
  94. package/templates/skills/setup-api-tests/SKILL-java.md +1094 -0
  95. package/templates/skills/setup-api-tests/SKILL-node.md +141 -0
  96. package/templates/skills/setup-api-tests/SKILL.md +9 -0
  97. package/templates/skills/setup-mutation-tests/SKILL-java.md +303 -0
  98. package/templates/skills/setup-mutation-tests/SKILL-node.md +408 -0
  99. package/templates/skills/setup-mutation-tests/SKILL.md +9 -0
  100. package/templates/skills/setup-test-pipeline/SKILL-java.md +454 -0
  101. package/templates/skills/setup-test-pipeline/SKILL-node.md +318 -0
  102. package/templates/skills/setup-test-pipeline/SKILL.md +9 -0
  103. package/templates/skills/write-api-tests/SKILL-java.md +115 -0
  104. package/templates/skills/write-api-tests/SKILL-node.md +83 -0
  105. package/templates/skills/write-api-tests/SKILL.md +9 -0
  106. package/templates/stryker.config.js +50 -0
package/README.md ADDED
@@ -0,0 +1,351 @@
1
+ # shiftleft-tools
2
+
3
+ CLI for setting up Cursor rules, AI skills, and Postman/Newman test infrastructure across Freshworks **Java Spring Boot** and **Node.js/Express** services.
4
+
5
+ Works with both **Cursor IDE** and **Claude Code**.
6
+
7
+ ## Quick Start
8
+
9
+ ```bash
10
+ # 1. Install the CLI (one-time) — see Installation below
11
+ npm install -g @freshworks/shiftleft-tools
12
+
13
+ # 2. Navigate to your service repo
14
+ cd /path/to/your-service
15
+
16
+ # 3. Initialize rules and skills (auto-detects Java or Node)
17
+ shiftleft init-rules
18
+
19
+ # 4. Initialize Postman tests (auto-detects stack from pom.xml or package.json)
20
+ shiftleft init-postman --name your-service --with-staging
21
+ ```
22
+
23
+ After setup, use skills in Cursor or Claude Code:
24
+ - `/setup-test-pipeline` — full test pipeline from scratch
25
+ - `/setup-api-tests` — set up Postman test infrastructure
26
+ - `/write-api-tests GET /apps` — write tests for a specific endpoint
27
+ - `/run-test-suite` — run unit, mutation, or API tests
28
+ - `/review-test-suite` — validate test suite quality
29
+
30
+ ## Installation
31
+
32
+ **Requirements:** Node.js ≥ 18 and **bash ≥ 4** (`shiftleft test` runs scripts
33
+ that use associative arrays / `${x^^}` / `mapfile`). macOS ships bash 3.2 — install
34
+ a newer one with `brew install bash`. `shiftleft test` locates a bash ≥ 4
35
+ automatically and fails with a clear message if none is found.
36
+
37
+ The CLI is published to the public npm registry as the scoped package
38
+ [`@freshworks/shiftleft-tools`](https://www.npmjs.com/package/@freshworks/shiftleft-tools):
39
+
40
+ ```bash
41
+ npm install -g @freshworks/shiftleft-tools
42
+ ```
43
+
44
+ > **CI / build agents** need the package installed globally too (the `run-all.sh`
45
+ > shim execs `shiftleft test`). Bake it into the agent image, or install it in the
46
+ > pipeline. The provided `Jenkinsfile-{java,node}` templates include an idempotent
47
+ > `ensureShiftleftCli()` step. Example pipeline step:
48
+ >
49
+ > ```groovy
50
+ > sh '''#!/bin/bash --login
51
+ > command -v shiftleft >/dev/null 2>&1 || npm install -g @freshworks/shiftleft-tools
52
+ > '''
53
+ > ```
54
+ > Run this before any stage that calls `run-all.sh` / `shiftleft test` / `stage-scripts`.
55
+
56
+ ### Local development
57
+
58
+ ```bash
59
+ git clone https://github.com/freshdesk/shiftleft-tools.git
60
+ cd dev-tools
61
+ npm install
62
+ npm link
63
+ ```
64
+
65
+ ### Verify installation
66
+
67
+ ```bash
68
+ shiftleft --version
69
+ ```
70
+
71
+ ## Usage
72
+
73
+ ### Claude Code skills: install the plugin (once per machine)
74
+
75
+ Claude Code skills are delivered as a **plugin**, not copied into each repo — so
76
+ they update everywhere when you update the plugin, with no per-repo step.
77
+
78
+ ```bash
79
+ # in Claude Code
80
+ /plugin install https://github.com/freshdesk/shiftleft-tools
81
+ ```
82
+
83
+ ### Initialize Cursor Rules & Skills
84
+
85
+ Cursor reads `.cursor/`, so `init-rules` **symlinks** that repo's Cursor skills
86
+ and rules to the installed `@freshworks/shiftleft-tools` package. A
87
+ `npm i -g @freshworks/shiftleft-tools@latest` then updates every linked repo at once.
88
+ The symlinks are gitignored (machine-local pointers), so each developer runs
89
+ `shiftleft link` (or `init-rules`) once after cloning.
90
+
91
+ ```bash
92
+ cd your-service
93
+ shiftleft init-rules
94
+ ```
95
+
96
+ Options:
97
+ - `--force, -f` - Overwrite existing `CLAUDE.md` / `AGENTS.md`
98
+ - `--skip-skills` - Link rules only, not Cursor skills
99
+ - `--stack <java|node>` - Project stack (auto-detected from `pom.xml` or `package.json`)
100
+ - `--copy` - Copy assets instead of symlinking (locked-down environments / Windows without symlink permission)
101
+
102
+ This creates:
103
+ ```
104
+ .cursor/
105
+ ├── rules/
106
+ │ ├── testing.mdc -> (symlink) package rule for your stack
107
+ │ └── local-test-setup.mdc -> (symlink) Java only
108
+ └── skills/ -> (symlink) package skills directory
109
+ CLAUDE.md # Skill invocation instructions for Claude Code (real file)
110
+ AGENTS.md # Agent routing and guardrails (real file)
111
+ .gitignore # symlink paths added here (not committed)
112
+ ```
113
+
114
+ > Migrating from an older version? A committed `.claude/skills/` directory is no
115
+ > longer needed — install the plugin and delete it. `shiftleft doctor` flags it.
116
+
117
+ ### Link / relink Cursor assets
118
+
119
+ ```bash
120
+ shiftleft link # (re)create the Cursor symlinks
121
+ shiftleft link --copy # copy instead of symlink
122
+ ```
123
+
124
+ ### Initialize Postman Test Infrastructure
125
+
126
+ Set up Postman/Newman testing for your project:
127
+
128
+ ```bash
129
+ cd your-service
130
+
131
+ # Auto-detect stack (pom.xml → Java, package.json → Node)
132
+ shiftleft init-postman
133
+
134
+ # Explicit stack
135
+ shiftleft init-postman --stack java --with-staging
136
+ shiftleft init-postman --stack node --with-staging
137
+ ```
138
+
139
+ Options:
140
+ - `--force, -f` - Overwrite existing files
141
+ - `--name, -n <name>` - Service name (inferred from `pom.xml` or `package.json` if not provided)
142
+ - `--stack <java|node>` - Project stack (auto-detected if omitted)
143
+ - `--with-staging` - Include staging environment, JWT scripts, and AWS config
144
+
145
+ **Committed (repo-owned scaffold + entrypoint):**
146
+ ```
147
+ postman/
148
+ ├── package.json
149
+ ├── collections/ # your test collections
150
+ ├── config/local.json # URLs, ports, auth — yours to edit
151
+ ├── environments/
152
+ ├── mocks/ # Node: nock stubs (repo-owned)
153
+ └── scripts/
154
+ ├── run-all.sh # thin shim → `shiftleft test` (do not edit)
155
+ ├── setup-mocks.js # Node: app-runtime mocks (repo-owned)
156
+ └── wiremock/mappings/ # Java: your WireMock stubs
157
+ ```
158
+
159
+ **Staged from the package (gitignored, machine-local cache):**
160
+ ```
161
+ postman/scripts/
162
+ ├── .run-all-impl.sh # the real orchestrator
163
+ ├── lib/ runners/ report-generators/
164
+ ├── auth/ infra/ # Java
165
+ └── database/ # Node
166
+ ```
167
+
168
+ The library scripts are *not vendored*: `shiftleft test` (and the `run-all.sh`
169
+ shim) re-stages them from the installed package before every run, so
170
+ `npm i -g @freshworks/shiftleft-tools@latest` changes test behavior in every repo
171
+ with no repo commits. CI agents need the package installed globally.
172
+
173
+ Also at repo root for Node: `stryker.config.js`, `requirements.txt`
174
+
175
+ Reference Node implementation: `freshapps_api_node`
176
+
177
+ ### Run the test suite
178
+
179
+ ```bash
180
+ shiftleft test # stage latest scripts + run everything
181
+ shiftleft test --skip-unit --no-delay # all orchestrator flags pass through
182
+ postman/scripts/run-all.sh --env local # same thing, via the committed shim
183
+ shiftleft stage-scripts # stage only (before calling staged scripts directly)
184
+ ```
185
+
186
+ ### Protect a customized library script
187
+
188
+ Staging overwrites library scripts from the package on every run. If your repo
189
+ has customized one (e.g. a service-specific `runners/run-tests-local.sh`), mark
190
+ it **protected** so staging leaves it alone:
191
+
192
+ ```bash
193
+ shiftleft protect runners/run-tests-local.sh runners/run-tests-staging.sh
194
+ shiftleft protect --list # show protected paths
195
+ shiftleft protect --remove runners/run-tests-local.sh
196
+ ```
197
+
198
+ Protected paths (relative to `postman/scripts/`) are recorded under `protected`
199
+ in `.shiftleft.json` and excluded from `shiftleft test` / `stage-scripts`. Keep
200
+ the protected files **committed** (or gitignore-excepted) so they survive a fresh
201
+ clone — staging won't recreate them. `shiftleft doctor` lists them.
202
+
203
+ ### Update to Latest Version
204
+
205
+ ```bash
206
+ shiftleft update # Update everything
207
+ shiftleft update --rules # Rules only
208
+ shiftleft update --skills # Skills only
209
+ shiftleft update --postman # Postman scripts only
210
+ shiftleft update --force # Overwrite locally-edited files too
211
+ ```
212
+
213
+ Updates are tracked in a `.shiftleft.json` manifest (committed). Files you've
214
+ edited locally are never silently overwritten — `update` writes a
215
+ `<file>.shiftleft-new` beside them instead. Repo-owned scaffold (config,
216
+ collections, environments) is left untouched unless you pass `--force`.
217
+
218
+ For repos set up before the staged-scripts model, `update --postman` converts
219
+ the committed `run-all.sh` to the shim, prunes the now-unvendored library
220
+ scripts from the manifest, and adds the cache paths to `postman/.gitignore`.
221
+ The old committed library files keep working until you `git rm -r` them.
222
+
223
+ ### Check for drift
224
+
225
+ ```bash
226
+ shiftleft doctor # Report version/file drift vs. latest
227
+ shiftleft doctor --check # Exit 1 if stale/drifted (for CI)
228
+ shiftleft doctor --json # Machine-readable report
229
+ ```
230
+
231
+ ### Audit & Scaffold Pipeline
232
+
233
+ ```bash
234
+ shiftleft setup-pipeline # Audit gaps and copy missing scripts
235
+ shiftleft setup-pipeline -y # Skip confirmation
236
+ ```
237
+
238
+ ## What's Included
239
+
240
+ ### Cursor Rules
241
+
242
+ | Rule | Stack | Description |
243
+ |------|-------|-------------|
244
+ | `testing.mdc` | Java | PIT mutation survival, strong JUnit assertions |
245
+ | `testing.mdc` | Node | Stryker survival, strong Chai assertions (from `testing-node.mdc`) |
246
+ | `local-test-setup.mdc` | Java | H2 config, WireMock, Flyway for local tests |
247
+
248
+ ### Skills (Cursor IDE + Claude Code)
249
+
250
+ | Skill | Invoke | Description |
251
+ |-------|--------|-------------|
252
+ | `setup-test-pipeline` | `/setup-test-pipeline` | Full pipeline: unit, coverage, mutation, Postman, Jenkins |
253
+ | `setup-api-tests` | `/setup-api-tests` | Postman/Newman infrastructure from scratch |
254
+ | `write-api-tests` | `/write-api-tests [METHOD /path]` | Write Postman tests for specific endpoints |
255
+ | `setup-mutation-tests` | `/setup-mutation-tests` | PIT (Java) or Stryker (Node) |
256
+ | `run-test-suite` | `/run-test-suite` | Run unit, mutation, Postman, or API coverage |
257
+ | `review-test-suite` | `/review-test-suite` | 20-point test maturity checklist |
258
+ | `enhance-test-pipeline` | `/enhance-test-pipeline` | Audit existing repo and fill gaps |
259
+
260
+ Skills auto-detect stack from `pom.xml` (Java) or `package.json` (Node).
261
+
262
+ ## Test Commands
263
+
264
+ ### Java (Spring Boot)
265
+
266
+ | Command | Description |
267
+ |---------|-------------|
268
+ | `mvn test` | Unit tests |
269
+ | `cd postman/scripts && ./runners/run-tests-local.sh` | Postman API tests (local) |
270
+ | `./postman/scripts/report-generators/java-api-coverage-matrix.sh` | API coverage report |
271
+ | `./postman/scripts/report-generators/mutation-report.sh` | PIT mutation testing (target: 80%+) |
272
+ | `cd postman/scripts && ./run-all.sh` | Full test suite |
273
+
274
+ ### Node.js (Express)
275
+
276
+ | Command | Description |
277
+ |---------|-------------|
278
+ | `yarn unit-tests` | Unit tests + nyc coverage |
279
+ | `yarn mutation-tests` | Stryker (changed files vs origin/master) |
280
+ | `yarn mutation-tests:full` | Stryker full scan (CI) |
281
+ | `cd postman/scripts && ./runners/run-tests.sh local` | Postman API tests (local) |
282
+ | `./postman/scripts/report-generators/node-api-coverage-matrix.sh ./src/controllers ./postman` | API coverage |
283
+ | `cd postman/scripts && ./run-all.sh` | Full test suite |
284
+
285
+ ### Before Merge Checklist
286
+
287
+ **Java:**
288
+ ```bash
289
+ mvn test
290
+ cd postman/scripts && ./runners/run-tests-local.sh
291
+ ./postman/scripts/report-generators/java-api-coverage-matrix.sh
292
+ ./postman/scripts/report-generators/mutation-report.sh
293
+ ```
294
+
295
+ **Node:**
296
+ ```bash
297
+ yarn unit-tests
298
+ cd postman/scripts && ./runners/run-tests.sh local
299
+ ./postman/scripts/report-generators/node-api-coverage-matrix.sh ./src/controllers ./postman
300
+ yarn mutation-tests:full
301
+ ```
302
+
303
+ Or run everything at once (either stack):
304
+ ```bash
305
+ cd postman/scripts && ./run-all.sh
306
+ ```
307
+
308
+ ## What Cursor Learns from Rules
309
+
310
+ The rules teach Cursor to:
311
+
312
+ 1. **Write strong unit tests** — No weak assertions (`assertNotNull()`, `expect(x).to.exist` without value checks)
313
+ 2. **Survive mutation testing** — PIT (Java) or Stryker (Node); weak tests that pass with mutated code are flagged
314
+ 3. **Test all output fields** — If a method returns 5 fields, assert on all 5
315
+ 4. **Follow Postman best practices** — Single status assertion per test, cover query params, document skips
316
+
317
+ ## Development
318
+
319
+ ### Building
320
+
321
+ ```bash
322
+ npm install
323
+ ```
324
+
325
+ ### Testing Locally
326
+
327
+ ```bash
328
+ npm link
329
+ cd /path/to/test/project
330
+ shiftleft init-rules
331
+ shiftleft init-postman
332
+ ```
333
+
334
+ ### Distributing a new version
335
+
336
+ ```bash
337
+ npm version patch|minor|major
338
+ npm pack
339
+ # Generates: freshworks-shiftleft-tools-x.x.x.tgz
340
+ ```
341
+
342
+ ## Requirements
343
+
344
+ - Node.js 18+ and npm 8.4+ (for the CLI and Postman/Newman runner)
345
+ - **Java projects:** Java 21+, Maven
346
+ - **Node projects:** Yarn (recommended), Mocha, nyc, Stryker
347
+ - AWS CLI (for staging Postman tests with JWT from Secrets Manager)
348
+
349
+ ## License
350
+
351
+ UNLICENSED - Internal use only
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { program } from 'commander';
4
+ import { initRules } from '../src/commands/init-rules.js';
5
+ import { initPostman } from '../src/commands/init-postman.js';
6
+ import { update } from '../src/commands/update.js';
7
+ import { doctor } from '../src/commands/doctor.js';
8
+ import { link } from '../src/commands/link.js';
9
+ import { runTests, stageScriptsCommand } from '../src/commands/run-tests.js';
10
+ import { protect } from '../src/commands/protect.js';
11
+ import { setupPipeline } from '../src/commands/setup-pipeline.js';
12
+ import { readFileSync } from 'fs';
13
+ import { fileURLToPath } from 'url';
14
+ import { dirname, join } from 'path';
15
+
16
+ const __filename = fileURLToPath(import.meta.url);
17
+ const __dirname = dirname(__filename);
18
+ const pkg = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf8'));
19
+
20
+ program
21
+ .name('shiftleft')
22
+ .description('CLI for managing Cursor rules/skills and Postman test infrastructure')
23
+ .version(pkg.version);
24
+
25
+ program
26
+ .command('init-rules')
27
+ .description('Link Cursor rules/skills and create CLAUDE.md / AGENTS.md')
28
+ .option('-f, --force', 'Overwrite existing CLAUDE.md / AGENTS.md', false)
29
+ .option('--skip-skills', 'Do not link Cursor skills', false)
30
+ .option('--copy', 'Copy Cursor assets instead of symlinking (locked-down environments)', false)
31
+ .option('--stack <stack>', 'Project stack: java or node (auto-detected if omitted)')
32
+ .action(initRules);
33
+
34
+ program
35
+ .command('init-postman')
36
+ .description('Initialize Postman/Newman test infrastructure')
37
+ .option('-f, --force', 'Overwrite existing files', false)
38
+ .option('-n, --name <name>', 'Service name for the tests')
39
+ .option('--stack <stack>', 'Project stack: java or node (auto-detected if omitted)')
40
+ .option('--with-staging', 'Include staging environment support (JWT, AWS)', false)
41
+ .action(initPostman);
42
+
43
+ program
44
+ .command('update')
45
+ .description('Update rules/skills/postman to latest version')
46
+ .option('--rules', 'Update only rules', false)
47
+ .option('--skills', 'Update only skills', false)
48
+ .option('--postman', 'Update only postman scripts', false)
49
+ .option('-f, --force', 'Overwrite without prompting', false)
50
+ .action(update);
51
+
52
+ program
53
+ .command('test')
54
+ .description('Stage the latest library scripts and run the test orchestrator (all flags pass through)')
55
+ .allowUnknownOption(true)
56
+ .helpOption(false) // forward -h/--help to the orchestrator too
57
+ .argument('[args...]', 'Arguments forwarded to the orchestrator (e.g. --skip-unit --no-delay)')
58
+ .action((args, _options, command) => runTests(command.args));
59
+
60
+ program
61
+ .command('stage-scripts')
62
+ .description('Stage the packaged library scripts into postman/scripts (gitignored cache)')
63
+ .option('--stack <stack>', 'Project stack: java or node (auto-detected if omitted)')
64
+ .action(stageScriptsCommand);
65
+
66
+ program
67
+ .command('protect')
68
+ .description('Mark a library script (relative to postman/scripts/) as repo-owned so staging never overwrites it')
69
+ .argument('[paths...]', 'Paths under postman/scripts (e.g. runners/run-tests-local.sh)')
70
+ .option('--list', 'List protected paths', false)
71
+ .option('--remove', 'Remove the given paths from the protected list', false)
72
+ .action((paths, options) => protect(paths, options));
73
+
74
+ program
75
+ .command('link')
76
+ .description('Link Cursor skills/rules to the installed shiftleft-tools package (symlinks, gitignored)')
77
+ .option('--copy', 'Copy instead of symlinking (locked-down environments)', false)
78
+ .option('--stack <stack>', 'Project stack: java or node (auto-detected if omitted)')
79
+ .action(link);
80
+
81
+ program
82
+ .command('doctor')
83
+ .description('Report whether managed files are up to date, drifted, or missing')
84
+ .option('--check', 'Exit with code 1 if the repo is stale, drifted, or has broken symlinks', false)
85
+ .option('--json', 'Emit a machine-readable report', false)
86
+ .action(doctor);
87
+
88
+ program
89
+ .command('setup-pipeline')
90
+ .description('Audit and scaffold test pipeline (unit, mutation, Postman, coverage, quality report)')
91
+ .option('-f, --force', 'Overwrite existing scripts', false)
92
+ .option('-y, --yes', 'Skip confirmation prompt', false)
93
+ .action(setupPipeline);
94
+
95
+ program.parse();
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@freshworks/shiftleft-tools",
3
+ "version": "1.1.8",
4
+ "description": "CLI for managing Cursor rules/skills and Postman test infrastructure across Java Spring Boot and Node.js/Express projects",
5
+ "type": "module",
6
+ "main": "src/index.js",
7
+ "bin": {
8
+ "shiftleft": "./bin/shiftleft.js"
9
+ },
10
+ "scripts": {
11
+ "test": "node --test",
12
+ "lint": "eslint src bin",
13
+ "format": "prettier --write ."
14
+ },
15
+ "keywords": [
16
+ "cursor",
17
+ "rules",
18
+ "skills",
19
+ "postman",
20
+ "newman",
21
+ "java",
22
+ "spring-boot",
23
+ "testing"
24
+ ],
25
+ "author": "Freshworks Developer Platform Team",
26
+ "license": "UNLICENSED",
27
+ "private": false,
28
+ "engines": {
29
+ "node": ">=18.0.0"
30
+ },
31
+ "dependencies": {
32
+ "chalk": "^5.3.0",
33
+ "commander": "^12.0.0",
34
+ "ejs": "^3.1.10",
35
+ "fs-extra": "^11.2.0",
36
+ "inquirer": "^9.2.15",
37
+ "ora": "^8.0.1"
38
+ },
39
+ "devDependencies": {
40
+ "eslint": "^8.57.0",
41
+ "prettier": "^3.2.5"
42
+ },
43
+ "repository": {
44
+ "type": "git",
45
+ "url": "https://github.com/freshdesk/shiftleft-tools.git"
46
+ },
47
+ "publishConfig": {
48
+ "registry": "https://registry.npmjs.org/",
49
+ "access": "public"
50
+ },
51
+ "files": [
52
+ "bin/",
53
+ "src/",
54
+ "templates/",
55
+ "templates/postman-node/"
56
+ ]
57
+ }