Skip to content

feat: scan workers using cli - #68

Merged
aidanhibbard merged 2 commits into
mainfrom
feat/cli-list-workers
Jul 19, 2026
Merged

feat: scan workers using cli#68
aidanhibbard merged 2 commits into
mainfrom
feat/cli-list-workers

Conversation

@aidanhibbard

Copy link
Copy Markdown
Owner

Summary

List what workers will be picked up via the cli with support for workers flag.

Changes

  • Adds workers list command to CLI
  • Provides JSON output of workers that will be picked up by the module

How to Test

  1. Create worker files
  2. Run the CLI command
  3. Validate output

Screenshots (optional)

n/a

Linked Issues

Closes #64

Checklist

  • I read CONTRIBUTING.md and agree to the Code of Conduct
  • I tested these changes locally
  • Added/updated tests if needed
  • Updated docs (README/docs) if needed
  • npm run ci passes (or npm run lint and npm test at minimum)
  • No breaking changes, or I documented them above

@aidanhibbard aidanhibbard self-assigned this Jul 19, 2026
@aidanhibbard aidanhibbard added the enhancement New feature or request label Jul 19, 2026
@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@aidanhibbard, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 54 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6a232539-b936-4454-a418-ca81982dcaf9

📥 Commits

Reviewing files that changed from the base of the PR and between 41a1c73 and d6996ff.

📒 Files selected for processing (2)
  • spec/cli.spec.ts
  • src/utils/parse-worker-definition.ts
📝 Walkthrough

Walkthrough

This change adds worker-file discovery and source parsing utilities, builds validated worker manifests with effective options, exposes workers list CLI output, supports worker filtering, and rejects duplicate worker names during build and generated worker startup.

Changes

Worker manifest and discovery

