flisk-import 0.2.3 → 0.3.0

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 TDK Landscape
3
+ Copyright (c) 2026 Flisk
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,24 +1,61 @@
1
- # tdk import
1
+ # flisk import
2
2
 
3
- Import the services in a repo's root `docker-compose.yml` into [TDK](https://github.com/flisk-sh/flisk) as `service.json` files. This is the Compose first tier of flisk-sh/flisk#511.
3
+ Import the services in a repo's root `docker-compose.yml` into [Flisk](https://github.com/flisk-sh/flisk) as `service.json` files. This is the Compose first tier of flisk-sh/flisk#511.
4
4
 
5
5
  ```bash
6
- tdk import . --dry-run # plan only
7
- tdk import . # plan, then ask before writing
8
- tdk import . --yes # write service.json files and project setup
6
+ flisk import . --dry-run # plan only
7
+ flisk import . # plan, then ask before writing
8
+ flisk import . --yes # write service.json files and project setup
9
9
  ```
10
10
 
11
11
  ## What to expect
12
12
 
13
13
  - **Reads one file:** the root `docker-compose.yml`. Not `compose.yaml`, override files, nested Compose files, Dockerfiles on their own, `package.json`, or Procfiles.
14
- - **Writes:** one bring-your-own `service.json` per Compose service, plus `.tdk/project.json` if the repo is not a TDK project yet. It never edits the Compose file or overwrites a `service.json` without `--force`.
15
- - **Keeps:** the build context and Dockerfile (or the image), the container port, `depends_on`, and an HTTP health path. Databases and brokers are private, with no proxy route.
16
- - **Drops, and says so:** env values, volumes, `command`, `env_file` and every other untranslated key; services with `profiles`, `extends`, an out-of-tree build or a `${VAR}` image.
17
- - **Does not start anything.** Put env values in `.env`, then run `tdk up` with TDK core **1.3.145 or later**. The importer does not check the core version.
14
+ - **Writes:** one bring-your-own `service.json` per Compose service, plus `.flisk/project.json` if the repo is not a Flisk project yet. It never edits the Compose file or overwrites a `service.json` without `--force`.
15
+ - **Keeps:** the service names (`db` stays `db`, so it stays the hostname), the build context and Dockerfile (or the image), the container port as written (3000, 80, 5432), `depends_on`, and an HTTP health path. Databases and brokers are private, with no proxy route.
16
+ - **Environment:** names go into `service.json` as `secrets.required`; literal values are copied to the project `.env`, which is added to `.gitignore`. Values in `.env` already are kept, and `${VAR}` values are left for you.
17
+ - **Drops, and says so:** volumes, `command`, `env_file` and every other untranslated key; services with `profiles`, `extends`, an out-of-tree build or a `${VAR}` image.
18
+ - **Does not start anything.** Run `flisk up` with Flisk core **1.4.11 or later**. The importer does not check the core version.
18
19
  - **Exit codes:** `0` when the plan succeeds (`--dry-run`, files written, or all `service.json` files already exist), `1` when no root `docker-compose.yml` or mappable service is found, and `2` when the write prompt is declined or closed without an answer (`Nothing written.`).
19
20
 
20
- See [docs/import.md](docs/import.md) for the full mapping and limits. `tdk import` is the core CLI command backed by this package.
21
+ See [docs/import.md](docs/import.md) for the full mapping and limits. `flisk import` is the core CLI command backed by this package.
21
22
 
22
23
  ```bash
23
24
  bun install && bun run build && bun run test
24
25
  ```
