@flisk-sh/flisk 1.4.0 → 1.4.2
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.
- package/README.md +305 -52
- package/cli/dist/commands/doctor.js +62 -0
- package/cli/dist/commands/runtime.js +6 -3
- package/cli/dist/generator/template-engine.js +7 -4
- package/cli/dist/utils/runtime-layout.js +7 -0
- package/cli/dist-bundle/{chunk-QQEV6D74.js → chunk-3XODDLRJ.js} +1 -1
- package/cli/dist-bundle/{chunk-VMB5673O.js → chunk-43XWL2PB.js} +30 -26
- package/cli/dist-bundle/{chunk-5EZ4EX6U.js → chunk-53L2JN7G.js} +1 -1
- package/cli/dist-bundle/{chunk-BWK6MPCB.js → chunk-5F7YP5IR.js} +1 -1
- package/cli/dist-bundle/{chunk-36SOQVAL.js → chunk-5QBYM33Q.js} +1 -1
- package/cli/dist-bundle/{chunk-HEMPQKD6.js → chunk-DU2BN46C.js} +1 -1
- package/cli/dist-bundle/{chunk-ICXF6PXA.js → chunk-ETKUVKJ2.js} +2 -2
- package/cli/dist-bundle/{chunk-PVBAGX5X.js → chunk-I7TGIK5N.js} +1 -1
- package/cli/dist-bundle/{chunk-B6Q5VKL7.js → chunk-IGN5UC3P.js} +1 -1
- package/cli/dist-bundle/chunk-MWOVYIBB.js +54 -0
- package/cli/dist-bundle/{chunk-D7N2GGJH.js → chunk-YHYRGWUH.js} +1 -1
- package/cli/dist-bundle/{chunk-VHFFSBVJ.js → chunk-YNCBBJ4V.js} +1 -1
- package/cli/dist-bundle/cli.js +153 -153
- package/cli/dist-bundle/{cold-preflight-ABU26DYW.js → cold-preflight-ZOPR7PWJ.js} +1 -1
- package/cli/dist-bundle/{demo-stage-EBIUCJBX.js → demo-stage-OHNTP2UJ.js} +1 -1
- package/cli/dist-bundle/{open-2KSAF6M2.js → open-XROJ6YEY.js} +1 -1
- package/cli/dist-bundle/project-7PTIOHGF.js +2 -0
- package/cli/dist-bundle/{services-V6Q55JR5.js → services-BIMF6MVU.js} +1 -1
- package/cli/dist-bundle/{tilt-port-owner-MWJ7P6NB.js → tilt-port-owner-ZY5M2JC4.js} +1 -1
- package/cli/package.json +1 -1
- package/package.json +12 -2
- package/runtime/platform/services/platform/proxy/service.yaml +14 -0
- package/cli/dist/commands/__tests__/project-e2e-helpers.js +0 -49
- package/cli/dist/commands/__tests__/ui-loading-screen.test.js +0 -16
- package/cli/dist/generator/__tests__/golden-helpers.js +0 -43
- package/cli/dist-bundle/chunk-763VK575.js +0 -54
- package/cli/dist-bundle/project-YD3C4ZV3.js +0 -2
- package/runtime/discovery/test_resource_snapshot.py +0 -253
- package/runtime/engine/assets/docker/wake-gateway/decide.test.ts +0 -177
- package/runtime/engine/topologies/tilt/manifest/tests/test_integration.star +0 -278
- package/runtime/engine/topologies/tilt/manifest/tests/test_loader_parser.star +0 -475
- package/runtime/engine/topologies/tilt/manifest/tests/test_manifest.star +0 -319
- package/runtime/engine/topologies/tilt/manifest/tests/test_validator.star +0 -472
- package/runtime/ext/ide-components/shared/test_config_service.py +0 -328
- /package/{shared-platform-engineering → runtime/shared-platform-engineering}/docker-templates/bun-hoisted-symlink-fix.sh +0 -0
- /package/{shared-platform-engineering → runtime/shared-platform-engineering}/docker-templates/infisical-entrypoint.sh +0 -0
- /package/{shared-platform-engineering → runtime/shared-platform-engineering}/docker-templates/install-deps.sh +0 -0
- /package/{shared-platform-engineering → runtime/shared-platform-engineering}/docker-templates/prisma-bun-client-link-fix.sh +0 -0
- /package/{shared-platform-engineering → runtime/shared-platform-engineering}/docker-templates/prisma-normalize-client.sh +0 -0
package/README.md
CHANGED
|
@@ -1,24 +1,145 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-
# Flisk
|
|
3
|
+
# Flisk: your whole stack, running locally with one command
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Ask your AI agent for an app, or type four commands yourself.<br />Flisk sets up the containers, database, routing, and secrets, wires them together, and keeps them in sync as you change things.
|
|
6
6
|
|
|
7
7
|
<img src="https://raw.githubusercontent.com/flisk-sh/.github/main/profile/header-flisk.svg" alt="Flisk: your whole stack, running locally with one command." width="100%">
|
|
8
8
|
|
|
9
|
+
[](https://discord.gg/Sjhb3tnq3)
|
|
10
|
+
[](https://www.npmjs.com/package/@flisk-sh/flisk) [](https://www.npmjs.com/package/@flisk-sh/flisk) [](https://github.com/flisk-sh/flisk/stargazers) [](LICENSE)
|
|
11
|
+
|
|
12
|
+
<a href="https://trendshift.io/repositories/266432?utm_source=trendshift-badge&utm_medium=badge&utm_campaign=badge-trendshift-266432" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/trendshift/repositories/266432/weekly?language=Starlark" alt="flisk-sh%2Fflisk | Trendshift" width="250" height="55"/></a>
|
|
13
|
+
|
|
14
|
+
<img src="docs/assets/demo-ai.svg" alt="An AI coding agent builds a small online shop with Flisk and runs it locally" width="900" />
|
|
15
|
+
|
|
16
|
+
<sub>An illustrative agent session. The Flisk commands, and the service list and URLs Flisk prints, come from a real run. Copy the prompt from <a href="#with-your-ai-agent">Try it</a>.</sub>
|
|
17
|
+
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
## Trusted by
|
|
21
|
+
|
|
22
|
+
<table align="center">
|
|
23
|
+
<tr><td align="center" valign="middle"><a href="https://www.linkedin.com/company/lekast/"><img src="docs/assets/trusted-by/lekast.png" alt="Lekast" height="64"></a></td><td align="center" valign="middle"><a href="https://medium.com/@mfin.services"><img src="docs/assets/trusted-by/mfin-services.png" alt="MFin Services" height="64"></a></td><td align="center" valign="middle"><a href="https://www.linkedin.com/company/makeofferio"><img src="docs/assets/trusted-by/makeoffer.png" alt="MakeOffer" height="64"></a></td><td align="center" valign="middle"><a href="https://redmoon.digital/"><img src="docs/assets/trusted-by/redmoon-digital.png" alt="RedMoon.Digital" height="64"></a></td></tr>
|
|
24
|
+
</table>
|
|
25
|
+
|
|
26
|
+
<p align="center"><sub>Teams that run <code>flisk up</code> on their own code, listed with their consent. <a href="docs/project/ADOPTERS.md">See all adopters</a> or <a href="https://github.com/flisk-sh/flisk/issues/new?template=we-use-flisk.yml">add yours</a>.</sub></p>
|
|
27
|
+
|
|
28
|
+
## Try it
|
|
29
|
+
|
|
30
|
+
### With your AI agent
|
|
31
|
+
|
|
32
|
+
Install Flisk, then paste a prompt into your coding agent. Claude Code, Codex, Cursor, GitHub Copilot, and any other agent that can run commands will work. Every block below has a copy button.
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install -g @flisk-sh/flisk
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**The prompt from the demo:**
|
|
39
|
+
|
|
40
|
+
```text
|
|
41
|
+
Build me a small online shop with a storefront and an orders API, and run it on my laptop with Flisk.
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Your agent creates the project, adds each part, and starts it. If something is missing on your computer, `flisk doctor` tells it what to fix.
|
|
45
|
+
|
|
46
|
+
<details>
|
|
47
|
+
<summary>More prompts to copy</summary>
|
|
48
|
+
|
|
49
|
+
**Add a service to a project you already have**
|
|
50
|
+
|
|
51
|
+
```text
|
|
52
|
+
Use Flisk to add a backend service called payments-api to my shop stack, then start the stack and give me the URLs.
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Build an AI agent with tools and a database**
|
|
56
|
+
|
|
57
|
+
```text
|
|
58
|
+
Use Flisk to scaffold an AI agent, an MCP tools server, and a database in one stack called shop, then start it and tell me how to talk to the agent.
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Something is not working**
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
Run flisk doctor, explain every problem in plain words, and fix what you can. Then start my stack with flisk up.
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**See what is running**
|
|
68
|
+
|
|
69
|
+
```text
|
|
70
|
+
Use flisk status to tell me which services are running, which are unhealthy, and what URL each one has.
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Stop everything**
|
|
74
|
+
|
|
75
|
+
```text
|
|
76
|
+
Stop my Flisk stack with flisk down and confirm nothing is left running.
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
</details>
|
|
80
|
+
|
|
81
|
+
<details>
|
|
82
|
+
<summary>Connect your agent to Flisk as an MCP server</summary>
|
|
83
|
+
|
|
84
|
+
Add this to your agent's MCP settings:
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"mcpServers": {
|
|
89
|
+
"flisk": { "command": "flisk", "args": ["mcp"] }
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The agent can then start the stack, check status, restart a service, and read agent sessions through Flisk tools instead of shell commands. See [use Flisk with your AI agent](#use-flisk-with-your-ai-agent).
|
|
95
|
+
|
|
96
|
+
</details>
|
|
97
|
+
|
|
98
|
+
### In your terminal
|
|
99
|
+
|
|
100
|
+
<p align="center">
|
|
101
|
+
<img src="docs/assets/demo-cli.svg" alt="Four flisk commands create a project, an API, and a website, then start them" width="900" />
|
|
102
|
+
</p>
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
npm install -g @flisk-sh/flisk
|
|
106
|
+
mkdir my-shop && cd my-shop
|
|
107
|
+
flisk project --yes
|
|
108
|
+
flisk resource orders-api --type backend --stack shop --yes
|
|
109
|
+
flisk resource shop-web --type frontend --stack shop --yes
|
|
110
|
+
flisk up shop
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
You get an orders API and a storefront behind one local gateway, with Postgres and live reload. You need Docker, [Tilt](https://docs.tilt.dev/install.html), Node.js 22.12+, and [Bun](https://bun.sh/) 1.2+; `flisk doctor` checks your machine. Prefer to answer questions instead? `npm init create-microservices my-project` asks what to create. See the [quick start](#quick-start) for every option.
|
|
114
|
+
|
|
115
|
+
<div align="center">
|
|
116
|
+
|
|
117
|
+
<p><strong><a href="#quick-start">Quick start</a> · <a href="#why-flisk-cli">Why Flisk</a> · <a href="#examples">Examples</a> · <a href="#installation">Installation</a> · <a href="#faq">FAQ</a> · <a href="#docs">Documentation</a></strong></p>
|
|
118
|
+
|
|
119
|
+
[Website](https://flisk.sh/) · [Quickstart](https://flisk.sh/docs/quickstart/) · [Examples](https://flisk.sh/docs/examples/) · [Awesome Flisk](https://github.com/flisk-sh/awesome-tdk-framework) · [Demo](https://flisk-sh.github.io/flisk-demo-animation/) · [Report a bug](https://github.com/flisk-sh/flisk/issues)
|
|
120
|
+
|
|
121
|
+
<a id="readme-languages"></a>
|
|
122
|
+
|
|
123
|
+
<p align="center">
|
|
124
|
+
|
|
125
|
+
English | [简体中文](docs/README-zh_cn.md) | [繁體中文](docs/README-zh_tw.md) | [日本語](docs/README-ja.md) | [한국어](docs/README-ko.md) | [Türkçe](docs/README-tr.md) | [Tiếng Việt](docs/README-vi.md) | [ไทย](docs/README-th.md) | [Deutsch](docs/README-de.md) | [Español](docs/README-es.md) | [Français](docs/README-fr.md) | [Українська](docs/README-uk.md) | [Polski](docs/README-pl.md) | [Português (Brasil)](docs/README-pt-BR.md) | [العربية](docs/README-ar.md) | [فارسی](docs/README-fa.md) | [Bahasa Indonesia](docs/README-id.md) | [Italiano](docs/README-it.md) | [Ελληνικά](docs/README-el.md) | [മലയാളം](docs/README-ml.md)
|
|
126
|
+
|
|
127
|
+
</p>
|
|
128
|
+
|
|
129
|
+
<details>
|
|
130
|
+
<summary>Test, scale, and security status</summary>
|
|
9
131
|
|
|
10
|
-
[](https://discord.gg/JG6r33HVB)
|
|
11
|
-
[](https://www.npmjs.com/package/@flisk-sh/flisk) [](https://www.npmjs.com/package/@flisk-sh/flisk) [](https://packagephobia.com/result?p=@flisk-sh/flisk) [](https://packagephobia.com/result?p=@flisk-sh/flisk) [](https://github.com/flisk-sh/flisk/stargazers) [](https://ossinsight.io/analyze/flisk-sh/flisk) [](https://x.com/brookservers)
|
|
12
132
|
[](https://github.com/flisk-sh/flisk/actions/workflows/e2e-journeys.yml) [](https://github.com/flisk-sh/flisk/actions/workflows/e2e-scale-full.yml) [](https://github.com/flisk-sh/flisk/actions/workflows/e2e-real-apps.yml) [](https://github.com/flisk-sh/flisk/security/code-scanning) [](https://scorecard.dev/viewer/?uri=github.com/flisk-sh/flisk) [](https://snyk.io/test/github/flisk-sh/flisk) [](https://socket.dev/npm/package/@flisk-sh/flisk/overview)
|
|
13
|
-
[](LICENSE)
|
|
14
133
|
|
|
15
134
|
[](https://github.com/flisk-sh/flisk/actions/runs/39160719471) [](https://github.com/flisk-sh/flisk/actions/runs/39160719471) [](https://github.com/flisk-sh/flisk/actions/runs/39160719471) [](https://github.com/flisk-sh/flisk/actions/runs/39160719471) [](https://github.com/flisk-sh/flisk/actions/runs/39160719471)
|
|
16
135
|
[](https://github.com/flisk-sh/flisk/blob/main/docs/assets/coverage.svg)
|
|
17
136
|
|
|
18
137
|
<sub>ERP fixture scale run on a clean GitHub-hosted runner (4 vCPU, 15 GB RAM), snapshot from [run 39160719471](https://github.com/flisk-sh/flisk/actions/runs/39160719471). The live status is in the ERP fixture scale E2E badge above.</sub>
|
|
19
138
|
|
|
139
|
+
[](https://packagephobia.com/result?p=@flisk-sh/flisk) [](https://packagephobia.com/result?p=@flisk-sh/flisk) [](https://ossinsight.io/analyze/flisk-sh/flisk) [](https://x.com/brookservers)
|
|
140
|
+
|
|
20
141
|
<a href="https://trendshift.io/repositories/266432?utm_source=trendshift-badge&utm_medium=badge&utm_campaign=badge-trendshift-266432" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/trendshift/repositories/266432/daily?language=Starlark" alt="flisk-sh%2Fflisk | Trendshift" width="250" height="55"/></a>
|
|
21
|
-
|
|
142
|
+
|
|
22
143
|
<p align="center">
|
|
23
144
|
<a href="https://www.bestpractices.dev/projects/15310">
|
|
24
145
|
<img src="https://www.bestpractices.dev/assets/openssf_bestpracticesbadge-a908f4124737f3d6b2c5abc82756bd2a435cff474b45615ce469746c31a4288c.svg" alt="OpenSSF Best Practices" height="80" align="middle" style="vertical-align: middle" />
|
|
@@ -28,19 +149,7 @@ Go from an empty folder to a running tech stack with one command. Built for agen
|
|
|
28
149
|
</a>
|
|
29
150
|
</p>
|
|
30
151
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
<a id="readme-languages"></a>
|
|
34
|
-
|
|
35
|
-
<p align="center">
|
|
36
|
-
|
|
37
|
-
English | [简体中文](docs/README-zh_cn.md) | [繁體中文](docs/README-zh_tw.md) | [日本語](docs/README-ja.md) | [한국어](docs/README-ko.md) | [Türkçe](docs/README-tr.md) | [Tiếng Việt](docs/README-vi.md) | [ไทย](docs/README-th.md) | [Deutsch](docs/README-de.md) | [Español](docs/README-es.md) | [Français](docs/README-fr.md) | [Українська](docs/README-uk.md) | [Polski](docs/README-pl.md) | [Português (Brasil)](docs/README-pt-BR.md) | [العربية](docs/README-ar.md) | [فارسی](docs/README-fa.md) | [Bahasa Indonesia](docs/README-id.md) | [Italiano](docs/README-it.md) | [Ελληνικά](docs/README-el.md) | [മലയാളം](docs/README-ml.md)
|
|
38
|
-
|
|
39
|
-
</p>
|
|
40
|
-
|
|
41
|
-
<br />
|
|
42
|
-
|
|
43
|
-
[Website](https://flisk.sh/) · [Quickstart](https://flisk.sh/docs/quickstart/) · [Examples](https://flisk.sh/docs/examples/) · [Awesome Flisk](https://github.com/flisk-sh/awesome-tdk-framework) · [Demo](https://flisk-sh.github.io/flisk-demo-animation/) · [Report a bug](https://github.com/flisk-sh/flisk/issues)
|
|
152
|
+
</details>
|
|
44
153
|
|
|
45
154
|
</div>
|
|
46
155
|
|
|
@@ -114,8 +223,9 @@ Fastest way (recommended): open the [Flisk starter](https://github.com/flisk-sh/
|
|
|
114
223
|
|
|
115
224
|
</details>
|
|
116
225
|
|
|
117
|
-
### ⚡
|
|
118
|
-
|
|
226
|
+
### ⚡ A running stack in about 14 seconds
|
|
227
|
+
|
|
228
|
+
On a one-backend quickstart with warm image layers, `flisk up` reaches a healthy API in 12.8 to 13.8 seconds ([timing notes](docs/benchmarks/quickstart-timing.md)). An 8-service stack settles in 32 to 42 seconds warm and about 4.5 minutes on its first cold build ([benchmark](docs/benchmarks/results/tdk-up-warm-start-2026-10-11/summary.md)). No vendor lock-in and no hand-written plumbing. Flisk works with:
|
|
119
229
|
* **Runtimes & Frameworks:** Bun, Node, Python, Go, Rust, React, Vue, Svelte, Elysia, Fastify, NestJS
|
|
120
230
|
* **Databases & Tooling:** Prisma, Drizzle, Atlas, Dbmate
|
|
121
231
|
* **Messaging & Gateway:** NATS, Traefik
|
|
@@ -134,11 +244,11 @@ flisk up shop
|
|
|
134
244
|
Agents get durable checkpoint volumes that survive `flisk down`, sticky session routing via `x-session-id`, graceful SIGTERM drain during hot reloads, a Docker health check on `/health`, and application-level readiness checks on `/ready`. See the [AI agents guide](docs/agents/ai-agents.md) and [honest comparison with agent frameworks](docs/compare-honest.md#ai-agent-frameworks-and-workflow-engines-libfx-langgraph-mastra-vercel-workflows-temporal).
|
|
135
245
|
|
|
136
246
|
|
|
137
|
-
Flisk
|
|
247
|
+
**What Flisk is:** a local development runtime. Define each service in `service.json` and run `flisk up`. Docker runs the containers, Tilt live-updates them while you code, and Flisk writes the configuration both use. No local Kubernetes is needed.
|
|
138
248
|
|
|
139
|
-
|
|
249
|
+
**What Flisk is not:** a deploy tool or a Compose file. Production deployment stays with Helm, Argo CD, or Kustomize.
|
|
140
250
|
|
|
141
|
-
|
|
251
|
+
Stability: 1.x. The core CLI is MIT and needs no key; Premium is optional. See [what Flisk writes](docs/generated-files.md) and how to check for drift.
|
|
142
252
|
|
|
143
253
|
|
|
144
254
|
> [!IMPORTANT]
|
|
@@ -147,12 +257,6 @@ Docker runs the containers. Tilt watches services and live-updates containers wh
|
|
|
147
257
|
> [official website](https://flisk.sh/). Follow the installation links from these official sources.
|
|
148
258
|
> A similar repository name or copied README does not establish that a download is official.
|
|
149
259
|
|
|
150
|
-
<p align="center"><strong><a href="#quick-start">Quick start</a> · <a href="#why-flisk-cli">Why Flisk</a> · <a href="#examples">Examples</a> · <a href="#installation">Installation</a> · <a href="#faq">FAQ</a> · <a href="#docs">Documentation</a></strong></p>
|
|
151
|
-
|
|
152
|
-
If Flisk helps you run your local stack, a ⭐ on [this repo](https://github.com/flisk-sh/flisk) helps other developers find it.
|
|
153
|
-
|
|
154
|
-
`flisk ui` opens an interactive terminal dashboard for inspecting running services. Move with `↑/↓` or `j/k`, search with `/`, and press `1`–`5` to jump between tabs. See [docs/ui.md](docs/ui.md) for every key binding.
|
|
155
|
-
|
|
156
260
|
## Why Flisk CLI?
|
|
157
261
|
|
|
158
262
|
- **One `service.json` per service.** Flisk generates the Dockerfile, Traefik routing, and Tiltfile from it. You do not hand-write a `docker-compose.yml` or `nginx.conf`.
|
|
@@ -178,6 +282,22 @@ See the [detailed tool comparison](docs/comparison.md) for architectural tradeof
|
|
|
178
282
|
|
|
179
283
|
Production deployment stays with your own tools (Helm, Argo CD, or Kustomize).
|
|
180
284
|
|
|
285
|
+
### Everything is wired together, and stays in sync
|
|
286
|
+
|
|
287
|
+
You do not connect services by hand. Flisk derives each connection from the same `service.json` files and regenerates it when they change.
|
|
288
|
+
|
|
289
|
+
| When you... | Flisk updates |
|
|
290
|
+
| --- | --- |
|
|
291
|
+
| Add a service with `flisk resource` | It is discovered automatically and its stack is enabled on the next `flisk up`. It gets an image build, a Compose entry, gateway routes, a health check, and its own `.autogenerated/` files. |
|
|
292
|
+
| Edit a `service.json` (port, `dependsOn`, features) | The Dockerfile, Compose entry, Traefik labels, and nginx config are regenerated on the next `flisk up`. A hand edit to a generated file is caught as drift before anything starts. |
|
|
293
|
+
| Edit your code | Tilt live-updates the running container. No rebuild step. |
|
|
294
|
+
| Add a backend route | Frontends already point at the API through generated `VITE_API_URL`, `env.ts`, and `api-client.ts`, built from the same hostnames the gateway routes. |
|
|
295
|
+
| Add a database or a second backend | `DATABASE_URL` and the other connection settings are injected into each service's environment. No copying of passwords or hostnames. |
|
|
296
|
+
| Run on a project with an older or missing `.env` | Missing secrets such as `JWT_SECRET` are generated without overwriting your values. |
|
|
297
|
+
| Declare `dependsOn` | Services start in health-checked order. |
|
|
298
|
+
|
|
299
|
+
See [how `flisk up` works](docs/how-flisk-up-works.md) for the full startup sequence.
|
|
300
|
+
|
|
181
301
|
## What you can do with Flisk
|
|
182
302
|
|
|
183
303
|
| You want to | Flisk does | Command |
|
|
@@ -268,33 +388,106 @@ curl http://api.shop.localhost/api/orders/health
|
|
|
268
388
|
|
|
269
389
|
`flisk up` prints the host ports it chose. It uses port 80 when it is free, so URLs carry no port. Otherwise it picks one from 8080-8180, and the URLs it prints include that port (on Linux and WSL2 a non-root user cannot check port 80, so the range is used there). Use the URL `flisk up` prints, or set `FLISK_HTTP_PORT`. A resource named `orders-api` is served at `/api/orders` (a trailing `-api` is dropped); `flisk up` prints the exact URLs.
|
|
270
390
|
|
|
271
|
-
|
|
272
|
-
<img src="docs/assets/demo.svg" alt="Flisk scaffolding a backend and a frontend, then listing the stack" width="900" />
|
|
273
|
-
<br /><br />
|
|
274
|
-
<em>Scaffolding a backend and frontend, then listing the stack.</em>
|
|
275
|
-
</p>
|
|
391
|
+
### What Flisk writes for you
|
|
276
392
|
|
|
277
|
-
|
|
393
|
+
You write one `service.json` per service. For the two-service shop above, Flisk writes the rest at three levels: the project, the stack, and each service.
|
|
278
394
|
|
|
279
|
-
|
|
395
|
+
```text
|
|
396
|
+
my-shop/
|
|
397
|
+
├── .env # generated DB_PASSWORD and JWT_SECRET
|
|
398
|
+
├── .flisk/
|
|
399
|
+
│ ├── project.json # project settings (yours to edit)
|
|
400
|
+
│ └── .flisk-out/ # PROJECT LEVEL
|
|
401
|
+
│ ├── Tiltfile # what Tilt runs
|
|
402
|
+
│ ├── docker-compose.traefik.yml # local gateway, bound to 127.0.0.1
|
|
403
|
+
│ ├── golden-layers.Dockerfile # shared base image layers
|
|
404
|
+
│ ├── TILT_TECH_STACK.star # tech stack settings
|
|
405
|
+
│ ├── TILT_RESOURCE_DEFAULTS.star # service defaults
|
|
406
|
+
│ ├── spec.master # project spec by stack
|
|
407
|
+
│ └── flisk-cli-ext/ # pinned copy of the Flisk engine
|
|
408
|
+
├── shared-platform-engineering/
|
|
409
|
+
│ └── docker-templates/ # container entrypoint scripts
|
|
410
|
+
└── services/
|
|
411
|
+
├── platform/database-management/
|
|
412
|
+
│ └── docker-compose.yml # Postgres 16
|
|
413
|
+
└── shop/
|
|
414
|
+
├── .autogenerated/ # STACK LEVEL
|
|
415
|
+
│ └── docker-compose.app.autogenerated.yml # every service in the stack
|
|
416
|
+
├── orders-api/
|
|
417
|
+
│ ├── service.json # you write this
|
|
418
|
+
│ └── .autogenerated/ # SERVICE LEVEL: 14 files
|
|
419
|
+
└── shop-web/
|
|
420
|
+
├── service.json # you write this
|
|
421
|
+
└── .autogenerated/ # SERVICE LEVEL: 18 files
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
The stack's Compose file is the part you would otherwise write by hand. For these two services it holds the image builds, environment, 33 Traefik routing labels, four networks, health checks, and CPU and memory limits. An excerpt:
|
|
425
|
+
|
|
426
|
+
```yaml
|
|
427
|
+
orders-api:
|
|
428
|
+
environment:
|
|
429
|
+
- DATABASE_URL=postgresql://my_shop:${DB_PASSWORD}@my_shop_postgres:5432/my_shop_shop?schema=public
|
|
430
|
+
- JWT_SECRET=${JWT_SECRET:?JWT_SECRET is not set. Run `flisk up` ...}
|
|
431
|
+
labels:
|
|
432
|
+
- "traefik.http.routers.orders-api-project.rule=Host(`api.my-shop.localhost`) && PathPrefix(`/api/orders`)"
|
|
433
|
+
- "traefik.http.middlewares.orders-api-strip-prefix-project.stripprefix.prefixes=/api/orders"
|
|
434
|
+
- "traefik.http.services.orders-api.loadbalancer.healthcheck.path=/health"
|
|
435
|
+
healthcheck:
|
|
436
|
+
test: ["CMD", "curl", "-f", "--max-time", "5", "http://localhost:4000/health"]
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
Secrets come from the project `.env` by default: `flisk project` generates a random database password and JWT secret, and `.env` is added to `.gitignore`. Set `FLISK_SECRET_PROVIDER=infisical` to read secrets from [Infisical](https://infisical.com/) instead ([environment](docs/environment.md)).
|
|
440
|
+
|
|
441
|
+
<details>
|
|
442
|
+
<summary>Every file in each service's <code>.autogenerated/</code> folder</summary>
|
|
280
443
|
|
|
281
444
|
```text
|
|
282
|
-
|
|
283
|
-
├──
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
445
|
+
shop-web/.autogenerated/
|
|
446
|
+
├── Dockerfile.app.autogenerated # app image
|
|
447
|
+
├── Dockerfile.app.autogenerated.dockerignore # build context
|
|
448
|
+
├── nginx.autogenerated.conf # serves the build, routes API requests
|
|
449
|
+
├── vite.config.frontend.autogenerated.ts # dev server
|
|
450
|
+
├── vite.config.build.autogenerated.ts # production build
|
|
451
|
+
├── tsconfig.autogenerated.json # TypeScript, host
|
|
452
|
+
├── tsconfig.docker.autogenerated.json # TypeScript, container
|
|
453
|
+
├── .npmrc.autogenerated # package registry, host
|
|
454
|
+
├── .npmrc.docker.autogenerated # package registry, container
|
|
455
|
+
├── bunfig.autogenerated.toml # Bun settings, host
|
|
456
|
+
├── bunfig.docker.autogenerated.toml # Bun settings, container
|
|
457
|
+
├── .env.frontend.autogenerated # frontend environment
|
|
458
|
+
├── env.ts # API URL for your imports
|
|
459
|
+
├── api-client.ts # client for the frontend's API route
|
|
460
|
+
├── api-index.ts # re-exports the client and URL
|
|
461
|
+
├── service.yaml # Tilt's projection of service.json
|
|
462
|
+
├── validation-report.autogenerated.json # preflight validation result
|
|
463
|
+
├── AGENTS.md # tells coding agents not to edit here
|
|
464
|
+
└── .flisk-contract/ # snapshots for drift checks
|
|
291
465
|
```
|
|
292
466
|
|
|
293
|
-
|
|
467
|
+
```text
|
|
468
|
+
orders-api/.autogenerated/
|
|
469
|
+
├── Dockerfile.app.autogenerated # app image
|
|
470
|
+
├── Dockerfile.app.autogenerated.dockerignore # build context
|
|
471
|
+
├── vite.config.backend.autogenerated.ts # server build
|
|
472
|
+
├── prisma.config.autogenerated.ts # database client
|
|
473
|
+
├── tsconfig.autogenerated.json # TypeScript, host
|
|
474
|
+
├── tsconfig.docker.autogenerated.json # TypeScript, container
|
|
475
|
+
├── .npmrc.autogenerated # package registry, host
|
|
476
|
+
├── .npmrc.docker.autogenerated # package registry, container
|
|
477
|
+
├── bunfig.autogenerated.toml # Bun settings, host
|
|
478
|
+
├── bunfig.docker.autogenerated.toml # Bun settings, container
|
|
479
|
+
├── .env.backend.autogenerated # backend environment
|
|
480
|
+
├── service.yaml # Tilt's projection of service.json
|
|
481
|
+
├── validation-report.autogenerated.json # preflight validation result
|
|
482
|
+
├── AGENTS.md # tells coding agents not to edit here
|
|
483
|
+
└── .flisk-contract/ # snapshots for drift checks
|
|
484
|
+
```
|
|
294
485
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
</
|
|
486
|
+
A stack with a database migrator also gets `docker-compose.migrator.autogenerated.yml` in the stack folder, and the migrator gets its own `Dockerfile.migrator.autogenerated`.
|
|
487
|
+
|
|
488
|
+
</details>
|
|
489
|
+
|
|
490
|
+
You never write an nginx config, a Dockerfile, a Compose file, or Traefik labels for this stack. `flisk up` regenerates these files when `service.json` changes and refuses to start if one was edited by hand. Python, Go, and Rust services, and optional features such as Playwright, get their own sets; the [generated-files guide](docs/generated-files.md) lists them and explains the drift checks.
|
|
298
491
|
|
|
299
492
|
If Helm, Compose, or your existing Tilt setup already gives you a working local environment, keep using it. Flisk CLI is for engineers managing several services who want a clear local service contract and one command to start the stack.
|
|
300
493
|
|
|
@@ -305,7 +498,8 @@ See [how Flisk compares to alternative dev tools](docs/comparison.md), [how Flis
|
|
|
305
498
|
Use `flisk ui` to inspect stacks and resources. Arrow keys or `j`/`k` move the
|
|
306
499
|
selection; `g`/`G` or Home/End jump to the first/last item, and PageUp/PageDown
|
|
307
500
|
move one visible page. `/` searches; navigation letters remain search text
|
|
308
|
-
while searching.
|
|
501
|
+
while searching. Press `1`–`5` to jump between tabs. The selected row stays
|
|
502
|
+
visible when the terminal is resized. See [docs/ui.md](docs/ui.md) for every key binding.
|
|
309
503
|
|
|
310
504
|
## Update Flisk
|
|
311
505
|
|
|
@@ -359,6 +553,7 @@ Set `FLISK_DEBUG=1` before running `flisk up --verbose` to include Starlark debu
|
|
|
359
553
|
|
|
360
554
|
## Docs
|
|
361
555
|
|
|
556
|
+
- [Flisk 101: a 13-lab course for beginners](docs/101/README.md)
|
|
362
557
|
- [CLI command cheat sheet](cli/README.md#cheat-sheet)
|
|
363
558
|
- [Mega cheat sheet: every command and flag](docs/cheat-sheet.md)
|
|
364
559
|
- [Documentation index](docs/README.md)
|
|
@@ -477,7 +672,65 @@ Then run `flisk doctor` and retry the same task. If the problem persists, [open
|
|
|
477
672
|
|
|
478
673
|
## Contributing and license
|
|
479
674
|
|
|
480
|
-
Contributions are welcome.
|
|
675
|
+
Contributions are welcome. **First step: [say hello on Discord](https://discord.gg/Sjhb3tnq3)**, tell us what you want to work on, and we will point you to a good first task. Then start with [CONTRIBUTING.md](.github/CONTRIBUTING.md) and the [contributor guide](docs/contributing/README.md). For the project structure, see the [architecture and repository map](docs/project-overview.md). To review pull requests, see [Review a pull request](docs/contributing/04-review-a-pr.md). Report security issues using [SECURITY.md](.github/SECURITY.md).
|
|
676
|
+
|
|
677
|
+
### Contributors
|
|
678
|
+
|
|
679
|
+
Thank you to everyone who has shipped code, docs, and fixes to Flisk since July 2026. Every merged change makes the local stack better for the next developer.
|
|
680
|
+
|
|
681
|
+
<table>
|
|
682
|
+
<tr>
|
|
683
|
+
<td align="center"><a href="https://github.com/kburym"><img src="https://github.com/kburym.png?size=80" width="64" alt="kburym" /><br /><sub><b>kburym</b></sub></a></td>
|
|
684
|
+
<td align="center"><a href="https://github.com/odykyi"><img src="https://github.com/odykyi.png?size=80" width="64" alt="odykyi" /><br /><sub><b>odykyi</b></sub></a></td>
|
|
685
|
+
<td align="center"><a href="https://github.com/sb123sb123"><img src="https://github.com/sb123sb123.png?size=80" width="64" alt="sb123sb123" /><br /><sub><b>sb123sb123</b></sub></a></td>
|
|
686
|
+
<td align="center"><a href="https://github.com/AK-Lmn"><img src="https://github.com/AK-Lmn.png?size=80" width="64" alt="AK-Lmn" /><br /><sub><b>AK-Lmn</b></sub></a></td>
|
|
687
|
+
<td align="center"><a href="https://github.com/yoreva-01"><img src="https://github.com/yoreva-01.png?size=80" width="64" alt="yoreva-01" /><br /><sub><b>yoreva-01</b></sub></a></td>
|
|
688
|
+
<td align="center"><a href="https://github.com/minutechreview"><img src="https://github.com/minutechreview.png?size=80" width="64" alt="minutechreview" /><br /><sub><b>minutechreview</b></sub></a></td>
|
|
689
|
+
</tr>
|
|
690
|
+
<tr>
|
|
691
|
+
<td align="center"><a href="https://github.com/Delfi2007"><img src="https://github.com/Delfi2007.png?size=80" width="64" alt="Delfi2007" /><br /><sub><b>Delfi2007</b></sub></a></td>
|
|
692
|
+
<td align="center"><a href="https://github.com/Ghifariezra"><img src="https://github.com/Ghifariezra.png?size=80" width="64" alt="Ghifariezra" /><br /><sub><b>Ghifariezra</b></sub></a></td>
|
|
693
|
+
<td align="center"><a href="https://github.com/Huang-404-Q"><img src="https://github.com/Huang-404-Q.png?size=80" width="64" alt="Huang-404-Q" /><br /><sub><b>Huang-404-Q</b></sub></a></td>
|
|
694
|
+
<td align="center"><a href="https://github.com/dbdefault"><img src="https://github.com/dbdefault.png?size=80" width="64" alt="dbdefault" /><br /><sub><b>dbdefault</b></sub></a></td>
|
|
695
|
+
<td align="center"><a href="https://github.com/Rohith-Saran"><img src="https://github.com/Rohith-Saran.png?size=80" width="64" alt="Rohith-Saran" /><br /><sub><b>Rohith-Saran</b></sub></a></td>
|
|
696
|
+
<td align="center"><a href="https://github.com/aazminu"><img src="https://github.com/aazminu.png?size=80" width="64" alt="aazminu" /><br /><sub><b>aazminu</b></sub></a></td>
|
|
697
|
+
</tr>
|
|
698
|
+
<tr>
|
|
699
|
+
<td align="center"><a href="https://github.com/xiehuanyi"><img src="https://github.com/xiehuanyi.png?size=80" width="64" alt="xiehuanyi" /><br /><sub><b>xiehuanyi</b></sub></a></td>
|
|
700
|
+
<td align="center"><a href="https://github.com/NimoCao"><img src="https://github.com/NimoCao.png?size=80" width="64" alt="NimoCao" /><br /><sub><b>NimoCao</b></sub></a></td>
|
|
701
|
+
<td align="center"><a href="https://github.com/rahul05ranjan"><img src="https://github.com/rahul05ranjan.png?size=80" width="64" alt="rahul05ranjan" /><br /><sub><b>rahul05ranjan</b></sub></a></td>
|
|
702
|
+
<td align="center"><a href="https://github.com/krishna2707"><img src="https://github.com/krishna2707.png?size=80" width="64" alt="krishna2707" /><br /><sub><b>krishna2707</b></sub></a></td>
|
|
703
|
+
<td align="center"><a href="https://github.com/arxh80"><img src="https://github.com/arxh80.png?size=80" width="64" alt="arxh80" /><br /><sub><b>arxh80</b></sub></a></td>
|
|
704
|
+
<td align="center"><a href="https://github.com/tnalbant"><img src="https://github.com/tnalbant.png?size=80" width="64" alt="tnalbant" /><br /><sub><b>tnalbant</b></sub></a></td>
|
|
705
|
+
</tr>
|
|
706
|
+
<tr>
|
|
707
|
+
<td align="center"><a href="https://github.com/sunny-kavixo"><img src="https://github.com/sunny-kavixo.png?size=80" width="64" alt="sunny-kavixo" /><br /><sub><b>sunny-kavixo</b></sub></a></td>
|
|
708
|
+
<td align="center"><a href="https://github.com/sohammkk"><img src="https://github.com/sohammkk.png?size=80" width="64" alt="sohammkk" /><br /><sub><b>sohammkk</b></sub></a></td>
|
|
709
|
+
<td align="center"><a href="https://github.com/sinhaananya812-star"><img src="https://github.com/sinhaananya812-star.png?size=80" width="64" alt="sinhaananya812-star" /><br /><sub><b>sinhaananya812-star</b></sub></a></td>
|
|
710
|
+
<td align="center"><a href="https://github.com/jay23606"><img src="https://github.com/jay23606.png?size=80" width="64" alt="jay23606" /><br /><sub><b>jay23606</b></sub></a></td>
|
|
711
|
+
<td align="center"><a href="https://github.com/floatyserve"><img src="https://github.com/floatyserve.png?size=80" width="64" alt="floatyserve" /><br /><sub><b>floatyserve</b></sub></a></td>
|
|
712
|
+
<td align="center"><a href="https://github.com/eddyflores100-lang"><img src="https://github.com/eddyflores100-lang.png?size=80" width="64" alt="eddyflores100-lang" /><br /><sub><b>eddyflores100-lang</b></sub></a></td>
|
|
713
|
+
</tr>
|
|
714
|
+
<tr>
|
|
715
|
+
<td align="center"><a href="https://github.com/denisvmedia"><img src="https://github.com/denisvmedia.png?size=80" width="64" alt="denisvmedia" /><br /><sub><b>denisvmedia</b></sub></a></td>
|
|
716
|
+
<td align="center"><a href="https://github.com/amritkang165"><img src="https://github.com/amritkang165.png?size=80" width="64" alt="amritkang165" /><br /><sub><b>amritkang165</b></sub></a></td>
|
|
717
|
+
<td align="center"><a href="https://github.com/airdropia"><img src="https://github.com/airdropia.png?size=80" width="64" alt="airdropia" /><br /><sub><b>airdropia</b></sub></a></td>
|
|
718
|
+
<td align="center"><a href="https://github.com/adity982"><img src="https://github.com/adity982.png?size=80" width="64" alt="adity982" /><br /><sub><b>adity982</b></sub></a></td>
|
|
719
|
+
<td align="center"><a href="https://github.com/YuuGR1337"><img src="https://github.com/YuuGR1337.png?size=80" width="64" alt="YuuGR1337" /><br /><sub><b>YuuGR1337</b></sub></a></td>
|
|
720
|
+
<td align="center"><a href="https://github.com/WilsonSoetomo"><img src="https://github.com/WilsonSoetomo.png?size=80" width="64" alt="WilsonSoetomo" /><br /><sub><b>WilsonSoetomo</b></sub></a></td>
|
|
721
|
+
</tr>
|
|
722
|
+
<tr>
|
|
723
|
+
<td align="center"><a href="https://github.com/Vignesh2662006"><img src="https://github.com/Vignesh2662006.png?size=80" width="64" alt="Vignesh2662006" /><br /><sub><b>Vignesh2662006</b></sub></a></td>
|
|
724
|
+
<td align="center"><a href="https://github.com/Samueldavidddsc"><img src="https://github.com/Samueldavidddsc.png?size=80" width="64" alt="Samueldavidddsc" /><br /><sub><b>Samueldavidddsc</b></sub></a></td>
|
|
725
|
+
<td align="center"><a href="https://github.com/Murphyvon"><img src="https://github.com/Murphyvon.png?size=80" width="64" alt="Murphyvon" /><br /><sub><b>Murphyvon</b></sub></a></td>
|
|
726
|
+
<td align="center"><a href="https://github.com/KeuqS"><img src="https://github.com/KeuqS.png?size=80" width="64" alt="KeuqS" /><br /><sub><b>KeuqS</b></sub></a></td>
|
|
727
|
+
<td align="center"><a href="https://github.com/Golden007-prog"><img src="https://github.com/Golden007-prog.png?size=80" width="64" alt="Golden007-prog" /><br /><sub><b>Golden007-prog</b></sub></a></td>
|
|
728
|
+
<td align="center"><a href="https://github.com/GeoCeff"><img src="https://github.com/GeoCeff.png?size=80" width="64" alt="GeoCeff" /><br /><sub><b>GeoCeff</b></sub></a></td>
|
|
729
|
+
</tr>
|
|
730
|
+
<tr>
|
|
731
|
+
<td align="center"><a href="https://github.com/Enard52"><img src="https://github.com/Enard52.png?size=80" width="64" alt="Enard52" /><br /><sub><b>Enard52</b></sub></a></td>
|
|
732
|
+
</tr>
|
|
733
|
+
</table>
|
|
481
734
|
|
|
482
735
|
Flisk is MIT-licensed; see [LICENSE](LICENSE). The [license boundary](docs/project/GOVERNANCE.md#license-boundary-and-donation-scope) says which code is MIT and which is downloaded with a key.
|
|
483
736
|
|
|
@@ -651,6 +651,67 @@ export function checkResourceDiscovery() {
|
|
|
651
651
|
fix: "Move each under services/<stack>/<name>, or add a matching pattern to discovery.paths in .flisk/project.json and run: flisk config regenerate",
|
|
652
652
|
};
|
|
653
653
|
}
|
|
654
|
+
/**
|
|
655
|
+
* `.autogenerated/` is written by `flisk up`, so a resource without it has simply not been generated yet.
|
|
656
|
+
* That is a warning, not a failure: `flisk doctor` is also run before the first `flisk up`.
|
|
657
|
+
*/
|
|
658
|
+
/** Regular files under `.autogenerated/`, nested ones included, without the `.flisk-contract` bookkeeping directory. */
|
|
659
|
+
function listGeneratedFiles(root) {
|
|
660
|
+
const files = [];
|
|
661
|
+
const collect = (dir, relativeDir) => {
|
|
662
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
663
|
+
if (relativeDir === "" && entry.name === ".flisk-contract")
|
|
664
|
+
continue;
|
|
665
|
+
const relativeFile = relativeDir === "" ? entry.name : `${relativeDir}/${entry.name}`;
|
|
666
|
+
if (entry.isDirectory())
|
|
667
|
+
collect(join(dir, entry.name), relativeFile);
|
|
668
|
+
else if (entry.isFile())
|
|
669
|
+
files.push(relativeFile);
|
|
670
|
+
}
|
|
671
|
+
};
|
|
672
|
+
collect(root, "");
|
|
673
|
+
return files.sort();
|
|
674
|
+
}
|
|
675
|
+
export function checkGeneratedFiles(strict = false) {
|
|
676
|
+
const projectRoot = findProjectRoot() ?? process.cwd();
|
|
677
|
+
const resources = discoverResourcesFromRoot(projectRoot).filter((resource) => (resource.config?.appType ?? resource.type) !== "library");
|
|
678
|
+
if (resources.length === 0) {
|
|
679
|
+
return {
|
|
680
|
+
name: "Generated Files",
|
|
681
|
+
didPass: true,
|
|
682
|
+
isSkipped: true,
|
|
683
|
+
message: "No resources to check",
|
|
684
|
+
};
|
|
685
|
+
}
|
|
686
|
+
const lines = [];
|
|
687
|
+
const missing = [];
|
|
688
|
+
for (const resource of resources) {
|
|
689
|
+
const label = normalize(relative(projectRoot, resource.path));
|
|
690
|
+
const dir = join(resource.path, AUTOGENERATED_DIR);
|
|
691
|
+
const files = existsSync(dir) ? listGeneratedFiles(dir) : [];
|
|
692
|
+
if (files.length === 0) {
|
|
693
|
+
missing.push(label);
|
|
694
|
+
lines.push(`${label}: no ${AUTOGENERATED_DIR}/ files`);
|
|
695
|
+
}
|
|
696
|
+
else {
|
|
697
|
+
lines.push(`${label}: ${files.join(", ")}`);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
if (missing.length === 0) {
|
|
701
|
+
return {
|
|
702
|
+
name: "Generated Files",
|
|
703
|
+
didPass: true,
|
|
704
|
+
message: `${formatCount(resources.length, "resource")} with generated files:\n ${lines.join("\n ")}`,
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
return {
|
|
708
|
+
name: "Generated Files",
|
|
709
|
+
didPass: false,
|
|
710
|
+
isWarning: !strict,
|
|
711
|
+
message: `${missing.length} of ${formatCount(resources.length, "resource")} not generated yet:\n ${lines.join("\n ")}`,
|
|
712
|
+
fix: "Run `flisk up` to generate them (it needs Docker, Compose and Tilt). `flisk config verify` checks the project-level files only.",
|
|
713
|
+
};
|
|
714
|
+
}
|
|
654
715
|
// The scripts `flisk project` copies into every project. Generated Dockerfiles
|
|
655
716
|
// may reference others; those are checked by scanning the Dockerfiles below.
|
|
656
717
|
const REQUIRED_DOCKER_TEMPLATE_FILES = [
|
|
@@ -1376,6 +1437,7 @@ export const doctorCommand = new Command("doctor")
|
|
|
1376
1437
|
() => checkFliskVersion(),
|
|
1377
1438
|
checkMasterConfigs,
|
|
1378
1439
|
checkGeneratedProjectRuntimeAssets,
|
|
1440
|
+
() => checkGeneratedFiles(options.strict),
|
|
1379
1441
|
checkStarlarkLoadExports,
|
|
1380
1442
|
checkStartupScripts,
|
|
1381
1443
|
// A backend without its health route never turns healthy; Traefik 404s it.
|
|
@@ -4,7 +4,8 @@ import { statSync } from "node:fs";
|
|
|
4
4
|
import { join, resolve } from "node:path";
|
|
5
5
|
import { Command } from "commander";
|
|
6
6
|
import { findCliAssetRoot, loadTemplate } from "../generator/template-engine.js";
|
|
7
|
-
import { describeLayoutProblems, EXTENSION_DIRS, inspectExtensionLayout, resolveExtensionDir, resolveTiltfile, } from "../utils/runtime-layout.js";
|
|
7
|
+
import { describeLayoutProblems, EXTENSION_DIRS, inspectExtensionLayout, resolveExtensionDir, resolveSharedPlatformDir, resolveTiltfile, } from "../utils/runtime-layout.js";
|
|
8
|
+
const SHARED_PLATFORM_TEMPLATES = "shared-platform-engineering/docker-templates";
|
|
8
9
|
const REQUIRED_ASSET_PATHS = [
|
|
9
10
|
{ path: "Tiltfile", directory: false },
|
|
10
11
|
{ path: "engine", directory: true },
|
|
@@ -12,7 +13,7 @@ const REQUIRED_ASSET_PATHS = [
|
|
|
12
13
|
{ path: "specs", directory: true },
|
|
13
14
|
{ path: "ext", directory: true },
|
|
14
15
|
{ path: "cli/templates", directory: true },
|
|
15
|
-
{ path:
|
|
16
|
+
{ path: SHARED_PLATFORM_TEMPLATES, directory: true },
|
|
16
17
|
];
|
|
17
18
|
const EXTENSION_NAMES = new Set(EXTENSION_DIRS);
|
|
18
19
|
const REQUIRED_TEMPLATES = [
|
|
@@ -41,7 +42,9 @@ export const runtimeCommand = new Command("runtime")
|
|
|
41
42
|
? resolveExtensionDir(assetRoot, path)
|
|
42
43
|
: path === "Tiltfile"
|
|
43
44
|
? resolveTiltfile(assetRoot)
|
|
44
|
-
:
|
|
45
|
+
: path === SHARED_PLATFORM_TEMPLATES
|
|
46
|
+
? join(resolveSharedPlatformDir(assetRoot), "docker-templates")
|
|
47
|
+
: join(assetRoot, path));
|
|
45
48
|
return directory ? !stats.isDirectory() : !stats.isFile();
|
|
46
49
|
}
|
|
47
50
|
catch {
|
|
@@ -10,7 +10,7 @@ import { AUTOGENERATED_DIR, DATABASE_MANAGEMENT_FEATURE, DOCKER_COMPOSE_FILE, PA
|
|
|
10
10
|
import { writeTextFile } from "../utils/file-helpers.js";
|
|
11
11
|
import { assertFliskGeneratedPath } from "../utils/generated-paths.js";
|
|
12
12
|
import { DEFAULT_ALWAYS_ENABLED_INFRA } from "../utils/project-config-defaults.js";
|
|
13
|
-
import { describeLayoutProblems, EXTENSION_DIRS, hasExtensionLayout, inspectExtensionLayout, resolveExtensionDir, resolveTiltfile, } from "../utils/runtime-layout.js";
|
|
13
|
+
import { describeLayoutProblems, EXTENSION_DIRS, hasExtensionLayout, inspectExtensionLayout, resolveExtensionDir, resolveSharedPlatformDir, resolveTiltfile, } from "../utils/runtime-layout.js";
|
|
14
14
|
import { generatedFieldErrorsForFile, validateServiceManifestFile, } from "../utils/service-manifest.js";
|
|
15
15
|
import { discoverResourcesFromRoot, discoverServiceManifestPaths } from "../utils/services.js";
|
|
16
16
|
import { isStackFeatureEnabledInStacks } from "../utils/stack-features.js";
|
|
@@ -582,10 +582,13 @@ function findSelfContainedEngineRoot() {
|
|
|
582
582
|
}
|
|
583
583
|
return null;
|
|
584
584
|
}
|
|
585
|
+
function hasDockerTemplates(sourceRoot) {
|
|
586
|
+
return fs.existsSync(path.join(resolveSharedPlatformDir(sourceRoot), "docker-templates"));
|
|
587
|
+
}
|
|
585
588
|
export function findCliAssetRoot() {
|
|
586
589
|
let dir = import.meta.dirname || process.cwd();
|
|
587
590
|
for (let i = 0; i < 8; i++) {
|
|
588
|
-
if (
|
|
591
|
+
if (hasDockerTemplates(dir)) {
|
|
589
592
|
return dir;
|
|
590
593
|
}
|
|
591
594
|
const parent = path.dirname(dir);
|
|
@@ -598,7 +601,7 @@ export function findCliAssetRoot() {
|
|
|
598
601
|
path.join(exeDir, "flisk-cli"),
|
|
599
602
|
path.join(process.cwd(), "node_modules", "@flisk-sh", "flisk"),
|
|
600
603
|
];
|
|
601
|
-
return
|
|
604
|
+
return candidates.find(hasDockerTemplates) ?? null;
|
|
602
605
|
}
|
|
603
606
|
export function ensureProjectRuntimeAssets(projectRoot) {
|
|
604
607
|
const sourceRoot = findCliAssetRoot();
|
|
@@ -609,7 +612,7 @@ export function ensureProjectRuntimeAssets(projectRoot) {
|
|
|
609
612
|
return copied;
|
|
610
613
|
}
|
|
611
614
|
for (const parts of PROJECT_RUNTIME_ASSET_DIRS) {
|
|
612
|
-
const source = path.join(sourceRoot, ...parts);
|
|
615
|
+
const source = path.join(resolveSharedPlatformDir(sourceRoot), ...parts.slice(1));
|
|
613
616
|
const target = assertFliskGeneratedPath(projectRoot, path.join(...parts));
|
|
614
617
|
if (!fs.existsSync(source)) {
|
|
615
618
|
continue;
|