@flisk-sh/flisk 1.3.190 → 1.3.192
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 +9 -9
- package/LICENSE +1 -1
- package/README.md +41 -41
- package/Tiltfile +2 -2
- package/cli/bin/{flisk.js → tdk.js} +1 -1
- package/cli/dist/cli.js +59 -0
- package/cli/dist/commands/__tests__/project-e2e-helpers.js +2 -2
- package/cli/dist/commands/completion.js +26 -26
- package/cli/dist/commands/config.js +1 -1
- package/cli/dist/commands/import.js +4 -4
- package/cli/dist/commands/maintainers.js +1 -1
- package/cli/dist/commands/mcp.js +1 -4
- package/cli/dist/commands/project.js +10 -2
- package/cli/dist/commands/resource.js +1 -1
- package/cli/dist/commands/ui.js +1 -1
- package/cli/dist/commands/up.js +77 -3
- package/cli/dist/commands/upgrade.js +28 -14
- package/cli/dist/generator/extension-fetch.js +3 -3
- package/cli/dist/generator/template-engine.js +8 -8
- package/cli/dist/mcp/tools.js +2 -5
- package/cli/dist/program.js +2 -0
- package/cli/dist/utils/cli-command.js +107 -0
- package/cli/dist/utils/cold-preflight.js +2 -1
- package/cli/dist/utils/constants.js +1 -1
- package/cli/dist/utils/doctor-fix.js +4 -5
- package/cli/dist/utils/doctor-runtime.js +1 -1
- package/cli/dist/utils/doctor-starlark.js +1 -1
- package/cli/dist/utils/doctor-wiring.js +2 -2
- package/cli/dist/utils/env-selection.js +201 -0
- package/cli/dist/utils/env-validator.js +6 -0
- package/cli/dist/utils/one-command.js +50 -0
- package/cli/dist/utils/platform.js +2 -6
- package/cli/dist/utils/project-templates.js +11 -7
- package/cli/dist/utils/secret-redaction.js +15 -6
- package/cli/dist/utils/service-manifest.js +1 -1
- package/cli/dist/utils/smoke.js +2 -2
- package/cli/dist/utils/tar.js +1 -1
- package/cli/dist-bundle/{chunk-BZ4H7MM4.js → chunk-42IVF3YT.js} +2 -2
- package/cli/dist-bundle/chunk-GOEBYLFN.js +2 -0
- package/cli/dist-bundle/chunk-KGKKDD4K.js +2 -0
- package/cli/dist-bundle/chunk-QR6O2A7L.js +34 -0
- package/cli/dist-bundle/chunk-RHSMS45X.js +438 -0
- package/cli/dist-bundle/chunk-XYFVXSEO.js +75 -0
- package/cli/dist-bundle/cli.js +342 -370
- package/cli/dist-bundle/cold-preflight-ZJAU3E7K.js +2 -0
- package/cli/dist-bundle/{extension-fetch-J4FFH7TJ.js → extension-fetch-6XNTDF44.js} +1 -1
- package/cli/dist-bundle/one-command-A4R272U3.js +4 -0
- package/cli/dist-bundle/project-FOAR7E55.js +2 -0
- package/cli/dist-bundle/project-templates-BHURA3LT.js +2 -0
- package/cli/dist-bundle/url-actions-D6ROTHZG.js +2 -0
- package/cli/package.json +2 -4
- package/cli/shared-platform-engineering/docker-templates/bun-hoisted-symlink-fix.sh +1 -1
- package/cli/shared-platform-engineering/docker-templates/infisical-entrypoint.sh +1 -1
- package/cli/shared-platform-engineering/docker-templates/install-deps.sh +1 -1
- package/cli/shared-platform-engineering/docker-templates/prisma-bun-client-link-fix.sh +1 -1
- package/cli/shared-platform-engineering/docker-templates/prisma-normalize-client.sh +1 -1
- package/cli/templates/Tiltfile.hbs +1 -1
- package/discovery/AGENTS.md +1 -1
- package/discovery/TILT_DISCOVERY.star +3 -3
- package/discovery/Tiltfile +3 -3
- package/discovery/config.star +1 -1
- package/discovery/constants.star +1 -1
- package/discovery/discovery_orchestrator.star +1 -1
- package/discovery/identity-management-frontend/service.yaml +1 -1
- package/discovery/json_manifest_scanner.star +1 -1
- package/discovery/manifest/constants.star +1 -1
- package/discovery/manifest/loading.star +2 -2
- package/discovery/manifest/normalize.star +1 -1
- package/discovery/registry.star +1 -1
- package/discovery/resource_snapshot.py +1 -1
- package/discovery/resource_snapshot.star +1 -1
- package/discovery/test_resource_snapshot.py +2 -2
- package/engine/AGENTS.md +7 -7
- package/engine/README.md +1 -1
- package/engine/Tiltfile +3 -3
- package/engine/assets/docker/wake-gateway/decide.ts +1 -1
- package/engine/assets/docker/wake-gateway/server.ts +1 -1
- package/engine/assets/scripts/mac-m1-resource-monitor.sh +8 -8
- package/engine/lifecycle/orchestrator.star +6 -6
- package/engine/paths.star +1 -1
- package/engine/schemas/project-schema.json +2 -2
- package/engine/schemas/service-schema.json +3 -3
- package/engine/scripts/debug-container.sh +2 -2
- package/engine/spec.master +1 -1
- package/engine/topologies/platform/docker/compose/compose.star +1 -1
- package/engine/topologies/platform/docker/compose/traefik_standalone.star +1 -1
- package/engine/topologies/platform/docker/config/healthcheck.star +1 -1
- package/engine/topologies/platform/docker/constants.star +2 -2
- package/engine/topologies/platform/docker/dockerfile/language_dockerfile.star +3 -3
- package/engine/topologies/platform/docker/layers/l1_base_layers.star +1 -1
- package/engine/topologies/platform/docker/layers/l2_dependency_layers.star +1 -1
- package/engine/topologies/platform/docker/layers/l3_builder_layers.star +1 -1
- package/engine/topologies/platform/docker/layers/l4_runtime_layers.star +1 -1
- package/engine/topologies/platform/docker/layers/prisma/constants.star +1 -1
- package/engine/topologies/platform/docker/layers/prisma/prisma_build.star +2 -2
- package/engine/topologies/platform/docker/networking/api_path_constants.star +1 -1
- package/engine/topologies/platform/docker/networking/traefik_static_routes.star +1 -1
- package/engine/topologies/platform/docker/secrets/env_secrets.star +1 -1
- package/engine/topologies/platform/docker/secrets/infisical.star +1 -1
- package/engine/topologies/platform/security/secrets.star +1 -1
- package/engine/topologies/tilt/common/utils.star +5 -3
- package/engine/topologies/tilt/common/utils_debug.star +1 -1
- package/engine/topologies/tilt/common/utils_deterministic.star +1 -1
- package/engine/topologies/tilt/common/utils_env.star +23 -3
- package/engine/topologies/tilt/config/profiles.star +1 -1
- package/engine/topologies/tilt/generators/infisical/organization.star +1 -1
- package/engine/topologies/tilt/generators/npmrc.star +4 -4
- package/engine/topologies/tilt/generators/typescript/backend_tsconfig.star +1 -1
- package/engine/topologies/tilt/generators/vite/helpers.star +1 -1
- package/engine/topologies/tilt/generators/vite/templates.star +1 -1
- package/engine/topologies/tilt/manifest/json_to_yaml.py +2 -2
- package/engine/topologies/tilt/manifest/loader.star +1 -1
- package/engine/topologies/tilt/manifest/schema.star +2 -2
- package/engine/topologies/tilt/manifest/tests/test_loader_parser.star +3 -3
- package/engine/topologies/tilt/manifest/tests/test_validator.star +2 -2
- package/engine/topologies/tilt/manifest/yaml_to_json.py +1 -1
- package/engine/topologies/tilt/resources/databases.star +1 -1
- package/engine/topologies/tilt/resources/infra-loader.star +8 -6
- package/engine/topologies/tilt/resources/libs_paths.star +1 -1
- package/engine/topologies/tilt/resources/libs_resource_definition.star +1 -1
- package/engine/topologies/tilt/resources/libs_setup.star +1 -1
- package/engine/topologies/tilt/resources/orchestrator/apply_compose_resource_registration.star +13 -8
- package/engine/topologies/tilt/resources/orchestrator/generators/frontend.star +1 -1
- package/engine/topologies/tilt/resources/orchestrator/generators/manifest_resource.star +1 -1
- package/engine/topologies/tilt/resources/watchers.star +7 -7
- package/engine/where-things-live.star +1 -1
- package/examples/tdk-example/LICENSE +1 -1
- package/examples/tdk-example/Tiltfile +7 -7
- package/examples/tdk-example/services/shop/orders-api/service.json +1 -1
- package/examples/tdk-example/services/shop/orders-app/index.html +1 -1
- package/examples/tdk-example/services/shop/orders-app/service.json +1 -1
- package/examples/tdk-example/services/shop/orders-worker/service.json +1 -1
- package/ext/Tiltfile +3 -3
- package/ext/ide-components/code_viewer/server.py +1 -1
- package/ext/ide-components/config_inspector/server.py +1 -1
- package/ext/ide-components/file_browser/server.py +1 -1
- package/ext/ide-components/shared/config_service.py +2 -2
- package/ext/ide-components/shared/file_utils.py +2 -2
- package/ext/ide-components/shared/http_utils.py +1 -1
- package/ext/ide-components/shared/syntax_highlighter.py +1 -1
- package/ext/ide-components/shared/template_engine.py +1 -1
- package/ext/ide-components/shared/templates/base.html +1 -1
- package/ext/ide-components/shared/test_config_service.py +1 -1
- package/ext/ide-components/shared/tilt_integration.py +1 -1
- package/ext/ui-enhancements/tiltfile.py +1 -1
- package/package.json +6 -10
- package/shared-platform-engineering/docker-templates/bun-hoisted-symlink-fix.sh +1 -1
- package/shared-platform-engineering/docker-templates/infisical-entrypoint.sh +1 -1
- package/shared-platform-engineering/docker-templates/install-deps.sh +1 -1
- package/shared-platform-engineering/docker-templates/prisma-bun-client-link-fix.sh +1 -1
- package/shared-platform-engineering/docker-templates/prisma-normalize-client.sh +1 -1
- package/cli/dist-bundle/chunk-CLCUIDBH.js +0 -510
- package/cli/dist-bundle/cold-preflight-SY26O2IG.js +0 -2
|
@@ -79,7 +79,7 @@ function shellTypeCondition(types) {
|
|
|
79
79
|
return parts.join(" || ");
|
|
80
80
|
}
|
|
81
81
|
/** The name of the variable that holds the `--type` of the command line. */
|
|
82
|
-
const TYPE_VARIABLE = "
|
|
82
|
+
const TYPE_VARIABLE = "tdk_type";
|
|
83
83
|
/** The stacks of the current project, read from the machine-readable CLI output. */
|
|
84
84
|
const BASH_STACKS = `flisk stacks --json 2>/dev/null | grep -o '"name":"[^"]*"' | sed 's/"name":"//;s/"$//'`;
|
|
85
85
|
const BASH_RESOURCES = `flisk resources --json 2>/dev/null | grep -o '"name":"[^"]*"' | sed 's/"name":"//;s/"$//'`;
|
|
@@ -106,7 +106,7 @@ const ZSH_TYPE = ` local ${TYPE_VARIABLE}=""
|
|
|
106
106
|
fi
|
|
107
107
|
done`;
|
|
108
108
|
/** The `--type` of the current command line, in fish. */
|
|
109
|
-
const FISH_TYPE = `function
|
|
109
|
+
const FISH_TYPE = `function __tdk_resource_type
|
|
110
110
|
set -l tokens (commandline -opc)
|
|
111
111
|
set -l ${TYPE_VARIABLE} ""
|
|
112
112
|
set -l token_count (count $tokens)
|
|
@@ -156,7 +156,7 @@ function zshTypeValues(flag, values) {
|
|
|
156
156
|
}
|
|
157
157
|
/** The values of a flag that depend on the `--type`, in fish. */
|
|
158
158
|
function fishTypeValues(values) {
|
|
159
|
-
const lines = [" switch (
|
|
159
|
+
const lines = [" switch (__tdk_resource_type)"];
|
|
160
160
|
for (const arm of typeValueArms(values)) {
|
|
161
161
|
lines.push(` case ${arm.types.map((type) => (type === "" ? "''" : type)).join(" ")}`);
|
|
162
162
|
lines.push(` printf '%s\\n' ${arm.values.join(" ")}`);
|
|
@@ -252,7 +252,7 @@ function renderBash(candidates) {
|
|
|
252
252
|
.join("\n");
|
|
253
253
|
return `# Flisk CLI Bash Completion
|
|
254
254
|
# Generated by "flisk completion bash". The command and flag lists come from the CLI itself.
|
|
255
|
-
|
|
255
|
+
_tdk_completions() {
|
|
256
256
|
local cur prev cmd sub options words commands stacks resources path ${TYPE_VARIABLE} ${TYPE_VARIABLE}_values
|
|
257
257
|
COMPREPLY=()
|
|
258
258
|
cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
@@ -335,24 +335,24 @@ ${positionalCases}
|
|
|
335
335
|
return 0
|
|
336
336
|
}
|
|
337
337
|
|
|
338
|
-
complete -F
|
|
338
|
+
complete -F _tdk_completions flisk
|
|
339
339
|
`;
|
|
340
340
|
}
|
|
341
341
|
/** The `_arguments` spec of the positional argument of a command. */
|
|
342
342
|
function zshPositionalSpecs(entry) {
|
|
343
343
|
// A command with sub-commands completes the name of the sub-command, not a value.
|
|
344
344
|
if (entry.subcommands.length > 0) {
|
|
345
|
-
return [`'1: :
|
|
345
|
+
return [`'1: :_tdk_${entry.name}_subcommands'`];
|
|
346
346
|
}
|
|
347
347
|
switch (entry.positional) {
|
|
348
348
|
case "stacks":
|
|
349
|
-
return ["'1:stack:
|
|
349
|
+
return ["'1:stack:_tdk_stacks'"];
|
|
350
350
|
case "resources":
|
|
351
|
-
return ["'1:resource:
|
|
351
|
+
return ["'1:resource:_tdk_resources'"];
|
|
352
352
|
case "stacks-and-resources":
|
|
353
|
-
return ["'1:target:
|
|
353
|
+
return ["'1:target:_tdk_stacks'"];
|
|
354
354
|
case "commands":
|
|
355
|
-
return ["'1:command:
|
|
355
|
+
return ["'1:command:_tdk_commands'"];
|
|
356
356
|
default:
|
|
357
357
|
break;
|
|
358
358
|
}
|
|
@@ -411,25 +411,25 @@ function renderZsh(candidates) {
|
|
|
411
411
|
.join("\n");
|
|
412
412
|
const subCommandLists = entries
|
|
413
413
|
.filter((entry) => entry.subcommands.length > 0)
|
|
414
|
-
.map((entry) => `
|
|
414
|
+
.map((entry) => `_tdk_${entry.name}_subcommands() {\n local commands=(\n${entry.subcommands
|
|
415
415
|
.map((subcommand) => ` '${subcommand.name}:${shortDescription(subcommand.description)}'`)
|
|
416
416
|
.join("\n")}\n )\n _describe -t commands '${entry.name} command' commands\n}`)
|
|
417
417
|
.join("\n\n");
|
|
418
418
|
const typeValueFunctions = Object.entries(candidates.typeValues)
|
|
419
|
-
.map(([flag, values]) => `
|
|
419
|
+
.map(([flag, values]) => `_tdk_${flag.slice(2)}_values() {\n${ZSH_TYPE}\n${zshTypeValues(flag, values)}\n}`)
|
|
420
420
|
.join("\n\n");
|
|
421
421
|
return `#compdef flisk
|
|
422
422
|
|
|
423
423
|
# Flisk CLI Zsh Completion
|
|
424
424
|
# Generated by "flisk completion zsh". The command and flag lists come from the CLI itself.
|
|
425
425
|
|
|
426
|
-
|
|
426
|
+
_tdk() {
|
|
427
427
|
local curcontext="$curcontext" state line
|
|
428
428
|
typeset -A opt_args
|
|
429
429
|
|
|
430
430
|
_arguments -C \\
|
|
431
431
|
${globalFlags} \\
|
|
432
|
-
'1: :
|
|
432
|
+
'1: :_tdk_commands' \\
|
|
433
433
|
'*:: :->args'
|
|
434
434
|
|
|
435
435
|
case "$line[1]" in
|
|
@@ -441,20 +441,20 @@ ${subCommandStates}
|
|
|
441
441
|
esac
|
|
442
442
|
}
|
|
443
443
|
|
|
444
|
-
|
|
444
|
+
_tdk_commands() {
|
|
445
445
|
local commands=(
|
|
446
446
|
${commandList}
|
|
447
447
|
)
|
|
448
448
|
_describe -t commands 'flisk command' commands
|
|
449
449
|
}
|
|
450
450
|
|
|
451
|
-
|
|
451
|
+
_tdk_stacks() {
|
|
452
452
|
local stacks
|
|
453
453
|
stacks=($(flisk stacks --json 2>/dev/null | grep -o '"name":"[^"]*"' | sed 's/"name":"//;s/"$//'))
|
|
454
454
|
_describe -t stacks 'stack' stacks
|
|
455
455
|
}
|
|
456
456
|
|
|
457
|
-
|
|
457
|
+
_tdk_resources() {
|
|
458
458
|
local resources
|
|
459
459
|
resources=($(flisk resources --json 2>/dev/null | grep -o '"name":"[^"]*"' | sed 's/"name":"//;s/"$//'))
|
|
460
460
|
_describe -t resources 'resource' resources
|
|
@@ -463,24 +463,24 @@ _flisk_resources() {
|
|
|
463
463
|
${subCommandLists}
|
|
464
464
|
|
|
465
465
|
${typeValueFunctions}
|
|
466
|
-
compdef
|
|
466
|
+
compdef _tdk flisk
|
|
467
467
|
`;
|
|
468
468
|
}
|
|
469
469
|
/** The `_arguments` spec of one flag, with the values it completes when it has them. */
|
|
470
470
|
function zshOptionSpec(option, candidates, entry) {
|
|
471
471
|
const description = shortDescription(option.description);
|
|
472
472
|
if (candidates.typeValues[option.flag]) {
|
|
473
|
-
return `'${option.flag}[${description}]:${option.flag.slice(2)}:
|
|
473
|
+
return `'${option.flag}[${description}]:${option.flag.slice(2)}:_tdk_${option.flag.slice(2)}_values'`;
|
|
474
474
|
}
|
|
475
475
|
const values = valuesOf(option.flag, candidates, entry);
|
|
476
476
|
if (values) {
|
|
477
477
|
return `'${option.flag}[${description}]:${option.flag.slice(2)}:(${values.join(" ")})'`;
|
|
478
478
|
}
|
|
479
479
|
if (option.flag === "--stack") {
|
|
480
|
-
return `'${option.flag}[${description}]:stack:
|
|
480
|
+
return `'${option.flag}[${description}]:stack:_tdk_stacks'`;
|
|
481
481
|
}
|
|
482
482
|
if (option.flag === "--only") {
|
|
483
|
-
return `'${option.flag}[${description}]:service:
|
|
483
|
+
return `'${option.flag}[${description}]:service:_tdk_resources'`;
|
|
484
484
|
}
|
|
485
485
|
return option.takesValue
|
|
486
486
|
? `'${option.flag}[${description}]:${option.flag.slice(2)}:'`
|
|
@@ -526,7 +526,7 @@ function renderFish(candidates) {
|
|
|
526
526
|
.filter((entry) => entry.positional === "commands")
|
|
527
527
|
.map((entry) => `complete -c flisk -f -n '${fishCondition(entry)}' -a '${commandWords(entries).join(" ")}'`);
|
|
528
528
|
const typeValueFunctions = Object.entries(candidates.typeValues)
|
|
529
|
-
.map(([flag, values]) => `function
|
|
529
|
+
.map(([flag, values]) => `function __tdk_${flag.slice(2)}_values\n${fishTypeValues(values)}\nend`)
|
|
530
530
|
.join("\n\n");
|
|
531
531
|
return `# Flisk CLI Fish Completion
|
|
532
532
|
# Generated by "flisk completion fish". The command and flag lists come from the CLI itself.
|
|
@@ -571,7 +571,7 @@ function fishCondition(entry) {
|
|
|
571
571
|
/** The fish argument that lists the values of a flag. */
|
|
572
572
|
function fishValueArgument(option, candidates, entry) {
|
|
573
573
|
if (candidates.typeValues[option.flag]) {
|
|
574
|
-
return ` -r -a '(
|
|
574
|
+
return ` -r -a '(__tdk_${option.flag.slice(2)}_values)'`;
|
|
575
575
|
}
|
|
576
576
|
const values = valuesOf(option.flag, candidates, entry);
|
|
577
577
|
return values ? ` -r -a '${values.join(" ")}'` : "";
|
|
@@ -761,11 +761,11 @@ export const completionCommand = new Command("completion")
|
|
|
761
761
|
const candidates = buildCompletionCandidates(program);
|
|
762
762
|
const completionScript = renderCompletionScript(shell, candidates);
|
|
763
763
|
const filename = shell === "bash"
|
|
764
|
-
? "
|
|
764
|
+
? "tdk-completion.bash"
|
|
765
765
|
: shell === "zsh"
|
|
766
|
-
? "
|
|
766
|
+
? "_tdk"
|
|
767
767
|
: shell === "fish"
|
|
768
|
-
? "
|
|
768
|
+
? "tdk.fish"
|
|
769
769
|
: "Microsoft.PowerShell_profile.ps1";
|
|
770
770
|
if (options.install) {
|
|
771
771
|
const home = homedir();
|
|
@@ -325,7 +325,7 @@ async function toggleInfraService(service, enabled) {
|
|
|
325
325
|
const granted = await hasVerdaccioLicense(projectRoot);
|
|
326
326
|
if (!granted) {
|
|
327
327
|
throw new Error("Verdaccio is a Premium feature and requires a license key that grants it. " +
|
|
328
|
-
"Set export TDK_LICENSE_KEY=<key> (request a Premium license at https://
|
|
328
|
+
"Set export TDK_LICENSE_KEY=<key> (request a Premium license at https://flisk.sh/#waitlist) and try again.");
|
|
329
329
|
}
|
|
330
330
|
}
|
|
331
331
|
const config = readProjectConfig(projectRoot);
|
|
@@ -9,7 +9,7 @@ import { getPackageVersion } from "../utils/paths.js";
|
|
|
9
9
|
* pinned version so a push to its main branch cannot change what `flisk import` does. Move the pin
|
|
10
10
|
* when a new importer is published. `TDK_IMPORT_PACKAGE` overrides the package spec.
|
|
11
11
|
*/
|
|
12
|
-
export const IMPORT_PACKAGE = "
|
|
12
|
+
export const IMPORT_PACKAGE = "flisk-import@0.2.2";
|
|
13
13
|
/** Minimum Flisk core release supporting buildContext required by flisk import (#634). */
|
|
14
14
|
export const MIN_CORE_VERSION = "1.3.104";
|
|
15
15
|
/** Recommended core version with automatic Tiltfile bootstrapping for imported stacks (#1018). */
|
|
@@ -109,7 +109,7 @@ export function importInvocation(args, env = process.env, platform = process.pla
|
|
|
109
109
|
shell: platform === "win32",
|
|
110
110
|
};
|
|
111
111
|
}
|
|
112
|
-
/** Runs
|
|
112
|
+
/** Runs flisk-import with the caller's terminal and resolves to its exit code. */
|
|
113
113
|
export function runImport(args, spawnFn = spawn, getVersionFn = getPackageVersion) {
|
|
114
114
|
const check = checkCoreVersion(getVersionFn(), args);
|
|
115
115
|
if (!check.ok) {
|
|
@@ -153,8 +153,8 @@ export function buildForwardedImportArgs(args, options = {}) {
|
|
|
153
153
|
return filtered;
|
|
154
154
|
}
|
|
155
155
|
export const importCommand = addYesOption(new Command("import"))
|
|
156
|
-
.description("Import the services in a directory's root docker-compose.yml (runs
|
|
157
|
-
.argument("[args...]", "Passed to
|
|
156
|
+
.description("Import the services in a directory's root docker-compose.yml (runs flisk-import)")
|
|
157
|
+
.argument("[args...]", "Passed to flisk-import: [dir] --dry-run --yes --force")
|
|
158
158
|
.option("-f, --force", "Overwrite an existing service.json", false)
|
|
159
159
|
.allowUnknownOption()
|
|
160
160
|
.helpOption(false)
|
|
@@ -6,7 +6,7 @@ import { Command } from "commander";
|
|
|
6
6
|
export const MIN_MAINTAINERS = 3;
|
|
7
7
|
export const MIN_COMPANIES = 2;
|
|
8
8
|
const REQUIRED_COLUMNS = ["name", "github id", "company"];
|
|
9
|
-
const PLACEHOLDER_COMPANIES = new Set(["", "tbd", "unknown", "
|
|
9
|
+
const PLACEHOLDER_COMPANIES = new Set(["", "tbd", "unknown", "flisk-sh"]);
|
|
10
10
|
function splitRow(line) {
|
|
11
11
|
return line
|
|
12
12
|
.trim()
|
package/cli/dist/commands/mcp.js
CHANGED
|
@@ -8,10 +8,7 @@ import { getPackageVersion } from "../utils/paths.js";
|
|
|
8
8
|
export const mcpCommand = new Command("mcp")
|
|
9
9
|
.description("Run a Model Context Protocol server over stdio for coding agents")
|
|
10
10
|
.action(async () => {
|
|
11
|
-
const server = createMcpServer(createTdkTools(), {
|
|
12
|
-
name: "flisk",
|
|
13
|
-
version: getPackageVersion(),
|
|
14
|
-
});
|
|
11
|
+
const server = createMcpServer(createTdkTools(), { name: "flisk", version: getPackageVersion() });
|
|
15
12
|
// Stdout is the protocol channel. Nothing else may write to it; diagnostics go to stderr.
|
|
16
13
|
const lines = createInterface({ input: process.stdin });
|
|
17
14
|
const pending = new Set();
|
|
@@ -78,7 +78,15 @@ function getDefaultCoreServices() {
|
|
|
78
78
|
.filter((f) => f.enabled_by_default && f.category === "core")
|
|
79
79
|
.map((f) => f.name);
|
|
80
80
|
}
|
|
81
|
-
|
|
81
|
+
/** The directory a template lands in: the requested path, or the template's repository name. */
|
|
82
|
+
export function templateTargetDir(templateName, targetDir) {
|
|
83
|
+
if (targetDir)
|
|
84
|
+
return targetDir;
|
|
85
|
+
const template = PROJECT_TEMPLATES[templateName];
|
|
86
|
+
const fromRepo = template?.repo.split("/").pop() ?? templateName;
|
|
87
|
+
return fromRepo.replace(/\.git$/, "");
|
|
88
|
+
}
|
|
89
|
+
export async function cloneProjectTemplate(templateName, targetDir, runtimeNextSteps) {
|
|
82
90
|
const template = PROJECT_TEMPLATES[templateName];
|
|
83
91
|
if (!template) {
|
|
84
92
|
console.log(chalk.red(`\n❌ Unknown template: "${templateName}"`));
|
|
@@ -89,7 +97,7 @@ async function cloneProjectTemplate(templateName, targetDir, runtimeNextSteps) {
|
|
|
89
97
|
console.log(chalk.gray("\nOr run `flisk project` with no template for a blank project."));
|
|
90
98
|
process.exit(1);
|
|
91
99
|
}
|
|
92
|
-
const dirName =
|
|
100
|
+
const dirName = templateTargetDir(templateName, targetDir);
|
|
93
101
|
if (!isPathSafe(dirName)) {
|
|
94
102
|
errorFactories.invalidPath(dirName).exit();
|
|
95
103
|
}
|
|
@@ -499,7 +499,7 @@ export const resourceCommand = addYesOption(new Command("resource"))
|
|
|
499
499
|
const granted = await hasDddLicense(projectRoot);
|
|
500
500
|
if (!granted) {
|
|
501
501
|
throw new Error("DDD scaffolding is a Premium feature and requires a license key that grants it. " +
|
|
502
|
-
"Set export TDK_LICENSE_KEY=<key> (request a Premium license at https://
|
|
502
|
+
"Set export TDK_LICENSE_KEY=<key> (request a Premium license at https://flisk.sh/#waitlist) and try again.");
|
|
503
503
|
}
|
|
504
504
|
dddEnabled = true;
|
|
505
505
|
}
|
package/cli/dist/commands/ui.js
CHANGED
|
@@ -45,7 +45,7 @@ export const LoadingScreen = ({ message = "Discovering resources...", animated =
|
|
|
45
45
|
// biome-ignore lint/correctness/noUnusedFunctionParameters: reserved callback prop kept in the component API
|
|
46
46
|
const ErrorScreen = ({ error, onRetry }) => {
|
|
47
47
|
const theme = useTUITheme();
|
|
48
|
-
return (_jsxs(Box, { flexDirection: "column", padding: 2, alignItems: "center", children: [_jsx(Text, { bold: true, color: theme.error, children: "Could Not Load Services" }), _jsx(Box, { marginY: 1 }), _jsxs(Text, { color: theme.error, children: [theme.ascii ? "[x]" : "\u2717", " ", error] }), _jsx(Box, { marginY: 1 }), _jsx(Text, { color: theme.muted, children: "Troubleshooting:" }), _jsx(Text, { color: theme.muted, children: " 1. Check that every service.json is valid JSON" }),
|
|
48
|
+
return (_jsxs(Box, { flexDirection: "column", padding: 2, alignItems: "center", children: [_jsx(Text, { bold: true, color: theme.error, children: "Could Not Load Services" }), _jsx(Box, { marginY: 1 }), _jsxs(Text, { color: theme.error, children: [theme.ascii ? "[x]" : "\u2717", " ", error] }), _jsx(Box, { marginY: 1 }), _jsx(Text, { color: theme.muted, children: "Troubleshooting:" }), _jsx(Text, { color: theme.muted, children: " 1. Check that every service.json is valid JSON" }), _jsx(Text, { color: theme.muted, children: " 2. Run flisk from your project (the folder with the Tiltfile)" }), _jsx(Text, { color: theme.muted, children: " 3. Try: flisk status --verbose" }), _jsx(Box, { marginY: 1 }), _jsx(Text, { color: theme.accent, children: "Press [r] to retry or [q] to quit" })] }));
|
|
49
49
|
};
|
|
50
50
|
const EmptyState = ({ message }) => {
|
|
51
51
|
const theme = useTUITheme();
|
package/cli/dist/commands/up.js
CHANGED
|
@@ -10,8 +10,9 @@ import { DEVCONTAINER_DOCKER_FIX, detectHost, isContainerHost, WEBCONTAINER_UP_M
|
|
|
10
10
|
import { handleDryRun } from "../utils/command-helpers.js";
|
|
11
11
|
import { STANDARD_PORTS } from "../utils/constants.js";
|
|
12
12
|
import { getDeferredResourceNames, summarizeTiltBuildError } from "../utils/doctor-runtime.js";
|
|
13
|
+
import { applyEnvFileSelection, assertEngineSupportsEnvFile, EnvFileError, envFileWarning, PROJECT_ENV_FILE_VAR, selectEnvFile, } from "../utils/env-selection.js";
|
|
13
14
|
import { completeEnvFile } from "../utils/env-validator.js";
|
|
14
|
-
import { errorFactories, handleTiltFailure, requireProjectRoot, runCommand, showError, showErrorAndExit, withTiltCheck, } from "../utils/errors.js";
|
|
15
|
+
import { errorFactories, getErrorMessage, handleTiltFailure, requireProjectRoot, runCommand, showError, showErrorAndExit, TdkError, withTiltCheck, } from "../utils/errors.js";
|
|
15
16
|
import { ensureSmokeRecordsIgnored } from "../utils/file-helpers.js";
|
|
16
17
|
import { formatCount } from "../utils/formatting.js";
|
|
17
18
|
import { exportHostPortPlan, getHostPortPlan, writeSavedHostPortPlan, } from "../utils/host-port-config.js";
|
|
@@ -162,6 +163,37 @@ function waitForTiltUi(port, timeoutMs = 30_000) {
|
|
|
162
163
|
attempt();
|
|
163
164
|
});
|
|
164
165
|
}
|
|
166
|
+
/**
|
|
167
|
+
* The env file of the run. `flisk up --env-file <path>` replaces the project `.env` for the run, so the
|
|
168
|
+
* file is resolved, read and checked before anything is written or started. Without the option the
|
|
169
|
+
* project `.env` stays the env file of the run, exactly as before.
|
|
170
|
+
*
|
|
171
|
+
* @throws TdkError when the file cannot be used; the run stops before it starts
|
|
172
|
+
*/
|
|
173
|
+
export function selectRunEnvFile(projectRoot, requested) {
|
|
174
|
+
if (requested === undefined)
|
|
175
|
+
return undefined;
|
|
176
|
+
if (!projectRoot) {
|
|
177
|
+
throw errorFactories.notInProject();
|
|
178
|
+
}
|
|
179
|
+
const selection = selectEnvFile(projectRoot, requested);
|
|
180
|
+
// A project created before this option vendored an engine that ignores the selection, so the run
|
|
181
|
+
// would silently use the project .env instead.
|
|
182
|
+
assertEngineSupportsEnvFile(projectRoot);
|
|
183
|
+
return selection;
|
|
184
|
+
}
|
|
185
|
+
/** The machine-readable failure of a refused `--env-file`, and the exit code it stops the run with. */
|
|
186
|
+
function envFileFailure(error) {
|
|
187
|
+
const suggestions = error instanceof TdkError ? error.suggestions : [];
|
|
188
|
+
return {
|
|
189
|
+
failure: {
|
|
190
|
+
code: error instanceof EnvFileError ? error.code : "ENV_FILE_INVALID",
|
|
191
|
+
message: getErrorMessage(error),
|
|
192
|
+
...(suggestions.length > 0 ? { suggestions } : {}),
|
|
193
|
+
},
|
|
194
|
+
exitCode: error instanceof TdkError ? error.exitCode : 2,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
165
197
|
export const upCommand = new Command("up")
|
|
166
198
|
.description("Start all services (optionally filtered by stack)")
|
|
167
199
|
.alias("deploy")
|
|
@@ -173,6 +205,7 @@ export const upCommand = new Command("up")
|
|
|
173
205
|
.option("--ignore-drift", "Start even if generated files differ from service.json", false)
|
|
174
206
|
.option("--ignore-version", "Start even if this flisk is older than minTdkVersion in .tdk/project.json", false)
|
|
175
207
|
.option("--only <services...>", "Start only these services plus what the Tiltfile enables for them (their dependsOn services and shared infrastructure). With a stack, names must belong to that stack; dependencies may cross stacks")
|
|
208
|
+
.option("--env-file <path>", "Use this project env file for the run instead of .env (for example: --env-file .env.integration)")
|
|
176
209
|
.option("--json", "Print one JSON object on stdout when the stack is ready or the command fails; implies --quiet", false)
|
|
177
210
|
.action(async (stackName, options) => {
|
|
178
211
|
const emit = options.json ? createJsonEmitter("UP_FAILED", "flisk up") : undefined;
|
|
@@ -192,6 +225,35 @@ export const upCommand = new Command("up")
|
|
|
192
225
|
onFail: (message) => emit?.({ ok: false }, [{ code: "TDK_VERSION_TOO_OLD", message }]),
|
|
193
226
|
});
|
|
194
227
|
}
|
|
228
|
+
// The env file of the run. `--env-file` replaces the project .env for this run, so the file is
|
|
229
|
+
// resolved and read before any prerequisite check, any write and any service starts.
|
|
230
|
+
const envFileRoot = versionRoot;
|
|
231
|
+
let envFileSelection;
|
|
232
|
+
if (options.envFile === undefined) {
|
|
233
|
+
// Without the option the project .env is the env file of the run, whatever the environment
|
|
234
|
+
// carries: an inherited TDK_ENV_FILE must not change the default.
|
|
235
|
+
delete process.env[PROJECT_ENV_FILE_VAR];
|
|
236
|
+
}
|
|
237
|
+
if (options.envFile !== undefined) {
|
|
238
|
+
try {
|
|
239
|
+
envFileSelection = selectRunEnvFile(envFileRoot, options.envFile);
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
const { failure, exitCode } = envFileFailure(error);
|
|
243
|
+
emit?.({ ok: false }, [failure]);
|
|
244
|
+
showErrorAndExit(failure.message, exitCode, failure.suggestions);
|
|
245
|
+
}
|
|
246
|
+
if (envFileSelection && envFileRoot) {
|
|
247
|
+
applyEnvFileSelection(envFileSelection);
|
|
248
|
+
if (!options.quiet) {
|
|
249
|
+
console.log(chalk.gray(`Using env file: ${envFileSelection.relativePath} (the project .env is not read in this run)`));
|
|
250
|
+
}
|
|
251
|
+
const warning = envFileWarning(envFileRoot, envFileSelection);
|
|
252
|
+
// stderr, not stdout: in --json mode stdout carries the JSON envelope only.
|
|
253
|
+
if (warning)
|
|
254
|
+
console.warn(chalk.yellow(warning));
|
|
255
|
+
}
|
|
256
|
+
}
|
|
195
257
|
const hostRefusal = options.dryRun ? null : await hostUpRefusal();
|
|
196
258
|
if (hostRefusal) {
|
|
197
259
|
emit?.({ ok: false }, [{ code: "HOST_UNSUPPORTED", message: hostRefusal }]);
|
|
@@ -281,7 +343,8 @@ export const upCommand = new Command("up")
|
|
|
281
343
|
if (!options.dryRun) {
|
|
282
344
|
// An older project's .env predates keys such as JWT_SECRET, which Compose now requires. Add what is missing (never
|
|
283
345
|
// changing an existing value) before anything starts. Only inside a real project, so a stray run never writes a .env.
|
|
284
|
-
|
|
346
|
+
// A selected env file replaces the project .env for this run: the run does not read it, so it is not completed either.
|
|
347
|
+
if (foundRoot && !envFileSelection) {
|
|
285
348
|
const addedEnvKeys = completeEnvFile(projectRoot);
|
|
286
349
|
if (addedEnvKeys.length > 0 && !options.quiet) {
|
|
287
350
|
console.log(chalk.gray(`Added ${addedEnvKeys.join(", ")} to .env (generated; existing values unchanged)`));
|
|
@@ -418,6 +481,14 @@ export const upCommand = new Command("up")
|
|
|
418
481
|
only: Boolean(options.only),
|
|
419
482
|
});
|
|
420
483
|
if (decision.action === "already-running") {
|
|
484
|
+
// The env file of the run belongs to the Tilt process this run starts. A stack that is
|
|
485
|
+
// already running keeps the env file it started with, so the selection would be ignored
|
|
486
|
+
// silently - say so instead of reporting a run that never happened.
|
|
487
|
+
if (envFileSelection) {
|
|
488
|
+
const message = `A Tilt is already running on port ${decision.ports.join(", ")}. --env-file applies to a new run only: run \`flisk down\` first, or pass --force to replace the running stack.`;
|
|
489
|
+
emit?.({ ok: false }, [{ code: "ENV_FILE_ALREADY_RUNNING", message }]);
|
|
490
|
+
showErrorAndExit(message);
|
|
491
|
+
}
|
|
421
492
|
const message = `Environment is already running on port ${decision.ports.join(", ")}.`;
|
|
422
493
|
emit?.({
|
|
423
494
|
ok: true,
|
|
@@ -553,7 +624,10 @@ export const upCommand = new Command("up")
|
|
|
553
624
|
console.warn(chalk.yellow(ignoreWarning));
|
|
554
625
|
const results = await runSmokePlans(smokePlans, {
|
|
555
626
|
recordDir: join(projectRoot, ".tdk", "smoke"),
|
|
556
|
-
...safeSmokeDeps(projectRoot, (message) => console.warn(chalk.yellow(message))
|
|
627
|
+
...safeSmokeDeps(projectRoot, (message) => console.warn(chalk.yellow(message)), {
|
|
628
|
+
// The selected env file holds secrets as much as the project .env.
|
|
629
|
+
envFiles: envFileSelection ? [envFileSelection.path] : [],
|
|
630
|
+
}),
|
|
557
631
|
});
|
|
558
632
|
for (const smokeResult of results) {
|
|
559
633
|
if (smokeResult.ok) {
|
|
@@ -12,7 +12,7 @@ import { PACKAGE_JSON } from "../utils/constants.js";
|
|
|
12
12
|
import { getErrorMessage, logVerbose, showErrorAndExit } from "../utils/errors.js";
|
|
13
13
|
import { showCancelled } from "../utils/formatting.js";
|
|
14
14
|
import { getPackageVersion } from "../utils/paths.js";
|
|
15
|
-
import { binaryAssetName, executableName, isWindows
|
|
15
|
+
import { binaryAssetName, executableName, isWindows } from "../utils/platform.js";
|
|
16
16
|
import { promptConfirm } from "../utils/prompt.js";
|
|
17
17
|
import { startSpinner } from "../utils/spinner.js";
|
|
18
18
|
import { extractTarball } from "../utils/tar.js";
|
|
@@ -33,11 +33,7 @@ export function isStandaloneBinary(tdkPath) {
|
|
|
33
33
|
/** @internal Exported for unit tests only; not part of the package API. */
|
|
34
34
|
export function classifyRunningInstall(execPath, scriptPath, platformName = process.platform) {
|
|
35
35
|
const runningName = (platformName === "win32" ? win32.basename(execPath) : basename(execPath)).toLowerCase();
|
|
36
|
-
|
|
37
|
-
runningName === "flisk.exe" ||
|
|
38
|
-
runningName === "tdk" ||
|
|
39
|
-
runningName === "tdk.exe";
|
|
40
|
-
if (isFliskBinary) {
|
|
36
|
+
if (runningName === "flisk" || runningName === "tdk.exe") {
|
|
41
37
|
return { method: "binary", path: execPath };
|
|
42
38
|
}
|
|
43
39
|
if (runningName === "node" || runningName === "node.exe") {
|
|
@@ -61,7 +57,7 @@ export function detectInstallation() {
|
|
|
61
57
|
if (runningInstall)
|
|
62
58
|
return runningInstall;
|
|
63
59
|
try {
|
|
64
|
-
const tdkPath = findOnPath(executableName())
|
|
60
|
+
const tdkPath = findOnPath(executableName());
|
|
65
61
|
if (!tdkPath)
|
|
66
62
|
return { method: "unknown" };
|
|
67
63
|
// `readlink -f` is not available on macOS. Use Node's cross-platform
|
|
@@ -84,7 +80,7 @@ export function detectInstallation() {
|
|
|
84
80
|
if (existsSync(join(cliRoot, ".git"))) {
|
|
85
81
|
return { method: "git", path: cliRoot };
|
|
86
82
|
}
|
|
87
|
-
// Standalone prebuilt binary from
|
|
83
|
+
// Standalone prebuilt binary from flisk-sh/releases (installed to e.g. /usr/local/bin),
|
|
88
84
|
// not a node_modules/.bun link and not sitting inside a git checkout.
|
|
89
85
|
if (isStandaloneBinary(realPath)) {
|
|
90
86
|
return { method: "binary", path: realPath };
|
|
@@ -138,8 +134,8 @@ export function detectAllInstallations() {
|
|
|
138
134
|
}
|
|
139
135
|
return [...unique.values()];
|
|
140
136
|
}
|
|
141
|
-
const BINARY_RELEASE_REPO = "flisk-sh/
|
|
142
|
-
const ENGINE_ASSET_NAME = "
|
|
137
|
+
const BINARY_RELEASE_REPO = "flisk-sh/releases";
|
|
138
|
+
const ENGINE_ASSET_NAME = "tdk-cli-engine.tar.gz";
|
|
143
139
|
const CHECKSUMS_ASSET_NAME = "checksums.txt";
|
|
144
140
|
/** Parses `shasum -a 256` / `sha256sum` output ("<hash> <name>" or "<hash> *<name>"). */
|
|
145
141
|
/** @internal Exported for unit tests only; not part of the package API. */
|
|
@@ -361,10 +357,27 @@ export async function getLatestVersion() {
|
|
|
361
357
|
return null;
|
|
362
358
|
}
|
|
363
359
|
}
|
|
360
|
+
/**
|
|
361
|
+
* Removes the package the CLI shipped under before the rename. It owns the old `flisk` command,
|
|
362
|
+
* so npm and bun refuse to install @flisk-sh/flisk next to it (EEXIST) and the upgrade dies
|
|
363
|
+
* before it starts. The removal is best effort: the package is often not installed at all.
|
|
364
|
+
*/
|
|
365
|
+
function removeLegacyInstallation(manager) {
|
|
366
|
+
const command = manager === "npm"
|
|
367
|
+
? "npm uninstall -g @tdk-landscape/tdk-cli-core"
|
|
368
|
+
: "bun remove -g @tdk-landscape/tdk-cli-core";
|
|
369
|
+
try {
|
|
370
|
+
execSync(command, { stdio: ["ignore", "ignore", "ignore"], timeout: 60000 });
|
|
371
|
+
}
|
|
372
|
+
catch {
|
|
373
|
+
// Not installed under the old name, or the manager is missing. Nothing to remove.
|
|
374
|
+
}
|
|
375
|
+
}
|
|
364
376
|
/** @internal Exported for unit tests only; not part of the package API. */
|
|
365
377
|
export async function upgradeViaNpm() {
|
|
366
378
|
const spinner = startSpinner("Upgrading via npm...");
|
|
367
379
|
try {
|
|
380
|
+
removeLegacyInstallation("npm");
|
|
368
381
|
execSync("npm install -g @flisk-sh/flisk@latest", {
|
|
369
382
|
stdio: ["inherit", "inherit", "pipe"],
|
|
370
383
|
timeout: 120000,
|
|
@@ -389,8 +402,8 @@ export async function upgradeViaNpm() {
|
|
|
389
402
|
console.log(chalk.gray("\nFor EACCES or EPERM, fix npm's global prefix or use the binary installer:"));
|
|
390
403
|
console.log(chalk.cyan(" https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally/"));
|
|
391
404
|
console.log(chalk.cyan(isWindows()
|
|
392
|
-
? " irm https://
|
|
393
|
-
: " curl -fsSL https://
|
|
405
|
+
? " irm https://flisk.sh/install.ps1 | iex"
|
|
406
|
+
: " curl -fsSL https://flisk.sh/install.sh | sh"));
|
|
394
407
|
}
|
|
395
408
|
return false;
|
|
396
409
|
}
|
|
@@ -399,6 +412,7 @@ export async function upgradeViaNpm() {
|
|
|
399
412
|
export async function upgradeViaBun() {
|
|
400
413
|
const spinner = startSpinner("Upgrading via bun...");
|
|
401
414
|
try {
|
|
415
|
+
removeLegacyInstallation("bun");
|
|
402
416
|
execFileSync(findOnPath("bun") ?? "bun", ["install", "-g", "@flisk-sh/flisk@latest"], {
|
|
403
417
|
stdio: "inherit",
|
|
404
418
|
timeout: 120000,
|
|
@@ -639,7 +653,7 @@ export function createUpgradeCommand() {
|
|
|
639
653
|
showErrorAndExit("Flisk Windows v1 supports AMD64 only. Use WSL2 Ubuntu or a 64-bit Intel/AMD PC.");
|
|
640
654
|
}
|
|
641
655
|
if (process.platform === "win32") {
|
|
642
|
-
showErrorAndExit("No Windows AMD64 binary in this Flisk release. Need asset
|
|
656
|
+
showErrorAndExit("No Windows AMD64 binary in this Flisk release. Need asset tdk-windows-amd64.exe.");
|
|
643
657
|
}
|
|
644
658
|
showErrorAndExit(`Unsupported OS: Flisk does not support this OS: ${process.platform}. Supported: linux, darwin, win32.`);
|
|
645
659
|
}
|
|
@@ -771,7 +785,7 @@ export function createUpgradeCommand() {
|
|
|
771
785
|
else if (installInfo.method === "binary" && binaryRelease && installInfo.path) {
|
|
772
786
|
const engineDir = join(dirname(installInfo.path), "tdk-cli");
|
|
773
787
|
if (isWindows()) {
|
|
774
|
-
console.log(chalk.cyan(" irm https://
|
|
788
|
+
console.log(chalk.cyan(" irm https://flisk.sh/install.ps1 | iex"));
|
|
775
789
|
}
|
|
776
790
|
else {
|
|
777
791
|
console.log(chalk.cyan(` curl -fsSL -o ${installInfo.path} ${binaryRelease.downloadUrl}`));
|
|
@@ -17,14 +17,14 @@
|
|
|
17
17
|
// template-engine.ts - Verdaccio and Sablier's real gate is the file
|
|
18
18
|
// overlay above (their public files are disabled stubs, not gated code).
|
|
19
19
|
//
|
|
20
|
-
// The worker (
|
|
20
|
+
// The worker (flisk-extension-dist) is the real access-control boundary: it
|
|
21
21
|
// checks the key against BUNDLES_REPO/keys/*.json - existence, activation/
|
|
22
22
|
// expiry dates, granted resources, and a per-key project limit - before
|
|
23
23
|
// serving anything. This client just asks and, if granted, unpacks the
|
|
24
24
|
// result over the vendored stub files so the generator pipeline picks up
|
|
25
25
|
// the real implementations transparently. See
|
|
26
|
-
//
|
|
27
|
-
//
|
|
26
|
+
// flisk-extension-dist/src/index.ts for the server-side enforcement and
|
|
27
|
+
// flisk-extension-dist/src/project-limit.ts for the project-limit logic.
|
|
28
28
|
import { randomUUID } from "node:crypto";
|
|
29
29
|
import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
30
30
|
import { homedir } from "node:os";
|
|
@@ -23,12 +23,12 @@ export function loadTemplate(filename) {
|
|
|
23
23
|
path.join(__dirname, "..", "..", "templates"), // Standard: dist/generator -> templates (also covers src/generator -> ../../templates in dev/test)
|
|
24
24
|
path.join(__dirname, "..", "templates"), // Installed: dist/generator -> dist/templates
|
|
25
25
|
path.join(__dirname, "..", "..", "..", "templates"), // Development: cli/dist/generator -> cli/templates
|
|
26
|
-
path.join(process.cwd(), "node_modules", "flisk", "templates"), // Monorepo root
|
|
26
|
+
path.join(process.cwd(), "node_modules", "@flisk-sh", "flisk", "templates"), // Monorepo root
|
|
27
27
|
// Compiled single-file binary (bun build --compile): __dirname resolves inside the
|
|
28
28
|
// virtual $bunfs filesystem, not a real path, so fall back to the directory the actual
|
|
29
|
-
// executable lives in. release-binaries.sh bundles cli/templates at
|
|
29
|
+
// executable lives in. release-binaries.sh bundles cli/templates at tdk-cli/cli/templates
|
|
30
30
|
// next to the platform binaries.
|
|
31
|
-
path.join(path.dirname(process.execPath), "
|
|
31
|
+
path.join(path.dirname(process.execPath), "tdk-cli", "cli", "templates"),
|
|
32
32
|
];
|
|
33
33
|
const triedPaths = [];
|
|
34
34
|
for (const templateDir of templateDirs) {
|
|
@@ -587,8 +587,8 @@ export function findCliAssetRoot() {
|
|
|
587
587
|
}
|
|
588
588
|
const exeDir = path.dirname(process.execPath);
|
|
589
589
|
const candidates = [
|
|
590
|
-
path.join(exeDir, "
|
|
591
|
-
path.join(process.cwd(), "node_modules", "flisk"),
|
|
590
|
+
path.join(exeDir, "tdk-cli"),
|
|
591
|
+
path.join(process.cwd(), "node_modules", "@flisk-sh", "flisk"),
|
|
592
592
|
];
|
|
593
593
|
return (candidates.find((candidate) => fs.existsSync(path.join(candidate, "shared-platform-engineering", "docker-templates"))) ?? null);
|
|
594
594
|
}
|
|
@@ -624,7 +624,7 @@ async function vendorTdkExtension(projectRoot) {
|
|
|
624
624
|
// 1. $TDK_EXTENSION_SOURCE (explicit override)
|
|
625
625
|
// 2. Self-contained repo (engine/ ships next to cli/ - public flisk)
|
|
626
626
|
// 3. Executable-adjacent checkout (bundled installs)
|
|
627
|
-
// 4. Relative ../
|
|
627
|
+
// 4. Relative ../tdk-cli sibling (monorepo maintainer layout)
|
|
628
628
|
const sources = [];
|
|
629
629
|
if (process.env.TDK_EXTENSION_SOURCE) {
|
|
630
630
|
sources.push(process.env.TDK_EXTENSION_SOURCE);
|
|
@@ -641,8 +641,8 @@ async function vendorTdkExtension(projectRoot) {
|
|
|
641
641
|
// Bun's process object - it was always undefined, silently falling
|
|
642
642
|
// back to cwd() instead of the binary's real location.
|
|
643
643
|
const exeDir = path.dirname(process.execPath);
|
|
644
|
-
sources.push(path.join(exeDir, "
|
|
645
|
-
sources.push(path.join(projectRoot, "..", "
|
|
644
|
+
sources.push(path.join(exeDir, "tdk-cli"));
|
|
645
|
+
sources.push(path.join(projectRoot, "..", "tdk-cli"));
|
|
646
646
|
let sourceRoot = "";
|
|
647
647
|
for (const candidate of sources) {
|
|
648
648
|
if (candidate &&
|
package/cli/dist/mcp/tools.js
CHANGED
|
@@ -79,10 +79,7 @@ export function toToolResult(run) {
|
|
|
79
79
|
return {
|
|
80
80
|
data: {
|
|
81
81
|
errors: [
|
|
82
|
-
{
|
|
83
|
-
code: "NO_JSON",
|
|
84
|
-
message: run.stderr.trim() || `flisk exited with code ${run.exitCode}`,
|
|
85
|
-
},
|
|
82
|
+
{ code: "NO_JSON", message: run.stderr.trim() || `flisk exited with code ${run.exitCode}` },
|
|
86
83
|
],
|
|
87
84
|
},
|
|
88
85
|
isError: true,
|
|
@@ -123,7 +120,7 @@ export const defaultUpDeps = {
|
|
|
123
120
|
},
|
|
124
121
|
sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
|
|
125
122
|
now: () => Date.now(),
|
|
126
|
-
logFile: () => join(tmpdir(), `
|
|
123
|
+
logFile: () => join(tmpdir(), `tdk-mcp-up-${Date.now()}.log`),
|
|
127
124
|
};
|
|
128
125
|
export function buildUpArgs(args) {
|
|
129
126
|
const stack = optionalName(args.stack, "stack");
|
package/cli/dist/program.js
CHANGED
|
@@ -20,6 +20,8 @@ export function createProgram() {
|
|
|
20
20
|
.description("Flisk CLI — start services on your machine.")
|
|
21
21
|
.version(pkg.version, "-v, --version", "Display version number")
|
|
22
22
|
.option("--verbose", "Enable verbose output", false)
|
|
23
|
+
.option("--template <name>", "Create a project from a starter template in one command (restaurant, saas, erp, ecommerce, example)")
|
|
24
|
+
.option("--project <dir>", "Directory to create the project in (default: the template name)")
|
|
23
25
|
.configureOutput({
|
|
24
26
|
outputError: (str, write) => write(chalk.red(str)),
|
|
25
27
|
writeOut: (str) => process.stdout.write(str),
|