26
+
27
+ ## Publishing
28
+
29
+ `flisk-import` is published to npmjs.org by the workflow in
30
+ [`.github/workflows/publish-npm.yml`](.github/workflows/publish-npm.yml), triggered by a
31
+ GitHub release. It uses **npm trusted publishing (OIDC)**, so no long-lived npm token
32
+ lives in this repository. The package is published under two names: the unscoped
33
+ `flisk-import` and the scoped `@flisk-sh/flisk-import` (the same archive with the name
34
+ rewritten in the packed manifest).
35
+
36
+ ### One-time owner setup
37
+
38
+ A trusted publisher has to exist on npm before the first OIDC publish succeeds, and it is
39
+ configured per package name:
40
+
41
+ 1. Open the package on npmjs.com → **Settings** → **Trusted Publisher** → **GitHub Actions**
42
+ 2. Fill in:
43
+ - Organization: `flisk-sh`
44
+ - Repository: `flisk-import`
45
+ - Workflow filename: `publish-npm.yml`
46
+ - Allowed actions: `npm publish`
47
+ 3. Repeat for `@flisk-sh/flisk-import` once that package exists
48
+
49
+ The same thing from the command line, for either name:
50
+
51
+ ```bash
52
+ npm trust github flisk-import --file publish-npm.yml --repo flisk-sh/flisk-import --allow-publish
53
+ npm trust list flisk-import
54
+ ```
55
+
56
+ ### The first version
57
+
58
+ A package's first version cannot be published through OIDC — npm has no trusted publisher
59
+ for a name that does not exist yet. Version 0.2.2 was therefore published once with a
60
+ token; every version after that publishes over OIDC from the release workflow.
61
+
package/dist/cli.js CHANGED
@@ -5,9 +5,9 @@ import { createInterface } from "node:readline/promises";
5
5
  import { Command } from "commander";
6
6
  import "./detectors/index.js";
7
7
  import { ImportError } from "./errors.js";
8
+ import { MIN_CORE_VERSION } from "./flisk.js";
8
9
  import { formatPlan } from "./format.js";
9
10
  import { buildPlan } from "./plan.js";
10
- import { MIN_CORE_VERSION } from "./tdk.js";
11
11
  import { applyWrites, manifestRelPath, planWrites } from "./write.js";
12
12
  async function confirm(message) {
13
13
  const rl = createInterface({ input: process.stdin, output: process.stdout });
@@ -46,7 +46,7 @@ const program = new Command("flisk-import")
46
46
  return void console.log("Nothing to write: every service.json already exists.");
47
47
  }
48
48
  if (!options.yes &&
49
- !(await confirm(`Write ${pending.length} service.json file(s)${writes.projectConfig ? " and create .tdk/project.json" : ""}?`))) {
49
+ !(await confirm(`Write ${pending.length} service.json file(s)${writes.projectConfig ? " and create .flisk/project.json" : ""}?`))) {
50
50
  console.log("Nothing written.");
51
51
  process.exitCode = 2;
52
52
  return;
@@ -55,11 +55,14 @@ const program = new Command("flisk-import")
55
55
  for (const item of written) {
56
56
  console.log(` wrote ${relative(process.cwd(), item.path) || manifestRelPath(plan, item)}`);
57
57
  }
58
- console.log(`\nWrote ${written.length} service.json file(s)${writes.projectConfig ? " and created .tdk/project.json" : ""}.`);
58
+ console.log(`\nWrote ${written.length} service.json file(s)${writes.projectConfig ? " and created .flisk/project.json" : ""}.`);
59
59
  const envFile = relative(process.cwd(), join(writes.projectRoot, ".env")) || ".env";
60
60
  console.log("\nNext:");
61
- if (plan.services.some((s) => s.envKeys.length))
62
- console.log(` - Put the environment values these services need in ${envFile}; values in docker-compose.yml were not copied.`);
61
+ const copied = Object.keys(writes.env.add);
62
+ if (copied.length)
63
+ console.log(` - Copied ${copied.length} environment value(s) from docker-compose.yml to ${envFile} (gitignored).`);
64
+ if (writes.items.some((item) => item.notes.some((note) => note.startsWith("no literal value"))))
65
+ console.log(` - Add the values listed above as missing to ${envFile}.`);
63
66
  console.log(` - Run \`flisk up\` with Flisk core ${MIN_CORE_VERSION} or later. The import did not start anything.`);
64
67
  });
