@getmonoceros/workbench 1.22.2 → 1.23.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/dist/bin.js CHANGED
@@ -2457,9 +2457,156 @@ var init_claude_settings = __esm({
2457
2457
  }
2458
2458
  });
2459
2459
 
2460
- // src/create/scaffold.ts
2461
- import { existsSync as existsSync6, promises as fs7 } from "fs";
2460
+ // src/create/opencode-config.ts
2461
+ import { existsSync as existsSync6, promises as fsp3 } from "fs";
2462
2462
  import path9 from "path";
2463
+ import { consola } from "consola";
2464
+ function parseOpencodeModel(model) {
2465
+ const idx = model.indexOf("/");
2466
+ if (idx <= 0 || idx === model.length - 1) return void 0;
2467
+ return { provider: model.slice(0, idx), modelId: model.slice(idx + 1) };
2468
+ }
2469
+ async function writeOpencodeConfig(targetDir, containerName2, features) {
2470
+ if (!features) return;
2471
+ const entry2 = Object.entries(features).find(
2472
+ ([ref]) => matchMonocerosFeature(ref)?.name === "opencode"
2473
+ );
2474
+ if (!entry2) return;
2475
+ const options = entry2[1] ?? {};
2476
+ const str = (key) => typeof options[key] === "string" ? options[key].trim() : "";
2477
+ const model = str("model");
2478
+ const apiToken = str("apiToken");
2479
+ const npm = str("npm");
2480
+ const baseUrl = str("baseUrl");
2481
+ const file = path9.join(
2482
+ targetDir,
2483
+ "home",
2484
+ ".config",
2485
+ "opencode",
2486
+ "opencode.json"
2487
+ );
2488
+ await fsp3.mkdir(path9.dirname(file), { recursive: true });
2489
+ let config = {};
2490
+ if (existsSync6(file)) {
2491
+ try {
2492
+ const txt = await fsp3.readFile(file, "utf8");
2493
+ if (txt.trim()) {
2494
+ const parsed2 = JSON.parse(txt);
2495
+ if (typeof parsed2 === "object" && parsed2 !== null) {
2496
+ config = parsed2;
2497
+ }
2498
+ }
2499
+ } catch {
2500
+ config = {};
2501
+ }
2502
+ }
2503
+ if (typeof config.$schema !== "string") {
2504
+ config.$schema = "https://opencode.ai/config.json";
2505
+ }
2506
+ const workspaceRoot = `/workspaces/${containerName2}`;
2507
+ const managedInstructions = [
2508
+ `${workspaceRoot}/AGENTS.md`,
2509
+ `${workspaceRoot}/.monoceros/commands.md`
2510
+ ];
2511
+ const existingInstructions = Array.isArray(config.instructions) ? config.instructions.filter(
2512
+ (i) => typeof i === "string"
2513
+ ) : [];
2514
+ config.instructions = [
2515
+ ...managedInstructions,
2516
+ ...existingInstructions.filter((i) => !managedInstructions.includes(i))
2517
+ ];
2518
+ if (model) {
2519
+ config.model = model;
2520
+ }
2521
+ const parsed = parseOpencodeModel(model);
2522
+ if (npm) {
2523
+ if (!parsed) {
2524
+ consola.warn(
2525
+ "[opencode] `npm` is set but `model` is empty or has no provider prefix \u2014 set `model: <provider>/<model-id>` to configure a custom provider."
2526
+ );
2527
+ } else {
2528
+ writeCustomProvider(config, parsed, { npm, baseUrl, apiToken });
2529
+ }
2530
+ } else if (parsed) {
2531
+ if (KNOWN_APIKEY_PROVIDERS.includes(parsed.provider)) {
2532
+ if (apiToken) {
2533
+ writeHostedApiKey(config, parsed.provider, apiToken);
2534
+ }
2535
+ } else {
2536
+ consola.warn(
2537
+ `[opencode] '${parsed.provider}' is not a known single-key provider (${KNOWN_APIKEY_PROVIDERS.join(", ")}). For a custom or local provider (e.g. Ollama), set the \`npm\` and \`baseUrl\` options on the opencode feature.`
2538
+ );
2539
+ }
2540
+ }
2541
+ await fsp3.writeFile(file, `${JSON.stringify(config, null, 2)}
2542
+ `);
2543
+ }
2544
+ function providersOf(config) {
2545
+ if (typeof config.provider === "object" && config.provider !== null) {
2546
+ return config.provider;
2547
+ }
2548
+ const fresh = {};
2549
+ config.provider = fresh;
2550
+ return fresh;
2551
+ }
2552
+ function providerEntry(providers, id) {
2553
+ if (typeof providers[id] === "object" && providers[id] !== null) {
2554
+ return providers[id];
2555
+ }
2556
+ const fresh = {};
2557
+ providers[id] = fresh;
2558
+ return fresh;
2559
+ }
2560
+ function optionsOf(entry2) {
2561
+ if (typeof entry2.options === "object" && entry2.options !== null) {
2562
+ return entry2.options;
2563
+ }
2564
+ const fresh = {};
2565
+ entry2.options = fresh;
2566
+ return fresh;
2567
+ }
2568
+ function writeHostedApiKey(config, provider, apiToken) {
2569
+ const entry2 = providerEntry(providersOf(config), provider);
2570
+ optionsOf(entry2).apiKey = apiToken;
2571
+ }
2572
+ function writeCustomProvider(config, parsed, {
2573
+ npm,
2574
+ baseUrl,
2575
+ apiToken
2576
+ }) {
2577
+ const entry2 = providerEntry(providersOf(config), parsed.provider);
2578
+ entry2.npm = npm;
2579
+ if (typeof entry2.name !== "string") entry2.name = parsed.provider;
2580
+ const opts = optionsOf(entry2);
2581
+ if (baseUrl) opts.baseURL = baseUrl;
2582
+ if (apiToken) opts.apiKey = apiToken;
2583
+ const models = typeof entry2.models === "object" && entry2.models !== null ? entry2.models : {};
2584
+ if (models[parsed.modelId] === void 0) {
2585
+ models[parsed.modelId] = { name: parsed.modelId };
2586
+ }
2587
+ entry2.models = models;
2588
+ }
2589
+ var KNOWN_APIKEY_PROVIDERS;
2590
+ var init_opencode_config = __esm({
2591
+ "src/create/opencode-config.ts"() {
2592
+ "use strict";
2593
+ init_ref();
2594
+ KNOWN_APIKEY_PROVIDERS = [
2595
+ "anthropic",
2596
+ "openai",
2597
+ "google",
2598
+ "openrouter",
2599
+ "mistral",
2600
+ "groq",
2601
+ "deepseek",
2602
+ "xai"
2603
+ ];
2604
+ }
2605
+ });
2606
+
2607
+ // src/create/scaffold.ts
2608
+ import { existsSync as existsSync7, promises as fs7 } from "fs";
2609
+ import path10 from "path";
2463
2610
  function deriveRepoName(url) {
2464
2611
  const lastSep = Math.max(url.lastIndexOf("/"), url.lastIndexOf(":"));
2465
2612
  const tail = url.slice(lastSep + 1);
@@ -2590,7 +2737,7 @@ function featuresSourceRoot() {
2590
2737
  const override2 = process.env.MONOCEROS_FEATURES_DIR_OVERRIDE?.trim();
2591
2738
  if (override2 && override2.length > 0) return override2;
2592
2739
  const checkout = workbenchCheckoutRoot();
2593
- return checkout ? path9.join(checkout, "components", "features") : null;
2740
+ return checkout ? path10.join(checkout, "components", "features") : null;
2594
2741
  }
2595
2742
  function resolveFeatures(opts) {
2596
2743
  const resolved = [];
@@ -2630,8 +2777,8 @@ function resolveFeatures(opts) {
2630
2777
  const descriptor = featureDescriptor(name);
2631
2778
  const { paths, files } = descriptorPersistentHome(descriptor);
2632
2779
  const sourceRoot = featuresSourceRoot();
2633
- const localSourceDir = sourceRoot ? path9.join(sourceRoot, name) : null;
2634
- if (descriptor && localSourceDir && existsSync6(localSourceDir)) {
2780
+ const localSourceDir = sourceRoot ? path10.join(sourceRoot, name) : null;
2781
+ if (descriptor && localSourceDir && existsSync7(localSourceDir)) {
2635
2782
  resolved.push({
2636
2783
  devcontainerKey: `./features/${name}`,
2637
2784
  options,
@@ -3076,7 +3223,7 @@ function buildPostCreateScript(opts) {
3076
3223
  return lines.join("\n") + "\n";
3077
3224
  }
3078
3225
  async function writePostCreateScript(devcontainerDir, opts) {
3079
- const dest = path9.join(devcontainerDir, "post-create.sh");
3226
+ const dest = path10.join(devcontainerDir, "post-create.sh");
3080
3227
  await fs7.writeFile(dest, buildPostCreateScript(opts));
3081
3228
  await fs7.chmod(dest, 493);
3082
3229
  }
@@ -3090,11 +3237,11 @@ async function writeIfChanged(filePath, content) {
3090
3237
  }
3091
3238
  async function writeScaffold(opts, targetDir, scaffoldOpts = {}) {
3092
3239
  const dockerMode = scaffoldOpts.dockerMode ?? "rootful";
3093
- const devcontainerDir = path9.join(targetDir, ".devcontainer");
3094
- const monocerosDir = path9.join(targetDir, ".monoceros");
3095
- const projectsDir = path9.join(targetDir, "projects");
3096
- const homeDir = path9.join(targetDir, "home");
3097
- const dataDir = path9.join(targetDir, "data");
3240
+ const devcontainerDir = path10.join(targetDir, ".devcontainer");
3241
+ const monocerosDir = path10.join(targetDir, ".monoceros");
3242
+ const projectsDir = path10.join(targetDir, "projects");
3243
+ const homeDir = path10.join(targetDir, "home");
3244
+ const dataDir = path10.join(targetDir, "data");
3098
3245
  await fs7.mkdir(devcontainerDir, { recursive: true });
3099
3246
  await fs7.mkdir(monocerosDir, { recursive: true });
3100
3247
  await fs7.mkdir(projectsDir, { recursive: true });
@@ -3104,36 +3251,36 @@ async function writeScaffold(opts, targetDir, scaffoldOpts = {}) {
3104
3251
  for (const svc of opts.services) {
3105
3252
  const hasDataVolume = svc.volumes.some((v) => v.split(":")[0] === "data");
3106
3253
  if (hasDataVolume) {
3107
- await fs7.mkdir(path9.join(dataDir, svc.name), { recursive: true });
3254
+ await fs7.mkdir(path10.join(dataDir, svc.name), { recursive: true });
3108
3255
  }
3109
3256
  }
3110
3257
  }
3111
- const containerGitignore = path9.join(targetDir, ".gitignore");
3258
+ const containerGitignore = path10.join(targetDir, ".gitignore");
3112
3259
  await fs7.writeFile(
3113
3260
  containerGitignore,
3114
3261
  "/home/\n/.monoceros/\n/data/\n/AGENTS.md\n/CLAUDE.md\n"
3115
3262
  );
3116
- const gitkeep = path9.join(projectsDir, ".gitkeep");
3117
- if (!existsSync6(gitkeep)) {
3263
+ const gitkeep = path10.join(projectsDir, ".gitkeep");
3264
+ if (!existsSync7(gitkeep)) {
3118
3265
  await fs7.writeFile(gitkeep, "");
3119
3266
  }
3120
3267
  await fs7.writeFile(
3121
- path9.join(monocerosDir, ".gitignore"),
3268
+ path10.join(monocerosDir, ".gitignore"),
3122
3269
  "git-credentials*\ngitconfig\n"
3123
3270
  );
3124
3271
  const devcontainerJson = buildDevcontainerJson(opts, dockerMode);
3125
3272
  await writeIfChanged(
3126
- path9.join(devcontainerDir, "devcontainer.json"),
3273
+ path10.join(devcontainerDir, "devcontainer.json"),
3127
3274
  JSON.stringify(devcontainerJson, null, 2) + "\n"
3128
3275
  );
3129
- const featuresDir = path9.join(devcontainerDir, "features");
3130
- if (existsSync6(featuresDir)) {
3276
+ const featuresDir = path10.join(devcontainerDir, "features");
3277
+ if (existsSync7(featuresDir)) {
3131
3278
  await fs7.rm(featuresDir, { recursive: true, force: true });
3132
3279
  }
3133
3280
  const resolvedFeatures = resolveFeatures(opts);
3134
3281
  for (const f of resolvedFeatures) {
3135
3282
  if (!f.localSourceDir || !f.localName) continue;
3136
- const dest = path9.join(featuresDir, f.localName);
3283
+ const dest = path10.join(featuresDir, f.localName);
3137
3284
  await fs7.mkdir(dest, { recursive: true });
3138
3285
  const entries = await fs7.readdir(f.localSourceDir, { withFileTypes: true });
3139
3286
  for (const entry2 of entries) {
@@ -3142,38 +3289,39 @@ async function writeScaffold(opts, targetDir, scaffoldOpts = {}) {
3142
3289
  continue;
3143
3290
  }
3144
3291
  await fs7.cp(
3145
- path9.join(f.localSourceDir, entry2.name),
3146
- path9.join(dest, entry2.name)
3292
+ path10.join(f.localSourceDir, entry2.name),
3293
+ path10.join(dest, entry2.name)
3147
3294
  );
3148
3295
  }
3149
3296
  if (f.generatedManifest) {
3150
3297
  await fs7.writeFile(
3151
- path9.join(dest, "devcontainer-feature.json"),
3298
+ path10.join(dest, "devcontainer-feature.json"),
3152
3299
  JSON.stringify(f.generatedManifest, null, 2) + "\n"
3153
3300
  );
3154
3301
  }
3155
3302
  }
3156
3303
  for (const f of resolvedFeatures) {
3157
3304
  for (const sub of f.persistentHomePaths) {
3158
- await fs7.mkdir(path9.join(homeDir, sub), { recursive: true });
3305
+ await fs7.mkdir(path10.join(homeDir, sub), { recursive: true });
3159
3306
  }
3160
3307
  for (const entry2 of f.persistentHomeFiles) {
3161
- const filePath = path9.join(homeDir, entry2.path);
3162
- await fs7.mkdir(path9.dirname(filePath), { recursive: true });
3163
- if (!existsSync6(filePath)) {
3308
+ const filePath = path10.join(homeDir, entry2.path);
3309
+ await fs7.mkdir(path10.dirname(filePath), { recursive: true });
3310
+ if (!existsSync7(filePath)) {
3164
3311
  await fs7.writeFile(filePath, entry2.initialContent);
3165
3312
  }
3166
3313
  }
3167
3314
  }
3168
3315
  await writeClaudePermissionMode(targetDir, opts.features);
3316
+ await writeOpencodeConfig(targetDir, opts.name, opts.features);
3169
3317
  await writePostCreateScript(devcontainerDir, opts);
3170
- const composePath = path9.join(devcontainerDir, "compose.yaml");
3318
+ const composePath = path10.join(devcontainerDir, "compose.yaml");
3171
3319
  if (needsCompose(opts)) {
3172
3320
  await writeIfChanged(composePath, buildComposeYaml(opts, dockerMode));
3173
- } else if (existsSync6(composePath)) {
3321
+ } else if (existsSync7(composePath)) {
3174
3322
  await fs7.rm(composePath);
3175
3323
  }
3176
- const workspacePath = path9.join(targetDir, `${opts.name}.code-workspace`);
3324
+ const workspacePath = path10.join(targetDir, `${opts.name}.code-workspace`);
3177
3325
  let existingWorkspace;
3178
3326
  try {
3179
3327
  const raw = await fs7.readFile(workspacePath, "utf8");
@@ -3184,8 +3332,8 @@ async function writeScaffold(opts, targetDir, scaffoldOpts = {}) {
3184
3332
  const generated = buildCodeWorkspaceJson(opts);
3185
3333
  const merged = mergeCodeWorkspace(existingWorkspace, generated);
3186
3334
  await fs7.writeFile(workspacePath, JSON.stringify(merged, null, 2) + "\n");
3187
- const vscodeDir = path9.join(targetDir, ".vscode");
3188
- const settingsPath = path9.join(vscodeDir, "settings.json");
3335
+ const vscodeDir = path10.join(targetDir, ".vscode");
3336
+ const settingsPath = path10.join(vscodeDir, "settings.json");
3189
3337
  let existingSettings;
3190
3338
  try {
3191
3339
  existingSettings = JSON.parse(await fs7.readFile(settingsPath, "utf8"));
@@ -3207,6 +3355,7 @@ var init_scaffold = __esm({
3207
3355
  init_load_sync();
3208
3356
  init_generate_manifest();
3209
3357
  init_claude_settings();
3358
+ init_opencode_config();
3210
3359
  init_catalog();
3211
3360
  APT_PACKAGE_NAME_RE2 = /^[a-z0-9][a-z0-9.+-]*$/;
3212
3361
  FEATURE_REF_RE2 = /^[a-z0-9.-]+(\/[a-z0-9._-]+)+:[a-z0-9._-]+$/;
@@ -3660,8 +3809,8 @@ function removeRepoFromDoc(doc, urlOrPath) {
3660
3809
  if (!isMap2(item)) return false;
3661
3810
  const url = item.get("url");
3662
3811
  if (url === urlOrPath) return true;
3663
- const path27 = item.get("path");
3664
- const effectivePath = typeof path27 === "string" ? path27 : typeof url === "string" ? deriveRepoName(url) : void 0;
3812
+ const path28 = item.get("path");
3813
+ const effectivePath = typeof path28 === "string" ? path28 : typeof url === "string" ? deriveRepoName(url) : void 0;
3665
3814
  return effectivePath === urlOrPath;
3666
3815
  });
3667
3816
  if (idx < 0) return false;
@@ -3696,9 +3845,9 @@ var init_yml = __esm({
3696
3845
 
3697
3846
  // src/modify/index.ts
3698
3847
  import { promises as fs8 } from "fs";
3699
- import { consola } from "consola";
3848
+ import { consola as consola2 } from "consola";
3700
3849
  import { createPatch } from "diff";
3701
- import path10 from "path";
3850
+ import path11 from "path";
3702
3851
  function runAddLanguage(input) {
3703
3852
  const spec = parseLanguageSpec(input.language);
3704
3853
  if (!spec || !BUILTIN_LANGUAGES.has(spec.name) && !LANGUAGE_CATALOG[spec.name]) {
@@ -3783,7 +3932,7 @@ async function runAddRepo(input) {
3783
3932
  "Missing repo URL. Usage: monoceros add-repo <containername> <url>."
3784
3933
  );
3785
3934
  }
3786
- const path27 = (input.path ?? deriveRepoName(url)).trim();
3935
+ const path28 = (input.path ?? deriveRepoName(url)).trim();
3787
3936
  const hasName = typeof input.gitName === "string" && input.gitName.trim().length > 0;
3788
3937
  const hasEmail = typeof input.gitEmail === "string" && input.gitEmail.trim().length > 0;
3789
3938
  if (hasName !== hasEmail) {
@@ -3820,7 +3969,7 @@ async function runAddRepo(input) {
3820
3969
  const providerToWrite = !canonical && explicitProvider ? explicitProvider : void 0;
3821
3970
  const entry2 = {
3822
3971
  url,
3823
- path: path27,
3972
+ path: path28,
3824
3973
  ...hasName && hasEmail ? {
3825
3974
  gitUser: {
3826
3975
  name: input.gitName.trim(),
@@ -3952,7 +4101,7 @@ async function tryCloneInRunningContainer(input, entry2) {
3952
4101
  logger.info(
3953
4102
  `Cloned ${entry2.url} into /workspaces/${containerName2}/${targetRel} inside the running container.`
3954
4103
  );
3955
- void path10;
4104
+ void path11;
3956
4105
  }
3957
4106
  function shquote(value) {
3958
4107
  return `'${value.replace(/'/g, `'\\''`)}'`;
@@ -4194,9 +4343,9 @@ async function mutate(opts, apply) {
4194
4343
  }
4195
4344
  function defaultLogger() {
4196
4345
  return {
4197
- info: (m) => consola.info(m),
4198
- success: (m) => consola.success(m),
4199
- warn: (m) => consola.warn(m)
4346
+ info: (m) => consola2.info(m),
4347
+ success: (m) => consola2.success(m),
4348
+ warn: (m) => consola2.warn(m)
4200
4349
  };
4201
4350
  }
4202
4351
  async function syncPortsToProxy(input) {
@@ -4276,7 +4425,7 @@ var init_modify = __esm({
4276
4425
  init_scaffold();
4277
4426
  init_yml();
4278
4427
  defaultConfirm = async (message) => {
4279
- const result = await consola.prompt(message, {
4428
+ const result = await consola2.prompt(message, {
4280
4429
  type: "confirm",
4281
4430
  initial: false
4282
4431
  });
@@ -4287,7 +4436,7 @@ var init_modify = __esm({
4287
4436
 
4288
4437
  // src/commands/add-apt-packages.ts
4289
4438
  import { defineCommand } from "citty";
4290
- import { consola as consola2 } from "consola";
4439
+ import { consola as consola3 } from "consola";
4291
4440
  var addAptPackagesCommand;
4292
4441
  var init_add_apt_packages = __esm({
4293
4442
  "src/commands/add-apt-packages.ts"() {
@@ -4316,7 +4465,7 @@ var init_add_apt_packages = __esm({
4316
4465
  async run({ args }) {
4317
4466
  const packages = [...getInnerArgs()];
4318
4467
  if (packages.length === 0) {
4319
- consola2.error(
4468
+ consola3.error(
4320
4469
  "No package names given. Usage: `monoceros add-apt-packages <containername> [--yes] -- <pkg> [<pkg> \u2026]`."
4321
4470
  );
4322
4471
  process.exit(1);
@@ -4329,7 +4478,7 @@ var init_add_apt_packages = __esm({
4329
4478
  });
4330
4479
  process.exit(result.status === "aborted" ? 1 : 0);
4331
4480
  } catch (err) {
4332
- consola2.error(err instanceof Error ? err.message : String(err));
4481
+ consola3.error(err instanceof Error ? err.message : String(err));
4333
4482
  process.exit(1);
4334
4483
  }
4335
4484
  }
@@ -4339,7 +4488,7 @@ var init_add_apt_packages = __esm({
4339
4488
 
4340
4489
  // src/commands/add-feature.ts
4341
4490
  import { defineCommand as defineCommand2 } from "citty";
4342
- import { consola as consola3 } from "consola";
4491
+ import { consola as consola4 } from "consola";
4343
4492
  function parseOptionsAfterDashes(tokens) {
4344
4493
  const result = {};
4345
4494
  for (const token of tokens) {
@@ -4399,7 +4548,7 @@ var init_add_feature = __esm({
4399
4548
  try {
4400
4549
  options = parseOptionsAfterDashes(getInnerArgs());
4401
4550
  } catch (err) {
4402
- consola3.error(err instanceof Error ? err.message : String(err));
4551
+ consola4.error(err instanceof Error ? err.message : String(err));
4403
4552
  process.exit(1);
4404
4553
  }
4405
4554
  try {
@@ -4411,7 +4560,7 @@ var init_add_feature = __esm({
4411
4560
  });
4412
4561
  process.exit(result.status === "aborted" ? 1 : 0);
4413
4562
  } catch (err) {
4414
- consola3.error(err instanceof Error ? err.message : String(err));
4563
+ consola4.error(err instanceof Error ? err.message : String(err));
4415
4564
  process.exit(1);
4416
4565
  }
4417
4566
  }
@@ -4421,7 +4570,7 @@ var init_add_feature = __esm({
4421
4570
 
4422
4571
  // src/commands/add-from-url.ts
4423
4572
  import { defineCommand as defineCommand3 } from "citty";
4424
- import { consola as consola4 } from "consola";
4573
+ import { consola as consola5 } from "consola";
4425
4574
  function printSecurityWarning(url) {
4426
4575
  const w = (line) => process.stderr.write(line + "\n");
4427
4576
  w("");
@@ -4490,7 +4639,7 @@ var init_add_from_url = __esm({
4490
4639
  });
4491
4640
  process.exit(result.status === "aborted" ? 1 : 0);
4492
4641
  } catch (err) {
4493
- consola4.error(err instanceof Error ? err.message : String(err));
4642
+ consola5.error(err instanceof Error ? err.message : String(err));
4494
4643
  process.exit(1);
4495
4644
  }
4496
4645
  }
@@ -4500,7 +4649,7 @@ var init_add_from_url = __esm({
4500
4649
 
4501
4650
  // src/commands/add-repo.ts
4502
4651
  import { defineCommand as defineCommand4 } from "citty";
4503
- import { consola as consola5 } from "consola";
4652
+ import { consola as consola6 } from "consola";
4504
4653
  var addRepoCommand;
4505
4654
  var init_add_repo = __esm({
4506
4655
  "src/commands/add-repo.ts"() {
@@ -4559,7 +4708,7 @@ var init_add_repo = __esm({
4559
4708
  });
4560
4709
  process.exit(result.status === "aborted" ? 1 : 0);
4561
4710
  } catch (err) {
4562
- consola5.error(err instanceof Error ? err.message : String(err));
4711
+ consola6.error(err instanceof Error ? err.message : String(err));
4563
4712
  process.exit(1);
4564
4713
  }
4565
4714
  }
@@ -4569,7 +4718,7 @@ var init_add_repo = __esm({
4569
4718
 
4570
4719
  // src/commands/add-language.ts
4571
4720
  import { defineCommand as defineCommand5 } from "citty";
4572
- import { consola as consola6 } from "consola";
4721
+ import { consola as consola7 } from "consola";
4573
4722
  var addLanguageCommand;
4574
4723
  var init_add_language = __esm({
4575
4724
  "src/commands/add-language.ts"() {
@@ -4608,7 +4757,7 @@ var init_add_language = __esm({
4608
4757
  });
4609
4758
  process.exit(result.status === "aborted" ? 1 : 0);
4610
4759
  } catch (err) {
4611
- consola6.error(err instanceof Error ? err.message : String(err));
4760
+ consola7.error(err instanceof Error ? err.message : String(err));
4612
4761
  process.exit(1);
4613
4762
  }
4614
4763
  }
@@ -4618,7 +4767,7 @@ var init_add_language = __esm({
4618
4767
 
4619
4768
  // src/commands/add-port.ts
4620
4769
  import { defineCommand as defineCommand6 } from "citty";
4621
- import { consola as consola7 } from "consola";
4770
+ import { consola as consola8 } from "consola";
4622
4771
  function coerceToken(raw) {
4623
4772
  const n = Number(raw);
4624
4773
  return Number.isFinite(n) ? n : raw;
@@ -4656,7 +4805,7 @@ var init_add_port = __esm({
4656
4805
  async run({ args }) {
4657
4806
  const tokens = [...getInnerArgs()];
4658
4807
  if (tokens.length === 0) {
4659
- consola7.error(
4808
+ consola8.error(
4660
4809
  "No ports given. Usage: `monoceros add-port <containername> [--yes] [--default] -- <port> [<port> \u2026]`."
4661
4810
  );
4662
4811
  process.exit(1);
@@ -4670,7 +4819,7 @@ var init_add_port = __esm({
4670
4819
  });
4671
4820
  process.exit(result.status === "aborted" ? 1 : 0);
4672
4821
  } catch (err) {
4673
- consola7.error(err instanceof Error ? err.message : String(err));
4822
+ consola8.error(err instanceof Error ? err.message : String(err));
4674
4823
  process.exit(1);
4675
4824
  }
4676
4825
  }
@@ -4680,7 +4829,7 @@ var init_add_port = __esm({
4680
4829
 
4681
4830
  // src/commands/add-service.ts
4682
4831
  import { defineCommand as defineCommand7 } from "citty";
4683
- import { consola as consola8 } from "consola";
4832
+ import { consola as consola9 } from "consola";
4684
4833
  var addServiceCommand;
4685
4834
  var init_add_service = __esm({
4686
4835
  "src/commands/add-service.ts"() {
@@ -4724,7 +4873,7 @@ var init_add_service = __esm({
4724
4873
  });
4725
4874
  process.exit(result.status === "aborted" ? 1 : 0);
4726
4875
  } catch (err) {
4727
- consola8.error(err instanceof Error ? err.message : String(err));
4876
+ consola9.error(err instanceof Error ? err.message : String(err));
4728
4877
  process.exit(1);
4729
4878
  }
4730
4879
  }
@@ -4734,7 +4883,7 @@ var init_add_service = __esm({
4734
4883
 
4735
4884
  // src/config/state.ts
4736
4885
  import { promises as fs9 } from "fs";
4737
- import path11 from "path";
4886
+ import path12 from "path";
4738
4887
  function buildStateFile(opts) {
4739
4888
  return {
4740
4889
  schemaVersion: CONFIG_SCHEMA_VERSION,
@@ -4745,7 +4894,7 @@ function buildStateFile(opts) {
4745
4894
  };
4746
4895
  }
4747
4896
  function stateFilePath(targetDir) {
4748
- return path11.join(targetDir, ".monoceros", "state.json");
4897
+ return path12.join(targetDir, ".monoceros", "state.json");
4749
4898
  }
4750
4899
  async function readStateFile(targetDir) {
4751
4900
  try {
@@ -4756,7 +4905,7 @@ async function readStateFile(targetDir) {
4756
4905
  }
4757
4906
  }
4758
4907
  async function writeStateFile(targetDir, state) {
4759
- const monocerosDir = path11.join(targetDir, ".monoceros");
4908
+ const monocerosDir = path12.join(targetDir, ".monoceros");
4760
4909
  await fs9.mkdir(monocerosDir, { recursive: true });
4761
4910
  await fs9.writeFile(
4762
4911
  stateFilePath(targetDir),
@@ -4868,7 +5017,7 @@ var init_transform = __esm({
4868
5017
 
4869
5018
  // src/apply/apply-log.ts
4870
5019
  import { createWriteStream, mkdirSync } from "fs";
4871
- import path12 from "path";
5020
+ import path13 from "path";
4872
5021
  import { Writable } from "stream";
4873
5022
  function safeIsoStamp(d) {
4874
5023
  return d.toISOString().replace(/[:.]/g, "-");
@@ -4878,7 +5027,7 @@ function createApplyLog(opts) {
4878
5027
  const dir = containerLogsDir(opts.name, opts.home);
4879
5028
  mkdirSync(dir, { recursive: true });
4880
5029
  const file = `apply-${opts.name}-${safeIsoStamp(now)}.log`;
4881
- const fullPath = path12.join(dir, file);
5030
+ const fullPath = path13.join(dir, file);
4882
5031
  const stream = createWriteStream(fullPath, { flags: "w" });
4883
5032
  const header = [
4884
5033
  `# monoceros apply log`,
@@ -5745,7 +5894,7 @@ var init_markers = __esm({
5745
5894
 
5746
5895
  // src/briefing/index.ts
5747
5896
  import { promises as fs10 } from "fs";
5748
- import path13 from "path";
5897
+ import path14 from "path";
5749
5898
  async function writeBriefing(input) {
5750
5899
  const subCommands = input.subCommands ?? await loadSubCommandsDynamic();
5751
5900
  const manifestLoader = input.manifestLoader ?? ((ref) => loadFeatureManifestSummary(ref));
@@ -5758,12 +5907,12 @@ async function writeBriefing(input) {
5758
5907
  );
5759
5908
  const claudeBody = generateClaudeMd();
5760
5909
  const commandsBody = generateCommandsMd(subCommands);
5761
- await writeMarkerAware(path13.join(input.targetDir, "AGENTS.md"), agentsBody);
5762
- await writeMarkerAware(path13.join(input.targetDir, "CLAUDE.md"), claudeBody);
5763
- const monocerosDir = path13.join(input.targetDir, ".monoceros");
5910
+ await writeMarkerAware(path14.join(input.targetDir, "AGENTS.md"), agentsBody);
5911
+ await writeMarkerAware(path14.join(input.targetDir, "CLAUDE.md"), claudeBody);
5912
+ const monocerosDir = path14.join(input.targetDir, ".monoceros");
5764
5913
  await fs10.mkdir(monocerosDir, { recursive: true });
5765
5914
  await fs10.writeFile(
5766
- path13.join(monocerosDir, "commands.md"),
5915
+ path14.join(monocerosDir, "commands.md"),
5767
5916
  commandsBody,
5768
5917
  "utf8"
5769
5918
  );
@@ -5922,7 +6071,7 @@ var init_runtime_pull_hint = __esm({
5922
6071
  import { spawn as spawn4 } from "child_process";
5923
6072
  import { readFileSync as readFileSync4 } from "fs";
5924
6073
  import { createRequire } from "module";
5925
- import path14 from "path";
6074
+ import path15 from "path";
5926
6075
  function devcontainerCliPath() {
5927
6076
  if (cachedBinaryPath) return cachedBinaryPath;
5928
6077
  const pkgJsonPath = require_.resolve("@devcontainers/cli/package.json");
@@ -5931,7 +6080,7 @@ function devcontainerCliPath() {
5931
6080
  if (!binEntry) {
5932
6081
  throw new Error("Could not resolve @devcontainers/cli bin entry.");
5933
6082
  }
5934
- cachedBinaryPath = path14.resolve(path14.dirname(pkgJsonPath), binEntry);
6083
+ cachedBinaryPath = path15.resolve(path15.dirname(pkgJsonPath), binEntry);
5935
6084
  return cachedBinaryPath;
5936
6085
  }
5937
6086
  var require_, cachedBinaryPath, spawnDevcontainer;
@@ -6005,10 +6154,10 @@ var init_cli = __esm({
6005
6154
 
6006
6155
  // src/devcontainer/compose.ts
6007
6156
  import { spawn as spawn5 } from "child_process";
6008
- import { existsSync as existsSync7 } from "fs";
6009
- import path15 from "path";
6157
+ import { existsSync as existsSync8 } from "fs";
6158
+ import path16 from "path";
6010
6159
  import { Writable as Writable3 } from "stream";
6011
- import { consola as consola9 } from "consola";
6160
+ import { consola as consola10 } from "consola";
6012
6161
  async function findContainerIds(filters, exec = spawnDocker) {
6013
6162
  const ids = /* @__PURE__ */ new Set();
6014
6163
  for (const filter of filters) {
@@ -6056,16 +6205,16 @@ async function cleanupDockerObjects(opts) {
6056
6205
  return { exitCode: rmExit, removedIds: ids };
6057
6206
  }
6058
6207
  function composeProjectName(root) {
6059
- return `${path15.basename(root)}_devcontainer`;
6208
+ return `${path16.basename(root)}_devcontainer`;
6060
6209
  }
6061
6210
  function resolveCompose(root) {
6062
- if (!existsSync7(path15.join(root, ".devcontainer"))) {
6211
+ if (!existsSync8(path16.join(root, ".devcontainer"))) {
6063
6212
  throw new Error(
6064
6213
  `No .devcontainer/ at ${root}. Run \`monoceros apply <name>\` first.`
6065
6214
  );
6066
6215
  }
6067
- const composeFile = path15.join(root, ".devcontainer", "compose.yaml");
6068
- if (!existsSync7(composeFile)) {
6216
+ const composeFile = path16.join(root, ".devcontainer", "compose.yaml");
6217
+ if (!existsSync8(composeFile)) {
6069
6218
  throw new Error(
6070
6219
  `No compose.yaml at ${composeFile}. \`start\` / \`stop\` / \`status\` / \`logs\` require services configured via \`monoceros add-service <name> <svc>\`. Use \`monoceros shell <name>\` to enter the container directly.`
6071
6220
  );
@@ -6080,7 +6229,7 @@ async function runComposeAction(buildSubArgs, opts) {
6080
6229
  }
6081
6230
  async function runStart(opts) {
6082
6231
  resolveCompose(opts.root);
6083
- const logger = opts.logger ?? { info: (msg) => consola9.info(msg) };
6232
+ const logger = opts.logger ?? { info: (msg) => consola10.info(msg) };
6084
6233
  const spawnFn = opts.spawn ?? spawnDevcontainer;
6085
6234
  logger.info(`Bringing devcontainer up at ${opts.root}\u2026`);
6086
6235
  return spawnFn(
@@ -6326,14 +6475,14 @@ var init_images = __esm({
6326
6475
  });
6327
6476
 
6328
6477
  // src/config/machine-state.ts
6329
- import { promises as fsp3 } from "fs";
6330
- import path16 from "path";
6478
+ import { promises as fsp4 } from "fs";
6479
+ import path17 from "path";
6331
6480
  function machineStatePath(home = monocerosHome()) {
6332
- return path16.join(home, ".machine-state.json");
6481
+ return path17.join(home, ".machine-state.json");
6333
6482
  }
6334
6483
  async function readMachineState(home = monocerosHome()) {
6335
6484
  try {
6336
- const raw = await fsp3.readFile(machineStatePath(home), "utf8");
6485
+ const raw = await fsp4.readFile(machineStatePath(home), "utf8");
6337
6486
  const parsed = JSON.parse(raw);
6338
6487
  if (typeof parsed === "object" && parsed !== null) {
6339
6488
  return parsed;
@@ -6343,7 +6492,7 @@ async function readMachineState(home = monocerosHome()) {
6343
6492
  return {};
6344
6493
  }
6345
6494
  async function writeMachineState(state, home = monocerosHome()) {
6346
- await fsp3.writeFile(
6495
+ await fsp4.writeFile(
6347
6496
  machineStatePath(home),
6348
6497
  `${JSON.stringify(state, null, 2)}
6349
6498
  `
@@ -6455,8 +6604,8 @@ var init_docker_mode = __esm({
6455
6604
  // src/devcontainer/identity.ts
6456
6605
  import { spawn as spawn7 } from "child_process";
6457
6606
  import { promises as fs11 } from "fs";
6458
- import path17 from "path";
6459
- import { consola as consola10 } from "consola";
6607
+ import path18 from "path";
6608
+ import { consola as consola11 } from "consola";
6460
6609
  async function resolveIdentityWithPrompt(options = {}) {
6461
6610
  const spawnFn = options.spawn ?? realGitConfigGet;
6462
6611
  const promptFn = options.prompt ?? realIdentityPrompt;
@@ -6511,8 +6660,8 @@ async function resolveIdentityWithPrompt(options = {}) {
6511
6660
  };
6512
6661
  }
6513
6662
  async function collectGitIdentity(devContainerRoot, options = {}) {
6514
- const gitconfigDir = path17.join(devContainerRoot, ".monoceros");
6515
- const gitconfigPath = path17.join(gitconfigDir, "gitconfig");
6663
+ const gitconfigDir = path18.join(devContainerRoot, ".monoceros");
6664
+ const gitconfigPath = path18.join(gitconfigDir, "gitconfig");
6516
6665
  const logger = options.logger ?? { info: () => {
6517
6666
  }, warn: () => {
6518
6667
  } };
@@ -6605,7 +6754,7 @@ var init_identity = __esm({
6605
6754
  return void 0;
6606
6755
  }
6607
6756
  const label = key === "user.name" ? "Git user.name for this dev container (full name)" : "Git user.email for this dev container";
6608
- const value = await consola10.prompt(`${label}:`, { type: "text" });
6757
+ const value = await consola11.prompt(`${label}:`, { type: "text" });
6609
6758
  if (typeof value !== "string") return void 0;
6610
6759
  const trimmed = value.trim();
6611
6760
  return trimmed.length > 0 ? trimmed : void 0;
@@ -6615,7 +6764,7 @@ var init_identity = __esm({
6615
6764
  return ctx.reason === "prompt" ? "g" : "n";
6616
6765
  }
6617
6766
  const heading = ctx.reason === "persisted" ? `Found identity in .monoceros/gitconfig: ${ctx.name} <${ctx.email}>. Promote where?` : "Save this identity where?";
6618
- const choice = await consola10.prompt(heading, {
6767
+ const choice = await consola11.prompt(heading, {
6619
6768
  type: "select",
6620
6769
  options: [
6621
6770
  {
@@ -6646,14 +6795,14 @@ var init_identity = __esm({
6646
6795
  });
6647
6796
 
6648
6797
  // src/apply/index.ts
6649
- import { existsSync as existsSync8, promises as fs12 } from "fs";
6650
- import { consola as consola11 } from "consola";
6798
+ import { existsSync as existsSync9, promises as fs12 } from "fs";
6799
+ import { consola as consola12 } from "consola";
6651
6800
  async function runApply(opts) {
6652
6801
  const home = opts.monocerosHome ?? monocerosHome();
6653
6802
  const logger = opts.logger ?? {
6654
- info: (msg) => consola11.info(msg),
6655
- success: (msg) => consola11.success(msg),
6656
- warn: (msg) => consola11.warn(msg),
6803
+ info: (msg) => consola12.info(msg),
6804
+ success: (msg) => consola12.success(msg),
6805
+ warn: (msg) => consola12.warn(msg),
6657
6806
  // Default section renderer: empty line, bold-underlined "▸ Label",
6658
6807
  // empty line. Mirrors install.sh's section visuals.
6659
6808
  section: (label) => process.stderr.write(`
@@ -6668,7 +6817,7 @@ ${sectionLine(label)}
6668
6817
  );
6669
6818
  }
6670
6819
  const ymlPath = containerConfigPath(opts.name, home);
6671
- if (!existsSync8(ymlPath)) {
6820
+ if (!existsSync9(ymlPath)) {
6672
6821
  throw new Error(
6673
6822
  `No such config: ${ymlPath}. Run \`monoceros init <template> ${opts.name}\` first.`
6674
6823
  );
@@ -6941,7 +7090,7 @@ ${stripAnsi(formatted)}
6941
7090
  return { targetDir, configPath: ymlPath, containerExitCode: exitCode };
6942
7091
  }
6943
7092
  async function assertSafeTargetDir(targetDir, expectedOrigin) {
6944
- if (!existsSync8(targetDir)) return;
7093
+ if (!existsSync9(targetDir)) return;
6945
7094
  const entries = await fs12.readdir(targetDir);
6946
7095
  if (entries.length === 0) return;
6947
7096
  const state = await readStateFile(targetDir);
@@ -7071,18 +7220,18 @@ var CLI_VERSION;
7071
7220
  var init_version = __esm({
7072
7221
  "src/version.ts"() {
7073
7222
  "use strict";
7074
- CLI_VERSION = true ? "1.22.2" : "dev";
7223
+ CLI_VERSION = true ? "1.23.0" : "dev";
7075
7224
  }
7076
7225
  });
7077
7226
 
7078
7227
  // src/commands/_dispatch.ts
7079
- import { consola as consola12 } from "consola";
7228
+ import { consola as consola13 } from "consola";
7080
7229
  async function dispatch(runner) {
7081
7230
  try {
7082
7231
  const exitCode = await runner();
7083
7232
  process.exit(exitCode);
7084
7233
  } catch (err) {
7085
- consola12.error(err instanceof Error ? err.message : String(err));
7234
+ consola13.error(err instanceof Error ? err.message : String(err));
7086
7235
  process.exit(1);
7087
7236
  }
7088
7237
  }
@@ -7261,8 +7410,8 @@ var init_completion = __esm({
7261
7410
  });
7262
7411
 
7263
7412
  // src/completion/resolve.ts
7264
- import { existsSync as existsSync9, promises as fs13 } from "fs";
7265
- import path18 from "path";
7413
+ import { existsSync as existsSync10, promises as fs13 } from "fs";
7414
+ import path19 from "path";
7266
7415
  async function resolveCompletions(line, point, opts = {}) {
7267
7416
  const { prev, current } = parseCompletionLine(line, point);
7268
7417
  const ctx = { prev, current, opts };
@@ -7411,8 +7560,8 @@ function filterPrefix(values, fragment) {
7411
7560
  }
7412
7561
  async function listContainerNames(ctx) {
7413
7562
  const home = ctx.opts.monocerosHome ?? monocerosHome();
7414
- const dir = path18.join(home, "container-configs");
7415
- if (!existsSync9(dir)) return [];
7563
+ const dir = path19.join(home, "container-configs");
7564
+ if (!existsSync10(dir)) return [];
7416
7565
  const entries = await fs13.readdir(dir);
7417
7566
  return entries.filter((e) => e.endsWith(".yml")).map((e) => e.slice(0, -".yml".length)).sort();
7418
7567
  }
@@ -8080,14 +8229,14 @@ var init_generator = __esm({
8080
8229
  });
8081
8230
 
8082
8231
  // src/init/index.ts
8083
- import { existsSync as existsSync10, promises as fs14 } from "fs";
8084
- import path19 from "path";
8085
- import { consola as consola13 } from "consola";
8232
+ import { existsSync as existsSync11, promises as fs14 } from "fs";
8233
+ import path20 from "path";
8234
+ import { consola as consola14 } from "consola";
8086
8235
  async function runInit(opts) {
8087
8236
  const home = opts.monocerosHome ?? monocerosHome();
8088
8237
  const logger = opts.logger ?? {
8089
- success: (msg) => consola13.success(msg),
8090
- info: (msg) => consola13.info(msg)
8238
+ success: (msg) => consola14.success(msg),
8239
+ info: (msg) => consola14.info(msg)
8091
8240
  };
8092
8241
  if (!REGEX.solutionName.test(opts.name)) {
8093
8242
  throw new Error(
@@ -8095,12 +8244,12 @@ async function runInit(opts) {
8095
8244
  );
8096
8245
  }
8097
8246
  const dest = containerConfigPath(opts.name, home);
8098
- if (existsSync10(dest)) {
8247
+ if (existsSync11(dest)) {
8099
8248
  throw new Error(
8100
8249
  `Config already exists: ${dest}. Delete it manually before re-running \`monoceros init\` \u2014 this protects any hand-edits.`
8101
8250
  );
8102
8251
  }
8103
- const componentsRoot = opts.workbenchRoot ? path19.join(opts.workbenchRoot, "components") : componentsRootDir();
8252
+ const componentsRoot = opts.workbenchRoot ? path20.join(opts.workbenchRoot, "components") : componentsRootDir();
8104
8253
  const catalog = await loadComponentCatalog(componentsRoot);
8105
8254
  if (catalog.size === 0) {
8106
8255
  throw new Error(
@@ -8191,8 +8340,8 @@ async function runInit(opts) {
8191
8340
  }
8192
8341
  await ensureEnvVars(envPath, opts.name, seedVars);
8193
8342
  const documented = !anyComposed;
8194
- const ymlRel = path19.relative(home, dest);
8195
- const envRel = path19.relative(home, envPath);
8343
+ const ymlRel = path20.relative(home, dest);
8344
+ const envRel = path20.relative(home, envPath);
8196
8345
  if (documented) {
8197
8346
  logger.success(`Wrote documented default to ${ymlRel} and ${envRel}.`);
8198
8347
  logger.info(
@@ -8336,7 +8485,7 @@ var init_init = __esm({
8336
8485
 
8337
8486
  // src/commands/init.ts
8338
8487
  import { defineCommand as defineCommand11 } from "citty";
8339
- import { consola as consola14 } from "consola";
8488
+ import { consola as consola15 } from "consola";
8340
8489
  function collectListFlag(flag, rawArgs) {
8341
8490
  const eq = `${flag}=`;
8342
8491
  const pieces = [];
@@ -8462,7 +8611,7 @@ var init_init2 = __esm({
8462
8611
  ...ports && ports.length > 0 ? { withPorts: ports } : {}
8463
8612
  });
8464
8613
  } catch (err) {
8465
- consola14.error(err instanceof Error ? err.message : String(err));
8614
+ consola15.error(err instanceof Error ? err.message : String(err));
8466
8615
  process.exit(1);
8467
8616
  }
8468
8617
  }
@@ -8511,7 +8660,7 @@ var init_expand = __esm({
8511
8660
 
8512
8661
  // src/commands/list-components.ts
8513
8662
  import { defineCommand as defineCommand12 } from "citty";
8514
- import { consola as consola15 } from "consola";
8663
+ import { consola as consola16 } from "consola";
8515
8664
  var CATEGORY_LABELS, CATEGORY_ORDER, listComponentsCommand;
8516
8665
  var init_list_components = __esm({
8517
8666
  "src/commands/list-components.ts"() {
@@ -8540,7 +8689,7 @@ var init_list_components = __esm({
8540
8689
  try {
8541
8690
  const catalog = expandSelectable(await loadDescriptorCatalog());
8542
8691
  if (catalog.size === 0) {
8543
- consola15.warn(
8692
+ consola16.warn(
8544
8693
  "No components found. The workbench checkout looks incomplete."
8545
8694
  );
8546
8695
  process.exit(0);
@@ -8591,7 +8740,7 @@ var init_list_components = __esm({
8591
8740
  }
8592
8741
  process.exit(0);
8593
8742
  } catch (err) {
8594
- consola15.error(err instanceof Error ? err.message : String(err));
8743
+ consola16.error(err instanceof Error ? err.message : String(err));
8595
8744
  process.exit(1);
8596
8745
  }
8597
8746
  }
@@ -8601,8 +8750,8 @@ var init_list_components = __esm({
8601
8750
 
8602
8751
  // src/commands/logs.ts
8603
8752
  import { spawn as spawn8 } from "child_process";
8604
- import { existsSync as existsSync11 } from "fs";
8605
- import path20 from "path";
8753
+ import { existsSync as existsSync12 } from "fs";
8754
+ import path21 from "path";
8606
8755
  import { defineCommand as defineCommand13 } from "citty";
8607
8756
  function tailLogFile(file, follow) {
8608
8757
  const [cmd, args] = follow ? ["tail", ["-F", file]] : ["cat", [file]];
@@ -8645,8 +8794,8 @@ var init_logs = __esm({
8645
8794
  run({ args }) {
8646
8795
  const service = typeof args.service === "string" ? args.service : void 0;
8647
8796
  if (service) {
8648
- const logFile = path20.join(containerLogsDir(args.name), `${service}.log`);
8649
- if (existsSync11(logFile)) {
8797
+ const logFile = path21.join(containerLogsDir(args.name), `${service}.log`);
8798
+ if (existsSync12(logFile)) {
8650
8799
  return dispatch(() => tailLogFile(logFile, args.follow));
8651
8800
  }
8652
8801
  }
@@ -8664,10 +8813,10 @@ var init_logs = __esm({
8664
8813
 
8665
8814
  // src/commands/port.ts
8666
8815
  import { defineCommand as defineCommand14 } from "citty";
8667
- import { consola as consola16 } from "consola";
8816
+ import { consola as consola17 } from "consola";
8668
8817
  async function runPortListing(opts) {
8669
8818
  const out = opts.out ?? process.stdout;
8670
- const info = opts.info ?? ((m) => consola16.info(m));
8819
+ const info = opts.info ?? ((m) => consola17.info(m));
8671
8820
  const parsed = await readConfig(
8672
8821
  containerConfigPath(opts.name, opts.monocerosHome)
8673
8822
  );
@@ -8743,7 +8892,7 @@ var init_port = __esm({
8743
8892
  const code = await runPortListing({ name: args.name });
8744
8893
  process.exit(code);
8745
8894
  } catch (err) {
8746
- consola16.error(err instanceof Error ? err.message : String(err));
8895
+ consola17.error(err instanceof Error ? err.message : String(err));
8747
8896
  process.exit(1);
8748
8897
  }
8749
8898
  }
@@ -8753,7 +8902,7 @@ var init_port = __esm({
8753
8902
 
8754
8903
  // src/commands/remove-apt-packages.ts
8755
8904
  import { defineCommand as defineCommand15 } from "citty";
8756
- import { consola as consola17 } from "consola";
8905
+ import { consola as consola18 } from "consola";
8757
8906
  var removeAptPackagesCommand;
8758
8907
  var init_remove_apt_packages = __esm({
8759
8908
  "src/commands/remove-apt-packages.ts"() {
@@ -8782,7 +8931,7 @@ var init_remove_apt_packages = __esm({
8782
8931
  async run({ args }) {
8783
8932
  const packages = [...getInnerArgs()];
8784
8933
  if (packages.length === 0) {
8785
- consola17.error(
8934
+ consola18.error(
8786
8935
  "No package names given. Usage: `monoceros remove-apt-packages <containername> [--yes] -- <pkg> [<pkg> \u2026]`."
8787
8936
  );
8788
8937
  process.exit(1);
@@ -8795,7 +8944,7 @@ var init_remove_apt_packages = __esm({
8795
8944
  });
8796
8945
  process.exit(result.status === "aborted" ? 1 : 0);
8797
8946
  } catch (err) {
8798
- consola17.error(err instanceof Error ? err.message : String(err));
8947
+ consola18.error(err instanceof Error ? err.message : String(err));
8799
8948
  process.exit(1);
8800
8949
  }
8801
8950
  }
@@ -8805,7 +8954,7 @@ var init_remove_apt_packages = __esm({
8805
8954
 
8806
8955
  // src/commands/remove-feature.ts
8807
8956
  import { defineCommand as defineCommand16 } from "citty";
8808
- import { consola as consola18 } from "consola";
8957
+ import { consola as consola19 } from "consola";
8809
8958
  var removeFeatureCommand;
8810
8959
  var init_remove_feature = __esm({
8811
8960
  "src/commands/remove-feature.ts"() {
@@ -8844,7 +8993,7 @@ var init_remove_feature = __esm({
8844
8993
  });
8845
8994
  process.exit(result.status === "aborted" ? 1 : 0);
8846
8995
  } catch (err) {
8847
- consola18.error(err instanceof Error ? err.message : String(err));
8996
+ consola19.error(err instanceof Error ? err.message : String(err));
8848
8997
  process.exit(1);
8849
8998
  }
8850
8999
  }
@@ -8853,15 +9002,15 @@ var init_remove_feature = __esm({
8853
9002
  });
8854
9003
 
8855
9004
  // src/remove/index.ts
8856
- import { existsSync as existsSync12, promises as fs15 } from "fs";
8857
- import path21 from "path";
8858
- import { consola as consola19 } from "consola";
9005
+ import { existsSync as existsSync13, promises as fs15 } from "fs";
9006
+ import path22 from "path";
9007
+ import { consola as consola20 } from "consola";
8859
9008
  async function runRemove(opts) {
8860
9009
  const home = opts.monocerosHome ?? monocerosHome();
8861
9010
  const logger = opts.logger ?? {
8862
- info: (msg) => consola19.info(msg),
8863
- success: (msg) => consola19.success(msg),
8864
- warn: (msg) => consola19.warn(msg)
9011
+ info: (msg) => consola20.info(msg),
9012
+ success: (msg) => consola20.success(msg),
9013
+ warn: (msg) => consola20.warn(msg)
8865
9014
  };
8866
9015
  if (!REGEX.solutionName.test(opts.name)) {
8867
9016
  throw new Error(
@@ -8871,9 +9020,9 @@ async function runRemove(opts) {
8871
9020
  const ymlPath = containerConfigPath(opts.name, home);
8872
9021
  const envPath = containerEnvPath(opts.name, home);
8873
9022
  const containerPath = containerDir(opts.name, home);
8874
- const hasYml = existsSync12(ymlPath);
8875
- const hasEnv = existsSync12(envPath);
8876
- const hasContainer = existsSync12(containerPath);
9023
+ const hasYml = existsSync13(ymlPath);
9024
+ const hasEnv = existsSync13(envPath);
9025
+ const hasContainer = existsSync13(containerPath);
8877
9026
  if (!hasYml && !hasContainer) {
8878
9027
  throw new Error(
8879
9028
  `Nothing to remove for '${opts.name}': neither ${ymlPath} nor ${containerPath} exists.`
@@ -8899,16 +9048,16 @@ async function runRemove(opts) {
8899
9048
  let backupPath = null;
8900
9049
  if (!opts.noBackup && (hasYml || hasContainer)) {
8901
9050
  const ts = (opts.now ?? /* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
8902
- backupPath = path21.join(home, "container-backups", `${opts.name}-${ts}`);
9051
+ backupPath = path22.join(home, "container-backups", `${opts.name}-${ts}`);
8903
9052
  await fs15.mkdir(backupPath, { recursive: true });
8904
9053
  if (hasYml) {
8905
- await fs15.copyFile(ymlPath, path21.join(backupPath, `${opts.name}.yml`));
9054
+ await fs15.copyFile(ymlPath, path22.join(backupPath, `${opts.name}.yml`));
8906
9055
  }
8907
9056
  if (hasEnv) {
8908
- await fs15.copyFile(envPath, path21.join(backupPath, `${opts.name}.env`));
9057
+ await fs15.copyFile(envPath, path22.join(backupPath, `${opts.name}.env`));
8909
9058
  }
8910
9059
  if (hasContainer) {
8911
- await fs15.cp(containerPath, path21.join(backupPath, "container"), {
9060
+ await fs15.cp(containerPath, path22.join(backupPath, "container"), {
8912
9061
  recursive: true
8913
9062
  });
8914
9063
  }
@@ -8998,7 +9147,7 @@ var init_remove = __esm({
8998
9147
 
8999
9148
  // src/commands/remove.ts
9000
9149
  import { defineCommand as defineCommand17 } from "citty";
9001
- import { consola as consola20 } from "consola";
9150
+ import { consola as consola21 } from "consola";
9002
9151
  import { createInterface } from "readline/promises";
9003
9152
  var removeCommand;
9004
9153
  var init_remove2 = __esm({
@@ -9042,7 +9191,7 @@ var init_remove2 = __esm({
9042
9191
  const skipPrompt = args.yes === true;
9043
9192
  if (!skipPrompt) {
9044
9193
  const warning = noBackup ? `About to remove '${args.name}' WITHOUT a backup. Docker objects, container-configs entry, and container directory will all be deleted.` : `About to remove '${args.name}'. A backup will be written to container-backups/ first, then docker objects, container-configs entry, and container directory will all be deleted.`;
9045
- consola20.warn(warning);
9194
+ consola21.warn(warning);
9046
9195
  const rl = createInterface({
9047
9196
  input: process.stdin,
9048
9197
  output: process.stdout
@@ -9050,7 +9199,7 @@ var init_remove2 = __esm({
9050
9199
  const answer = await rl.question("Continue? [y/N] ");
9051
9200
  rl.close();
9052
9201
  if (!/^y(es)?$/i.test(answer.trim())) {
9053
- consola20.info("Aborted. Nothing changed.");
9202
+ consola21.info("Aborted. Nothing changed.");
9054
9203
  process.exit(0);
9055
9204
  }
9056
9205
  }
@@ -9059,7 +9208,7 @@ var init_remove2 = __esm({
9059
9208
  ...noBackup ? { noBackup: true } : {}
9060
9209
  });
9061
9210
  } catch (err) {
9062
- consola20.error(err instanceof Error ? err.message : String(err));
9211
+ consola21.error(err instanceof Error ? err.message : String(err));
9063
9212
  process.exit(1);
9064
9213
  }
9065
9214
  }
@@ -9068,17 +9217,17 @@ var init_remove2 = __esm({
9068
9217
  });
9069
9218
 
9070
9219
  // src/restore/index.ts
9071
- import { existsSync as existsSync13, promises as fs16 } from "fs";
9072
- import path22 from "path";
9073
- import { consola as consola21 } from "consola";
9220
+ import { existsSync as existsSync14, promises as fs16 } from "fs";
9221
+ import path23 from "path";
9222
+ import { consola as consola22 } from "consola";
9074
9223
  async function runRestore(opts) {
9075
9224
  const home = opts.monocerosHome ?? monocerosHome();
9076
9225
  const logger = opts.logger ?? {
9077
- info: (msg) => consola21.info(msg),
9078
- success: (msg) => consola21.success(msg)
9226
+ info: (msg) => consola22.info(msg),
9227
+ success: (msg) => consola22.success(msg)
9079
9228
  };
9080
- const backup = path22.resolve(opts.backupPath);
9081
- if (!existsSync13(backup)) {
9229
+ const backup = path23.resolve(opts.backupPath);
9230
+ if (!existsSync14(backup)) {
9082
9231
  throw new Error(`Backup not found: ${backup}.`);
9083
9232
  }
9084
9233
  const stat = await fs16.stat(backup);
@@ -9099,24 +9248,24 @@ async function runRestore(opts) {
9099
9248
  }
9100
9249
  const ymlFile = ymlFiles[0];
9101
9250
  const name = ymlFile.replace(/\.yml$/, "");
9102
- const containerInBackup = path22.join(backup, "container");
9103
- const hasContainer = existsSync13(containerInBackup);
9104
- const envInBackup = path22.join(backup, `${name}.env`);
9105
- const hasEnv = existsSync13(envInBackup);
9251
+ const containerInBackup = path23.join(backup, "container");
9252
+ const hasContainer = existsSync14(containerInBackup);
9253
+ const envInBackup = path23.join(backup, `${name}.env`);
9254
+ const hasEnv = existsSync14(envInBackup);
9106
9255
  const destYml = containerConfigPath(name, home);
9107
9256
  const destContainer = containerDir(name, home);
9108
- if (existsSync13(destYml)) {
9257
+ if (existsSync14(destYml)) {
9109
9258
  throw new Error(
9110
9259
  `Refusing to restore: ${destYml} already exists. Remove the current container first (\`monoceros remove ${name}\`) or rename the existing config.`
9111
9260
  );
9112
9261
  }
9113
- if (hasContainer && existsSync13(destContainer)) {
9262
+ if (hasContainer && existsSync14(destContainer)) {
9114
9263
  throw new Error(
9115
9264
  `Refusing to restore: ${destContainer} already exists. Remove the current container first (\`monoceros remove ${name}\`).`
9116
9265
  );
9117
9266
  }
9118
9267
  await fs16.mkdir(containerConfigsDir(home), { recursive: true });
9119
- await fs16.copyFile(path22.join(backup, ymlFile), destYml);
9268
+ await fs16.copyFile(path23.join(backup, ymlFile), destYml);
9120
9269
  if (hasEnv) {
9121
9270
  await fs16.copyFile(envInBackup, containerEnvPath(name, home));
9122
9271
  }
@@ -9142,7 +9291,7 @@ var init_restore = __esm({
9142
9291
 
9143
9292
  // src/commands/restore.ts
9144
9293
  import { defineCommand as defineCommand18 } from "citty";
9145
- import { consola as consola22 } from "consola";
9294
+ import { consola as consola23 } from "consola";
9146
9295
  var restoreCommand;
9147
9296
  var init_restore2 = __esm({
9148
9297
  "src/commands/restore.ts"() {
@@ -9165,7 +9314,7 @@ var init_restore2 = __esm({
9165
9314
  try {
9166
9315
  await runRestore({ backupPath: args["backup-path"] });
9167
9316
  } catch (err) {
9168
- consola22.error(err instanceof Error ? err.message : String(err));
9317
+ consola23.error(err instanceof Error ? err.message : String(err));
9169
9318
  process.exit(1);
9170
9319
  }
9171
9320
  }
@@ -9175,7 +9324,7 @@ var init_restore2 = __esm({
9175
9324
 
9176
9325
  // src/commands/remove-from-url.ts
9177
9326
  import { defineCommand as defineCommand19 } from "citty";
9178
- import { consola as consola23 } from "consola";
9327
+ import { consola as consola24 } from "consola";
9179
9328
  var removeFromUrlCommand;
9180
9329
  var init_remove_from_url = __esm({
9181
9330
  "src/commands/remove-from-url.ts"() {
@@ -9214,7 +9363,7 @@ var init_remove_from_url = __esm({
9214
9363
  });
9215
9364
  process.exit(result.status === "aborted" ? 1 : 0);
9216
9365
  } catch (err) {
9217
- consola23.error(err instanceof Error ? err.message : String(err));
9366
+ consola24.error(err instanceof Error ? err.message : String(err));
9218
9367
  process.exit(1);
9219
9368
  }
9220
9369
  }
@@ -9224,7 +9373,7 @@ var init_remove_from_url = __esm({
9224
9373
 
9225
9374
  // src/commands/remove-language.ts
9226
9375
  import { defineCommand as defineCommand20 } from "citty";
9227
- import { consola as consola24 } from "consola";
9376
+ import { consola as consola25 } from "consola";
9228
9377
  var removeLanguageCommand;
9229
9378
  var init_remove_language = __esm({
9230
9379
  "src/commands/remove-language.ts"() {
@@ -9263,7 +9412,7 @@ var init_remove_language = __esm({
9263
9412
  });
9264
9413
  process.exit(result.status === "aborted" ? 1 : 0);
9265
9414
  } catch (err) {
9266
- consola24.error(err instanceof Error ? err.message : String(err));
9415
+ consola25.error(err instanceof Error ? err.message : String(err));
9267
9416
  process.exit(1);
9268
9417
  }
9269
9418
  }
@@ -9273,7 +9422,7 @@ var init_remove_language = __esm({
9273
9422
 
9274
9423
  // src/commands/remove-port.ts
9275
9424
  import { defineCommand as defineCommand21 } from "citty";
9276
- import { consola as consola25 } from "consola";
9425
+ import { consola as consola26 } from "consola";
9277
9426
  function coerceToken2(raw) {
9278
9427
  const n = Number(raw);
9279
9428
  return Number.isFinite(n) ? n : raw;
@@ -9306,7 +9455,7 @@ var init_remove_port = __esm({
9306
9455
  async run({ args }) {
9307
9456
  const tokens = [...getInnerArgs()];
9308
9457
  if (tokens.length === 0) {
9309
- consola25.error(
9458
+ consola26.error(
9310
9459
  "No ports given. Usage: `monoceros remove-port <containername> [--yes] -- <port> [<port> \u2026]`."
9311
9460
  );
9312
9461
  process.exit(1);
@@ -9319,7 +9468,7 @@ var init_remove_port = __esm({
9319
9468
  });
9320
9469
  process.exit(result.status === "aborted" ? 1 : 0);
9321
9470
  } catch (err) {
9322
- consola25.error(err instanceof Error ? err.message : String(err));
9471
+ consola26.error(err instanceof Error ? err.message : String(err));
9323
9472
  process.exit(1);
9324
9473
  }
9325
9474
  }
@@ -9329,7 +9478,7 @@ var init_remove_port = __esm({
9329
9478
 
9330
9479
  // src/commands/remove-repo.ts
9331
9480
  import { defineCommand as defineCommand22 } from "citty";
9332
- import { consola as consola26 } from "consola";
9481
+ import { consola as consola27 } from "consola";
9333
9482
  var removeRepoCommand;
9334
9483
  var init_remove_repo = __esm({
9335
9484
  "src/commands/remove-repo.ts"() {
@@ -9368,7 +9517,7 @@ var init_remove_repo = __esm({
9368
9517
  });
9369
9518
  process.exit(result.status === "aborted" ? 1 : 0);
9370
9519
  } catch (err) {
9371
- consola26.error(err instanceof Error ? err.message : String(err));
9520
+ consola27.error(err instanceof Error ? err.message : String(err));
9372
9521
  process.exit(1);
9373
9522
  }
9374
9523
  }
@@ -9378,7 +9527,7 @@ var init_remove_repo = __esm({
9378
9527
 
9379
9528
  // src/commands/remove-service.ts
9380
9529
  import { defineCommand as defineCommand23 } from "citty";
9381
- import { consola as consola27 } from "consola";
9530
+ import { consola as consola28 } from "consola";
9382
9531
  var removeServiceCommand;
9383
9532
  var init_remove_service = __esm({
9384
9533
  "src/commands/remove-service.ts"() {
@@ -9417,7 +9566,7 @@ var init_remove_service = __esm({
9417
9566
  });
9418
9567
  process.exit(result.status === "aborted" ? 1 : 0);
9419
9568
  } catch (err) {
9420
- consola27.error(err instanceof Error ? err.message : String(err));
9569
+ consola28.error(err instanceof Error ? err.message : String(err));
9421
9570
  process.exit(1);
9422
9571
  }
9423
9572
  }
@@ -9427,9 +9576,9 @@ var init_remove_service = __esm({
9427
9576
 
9428
9577
  // src/devcontainer/browser-bridge.ts
9429
9578
  import { spawn as spawn9 } from "child_process";
9430
- import { existsSync as existsSync14, promises as fsp4, readFileSync as readFileSync5 } from "fs";
9579
+ import { existsSync as existsSync15, promises as fsp5, readFileSync as readFileSync5 } from "fs";
9431
9580
  import http from "http";
9432
- import path23 from "path";
9581
+ import path24 from "path";
9433
9582
  function parseCallbackTarget(authUrl) {
9434
9583
  try {
9435
9584
  const u = new URL(authUrl);
@@ -9463,12 +9612,12 @@ function openInBrowser(url) {
9463
9612
  }
9464
9613
  }
9465
9614
  async function startBrowserBridge(opts) {
9466
- const relayDir = path23.join(opts.root, RELAY_DIRNAME);
9467
- const relayScript = path23.join(relayDir, "xdg-open");
9468
- const urlFile = path23.join(relayDir, "url");
9469
- await fsp4.mkdir(relayDir, { recursive: true });
9470
- await fsp4.rm(urlFile, { force: true });
9471
- await fsp4.writeFile(
9615
+ const relayDir = path24.join(opts.root, RELAY_DIRNAME);
9616
+ const relayScript = path24.join(relayDir, "xdg-open");
9617
+ const urlFile = path24.join(relayDir, "url");
9618
+ await fsp5.mkdir(relayDir, { recursive: true });
9619
+ await fsp5.rm(urlFile, { force: true });
9620
+ await fsp5.writeFile(
9472
9621
  relayScript,
9473
9622
  `#!/bin/sh
9474
9623
  printf '%s\\n' "$1" > "$(dirname "$0")/url"
@@ -9476,7 +9625,7 @@ exit 0
9476
9625
  `,
9477
9626
  { mode: 493 }
9478
9627
  );
9479
- await fsp4.chmod(relayScript, 493);
9628
+ await fsp5.chmod(relayScript, 493);
9480
9629
  const servers = [];
9481
9630
  let lastOpened = null;
9482
9631
  const onUrl = (url) => {
@@ -9509,7 +9658,7 @@ exit 0
9509
9658
  servers.push(server);
9510
9659
  };
9511
9660
  const poll = setInterval(() => {
9512
- if (!existsSync14(urlFile)) return;
9661
+ if (!existsSync15(urlFile)) return;
9513
9662
  let content = "";
9514
9663
  try {
9515
9664
  content = readFileSync5(urlFile, "utf8");
@@ -9526,7 +9675,7 @@ exit 0
9526
9675
  async dispose() {
9527
9676
  clearInterval(poll);
9528
9677
  for (const s of servers) s.close();
9529
- await fsp4.rm(relayDir, { recursive: true, force: true });
9678
+ await fsp5.rm(relayDir, { recursive: true, force: true });
9530
9679
  }
9531
9680
  };
9532
9681
  }
@@ -9539,18 +9688,18 @@ var init_browser_bridge = __esm({
9539
9688
  });
9540
9689
 
9541
9690
  // src/devcontainer/claude-trust.ts
9542
- import { existsSync as existsSync15, promises as fsp5 } from "fs";
9543
- import path24 from "path";
9691
+ import { existsSync as existsSync16, promises as fsp6 } from "fs";
9692
+ import path25 from "path";
9544
9693
  function resolveContainerCwd(name, cwd) {
9545
9694
  const workspace = `/workspaces/${name}`;
9546
9695
  if (!cwd) return workspace;
9547
- return path24.posix.isAbsolute(cwd) ? cwd : path24.posix.join(workspace, cwd);
9696
+ return path25.posix.isAbsolute(cwd) ? cwd : path25.posix.join(workspace, cwd);
9548
9697
  }
9549
9698
  async function preApproveClaudeProject(opts) {
9550
- const file = path24.join(opts.root, "home", ".claude.json");
9551
- if (!existsSync15(file)) return;
9699
+ const file = path25.join(opts.root, "home", ".claude.json");
9700
+ if (!existsSync16(file)) return;
9552
9701
  try {
9553
- const raw = await fsp5.readFile(file, "utf8");
9702
+ const raw = await fsp6.readFile(file, "utf8");
9554
9703
  const config = raw.trim() ? JSON.parse(raw) : {};
9555
9704
  if (typeof config !== "object" || config === null) return;
9556
9705
  const dir = resolveContainerCwd(opts.name, opts.cwd);
@@ -9570,7 +9719,7 @@ async function preApproveClaudeProject(opts) {
9570
9719
  if (typeof entry2.projectOnboardingSeenCount !== "number") {
9571
9720
  entry2.projectOnboardingSeenCount = 1;
9572
9721
  }
9573
- await fsp5.writeFile(file, `${JSON.stringify(config, null, 2)}
9722
+ await fsp6.writeFile(file, `${JSON.stringify(config, null, 2)}
9574
9723
  `);
9575
9724
  } catch {
9576
9725
  }
@@ -9582,8 +9731,8 @@ var init_claude_trust = __esm({
9582
9731
  });
9583
9732
 
9584
9733
  // src/devcontainer/shell.ts
9585
- import { existsSync as existsSync16 } from "fs";
9586
- import path25 from "path";
9734
+ import { existsSync as existsSync17 } from "fs";
9735
+ import path26 from "path";
9587
9736
  async function runShell(opts) {
9588
9737
  assertContainerExists(opts.root);
9589
9738
  const spawnFn = opts.spawn ?? spawnDevcontainer;
@@ -9606,7 +9755,7 @@ async function runShell(opts) {
9606
9755
  );
9607
9756
  }
9608
9757
  function assertContainerExists(root) {
9609
- if (!existsSync16(path25.join(root, ".devcontainer"))) {
9758
+ if (!existsSync17(path26.join(root, ".devcontainer"))) {
9610
9759
  throw new Error(
9611
9760
  `No .devcontainer/ at ${root}. Run \`monoceros apply <name>\` first.`
9612
9761
  );
@@ -9696,7 +9845,7 @@ var init_run = __esm({
9696
9845
 
9697
9846
  // src/commands/run.ts
9698
9847
  import { defineCommand as defineCommand24 } from "citty";
9699
- import { consola as consola28 } from "consola";
9848
+ import { consola as consola29 } from "consola";
9700
9849
  var runCommand;
9701
9850
  var init_run2 = __esm({
9702
9851
  "src/commands/run.ts"() {
@@ -9724,7 +9873,7 @@ var init_run2 = __esm({
9724
9873
  async run({ args }) {
9725
9874
  const command = [...getInnerArgs()];
9726
9875
  if (command.length === 0) {
9727
- consola28.error(
9876
+ consola29.error(
9728
9877
  "No command provided. Usage: `monoceros run <containername> -- <cmd> [args\u2026]`."
9729
9878
  );
9730
9879
  process.exit(1);
@@ -9738,7 +9887,7 @@ var init_run2 = __esm({
9738
9887
  });
9739
9888
  process.exit(exitCode);
9740
9889
  } catch (err) {
9741
- consola28.error(err instanceof Error ? err.message : String(err));
9890
+ consola29.error(err instanceof Error ? err.message : String(err));
9742
9891
  process.exit(1);
9743
9892
  }
9744
9893
  }
@@ -9748,7 +9897,7 @@ var init_run2 = __esm({
9748
9897
 
9749
9898
  // src/commands/shell.ts
9750
9899
  import { defineCommand as defineCommand25 } from "citty";
9751
- import { consola as consola29 } from "consola";
9900
+ import { consola as consola30 } from "consola";
9752
9901
  var shellCommand;
9753
9902
  var init_shell2 = __esm({
9754
9903
  "src/commands/shell.ts"() {
@@ -9773,7 +9922,7 @@ var init_shell2 = __esm({
9773
9922
  const exitCode = await runShell({ root: containerDir(args.name) });
9774
9923
  process.exit(exitCode);
9775
9924
  } catch (err) {
9776
- consola29.error(err instanceof Error ? err.message : String(err));
9925
+ consola30.error(err instanceof Error ? err.message : String(err));
9777
9926
  process.exit(1);
9778
9927
  }
9779
9928
  }
@@ -9783,7 +9932,7 @@ var init_shell2 = __esm({
9783
9932
 
9784
9933
  // src/commands/start.ts
9785
9934
  import { defineCommand as defineCommand26 } from "citty";
9786
- import { consola as consola30 } from "consola";
9935
+ import { consola as consola31 } from "consola";
9787
9936
  var startCommand;
9788
9937
  var init_start = __esm({
9789
9938
  "src/commands/start.ts"() {
@@ -9820,7 +9969,7 @@ var init_start = __esm({
9820
9969
  hostPort = proxyHostPort(global);
9821
9970
  }
9822
9971
  } catch (err) {
9823
- consola30.warn(
9972
+ consola31.warn(
9824
9973
  `Could not read container yml ahead of start: ${err instanceof Error ? err.message : String(err)}. Skipping Traefik pre-flight.`
9825
9974
  );
9826
9975
  }
@@ -9875,7 +10024,7 @@ var init_status = __esm({
9875
10024
 
9876
10025
  // src/commands/stop.ts
9877
10026
  import { defineCommand as defineCommand28 } from "citty";
9878
- import { consola as consola31 } from "consola";
10027
+ import { consola as consola32 } from "consola";
9879
10028
  var stopCommand;
9880
10029
  var init_stop = __esm({
9881
10030
  "src/commands/stop.ts"() {
@@ -9909,10 +10058,10 @@ var init_stop = __esm({
9909
10058
  });
9910
10059
  try {
9911
10060
  await maybeStopProxy({
9912
- logger: { info: (msg) => consola31.info(msg) }
10061
+ logger: { info: (msg) => consola32.info(msg) }
9913
10062
  });
9914
10063
  } catch (err) {
9915
- consola31.warn(
10064
+ consola32.warn(
9916
10065
  `Could not tear down the Traefik proxy: ${err instanceof Error ? err.message : String(err)}. Ignored.`
9917
10066
  );
9918
10067
  }
@@ -9924,11 +10073,11 @@ var init_stop = __esm({
9924
10073
  });
9925
10074
 
9926
10075
  // src/tunnel/resolve.ts
9927
- import { existsSync as existsSync17 } from "fs";
9928
- import path26 from "path";
10076
+ import { existsSync as existsSync18 } from "fs";
10077
+ import path27 from "path";
9929
10078
  async function resolveTunnelTarget(opts) {
9930
10079
  const ymlPath = containerConfigPath(opts.name, opts.monocerosHome);
9931
- if (!existsSync17(ymlPath)) {
10080
+ if (!existsSync18(ymlPath)) {
9932
10081
  throw new Error(
9933
10082
  `No yml profile for '${opts.name}' at ${ymlPath}. Run \`monoceros init ${opts.name}\` first.`
9934
10083
  );
@@ -9936,13 +10085,13 @@ async function resolveTunnelTarget(opts) {
9936
10085
  const parsed = await readConfig(ymlPath);
9937
10086
  const config = parsed.config;
9938
10087
  const containerRoot = containerDir(opts.name, opts.monocerosHome);
9939
- if (!existsSync17(containerRoot)) {
10088
+ if (!existsSync18(containerRoot)) {
9940
10089
  throw new Error(
9941
10090
  `Container '${opts.name}' is not materialised at ${containerRoot}. Run \`monoceros apply ${opts.name}\` first.`
9942
10091
  );
9943
10092
  }
9944
- const composePath = path26.join(containerRoot, ".devcontainer", "compose.yaml");
9945
- const isCompose = existsSync17(composePath);
10093
+ const composePath = path27.join(containerRoot, ".devcontainer", "compose.yaml");
10094
+ const isCompose = existsSync18(composePath);
9946
10095
  const parsedTarget = parseTargetArg(opts.target, config);
9947
10096
  const docker = opts.docker ?? defaultDockerExec;
9948
10097
  if (isCompose) {
@@ -10178,7 +10327,7 @@ var init_port_check2 = __esm({
10178
10327
 
10179
10328
  // src/tunnel/run.ts
10180
10329
  import { spawn as spawn10 } from "child_process";
10181
- import { consola as consola32 } from "consola";
10330
+ import { consola as consola33 } from "consola";
10182
10331
  function signalNumber(signal) {
10183
10332
  switch (signal) {
10184
10333
  case "SIGINT":
@@ -10191,8 +10340,8 @@ function signalNumber(signal) {
10191
10340
  }
10192
10341
  async function runTunnel(opts) {
10193
10342
  const log = opts.logger ?? {
10194
- info: (m) => consola32.info(m),
10195
- warn: (m) => consola32.warn(m)
10343
+ info: (m) => consola33.info(m),
10344
+ warn: (m) => consola33.warn(m)
10196
10345
  };
10197
10346
  const resolve = opts.resolve ?? resolveTunnelTarget;
10198
10347
  const resolveArgs3 = {
@@ -10299,7 +10448,7 @@ var init_run3 = __esm({
10299
10448
 
10300
10449
  // src/commands/tunnel.ts
10301
10450
  import { defineCommand as defineCommand29 } from "citty";
10302
- import { consola as consola33 } from "consola";
10451
+ import { consola as consola34 } from "consola";
10303
10452
  function parseLocalPort(raw) {
10304
10453
  if (raw === void 0) return void 0;
10305
10454
  const n = Number(raw);
@@ -10352,7 +10501,7 @@ var init_tunnel = __esm({
10352
10501
  });
10353
10502
  process.exit(exitCode);
10354
10503
  } catch (err) {
10355
- consola33.error(err instanceof Error ? err.message : String(err));
10504
+ consola34.error(err instanceof Error ? err.message : String(err));
10356
10505
  process.exit(1);
10357
10506
  }
10358
10507
  }
@@ -10422,8 +10571,8 @@ var init_prune = __esm({
10422
10571
  });
10423
10572
 
10424
10573
  // src/upgrade/index.ts
10425
- import { existsSync as existsSync18, promises as fs17 } from "fs";
10426
- import { consola as consola34 } from "consola";
10574
+ import { existsSync as existsSync19, promises as fs17 } from "fs";
10575
+ import { consola as consola35 } from "consola";
10427
10576
  async function fetchRuntimeVersions() {
10428
10577
  const tokenUrl = `https://ghcr.io/token?service=ghcr.io&scope=repository:${RUNTIME_REPO}:pull`;
10429
10578
  const tokenRes = await fetch(tokenUrl);
@@ -10461,7 +10610,7 @@ ${yml}`;
10461
10610
  }
10462
10611
  async function runUpgrade(opts) {
10463
10612
  const home = opts.monocerosHome ?? monocerosHome();
10464
- const logger = opts.logger ?? consola34;
10613
+ const logger = opts.logger ?? consola35;
10465
10614
  const fetchVersions = opts.fetchVersions ?? fetchRuntimeVersions;
10466
10615
  if (opts.list) {
10467
10616
  const versions = await fetchVersions();
@@ -10487,7 +10636,7 @@ async function runUpgrade(opts) {
10487
10636
  );
10488
10637
  }
10489
10638
  }
10490
- if (opts.name && !existsSync18(containerConfigPath(opts.name, home))) {
10639
+ if (opts.name && !existsSync19(containerConfigPath(opts.name, home))) {
10491
10640
  throw new Error(
10492
10641
  `No such config: ${containerConfigPath(opts.name, home)}. Run \`monoceros init <template> ${opts.name}\` first.`
10493
10642
  );
@@ -10538,7 +10687,7 @@ async function runUpgrade(opts) {
10538
10687
  let bumped = 0;
10539
10688
  for (const name of targets) {
10540
10689
  const ymlPath = containerConfigPath(name, home);
10541
- if (!existsSync18(ymlPath)) continue;
10690
+ if (!existsSync19(ymlPath)) continue;
10542
10691
  const raw = await fs17.readFile(ymlPath, "utf8");
10543
10692
  const updated = setRuntimeVersion(raw, pinVersion);
10544
10693
  if (updated !== raw) {
@@ -10989,25 +11138,25 @@ function detectHelpRequest(argv, main2) {
10989
11138
  const separatorIdx = argv.indexOf("--");
10990
11139
  if (helpIdx === -1) return null;
10991
11140
  if (separatorIdx !== -1 && separatorIdx < helpIdx) return null;
10992
- const path27 = [];
11141
+ const path28 = [];
10993
11142
  const tokens = argv.slice(
10994
11143
  0,
10995
11144
  separatorIdx === -1 ? argv.length : separatorIdx
10996
11145
  );
10997
11146
  let cursor = main2;
10998
11147
  const mainName = (main2.meta ?? {}).name ?? "monoceros";
10999
- path27.push(mainName);
11148
+ path28.push(mainName);
11000
11149
  for (const tok of tokens) {
11001
11150
  if (tok.startsWith("-")) continue;
11002
11151
  const subs = cursor.subCommands ?? {};
11003
11152
  if (tok in subs) {
11004
11153
  cursor = subs[tok];
11005
- path27.push(tok);
11154
+ path28.push(tok);
11006
11155
  continue;
11007
11156
  }
11008
11157
  break;
11009
11158
  }
11010
- return { path: path27, cmd: cursor };
11159
+ return { path: path28, cmd: cursor };
11011
11160
  }
11012
11161
  async function maybeRenderHelp(argv, main2) {
11013
11162
  const hit = detectHelpRequest(argv, main2);