Layer / File(s) Summary
Worker discovery and definition parsing
src/utils/parse-worker-definition.ts, src/utils/scan-worker-files.ts, src/utils/scan-folder.ts, spec/utils/parse-worker-definition.spec.ts, spec/utils/scan-worker-files.spec.ts
Worker files are discovered using configurable glob patterns and parsed for names and supported numeric options.
Manifest construction and duplicate validation
src/utils/build-worker-manifest.ts, spec/utils/build-worker-manifest.spec.ts
Worker definitions are converted into manifest entries with BullMQ defaults, effective options, selection filtering, and duplicate-name validation.
Workers list CLI and output
src/cli.ts, src/utils/cli/*, spec/cli.spec.ts, docs/api.md
The new workers list command loads processor settings, builds a manifest, supports --workers, and prints JSON or formatted output.
Build and startup duplicate enforcement
src/module.ts, src/utils/generate-workers-entry-content.ts, spec/utils/generate-workers-entry-content.spec.ts, changelog.md
Duplicate worker names now produce build errors or terminate generated worker startup, with the behavior documented in the changelog.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant NuxtConfig
  participant buildWorkerManifest
  participant printWorkersManifest
  CLI->>NuxtConfig: load processor configuration
  CLI->>buildWorkerManifest: build filtered or complete manifest
  buildWorkerManifest-->>CLI: return WorkerManifest
  CLI->>printWorkersManifest: print JSON or formatted output
Loading

Possibly related PRs

Poem

A bunny finds workers, one by one,
With names and options neatly spun.
JSON hops from the command-line gate,
While duplicate names meet their fate.
“Builds are tidy!” the rabbit sings,
And wiggles both its ears and wings.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Linked Issues check ❓ Inconclusive Issue #64 is mostly covered, but build-time manifest emission and missing-worker failure can't be verified from the provided summary. Add or summarize the code paths that emit the manifest during production builds and preserve --workers= missing-worker failure.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and matches the main change: adding a workers CLI command.
Description check ✅ Passed The PR description follows the template and includes summary, changes, testing, linked issue, and checklist sections.
Out of Scope Changes check ✅ Passed All changes relate to the workers manifest CLI, build validation, docs, or tests; no unrelated scope is evident.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/cli-list-workers

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@aidanhibbard
aidanhibbard merged commit 1d1fea1 into main Jul 19, 2026
2 of 3 checks passed
@aidanhibbard
aidanhibbard deleted the feat/cli-list-workers branch July 19, 2026 23:24

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/utils/generate-workers-entry-content.ts (1)

45-50: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Reuse registeredWorkers to simplify logic.

Since registeredWorkers is already derived from api.workers on line 26, you can reuse it here to avoid redundant array-type checks and simplify the code.

♻️ Proposed refactor
-const workersToRun = selectedWorkers
-  ? (Array.isArray(api.workers) ? api.workers.filter(w => w && selectedWorkers.includes(w.name)) : [])
-  : (Array.isArray(api.workers) ? api.workers : [])
-if (selectedWorkers && workersToRun.length === 0) {
-  const available = (Array.isArray(api.workers) ? api.workers.map(w => w && w.name).filter(Boolean) : [])
+const workersToRun = selectedWorkers
+  ? registeredWorkers.filter(w => w && selectedWorkers.includes(w.name))
+  : registeredWorkers
+if (selectedWorkers && workersToRun.length === 0) {
+  const available = registeredWorkers.map(w => w && w.name).filter(Boolean)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/generate-workers-entry-content.ts` around lines 45 - 50, Update the
workers selection and warning logic around registeredWorkers to reuse that
already-normalized collection instead of repeatedly checking and reading
api.workers. Filter registeredWorkers for selectedWorkers and derive the
available worker names from registeredWorkers while preserving the existing
no-match warning behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@spec/cli.spec.ts`:
- Line 285: Fix the implicit any errors in both stdoutSpy.mock.calls map
callbacks: annotate each call parameter as unknown[] at spec/cli.spec.ts lines
285-285 and 304-304, while preserving the existing String(call[0]) behavior.

In `@src/utils/parse-worker-definition.ts`:
- Around line 84-93: Update extractWorkerName and extractPropertyObjectLiteral
to locate name and options through the existing parseTopLevelObject helper
rather than regex-scanning nested source text, preserving null when the
top-level property is absent. In the related parseStringLiteral logic, adjust
the return at match[2] so it satisfies the declared string | null type,
including an appropriate null fallback for an unavailable capture.

---

Nitpick comments:
In `@src/utils/generate-workers-entry-content.ts`:
- Around line 45-50: Update the workers selection and warning logic around
registeredWorkers to reuse that already-normalized collection instead of
repeatedly checking and reading api.workers. Filter registeredWorkers for
selectedWorkers and derive the available worker names from registeredWorkers
while preserving the existing no-match warning behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9d394a97-5564-4f89-9e7e-09ffb4274bd2

📥 Commits

Reviewing files that changed from the base of the PR and between a976db1 and 41a1c73.

⛔ Files ignored due to path filters (1)
  • spec/utils/__snapshots__/generate-workers-entry-content.spec.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (16)
  • changelog.md
  • docs/api.md
  • spec/cli.spec.ts
  • spec/utils/build-worker-manifest.spec.ts
  • spec/utils/generate-workers-entry-content.spec.ts
  • spec/utils/parse-worker-definition.spec.ts
  • spec/utils/scan-worker-files.spec.ts
  • src/cli.ts
  • src/module.ts
  • src/utils/build-worker-manifest.ts
  • src/utils/cli/print-workers-manifest.ts
  • src/utils/cli/resolve-processor-options.ts
  • src/utils/generate-workers-entry-content.ts
  • src/utils/parse-worker-definition.ts
  • src/utils/scan-folder.ts
  • src/utils/scan-worker-files.ts

Comment thread spec/cli.spec.ts Outdated
Comment on lines +84 to +93
function extractPropertyObjectLiteral(objectLiteral: string, propertyName: string): string | null {
const pattern = new RegExp(`\\b${propertyName}:\\s*\\{`)
const match = pattern.exec(objectLiteral)
if (!match) {
return null
}

const openBraceIndex = objectLiteral.indexOf('{', match.index)
return extractObjectLiteral(objectLiteral, openBraceIndex)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

extractWorkerName/extractPropertyObjectLiteral aren't scoped to top-level keys, risking wrong name/options extraction.

Both helpers run a plain regex .match()/.exec() over the entire objectLiteral text, which includes the body of nested functions/objects (e.g. processor). If a name: or options:-shaped literal appears earlier in the source than the true top-level property (e.g. a fallback object inside processor containing { name: 'unknown' }), the wrong value is picked — silently mis-extracting the worker's identity. Given that parsed.name feeds duplicate-name detection and the manifest (per build-worker-manifest.ts's collectWorkerEntries, which uses parsed.name/parsed.options), this is a correctness risk for a core PR acceptance criterion.

The file already has parseTopLevelObject, which correctly respects nesting depth — reuse it instead of blind regex search for name/options.

Additionally, line 246 (return match[2]) has the same string | undefined vs string | null TS error as flagged for parseStringLiteral.

♻️ Proposed refactor
-function extractWorkerName(objectLiteral: string): string | null {
-  const match = objectLiteral.match(/\bname:\s*(['"`])([^'"`]+)\1/)
-  if (!match) {
-    return null
-  }
-  return match[2]
-}
-
 export function parseWorkerDefinition(source: string): ParsedWorkerDefinition | null {
   const callIndex = findDefineWorkerCallIndex(source)
   if (callIndex === -1) {
     return null
   }

   const afterCall = source.slice(callIndex)
   const openParenIndex = afterCall.indexOf('(')
   if (openParenIndex === -1) {
     return null
   }

   const argsStart = afterCall.slice(openParenIndex + 1)
   const openBraceIndex = argsStart.indexOf('{')
   if (openBraceIndex === -1) {
     return null
   }

   const objectLiteral = extractObjectLiteral(argsStart, openBraceIndex)
   if (!objectLiteral) {
     return null
   }

-  const name = extractWorkerName(objectLiteral)
+  const topLevel = parseTopLevelObject(objectLiteral)
+  const nameValue = topLevel.get('name')
+  const name = nameValue ? parseStringLiteral(nameValue) : null
   if (!name) {
     return null
   }

-  const optionsLiteral = extractPropertyObjectLiteral(objectLiteral, 'options')
-  const options = optionsLiteral ? parseOptionsObject(optionsLiteral) : {}
+  const optionsValue = topLevel.get('options')
+  const options = optionsValue ? parseOptionsObject(optionsValue) : {}

   return { name, options }
 }

Also applies to: 241-282

🧰 Tools
🪛 ast-grep (0.44.1)

[warning] 84-84: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(\\b${propertyName}:\\s*\\{)
Note: [CWE-1333] Inefficient Regular Expression Complexity

(regexp-from-variable)

🪛 OpenGrep (1.25.0)

[ERROR] 86-86: Dynamic command passed to child_process.exec/execSync. Use child_process.execFile or spawn with an argument array instead.

(coderabbit.command-injection.exec-js)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/parse-worker-definition.ts` around lines 84 - 93, Update
extractWorkerName and extractPropertyObjectLiteral to locate name and options
through the existing parseTopLevelObject helper rather than regex-scanning
nested source text, preserving null when the top-level property is absent. In
the related parseStringLiteral logic, adjust the return at match[2] so it
satisfies the declared string | null type, including an appropriate null
fallback for an unavailable capture.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add nuxt-processor workers list --json and build-time manifest

1 participant