65
68
  try {
@@ -1,8 +1,8 @@
1
1
  import { readFileSync } from "node:fs";
2
2
  import { dirname, isAbsolute, join, normalize } from "node:path/posix";
3
3
  import { isAlias, isMap, parseDocument, visit } from "yaml";
4
+ import { HEALTH_CHECK_PATH_PATTERN } from "../flisk.js";
4
5
  import { registerDetector } from "../registry.js";
5
- import { HEALTH_CHECK_PATH_PATTERN } from "../tdk.js";
6
6
  const isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
7
7
  /** Container-side port of one `ports:` entry, in short or long syntax. */
8
8
  function containerPort(entry) {
@@ -41,6 +41,26 @@ function envNames(environment) {
41
41
  }
42
42
  return isObj(environment) ? Object.keys(environment) : [];
43
43
  }
44
+ /** Literal environment values; interpolated ones (`${VAR}`) and empty entries are left for the user. */
45
+ function envValues(environment) {
46
+ const pairs = Array.isArray(environment)
47
+ ? environment
48
+ .filter((e) => typeof e === "string" && e.includes("="))
49
+ .map((e) => [e.slice(0, e.indexOf("=")), e.slice(e.indexOf("=") + 1)])
50
+ : isObj(environment)
51
+ ? Object.entries(environment)
52
+ : [];
53
+ const out = {};
54
+ for (const [key, raw] of pairs) {
55
+ if (raw === null || raw === undefined || typeof raw === "object")
56
+ continue;
57
+ const value = String(raw);
58
+ if (value.includes("${") || value.includes("\n"))
59
+ continue;
60
+ out[key] = value;
61
+ }
62
+ return out;
63
+ }
44
64
  function commandOf(command) {
45
65
  if (typeof command === "string")
46
66
  return command;
@@ -176,6 +196,7 @@ registerDetector({
176
196
  : [];
177
197
  const command = commandOf(raw.command);
178
198
  const envKeys = envNames(raw.environment);
199
+ const env = envValues(raw.environment);
179
200
  const foundHealthPath = healthPathOf(raw.healthcheck);
180
201
  const healthCheckPath = foundHealthPath && HEALTH_CHECK_PATH_PATTERN.test(foundHealthPath)
181
202
  ? foundHealthPath
@@ -208,6 +229,7 @@ registerDetector({
208
229
  ...(healthCheckPath ? { healthCheckPath } : {}),
209
230
  exposeViaProxy,
210
231
  ...(envKeys.length ? { envKeys } : {}),
232
+ ...(Object.keys(env).length ? { env } : {}),
211
233
  ...(dependsOn.length ? { dependsOn } : {}),
212
234
  confidence: "high",
213
235
  sources: [base],
@@ -4,11 +4,12 @@ import { dirname, join, resolve } from "node:path";
4
4
  export const SERVICE_MANIFEST_SCHEMA_VERSION = 1;
5
5
  export const SERVICE_MANIFEST_SCHEMA_URL = "https://flisk.sh/schema.service.json";
6
6
  /**
7
- * Oldest Flisk core that starts an imported project: 1.3.104 added `buildContext`, and 1.3.145
8
- * (flisk#1018) bootstraps a project that has `.tdk/project.json` but no Tiltfile yet.
9
- * Stated, not checked: the importer does not read the installed core version.
7
+ * Oldest Flisk core that starts an imported project: 1.3.104 added `buildContext`, 1.3.145
8
+ * (flisk#1018) bootstraps a project that has `.flisk/project.json` but no Tiltfile yet, and the
9
+ * release after 1.4.10 (flisk#2646) accepts a bring-your-own port outside 4000-5999 and two-letter
10
+ * names, which this importer now writes. Stated, not checked: it does not read the installed version.
10
11
  */
11
- export const MIN_CORE_VERSION = "1.3.145";
12
+ export const MIN_CORE_VERSION = "1.4.11";
12
13
  /** Flisk's bring-your-own port range. */
13
14
  export const BYO_PORT_RANGE = { min: 4000, max: 5999, label: "4000-5999" };
14
15
  /**
@@ -26,11 +27,11 @@ export function validateName(label, name) {
26
27
  error: `${label} "${name}" must use lowercase letters, numbers, and hyphens only`,
27
28
  };
28
29
  }
29
- /** Nearest directory at or above `start` holding `.tdk/project.json`. */
30
+ /** Nearest directory at or above `start` holding `.flisk/project.json`. */
30
31
  export function findProjectRoot(start) {
31
32
  let dir = resolve(start);
32
33
  while (true) {
33
- if (existsSync(join(dir, ".tdk", "project.json")))
34
+ if (existsSync(join(dir, ".flisk", "project.json")))
34
35
  return dir;
35
36
  const parent = dirname(dir);
36
37
  if (parent === dir)
package/dist/format.js CHANGED
@@ -10,7 +10,7 @@ export function formatPlan(plan, writes) {
10
10
  const jobs = plan.services.filter((s) => s.kind === "job").length;
11
11
  out.push(`Found ${plan.services.length - jobs} service(s) and ${jobs} job(s) in ${plan.root}`, `Read only: ${plan.files.join(", ")}. Lines below name what was not translated.`, "");
12
12
  if (writes.projectConfig)
13
- out.push(` .tdk/project.json [create Flisk project]`, "");
13
+ out.push(` .flisk/project.json [create Flisk project]`, "");
14
14
  for (const service of plan.services) {
15
15
  const item = writes.items.find((i) => i.service === service);
16
16
  out.push(` ${service.name} (${service.kind}${service.dir ? `, ${service.dir}/` : ""})`);
package/dist/merge.js CHANGED
@@ -8,10 +8,11 @@ function slug(raw) {
8
8
  }
9
9
  export function toResourceName(raw) {
10
10
  let name = slug(raw) || "svc";
11
- // Resource names must start with a letter and be at least 3 characters (service schema).
11
+ // Resource names must start with a letter and be at least 2 characters (service schema), so a
12
+ // Compose name such as `db` is kept and stays the container's hostname.
12
13
  if (!/^[a-z]/.test(name))
13
14
  name = `svc-${name}`;
14
- if (name.length < 3)
15
+ if (name.length < 2)
15
16
  name = `${name}-svc`;
16
17
  return name;
17
18
  }
@@ -57,6 +58,7 @@ function mergeGroup(name, dir, members, resolve) {
57
58
  dir,
58
59
  kind: ordered[0].kind,
59
60
  envKeys: [...new Set(ordered.flatMap((c) => c.envKeys ?? []))].sort(),
61
+ env: Object.assign({}, ...[...ordered].reverse().map((c) => c.env ?? {})),
60
62
  dependsOn: [...new Set(ordered.flatMap((c) => (c.dependsOn ?? []).map(resolve)))].sort(),
61
63
  exposeViaProxy: ordered.find((c) => c.exposeViaProxy !== undefined)?.exposeViaProxy,
62
64
  procfileCommands: ordered.flatMap((c) => c.sources.some((source) => source.detector === "procfile") && c.command ? [c.command] : []),
package/dist/scan.js CHANGED
@@ -8,7 +8,7 @@ export const HARD_SKIPS = new Set([
8
8
  "dist",
9
9
  ".autogenerated",
10
10
  // Output of `flisk project`: never a source of services.
11
- ".tdk",
11
+ ".flisk",
12
12
  "shared-platform-engineering",
13
13
  ]);
14
14
  export const MAX_DEPTH = 8;
@@ -84,8 +84,8 @@ export function scanTree(root, limits = { depth: MAX_DEPTH, files: MAX_FILES })
84
84
  let depthCapped = false;
85
85
  let fileCapped = false;
86
86
  // In a Flisk project, `services/` holds manifests and generated compose files, not sources.
87
- const isTdkProject = existsSync(join(root, ".tdk", "project.json"));
88
- if (isTdkProject)
87
+ const isFliskProject = existsSync(join(root, ".flisk", "project.json"));
88
+ if (isFliskProject)
89
89
  notes.push("Flisk project detected: services/ was not scanned");
90
90
  const walk = (rel, depth, inherited) => {
91
91
  const abs = join(root, rel);
@@ -106,7 +106,7 @@ export function scanTree(root, limits = { depth: MAX_DEPTH, files: MAX_FILES })
106
106
  if (entry.isDirectory()) {
107
107
  if (HARD_SKIPS.has(entry.name) || isIgnored(rules, entryRel, entry.name, true))
108
108
  continue;
109
- if (isTdkProject && entryRel === "services")
109
+ if (isFliskProject && entryRel === "services")
110
110
  continue;
111
111
  if (depth >= limits.depth) {
112
112
  depthCapped = true;
package/dist/write.js CHANGED
@@ -1,9 +1,25 @@
1
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
2
  import { basename, dirname, join, relative, resolve } from "node:path";
3
3
  import { ImportError } from "./errors.js";
4
+ import { BYO_PORT_RANGE, findProjectRoot, IMAGE_PATTERN, SERVICE_MANIFEST_SCHEMA_URL, SERVICE_MANIFEST_SCHEMA_VERSION, validateName, } from "./flisk.js";
4
5
  import { toResourceName } from "./merge.js";
5
6
  import { usedManifestPorts } from "./plan.js";
6
- import { BYO_PORT_RANGE, findProjectRoot, IMAGE_PATTERN, SERVICE_MANIFEST_SCHEMA_URL, SERVICE_MANIFEST_SCHEMA_VERSION, validateName, } from "./tdk.js";
7
+ /** Secret names the service schema accepts (`secrets.required`). */
8
+ const ENV_NAME = /^[A-Z_][A-Z0-9_]*$/;
9
+ function readEnvKeys(path) {
10
+ if (!existsSync(path))
11
+ return new Set();
12
+ return new Set(readFileSync(path, "utf8")
13
+ .split(/\r?\n/)
14
+ .map((line) => line.match(/^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/)?.[1])
15
+ .filter((key) => key !== undefined));
16
+ }
17
+ /** A .env value, quoted when it holds characters a dotenv parser would split or strip. */
18
+ function envLine(key, value) {
19
+ return /^[A-Za-z0-9_./:@+-]*$/.test(value)
20
+ ? `${key}=${value}`
21
+ : `${key}=${JSON.stringify(value)}`;
22
+ }
7
23
  function existingPort(path) {
8
24
  try {
9
25
  const port = JSON.parse(readFileSync(path, "utf8")).port;
@@ -29,7 +45,7 @@ export function planWrites(plan, force) {
29
45
  ]);
30
46
  }
31
47
  const servicesDir = join(projectRoot, "services");
32
- const projectConfigPath = join(projectRoot, ".tdk", "project.json");
48
+ const projectConfigPath = join(projectRoot, ".flisk", "project.json");
33
49
  const projectConfig = existsSync(projectConfigPath)
34
50
  ? undefined
35
51
  : {
@@ -58,6 +74,9 @@ export function planWrites(plan, force) {
58
74
  overrides: {},
59
75
  }, null, 2)}\n`,
60
76
  };
77
+ const envPath = join(projectRoot, ".env");
78
+ const envKept = readEnvKeys(envPath);
79
+ const envAdd = {};
61
80
  const used = usedManifestPorts(servicesDir);
62
81
  const items = [];
63
82
  const rejected = [];
@@ -97,8 +116,9 @@ export function planWrites(plan, force) {
97
116
  // Never written, so no port is needed; keep the one on disk for the plan.
98
117
  port = existingPort(path) ?? BYO_PORT_RANGE.min;
99
118
  }
100
- else if (service.port !== undefined && free(service.port)) {
101
- // The schema accepts this port for bring-your-own and no other service in the project uses it.
119
+ else if (service.port !== undefined) {
120
+ // A bring-your-own port is the port inside its own container (Traefik reaches it on the stack
121
+ // network; nothing is published on the host), so the Compose port is kept as written.
102
122
  port = service.port;
103
123
  }
104
124
  else if (keep !== undefined && free(keep)) {
@@ -112,11 +132,8 @@ export function planWrites(plan, force) {
112
132
  }
113
133
  }
114
134
  }
115
- if (status !== "exists" &&
116
- service.port !== undefined &&
117
- port !== undefined &&
118
- port !== service.port)
119
- notes.push(`Compose port ${service.port} is outside ${BYO_PORT_RANGE.label} or already used; assigned ${port}. The container must listen on $PORT (${port}) or it will not answer`);
135
+ if (status !== "exists" && service.port === undefined && !isPrivate && port !== undefined)
136
+ notes.push(`port ${port} assigned: Compose gives no single container port; the container must listen on $PORT (${port})`);
120
137
  if (port === undefined) {
121
138
  rejected.push({ name: service.name, reason: `no free port in ${BYO_PORT_RANGE.label}` });
122
139
  continue;
@@ -135,8 +152,23 @@ export function planWrites(plan, force) {
135
152
  notes.push("no health path: the service does not serve HTTP (non-HTTP image or job)");
136
153
  if (!isPrivate && !nonHttp && !service.healthCheckPath)
137
154
  notes.push("health path / is assumed: no HTTP health path could be read from Compose. Traefik routes only while it answers 2xx or 3xx");
138
- if (service.envKeys.length)
139
- notes.push("environment values are not written; put them in the project .env");
155
+ // Names go into service.json as secrets, so Flisk injects them; values go to the gitignored project .env.
156
+ const secretNames = service.envKeys.filter((key) => ENV_NAME.test(key));
157
+ const skippedNames = service.envKeys.filter((key) => !ENV_NAME.test(key));
158
+ if (skippedNames.length)
159
+ notes.push(`environment names not written (Flisk accepts A-Z, 0-9 and _): ${skippedNames.join(", ")}`);
160
+ const missing = [];
161
+ for (const key of secretNames) {
162
+ const value = service.env[key];
163
+ if (envKept.has(key) || key in envAdd)
164
+ continue;
165
+ if (value === undefined)
166
+ missing.push(key);
167
+ else
168
+ envAdd[key] = value;
169
+ }
170
+ if (missing.length)
171
+ notes.push(`no literal value in docker-compose.yml for ${missing.join(", ")}; add it to the project .env`);
140
172
  if (service.dockerfile && service.image)
141
173
  notes.push(`image "${service.image}" is not written: with build and image, Flisk builds from ${service.dockerfile} and does not pull the tag`);
142
174
  // With both build and image, Compose builds the Dockerfile and tags the result as `image`.
@@ -158,10 +190,18 @@ export function planWrites(plan, force) {
158
190
  ...source,
159
191
  ...(isPrivate ? { exposeViaProxy: false } : {}),
160
192
  ...(dependsOn.length ? { dependsOn } : {}),
193
+ ...(secretNames.length ? { secrets: { required: secretNames } } : {}),
161
194
  };
162
195
  items.push({ service, path, manifest, status, notes });
163
196
  }
164
- return { projectRoot, stack, items, projectConfig, rejected };
197
+ return {
198
+ projectRoot,
199
+ stack,
200
+ items,
201
+ projectConfig,
202
+ rejected,
203
+ env: { path: envPath, add: envAdd },
204
+ };
165
205
  }
166
206
  export function applyWrites(writes) {
167
207
  const written = [];
@@ -176,8 +216,24 @@ export function applyWrites(writes) {
176
216
  writeFileSync(item.path, `${JSON.stringify(item.manifest, null, 2)}\n`);
177
217
  written.push(item);
178
218
  }
219
+ const keys = Object.keys(writes.env.add);
220
+ if (keys.length) {
221
+ const existing = existsSync(writes.env.path) ? readFileSync(writes.env.path, "utf8") : "";
222
+ const lines = keys.map((key) => envLine(key, writes.env.add[key]));
223
+ const block = `${existing && !existing.endsWith("\n") ? "\n" : ""}# From docker-compose.yml (flisk import)\n${lines.join("\n")}\n`;
224
+ writeFileSync(writes.env.path, existing + block);
225
+ ensureGitignored(writes.projectRoot, ".env");
226
+ }
179
227
  return written;
180
228
  }
181
229
  export function manifestRelPath(plan, item) {
182
230
  return relative(plan.root, item.path).split("\\").join("/");
183
231
  }
232
+ /** Keeps the project .env out of git: it now holds values copied from docker-compose.yml. */
233
+ function ensureGitignored(projectRoot, entry) {
234
+ const path = join(projectRoot, ".gitignore");
235
+ const content = existsSync(path) ? readFileSync(path, "utf8") : "";
236
+ if (content.split(/\r?\n/).some((line) => line.trim() === entry || line.trim() === `/${entry}`))
237
+ return;
238
+ writeFileSync(path, `${content}${content && !content.endsWith("\n") ? "\n" : ""}${entry}\n`);
239
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "flisk-import",
3
- "version": "0.2.3",
4
- "description": "Import services from a repository's root docker-compose.yml into TDK service.json files.",
3
+ "version": "0.3.0",
4
+ "description": "Import services from a repository's root docker-compose.yml into Flisk service.json files.",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "bin": {