@flisk-sh/flisk 1.4.2 → 1.4.6
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/CHANGELOG.md +4 -0
- package/README.md +148 -49
- package/cli/dist/backend-languages/bun.js +5 -0
- package/cli/dist/backend-languages/go.js +3 -1
- package/cli/dist/cli.js +9 -0
- package/cli/dist/commands/completion.js +8 -1
- package/cli/dist/commands/config.js +130 -55
- package/cli/dist/commands/doctor.js +66 -27
- package/cli/dist/commands/down.js +33 -1
- package/cli/dist/commands/logs.js +39 -1
- package/cli/dist/commands/project.js +12 -0
- package/cli/dist/commands/resource.js +39 -11
- package/cli/dist/commands/status.js +57 -19
- package/cli/dist/commands/up.js +221 -18
- package/cli/dist/commands/upgrade.js +2 -2
- package/cli/dist/frontend-frameworks/next.js +197 -0
- package/cli/dist/frontend-frameworks/react.js +81 -12
- package/cli/dist/frontend-frameworks/registry.js +5 -4
- package/cli/dist/frontend-frameworks/vue.js +82 -12
- package/cli/dist/generator/resource-templates.js +2 -4
- package/cli/dist/generator/template-engine.js +5 -3
- package/cli/dist/utils/bun-requirement.js +7 -4
- package/cli/dist/utils/cold-preflight.js +55 -34
- package/cli/dist/utils/config-explain.js +197 -0
- package/cli/dist/utils/demo-reset.js +22 -0
- package/cli/dist/utils/discovery-paths.js +7 -1
- package/cli/dist/utils/doctor-native.js +96 -0
- package/cli/dist/utils/host-port-plan.js +8 -3
- package/cli/dist/utils/native-project.js +41 -0
- package/cli/dist/utils/native-runtime.js +513 -0
- package/cli/dist/utils/native-service.js +95 -0
- package/cli/dist/utils/native-up.js +156 -0
- package/cli/dist/utils/platform.js +1 -1
- package/cli/dist/utils/port-conflict-fix.js +16 -14
- package/cli/dist/utils/port-occupant.js +35 -0
- package/cli/dist/utils/project-features.js +7 -16
- package/cli/dist/utils/project-templates.js +9 -9
- package/cli/dist/utils/resource-features.js +5 -5
- package/cli/dist/utils/service-manifest.js +20 -3
- package/cli/dist/utils/service-urls.js +11 -0
- package/cli/dist/utils/services.js +15 -2
- package/cli/dist/utils/startup-report.js +4 -3
- package/cli/dist/utils/tar.js +33 -28
- package/cli/dist/utils/tilt-logs.js +8 -0
- package/cli/dist/utils/tilt-process.js +4 -3
- package/cli/dist/utils/windows-doctor.js +18 -15
- package/cli/dist-bundle/chunk-BIVAAWBX.js +24 -0
- package/cli/dist-bundle/{chunk-YNCBBJ4V.js → chunk-C4UFBXRD.js} +1 -1
- package/cli/dist-bundle/{chunk-53L2JN7G.js → chunk-CAEMWNPF.js} +1 -1
- package/cli/dist-bundle/chunk-CDKEHFW6.js +35 -0
- package/cli/dist-bundle/{chunk-5QBYM33Q.js → chunk-DPQK5TIS.js} +1 -1
- package/cli/dist-bundle/chunk-ETXZ5LUG.js +18 -0
- package/cli/dist-bundle/chunk-GPUJ55MI.js +3 -0
- package/cli/dist-bundle/chunk-GT76VMUL.js +130 -0
- package/cli/dist-bundle/{chunk-IGN5UC3P.js → chunk-IDNES5PE.js} +14 -7
- package/cli/dist-bundle/{chunk-MWOVYIBB.js → chunk-MUDE4DZD.js} +5 -5
- package/cli/dist-bundle/chunk-QEBN6ZVQ.js +2 -0
- package/cli/dist-bundle/{chunk-I7TGIK5N.js → chunk-R7DWXISM.js} +1 -1
- package/cli/dist-bundle/{chunk-DU2BN46C.js → chunk-U5FCQF42.js} +1 -1
- package/cli/dist-bundle/{chunk-3XODDLRJ.js → chunk-WCGBVETR.js} +1 -1
- package/cli/dist-bundle/cli.js +626 -389
- package/cli/dist-bundle/cold-preflight-KUWOL2Q2.js +2 -0
- package/cli/dist-bundle/{demo-stage-OHNTP2UJ.js → demo-stage-QCC4IWXR.js} +1 -1
- package/cli/dist-bundle/{extension-fetch-VEFSCG4B.js → extension-fetch-KIPYDIRM.js} +1 -1
- package/cli/dist-bundle/{open-XROJ6YEY.js → open-AZNX4AC5.js} +1 -1
- package/cli/dist-bundle/project-5SWIGCNP.js +2 -0
- package/cli/dist-bundle/{project-templates-EYSQG2EO.js → project-templates-2VQPUBSQ.js} +1 -1
- package/cli/dist-bundle/{services-BIMF6MVU.js → services-EY5WKPHQ.js} +1 -1
- package/cli/dist-bundle/{tilt-port-owner-ZY5M2JC4.js → tilt-port-owner-UBU6JWOA.js} +1 -1
- package/cli/package.json +1 -1
- package/examples/{tdk-example → flisk-example}/README.md +2 -2
- package/package.json +2 -2
- package/runtime/discovery/AGENTS.md +1 -1
- package/runtime/discovery/TILT_DISCOVERY.star +1 -1
- package/runtime/discovery/deterministic.star +1 -1
- package/runtime/engine/AGENTS.md +3 -3
- package/runtime/engine/README.md +1 -1
- package/runtime/engine/REFACTORING_MANIFEST_SYSTEM.md +1 -1
- package/runtime/engine/assets/docker/wake-gateway/decide.ts +1 -1
- package/runtime/engine/assets/docker/wake-gateway/server.ts +2 -2
- package/runtime/engine/assets/scripts/mac-m1-resource-monitor.sh +6 -6
- package/runtime/engine/schemas/service-schema.json +99 -21
- package/runtime/engine/scripts/debug-container.sh +1 -1
- package/runtime/engine/scripts/generate-manifest.sh +2 -2
- package/runtime/engine/topologies/platform/docker/compose/compose.star +40 -4
- package/runtime/engine/topologies/platform/docker/compose/traefik_standalone.star +19 -4
- package/runtime/engine/topologies/platform/docker/constants.star +2 -2
- package/runtime/engine/topologies/platform/docker/dockerfile/language_dockerfile.star +6 -0
- package/runtime/engine/topologies/platform/docker/dockerfile/next_dockerfile.star +83 -0
- package/runtime/engine/topologies/platform/docker/index.star +4 -0
- package/runtime/engine/topologies/platform/docker/layers/prisma/filesystem_setup.star +7 -0
- package/runtime/engine/topologies/platform/docker/networking/traefik.star +85 -46
- package/runtime/engine/topologies/platform/docker/networking/traefik_static_routes.star +2 -2
- package/runtime/engine/topologies/tilt/common/utils_output.star +1 -0
- package/runtime/engine/topologies/tilt/generators/validators.star +1 -1
- package/runtime/engine/topologies/tilt/generators/vite/frontend.star +2 -2
- package/runtime/engine/topologies/tilt/generators/vite/generators.star +3 -0
- package/runtime/engine/topologies/tilt/manifest/constants.star +3 -0
- package/runtime/engine/topologies/tilt/manifest/mapper.star +1 -1
- package/runtime/engine/topologies/tilt/manifest/parser.star +9 -3
- package/runtime/engine/topologies/tilt/resources/orchestrator/apply_compose_resource_registration.star +9 -4
- package/runtime/engine/topologies/tilt/resources/orchestrator/generators/dependencies/resolver.star +50 -24
- package/runtime/engine/topologies/tilt/resources/orchestrator/generators/env.star +11 -2
- package/runtime/engine/topologies/tilt/resources/orchestrator/generators/manifest_resource.star +23 -9
- package/runtime/ext/ide-components/README.md +1 -1
- package/runtime/ext/ui-enhancements/extension.yaml +2 -2
- package/runtime/specs/specs/TILT_SERVICE_DEFAULTS.star +1 -1
- package/runtime/specs/specs/TILT_TECH_STACK.star +1 -1
- package/cli/dist-bundle/chunk-43XWL2PB.js +0 -61
- package/cli/dist-bundle/chunk-5F7YP5IR.js +0 -17
- package/cli/dist-bundle/chunk-ETKUVKJ2.js +0 -35
- package/cli/dist-bundle/chunk-K6SOCO6V.js +0 -3
- package/cli/dist-bundle/chunk-YHYRGWUH.js +0 -24
- package/cli/dist-bundle/chunk-YL56J2WX.js +0 -2
- package/cli/dist-bundle/cold-preflight-ZOPR7PWJ.js +0 -2
- package/cli/dist-bundle/project-7PTIOHGF.js +0 -2
- /package/examples/{tdk-example → flisk-example}/LICENSE +0 -0
- /package/examples/{tdk-example → flisk-example}/TILT_SERVICE_DEFAULTS.star +0 -0
- /package/examples/{tdk-example → flisk-example}/TILT_TECH_STACK.star +0 -0
- /package/examples/{tdk-example → flisk-example}/Tiltfile +0 -0
- /package/examples/{tdk-example → flisk-example}/services/platform/messaging/docker-compose.yml +0 -0
- /package/examples/{tdk-example → flisk-example}/services/shop/orders-api/package.json +0 -0
- /package/examples/{tdk-example → flisk-example}/services/shop/orders-api/service.json +0 -0
- /package/examples/{tdk-example → flisk-example}/services/shop/orders-api/src/index.ts +0 -0
- /package/examples/{tdk-example → flisk-example}/services/shop/orders-app/index.html +0 -0
- /package/examples/{tdk-example → flisk-example}/services/shop/orders-app/package.json +0 -0
- /package/examples/{tdk-example → flisk-example}/services/shop/orders-app/public/.gitkeep +0 -0
- /package/examples/{tdk-example → flisk-example}/services/shop/orders-app/service.json +0 -0
- /package/examples/{tdk-example → flisk-example}/services/shop/orders-app/src/main.tsx +0 -0
- /package/examples/{tdk-example → flisk-example}/services/shop/orders-app/src/orders.tsx +0 -0
- /package/examples/{tdk-example → flisk-example}/services/shop/orders-app/src/style.css +0 -0
- /package/examples/{tdk-example → flisk-example}/services/shop/orders-worker/package.json +0 -0
- /package/examples/{tdk-example → flisk-example}/services/shop/orders-worker/service.json +0 -0
- /package/examples/{tdk-example → flisk-example}/services/shop/orders-worker/src/index.ts +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
Notable changes to the `flisk` CLI. Versions match [npm](https://www.npmjs.com/package/@flisk-sh/flisk?activeTab=versions) and the [binary releases](https://github.com/flisk-sh/releases/releases).
|
|
4
4
|
|
|
5
|
+
## 1.4.3 (2026-10-25)
|
|
6
|
+
|
|
7
|
+
- `flisk init` is now an alias of `flisk project`. It accepts the same template names and flags.
|
|
8
|
+
|
|
5
9
|
## 1.3.195 (2026-10-21)
|
|
6
10
|
|
|
7
11
|
- `flisk demo` and `flisk restaurant` now clone the demo template into a fixed directory (`~/.flisk/flisk-demo/`) instead of creating `tdk-restaurant-example-N` directories in the current workspace. Previous runs are cleaned up automatically. The `restaurant` template still creates a named directory in the current folder when used explicitly.
|
package/README.md
CHANGED
|
@@ -81,7 +81,11 @@ Stop my Flisk stack with flisk down and confirm nothing is left running.
|
|
|
81
81
|
<details>
|
|
82
82
|
<summary>Connect your agent to Flisk as an MCP server</summary>
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
Install the CLI, then add the Flisk MCP server to your agent's settings:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
npm install -g @flisk-sh/flisk
|
|
88
|
+
```
|
|
85
89
|
|
|
86
90
|
```json
|
|
87
91
|
{
|
|
@@ -110,13 +114,13 @@ flisk resource shop-web --type frontend --stack shop --yes
|
|
|
110
114
|
flisk up shop
|
|
111
115
|
```
|
|
112
116
|
|
|
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.
|
|
117
|
+
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. A simpler app needs none of those: give each service a `command` and [run it as local processes](docs/run-without-docker.md). 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
118
|
|
|
115
119
|
<div align="center">
|
|
116
120
|
|
|
117
121
|
<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
122
|
|
|
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-
|
|
123
|
+
[Website](https://flisk.sh/) · [Quickstart](https://flisk.sh/docs/quickstart/) · [Examples](https://flisk.sh/docs/examples/) · [Awesome Flisk](https://github.com/flisk-sh/awesome-flisk-framework) · [Demo](https://flisk-sh.github.io/flisk-demo-animation/) · [Report a bug](https://github.com/flisk-sh/flisk/issues)
|
|
120
124
|
|
|
121
125
|
<a id="readme-languages"></a>
|
|
122
126
|
|
|
@@ -223,12 +227,9 @@ Fastest way (recommended): open the [Flisk starter](https://github.com/flisk-sh/
|
|
|
223
227
|
|
|
224
228
|
</details>
|
|
225
229
|
|
|
226
|
-
### ⚡ A
|
|
230
|
+
### ⚡ A one-backend stack is healthy in about 14 seconds
|
|
227
231
|
|
|
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.
|
|
229
|
-
* **Runtimes & Frameworks:** Bun, Node, Python, Go, Rust, React, Vue, Svelte, Elysia, Fastify, NestJS
|
|
230
|
-
* **Databases & Tooling:** Prisma, Drizzle, Atlas, Dbmate
|
|
231
|
-
* **Messaging & Gateway:** NATS, Traefik
|
|
232
|
+
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.
|
|
232
233
|
|
|
233
234
|
### 🤖 Run your AI agents next to your services
|
|
234
235
|
|
|
@@ -244,7 +245,7 @@ flisk up shop
|
|
|
244
245
|
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).
|
|
245
246
|
|
|
246
247
|
|
|
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.
|
|
248
|
+
**What Flisk is:** a local development runtime. Define each service in `service.json` and run `flisk up`. A service with a `command` runs as a local process, with nothing else installed. When you need a database, one gateway URL, or the container you deploy, Docker runs the containers, Tilt live-updates them while you code, and Flisk writes the configuration both use. No local Kubernetes is needed.
|
|
248
249
|
|
|
249
250
|
**What Flisk is not:** a deploy tool or a Compose file. Production deployment stays with Helm, Argo CD, or Kustomize.
|
|
250
251
|
|
|
@@ -311,6 +312,12 @@ See [how `flisk up` works](docs/how-flisk-up-works.md) for the full startup sequ
|
|
|
311
312
|
| Catch config drift | Compares generated files with what Flisk last wrote | `flisk config verify` |
|
|
312
313
|
| Keep Flisk current | Upgrades the CLI in place | `flisk upgrade` |
|
|
313
314
|
|
|
315
|
+
Flisk works with:
|
|
316
|
+
|
|
317
|
+
* **Runtimes & Frameworks:** Bun, Node, Python, Go, Rust, React, Vue, Svelte, Elysia, Fastify, NestJS
|
|
318
|
+
* **Databases & Tooling:** Prisma, Drizzle, Atlas, Dbmate
|
|
319
|
+
* **Messaging & Gateway:** NATS, Traefik
|
|
320
|
+
|
|
314
321
|
## Who uses Flisk
|
|
315
322
|
|
|
316
323
|
Teams that run `flisk up` on their own code (listed with their consent in [ADOPTERS.md](docs/project/ADOPTERS.md)):
|
|
@@ -326,67 +333,157 @@ If Flisk saves you time, a ⭐ on [this repo](https://github.com/flisk-sh/flisk)
|
|
|
326
333
|
|
|
327
334
|
## Quick start
|
|
328
335
|
|
|
329
|
-
|
|
336
|
+
Get a running local stack in **3 commands**. Works on macOS, Linux, and Windows (via WSL2).
|
|
330
337
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
|
334
|
-
|
|
338
|
+
### Prerequisites (install once)
|
|
339
|
+
|
|
340
|
+
| Tool | Version | Install | Needed for |
|
|
341
|
+
|------|---------|---------|------------|
|
|
342
|
+
| **Your app's runtime** | whatever your app uses | Node.js, Python, Go, Bun, ... | Every path: it runs your code |
|
|
343
|
+
| **Node.js** | 22.12+ | [nodejs.org](https://nodejs.org/) | npm install (`npm install -g @flisk-sh/flisk`) |
|
|
344
|
+
| **Docker** | Engine 25+, Compose 2.20.2+ | [docker.com](https://www.docker.com/products/docker-desktop/) | Docker + Tilt path only |
|
|
345
|
+
| **Tilt** | 0.25+ | `curl -fsSL https://raw.githubusercontent.com/tilt-dev/tilt/master/scripts/install.sh \| bash` | Docker + Tilt path only |
|
|
346
|
+
| **Bun** | 1.2+ | `curl -fsSL https://bun.sh/install \| bash` | Bun install (`bun add -g @flisk-sh/flisk`), or generated JavaScript services |
|
|
335
347
|
|
|
336
|
-
|
|
348
|
+
> **Two paths.** A project whose services each declare a `command` runs them as local processes: you need only Flisk and your app's runtime ([simplest path](#simplest-path-no-docker)). Docker and Tilt are needed for the Docker + Tilt path: databases such as Postgres, one gateway URL for every service, and running the same container you deploy. `flisk doctor` checks only what your project uses.
|
|
337
349
|
|
|
338
|
-
**
|
|
350
|
+
> **Windows?** Use WSL2 Ubuntu. See the [Windows & WSL2 guide](docs/wsl2.md) for the recommended setup.
|
|
339
351
|
|
|
340
|
-
|
|
341
|
-
- Docker, installed and running (Engine 25+, Compose 2.20.2+)
|
|
342
|
-
- [Tilt](https://docs.tilt.dev/install.html)
|
|
343
|
-
- [Bun](https://bun.sh/) 1.2+
|
|
352
|
+
---
|
|
344
353
|
|
|
345
|
-
|
|
354
|
+
### Simplest path: no Docker
|
|
355
|
+
|
|
356
|
+
For an app made of services you can start with one command each (an API, a website, a worker), put a `service.json` next to each one:
|
|
357
|
+
|
|
358
|
+
```json
|
|
359
|
+
{ "schemaVersion": 1, "name": "api", "command": "node server.js", "port": 4000, "healthCheckPath": "/health" }
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
```json
|
|
363
|
+
{ "schemaVersion": 1, "name": "web", "command": "node server.js", "port": 3000, "dependsOn": ["api"] }
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
Then start everything from the project folder:
|
|
346
367
|
|
|
347
368
|
```bash
|
|
369
|
+
flisk up
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
Flisk starts the API, waits until it answers, starts the website, prints both URLs, prefixes each line of output with the service name, and restarts a service that crashes. Ctrl+C or `flisk down` stops them. No Docker, no Tilt, no generated files. See [Run your app without Docker](docs/run-without-docker.md) for every field, and for when to switch to the Docker + Tilt path.
|
|
373
|
+
|
|
374
|
+
---
|
|
375
|
+
|
|
376
|
+
### Fastest path: one-command demo (no manual steps)
|
|
377
|
+
|
|
378
|
+
```bash
|
|
379
|
+
# 1. Install Flisk
|
|
348
380
|
npm install -g @flisk-sh/flisk
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
flisk
|
|
381
|
+
|
|
382
|
+
# 2. Run the demo — scaffolds a project, installs deps, boots the stack, opens the frontend
|
|
383
|
+
flisk demo
|
|
352
384
|
```
|
|
353
385
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
386
|
+
That's it. The demo clones the starter into `~/.flisk/flisk-demo`, installs dependencies, starts the stack, and opens the frontend in your browser. Press `Ctrl+C` to stop, then run `flisk down` to clean up.
|
|
387
|
+
|
|
388
|
+
---
|
|
357
389
|
|
|
358
|
-
|
|
390
|
+
### Full control: manual project setup
|
|
359
391
|
|
|
360
|
-
|
|
392
|
+
If you want to build your own service structure:
|
|
361
393
|
|
|
362
394
|
```bash
|
|
363
|
-
|
|
395
|
+
# 1. Install Flisk (skip if already installed)
|
|
396
|
+
npm install -g @flisk-sh/flisk
|
|
397
|
+
|
|
398
|
+
# 2. Create a project with a backend API
|
|
399
|
+
mkdir my-project && cd my-project
|
|
400
|
+
flisk project --yes
|
|
401
|
+
flisk resource api --type backend --stack main --yes
|
|
402
|
+
|
|
403
|
+
# 3. Start the stack
|
|
404
|
+
flisk up main
|
|
364
405
|
```
|
|
365
406
|
|
|
366
|
-
|
|
407
|
+
`flisk up` prints the URLs (e.g., `http://api.main.localhost/api/api/health`). Try it:
|
|
367
408
|
|
|
368
|
-
|
|
369
|
-
|
|
409
|
+
```bash
|
|
410
|
+
curl http://api.main.localhost/api/api/health
|
|
411
|
+
```
|
|
370
412
|
|
|
371
|
-
|
|
413
|
+
To add a frontend later:
|
|
372
414
|
|
|
373
|
-
|
|
415
|
+
```bash
|
|
416
|
+
flisk resource web --type frontend --stack main --yes
|
|
417
|
+
flisk up main
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
---
|
|
421
|
+
|
|
422
|
+
### Alternative: guided scaffolder
|
|
423
|
+
|
|
424
|
+
Prefer interactive prompts? The `create-microservices` package asks for your service types and generates a ready project:
|
|
374
425
|
|
|
375
426
|
```bash
|
|
376
|
-
|
|
427
|
+
npm install -g @flisk-sh/flisk
|
|
428
|
+
npm init create-microservices my-project
|
|
429
|
+
cd my-project
|
|
430
|
+
flisk up main
|
|
377
431
|
```
|
|
378
432
|
|
|
379
|
-
|
|
433
|
+
To skip prompts and get a default `api` + `web`:
|
|
380
434
|
|
|
381
435
|
```bash
|
|
382
|
-
|
|
383
|
-
flisk project --yes
|
|
384
|
-
flisk resource orders-api --type backend --stack shop --yes
|
|
385
|
-
flisk up shop
|
|
386
|
-
curl http://api.shop.localhost/api/orders/health
|
|
436
|
+
npm init create-microservices my-project -- --yes
|
|
387
437
|
```
|
|
388
438
|
|
|
389
|
-
|
|
439
|
+
See the [`create-microservices` README](https://github.com/flisk-sh/create-microservices#readme) for all options.
|
|
440
|
+
|
|
441
|
+
---
|
|
442
|
+
|
|
443
|
+
### Verify it works
|
|
444
|
+
|
|
445
|
+
After `flisk up`, you'll see output like:
|
|
446
|
+
|
|
447
|
+
```
|
|
448
|
+
Flisk is up.
|
|
449
|
+
Tilt UI: http://localhost:10350
|
|
450
|
+
Services:
|
|
451
|
+
✓ api → http://api.main.localhost/api/api/health
|
|
452
|
+
✓ web → http://web.main.localhost
|
|
453
|
+
Stop: flisk down
|
|
454
|
+
Logs: flisk logs <service>
|
|
455
|
+
Next: flisk help # or visit https://flisk.sh/docs
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
- **Tilt UI**: Open to watch live updates, see logs, and debug
|
|
459
|
+
- **Services**: Click the URLs or curl the health endpoints
|
|
460
|
+
- **Stop**: `flisk down` stops everything; containers persist for inspection
|
|
461
|
+
|
|
462
|
+
---
|
|
463
|
+
|
|
464
|
+
### Common next steps
|
|
465
|
+
|
|
466
|
+
| Goal | Command |
|
|
467
|
+
|------|---------|
|
|
468
|
+
| See running services | `flisk ui` |
|
|
469
|
+
| Check environment health | `flisk doctor` |
|
|
470
|
+
| View service logs | `flisk logs api` |
|
|
471
|
+
| Restart a service | `flisk restart api` |
|
|
472
|
+
| Preview without starting | `flisk up main --dry-run` |
|
|
473
|
+
| Catch config drift | `flisk config verify` |
|
|
474
|
+
| Upgrade Flisk | `flisk upgrade` |
|
|
475
|
+
|
|
476
|
+
### Troubleshooting
|
|
477
|
+
|
|
478
|
+
| Issue | Fix |
|
|
479
|
+
|-------|-----|
|
|
480
|
+
| `flisk doctor` fails | Run the fix commands it prints, then retry |
|
|
481
|
+
| Port 80/5432 in use | `flisk doctor` shows the owner; stop it or set `FLISK_HTTP_PORT` |
|
|
482
|
+
| Docker not running | Start Docker Desktop / `systemctl start docker` |
|
|
483
|
+
| Windows native | Use WSL2 Ubuntu; see [Windows guide](docs/wsl2.md) |
|
|
484
|
+
| `flisk up` refuses | Run `flisk doctor` first; it explains what's missing |
|
|
485
|
+
|
|
486
|
+
Full troubleshooting: [docs/troubleshooting.md](docs/troubleshooting.md)
|
|
390
487
|
|
|
391
488
|
### What Flisk writes for you
|
|
392
489
|
|
|
@@ -522,11 +619,11 @@ Runnable examples show Flisk on real stacks. Start with the smallest one:
|
|
|
522
619
|
| [one-backend-helm](examples/one-backend-helm/README.md) | Working alongside Helm |
|
|
523
620
|
| [byo](examples/byo/README.md) | Bringing your own existing resources |
|
|
524
621
|
| [byo-jobs](examples/byo-jobs/README.md) | Bring-your-own jobs |
|
|
525
|
-
| [
|
|
622
|
+
| [flisk-example](examples/flisk-example/README.md) | A full multi-service stack |
|
|
526
623
|
|
|
527
624
|
## Use Flisk with your AI agent
|
|
528
625
|
|
|
529
|
-
The repository ships agent skills for common Flisk work,
|
|
626
|
+
The repository ships agent skills for common Flisk work under [`.agents/skills`](.agents/skills): `flisk-build` (turn "build me a shop" into Flisk steps, check every URL, and report them), `flisk-recipe-starters` (start from a working restaurant, SaaS, store, AI agent or user-management app), recipes for a shop, a SaaS with login and billing, an AI agent with MCP tools and a database, and a blog (`flisk-recipe-shop`, `flisk-recipe-saas`, `flisk-recipe-ai-agent`, `flisk-recipe-blog`), `flisk-doctor` (environment checks), `flisk-up` (preview and start a stack), `flisk-resource` (create a service), `flisk-status` (health and URLs), and `flisk-troubleshoot` (fixing `flisk` and Tilt errors). More prompts to copy, by category (spreadsheets, recruiting, product management, shops, AI agents), are in the [prompt gallery](docs/recipes/build-with-your-agent.md). Agents working in this repo also follow [AGENTS.md](AGENTS.md). Use these skills to let your agent check your setup and explain failures instead of guessing at Docker or Tilt configuration.
|
|
530
627
|
|
|
531
628
|
## Installation
|
|
532
629
|
|
|
@@ -574,7 +671,7 @@ Set `FLISK_DEBUG=1` before running `flisk up --verbose` to include Starlark debu
|
|
|
574
671
|
- [Generated service files and drift checks](docs/generated-files.md)
|
|
575
672
|
- [Runnable one-backend example](examples/one-backend/README.md)
|
|
576
673
|
- [Runnable Python backend example](examples/one-backend-python/README.md)
|
|
577
|
-
- [Full multi-service example](examples/
|
|
674
|
+
- [Full multi-service example](examples/flisk-example/README.md)
|
|
578
675
|
- [Features and license limits](docs/FEATURES.md)
|
|
579
676
|
- [Tool comparison: docker-compose, Tilt, Skaffold, DevSpace, kind](docs/comparison.md)
|
|
580
677
|
- [Honest comparison and known limits](docs/compare-honest.md)
|
|
@@ -598,7 +695,7 @@ published on 21 September 2026. Those dates describe the current repository and
|
|
|
598
695
|
|
|
599
696
|
## Requirements and support
|
|
600
697
|
|
|
601
|
-
For the local runtime, install Docker (Desktop, OrbStack, or Colima; Engine 25+, Compose 2.20.2+) and [Tilt](https://docs.tilt.dev/install.html). Bun 1.2+ is used by the default generated services. Flisk selects host ports from bounded fallback ranges for HTTP, HTTPS, and Postgres; set `FLISK_HTTP_PORT`, `FLISK_HTTPS_PORT`, or `FLISK_POSTGRES_PORT` to override them. Dev ports listen on `127.0.0.1` only, so other machines on your network cannot reach them. Set `FLISK_BIND_ADDRESS` (for example `0.0.0.0`, to test from a phone) to change that; `flisk doctor` warns when it is a wildcard address. Flisk supports macOS, Linux, and Windows through WSL2 Ubuntu
|
|
698
|
+
For the local runtime, install Docker (Desktop, OrbStack, or Colima; Engine 25+, Compose 2.20.2+) and [Tilt](https://docs.tilt.dev/install.html). Bun 1.2+ is used by the default generated services. Flisk selects host ports from bounded fallback ranges for HTTP, HTTPS, and Postgres; set `FLISK_HTTP_PORT`, `FLISK_HTTPS_PORT`, or `FLISK_POSTGRES_PORT` to override them. Dev ports listen on `127.0.0.1` only, so other machines on your network cannot reach them. Set `FLISK_BIND_ADDRESS` (for example `0.0.0.0`, to test from a phone) to change that; `flisk doctor` warns when it is a wildcard address. Flisk supports macOS, Linux, and **Windows through WSL2 Ubuntu**; native Windows supports CLI inspection only (`flisk --version`, `flisk doctor`, `flisk up --dry-run`). `flisk up` exits with a clear refusal pointing to WSL2. See the **[Windows & WSL2 guide](docs/wsl2.md)** for the recommended setup, prerequisites, verification steps, and troubleshooting.
|
|
602
699
|
|
|
603
700
|
On native Windows, `flisk --version`, `flisk doctor`, and `flisk up --dry-run` are inspect-only commands. `flisk up` exits 1 with “Landscape startup needs Ubuntu on WSL2. Native Windows is inspect-only.”
|
|
604
701
|
|
|
@@ -612,7 +709,7 @@ On native Windows, `flisk --version`, `flisk doctor`, and `flisk up --dry-run` a
|
|
|
612
709
|
|
|
613
710
|
Core stays free. Premium is a separate key for the extras above; no key required to run `flisk up`.
|
|
614
711
|
|
|
615
|
-
**Ecosystem map:** examples, articles, related tools, and notes live in [awesome-
|
|
712
|
+
**Ecosystem map:** examples, articles, related tools, and notes live in [awesome-flisk-framework](https://github.com/flisk-sh/awesome-flisk-framework). Star this repo (`flisk`) if the CLI is what you run; use the awesome list to browse the rest.
|
|
616
713
|
|
|
617
714
|
<p align="center">
|
|
618
715
|
|
|
@@ -639,7 +736,7 @@ No. Core CLI is MIT and needs no key to run `flisk up`. Premium extras are optio
|
|
|
639
736
|
<details>
|
|
640
737
|
<summary><strong>Which platforms are supported?</strong></summary>
|
|
641
738
|
|
|
642
|
-
macOS and Linux are supported directly. Windows is supported through WSL2 Ubuntu; native Windows supports CLI inspection only (`flisk --version`, `flisk doctor`,
|
|
739
|
+
macOS and Linux are supported directly. Windows is supported through WSL2 Ubuntu; native Windows supports CLI inspection only (`flisk --version`, `flisk doctor`, `flisk up --dry-run`). See [Requirements and support](#requirements-and-support) and the **[Windows & WSL2 guide](docs/wsl2.md)** for the recommended setup, prerequisites, verification steps, and troubleshooting.
|
|
643
740
|
|
|
644
741
|
</details>
|
|
645
742
|
|
|
@@ -735,3 +832,5 @@ Thank you to everyone who has shipped code, docs, and fixes to Flisk since July
|
|
|
735
832
|
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.
|
|
736
833
|
|
|
737
834
|
Project governance: [GOVERNANCE.md](docs/project/GOVERNANCE.md), [MAINTAINERS.md](docs/project/MAINTAINERS.md), [ADOPTERS.md](docs/project/ADOPTERS.md).
|
|
835
|
+
|
|
836
|
+
<img src='https://raw.githubusercontent.com/flisk-sh/flisk-emoji/main/png/flisk-thunder-64.png' width='20' alt='flisk'> Using Flisk in Slack or Discord? Get the [Flisk green thunder emoji](https://github.com/flisk-sh/flisk-emoji) (SVG and PNG, MIT).
|
|
@@ -24,9 +24,14 @@ app.get('/health/db', async (c) => {
|
|
|
24
24
|
`
|
|
25
25
|
: "";
|
|
26
26
|
return `import { Hono } from 'hono';
|
|
27
|
+
import { cors } from 'hono/cors';
|
|
27
28
|
${drizzleImports}
|
|
28
29
|
const app = new Hono();
|
|
29
30
|
|
|
31
|
+
// The frontend runs on its own *.localhost origin (app.<project>.localhost), so the browser needs CORS to call this API.
|
|
32
|
+
const LOCAL_FRONTEND_ORIGIN = /^https?:\\/\\/([a-z0-9-]+\\.)+localhost(:\\d+)?$/;
|
|
33
|
+
app.use('*', cors({ origin: (origin) => (LOCAL_FRONTEND_ORIGIN.test(origin) ? origin : undefined) }));
|
|
34
|
+
|
|
30
35
|
// Health check endpoint (required by TILT_RESOURCE_DEFAULTS.star)
|
|
31
36
|
app.get('/health', (c) => {
|
|
32
37
|
return c.json({ status: 'ok', service: '${name}' });
|
|
@@ -34,7 +34,9 @@ import (
|
|
|
34
34
|
func writeJSON(w http.ResponseWriter, status int, body any) {
|
|
35
35
|
w.Header().Set("Content-Type", "application/json")
|
|
36
36
|
w.WriteHeader(status)
|
|
37
|
-
|
|
37
|
+
if err := json.NewEncoder(w).Encode(body); err != nil {
|
|
38
|
+
log.Printf("failed to encode JSON response: %v", err)
|
|
39
|
+
}
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
func newMux() *http.ServeMux {
|
package/cli/dist/cli.js
CHANGED
|
@@ -12,6 +12,7 @@ import { showHelp } from "./commands/help.js";
|
|
|
12
12
|
import { createProgram } from "./program.js";
|
|
13
13
|
import { ensureGlobalInstall } from "./utils/cli-command.js";
|
|
14
14
|
import { formatColdPreflight, runColdPreflight } from "./utils/cold-preflight.js";
|
|
15
|
+
import { stopDemoStack } from "./utils/demo-reset.js";
|
|
15
16
|
import { unknownHelpTarget } from "./utils/help-command.js";
|
|
16
17
|
import { bareTemplateArg } from "./utils/project-templates.js";
|
|
17
18
|
const program = createProgram();
|
|
@@ -68,6 +69,7 @@ if (templateArg) {
|
|
|
68
69
|
}
|
|
69
70
|
}
|
|
70
71
|
const destination = isAbsolute(targetName) ? targetName : resolve(cwd(), targetName);
|
|
72
|
+
console.log(chalk.gray(`📁 Demo folder: ${destination}`));
|
|
71
73
|
// Reusing an existing checkout is what keeps a second take free: the clone and the
|
|
72
74
|
// dependency install are skipped, so the recording starts on the interesting part.
|
|
73
75
|
let reused = false;
|
|
@@ -85,6 +87,13 @@ if (templateArg) {
|
|
|
85
87
|
await openUrl(running.url);
|
|
86
88
|
process.exit(0);
|
|
87
89
|
}
|
|
90
|
+
// Take the old stack down before its folder goes, so a Traefik left behind does not keep port 80.
|
|
91
|
+
try {
|
|
92
|
+
stopDemoStack(destination);
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
console.log(chalk.yellow(`Could not stop the previous demo stack: ${error.message}`));
|
|
96
|
+
}
|
|
88
97
|
if (keep) {
|
|
89
98
|
reused = true;
|
|
90
99
|
}
|
|
@@ -463,7 +463,14 @@ _flisk_resources() {
|
|
|
463
463
|
${subCommandLists}
|
|
464
464
|
|
|
465
465
|
${typeValueFunctions}
|
|
466
|
-
|
|
466
|
+
|
|
467
|
+
# Autoloaded from fpath, this file is the body of _flisk, so run it now to complete the first TAB.
|
|
468
|
+
# Sourced (\`source <(flisk completion zsh)\`), register it instead.
|
|
469
|
+
if [ "$funcstack[1]" = "_flisk" ]; then
|
|
470
|
+
_flisk "$@"
|
|
471
|
+
else
|
|
472
|
+
compdef _flisk flisk
|
|
473
|
+
fi
|
|
467
474
|
`;
|
|
468
475
|
}
|
|
469
476
|
/** The `_arguments` spec of one flag, with the values it completes when it has them. */
|
|
@@ -9,7 +9,8 @@ import { hasVerdaccioLicense } from "../generator/extension-fetch.js";
|
|
|
9
9
|
import { generateMasterConfigs, readProjectConfig, TemplateEngine, verifyMasterConfigs, } from "../generator/template-engine.js";
|
|
10
10
|
import { isMasterConfigFileName } from "../types/index.js";
|
|
11
11
|
import { assertValid, handleDryRun } from "../utils/command-helpers.js";
|
|
12
|
-
import {
|
|
12
|
+
import { explainConfigFile } from "../utils/config-explain.js";
|
|
13
|
+
import { MASTER_CONFIG_FILES, PROJECT_JSON, RESOURCE_DEFAULTS_FILE, TECH_STACK_FILE, } from "../utils/constants.js";
|
|
13
14
|
import { clearDiscoveryCache } from "../utils/discovery-context.js";
|
|
14
15
|
import { checkPrismaConsistency } from "../utils/doctor-wiring.js";
|
|
15
16
|
import { errorFactories, requireProjectRoot, runCommand, showError } from "../utils/errors.js";
|
|
@@ -20,6 +21,12 @@ import { SERVICE_MANIFEST_SCHEMA_VERSION, validateServiceManifest, } from "../ut
|
|
|
20
21
|
import { discoverResourcesWithProblems, discoverServiceManifestPaths, warnAboutSkippedFiles, } from "../utils/services.js";
|
|
21
22
|
import { evaluateSharedPlatformPostgres } from "../utils/shared-platform-postgres.js";
|
|
22
23
|
import { validateOptionalInfraService } from "../utils/validation.js";
|
|
24
|
+
/** Human wording for `flisk config explain`, one line per drift outcome. */
|
|
25
|
+
const DRIFT_LABELS = {
|
|
26
|
+
"blocks-up": "yes, until the edit is removed or --ignore-drift is passed",
|
|
27
|
+
none: "no",
|
|
28
|
+
unknown: "unknown",
|
|
29
|
+
};
|
|
23
30
|
export const configCommand = new Command("config")
|
|
24
31
|
.description("Manage project configuration and regenerate master files")
|
|
25
32
|
.addCommand(new Command("regenerate")
|
|
@@ -36,72 +43,104 @@ export const configCommand = new Command("config")
|
|
|
36
43
|
const newFiles = engine.generateAll(projectConfig);
|
|
37
44
|
const outputDir = join(projectRoot, ".flisk", ".flisk-out");
|
|
38
45
|
const filesToCheck = MASTER_CONFIG_FILES;
|
|
46
|
+
const fileGroups = [
|
|
47
|
+
{
|
|
48
|
+
title: "📋 Core orchestration",
|
|
49
|
+
files: [TECH_STACK_FILE, RESOURCE_DEFAULTS_FILE],
|
|
50
|
+
description: "Tilt tech stack and resource defaults; drives all service generation",
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
title: "📦 Project spec",
|
|
54
|
+
files: ["spec.master"],
|
|
55
|
+
description: "Compiled project specification; used by Tilt for service discovery",
|
|
56
|
+
},
|
|
57
|
+
];
|
|
39
58
|
let hasChanges = false;
|
|
40
|
-
for (const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (currentContent === newContent) {
|
|
55
|
-
console.log(chalk.green(`✓ ${filename}`));
|
|
56
|
-
console.log(chalk.gray(" Status: No changes\n"));
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
console.log(chalk.yellow(`📝 ${filename}`));
|
|
60
|
-
console.log(chalk.gray(" Status: MODIFIED"));
|
|
61
|
-
const currentLines = currentContent.split("\n").length;
|
|
62
|
-
const newLines = newContent.split("\n").length;
|
|
63
|
-
const lineDiff = newLines - currentLines;
|
|
64
|
-
if (lineDiff > 0) {
|
|
65
|
-
console.log(chalk.gray(` Lines: ${currentLines} → ${newLines} (+${lineDiff})`));
|
|
59
|
+
for (const group of fileGroups) {
|
|
60
|
+
let groupHasChanges = false;
|
|
61
|
+
const groupChanges = [];
|
|
62
|
+
for (const filename of group.files) {
|
|
63
|
+
if (!filesToCheck.includes(filename))
|
|
64
|
+
continue;
|
|
65
|
+
if (!isMasterConfigFileName(filename))
|
|
66
|
+
continue;
|
|
67
|
+
const newContent = newFiles[filename];
|
|
68
|
+
const filePath = join(outputDir, filename);
|
|
69
|
+
if (!existsSync(filePath)) {
|
|
70
|
+
groupHasChanges = true;
|
|
71
|
+
groupChanges.push({ filename, isNew: true, lineDiff: 0, diffLines: [] });
|
|
72
|
+
continue;
|
|
66
73
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
74
|
+
const currentContent = readFileSync(filePath, "utf-8");
|
|
75
|
+
if (currentContent !== newContent) {
|
|
76
|
+
groupHasChanges = true;
|
|
77
|
+
const currentLines = currentContent.split("\n").length;
|
|
78
|
+
const newLines = newContent.split("\n").length;
|
|
79
|
+
const lineDiff = newLines - currentLines;
|
|
80
|
+
const currentLinesArr = currentContent.split("\n");
|
|
81
|
+
const newLinesArr = newContent.split("\n");
|
|
82
|
+
let firstDiffLine = -1;
|
|
83
|
+
for (let i = 0; i < Math.max(currentLinesArr.length, newLinesArr.length); i++) {
|
|
84
|
+
if (currentLinesArr[i] !== newLinesArr[i]) {
|
|
85
|
+
firstDiffLine = i;
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
80
88
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
const diffLines = [];
|
|
90
|
+
if (firstDiffLine >= 0) {
|
|
91
|
+
const contextStart = Math.max(0, firstDiffLine - 1);
|
|
92
|
+
const contextEnd = Math.min(currentLinesArr.length, firstDiffLine + 2);
|
|
93
|
+
for (let i = contextStart; i < contextEnd; i++) {
|
|
94
|
+
const line = currentLinesArr[i];
|
|
95
|
+
const newLine = newLinesArr[i];
|
|
96
|
+
if (line !== newLine) {
|
|
97
|
+
if (line !== undefined) {
|
|
98
|
+
diffLines.push(chalk.red(` - ${line.substring(0, 60)}${line.length > 60 ? "..." : ""}`));
|
|
99
|
+
}
|
|
100
|
+
if (newLine !== undefined) {
|
|
101
|
+
diffLines.push(chalk.green(` + ${newLine.substring(0, 60)}${newLine.length > 60 ? "..." : ""}`));
|
|
102
|
+
}
|
|
92
103
|
}
|
|
93
|
-
|
|
94
|
-
|
|
104
|
+
else {
|
|
105
|
+
diffLines.push(chalk.gray(` ${line.substring(0, 60)}${line.length > 60 ? "..." : ""}`));
|
|
95
106
|
}
|
|
96
107
|
}
|
|
108
|
+
}
|
|
109
|
+
groupChanges.push({ filename, isNew: false, lineDiff, diffLines });
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (groupHasChanges) {
|
|
113
|
+
console.log(chalk.blue(`\n${group.title}`));
|
|
114
|
+
console.log(chalk.gray(` ${group.description}\n`));
|
|
115
|
+
for (const change of groupChanges) {
|
|
116
|
+
if (change.isNew) {
|
|
117
|
+
console.log(chalk.yellow(` 📁 ${change.filename}`));
|
|
118
|
+
console.log(chalk.gray(" Status: NEW (file does not exist)\n"));
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
console.log(chalk.yellow(` 📝 ${change.filename}`));
|
|
122
|
+
console.log(chalk.gray(" Status: MODIFIED"));
|
|
123
|
+
if (change.lineDiff > 0) {
|
|
124
|
+
console.log(chalk.gray(` Lines: +${change.lineDiff}`));
|
|
125
|
+
}
|
|
126
|
+
else if (change.lineDiff < 0) {
|
|
127
|
+
console.log(chalk.gray(` Lines: ${change.lineDiff}`));
|
|
128
|
+
}
|
|
97
129
|
else {
|
|
98
|
-
console.log(chalk.gray(
|
|
130
|
+
console.log(chalk.gray(" Lines: content changed"));
|
|
99
131
|
}
|
|
132
|
+
for (const diffLine of change.diffLines) {
|
|
133
|
+
console.log(diffLine);
|
|
134
|
+
}
|
|
135
|
+
console.log("");
|
|
100
136
|
}
|
|
101
137
|
}
|
|
102
|
-
console.log("");
|
|
103
138
|
hasChanges = true;
|
|
104
139
|
}
|
|
140
|
+
else {
|
|
141
|
+
console.log(chalk.green(`\n✅ ${group.title} — all up to date`));
|
|
142
|
+
console.log(chalk.gray(` ${group.description}\n`));
|
|
143
|
+
}
|
|
105
144
|
}
|
|
106
145
|
if (hasChanges) {
|
|
107
146
|
console.log(chalk.blue("💡 Run without --dry-run to apply these changes.\n"));
|
|
@@ -268,6 +307,42 @@ export const configCommand = new Command("config")
|
|
|
268
307
|
return;
|
|
269
308
|
}
|
|
270
309
|
await runCommand(action);
|
|
310
|
+
}))
|
|
311
|
+
.addCommand(new Command("explain")
|
|
312
|
+
.description("Explain whether a project file is Flisk-generated and what editing it does on flisk up")
|
|
313
|
+
.argument("<file>", "Project file to explain, relative to the current directory or absolute")
|
|
314
|
+
.option("--json", "Emit a machine-readable explanation")
|
|
315
|
+
.action(async (file, options) => {
|
|
316
|
+
const action = async () => {
|
|
317
|
+
const projectRoot = options.json ? findProjectRoot() : requireProjectRoot();
|
|
318
|
+
if (!projectRoot)
|
|
319
|
+
throw errorFactories.notInProject();
|
|
320
|
+
const explanation = explainConfigFile(projectRoot, file);
|
|
321
|
+
if (options.json) {
|
|
322
|
+
console.log(JSON.stringify(createMachineEnvelope(explanation)));
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
console.log(chalk.blue(`${explanation.file}\n`));
|
|
326
|
+
console.log(` Ownership: ${explanation.ownership}`);
|
|
327
|
+
console.log(` ${explanation.reason}`);
|
|
328
|
+
if (explanation.source)
|
|
329
|
+
console.log(` Source: ${explanation.source}`);
|
|
330
|
+
console.log(` Edited now: ${explanation.isEditedNow ? "yes" : "no"}`);
|
|
331
|
+
console.log(` Editing it blocks flisk up: ${DRIFT_LABELS[explanation.driftOnUp]}`);
|
|
332
|
+
console.log(chalk.blue("\nNext:"));
|
|
333
|
+
for (const step of explanation.next)
|
|
334
|
+
console.log(chalk.gray(` - ${step}`));
|
|
335
|
+
};
|
|
336
|
+
if (options.json) {
|
|
337
|
+
try {
|
|
338
|
+
await action();
|
|
339
|
+
}
|
|
340
|
+
catch (error) {
|
|
341
|
+
writeMachineError(error);
|
|
342
|
+
}
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
await runCommand(action);
|
|
271
346
|
}))
|
|
272
347
|
.addCommand(new Command("edit").description("Open .flisk/project.json in your $EDITOR").action(async () => {
|
|
273
348
|
await runCommand(async () => {
|