@flisk-sh/flisk 1.4.5 → 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/README.md +37 -14
- package/cli/dist/commands/doctor.js +50 -12
- package/cli/dist/commands/down.js +33 -1
- package/cli/dist/commands/logs.js +38 -1
- package/cli/dist/commands/project.js +11 -0
- package/cli/dist/commands/status.js +39 -10
- package/cli/dist/commands/up.js +119 -1
- package/cli/dist/commands/upgrade.js +2 -2
- package/cli/dist/utils/bun-requirement.js +7 -4
- package/cli/dist/utils/cold-preflight.js +52 -32
- package/cli/dist/utils/doctor-native.js +96 -0
- 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/project-templates.js +1 -1
- package/cli/dist/utils/service-manifest.js +19 -3
- package/cli/dist/utils/services.js +15 -2
- package/cli/dist/utils/tilt-logs.js +8 -0
- package/cli/dist-bundle/{chunk-V36PT2HF.js → chunk-BIVAAWBX.js} +1 -1
- package/cli/dist-bundle/{chunk-U42XZWXB.js → chunk-C4UFBXRD.js} +1 -1
- package/cli/dist-bundle/{chunk-CGTWXWBU.js → chunk-CAEMWNPF.js} +1 -1
- package/cli/dist-bundle/chunk-CDKEHFW6.js +35 -0
- package/cli/dist-bundle/{chunk-LUUJ4JB7.js → chunk-DPQK5TIS.js} +1 -1
- package/cli/dist-bundle/chunk-ETXZ5LUG.js +18 -0
- package/cli/dist-bundle/chunk-GT76VMUL.js +130 -0
- package/cli/dist-bundle/{chunk-4J2FLFUA.js → chunk-IDNES5PE.js} +1 -1
- package/cli/dist-bundle/{chunk-SFOFTVYM.js → chunk-MUDE4DZD.js} +1 -1
- package/cli/dist-bundle/{chunk-BP2M4OJ4.js → chunk-QEBN6ZVQ.js} +1 -1
- package/cli/dist-bundle/{chunk-VMVTECCK.js → chunk-R7DWXISM.js} +1 -1
- package/cli/dist-bundle/{chunk-Z5QEE4SW.js → chunk-U5FCQF42.js} +1 -1
- package/cli/dist-bundle/{chunk-TIYTGN5R.js → chunk-WCGBVETR.js} +1 -1
- package/cli/dist-bundle/cli.js +357 -352
- package/cli/dist-bundle/cold-preflight-KUWOL2Q2.js +2 -0
- package/cli/dist-bundle/{demo-stage-G4W23BXW.js → demo-stage-QCC4IWXR.js} +1 -1
- package/cli/dist-bundle/{open-HQFT6WDC.js → open-AZNX4AC5.js} +1 -1
- package/cli/dist-bundle/project-5SWIGCNP.js +2 -0
- package/cli/dist-bundle/{project-templates-IMJ3OX5I.js → project-templates-2VQPUBSQ.js} +1 -1
- package/cli/dist-bundle/{services-GLFKZBBZ.js → services-EY5WKPHQ.js} +1 -1
- package/cli/dist-bundle/{tilt-port-owner-PJN4MPYE.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/traefik_standalone.star +19 -4
- package/runtime/engine/topologies/platform/docker/constants.star +2 -2
- package/runtime/engine/topologies/platform/docker/networking/traefik_static_routes.star +2 -2
- package/runtime/engine/topologies/tilt/manifest/mapper.star +1 -1
- package/runtime/engine/topologies/tilt/resources/orchestrator/apply_compose_resource_registration.star +1 -1
- 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-BMHPPX2Q.js +0 -35
- package/cli/dist-bundle/chunk-PEZQEZVV.js +0 -17
- package/cli/dist-bundle/chunk-ULMQVD7J.js +0 -122
- package/cli/dist-bundle/cold-preflight-3BNDOLGS.js +0 -2
- package/cli/dist-bundle/project-JZO2CPZZ.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/README.md
CHANGED
|
@@ -114,13 +114,13 @@ flisk resource shop-web --type frontend --stack shop --yes
|
|
|
114
114
|
flisk up shop
|
|
115
115
|
```
|
|
116
116
|
|
|
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. 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.
|
|
118
118
|
|
|
119
119
|
<div align="center">
|
|
120
120
|
|
|
121
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>
|
|
122
122
|
|
|
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-
|
|
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)
|
|
124
124
|
|
|
125
125
|
<a id="readme-languages"></a>
|
|
126
126
|
|
|
@@ -245,7 +245,7 @@ flisk up shop
|
|
|
245
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).
|
|
246
246
|
|
|
247
247
|
|
|
248
|
-
**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.
|
|
249
249
|
|
|
250
250
|
**What Flisk is not:** a deploy tool or a Compose file. Production deployment stays with Helm, Argo CD, or Kustomize.
|
|
251
251
|
|
|
@@ -337,19 +337,42 @@ Get a running local stack in **3 commands**. Works on macOS, Linux, and Windows
|
|
|
337
337
|
|
|
338
338
|
### Prerequisites (install once)
|
|
339
339
|
|
|
340
|
-
| Tool | Version | Install |
|
|
341
|
-
|
|
342
|
-
| **
|
|
343
|
-
| **
|
|
344
|
-
| **
|
|
345
|
-
| **
|
|
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 |
|
|
346
347
|
|
|
347
|
-
> **
|
|
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.
|
|
348
349
|
|
|
349
350
|
> **Windows?** Use WSL2 Ubuntu. See the [Windows & WSL2 guide](docs/wsl2.md) for the recommended setup.
|
|
350
351
|
|
|
351
352
|
---
|
|
352
353
|
|
|
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:
|
|
367
|
+
|
|
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
|
+
|
|
353
376
|
### Fastest path: one-command demo (no manual steps)
|
|
354
377
|
|
|
355
378
|
```bash
|
|
@@ -596,11 +619,11 @@ Runnable examples show Flisk on real stacks. Start with the smallest one:
|
|
|
596
619
|
| [one-backend-helm](examples/one-backend-helm/README.md) | Working alongside Helm |
|
|
597
620
|
| [byo](examples/byo/README.md) | Bringing your own existing resources |
|
|
598
621
|
| [byo-jobs](examples/byo-jobs/README.md) | Bring-your-own jobs |
|
|
599
|
-
| [
|
|
622
|
+
| [flisk-example](examples/flisk-example/README.md) | A full multi-service stack |
|
|
600
623
|
|
|
601
624
|
## Use Flisk with your AI agent
|
|
602
625
|
|
|
603
|
-
The repository ships
|
|
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.
|
|
604
627
|
|
|
605
628
|
## Installation
|
|
606
629
|
|
|
@@ -648,7 +671,7 @@ Set `FLISK_DEBUG=1` before running `flisk up --verbose` to include Starlark debu
|
|
|
648
671
|
- [Generated service files and drift checks](docs/generated-files.md)
|
|
649
672
|
- [Runnable one-backend example](examples/one-backend/README.md)
|
|
650
673
|
- [Runnable Python backend example](examples/one-backend-python/README.md)
|
|
651
|
-
- [Full multi-service example](examples/
|
|
674
|
+
- [Full multi-service example](examples/flisk-example/README.md)
|
|
652
675
|
- [Features and license limits](docs/FEATURES.md)
|
|
653
676
|
- [Tool comparison: docker-compose, Tilt, Skaffold, DevSpace, kind](docs/comparison.md)
|
|
654
677
|
- [Honest comparison and known limits](docs/compare-honest.md)
|
|
@@ -686,7 +709,7 @@ On native Windows, `flisk --version`, `flisk doctor`, and `flisk up --dry-run` a
|
|
|
686
709
|
|
|
687
710
|
Core stays free. Premium is a separate key for the extras above; no key required to run `flisk up`.
|
|
688
711
|
|
|
689
|
-
**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.
|
|
690
713
|
|
|
691
714
|
<p align="center">
|
|
692
715
|
|
|
@@ -15,6 +15,7 @@ import { isPathDiscovered, readDiscoveryPaths } from "../utils/discovery-paths.j
|
|
|
15
15
|
import { checkCrashLoopingContainers } from "../utils/doctor-crashloop.js";
|
|
16
16
|
import { applyDoctorFixes, checkDuplicateFliskInstalls, hasFailedActions, planDoctorFixes, projectTiltPids, } from "../utils/doctor-fix.js";
|
|
17
17
|
import { checkDiskSpace, dockerDesktopStuck } from "../utils/doctor-host.js";
|
|
18
|
+
import { checkNativeCommands, checkNativeDependsOn, checkNativeRuntime, checkNativeServiceHealth, } from "../utils/doctor-native.js";
|
|
18
19
|
import { collectDoctorChecks, createDoctorReport, getDoctorExitCode, } from "../utils/doctor-report.js";
|
|
19
20
|
import { checkHealthRoutes, checkIngressPorts, checkPrivateNpmRegistry, checkTiltResourceHealth, projectConfigEnablesVerdaccio, summarizeAdvertisedProbes, summarizeServiceProbes, summarizeSmokeResults, } from "../utils/doctor-runtime.js";
|
|
20
21
|
import { checkStarlarkLoadExports } from "../utils/doctor-starlark.js";
|
|
@@ -25,6 +26,7 @@ import { evaluateFliskVersionFloor } from "../utils/flisk-version.js";
|
|
|
25
26
|
import { formatCount } from "../utils/formatting.js";
|
|
26
27
|
import { getHostPortPlan, resolveRuntimeIngressPort } from "../utils/host-port-config.js";
|
|
27
28
|
import { createHostPortPlan } from "../utils/host-port-plan.js";
|
|
29
|
+
import { findNativeProject } from "../utils/native-project.js";
|
|
28
30
|
import { findProjectRoot, getPackageVersion } from "../utils/paths.js";
|
|
29
31
|
import { promptConfirm } from "../utils/prompt.js";
|
|
30
32
|
import { EnvUnreadableError, envSecretValues, redactSecrets, redactValue, } from "../utils/secret-redaction.js";
|
|
@@ -1285,8 +1287,13 @@ export const doctorCommand = new Command("doctor")
|
|
|
1285
1287
|
process.exit(2);
|
|
1286
1288
|
return;
|
|
1287
1289
|
}
|
|
1290
|
+
// A project whose services all declare `command` runs as local processes: doctor checks only what they need (#2231).
|
|
1291
|
+
const nativeProject = findNativeProject();
|
|
1292
|
+
const nativeResources = nativeProject?.resources ?? null;
|
|
1288
1293
|
if (!options.json) {
|
|
1289
|
-
console.log(
|
|
1294
|
+
console.log(nativeResources
|
|
1295
|
+
? "Flisk doctor checks what this project's local processes need; its services declare commands, so Docker and Tilt are not checked."
|
|
1296
|
+
: "Flisk doctor checks your local Docker + Tilt development environment; it does not check cluster deployments.");
|
|
1290
1297
|
}
|
|
1291
1298
|
const host = detectHost();
|
|
1292
1299
|
if (process.platform === "win32") {
|
|
@@ -1343,10 +1350,15 @@ export const doctorCommand = new Command("doctor")
|
|
|
1343
1350
|
console.log(`\n${chalk.bold("🔍 Flisk Doctor")}\n`);
|
|
1344
1351
|
console.log("Checking environment...\n");
|
|
1345
1352
|
}
|
|
1346
|
-
|
|
1353
|
+
// A directory of command services is a project for doctor even before `flisk up` writes its .flisk/project.json.
|
|
1354
|
+
const projectRoot = findProjectRoot() ?? nativeProject?.projectRoot ?? null;
|
|
1347
1355
|
// Repairs run before the checks so the checks report the state after the fix.
|
|
1348
1356
|
let fixActions;
|
|
1349
|
-
if (options.fix) {
|
|
1357
|
+
if (options.fix && nativeResources) {
|
|
1358
|
+
// The repairs are for Docker networks and Tilt probes, which a project of local processes does not have.
|
|
1359
|
+
fixActions = [];
|
|
1360
|
+
}
|
|
1361
|
+
else if (options.fix) {
|
|
1350
1362
|
try {
|
|
1351
1363
|
let projectName;
|
|
1352
1364
|
if (projectRoot) {
|
|
@@ -1388,16 +1400,19 @@ export const doctorCommand = new Command("doctor")
|
|
|
1388
1400
|
if (!options.json)
|
|
1389
1401
|
printFixActions(fixActions, options.dryRun);
|
|
1390
1402
|
}
|
|
1403
|
+
// The host port plan places the gateway and Postgres containers; a project of local processes has neither.
|
|
1391
1404
|
let hostPortPlan;
|
|
1392
1405
|
let portPlanError;
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1406
|
+
if (!nativeResources) {
|
|
1407
|
+
try {
|
|
1408
|
+
hostPortPlan = await getHostPortPlan(projectRoot ?? process.cwd());
|
|
1409
|
+
}
|
|
1410
|
+
catch (error) {
|
|
1411
|
+
hostPortPlan = null;
|
|
1412
|
+
portPlanError = error instanceof Error ? error.message : String(error);
|
|
1413
|
+
}
|
|
1399
1414
|
}
|
|
1400
|
-
const
|
|
1415
|
+
const containerMachineChecks = [
|
|
1401
1416
|
() => hostPortPlan
|
|
1402
1417
|
? {
|
|
1403
1418
|
name: "Host Ports",
|
|
@@ -1434,7 +1449,7 @@ export const doctorCommand = new Command("doctor")
|
|
|
1434
1449
|
requiresContainerRuntime("Docker Network Pool", () => checkDockerNetworkCapacity()),
|
|
1435
1450
|
() => checkDuplicateFliskInstalls(),
|
|
1436
1451
|
];
|
|
1437
|
-
const
|
|
1452
|
+
const containerProjectChecks = [
|
|
1438
1453
|
() => checkFliskVersion(),
|
|
1439
1454
|
checkMasterConfigs,
|
|
1440
1455
|
checkGeneratedProjectRuntimeAssets,
|
|
@@ -1495,8 +1510,31 @@ export const doctorCommand = new Command("doctor")
|
|
|
1495
1510
|
// When Tilt is up, surface red resources (Traefik/apps never started).
|
|
1496
1511
|
requiresContainerRuntime("Tilt Resources", checkTiltResourceHealth),
|
|
1497
1512
|
];
|
|
1513
|
+
const machineChecks = nativeResources
|
|
1514
|
+
? [
|
|
1515
|
+
() => checkNativeRuntime(nativeResources),
|
|
1516
|
+
() => checkNativeCommands(nativeResources),
|
|
1517
|
+
() => checkWslProjectLocation(findProjectRoot() ?? process.cwd(), options.strict),
|
|
1518
|
+
() => checkDuplicateFliskInstalls(),
|
|
1519
|
+
]
|
|
1520
|
+
: containerMachineChecks;
|
|
1521
|
+
const projectChecks = nativeResources
|
|
1522
|
+
? [
|
|
1523
|
+
() => checkFliskVersion(),
|
|
1524
|
+
() => checkDuplicateResourceNames(),
|
|
1525
|
+
() => checkDependsOnShape(),
|
|
1526
|
+
() => checkNativeDependsOn(nativeResources),
|
|
1527
|
+
() => checkCircularDependencies(),
|
|
1528
|
+
() => checkServicePorts(),
|
|
1529
|
+
() => checkSchemaVersions(undefined, options.strict),
|
|
1530
|
+
() => checkDuplicateResourcePorts(),
|
|
1531
|
+
]
|
|
1532
|
+
: containerProjectChecks;
|
|
1533
|
+
if (options.ping && nativeResources && projectRoot) {
|
|
1534
|
+
projectChecks.push(() => checkNativeServiceHealth(projectRoot, nativeResources, pingTimeout));
|
|
1535
|
+
}
|
|
1498
1536
|
// Runs last: needs routable services (and working Traefik) to mean anything.
|
|
1499
|
-
if (options.ping) {
|
|
1537
|
+
if (options.ping && !nativeResources) {
|
|
1500
1538
|
// Probe the port a running stack is actually on, not the one the next `flisk up` would pick.
|
|
1501
1539
|
const pingPort = projectRoot
|
|
1502
1540
|
? resolveRuntimeIngressPort(projectRoot, hostPortPlan?.ingressHttp)
|
|
@@ -8,8 +8,10 @@ import { pruneProjectNetworks, stopProjectTiltUp, waitForTiltUpExit, } from "../
|
|
|
8
8
|
import { errorFactories, handleTiltFailure, withTiltCheck } from "../utils/errors.js";
|
|
9
9
|
import { createJsonEmitter } from "../utils/json-output.js";
|
|
10
10
|
import { writeMachineError } from "../utils/machine-output.js";
|
|
11
|
+
import { readNativeRunState, stopNativeRun } from "../utils/native-runtime.js";
|
|
12
|
+
import { isNativeProject } from "../utils/native-service.js";
|
|
11
13
|
import { findProjectRoot } from "../utils/paths.js";
|
|
12
|
-
import { discoverResources, discoverStacks } from "../utils/services.js";
|
|
14
|
+
import { discoverResources, discoverResourcesFromRoot, discoverStacks } from "../utils/services.js";
|
|
13
15
|
import { buildTiltDownArgs, getTiltfilePath, runTilt } from "../utils/tilt.js";
|
|
14
16
|
function allStackNames() {
|
|
15
17
|
try {
|
|
@@ -20,6 +22,17 @@ function allStackNames() {
|
|
|
20
22
|
return undefined;
|
|
21
23
|
}
|
|
22
24
|
}
|
|
25
|
+
/** True when `flisk down` stops local processes instead of Tilt: a native run is on record, or every service declares `command`. */
|
|
26
|
+
function isNativeRun(projectRoot) {
|
|
27
|
+
if (readNativeRunState(projectRoot))
|
|
28
|
+
return true;
|
|
29
|
+
try {
|
|
30
|
+
return isNativeProject(discoverResourcesFromRoot(projectRoot));
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
23
36
|
function pruneNetworksOrWarn(json) {
|
|
24
37
|
const root = findProjectRoot();
|
|
25
38
|
if (!root)
|
|
@@ -64,6 +77,25 @@ export const downCommand = addYesOption(new Command("down"))
|
|
|
64
77
|
}
|
|
65
78
|
}
|
|
66
79
|
const emit = options.json ? createJsonEmitter("DOWN_FAILED", "flisk down") : undefined;
|
|
80
|
+
// A project of `command` services (or one with a native run on record) stops without Docker or Tilt.
|
|
81
|
+
const projectRoot = findProjectRoot();
|
|
82
|
+
if (isNativeRun(projectRoot)) {
|
|
83
|
+
if (emit && options.dryRun) {
|
|
84
|
+
emit({ ok: true, dryRun: true, runtime: "native" });
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (handleDryRun(options, "not stopping local processes", "stop the local processes of this project")) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const stopped = await stopNativeRun(projectRoot);
|
|
91
|
+
if (!options.json) {
|
|
92
|
+
console.log(stopped.wasRunning
|
|
93
|
+
? chalk.blue(`Stopped local processes: ${stopped.services.join(", ")}`)
|
|
94
|
+
: chalk.gray("Nothing is running for this project."));
|
|
95
|
+
}
|
|
96
|
+
emit?.({ ok: true, runtime: "native", stopped: stopped.services });
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
67
99
|
await withTiltCheck(async () => {
|
|
68
100
|
if (emit && options.dryRun) {
|
|
69
101
|
emit({ ok: true, dryRun: true });
|
|
@@ -4,10 +4,13 @@ import { Command } from "commander";
|
|
|
4
4
|
import { STANDARD_PORTS } from "../utils/constants.js";
|
|
5
5
|
import { errorFactories, FliskError, runCommand, showErrorAndExit } from "../utils/errors.js";
|
|
6
6
|
import { createMachineEnvelope } from "../utils/machine-output.js";
|
|
7
|
+
import { readNativeLogLines } from "../utils/native-runtime.js";
|
|
8
|
+
import { isNativeProject } from "../utils/native-service.js";
|
|
7
9
|
import { findProjectRoot } from "../utils/paths.js";
|
|
8
10
|
import { EnvUnreadableError, envSecretValues, redactSecrets, redactValue, } from "../utils/secret-redaction.js";
|
|
11
|
+
import { discoverResourcesFromRoot } from "../utils/services.js";
|
|
9
12
|
import { isTiltAvailable, runTilt } from "../utils/tilt.js";
|
|
10
|
-
import { DEFAULT_LOG_TAIL, isTiltConnectionFailure, isValidPort, isValidSince, isValidTail, MAX_LOG_TAIL, parseTiltLogLines, } from "../utils/tilt-logs.js";
|
|
13
|
+
import { DEFAULT_LOG_TAIL, isTiltConnectionFailure, isValidPort, isValidSince, isValidTail, MAX_LOG_TAIL, parseTiltLogLines, sinceMilliseconds, } from "../utils/tilt-logs.js";
|
|
11
14
|
import { tiltUnreachableMessage } from "../utils/tilt-unreachable-message.js";
|
|
12
15
|
/** Resource names Tilt knows about, or null when they cannot be listed (the logs call then reports the real error). */
|
|
13
16
|
async function tiltResourceNames(port) {
|
|
@@ -25,6 +28,17 @@ async function tiltResourceNames(port) {
|
|
|
25
28
|
return null;
|
|
26
29
|
}
|
|
27
30
|
}
|
|
31
|
+
/** The project's services when every one declares `command` (they run as local processes), else null. */
|
|
32
|
+
function nativeResources(projectRoot) {
|
|
33
|
+
try {
|
|
34
|
+
const resources = discoverResourcesFromRoot(projectRoot);
|
|
35
|
+
return isNativeProject(resources) ? resources : null;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// Discovery problems are reported by the commands that start the stack; logs still asks Tilt.
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
28
42
|
export const logsCommand = new Command("logs")
|
|
29
43
|
.description("Print a bounded snapshot of recent logs from the running stack")
|
|
30
44
|
.showHelpAfterError("\nService names are not positional. Use: flisk logs --service <name>")
|
|
@@ -81,6 +95,29 @@ export const logsCommand = new Command("logs")
|
|
|
81
95
|
"Fix the read permission on .env, or move it out of the project",
|
|
82
96
|
]);
|
|
83
97
|
}
|
|
98
|
+
// A project of `command` services keeps its output in .flisk/native/logs, so no Tilt is involved.
|
|
99
|
+
const resources = nativeResources(projectRoot);
|
|
100
|
+
if (resources) {
|
|
101
|
+
const known = resources.map((resource) => resource.name);
|
|
102
|
+
const unknown = services.filter((name) => !known.includes(name));
|
|
103
|
+
if (unknown.length > 0) {
|
|
104
|
+
const error = errorFactories.unknownServices(unknown, known);
|
|
105
|
+
fail("UNKNOWN_SERVICE", error.message, error.exitCode, error.suggestions);
|
|
106
|
+
}
|
|
107
|
+
const lines = readNativeLogLines(projectRoot, services.length > 0 ? services : known, {
|
|
108
|
+
tail,
|
|
109
|
+
sinceMs: options.since === undefined ? undefined : sinceMilliseconds(options.since),
|
|
110
|
+
});
|
|
111
|
+
if (options.json) {
|
|
112
|
+
console.log(JSON.stringify(redactValue(createMachineEnvelope({ services, tail, since: options.since ?? null, lines }), secrets)));
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
const width = Math.max(0, ...lines.map((line) => line.resource.length));
|
|
116
|
+
for (const line of lines) {
|
|
117
|
+
console.log(redactSecrets(`${line.resource.padEnd(width)} | ${line.text}`, secrets));
|
|
118
|
+
}
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
84
121
|
if (!(await isTiltAvailable())) {
|
|
85
122
|
fail("TILT_MISSING", "Tilt is not installed. Run: flisk doctor");
|
|
86
123
|
}
|
|
@@ -213,6 +213,17 @@ const DEFAULT_PROJECT_JSON = {
|
|
|
213
213
|
},
|
|
214
214
|
overrides: {},
|
|
215
215
|
};
|
|
216
|
+
/**
|
|
217
|
+
* Writes .flisk/project.json with the defaults `flisk project --yes` uses, and nothing else: no generated Tiltfile, Compose file,
|
|
218
|
+
* .env or engine copy. `flisk up` uses it to adopt a directory of `command` services as a project, so `flisk down` and
|
|
219
|
+
* `flisk doctor` find it afterwards.
|
|
220
|
+
*/
|
|
221
|
+
export function writeDefaultProjectConfig(projectRoot) {
|
|
222
|
+
const projectConfig = JSON.parse(JSON.stringify(DEFAULT_PROJECT_JSON));
|
|
223
|
+
projectConfig.project.name = basename(projectRoot) || "my-project";
|
|
224
|
+
ensureDirectory(join(projectRoot, ".flisk"));
|
|
225
|
+
writeJsonFile(join(projectRoot, ".flisk", PROJECT_JSON), projectConfig);
|
|
226
|
+
}
|
|
216
227
|
export const projectCommand = addYesOption(new Command("project"))
|
|
217
228
|
.alias("init")
|
|
218
229
|
.description("Initialize or validate project-level master configuration")
|
|
@@ -8,6 +8,8 @@ import { runCommand } from "../utils/errors.js";
|
|
|
8
8
|
import { formatCount, showDetail, showStep } from "../utils/formatting.js";
|
|
9
9
|
import { getHostPortPlan } from "../utils/host-port-config.js";
|
|
10
10
|
import { createMachineEnvelope, writeMachineError } from "../utils/machine-output.js";
|
|
11
|
+
import { nativeServiceStates } from "../utils/native-runtime.js";
|
|
12
|
+
import { isNativeProject } from "../utils/native-service.js";
|
|
11
13
|
import { findProjectRoot } from "../utils/paths.js";
|
|
12
14
|
import { deriveServiceStates } from "../utils/service-runtime-state.js";
|
|
13
15
|
import { groupSharedPostgres, readProjectName } from "../utils/shared-infra.js";
|
|
@@ -31,19 +33,30 @@ export const statusCommand = new Command("status")
|
|
|
31
33
|
const sharedInfraGroup = projectName
|
|
32
34
|
? groupSharedPostgres(projectName, discovery.stacks)
|
|
33
35
|
: null;
|
|
36
|
+
// A project of `command` services runs as local processes: its state comes from the run on record, not from Tilt.
|
|
37
|
+
const nativeStates = projectRoot && isNativeProject(discovery.resources)
|
|
38
|
+
? nativeServiceStates(projectRoot, discovery.resources.map((resource) => resource.name))
|
|
39
|
+
: null;
|
|
34
40
|
let tiltAvailable = false;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
if (!nativeStates) {
|
|
42
|
+
try {
|
|
43
|
+
tiltAvailable = await isTiltAvailable();
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
// Tilt not available (spawn error)
|
|
47
|
+
tiltAvailable = false;
|
|
48
|
+
}
|
|
41
49
|
}
|
|
42
50
|
if (!options.json) {
|
|
43
51
|
showStep("Flisk Status\n");
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
52
|
+
if (nativeStates) {
|
|
53
|
+
console.log(chalk.bold("Runtime:"), "local processes (no Docker, no Tilt)");
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
console.log(chalk.bold("Tilt:"), tiltAvailable ? chalk.green("available") : chalk.red("not found"));
|
|
57
|
+
if (!tiltAvailable) {
|
|
58
|
+
showDetail("Install Tilt: https://docs.tilt.dev/install.html");
|
|
59
|
+
}
|
|
47
60
|
}
|
|
48
61
|
console.log();
|
|
49
62
|
}
|
|
@@ -53,7 +66,7 @@ export const statusCommand = new Command("status")
|
|
|
53
66
|
// Tilt answers or its output cannot be read.
|
|
54
67
|
let readiness = null;
|
|
55
68
|
// The same look at Tilt feeds readiness and each service's state, so `flisk status` and `flisk ui` cannot disagree.
|
|
56
|
-
let serviceStates =
|
|
69
|
+
let serviceStates = nativeStates;
|
|
57
70
|
const tiltPort = getTiltPollingPort(process.env.TILT_PORT);
|
|
58
71
|
// Port plan is best effort; service URLs are shown in both JSON and terminal output.
|
|
59
72
|
let portPlan = null;
|
|
@@ -99,7 +112,23 @@ export const statusCommand = new Command("status")
|
|
|
99
112
|
}
|
|
100
113
|
if (options.json) {
|
|
101
114
|
const errors = queryError ? [{ code: "TILT_STATUS_UNAVAILABLE", message: queryError }] : [];
|
|
115
|
+
// A native run answers the readiness question agents poll (data.tilt.readiness.ready) from its own run state.
|
|
116
|
+
if (nativeStates) {
|
|
117
|
+
const states = Object.entries(nativeStates);
|
|
118
|
+
const isRunning = states.some(([, state]) => state.status !== "unknown");
|
|
119
|
+
readiness = isRunning
|
|
120
|
+
? {
|
|
121
|
+
ready: states.every(([, state]) => state.status === "ready"),
|
|
122
|
+
failures: [],
|
|
123
|
+
pending: states.filter(([, state]) => state.status !== "ready").length,
|
|
124
|
+
timedOut: false,
|
|
125
|
+
enabled: states.map(([name]) => name),
|
|
126
|
+
}
|
|
127
|
+
: null;
|
|
128
|
+
}
|
|
102
129
|
const data = {
|
|
130
|
+
// Only a project of local processes says so; a container project's report keeps its shape.
|
|
131
|
+
...(nativeStates ? { runtime: "native" } : {}),
|
|
103
132
|
tilt: {
|
|
104
133
|
available: tiltAvailable,
|
|
105
134
|
resourcesQueried: options.tilt && tiltAvailable,
|
package/cli/dist/commands/up.js
CHANGED
|
@@ -20,6 +20,9 @@ import { exportHostPortPlan, getHostPortPlan, writeSavedHostPortPlan, } from "..
|
|
|
20
20
|
import { formatHostPortPlan } from "../utils/host-port-plan.js";
|
|
21
21
|
import { createJsonEmitter } from "../utils/json-output.js";
|
|
22
22
|
import { toMachineError } from "../utils/machine-output.js";
|
|
23
|
+
import { hasNearbyServiceJson } from "../utils/native-project.js";
|
|
24
|
+
import { formatMixedRuntimeRefusal, isNativeProject, isNativeService, resolveRuntimeMode, } from "../utils/native-service.js";
|
|
25
|
+
import { runNativeUp } from "../utils/native-up.js";
|
|
23
26
|
import { nativeWindowsStackRefusal } from "../utils/native-windows.js";
|
|
24
27
|
import { findProjectRoot, getPackageVersion } from "../utils/paths.js";
|
|
25
28
|
import { findAvailablePort } from "../utils/port-assignment.js";
|
|
@@ -38,7 +41,7 @@ import { stopTiltOnPort } from "../utils/tilt-process.js";
|
|
|
38
41
|
import { parseTiltPort, resolveTiltPort, secondUpAction, stopTiltForUp, } from "../utils/tilt-startup.js";
|
|
39
42
|
import { findUnknownServices, resolveOnlySelection } from "../utils/up-only.js";
|
|
40
43
|
import { tiltGetUiResources, waitForTiltResourcesReady } from "../utils/up-readiness.js";
|
|
41
|
-
import { enableDiscoveredStacks } from "./project.js";
|
|
44
|
+
import { enableDiscoveredStacks, writeDefaultProjectConfig } from "./project.js";
|
|
42
45
|
export function formatUpSuccess(port, options = {}) {
|
|
43
46
|
const { appUrls = [], serviceHealth = [], showLogsHint = serviceHealth.length > 0 } = options;
|
|
44
47
|
const lines = [];
|
|
@@ -235,6 +238,67 @@ function envFileFailure(error) {
|
|
|
235
238
|
exitCode: error instanceof FliskError ? error.exitCode : 2,
|
|
236
239
|
};
|
|
237
240
|
}
|
|
241
|
+
/**
|
|
242
|
+
* Decides whether `flisk up` runs the selection as local processes (#2229). Returns null for today's Docker + Tilt path, which
|
|
243
|
+
* a project without any `command` service always takes. Outside a project, a directory whose services all declare `command`
|
|
244
|
+
* becomes the project. Refuses (through `fail`) an unknown stack or service, an invalid service.json, and a run that would mix
|
|
245
|
+
* native and container services.
|
|
246
|
+
*/
|
|
247
|
+
export function selectNativeRun(stackName, only, fail, cwd = process.cwd()) {
|
|
248
|
+
const foundRoot = findProjectRoot(cwd);
|
|
249
|
+
if (!foundRoot && !hasNearbyServiceJson(cwd))
|
|
250
|
+
return null;
|
|
251
|
+
const projectRoot = foundRoot ?? cwd;
|
|
252
|
+
let discovered;
|
|
253
|
+
try {
|
|
254
|
+
discovered = discoverResourcesWithProblems(projectRoot);
|
|
255
|
+
}
|
|
256
|
+
catch {
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
const all = discovered.resources;
|
|
260
|
+
if (!all.some(isNativeService))
|
|
261
|
+
return null;
|
|
262
|
+
if (!foundRoot && !isNativeProject(all))
|
|
263
|
+
return null;
|
|
264
|
+
if (discovered.problems.length > 0) {
|
|
265
|
+
fail("INVALID_SERVICE_CONFIG", discovered.problems
|
|
266
|
+
.map((problem) => `Invalid service.json at ${problem.path}: ${problem.reason}`)
|
|
267
|
+
.join("\n"));
|
|
268
|
+
}
|
|
269
|
+
let requested = all;
|
|
270
|
+
if (stackName) {
|
|
271
|
+
if (!stackExists(stackName, all)) {
|
|
272
|
+
const error = errorFactories.stackNotFound(stackName, discoverStacks(all).map((s) => s.name));
|
|
273
|
+
fail("STACK_NOT_FOUND", error.message, error.suggestions);
|
|
274
|
+
}
|
|
275
|
+
requested = getResourcesForStack(stackName, all);
|
|
276
|
+
}
|
|
277
|
+
if (only) {
|
|
278
|
+
const unknown = findUnknownServices(only, requested);
|
|
279
|
+
if (unknown.length > 0) {
|
|
280
|
+
const error = errorFactories.unknownServices(unknown, requested.map((service) => service.name));
|
|
281
|
+
fail("UNKNOWN_SERVICE", error.message, error.suggestions);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
// A process cannot start before what it depends on, so a stack or --only selection always brings its dependsOn closure.
|
|
285
|
+
const names = only ?? requested.map((service) => service.name);
|
|
286
|
+
const selection = resolveOnlySelection(names, all);
|
|
287
|
+
const { mode, mixed } = resolveRuntimeMode(selection.selected, all);
|
|
288
|
+
if (mode === "container") {
|
|
289
|
+
const containerNames = (selection.selected.some(isNativeService) ? selection.selected : all)
|
|
290
|
+
.filter((service) => !isNativeService(service))
|
|
291
|
+
.map((service) => service.name);
|
|
292
|
+
fail("MIXED_RUNTIME", formatMixedRuntimeRefusal(mixed, containerNames));
|
|
293
|
+
}
|
|
294
|
+
return {
|
|
295
|
+
projectRoot,
|
|
296
|
+
isNewProject: !foundRoot,
|
|
297
|
+
all,
|
|
298
|
+
selected: selection.selected,
|
|
299
|
+
dependencies: only ? selection.dependencies : [],
|
|
300
|
+
};
|
|
301
|
+
}
|
|
238
302
|
export const upCommand = new Command("up")
|
|
239
303
|
.description("Start all services (optionally filtered by stack)")
|
|
240
304
|
.alias("deploy")
|
|
@@ -266,6 +330,60 @@ export const upCommand = new Command("up")
|
|
|
266
330
|
onFail: (message) => emit?.({ ok: false }, [{ code: "FLISK_VERSION_TOO_OLD", message }]),
|
|
267
331
|
});
|
|
268
332
|
}
|
|
333
|
+
// Every selected service declares `command`: run them as local processes, with no Docker, Compose, Tilt or generated
|
|
334
|
+
// files (#2229). Decided before any Docker or Tilt check; a project without `command` services never enters this branch.
|
|
335
|
+
const nativeRun = selectNativeRun(stackName, options.only, (code, message, suggestions) => {
|
|
336
|
+
emit?.({ ok: false }, [
|
|
337
|
+
{ code, message, ...(suggestions && suggestions.length > 0 ? { suggestions } : {}) },
|
|
338
|
+
]);
|
|
339
|
+
return showErrorAndExit(message, 1, suggestions);
|
|
340
|
+
});
|
|
341
|
+
if (nativeRun) {
|
|
342
|
+
const platformRefusal = nativeWindowsUpRefusal(process.platform, process.env.FLISK_ALLOW_NATIVE_WINDOWS);
|
|
343
|
+
if (platformRefusal)
|
|
344
|
+
showErrorAndExit(platformRefusal);
|
|
345
|
+
const { projectRoot } = nativeRun;
|
|
346
|
+
let envFilePath;
|
|
347
|
+
if (options.envFile !== undefined) {
|
|
348
|
+
try {
|
|
349
|
+
envFilePath = selectEnvFile(projectRoot, options.envFile).path;
|
|
350
|
+
}
|
|
351
|
+
catch (error) {
|
|
352
|
+
const { failure, exitCode } = envFileFailure(error);
|
|
353
|
+
emit?.({ ok: false }, [failure]);
|
|
354
|
+
showErrorAndExit(failure.message, exitCode, failure.suggestions);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
if (!nativeRun.isNewProject) {
|
|
358
|
+
enforceSchemaVersionGate(projectRoot, {
|
|
359
|
+
resources: nativeRun.all,
|
|
360
|
+
onInvalid: (message) => emit?.({ ok: false }, [{ code: "INVALID_SCHEMA_VERSION", message }]),
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
enforceServiceConfigGate(projectRoot, {
|
|
364
|
+
resources: nativeRun.all,
|
|
365
|
+
onInvalid: (message) => emit?.({ ok: false }, [{ code: "INVALID_SERVICE_CONFIG", message }]),
|
|
366
|
+
});
|
|
367
|
+
if (nativeRun.isNewProject && !options.dryRun) {
|
|
368
|
+
writeDefaultProjectConfig(projectRoot);
|
|
369
|
+
if (!options.quiet) {
|
|
370
|
+
console.log(chalk.gray("Created .flisk/project.json (this directory is now a Flisk project)"));
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
await runNativeUp({
|
|
374
|
+
projectRoot,
|
|
375
|
+
selected: nativeRun.selected,
|
|
376
|
+
dependencies: nativeRun.dependencies,
|
|
377
|
+
stackName,
|
|
378
|
+
only: options.only,
|
|
379
|
+
envFilePath,
|
|
380
|
+
dryRun: options.dryRun,
|
|
381
|
+
quiet: options.quiet,
|
|
382
|
+
force: options.force,
|
|
383
|
+
emit,
|
|
384
|
+
});
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
269
387
|
// The env file of the run. `--env-file` replaces the project .env for this run, so the file is
|
|
270
388
|
// resolved and read before any prerequisite check, any write and any service starts.
|
|
271
389
|
const envFileRoot = versionRoot;
|
|
@@ -140,7 +140,7 @@ export function detectAllInstallations() {
|
|
|
140
140
|
return [...unique.values()];
|
|
141
141
|
}
|
|
142
142
|
const BINARY_RELEASE_REPO = "flisk-sh/releases";
|
|
143
|
-
const ENGINE_ASSET_NAME = "
|
|
143
|
+
const ENGINE_ASSET_NAME = "flisk-cli-engine.tar.gz";
|
|
144
144
|
const CHECKSUMS_ASSET_NAME = "checksums.txt";
|
|
145
145
|
/** Parses `shasum -a 256` / `sha256sum` output ("<hash> <name>" or "<hash> *<name>"). */
|
|
146
146
|
/** @internal Exported for unit tests only; not part of the package API. */
|
|
@@ -656,7 +656,7 @@ export function createUpgradeCommand() {
|
|
|
656
656
|
showErrorAndExit("Flisk Windows v1 supports AMD64 only. Use WSL2 Ubuntu or a 64-bit Intel/AMD PC.");
|
|
657
657
|
}
|
|
658
658
|
if (process.platform === "win32") {
|
|
659
|
-
showErrorAndExit("No Windows AMD64 binary in this Flisk release. Need asset
|
|
659
|
+
showErrorAndExit("No Windows AMD64 binary in this Flisk release. Need asset flisk-windows-amd64.exe.");
|
|
660
660
|
}
|
|
661
661
|
showErrorAndExit(`Unsupported OS: Flisk does not support this OS: ${process.platform}. Supported: linux, darwin, win32.`);
|
|
662
662
|
}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
import { isNativeService } from "./native-service.js";
|
|
1
2
|
import { isApiServiceType } from "./resource-kind.js";
|
|
2
3
|
/**
|
|
3
4
|
* Bun runs the generated JS services. A project without any has nothing for Bun to run, so neither `flisk doctor` nor
|
|
4
|
-
* `flisk up` needs it.
|
|
5
|
+
* `flisk up` needs it. A `command` service runs whatever its command names, so it never needs Bun on Flisk's behalf.
|
|
6
|
+
* Doctor and the start-up preflight share this rule so they cannot disagree.
|
|
5
7
|
*/
|
|
6
8
|
export function projectNeedsBun(resources) {
|
|
7
|
-
return resources.some((resource) =>
|
|
8
|
-
resource.config?.appType
|
|
9
|
-
|
|
9
|
+
return resources.some((resource) => !isNativeService(resource) &&
|
|
10
|
+
(isApiServiceType(resource.config?.appType) ||
|
|
11
|
+
resource.config?.appType === "frontend" ||
|
|
12
|
+
resource.config?.appType === "worker"));
|
|
10
13
|
}
|