laracrew 0.1.1

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.
@@ -0,0 +1,79 @@
1
+ # Examples
2
+
3
+ Five working stacks. Only one of them is Laravel — laracrew supervises processes, and it does
4
+ not care what language wrote them.
5
+
6
+ Each example is self-contained: projects are declared inline, so there is nothing to wire up in
7
+ `projects.yaml` first. Copy one, change the paths at the top, and run it.
8
+
9
+ ```bash
10
+ cp -r examples/node-api-and-web ~/.laracrew/stacks/
11
+ $EDITOR ~/.laracrew/stacks/node-api-and-web/stack.yaml # fix the paths
12
+ laracrew doctor node-api-and-web
13
+ laracrew up node-api-and-web
14
+ ```
15
+
16
+ Each stack declares a `command:`, so `laracrew link <name>` turns it into a single global word
17
+ you can type from anywhere.
18
+
19
+ | Example | Stack | What it is |
20
+ |---|---|---|
21
+ | [laravel-dual](laravel-dual/stack.yaml) | `dual` | Two interconnected Laravel apps: queues, Redis stream listeners, schedulers, Vite |
22
+ | [node-api-and-web](node-api-and-web/stack.yaml) | `web` | TypeScript API, Vite frontend, BullMQ worker, Postgres and Redis |
23
+ | [django-celery](django-celery/stack.yaml) | `django` | Django, a Celery worker, beat, and the optional extras |
24
+ | [polyglot-microservices](polyglot-microservices/stack.yaml) | `micro` | Go, Rust, Node and Python behind a gateway, with Docker Compose for infrastructure |
25
+ | [frontend-monorepo](frontend-monorepo/stack.yaml) | `fe` | The smallest useful stack: tsc, Tailwind, Storybook and docs watchers in one repo |
26
+
27
+ ## What each one is there to teach
28
+
29
+ **laravel-dual** — the case laracrew was built for. Graceful worker shutdown through
30
+ `php artisan queue:restart`, so a job is never killed mid-flight; the portal waiting on a real
31
+ HTTP 200 from the API rather than a sleep; profiles to skip Vite when you are only touching the
32
+ backend.
33
+
34
+ **node-api-and-web** — no PHP anywhere. A one-shot `types:build` that everything else depends on,
35
+ readiness by log output for tools that announce themselves (`Local: http://…`), per-service
36
+ environment variables, and a secret read from your own shell with `${env:VAR:fallback}` instead
37
+ of being committed.
38
+
39
+ **django-celery** — migrations that must finish before the web server starts, `PYTHONUNBUFFERED`
40
+ so the log pane is not empty, a `SIGTERM` graceful stop for Celery instead of an artisan command,
41
+ and a second worker plus Flower left dormant behind `autostart: false`.
42
+
43
+ **polyglot-microservices** — the ordering problem at full size. `docker compose up` supervised as
44
+ an ordinary process so it stops with everything else; a gateway that starts only once all three
45
+ services answer `/health`; a generous gate on the Rust service because a cold `cargo build` is
46
+ slow, rather than a boot that fails at 30 seconds.
47
+
48
+ **frontend-monorepo** — proof that a "stack" needs neither multiple apps nor a server. Watchers
49
+ in one repository, ordered so types build before Storybook consumes them, with `vitest --watch`
50
+ and `lint:fix` sitting idle until you press `s`.
51
+
52
+ ## Patterns worth stealing
53
+
54
+ **Gate on reality, not on time.** `ready: { http: … }` or `{ tcp: … }` beats a sleep. When a
55
+ build is genuinely slow, raise `timeoutMs` rather than removing the gate.
56
+
57
+ ```yaml
58
+ ready: { http: "http://127.0.0.1:8002/health", timeoutMs: 300000, intervalMs: 2000 }
59
+ ```
60
+
61
+ **Keep the occasional things in the stack, just not running.** A backfill command, a database
62
+ UI, a test watcher — define them with `autostart: false` so they are documented and one keypress
63
+ away, instead of living in your shell history.
64
+
65
+ **Let laracrew own Docker Compose too.** It is a long-running process like any other. Supervised
66
+ here, it stops when the rest of the stack stops.
67
+
68
+ ```yaml
69
+ - name: infra
70
+ cmd: ["docker", "compose", "up"]
71
+ ready: { tcp: "127.0.0.1:5432", timeoutMs: 120000, intervalMs: 1000 }
72
+ stop: { graceMs: 30000 }
73
+ ```
74
+
75
+ **Use the argv form when arguments get interesting.** `cmd: ["npm", "run", "dev"]` cannot
76
+ mis-split on a path containing spaces the way a shell string can.
77
+
78
+ **A gate with nothing to start is fine.** An `external: true` service is just a health check, so
79
+ it can stand in as a named wait step — see `kafka-wait` in the microservices example.
@@ -0,0 +1,94 @@
1
+ # Django with Celery: web server, worker, beat scheduler, and the optional extras.
2
+ #
3
+ # Demonstrates: reading values out of the project's own .env with ${project.env:...},
4
+ # a virtualenv interpreter, autostart:false for tools you open occasionally,
5
+ # and a worker whose graceful stop is a signal rather than an artisan command.
6
+ #
7
+ # Setup: edit the path and the interpreter, then
8
+ # cp -r django-celery ~/.laracrew/stacks/
9
+ # laracrew up django-celery
10
+ name: django-celery
11
+ description: Django + Celery worker + beat
12
+ command: django
13
+
14
+ projects:
15
+ app:
16
+ path: ~/code/bookstore
17
+ envFile: .env # DJANGO_SETTINGS_MODULE, REDIS_URL, DB_*
18
+ color: green
19
+
20
+ defaults:
21
+ restart: on-failure
22
+ backoff: { initialMs: 1000, maxMs: 20000, factor: 2, maxRestarts: 10 }
23
+ # Celery handles SIGTERM properly: it stops accepting work and drains what it holds.
24
+ stop: { signal: SIGTERM, graceMs: 20000 }
25
+
26
+ services:
27
+ - name: redis
28
+ external: true
29
+ ready: { tcp: "127.0.0.1:6379", timeoutMs: 10000 }
30
+
31
+ - name: postgres
32
+ external: true
33
+ ready: { tcp: "127.0.0.1:5432", timeoutMs: 10000 }
34
+
35
+ # Migrations run to completion before anything that touches the database starts.
36
+ - name: migrate
37
+ project: app
38
+ cmd: [".venv/bin/python", "manage.py", "migrate", "--noinput"]
39
+ groups: [setup]
40
+ needs: [postgres]
41
+ restart: never
42
+ ready: { logMatch: "No migrations to apply|Applying|OK", timeoutMs: 120000 }
43
+
44
+ - name: web
45
+ project: app
46
+ cmd: [".venv/bin/python", "manage.py", "runserver", "0.0.0.0:${port:8000}"]
47
+ groups: [http]
48
+ needs: [postgres, redis, migrate]
49
+ env:
50
+ PYTHONUNBUFFERED: "1" # without this, output is buffered and the log pane stays empty
51
+ DJANGO_SETTINGS_MODULE: bookstore.settings.local
52
+ ready: { http: "http://127.0.0.1:8000/healthz", timeoutMs: 30000 }
53
+ url: http://127.0.0.1:8000
54
+ stop: { graceMs: 5000 }
55
+
56
+ - name: celery:worker
57
+ project: app
58
+ cmd: [".venv/bin/celery", "-A", "bookstore", "worker", "--loglevel=info", "--concurrency=4"]
59
+ groups: [workers]
60
+ needs: [redis, migrate]
61
+ env:
62
+ PYTHONUNBUFFERED: "1"
63
+ ready: { logMatch: "ready\\.$|celery@.* ready", timeoutMs: 30000 }
64
+
65
+ - name: celery:beat
66
+ project: app
67
+ cmd: [".venv/bin/celery", "-A", "bookstore", "beat", "--loglevel=info"]
68
+ groups: [scheduler]
69
+ needs: [redis, celery:worker]
70
+ env:
71
+ PYTHONUNBUFFERED: "1"
72
+
73
+ # A second worker for a queue that only matters during imports.
74
+ - name: celery:imports
75
+ project: app
76
+ cmd: [".venv/bin/celery", "-A", "bookstore", "worker", "--queues=imports", "--concurrency=1"]
77
+ groups: [workers]
78
+ needs: [redis]
79
+ autostart: false
80
+ env:
81
+ PYTHONUNBUFFERED: "1"
82
+
83
+ # Monitoring UI — useful, but not something you need running all day.
84
+ - name: flower
85
+ project: app
86
+ cmd: [".venv/bin/celery", "-A", "bookstore", "flower", "--port=5555"]
87
+ groups: [tooling]
88
+ needs: [redis]
89
+ autostart: false
90
+ url: http://127.0.0.1:5555
91
+
92
+ profiles:
93
+ no-scheduler: { except: [scheduler] }
94
+ workers-only: { only: [workers, redis, migrate, postgres] }
@@ -0,0 +1,76 @@
1
+ # The smallest useful stack: a handful of watchers in one repository. No servers,
2
+ # no databases, no projects — just the processes you would otherwise keep in six tabs.
3
+ #
4
+ # Demonstrates: that a "stack" does not need multiple apps or any Laravel at all, and that
5
+ # `cwd` alone is enough when everything lives under one root.
6
+ #
7
+ # Setup: point `root` at your repository, then
8
+ # cp -r frontend-monorepo ~/.laracrew/stacks/
9
+ # laracrew up frontend-monorepo
10
+ name: frontend-monorepo
11
+ description: Type checking, bundling and docs for a pnpm workspace
12
+ command: fe
13
+
14
+ projects:
15
+ root:
16
+ path: ~/code/design-system
17
+ color: cyan
18
+
19
+ defaults:
20
+ restart: on-failure
21
+ backoff: { initialMs: 1000, maxMs: 10000, factor: 2, maxRestarts: 5 }
22
+ stop: { graceMs: 3000 }
23
+
24
+ services:
25
+ # Types first: everything else consumes the built declarations.
26
+ - name: types
27
+ project: root
28
+ cwd: packages/core # relative to the project path
29
+ cmd: ["pnpm", "exec", "tsc", "--watch", "--preserveWatchOutput"]
30
+ groups: [build]
31
+ ready: { logMatch: "Found 0 errors|Watching for file changes", timeoutMs: 120000 }
32
+
33
+ - name: tailwind
34
+ project: root
35
+ cwd: packages/ui
36
+ cmd: ["pnpm", "exec", "tailwindcss", "-i", "./src/index.css", "-o", "./dist/index.css", "--watch"]
37
+ groups: [build]
38
+ ready: { logMatch: "Done in|Rebuilding", timeoutMs: 60000 }
39
+
40
+ - name: storybook
41
+ project: root
42
+ cwd: packages/ui
43
+ cmd: ["pnpm", "run", "storybook"]
44
+ groups: [docs]
45
+ needs: [types, tailwind]
46
+ ready: { logMatch: "Storybook.*started|Local:", timeoutMs: 180000 }
47
+ url: http://127.0.0.1:6006
48
+
49
+ - name: docs
50
+ project: root
51
+ cwd: apps/docs
52
+ cmd: ["pnpm", "run", "dev"] # Astro, Docusaurus, Next — whatever you use
53
+ groups: [docs]
54
+ needs: [types]
55
+ ready: { logMatch: "Local:|ready in", timeoutMs: 60000 }
56
+ url: http://127.0.0.1:4321
57
+
58
+ # Noisy on every keystroke — start it when you are actually fixing tests.
59
+ - name: tests
60
+ project: root
61
+ cmd: ["pnpm", "exec", "vitest", "--watch"]
62
+ groups: [tooling]
63
+ autostart: false
64
+ restart: never
65
+
66
+ # One-shot: select it, press `s`, watch it finish, carry on.
67
+ - name: lint
68
+ project: root
69
+ cmd: ["pnpm", "run", "lint:fix"]
70
+ groups: [tooling]
71
+ autostart: false
72
+ restart: never
73
+
74
+ profiles:
75
+ build-only: { only: [build] }
76
+ no-storybook: { except: [storybook] } # it is the slowest thing here
@@ -0,0 +1,107 @@
1
+ # Two interconnected Laravel apps: queues, Redis stream listeners, schedulers, Vite.
2
+ #
3
+ # Demonstrates: artisan-aware graceful stop, readiness gates that order the boot,
4
+ # autostart:false for commands you run occasionally, groups and profiles.
5
+ #
6
+ # Setup: edit the two paths below, then
7
+ # cp -r laravel-dual ~/.laracrew/stacks/
8
+ # laracrew doctor laravel-dual && laracrew up laravel-dual
9
+ name: laravel-dual
10
+ description: API + Portal with queues, streams and schedulers
11
+ command: dual
12
+
13
+ # Projects are declared inline here so the example is self-contained. Move them to
14
+ # ~/.laracrew/projects.yaml and use `use: [api, portal]` once you have several stacks.
15
+ projects:
16
+ api:
17
+ path: D:/work/api
18
+ php: php # or an absolute path to a specific build
19
+ envFile: .env # read for QUEUE_CONNECTION, REDIS_*, APP_URL
20
+ color: cyan
21
+ portal:
22
+ path: D:/work/portal
23
+ php: php
24
+ color: magenta
25
+
26
+ defaults:
27
+ restart: on-failure
28
+ backoff: { initialMs: 2000, maxMs: 30000, factor: 2, maxRestarts: 10 }
29
+ # Workers finish the job they are holding before laracrew terminates them.
30
+ stop: { artisan: "queue:restart", graceMs: 15000 }
31
+
32
+ services:
33
+ - name: redis
34
+ external: true # health-checked, never started or stopped by laracrew
35
+ ready: { tcp: "127.0.0.1:6379", timeoutMs: 10000 }
36
+
37
+ # ---------------------------------------------------------------- api
38
+ - name: api:serve
39
+ project: api
40
+ cmd: php artisan serve --port=${port:8000}
41
+ groups: [http]
42
+ needs: [redis]
43
+ ready: { http: "http://127.0.0.1:8000/up", timeoutMs: 20000 }
44
+ url: http://127.0.0.1:8000
45
+ stop: { graceMs: 5000 } # a web server has no job to finish
46
+
47
+ - name: api:queue
48
+ project: api
49
+ cmd:
50
+ ["php", "artisan", "queue:work", "redis", "--queue=high,default", "--tries=3", "--timeout=90"]
51
+ groups: [workers]
52
+ needs: [redis]
53
+ metrics: { queues: [high, default] }
54
+
55
+ - name: api:streams
56
+ project: api
57
+ cmd: ["php", "artisan", "redis-stream:run", "orders_sync"]
58
+ groups: [workers, streams]
59
+ needs: [redis]
60
+ metrics:
61
+ streams:
62
+ - { key: orders_sync, group: api-consumers }
63
+
64
+ - name: api:schedule
65
+ project: api
66
+ cmd: ["php", "artisan", "schedule:work"] # schedule:run is one tick; :work is the daemon
67
+ groups: [scheduler]
68
+ needs: [redis]
69
+
70
+ - name: api:vite
71
+ project: api
72
+ cmd: npm run dev
73
+ groups: [assets]
74
+ ready: { logMatch: "ready in|Local:", timeoutMs: 30000 }
75
+ stop: { graceMs: 3000 }
76
+
77
+ # ---------------------------------------------------------------- portal
78
+ # Nothing here starts until the API is actually answering HTTP.
79
+ - name: portal:serve
80
+ project: portal
81
+ cmd: php artisan serve --port=${port:8001}
82
+ groups: [http]
83
+ needs: [redis, api:serve]
84
+ ready: { http: "http://127.0.0.1:8001/up", timeoutMs: 20000 }
85
+ url: http://127.0.0.1:8001
86
+ stop: { graceMs: 5000 }
87
+
88
+ - name: portal:queue
89
+ project: portal
90
+ cmd: ["php", "artisan", "queue:work", "redis", "--tries=3"]
91
+ groups: [workers]
92
+ needs: [redis, api:serve]
93
+ metrics: { queues: [default] }
94
+
95
+ # Defined but not launched — select it and press `s` when you need a backfill.
96
+ - name: portal:backfill
97
+ project: portal
98
+ cmd: ["php", "artisan", "portal:backfill-orders"]
99
+ groups: [maintenance]
100
+ needs: [redis]
101
+ autostart: false
102
+ restart: never
103
+
104
+ profiles:
105
+ light: { except: [assets] } # skip Vite when you are only touching the backend
106
+ workers-only: { only: [workers, redis] }
107
+ api-only: { except: [portal:serve, portal:queue, portal:backfill] }
@@ -0,0 +1,99 @@
1
+ # A TypeScript API, a Vite frontend, a BullMQ worker and a database — no PHP anywhere.
2
+ #
3
+ # Demonstrates: logMatch readiness for tools that announce themselves, per-service env,
4
+ # a build step that must finish before anything else starts, argv-form
5
+ # commands so paths with spaces cannot mis-split.
6
+ #
7
+ # Setup: edit the paths, then
8
+ # cp -r node-api-and-web ~/.laracrew/stacks/
9
+ # laracrew up node-api-and-web
10
+ name: node-api-and-web
11
+ description: Node API + Vite web + BullMQ worker
12
+ command: web
13
+
14
+ projects:
15
+ api:
16
+ path: ~/code/shop/api
17
+ color: cyan
18
+ web:
19
+ path: ~/code/shop/web
20
+ color: magenta
21
+ shared:
22
+ path: ~/code/shop/packages/types
23
+ color: green
24
+
25
+ defaults:
26
+ restart: on-failure
27
+ backoff: { initialMs: 1000, maxMs: 15000, factor: 2, maxRestarts: 10 }
28
+ stop: { graceMs: 5000 }
29
+
30
+ services:
31
+ # Infrastructure this stack expects to already be running.
32
+ - name: postgres
33
+ external: true
34
+ ready: { tcp: "127.0.0.1:5432", timeoutMs: 10000 }
35
+
36
+ - name: redis
37
+ external: true
38
+ ready: { tcp: "127.0.0.1:6379", timeoutMs: 10000 }
39
+
40
+ # A one-shot build. `restart: never` means it is finished, not crashed, when it exits 0.
41
+ # Everything that imports the shared types waits for it.
42
+ - name: types:build
43
+ project: shared
44
+ cmd: ["npm", "run", "build"]
45
+ groups: [build]
46
+ restart: never
47
+ ready: { logMatch: "build (complete|succeeded)|Done in", timeoutMs: 120000 }
48
+
49
+ - name: api
50
+ project: api
51
+ cmd: ["npm", "run", "dev"] # e.g. tsx watch src/server.ts
52
+ groups: [backend]
53
+ needs: [postgres, redis, types:build]
54
+ env:
55
+ NODE_ENV: development
56
+ PORT: "3000"
57
+ # Pull a secret from your own shell rather than committing it.
58
+ STRIPE_KEY: ${env:STRIPE_TEST_KEY:sk_test_placeholder}
59
+ ready: { http: "http://127.0.0.1:3000/health", timeoutMs: 30000 }
60
+ url: http://127.0.0.1:3000
61
+
62
+ - name: api:worker
63
+ project: api
64
+ cmd: ["npm", "run", "worker"] # BullMQ / Bee-Queue consumer
65
+ groups: [backend, workers]
66
+ needs: [redis, types:build]
67
+ # Give an in-flight job a moment to settle before the process is taken down.
68
+ stop: { graceMs: 10000 }
69
+
70
+ - name: web
71
+ project: web
72
+ cmd: ["npm", "run", "dev"]
73
+ groups: [frontend]
74
+ needs: [api] # don't boot the UI against an API that isn't answering
75
+ env:
76
+ VITE_API_URL: http://127.0.0.1:3000
77
+ ready: { logMatch: "Local:\\s+http", timeoutMs: 30000 }
78
+ url: http://127.0.0.1:5173
79
+ stop: { graceMs: 3000 }
80
+
81
+ # Handy, but noisy — start it when you actually want it.
82
+ - name: web:test
83
+ project: web
84
+ cmd: ["npm", "run", "test:watch"]
85
+ groups: [tooling]
86
+ autostart: false
87
+ restart: never
88
+
89
+ - name: api:studio
90
+ project: api
91
+ cmd: ["npm", "run", "db:studio"] # Prisma Studio, Drizzle Studio, etc.
92
+ groups: [tooling]
93
+ needs: [postgres]
94
+ autostart: false
95
+ url: http://127.0.0.1:5555
96
+
97
+ profiles:
98
+ backend-only: { only: [backend, postgres, redis, types:build] }
99
+ frontend-only: { only: [frontend, types:build] }
@@ -0,0 +1,120 @@
1
+ # Four services in four languages, plus their infrastructure in Docker.
2
+ #
3
+ # Demonstrates: laracrew managing `docker compose` itself as a supervised process,
4
+ # a strict boot order enforced by HTTP and TCP gates rather than sleeps,
5
+ # and a gateway that refuses to start before its dependencies answer.
6
+ #
7
+ # This is the case laracrew is really for: the ordering is the hard part, not the running.
8
+ #
9
+ # Setup: edit the paths, then
10
+ # cp -r polyglot-microservices ~/.laracrew/stacks/
11
+ # laracrew up polyglot-microservices
12
+ name: polyglot-microservices
13
+ description: Go gateway, Rust search, Node orders, Python pricing
14
+ command: micro
15
+
16
+ projects:
17
+ infra:
18
+ path: ~/code/platform/infra # holds docker-compose.yml
19
+ color: yellow
20
+ gateway:
21
+ path: ~/code/platform/gateway # Go
22
+ color: cyan
23
+ search:
24
+ path: ~/code/platform/search # Rust
25
+ color: red
26
+ orders:
27
+ path: ~/code/platform/orders # Node
28
+ color: magenta
29
+ pricing:
30
+ path: ~/code/platform/pricing # Python
31
+ color: green
32
+
33
+ defaults:
34
+ restart: on-failure
35
+ backoff: { initialMs: 2000, maxMs: 30000, factor: 2, maxRestarts: 8 }
36
+ stop: { graceMs: 10000 }
37
+
38
+ services:
39
+ # Docker Compose is just another long-running process. laracrew starts it, streams its
40
+ # output, and stops it with the rest of the stack — no separate terminal, no forgetting.
41
+ - name: infra
42
+ project: infra
43
+ cmd: ["docker", "compose", "up"]
44
+ groups: [infra]
45
+ # Ready when every port we depend on is actually accepting connections.
46
+ ready: { tcp: "127.0.0.1:5432", timeoutMs: 120000, intervalMs: 1000 }
47
+ # Compose needs time to stop its own containers cleanly.
48
+ stop: { graceMs: 30000 }
49
+
50
+ - name: kafka-wait
51
+ external: true # nothing to start; this row exists purely as a gate
52
+ needs: [infra]
53
+ ready: { tcp: "127.0.0.1:9092", timeoutMs: 120000, intervalMs: 1000 }
54
+
55
+ # ---------------------------------------------------------------- services
56
+ - name: pricing
57
+ project: pricing
58
+ cmd: ["uvicorn", "app.main:app", "--reload", "--port", "${port:8001}"]
59
+ groups: [services]
60
+ needs: [infra]
61
+ env:
62
+ PYTHONUNBUFFERED: "1"
63
+ ready: { http: "http://127.0.0.1:8001/health", timeoutMs: 60000 }
64
+ url: http://127.0.0.1:8001
65
+
66
+ - name: search
67
+ project: search
68
+ cmd: ["cargo", "watch", "-x", "run"]
69
+ groups: [services]
70
+ needs: [infra]
71
+ env:
72
+ RUST_LOG: info
73
+ # A cold cargo build is slow; give the gate room rather than failing the boot.
74
+ ready: { http: "http://127.0.0.1:8002/health", timeoutMs: 300000, intervalMs: 2000 }
75
+ url: http://127.0.0.1:8002
76
+
77
+ - name: orders
78
+ project: orders
79
+ cmd: ["npm", "run", "dev"]
80
+ groups: [services]
81
+ needs: [infra, kafka-wait]
82
+ env:
83
+ NODE_ENV: development
84
+ KAFKA_BROKERS: 127.0.0.1:9092
85
+ ready: { http: "http://127.0.0.1:8003/health", timeoutMs: 60000 }
86
+ url: http://127.0.0.1:8003
87
+
88
+ # The gateway proxies all three, so it starts last — by declaration, not by sleeping.
89
+ - name: gateway
90
+ project: gateway
91
+ cmd: ["go", "run", "./cmd/gateway"]
92
+ groups: [edge]
93
+ needs: [pricing, search, orders]
94
+ env:
95
+ PRICING_URL: http://127.0.0.1:8001
96
+ SEARCH_URL: http://127.0.0.1:8002
97
+ ORDERS_URL: http://127.0.0.1:8003
98
+ ready: { http: "http://127.0.0.1:8080/health", timeoutMs: 60000 }
99
+ url: http://127.0.0.1:8080
100
+
101
+ # ---------------------------------------------------------------- on demand
102
+ - name: orders:consumer
103
+ project: orders
104
+ cmd: ["npm", "run", "consumer"]
105
+ groups: [workers]
106
+ needs: [kafka-wait]
107
+ autostart: false
108
+
109
+ - name: seed
110
+ project: infra
111
+ cmd: ["./scripts/seed.sh"]
112
+ groups: [maintenance]
113
+ needs: [infra]
114
+ autostart: false
115
+ restart: never
116
+
117
+ profiles:
118
+ # Work on the gateway against services you are not editing.
119
+ edge-only: { only: [edge, infra, kafka-wait] }
120
+ no-search: { except: [search] } # skip the slow Rust rebuild
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "laracrew",
3
+ "version": "0.1.1",
4
+ "description": "Boot and supervise all the long-running processes of your Laravel projects with one command.",
5
+ "keywords": [
6
+ "laravel",
7
+ "cli",
8
+ "tui",
9
+ "queue",
10
+ "horizon",
11
+ "redis",
12
+ "process-manager",
13
+ "dev-tools"
14
+ ],
15
+ "license": "MIT",
16
+ "type": "module",
17
+ "engines": {
18
+ "node": ">=20"
19
+ },
20
+ "bin": {
21
+ "laracrew": "./dist/index.js"
22
+ },
23
+ "exports": {
24
+ ".": "./dist/index.js",
25
+ "./package.json": "./package.json"
26
+ },
27
+ "files": [
28
+ "dist",
29
+ "examples",
30
+ "CHANGELOG.md"
31
+ ],
32
+ "sideEffects": false,
33
+ "scripts": {
34
+ "build": "tsup",
35
+ "dev": "tsx src/index.ts",
36
+ "test": "vitest run",
37
+ "test:watch": "vitest",
38
+ "typecheck": "tsc --noEmit",
39
+ "prepublishOnly": "npm run typecheck && npm test && npm run build",
40
+ "prepack": "npm run build"
41
+ },
42
+ "dependencies": {
43
+ "commander": "^12.1.0",
44
+ "yaml": "^2.5.1",
45
+ "zod": "^3.23.8"
46
+ },
47
+ "devDependencies": {
48
+ "@types/node": "^22.7.4",
49
+ "tsup": "^8.3.0",
50
+ "tsx": "^4.19.1",
51
+ "typescript": "^5.6.2",
52
+ "vitest": "^2.1.1"
53
+ },
54
+ "author": "viduranga <https://github.com/vidux>"
55
+ }