@getmonoceros/workbench 1.30.0 → 1.31.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/bundled-components/languages/dotnet/component.yml +5 -0
- package/bundled-components/languages/go/component.yml +1 -0
- package/bundled-components/languages/java/component.yml +1 -0
- package/bundled-components/languages/python/component.yml +3 -0
- package/bundled-components/languages/rust/component.yml +1 -0
- package/bundled-components/services/keycloak/component.yml +46 -0
- package/dist/bin.js +493 -69
- package/dist/bin.js.map +1 -1
- package/package.json +2 -1
package/dist/bin.js
CHANGED
|
@@ -727,11 +727,28 @@ var init_descriptor = __esm({
|
|
|
727
727
|
* Coerced to string so authors can write bare YAML numbers
|
|
728
728
|
* (`versions: [latest, 21, 17]`) without quoting.
|
|
729
729
|
*/
|
|
730
|
-
versions: z2.array(z2.coerce.string()).optional()
|
|
730
|
+
versions: z2.array(z2.coerce.string()).optional(),
|
|
731
|
+
/**
|
|
732
|
+
* VS Code extensions to *recommend* (not auto-install) when this language
|
|
733
|
+
* is present, written to the `.code-workspace` `extensions.recommendations`
|
|
734
|
+
* (ADR 0016). List every editor variant where editors diverge: VS Code and
|
|
735
|
+
* VSCodium each resolve recommendation IDs against their own registry (MS
|
|
736
|
+
* Marketplace / Open VSX) and silently skip what they can't find, so an
|
|
737
|
+
* ID that only exists for one editor is simply ignored by the other. E.g.
|
|
738
|
+
* `[ms-python.python, ms-python.vscode-pylance]` — Codium drops Pylance.
|
|
739
|
+
*/
|
|
740
|
+
vscodeExtensions: z2.array(z2.string()).optional()
|
|
731
741
|
});
|
|
732
742
|
ServiceBlockSchema = z2.object({
|
|
733
743
|
image: z2.string().min(1),
|
|
734
744
|
defaultPort: z2.number().int().positive().optional(),
|
|
745
|
+
/**
|
|
746
|
+
* Compose `command:` for the service container — the process to run
|
|
747
|
+
* instead of the image's default CMD. Baked into the expanded yml
|
|
748
|
+
* (visible + editable, unlike `deferStart`). E.g. Keycloak needs
|
|
749
|
+
* `start-dev --import-realm` because its image has no auto-start default.
|
|
750
|
+
*/
|
|
751
|
+
command: z2.string().optional(),
|
|
735
752
|
dataMount: z2.string().optional(),
|
|
736
753
|
/**
|
|
737
754
|
* Compose `user:` for the service container (e.g. `"0:0"`). Needed for
|
|
@@ -769,7 +786,32 @@ var init_descriptor = __esm({
|
|
|
769
786
|
apt: z2.array(z2.string()).optional(),
|
|
770
787
|
npm: z2.array(z2.string()).optional()
|
|
771
788
|
}).optional(),
|
|
772
|
-
vscodeExtensions: z2.array(z2.string()).optional()
|
|
789
|
+
vscodeExtensions: z2.array(z2.string()).optional(),
|
|
790
|
+
/**
|
|
791
|
+
* Example bind-mounts rendered as a COMMENTED `volumes:` scaffold in the
|
|
792
|
+
* generated yml (init / add-service), for the builder to uncomment and
|
|
793
|
+
* edit. NOT active volumes — the catalog can't know the builder's repo
|
|
794
|
+
* path. Used by services that need a project file but can't auto-wire it
|
|
795
|
+
* (e.g. Keycloak's realm.json / theme). Each entry is a compose volume
|
|
796
|
+
* spec, e.g. `projects/<app>/keycloak/realm.json:/opt/keycloak/data/import/<app>.json:ro`.
|
|
797
|
+
*/
|
|
798
|
+
exampleVolumes: z2.array(z2.string()).optional(),
|
|
799
|
+
/**
|
|
800
|
+
* Start this service in a SECOND WAVE, host-side, *after* `devcontainer
|
|
801
|
+
* up` (and thus the in-container repo clone in post-create) has
|
|
802
|
+
* finished — instead of together with the workspace at `compose up`.
|
|
803
|
+
* For a service that bind-mounts a file from a cloned repo (e.g.
|
|
804
|
+
* Keycloak's `realm.json`, a Postgres `init.sql`): the file does not
|
|
805
|
+
* exist at the normal parallel start, but is on disk by the time the
|
|
806
|
+
* second wave runs. See ADR 0025.
|
|
807
|
+
*
|
|
808
|
+
* Deliberately a HIDDEN, descriptor-only field: it is NOT exposed in the
|
|
809
|
+
* user-facing yml schema and not baked into the expanded service object.
|
|
810
|
+
* The start paths resolve it by catalog lookup on the service name
|
|
811
|
+
* (`serviceDefersStart`). Caveat: a deferred service is NOT reachable
|
|
812
|
+
* during the workspace's post-create.
|
|
813
|
+
*/
|
|
814
|
+
deferStart: z2.boolean().optional()
|
|
773
815
|
});
|
|
774
816
|
PersistentHomeFileSchema = z2.object({
|
|
775
817
|
path: z2.string().min(1),
|
|
@@ -2219,6 +2261,12 @@ function knownLanguages() {
|
|
|
2219
2261
|
function knownServices() {
|
|
2220
2262
|
return Object.keys(SERVICE_CATALOG).sort();
|
|
2221
2263
|
}
|
|
2264
|
+
function serviceDefersStart(name) {
|
|
2265
|
+
return SERVICE_CATALOG[name]?.deferStart === true;
|
|
2266
|
+
}
|
|
2267
|
+
function curatedServiceExampleVolumes(name) {
|
|
2268
|
+
return SERVICE_CATALOG[name]?.exampleVolumes ?? [];
|
|
2269
|
+
}
|
|
2222
2270
|
function resolveService(entry2) {
|
|
2223
2271
|
return {
|
|
2224
2272
|
name: entry2.name,
|
|
@@ -2254,6 +2302,7 @@ function expandCuratedService(name) {
|
|
|
2254
2302
|
} : {},
|
|
2255
2303
|
...def.dataMount ? { volumes: [`data:${def.dataMount}`] } : {},
|
|
2256
2304
|
...def.user ? { user: def.user } : {},
|
|
2305
|
+
...def.command ? { command: def.command } : {},
|
|
2257
2306
|
...def.healthcheck ? { healthcheck: def.healthcheck } : {},
|
|
2258
2307
|
// Bake the connection-env templates into the yml (suffix → template) so
|
|
2259
2308
|
// they travel with the service: a renamed/duplicated instance keeps them,
|
|
@@ -2308,7 +2357,7 @@ function deriveServiceName(image) {
|
|
|
2308
2357
|
const noTag = lastSegment.split("@")[0].split(":")[0];
|
|
2309
2358
|
return noTag.toLowerCase().replace(/[^a-z0-9_-]/g, "-");
|
|
2310
2359
|
}
|
|
2311
|
-
var DEFAULT_BASE_IMAGE, override, BASE_IMAGE, RUNTIME_IMAGE_REPO, DEFAULT_RUNTIME_VERSION, MIN_RUNTIME_FOR_SSH_ATTACH, DESCRIPTORS, BUILTIN_LANGUAGES, LANGUAGE_CATALOG, LANGUAGE_SPEC_RE, SERVICE_CATALOG;
|
|
2360
|
+
var DEFAULT_BASE_IMAGE, override, BASE_IMAGE, RUNTIME_IMAGE_REPO, DEFAULT_RUNTIME_VERSION, MIN_RUNTIME_FOR_SSH_ATTACH, DESCRIPTORS, BUILTIN_LANGUAGES, LANGUAGE_CATALOG, LANGUAGE_SPEC_RE, SERVICE_CATALOG, DEFERRED_SERVICE_PROFILE;
|
|
2312
2361
|
var init_catalog = __esm({
|
|
2313
2362
|
"src/create/catalog.ts"() {
|
|
2314
2363
|
"use strict";
|
|
@@ -2338,7 +2387,8 @@ var init_catalog = __esm({
|
|
|
2338
2387
|
feature: c.descriptor.language.feature,
|
|
2339
2388
|
...Object.keys(defaults).length > 0 ? { defaultOptions: defaults } : {},
|
|
2340
2389
|
...Object.keys(ymlOptions).length > 0 ? { ymlOptions } : {},
|
|
2341
|
-
...c.descriptor.language.defaultVersion !== void 0 ? { defaultVersion: c.descriptor.language.defaultVersion } : {}
|
|
2390
|
+
...c.descriptor.language.defaultVersion !== void 0 ? { defaultVersion: c.descriptor.language.defaultVersion } : {},
|
|
2391
|
+
...c.descriptor.language.vscodeExtensions ? { vscodeExtensions: c.descriptor.language.vscodeExtensions } : {}
|
|
2342
2392
|
};
|
|
2343
2393
|
return [key, entry2];
|
|
2344
2394
|
})
|
|
@@ -2364,11 +2414,15 @@ var init_catalog = __esm({
|
|
|
2364
2414
|
defaultPort: svc.defaultPort,
|
|
2365
2415
|
...svc.vscodeExtensions ? { vscodeExtensions: svc.vscodeExtensions } : {},
|
|
2366
2416
|
...svc.connectionEnv ? { connectionEnv: svc.connectionEnv } : {},
|
|
2367
|
-
...svc.client ? { client: svc.client } : {}
|
|
2417
|
+
...svc.client ? { client: svc.client } : {},
|
|
2418
|
+
...svc.command ? { command: svc.command } : {},
|
|
2419
|
+
...svc.exampleVolumes ? { exampleVolumes: svc.exampleVolumes } : {},
|
|
2420
|
+
...svc.deferStart ? { deferStart: true } : {}
|
|
2368
2421
|
};
|
|
2369
2422
|
return [key, entry2];
|
|
2370
2423
|
})
|
|
2371
2424
|
);
|
|
2425
|
+
DEFERRED_SERVICE_PROFILE = "monoceros-deferred";
|
|
2372
2426
|
}
|
|
2373
2427
|
});
|
|
2374
2428
|
|
|
@@ -2428,6 +2482,13 @@ function renderCustomService(name, image) {
|
|
|
2428
2482
|
].join("\n");
|
|
2429
2483
|
return { bodyLines, comment };
|
|
2430
2484
|
}
|
|
2485
|
+
function exampleVolumesComment(exampleVolumes) {
|
|
2486
|
+
if (exampleVolumes.length === 0) return void 0;
|
|
2487
|
+
return [
|
|
2488
|
+
" volumes: # uncomment + edit to mount your realm/theme",
|
|
2489
|
+
...exampleVolumes.map((v) => ` - ${v}`)
|
|
2490
|
+
].join("\n");
|
|
2491
|
+
}
|
|
2431
2492
|
function customServiceHint(name) {
|
|
2432
2493
|
return `'${name}' is a custom image \u2014 Monoceros doesn't know its env, ports or volumes. Review the commented block under services[].${name} in the yml and fill in what the image needs.`;
|
|
2433
2494
|
}
|
|
@@ -3109,11 +3170,12 @@ function buildDevcontainerJson(opts, dockerMode = "rootful") {
|
|
|
3109
3170
|
const workspaceEnv = featureWorkspaceEnv(resolvedFeatures);
|
|
3110
3171
|
const containerEnvField = Object.keys(workspaceEnv).length > 0 ? { containerEnv: workspaceEnv } : void 0;
|
|
3111
3172
|
if (needsCompose(opts)) {
|
|
3173
|
+
const eagerServices = opts.services.filter((s) => !serviceDefersStart(s.name)).map((s) => s.name);
|
|
3112
3174
|
return {
|
|
3113
3175
|
name: opts.name,
|
|
3114
3176
|
dockerComposeFile: "compose.yaml",
|
|
3115
3177
|
service: "workspace",
|
|
3116
|
-
...
|
|
3178
|
+
...eagerServices.length > 0 ? { runServices: eagerServices } : {},
|
|
3117
3179
|
workspaceFolder: `/workspaces/${opts.name}`,
|
|
3118
3180
|
remoteUser: "node",
|
|
3119
3181
|
forwardPorts: ports,
|
|
@@ -3212,6 +3274,10 @@ function buildComposeYaml(opts, dockerMode = "rootful") {
|
|
|
3212
3274
|
for (const svc of opts.services) {
|
|
3213
3275
|
lines.push(` ${svc.name}:`);
|
|
3214
3276
|
lines.push(` image: ${svc.image}`);
|
|
3277
|
+
if (serviceDefersStart(svc.name)) {
|
|
3278
|
+
lines.push(" profiles:");
|
|
3279
|
+
lines.push(` - ${DEFERRED_SERVICE_PROFILE}`);
|
|
3280
|
+
}
|
|
3215
3281
|
if (svc.user !== void 0) {
|
|
3216
3282
|
lines.push(` user: ${composeScalar(svc.user)}`);
|
|
3217
3283
|
}
|
|
@@ -3273,9 +3339,22 @@ function extractRepoHost(url) {
|
|
|
3273
3339
|
}
|
|
3274
3340
|
function computeExtensionRecommendations(opts) {
|
|
3275
3341
|
const recs = /* @__PURE__ */ new Set();
|
|
3342
|
+
for (const langSpec of opts.languages) {
|
|
3343
|
+
const parsed = parseLanguageSpec(langSpec);
|
|
3344
|
+
if (!parsed) continue;
|
|
3345
|
+
for (const ext of LANGUAGE_CATALOG[parsed.name]?.vscodeExtensions ?? []) {
|
|
3346
|
+
recs.add(ext);
|
|
3347
|
+
}
|
|
3348
|
+
}
|
|
3276
3349
|
for (const svc of opts.services) {
|
|
3277
|
-
const
|
|
3278
|
-
|
|
3350
|
+
for (const ext of SERVICE_CATALOG[svc.name]?.vscodeExtensions ?? []) {
|
|
3351
|
+
recs.add(ext);
|
|
3352
|
+
}
|
|
3353
|
+
}
|
|
3354
|
+
for (const rawRef of Object.keys(opts.features ?? {})) {
|
|
3355
|
+
const match = matchMonocerosFeature(rawRef);
|
|
3356
|
+
const descriptor = match ? featureDescriptor(match.name) : void 0;
|
|
3357
|
+
for (const ext of descriptor?.feature?.vscodeExtensions ?? []) {
|
|
3279
3358
|
recs.add(ext);
|
|
3280
3359
|
}
|
|
3281
3360
|
}
|
|
@@ -4130,7 +4209,7 @@ async function runAddService(input) {
|
|
|
4130
4209
|
const image = curated ? expandCuratedService(arg).image : arg;
|
|
4131
4210
|
const custom = curated ? null : renderCustomService(name, arg);
|
|
4132
4211
|
const bodyLines = curated ? renderServiceObjectBody({ ...expandCuratedService(arg), name }) : custom.bodyLines;
|
|
4133
|
-
const scaffoldComment = curated ?
|
|
4212
|
+
const scaffoldComment = curated ? exampleVolumesComment(curatedServiceExampleVolumes(arg)) : custom.comment;
|
|
4134
4213
|
const result = await mutate(input, (doc) => {
|
|
4135
4214
|
const r = addServiceEntryToDoc(
|
|
4136
4215
|
doc,
|
|
@@ -6738,6 +6817,25 @@ import { existsSync as existsSync9 } from "fs";
|
|
|
6738
6817
|
import path17 from "path";
|
|
6739
6818
|
import { Writable as Writable3 } from "stream";
|
|
6740
6819
|
import { consola as consola10 } from "consola";
|
|
6820
|
+
function spawnDockerComposeTo(opts) {
|
|
6821
|
+
return (args, cwd) => new Promise((resolve, reject) => {
|
|
6822
|
+
const child = spawn6("docker", ["compose", ...args], {
|
|
6823
|
+
cwd,
|
|
6824
|
+
stdio: ["inherit", "pipe", "pipe"]
|
|
6825
|
+
});
|
|
6826
|
+
const route = (src, screen) => {
|
|
6827
|
+
if (!src) return;
|
|
6828
|
+
src.pipe(createSecretMaskStream()).on("data", (chunk) => {
|
|
6829
|
+
opts.logSink?.write(chunk);
|
|
6830
|
+
if (!opts.silent) screen.write(chunk);
|
|
6831
|
+
});
|
|
6832
|
+
};
|
|
6833
|
+
route(child.stdout, process.stdout);
|
|
6834
|
+
route(child.stderr, process.stderr);
|
|
6835
|
+
child.on("error", reject);
|
|
6836
|
+
child.on("exit", (code) => resolve(code ?? 0));
|
|
6837
|
+
});
|
|
6838
|
+
}
|
|
6741
6839
|
async function findContainerIds(filters, exec = spawnDocker) {
|
|
6742
6840
|
const ids = /* @__PURE__ */ new Set();
|
|
6743
6841
|
for (const filter of filters) {
|
|
@@ -6813,6 +6911,32 @@ async function runComposeAction(buildSubArgs, opts) {
|
|
|
6813
6911
|
const subArgs = buildSubArgs(opts.service);
|
|
6814
6912
|
return spawnFn(["-f", composeFile, "-p", projectName, ...subArgs], opts.root);
|
|
6815
6913
|
}
|
|
6914
|
+
async function startDeferredServices(opts) {
|
|
6915
|
+
if (opts.services.length === 0) return 0;
|
|
6916
|
+
const { composeFile, projectName } = resolveCompose(opts.root);
|
|
6917
|
+
const spawnFn = opts.spawn ?? spawnDockerComposeTo({
|
|
6918
|
+
...opts.logSink ? { logSink: opts.logSink } : {},
|
|
6919
|
+
...opts.silent ? { silent: true } : {}
|
|
6920
|
+
});
|
|
6921
|
+
opts.logger?.info(
|
|
6922
|
+
`Starting deferred service(s): ${opts.services.join(", ")}\u2026`
|
|
6923
|
+
);
|
|
6924
|
+
return spawnFn(
|
|
6925
|
+
[
|
|
6926
|
+
"-f",
|
|
6927
|
+
composeFile,
|
|
6928
|
+
"-p",
|
|
6929
|
+
projectName,
|
|
6930
|
+
"--profile",
|
|
6931
|
+
DEFERRED_SERVICE_PROFILE,
|
|
6932
|
+
"up",
|
|
6933
|
+
"-d",
|
|
6934
|
+
"--quiet-pull",
|
|
6935
|
+
...opts.services
|
|
6936
|
+
],
|
|
6937
|
+
opts.root
|
|
6938
|
+
);
|
|
6939
|
+
}
|
|
6816
6940
|
async function runStart(opts) {
|
|
6817
6941
|
assertDevcontainer(opts.root);
|
|
6818
6942
|
const logger = opts.logger ?? { info: (msg) => consola10.info(msg) };
|
|
@@ -7040,6 +7164,7 @@ var init_compose = __esm({
|
|
|
7040
7164
|
"use strict";
|
|
7041
7165
|
init_proxy();
|
|
7042
7166
|
init_mask_secrets();
|
|
7167
|
+
init_catalog();
|
|
7043
7168
|
init_cli();
|
|
7044
7169
|
init_proxy();
|
|
7045
7170
|
spawnDockerCompose = (args, cwd) => {
|
|
@@ -7116,7 +7241,7 @@ var init_images = __esm({
|
|
|
7116
7241
|
});
|
|
7117
7242
|
|
|
7118
7243
|
// src/config/machine-state.ts
|
|
7119
|
-
import { promises as fsp4 } from "fs";
|
|
7244
|
+
import { promises as fsp4, readFileSync as readFileSync6 } from "fs";
|
|
7120
7245
|
import path18 from "path";
|
|
7121
7246
|
function machineStatePath(home = monocerosHome()) {
|
|
7122
7247
|
return path18.join(home, ".machine-state.json");
|
|
@@ -7132,6 +7257,18 @@ async function readMachineState(home = monocerosHome()) {
|
|
|
7132
7257
|
}
|
|
7133
7258
|
return {};
|
|
7134
7259
|
}
|
|
7260
|
+
function readMachineStateSync(home = monocerosHome()) {
|
|
7261
|
+
try {
|
|
7262
|
+
const parsed = JSON.parse(
|
|
7263
|
+
readFileSync6(machineStatePath(home), "utf8")
|
|
7264
|
+
);
|
|
7265
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
7266
|
+
return parsed;
|
|
7267
|
+
}
|
|
7268
|
+
} catch {
|
|
7269
|
+
}
|
|
7270
|
+
return {};
|
|
7271
|
+
}
|
|
7135
7272
|
async function writeMachineState(state, home = monocerosHome()) {
|
|
7136
7273
|
await fsp4.writeFile(
|
|
7137
7274
|
machineStatePath(home),
|
|
@@ -7147,6 +7284,12 @@ async function recordBuiltImage(record, home = monocerosHome()) {
|
|
|
7147
7284
|
state.builtImages = [...rest, record];
|
|
7148
7285
|
await writeMachineState(state, home);
|
|
7149
7286
|
}
|
|
7287
|
+
async function recordVersionCheck(opts, home = monocerosHome()) {
|
|
7288
|
+
const state = await readMachineState(home);
|
|
7289
|
+
state.lastVersionCheckAt = opts.nowIso;
|
|
7290
|
+
if (opts.latestVersion) state.latestVersion = opts.latestVersion;
|
|
7291
|
+
await writeMachineState(state, home);
|
|
7292
|
+
}
|
|
7150
7293
|
async function markUpgraded(nowIso, home = monocerosHome()) {
|
|
7151
7294
|
const state = await readMachineState(home);
|
|
7152
7295
|
state.lastUpgradeAt = nowIso;
|
|
@@ -7686,6 +7829,30 @@ Fix the value in the env file (or the yml).`
|
|
|
7686
7829
|
...progress ? { progressSink: progress.streamSink, silent: true } : {},
|
|
7687
7830
|
logger: internalLogger
|
|
7688
7831
|
});
|
|
7832
|
+
if (exitCode === 0) {
|
|
7833
|
+
const deferred = createOpts.services.filter((s) => serviceDefersStart(s.name)).map((s) => s.name);
|
|
7834
|
+
if (deferred.length > 0) {
|
|
7835
|
+
if (progress) progress.setPhase("starting services\u2026");
|
|
7836
|
+
try {
|
|
7837
|
+
const deferExit = await startDeferredServices({
|
|
7838
|
+
root: targetDir,
|
|
7839
|
+
services: deferred,
|
|
7840
|
+
logSink: applyLog.sink,
|
|
7841
|
+
silent: progress !== null,
|
|
7842
|
+
logger: internalLogger
|
|
7843
|
+
});
|
|
7844
|
+
if (deferExit !== 0) {
|
|
7845
|
+
containerLogger.warn?.(
|
|
7846
|
+
`Deferred service(s) ${deferred.join(", ")} did not start cleanly (exit ${deferExit}). The workspace is up; bring them up with \`monoceros start ${opts.name}\`.`
|
|
7847
|
+
);
|
|
7848
|
+
}
|
|
7849
|
+
} catch (err) {
|
|
7850
|
+
containerLogger.warn?.(
|
|
7851
|
+
`Could not start deferred service(s) ${deferred.join(", ")}: ${err instanceof Error ? err.message : String(err)}. The workspace is up.`
|
|
7852
|
+
);
|
|
7853
|
+
}
|
|
7854
|
+
}
|
|
7855
|
+
}
|
|
7689
7856
|
if (progress) {
|
|
7690
7857
|
if (exitCode === 0) {
|
|
7691
7858
|
progress.succeed();
|
|
@@ -7880,7 +8047,7 @@ var init_apply = __esm({
|
|
|
7880
8047
|
|
|
7881
8048
|
// src/devcontainer/browser-bridge.ts
|
|
7882
8049
|
import { spawn as spawn9 } from "child_process";
|
|
7883
|
-
import { existsSync as existsSync11, promises as fsp5, readFileSync as
|
|
8050
|
+
import { existsSync as existsSync11, promises as fsp5, readFileSync as readFileSync7 } from "fs";
|
|
7884
8051
|
import http from "http";
|
|
7885
8052
|
import path20 from "path";
|
|
7886
8053
|
function parseCallbackTarget(authUrl) {
|
|
@@ -7983,7 +8150,7 @@ exit 0
|
|
|
7983
8150
|
if (!existsSync11(urlFile)) return;
|
|
7984
8151
|
let content = "";
|
|
7985
8152
|
try {
|
|
7986
|
-
content =
|
|
8153
|
+
content = readFileSync7(urlFile, "utf8");
|
|
7987
8154
|
} catch {
|
|
7988
8155
|
return;
|
|
7989
8156
|
}
|
|
@@ -8180,7 +8347,7 @@ var CLI_VERSION;
|
|
|
8180
8347
|
var init_version = __esm({
|
|
8181
8348
|
"src/version.ts"() {
|
|
8182
8349
|
"use strict";
|
|
8183
|
-
CLI_VERSION = true ? "1.
|
|
8350
|
+
CLI_VERSION = true ? "1.31.0" : "dev";
|
|
8184
8351
|
}
|
|
8185
8352
|
});
|
|
8186
8353
|
|
|
@@ -8825,6 +8992,140 @@ var init_complete = __esm({
|
|
|
8825
8992
|
}
|
|
8826
8993
|
});
|
|
8827
8994
|
|
|
8995
|
+
// src/update/notifier.ts
|
|
8996
|
+
import { spawn as spawn11 } from "child_process";
|
|
8997
|
+
function isNewerVersion(latest, current) {
|
|
8998
|
+
const parse = (v) => {
|
|
8999
|
+
const m = /^(\d+)\.(\d+)\.(\d+)/.exec(v.trim());
|
|
9000
|
+
return m ? [Number(m[1]), Number(m[2]), Number(m[3])] : null;
|
|
9001
|
+
};
|
|
9002
|
+
const a = parse(latest);
|
|
9003
|
+
const b = parse(current);
|
|
9004
|
+
if (!a || !b) return false;
|
|
9005
|
+
for (let i = 0; i < 3; i++) {
|
|
9006
|
+
if (a[i] !== b[i]) return a[i] > b[i];
|
|
9007
|
+
}
|
|
9008
|
+
return false;
|
|
9009
|
+
}
|
|
9010
|
+
function formatUpdateNotice(latest, current) {
|
|
9011
|
+
return `
|
|
9012
|
+
\u2B06 Monoceros ${latest} is available (you have ${current}).
|
|
9013
|
+
Update: ${INSTALL_COMMAND}
|
|
9014
|
+
`;
|
|
9015
|
+
}
|
|
9016
|
+
function decideUpdateAction(state, currentVersion, now, intervalMs = CHECK_INTERVAL_MS) {
|
|
9017
|
+
const notice = state.latestVersion && isNewerVersion(state.latestVersion, currentVersion) ? formatUpdateNotice(state.latestVersion, currentVersion) : null;
|
|
9018
|
+
const last = state.lastVersionCheckAt ? new Date(state.lastVersionCheckAt).getTime() : NaN;
|
|
9019
|
+
const refresh = !Number.isFinite(last) || now.getTime() - last > intervalMs;
|
|
9020
|
+
return { notice, refresh };
|
|
9021
|
+
}
|
|
9022
|
+
function scheduleUpdateNotice(opts) {
|
|
9023
|
+
try {
|
|
9024
|
+
if (process.env[OPT_OUT_ENV]) return;
|
|
9025
|
+
if (opts.currentVersion === "dev") return;
|
|
9026
|
+
if (!process.stdout.isTTY) return;
|
|
9027
|
+
if (opts.commandName === void 0) return;
|
|
9028
|
+
if (SKIP_COMMANDS.has(opts.commandName)) return;
|
|
9029
|
+
const argv = opts.argv ?? process.argv.slice(2);
|
|
9030
|
+
if (argv.some((a) => ["-h", "--help", "-v", "--version"].includes(a))) {
|
|
9031
|
+
return;
|
|
9032
|
+
}
|
|
9033
|
+
const state = readMachineStateSync();
|
|
9034
|
+
const { notice, refresh } = decideUpdateAction(
|
|
9035
|
+
state,
|
|
9036
|
+
opts.currentVersion,
|
|
9037
|
+
opts.now ?? /* @__PURE__ */ new Date()
|
|
9038
|
+
);
|
|
9039
|
+
if (notice) {
|
|
9040
|
+
process.on("exit", () => {
|
|
9041
|
+
try {
|
|
9042
|
+
process.stderr.write(notice);
|
|
9043
|
+
} catch {
|
|
9044
|
+
}
|
|
9045
|
+
});
|
|
9046
|
+
}
|
|
9047
|
+
if (refresh) spawnBackgroundCheck();
|
|
9048
|
+
} catch {
|
|
9049
|
+
}
|
|
9050
|
+
}
|
|
9051
|
+
function spawnBackgroundCheck() {
|
|
9052
|
+
const self = process.argv[1];
|
|
9053
|
+
if (!self) return;
|
|
9054
|
+
try {
|
|
9055
|
+
const child = spawn11(process.execPath, [self, "__update-check"], {
|
|
9056
|
+
detached: true,
|
|
9057
|
+
stdio: "ignore"
|
|
9058
|
+
});
|
|
9059
|
+
child.unref();
|
|
9060
|
+
} catch {
|
|
9061
|
+
}
|
|
9062
|
+
}
|
|
9063
|
+
async function runUpdateCheck(now = /* @__PURE__ */ new Date(), home) {
|
|
9064
|
+
let latestVersion;
|
|
9065
|
+
try {
|
|
9066
|
+
const controller = new AbortController();
|
|
9067
|
+
const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
9068
|
+
try {
|
|
9069
|
+
const res = await fetch(REGISTRY_URL, { signal: controller.signal });
|
|
9070
|
+
if (res.ok) {
|
|
9071
|
+
const json = await res.json();
|
|
9072
|
+
if (typeof json.version === "string") latestVersion = json.version;
|
|
9073
|
+
}
|
|
9074
|
+
} finally {
|
|
9075
|
+
clearTimeout(timer);
|
|
9076
|
+
}
|
|
9077
|
+
} catch {
|
|
9078
|
+
}
|
|
9079
|
+
try {
|
|
9080
|
+
await recordVersionCheck(
|
|
9081
|
+
{
|
|
9082
|
+
...latestVersion ? { latestVersion } : {},
|
|
9083
|
+
nowIso: now.toISOString()
|
|
9084
|
+
},
|
|
9085
|
+
home
|
|
9086
|
+
);
|
|
9087
|
+
} catch {
|
|
9088
|
+
}
|
|
9089
|
+
}
|
|
9090
|
+
var PACKAGE, REGISTRY_URL, INSTALL_COMMAND, CHECK_INTERVAL_MS, OPT_OUT_ENV, FETCH_TIMEOUT_MS, SKIP_COMMANDS;
|
|
9091
|
+
var init_notifier = __esm({
|
|
9092
|
+
"src/update/notifier.ts"() {
|
|
9093
|
+
"use strict";
|
|
9094
|
+
init_machine_state();
|
|
9095
|
+
PACKAGE = "@getmonoceros/workbench";
|
|
9096
|
+
REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE}/latest`;
|
|
9097
|
+
INSTALL_COMMAND = "curl -fsSL https://raw.githubusercontent.com/getmonoceros/workbench/main/install.sh | bash";
|
|
9098
|
+
CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
9099
|
+
OPT_OUT_ENV = "MONOCEROS_NO_UPDATE_NOTIFIER";
|
|
9100
|
+
FETCH_TIMEOUT_MS = 5e3;
|
|
9101
|
+
SKIP_COMMANDS = /* @__PURE__ */ new Set(["__complete", "__update-check", "completion"]);
|
|
9102
|
+
}
|
|
9103
|
+
});
|
|
9104
|
+
|
|
9105
|
+
// src/commands/__update-check.ts
|
|
9106
|
+
import { defineCommand as defineCommand11 } from "citty";
|
|
9107
|
+
var __updateCheckCommand;
|
|
9108
|
+
var init_update_check = __esm({
|
|
9109
|
+
"src/commands/__update-check.ts"() {
|
|
9110
|
+
"use strict";
|
|
9111
|
+
init_notifier();
|
|
9112
|
+
__updateCheckCommand = defineCommand11({
|
|
9113
|
+
meta: {
|
|
9114
|
+
name: "__update-check",
|
|
9115
|
+
group: "internal",
|
|
9116
|
+
hidden: true,
|
|
9117
|
+
description: "Internal: refresh the cached latest-version (background)."
|
|
9118
|
+
},
|
|
9119
|
+
async run() {
|
|
9120
|
+
try {
|
|
9121
|
+
await runUpdateCheck();
|
|
9122
|
+
} catch {
|
|
9123
|
+
}
|
|
9124
|
+
}
|
|
9125
|
+
});
|
|
9126
|
+
}
|
|
9127
|
+
});
|
|
9128
|
+
|
|
8828
9129
|
// src/init/generator.ts
|
|
8829
9130
|
function generateComposedYml(name, composed, lookupManifest, repoUrls = [], ports = []) {
|
|
8830
9131
|
const lines = [];
|
|
@@ -8990,6 +9291,12 @@ function generateDocumentedYml(name, catalog, lookupManifest, repoUrls = [], por
|
|
|
8990
9291
|
const body = renderServiceObjectBody(expandCuratedService(svc));
|
|
8991
9292
|
lines.push(`# - ${body[0]}`);
|
|
8992
9293
|
for (const line of body.slice(1)) lines.push(`# ${line}`);
|
|
9294
|
+
const exComment = exampleVolumesComment(
|
|
9295
|
+
curatedServiceExampleVolumes(svc)
|
|
9296
|
+
);
|
|
9297
|
+
if (exComment) {
|
|
9298
|
+
for (const cl of exComment.split("\n")) lines.push(`# ${cl}`);
|
|
9299
|
+
}
|
|
8993
9300
|
}
|
|
8994
9301
|
}
|
|
8995
9302
|
lines.push("");
|
|
@@ -9109,6 +9416,12 @@ function pushServiceEntry(out, svc) {
|
|
|
9109
9416
|
const body = renderServiceObjectBody(expandCuratedService(svc.name));
|
|
9110
9417
|
out.push(` - ${body[0]}`);
|
|
9111
9418
|
for (const line of body.slice(1)) out.push(` ${line}`);
|
|
9419
|
+
const exComment = exampleVolumesComment(
|
|
9420
|
+
curatedServiceExampleVolumes(svc.name)
|
|
9421
|
+
);
|
|
9422
|
+
if (exComment) {
|
|
9423
|
+
for (const cl of exComment.split("\n")) out.push(` #${cl}`);
|
|
9424
|
+
}
|
|
9112
9425
|
}
|
|
9113
9426
|
function pushGitIdentityBlock(lines) {
|
|
9114
9427
|
pushSectionHeader(
|
|
@@ -9398,19 +9711,19 @@ function resolveInitAptPackages(entries) {
|
|
|
9398
9711
|
}
|
|
9399
9712
|
function resolveInitServices(entries) {
|
|
9400
9713
|
const out = [];
|
|
9401
|
-
const
|
|
9714
|
+
const byName2 = /* @__PURE__ */ new Map();
|
|
9402
9715
|
for (const raw of entries) {
|
|
9403
9716
|
const e = raw.trim();
|
|
9404
9717
|
if (!e) continue;
|
|
9405
9718
|
const svc = isCuratedService(e) ? { kind: "curated", name: e } : { kind: "custom", name: deriveServiceName(e), image: e };
|
|
9406
|
-
const existing =
|
|
9719
|
+
const existing = byName2.get(svc.name);
|
|
9407
9720
|
if (existing) {
|
|
9408
9721
|
if (existing.kind === svc.kind && existing.image === svc.image) continue;
|
|
9409
9722
|
throw new Error(
|
|
9410
9723
|
`Two --with-services entries resolve to the service name '${svc.name}'. Add one after init with \`monoceros add-service ${"<name>"} <image> --as=<other>\`.`
|
|
9411
9724
|
);
|
|
9412
9725
|
}
|
|
9413
|
-
|
|
9726
|
+
byName2.set(svc.name, svc);
|
|
9414
9727
|
out.push(svc);
|
|
9415
9728
|
}
|
|
9416
9729
|
return out;
|
|
@@ -9466,7 +9779,7 @@ var init_init = __esm({
|
|
|
9466
9779
|
});
|
|
9467
9780
|
|
|
9468
9781
|
// src/commands/init.ts
|
|
9469
|
-
import { defineCommand as
|
|
9782
|
+
import { defineCommand as defineCommand12 } from "citty";
|
|
9470
9783
|
import { consola as consola17 } from "consola";
|
|
9471
9784
|
function collectListFlag(flag, rawArgs) {
|
|
9472
9785
|
const eq = `${flag}=`;
|
|
@@ -9532,7 +9845,7 @@ var init_init2 = __esm({
|
|
|
9532
9845
|
"src/commands/init.ts"() {
|
|
9533
9846
|
"use strict";
|
|
9534
9847
|
init_init();
|
|
9535
|
-
initCommand =
|
|
9848
|
+
initCommand = defineCommand12({
|
|
9536
9849
|
meta: {
|
|
9537
9850
|
name: "init",
|
|
9538
9851
|
group: "lifecycle",
|
|
@@ -9640,8 +9953,76 @@ var init_expand = __esm({
|
|
|
9640
9953
|
}
|
|
9641
9954
|
});
|
|
9642
9955
|
|
|
9956
|
+
// src/catalog/catalog-json.ts
|
|
9957
|
+
function projectOption(key, spec) {
|
|
9958
|
+
if (spec.surface === "silent") return null;
|
|
9959
|
+
const out = {
|
|
9960
|
+
key,
|
|
9961
|
+
type: spec.type,
|
|
9962
|
+
surface: spec.surface
|
|
9963
|
+
};
|
|
9964
|
+
if (spec.default !== void 0) out.default = spec.default;
|
|
9965
|
+
if (spec.description !== void 0) out.description = spec.description;
|
|
9966
|
+
if (spec.proposals !== void 0) out.proposals = spec.proposals;
|
|
9967
|
+
return out;
|
|
9968
|
+
}
|
|
9969
|
+
function projectOptions(options) {
|
|
9970
|
+
return Object.entries(options).map(([key, spec]) => projectOption(key, spec)).filter((o) => o !== null).sort((a, b) => a.key.localeCompare(b.key));
|
|
9971
|
+
}
|
|
9972
|
+
function byName(a, b) {
|
|
9973
|
+
return a.name.localeCompare(b.name);
|
|
9974
|
+
}
|
|
9975
|
+
function buildCatalogJson(catalog, cliVersion) {
|
|
9976
|
+
const languages = [];
|
|
9977
|
+
const services = [];
|
|
9978
|
+
const features = [];
|
|
9979
|
+
for (const { descriptor: d } of catalog.values()) {
|
|
9980
|
+
const base = {
|
|
9981
|
+
name: d.name ?? d.id,
|
|
9982
|
+
displayName: d.displayName,
|
|
9983
|
+
description: d.description,
|
|
9984
|
+
options: projectOptions(d.options)
|
|
9985
|
+
};
|
|
9986
|
+
if (d.documentationURL !== void 0) {
|
|
9987
|
+
base.documentationURL = d.documentationURL;
|
|
9988
|
+
}
|
|
9989
|
+
if (d.category === "language" && d.language) {
|
|
9990
|
+
const lang = { ...base };
|
|
9991
|
+
if (d.language.defaultVersion !== void 0) {
|
|
9992
|
+
lang.defaultVersion = d.language.defaultVersion;
|
|
9993
|
+
}
|
|
9994
|
+
if (d.language.versions !== void 0) {
|
|
9995
|
+
lang.versions = d.language.versions;
|
|
9996
|
+
}
|
|
9997
|
+
languages.push(lang);
|
|
9998
|
+
} else if (d.category === "service" && d.service) {
|
|
9999
|
+
const svc = { ...base };
|
|
10000
|
+
if (d.service.defaultPort !== void 0) {
|
|
10001
|
+
svc.defaultPort = d.service.defaultPort;
|
|
10002
|
+
}
|
|
10003
|
+
services.push(svc);
|
|
10004
|
+
} else if (d.category === "feature") {
|
|
10005
|
+
features.push({ ...base, presets: Object.keys(d.presets ?? {}).sort() });
|
|
10006
|
+
}
|
|
10007
|
+
}
|
|
10008
|
+
return {
|
|
10009
|
+
schemaVersion: CATALOG_JSON_SCHEMA_VERSION,
|
|
10010
|
+
cliVersion,
|
|
10011
|
+
languages: languages.sort(byName),
|
|
10012
|
+
services: services.sort(byName),
|
|
10013
|
+
features: features.sort(byName)
|
|
10014
|
+
};
|
|
10015
|
+
}
|
|
10016
|
+
var CATALOG_JSON_SCHEMA_VERSION;
|
|
10017
|
+
var init_catalog_json = __esm({
|
|
10018
|
+
"src/catalog/catalog-json.ts"() {
|
|
10019
|
+
"use strict";
|
|
10020
|
+
CATALOG_JSON_SCHEMA_VERSION = 1;
|
|
10021
|
+
}
|
|
10022
|
+
});
|
|
10023
|
+
|
|
9643
10024
|
// src/commands/list-components.ts
|
|
9644
|
-
import { defineCommand as
|
|
10025
|
+
import { defineCommand as defineCommand13 } from "citty";
|
|
9645
10026
|
import { consola as consola18 } from "consola";
|
|
9646
10027
|
var CATEGORY_LABELS, CATEGORY_ORDER, listComponentsCommand;
|
|
9647
10028
|
var init_list_components = __esm({
|
|
@@ -9649,6 +10030,8 @@ var init_list_components = __esm({
|
|
|
9649
10030
|
"use strict";
|
|
9650
10031
|
init_load();
|
|
9651
10032
|
init_expand();
|
|
10033
|
+
init_catalog_json();
|
|
10034
|
+
init_version();
|
|
9652
10035
|
init_format();
|
|
9653
10036
|
CATEGORY_LABELS = {
|
|
9654
10037
|
language: "Languages",
|
|
@@ -9660,16 +10043,28 @@ var init_list_components = __esm({
|
|
|
9660
10043
|
"service",
|
|
9661
10044
|
"feature"
|
|
9662
10045
|
];
|
|
9663
|
-
listComponentsCommand =
|
|
10046
|
+
listComponentsCommand = defineCommand13({
|
|
9664
10047
|
meta: {
|
|
9665
10048
|
name: "list-components",
|
|
9666
10049
|
group: "discovery",
|
|
9667
|
-
description: "Print the components catalog used by `monoceros init --with-languages=\u2026 / --with-services=\u2026 / --with-features=\u2026`, grouped by category (Languages, Services, Features). Component names render in cyan, descriptions in default colour; when piped, the formatting drops out and lines become `name<TAB>description` for grep/awk-friendly consumption."
|
|
10050
|
+
description: "Print the components catalog used by `monoceros init --with-languages=\u2026 / --with-services=\u2026 / --with-features=\u2026`, grouped by category (Languages, Services, Features). Component names render in cyan, descriptions in default colour; when piped, the formatting drops out and lines become `name<TAB>description` for grep/awk-friendly consumption. `--json` emits the full catalog (options, versions, presets) as a machine-readable document \u2014 the same shape published at getmonoceros.build/catalog.json."
|
|
9668
10051
|
},
|
|
9669
|
-
args: {
|
|
9670
|
-
|
|
10052
|
+
args: {
|
|
10053
|
+
json: {
|
|
10054
|
+
type: "boolean",
|
|
10055
|
+
description: "Emit the catalog as a JSON document (name, options, versions, presets per component) instead of the human-readable listing."
|
|
10056
|
+
}
|
|
10057
|
+
},
|
|
10058
|
+
async run({ args }) {
|
|
9671
10059
|
try {
|
|
9672
|
-
const
|
|
10060
|
+
const descriptors = await loadDescriptorCatalog();
|
|
10061
|
+
if (args.json) {
|
|
10062
|
+
const doc = buildCatalogJson(descriptors, CLI_VERSION);
|
|
10063
|
+
process.stdout.write(`${JSON.stringify(doc, null, 2)}
|
|
10064
|
+
`);
|
|
10065
|
+
process.exit(0);
|
|
10066
|
+
}
|
|
10067
|
+
const catalog = expandSelectable(descriptors);
|
|
9673
10068
|
if (catalog.size === 0) {
|
|
9674
10069
|
consola18.warn(
|
|
9675
10070
|
"No components found. The workbench checkout looks incomplete."
|
|
@@ -9731,14 +10126,14 @@ var init_list_components = __esm({
|
|
|
9731
10126
|
});
|
|
9732
10127
|
|
|
9733
10128
|
// src/commands/logs.ts
|
|
9734
|
-
import { spawn as
|
|
10129
|
+
import { spawn as spawn12 } from "child_process";
|
|
9735
10130
|
import { existsSync as existsSync16 } from "fs";
|
|
9736
10131
|
import path25 from "path";
|
|
9737
|
-
import { defineCommand as
|
|
10132
|
+
import { defineCommand as defineCommand14 } from "citty";
|
|
9738
10133
|
function tailLogFile(file, follow) {
|
|
9739
10134
|
const [cmd, args] = follow ? ["tail", ["-F", file]] : ["cat", [file]];
|
|
9740
10135
|
return new Promise((resolve, reject) => {
|
|
9741
|
-
const child =
|
|
10136
|
+
const child = spawn12(cmd, args, { stdio: "inherit" });
|
|
9742
10137
|
child.on("error", reject);
|
|
9743
10138
|
child.on("exit", (code) => resolve(code ?? 0));
|
|
9744
10139
|
});
|
|
@@ -9750,7 +10145,7 @@ var init_logs = __esm({
|
|
|
9750
10145
|
init_paths();
|
|
9751
10146
|
init_compose();
|
|
9752
10147
|
init_dispatch();
|
|
9753
|
-
logsCommand =
|
|
10148
|
+
logsCommand = defineCommand14({
|
|
9754
10149
|
meta: {
|
|
9755
10150
|
name: "logs",
|
|
9756
10151
|
group: "run",
|
|
@@ -9794,14 +10189,14 @@ var init_logs = __esm({
|
|
|
9794
10189
|
});
|
|
9795
10190
|
|
|
9796
10191
|
// src/commands/open.ts
|
|
9797
|
-
import { defineCommand as
|
|
10192
|
+
import { defineCommand as defineCommand15 } from "citty";
|
|
9798
10193
|
var openCommand;
|
|
9799
10194
|
var init_open2 = __esm({
|
|
9800
10195
|
"src/commands/open.ts"() {
|
|
9801
10196
|
"use strict";
|
|
9802
10197
|
init_open();
|
|
9803
10198
|
init_dispatch();
|
|
9804
|
-
openCommand =
|
|
10199
|
+
openCommand = defineCommand15({
|
|
9805
10200
|
meta: {
|
|
9806
10201
|
name: "open",
|
|
9807
10202
|
group: "run",
|
|
@@ -9827,7 +10222,7 @@ var init_open2 = __esm({
|
|
|
9827
10222
|
});
|
|
9828
10223
|
|
|
9829
10224
|
// src/commands/port.ts
|
|
9830
|
-
import { defineCommand as
|
|
10225
|
+
import { defineCommand as defineCommand16 } from "citty";
|
|
9831
10226
|
import { consola as consola19 } from "consola";
|
|
9832
10227
|
async function runPortListing(opts) {
|
|
9833
10228
|
const out = opts.out ?? process.stdout;
|
|
@@ -9889,7 +10284,7 @@ var init_port = __esm({
|
|
|
9889
10284
|
init_schema();
|
|
9890
10285
|
init_dynamic();
|
|
9891
10286
|
init_format();
|
|
9892
|
-
portCommand =
|
|
10287
|
+
portCommand = defineCommand16({
|
|
9893
10288
|
meta: {
|
|
9894
10289
|
name: "port",
|
|
9895
10290
|
group: "discovery",
|
|
@@ -9916,7 +10311,7 @@ var init_port = __esm({
|
|
|
9916
10311
|
});
|
|
9917
10312
|
|
|
9918
10313
|
// src/commands/remove-apt-packages.ts
|
|
9919
|
-
import { defineCommand as
|
|
10314
|
+
import { defineCommand as defineCommand17 } from "citty";
|
|
9920
10315
|
import { consola as consola20 } from "consola";
|
|
9921
10316
|
var removeAptPackagesCommand;
|
|
9922
10317
|
var init_remove_apt_packages = __esm({
|
|
@@ -9924,7 +10319,7 @@ var init_remove_apt_packages = __esm({
|
|
|
9924
10319
|
"use strict";
|
|
9925
10320
|
init_inner_args();
|
|
9926
10321
|
init_modify();
|
|
9927
|
-
removeAptPackagesCommand =
|
|
10322
|
+
removeAptPackagesCommand = defineCommand17({
|
|
9928
10323
|
meta: {
|
|
9929
10324
|
name: "remove-apt-packages",
|
|
9930
10325
|
group: "edit",
|
|
@@ -9968,14 +10363,14 @@ var init_remove_apt_packages = __esm({
|
|
|
9968
10363
|
});
|
|
9969
10364
|
|
|
9970
10365
|
// src/commands/remove-feature.ts
|
|
9971
|
-
import { defineCommand as
|
|
10366
|
+
import { defineCommand as defineCommand18 } from "citty";
|
|
9972
10367
|
import { consola as consola21 } from "consola";
|
|
9973
10368
|
var removeFeatureCommand;
|
|
9974
10369
|
var init_remove_feature = __esm({
|
|
9975
10370
|
"src/commands/remove-feature.ts"() {
|
|
9976
10371
|
"use strict";
|
|
9977
10372
|
init_modify();
|
|
9978
|
-
removeFeatureCommand =
|
|
10373
|
+
removeFeatureCommand = defineCommand18({
|
|
9979
10374
|
meta: {
|
|
9980
10375
|
name: "remove-feature",
|
|
9981
10376
|
group: "edit",
|
|
@@ -10171,7 +10566,7 @@ var init_remove = __esm({
|
|
|
10171
10566
|
});
|
|
10172
10567
|
|
|
10173
10568
|
// src/commands/remove.ts
|
|
10174
|
-
import { defineCommand as
|
|
10569
|
+
import { defineCommand as defineCommand19 } from "citty";
|
|
10175
10570
|
import { consola as consola23 } from "consola";
|
|
10176
10571
|
import { createInterface } from "readline/promises";
|
|
10177
10572
|
var removeCommand;
|
|
@@ -10179,7 +10574,7 @@ var init_remove2 = __esm({
|
|
|
10179
10574
|
"src/commands/remove.ts"() {
|
|
10180
10575
|
"use strict";
|
|
10181
10576
|
init_remove();
|
|
10182
|
-
removeCommand =
|
|
10577
|
+
removeCommand = defineCommand19({
|
|
10183
10578
|
meta: {
|
|
10184
10579
|
name: "remove",
|
|
10185
10580
|
group: "lifecycle",
|
|
@@ -10315,14 +10710,14 @@ var init_restore = __esm({
|
|
|
10315
10710
|
});
|
|
10316
10711
|
|
|
10317
10712
|
// src/commands/restore.ts
|
|
10318
|
-
import { defineCommand as
|
|
10713
|
+
import { defineCommand as defineCommand20 } from "citty";
|
|
10319
10714
|
import { consola as consola25 } from "consola";
|
|
10320
10715
|
var restoreCommand;
|
|
10321
10716
|
var init_restore2 = __esm({
|
|
10322
10717
|
"src/commands/restore.ts"() {
|
|
10323
10718
|
"use strict";
|
|
10324
10719
|
init_restore();
|
|
10325
|
-
restoreCommand =
|
|
10720
|
+
restoreCommand = defineCommand20({
|
|
10326
10721
|
meta: {
|
|
10327
10722
|
name: "restore",
|
|
10328
10723
|
group: "lifecycle",
|
|
@@ -10348,14 +10743,14 @@ var init_restore2 = __esm({
|
|
|
10348
10743
|
});
|
|
10349
10744
|
|
|
10350
10745
|
// src/commands/remove-from-url.ts
|
|
10351
|
-
import { defineCommand as
|
|
10746
|
+
import { defineCommand as defineCommand21 } from "citty";
|
|
10352
10747
|
import { consola as consola26 } from "consola";
|
|
10353
10748
|
var removeFromUrlCommand;
|
|
10354
10749
|
var init_remove_from_url = __esm({
|
|
10355
10750
|
"src/commands/remove-from-url.ts"() {
|
|
10356
10751
|
"use strict";
|
|
10357
10752
|
init_modify();
|
|
10358
|
-
removeFromUrlCommand =
|
|
10753
|
+
removeFromUrlCommand = defineCommand21({
|
|
10359
10754
|
meta: {
|
|
10360
10755
|
name: "remove-from-url",
|
|
10361
10756
|
group: "edit",
|
|
@@ -10397,14 +10792,14 @@ var init_remove_from_url = __esm({
|
|
|
10397
10792
|
});
|
|
10398
10793
|
|
|
10399
10794
|
// src/commands/remove-language.ts
|
|
10400
|
-
import { defineCommand as
|
|
10795
|
+
import { defineCommand as defineCommand22 } from "citty";
|
|
10401
10796
|
import { consola as consola27 } from "consola";
|
|
10402
10797
|
var removeLanguageCommand;
|
|
10403
10798
|
var init_remove_language = __esm({
|
|
10404
10799
|
"src/commands/remove-language.ts"() {
|
|
10405
10800
|
"use strict";
|
|
10406
10801
|
init_modify();
|
|
10407
|
-
removeLanguageCommand =
|
|
10802
|
+
removeLanguageCommand = defineCommand22({
|
|
10408
10803
|
meta: {
|
|
10409
10804
|
name: "remove-language",
|
|
10410
10805
|
group: "edit",
|
|
@@ -10446,7 +10841,7 @@ var init_remove_language = __esm({
|
|
|
10446
10841
|
});
|
|
10447
10842
|
|
|
10448
10843
|
// src/commands/remove-port.ts
|
|
10449
|
-
import { defineCommand as
|
|
10844
|
+
import { defineCommand as defineCommand23 } from "citty";
|
|
10450
10845
|
import { consola as consola28 } from "consola";
|
|
10451
10846
|
function coerceToken2(raw) {
|
|
10452
10847
|
const n = Number(raw);
|
|
@@ -10458,7 +10853,7 @@ var init_remove_port = __esm({
|
|
|
10458
10853
|
"use strict";
|
|
10459
10854
|
init_inner_args();
|
|
10460
10855
|
init_modify();
|
|
10461
|
-
removePortCommand =
|
|
10856
|
+
removePortCommand = defineCommand23({
|
|
10462
10857
|
meta: {
|
|
10463
10858
|
name: "remove-port",
|
|
10464
10859
|
group: "edit",
|
|
@@ -10502,14 +10897,14 @@ var init_remove_port = __esm({
|
|
|
10502
10897
|
});
|
|
10503
10898
|
|
|
10504
10899
|
// src/commands/remove-repo.ts
|
|
10505
|
-
import { defineCommand as
|
|
10900
|
+
import { defineCommand as defineCommand24 } from "citty";
|
|
10506
10901
|
import { consola as consola29 } from "consola";
|
|
10507
10902
|
var removeRepoCommand;
|
|
10508
10903
|
var init_remove_repo = __esm({
|
|
10509
10904
|
"src/commands/remove-repo.ts"() {
|
|
10510
10905
|
"use strict";
|
|
10511
10906
|
init_modify();
|
|
10512
|
-
removeRepoCommand =
|
|
10907
|
+
removeRepoCommand = defineCommand24({
|
|
10513
10908
|
meta: {
|
|
10514
10909
|
name: "remove-repo",
|
|
10515
10910
|
group: "edit",
|
|
@@ -10551,14 +10946,14 @@ var init_remove_repo = __esm({
|
|
|
10551
10946
|
});
|
|
10552
10947
|
|
|
10553
10948
|
// src/commands/remove-service.ts
|
|
10554
|
-
import { defineCommand as
|
|
10949
|
+
import { defineCommand as defineCommand25 } from "citty";
|
|
10555
10950
|
import { consola as consola30 } from "consola";
|
|
10556
10951
|
var removeServiceCommand;
|
|
10557
10952
|
var init_remove_service = __esm({
|
|
10558
10953
|
"src/commands/remove-service.ts"() {
|
|
10559
10954
|
"use strict";
|
|
10560
10955
|
init_modify();
|
|
10561
|
-
removeServiceCommand =
|
|
10956
|
+
removeServiceCommand = defineCommand25({
|
|
10562
10957
|
meta: {
|
|
10563
10958
|
name: "remove-service",
|
|
10564
10959
|
group: "edit",
|
|
@@ -10700,7 +11095,7 @@ var init_run = __esm({
|
|
|
10700
11095
|
});
|
|
10701
11096
|
|
|
10702
11097
|
// src/commands/run.ts
|
|
10703
|
-
import { defineCommand as
|
|
11098
|
+
import { defineCommand as defineCommand26 } from "citty";
|
|
10704
11099
|
import { consola as consola31 } from "consola";
|
|
10705
11100
|
var runCommand;
|
|
10706
11101
|
var init_run2 = __esm({
|
|
@@ -10709,7 +11104,7 @@ var init_run2 = __esm({
|
|
|
10709
11104
|
init_paths();
|
|
10710
11105
|
init_run();
|
|
10711
11106
|
init_inner_args();
|
|
10712
|
-
runCommand =
|
|
11107
|
+
runCommand = defineCommand26({
|
|
10713
11108
|
meta: {
|
|
10714
11109
|
name: "run",
|
|
10715
11110
|
group: "run",
|
|
@@ -10752,7 +11147,7 @@ var init_run2 = __esm({
|
|
|
10752
11147
|
});
|
|
10753
11148
|
|
|
10754
11149
|
// src/commands/shell.ts
|
|
10755
|
-
import { defineCommand as
|
|
11150
|
+
import { defineCommand as defineCommand27 } from "citty";
|
|
10756
11151
|
import { consola as consola32 } from "consola";
|
|
10757
11152
|
var shellCommand;
|
|
10758
11153
|
var init_shell2 = __esm({
|
|
@@ -10760,7 +11155,7 @@ var init_shell2 = __esm({
|
|
|
10760
11155
|
"use strict";
|
|
10761
11156
|
init_paths();
|
|
10762
11157
|
init_shell();
|
|
10763
|
-
shellCommand =
|
|
11158
|
+
shellCommand = defineCommand27({
|
|
10764
11159
|
meta: {
|
|
10765
11160
|
name: "shell",
|
|
10766
11161
|
group: "run",
|
|
@@ -10790,7 +11185,7 @@ var init_shell2 = __esm({
|
|
|
10790
11185
|
});
|
|
10791
11186
|
|
|
10792
11187
|
// src/commands/start.ts
|
|
10793
|
-
import { defineCommand as
|
|
11188
|
+
import { defineCommand as defineCommand28 } from "citty";
|
|
10794
11189
|
import { consola as consola33 } from "consola";
|
|
10795
11190
|
var startCommand;
|
|
10796
11191
|
var init_start = __esm({
|
|
@@ -10800,11 +11195,12 @@ var init_start = __esm({
|
|
|
10800
11195
|
init_io();
|
|
10801
11196
|
init_paths();
|
|
10802
11197
|
init_compose();
|
|
11198
|
+
init_catalog();
|
|
10803
11199
|
init_open();
|
|
10804
11200
|
init_proxy();
|
|
10805
11201
|
init_port_check();
|
|
10806
11202
|
init_dispatch();
|
|
10807
|
-
startCommand =
|
|
11203
|
+
startCommand = defineCommand28({
|
|
10808
11204
|
meta: {
|
|
10809
11205
|
name: "start",
|
|
10810
11206
|
group: "run",
|
|
@@ -10825,6 +11221,7 @@ var init_start = __esm({
|
|
|
10825
11221
|
return dispatch(async () => {
|
|
10826
11222
|
let needsProxy = false;
|
|
10827
11223
|
let hostPort = 80;
|
|
11224
|
+
let deferred = [];
|
|
10828
11225
|
try {
|
|
10829
11226
|
const parsed = await readConfig(containerConfigPath(args.name));
|
|
10830
11227
|
if ((parsed.config.routing?.ports ?? []).length > 0) {
|
|
@@ -10832,6 +11229,7 @@ var init_start = __esm({
|
|
|
10832
11229
|
const global = await readMonocerosConfig();
|
|
10833
11230
|
hostPort = proxyHostPort(global);
|
|
10834
11231
|
}
|
|
11232
|
+
deferred = (parsed.config.services ?? []).filter((s) => serviceDefersStart(s.name)).map((s) => s.name);
|
|
10835
11233
|
} catch (err) {
|
|
10836
11234
|
consola33.warn(
|
|
10837
11235
|
`Could not read container yml ahead of start: ${err instanceof Error ? err.message : String(err)}. Skipping Traefik pre-flight.`
|
|
@@ -10842,6 +11240,24 @@ var init_start = __esm({
|
|
|
10842
11240
|
await ensureProxy({ hostPort });
|
|
10843
11241
|
}
|
|
10844
11242
|
const exitCode = await runStart({ root: containerDir(args.name) });
|
|
11243
|
+
if (exitCode === 0 && deferred.length > 0) {
|
|
11244
|
+
try {
|
|
11245
|
+
const deferExit = await startDeferredServices({
|
|
11246
|
+
root: containerDir(args.name),
|
|
11247
|
+
services: deferred,
|
|
11248
|
+
logger: consola33
|
|
11249
|
+
});
|
|
11250
|
+
if (deferExit !== 0) {
|
|
11251
|
+
consola33.warn(
|
|
11252
|
+
`Deferred service(s) ${deferred.join(", ")} did not start cleanly (exit ${deferExit}).`
|
|
11253
|
+
);
|
|
11254
|
+
}
|
|
11255
|
+
} catch (err) {
|
|
11256
|
+
consola33.warn(
|
|
11257
|
+
`Could not start deferred service(s) ${deferred.join(", ")}: ${err instanceof Error ? err.message : String(err)}`
|
|
11258
|
+
);
|
|
11259
|
+
}
|
|
11260
|
+
}
|
|
10845
11261
|
if (args.open && exitCode === 0) {
|
|
10846
11262
|
try {
|
|
10847
11263
|
await runOpen({ name: args.name, tool: args.open });
|
|
@@ -10857,7 +11273,7 @@ var init_start = __esm({
|
|
|
10857
11273
|
});
|
|
10858
11274
|
|
|
10859
11275
|
// src/commands/status.ts
|
|
10860
|
-
import { defineCommand as
|
|
11276
|
+
import { defineCommand as defineCommand29 } from "citty";
|
|
10861
11277
|
var statusCommand;
|
|
10862
11278
|
var init_status = __esm({
|
|
10863
11279
|
"src/commands/status.ts"() {
|
|
@@ -10865,7 +11281,7 @@ var init_status = __esm({
|
|
|
10865
11281
|
init_paths();
|
|
10866
11282
|
init_compose();
|
|
10867
11283
|
init_dispatch();
|
|
10868
|
-
statusCommand =
|
|
11284
|
+
statusCommand = defineCommand29({
|
|
10869
11285
|
meta: {
|
|
10870
11286
|
name: "status",
|
|
10871
11287
|
group: "run",
|
|
@@ -10895,7 +11311,7 @@ var init_status = __esm({
|
|
|
10895
11311
|
});
|
|
10896
11312
|
|
|
10897
11313
|
// src/commands/stop.ts
|
|
10898
|
-
import { defineCommand as
|
|
11314
|
+
import { defineCommand as defineCommand30 } from "citty";
|
|
10899
11315
|
import { consola as consola34 } from "consola";
|
|
10900
11316
|
var stopCommand;
|
|
10901
11317
|
var init_stop = __esm({
|
|
@@ -10905,7 +11321,7 @@ var init_stop = __esm({
|
|
|
10905
11321
|
init_compose();
|
|
10906
11322
|
init_proxy();
|
|
10907
11323
|
init_dispatch();
|
|
10908
|
-
stopCommand =
|
|
11324
|
+
stopCommand = defineCommand30({
|
|
10909
11325
|
meta: {
|
|
10910
11326
|
name: "stop",
|
|
10911
11327
|
group: "run",
|
|
@@ -11198,7 +11614,7 @@ var init_port_check2 = __esm({
|
|
|
11198
11614
|
});
|
|
11199
11615
|
|
|
11200
11616
|
// src/tunnel/run.ts
|
|
11201
|
-
import { spawn as
|
|
11617
|
+
import { spawn as spawn13 } from "child_process";
|
|
11202
11618
|
import { consola as consola35 } from "consola";
|
|
11203
11619
|
function signalNumber(signal) {
|
|
11204
11620
|
switch (signal) {
|
|
@@ -11288,7 +11704,7 @@ var init_run3 = __esm({
|
|
|
11288
11704
|
init_port_check2();
|
|
11289
11705
|
SOCAT_IMAGE = "alpine/socat:1.8.0.3";
|
|
11290
11706
|
defaultDockerSpawn = (args) => {
|
|
11291
|
-
const child =
|
|
11707
|
+
const child = spawn13("docker", args, {
|
|
11292
11708
|
stdio: "inherit"
|
|
11293
11709
|
});
|
|
11294
11710
|
const exited = new Promise((resolve, reject) => {
|
|
@@ -11319,7 +11735,7 @@ var init_run3 = __esm({
|
|
|
11319
11735
|
});
|
|
11320
11736
|
|
|
11321
11737
|
// src/commands/tunnel.ts
|
|
11322
|
-
import { defineCommand as
|
|
11738
|
+
import { defineCommand as defineCommand31 } from "citty";
|
|
11323
11739
|
import { consola as consola36 } from "consola";
|
|
11324
11740
|
function parseLocalPort(raw) {
|
|
11325
11741
|
if (raw === void 0) return void 0;
|
|
@@ -11336,7 +11752,7 @@ var init_tunnel = __esm({
|
|
|
11336
11752
|
"src/commands/tunnel.ts"() {
|
|
11337
11753
|
"use strict";
|
|
11338
11754
|
init_run3();
|
|
11339
|
-
tunnelCommand =
|
|
11755
|
+
tunnelCommand = defineCommand31({
|
|
11340
11756
|
meta: {
|
|
11341
11757
|
name: "tunnel",
|
|
11342
11758
|
group: "discovery",
|
|
@@ -11628,7 +12044,7 @@ var init_upgrade = __esm({
|
|
|
11628
12044
|
});
|
|
11629
12045
|
|
|
11630
12046
|
// src/commands/upgrade.ts
|
|
11631
|
-
import { defineCommand as
|
|
12047
|
+
import { defineCommand as defineCommand32 } from "citty";
|
|
11632
12048
|
var upgradeCommand;
|
|
11633
12049
|
var init_upgrade2 = __esm({
|
|
11634
12050
|
"src/commands/upgrade.ts"() {
|
|
@@ -11636,7 +12052,7 @@ var init_upgrade2 = __esm({
|
|
|
11636
12052
|
init_upgrade();
|
|
11637
12053
|
init_version();
|
|
11638
12054
|
init_dispatch();
|
|
11639
|
-
upgradeCommand =
|
|
12055
|
+
upgradeCommand = defineCommand32({
|
|
11640
12056
|
meta: {
|
|
11641
12057
|
name: "upgrade",
|
|
11642
12058
|
group: "lifecycle",
|
|
@@ -11678,7 +12094,7 @@ var main_exports = {};
|
|
|
11678
12094
|
__export(main_exports, {
|
|
11679
12095
|
main: () => main
|
|
11680
12096
|
});
|
|
11681
|
-
import { defineCommand as
|
|
12097
|
+
import { defineCommand as defineCommand33 } from "citty";
|
|
11682
12098
|
var main;
|
|
11683
12099
|
var init_main = __esm({
|
|
11684
12100
|
"src/main.ts"() {
|
|
@@ -11693,6 +12109,7 @@ var init_main = __esm({
|
|
|
11693
12109
|
init_apply2();
|
|
11694
12110
|
init_completion();
|
|
11695
12111
|
init_complete();
|
|
12112
|
+
init_update_check();
|
|
11696
12113
|
init_init2();
|
|
11697
12114
|
init_list_components();
|
|
11698
12115
|
init_logs();
|
|
@@ -11715,7 +12132,7 @@ var init_main = __esm({
|
|
|
11715
12132
|
init_tunnel();
|
|
11716
12133
|
init_upgrade2();
|
|
11717
12134
|
init_version();
|
|
11718
|
-
main =
|
|
12135
|
+
main = defineCommand33({
|
|
11719
12136
|
meta: {
|
|
11720
12137
|
name: "monoceros",
|
|
11721
12138
|
version: CLI_VERSION,
|
|
@@ -11752,7 +12169,8 @@ var init_main = __esm({
|
|
|
11752
12169
|
port: portCommand,
|
|
11753
12170
|
tunnel: tunnelCommand,
|
|
11754
12171
|
completion: completionCommand,
|
|
11755
|
-
__complete: __completeCommand
|
|
12172
|
+
__complete: __completeCommand,
|
|
12173
|
+
"__update-check": __updateCheckCommand
|
|
11756
12174
|
}
|
|
11757
12175
|
});
|
|
11758
12176
|
}
|
|
@@ -12042,9 +12460,15 @@ async function maybeRenderHelp(argv, main2) {
|
|
|
12042
12460
|
// src/bin.ts
|
|
12043
12461
|
init_inner_args();
|
|
12044
12462
|
init_main();
|
|
12463
|
+
init_notifier();
|
|
12464
|
+
init_version();
|
|
12045
12465
|
bootstrapDockerGroup();
|
|
12046
12466
|
consumeInnerArgsFromProcessArgv();
|
|
12047
12467
|
async function entry() {
|
|
12468
|
+
scheduleUpdateNotice({
|
|
12469
|
+
currentVersion: CLI_VERSION,
|
|
12470
|
+
commandName: process.argv.slice(2).find((a) => !a.startsWith("-"))
|
|
12471
|
+
});
|
|
12048
12472
|
if (await maybeRenderHelp(process.argv.slice(2), main)) {
|
|
12049
12473
|
return;
|
|
12050
12474
|
}
|