packages-worker — Add a New Sub-worker
SkillDev toolsScaffolds a new sub-worker in the packages_worker codebase following its multi-entry-point structure.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the packages-worker — Add a New Sub-worker skill
About this capability
Scaffold a new sub-worker inside packages_worker (npm, deps.dev, osv, scorecard, etc.) following the single-service multi-entry-point structure. Use when: "add a new packages worker", "scaffold a sub-worker in packages_worker", "new worker for packages-db", "add npm worker", "add OSV worker", "add d
What this skill tells your AI
The instructions your AI receives, as published by linuxfoundation/crowd.dev in .claude/skills/packages-worker-add-entrypoint/SKILL.md and read by ahel’s review.
You are adding a new data-ingestion worker to services/apps/packages_worker/.
The structure follows the same pattern as backend/ (where api.ts and
job-generator.ts share one Dockerfile): one npm package, one Docker image,
each worker in its own src/{worker}/ directory with its own entry point.
services/apps/packages_worker/
src/
bin/
github-repos-enricher.ts ← existing worker
<name>.ts ← entry point you will create
github/ ← existing worker logic
<worker>/ ← directory you will create
index.ts ← main logic for this worker
types.ts
config.ts ← shared — add your config getter here
db.ts ← shared — do not modify
Step 1 — Gather requirements
Ask the engineer for:
- Worker name (kebab-case) — e.g.
npm-sync,osv-sync,scorecard-runner. Used as the entry point filename (src/bin/<name>.ts) and docker-compose service name. - Worker directory name (short, lowercase) — e.g.
npm,osv,scorecard. Becomessrc/<worker>/. - What it does — what data it fetches/writes, what table(s) in packages-db it reads from and writes to.
- External API or data source (if any) — URL, auth method, rate-limit characteristics.
- Required env vars beyond the shared DB vars — e.g.
NPM_API_URL,OSV_API_KEY.
Do not proceed until you have answers to 1–3.
Step 2 — Read existing files first
cat services/apps/packages_worker/src/bin/github-repos-enricher.ts
cat services/apps/packages_worker/src/config.ts
cat services/apps/packages_worker/package.json
cat scripts/services/github-repos-enricher.yaml
These are the canonical references. Do not deviate from the patterns you see there.
Step 3 — Scaffold the files
3a. Worker directory — services/apps/packages_worker/src/<worker>/
Create the directory with at minimum:
types.ts — types specific to this worker (input/output shapes, error kinds if calling an external API).
index.ts — the main logic function(s) this worker runs. What goes here depends entirely on what the worker does — do not force a loop shape if it does not fit. Discuss with the engineer what the execution model should be (continuous loop, one-shot batch, event-driven, etc.) and implement accordingly.
Add any additional files the worker needs (e.g. an API client, a DB query helper). All DB access uses inline pg-promise SQL via qx.select / qx.result / qx.none — do not add files to services/libs/data-access-layer.
3b. Entry point — services/apps/packages_worker/src/bin/<name>.ts
Follow the structure of github-repos-enricher.ts:
- Import
getServiceLoggerfrom@crowd/logging - Import your worker's config getter from
../configandgetPackagesDbfrom../db - Import your worker's main function from
../<worker>/index - Set
liveFilePath/readyFilePathto../tmp/<name>-live.tmp/../tmp/<name>-ready.tmp - Handle SIGINT / SIGTERM with a
shuttingDownflag - In
main(): call config getter → validate any required tokens/keys →await getPackagesDb()→await qx.selectOne('SELECT 1')→fs.mkdirSyncfor the tmp dir →setIntervalwriting probe files every 5000ms → call your worker's main function →clearInterval→process.exit(0) - Fatal handler:
main().catch(err => { log.error({ err }, '<name> fatal error'); process.exit(1) })
3c. Config additions — services/apps/packages_worker/src/config.ts
Read the file first, then add a get<Worker>Config() function:
- Use
requireEnv(name)for string vars,requireEnvInt(name)for integers - No defaults, no
?? undefined— the process must refuse to start on missing config
3d. Docker-compose service — scripts/services/<name>.yaml
Copy scripts/services/github-repos-enricher.yaml and adapt:
- Service names:
<name>(prod) and<name>-dev(dev) command(prod):pnpm run start:<name>command(dev):pnpm run dev:<name>env_file: keep the same four files (backend/.env.dist.local,backend/.env.dist.composed,backend/.env.override.local,backend/.env.override.composed)environment: set any tuning var defaults inline (avoids requiring them in.env.override.localfor local dev)volumes(dev only): bind-mount./services/apps/packages_worker/srcplus everyservices/libs/*/srcdirectory (copy the full list from the enricher yaml for hot reload)
3e. package.json scripts — services/apps/packages_worker/package.json
Read the file first, then add:
"start:<name>": "tsx src/bin/<name>.ts",
"dev:<name>": "tsx watch src/bin/<name>.ts"
3f. Env var files — backend/.env.dist.local and backend/.env.dist.composed
Append new required vars with empty-string defaults (or sensible local values for non-secrets):
NEW_WORKER_API_KEY=
Step 4 — TypeScript check
cd services/apps/packages_worker && pnpm tsc --noEmit
Fix any errors before proceeding.
Checklist before committing
-
src/<worker>/directory created withtypes.tsandindex.ts -
src/bin/<name>.ts— probe files, SIGINT/SIGTERM handler, fail-fast config check,SELECT 1on startup -
config.ts— newget<Worker>Config()usingrequireEnv/requireEnvInt, no defaults -
scripts/services/<name>.yaml— prod + dev services with bind mounts -
package.json—start:<name>anddev:<name>scripts added -
backend/.env.dist.localand.env.dist.composed— new vars documented - No new files in
services/libs/data-access-layer(packages-db uses inline SQL) -
pnpm tsc --noEmitpasses
Use /preflight before opening a PR and /commit to sign off.
Signals
- GitHub stars
- 3k
- Forks
- 727
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
packages-worker-add-entrypoint- Source
- github.com/linuxfoundation/crowd.dev