@getmonoceros/workbench 1.22.2 → 1.23.1

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,169 @@ 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 (typeof config.permission !== "string") {
2519
+ const permission = typeof config.permission === "object" && config.permission !== null ? config.permission : {};
2520
+ const ext = typeof permission.external_directory === "object" && permission.external_directory !== null ? permission.external_directory : {};
2521
+ for (const p of [
2522
+ `${workspaceRoot}/AGENTS.md`,
2523
+ `${workspaceRoot}/.monoceros/commands.md`,
2524
+ `${workspaceRoot}/projects/**`
2525
+ ]) {
2526
+ ext[p] = "allow";
2527
+ }
2528
+ permission.external_directory = ext;
2529
+ config.permission = permission;
2530
+ }
2531
+ if (model) {
2532
+ config.model = model;
2533
+ }
2534
+ const parsed = parseOpencodeModel(model);
2535
+ if (npm) {
2536
+ if (!parsed) {
2537
+ consola.warn(
2538
+ "[opencode] `npm` is set but `model` is empty or has no provider prefix \u2014 set `model: <provider>/<model-id>` to configure a custom provider."
2539
+ );
2540
+ } else {
2541
+ writeCustomProvider(config, parsed, { npm, baseUrl, apiToken });
2542
+ }
2543
+ } else if (parsed) {
2544
+ if (KNOWN_APIKEY_PROVIDERS.includes(parsed.provider)) {
2545
+ if (apiToken) {
2546
+ writeHostedApiKey(config, parsed.provider, apiToken);
2547
+ }
2548
+ } else {
2549
+ consola.warn(
2550
+ `[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.`
2551
+ );
2552
+ }
2553
+ }
2554
+ await fsp3.writeFile(file, `${JSON.stringify(config, null, 2)}
2555
+ `);
2556
+ }
2557
+ function providersOf(config) {
2558
+ if (typeof config.provider === "object" && config.provider !== null) {
2559
+ return config.provider;
2560
+ }
2561
+ const fresh = {};
2562
+ config.provider = fresh;
2563
+ return fresh;
2564
+ }
2565
+ function providerEntry(providers, id) {
2566
+ if (typeof providers[id] === "object" && providers[id] !== null) {
2567
+ return providers[id];
2568
+ }
2569
+ const fresh = {};
2570
+ providers[id] = fresh;
2571
+ return fresh;
2572
+ }
2573
+ function optionsOf(entry2) {
2574
+ if (typeof entry2.options === "object" && entry2.options !== null) {
2575
+ return entry2.options;
2576
+ }
2577
+ const fresh = {};
2578
+ entry2.options = fresh;
2579
+ return fresh;
2580
+ }
2581
+ function writeHostedApiKey(config, provider, apiToken) {
2582
+ const entry2 = providerEntry(providersOf(config), provider);
2583
+ optionsOf(entry2).apiKey = apiToken;
2584
+ }
2585
+ function writeCustomProvider(config, parsed, {
2586
+ npm,
2587
+ baseUrl,
2588
+ apiToken
2589
+ }) {
2590
+ const entry2 = providerEntry(providersOf(config), parsed.provider);
2591
+ entry2.npm = npm;
2592
+ if (typeof entry2.name !== "string") entry2.name = parsed.provider;
2593
+ const opts = optionsOf(entry2);
2594
+ if (baseUrl) opts.baseURL = baseUrl;
2595
+ if (apiToken) opts.apiKey = apiToken;
2596
+ const models = typeof entry2.models === "object" && entry2.models !== null ? entry2.models : {};
2597
+ if (models[parsed.modelId] === void 0) {
2598
+ models[parsed.modelId] = { name: parsed.modelId };
2599
+ }
2600
+ entry2.models = models;
2601
+ }
2602
+ var KNOWN_APIKEY_PROVIDERS;
2603
+ var init_opencode_config = __esm({
2604
+ "src/create/opencode-config.ts"() {
2605
+ "use strict";
2606
+ init_ref();
2607
+ KNOWN_APIKEY_PROVIDERS = [
2608
+ "anthropic",
2609
+ "openai",
2610
+ "google",
2611
+ "openrouter",
2612
+ "mistral",
2613
+ "groq",
2614
+ "deepseek",
2615
+ "xai"
2616
+ ];
2617
+ }
2618
+ });
2619
+
2620
+ // src/create/scaffold.ts
2621
+ import { existsSync as existsSync7, promises as fs7 } from "fs";
2622
+ import path10 from "path";
2463
2623
  function deriveRepoName(url) {
2464
2624
  const lastSep = Math.max(url.lastIndexOf("/"), url.lastIndexOf(":"));
2465
2625
  const tail = url.slice(lastSep + 1);
@@ -2590,7 +2750,7 @@ function featuresSourceRoot() {
2590
2750
  const override2 = process.env.MONOCEROS_FEATURES_DIR_OVERRIDE?.trim();
2591
2751
  if (override2 && override2.length > 0) return override2;
2592
2752
  const checkout = workbenchCheckoutRoot();
2593
- return checkout ? path9.join(checkout, "components", "features") : null;
2753
+ return checkout ? path10.join(checkout, "components", "features") : null;
2594
2754
  }
2595
2755
  function resolveFeatures(opts) {
2596
2756
  const resolved = [];
@@ -2630,8 +2790,8 @@ function resolveFeatures(opts) {
2630
2790
  const descriptor = featureDescriptor(name);
2631
2791
  const { paths, files } = descriptorPersistentHome(descriptor);
2632
2792
  const sourceRoot = featuresSourceRoot();
2633
- const localSourceDir = sourceRoot ? path9.join(sourceRoot, name) : null;
2634
- if (descriptor && localSourceDir && existsSync6(localSourceDir)) {
2793
+ const localSourceDir = sourceRoot ? path10.join(sourceRoot, name) : null;
2794
+ if (descriptor && localSourceDir && existsSync7(localSourceDir)) {
2635
2795
  resolved.push({
2636
2796
  devcontainerKey: `./features/${name}`,
2637
2797
  options,
@@ -3076,7 +3236,7 @@ function buildPostCreateScript(opts) {
3076
3236
  return lines.join("\n") + "\n";
3077
3237
  }
3078
3238
  async function writePostCreateScript(devcontainerDir, opts) {
3079
- const dest = path9.join(devcontainerDir, "post-create.sh");
3239
+ const dest = path10.join(devcontainerDir, "post-create.sh");
3080
3240
  await fs7.writeFile(dest, buildPostCreateScript(opts));
3081
3241
  await fs7.chmod(dest, 493);
3082
3242
  }
@@ -3090,11 +3250,11 @@ async function writeIfChanged(filePath, content) {
3090
3250
  }
3091
3251
  async function writeScaffold(opts, targetDir, scaffoldOpts = {}) {
3092
3252
  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");
3253
+ const devcontainerDir = path10.join(targetDir, ".devcontainer");
3254
+ const monocerosDir = path10.join(targetDir, ".monoceros");
3255
+ const projectsDir = path10.join(targetDir, "projects");
3256
+ const homeDir = path10.join(targetDir, "home");
3257
+ const dataDir = path10.join(targetDir, "data");
3098
3258
  await fs7.mkdir(devcontainerDir, { recursive: true });
3099
3259
  await fs7.mkdir(monocerosDir, { recursive: true });
3100
3260
  await fs7.mkdir(projectsDir, { recursive: true });
@@ -3104,36 +3264,36 @@ async function writeScaffold(opts, targetDir, scaffoldOpts = {}) {
3104
3264
  for (const svc of opts.services) {
3105
3265
  const hasDataVolume = svc.volumes.some((v) => v.split(":")[0] === "data");
3106
3266
  if (hasDataVolume) {
3107
- await fs7.mkdir(path9.join(dataDir, svc.name), { recursive: true });
3267
+ await fs7.mkdir(path10.join(dataDir, svc.name), { recursive: true });
3108
3268
  }
3109
3269
  }
3110
3270
  }
3111
- const containerGitignore = path9.join(targetDir, ".gitignore");
3271
+ const containerGitignore = path10.join(targetDir, ".gitignore");
3112
3272
  await fs7.writeFile(
3113
3273
  containerGitignore,
3114
3274
  "/home/\n/.monoceros/\n/data/\n/AGENTS.md\n/CLAUDE.md\n"
3115
3275
  );
3116
- const gitkeep = path9.join(projectsDir, ".gitkeep");
3117
- if (!existsSync6(gitkeep)) {
3276
+ const gitkeep = path10.join(projectsDir, ".gitkeep");
3277
+ if (!existsSync7(gitkeep)) {
3118
3278
  await fs7.writeFile(gitkeep, "");
3119
3279
  }
3120
3280
  await fs7.writeFile(
3121
- path9.join(monocerosDir, ".gitignore"),
3281
+ path10.join(monocerosDir, ".gitignore"),
3122
3282
  "git-credentials*\ngitconfig\n"
3123
3283
  );
3124
3284
  const devcontainerJson = buildDevcontainerJson(opts, dockerMode);
3125
3285
  await writeIfChanged(
3126
- path9.join(devcontainerDir, "devcontainer.json"),
3286
+ path10.join(devcontainerDir, "devcontainer.json"),
3127
3287
  JSON.stringify(devcontainerJson, null, 2) + "\n"
3128
3288
  );
3129
- const featuresDir = path9.join(devcontainerDir, "features");
3130
- if (existsSync6(featuresDir)) {
3289
+ const featuresDir = path10.join(devcontainerDir, "features");
3290
+ if (existsSync7(featuresDir)) {
3131
3291
  await fs7.rm(featuresDir, { recursive: true, force: true });
3132
3292
  }
3133
3293
  const resolvedFeatures = resolveFeatures(opts);
3134
3294
  for (const f of resolvedFeatures) {
3135
3295
  if (!f.localSourceDir || !f.localName) continue;
3136
- const dest = path9.join(featuresDir, f.localName);
3296
+ const dest = path10.join(featuresDir, f.localName);
3137
3297
  await fs7.mkdir(dest, { recursive: true });
3138
3298
  const entries = await fs7.readdir(f.localSourceDir, { withFileTypes: true });
3139
3299
  for (const entry2 of entries) {
@@ -3142,38 +3302,39 @@ async function writeScaffold(opts, targetDir, scaffoldOpts = {}) {
3142
3302
  continue;
3143
3303
  }
3144
3304
  await fs7.cp(
3145
- path9.join(f.localSourceDir, entry2.name),
3146
- path9.join(dest, entry2.name)
3305
+ path10.join(f.localSourceDir, entry2.name),
3306
+ path10.join(dest, entry2.name)
3147
3307
  );
3148
3308
  }
3149
3309
  if (f.generatedManifest) {
3150
3310
  await fs7.writeFile(
3151
- path9.join(dest, "devcontainer-feature.json"),
3311
+ path10.join(dest, "devcontainer-feature.json"),
3152
3312
  JSON.stringify(f.generatedManifest, null, 2) + "\n"
3153
3313
  );
3154
3314
  }
3155
3315
  }
3156
3316
  for (const f of resolvedFeatures) {
3157
3317
  for (const sub of f.persistentHomePaths) {
3158
- await fs7.mkdir(path9.join(homeDir, sub), { recursive: true });
3318
+ await fs7.mkdir(path10.join(homeDir, sub), { recursive: true });
3159
3319
  }
3160
3320
  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)) {
3321
+ const filePath = path10.join(homeDir, entry2.path);
3322
+ await fs7.mkdir(path10.dirname(filePath), { recursive: true });
3323
+ if (!existsSync7(filePath)) {
3164
3324
  await fs7.writeFile(filePath, entry2.initialContent);
3165
3325
  }
3166
3326
  }
3167
3327
  }
3168
3328
  await writeClaudePermissionMode(targetDir, opts.features);
3329
+ await writeOpencodeConfig(targetDir, opts.name, opts.features);
3169
3330
  await writePostCreateScript(devcontainerDir, opts);
3170
- const composePath = path9.join(devcontainerDir, "compose.yaml");
3331
+ const composePath = path10.join(devcontainerDir, "compose.yaml");
3171
3332
  if (needsCompose(opts)) {
3172
3333
  await writeIfChanged(composePath, buildComposeYaml(opts, dockerMode));
3173
- } else if (existsSync6(composePath)) {
3334
+ } else if (existsSync7(composePath)) {
3174
3335
  await fs7.rm(composePath);
3175
3336
  }
3176
- const workspacePath = path9.join(targetDir, `${opts.name}.code-workspace`);
3337
+ const workspacePath = path10.join(targetDir, `${opts.name}.code-workspace`);
3177
3338
  let existingWorkspace;
3178
3339
  try {
3179
3340
  const raw = await fs7.readFile(workspacePath, "utf8");
@@ -3184,8 +3345,8 @@ async function writeScaffold(opts, targetDir, scaffoldOpts = {}) {
3184
3345
  const generated = buildCodeWorkspaceJson(opts);
3185
3346
  const merged = mergeCodeWorkspace(existingWorkspace, generated);
3186
3347
  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");
3348
+ const vscodeDir = path10.join(targetDir, ".vscode");
3349
+ const settingsPath = path10.join(vscodeDir, "settings.json");
3189
3350
  let existingSettings;
3190
3351
  try {
3191
3352
  existingSettings = JSON.parse(await fs7.readFile(settingsPath, "utf8"));
@@ -3207,6 +3368,7 @@ var init_scaffold = __esm({
3207
3368
  init_load_sync();
3208
3369
  init_generate_manifest();
3209
3370
  init_claude_settings();
3371
+ init_opencode_config();
3210
3372
  init_catalog();
3211
3373
  APT_PACKAGE_NAME_RE2 = /^[a-z0-9][a-z0-9.+-]*$/;
3212
3374
  FEATURE_REF_RE2 = /^[a-z0-9.-]+(\/[a-z0-9._-]+)+:[a-z0-9._-]+$/;
@@ -3660,8 +3822,8 @@ function removeRepoFromDoc(doc, urlOrPath) {
3660
3822
  if (!isMap2(item)) return false;
3661
3823
  const url = item.get("url");
3662
3824
  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;
3825
+ const path28 = item.get("path");
3826
+ const effectivePath = typeof path28 === "string" ? path28 : typeof url === "string" ? deriveRepoName(url) : void 0;
3665
3827
  return effectivePath === urlOrPath;
3666
3828
  });
3667
3829
  if (idx < 0) return false;
@@ -3696,9 +3858,9 @@ var init_yml = __esm({
3696
3858
 
3697
3859
  // src/modify/index.ts
3698
3860
  import { promises as fs8 } from "fs";
3699
- import { consola } from "consola";
3861
+ import { consola as consola2 } from "consola";
3700
3862
  import { createPatch } from "diff";
3701
- import path10 from "path";
3863
+ import path11 from "path";
3702
3864
  function runAddLanguage(input) {
3703
3865
  const spec = parseLanguageSpec(input.language);
3704
3866
  if (!spec || !BUILTIN_LANGUAGES.has(spec.name) && !LANGUAGE_CATALOG[spec.name]) {
@@ -3783,7 +3945,7 @@ async function runAddRepo(input) {
3783
3945
  "Missing repo URL. Usage: monoceros add-repo <containername> <url>."
3784
3946
  );
3785
3947
  }
3786
- const path27 = (input.path ?? deriveRepoName(url)).trim();
3948
+ const path28 = (input.path ?? deriveRepoName(url)).trim();
3787
3949
  const hasName = typeof input.gitName === "string" && input.gitName.trim().length > 0;
3788
3950
  const hasEmail = typeof input.gitEmail === "string" && input.gitEmail.trim().length > 0;
3789
3951
  if (hasName !== hasEmail) {
@@ -3820,7 +3982,7 @@ async function runAddRepo(input) {
3820
3982
  const providerToWrite = !canonical && explicitProvider ? explicitProvider : void 0;
3821
3983
  const entry2 = {
3822
3984
  url,
3823
- path: path27,
3985
+ path: path28,
3824
3986
  ...hasName && hasEmail ? {
3825
3987
  gitUser: {
3826
3988
  name: input.gitName.trim(),
@@ -3952,7 +4114,7 @@ async function tryCloneInRunningContainer(input, entry2) {
3952
4114
  logger.info(
3953
4115
  `Cloned ${entry2.url} into /workspaces/${containerName2}/${targetRel} inside the running container.`
3954
4116
  );
3955
- void path10;
4117
+ void path11;
3956
4118
  }
3957
4119
  function shquote(value) {
3958
4120
  return `'${value.replace(/'/g, `'\\''`)}'`;
@@ -4194,9 +4356,9 @@ async function mutate(opts, apply) {
4194
4356
  }
4195
4357
  function defaultLogger() {
4196
4358
  return {
4197
- info: (m) => consola.info(m),
4198
- success: (m) => consola.success(m),
4199
- warn: (m) => consola.warn(m)
4359
+ info: (m) => consola2.info(m),
4360
+ success: (m) => consola2.success(m),
4361
+ warn: (m) => consola2.warn(m)
4200
4362
  };
4201
4363
  }
4202
4364
  async function syncPortsToProxy(input) {
@@ -4276,7 +4438,7 @@ var init_modify = __esm({
4276
4438
  init_scaffold();
4277
4439
  init_yml();
4278
4440
  defaultConfirm = async (message) => {
4279
- const result = await consola.prompt(message, {
4441
+ const result = await consola2.prompt(message, {
4280
4442
  type: "confirm",
4281
4443
  initial: false
4282
4444
  });
@@ -4287,7 +4449,7 @@ var init_modify = __esm({
4287
4449
 
4288
4450
  // src/commands/add-apt-packages.ts
4289
4451
  import { defineCommand } from "citty";
4290
- import { consola as consola2 } from "consola";
4452
+ import { consola as consola3 } from "consola";
4291
4453
  var addAptPackagesCommand;
4292
4454
  var init_add_apt_packages = __esm({
4293
4455
  "src/commands/add-apt-packages.ts"() {
@@ -4316,7 +4478,7 @@ var init_add_apt_packages = __esm({
4316
4478
  async run({ args }) {
4317
4479
  const packages = [...getInnerArgs()];
4318
4480
  if (packages.length === 0) {
4319
- consola2.error(
4481
+ consola3.error(
4320
4482
  "No package names given. Usage: `monoceros add-apt-packages <containername> [--yes] -- <pkg> [<pkg> \u2026]`."
4321
4483
  );
4322
4484
  process.exit(1);
@@ -4329,7 +4491,7 @@ var init_add_apt_packages = __esm({
4329
4491
  });
4330
4492
  process.exit(result.status === "aborted" ? 1 : 0);
4331
4493
  } catch (err) {
4332
- consola2.error(err instanceof Error ? err.message : String(err));
4494
+ consola3.error(err instanceof Error ? err.message : String(err));
4333
4495
  process.exit(1);
4334
4496
  }
4335
4497
  }
@@ -4339,7 +4501,7 @@ var init_add_apt_packages = __esm({
4339
4501
 
4340
4502
  // src/commands/add-feature.ts
4341
4503
  import { defineCommand as defineCommand2 } from "citty";
4342
- import { consola as consola3 } from "consola";
4504
+ import { consola as consola4 } from "consola";
4343
4505
  function parseOptionsAfterDashes(tokens) {
4344
4506
  const result = {};
4345
4507
  for (const token of tokens) {
@@ -4399,7 +4561,7 @@ var init_add_feature = __esm({
4399
4561
  try {
4400
4562
  options = parseOptionsAfterDashes(getInnerArgs());
4401
4563
  } catch (err) {
4402
- consola3.error(err instanceof Error ? err.message : String(err));
4564
+ consola4.error(err instanceof Error ? err.message : String(err));
4403
4565
  process.exit(1);
4404
4566
  }
4405
4567
  try {
@@ -4411,7 +4573,7 @@ var init_add_feature = __esm({
4411
4573
  });
4412
4574
  process.exit(result.status === "aborted" ? 1 : 0);
4413
4575
  } catch (err) {
4414
- consola3.error(err instanceof Error ? err.message : String(err));
4576
+ consola4.error(err instanceof Error ? err.message : String(err));
4415
4577
  process.exit(1);
4416
4578
  }
4417
4579
  }
@@ -4421,7 +4583,7 @@ var init_add_feature = __esm({
4421
4583
 
4422
4584
  // src/commands/add-from-url.ts
4423
4585
  import { defineCommand as defineCommand3 } from "citty";
4424
- import { consola as consola4 } from "consola";
4586
+ import { consola as consola5 } from "consola";
4425
4587
  function printSecurityWarning(url) {
4426
4588
  const w = (line) => process.stderr.write(line + "\n");
4427
4589
  w("");
@@ -4490,7 +4652,7 @@ var init_add_from_url = __esm({
4490
4652
  });
4491
4653
  process.exit(result.status === "aborted" ? 1 : 0);
4492
4654
  } catch (err) {
4493
- consola4.error(err instanceof Error ? err.message : String(err));
4655
+ consola5.error(err instanceof Error ? err.message : String(err));
4494
4656
  process.exit(1);
4495
4657
  }
4496
4658
  }
@@ -4500,7 +4662,7 @@ var init_add_from_url = __esm({
4500
4662
 
4501
4663
  // src/commands/add-repo.ts
4502
4664
  import { defineCommand as defineCommand4 } from "citty";
4503
- import { consola as consola5 } from "consola";
4665
+ import { consola as consola6 } from "consola";
4504
4666
  var addRepoCommand;
4505
4667
  var init_add_repo = __esm({
4506
4668
  "src/commands/add-repo.ts"() {
@@ -4559,7 +4721,7 @@ var init_add_repo = __esm({
4559
4721
  });
4560
4722
  process.exit(result.status === "aborted" ? 1 : 0);
4561
4723
  } catch (err) {
4562
- consola5.error(err instanceof Error ? err.message : String(err));
4724
+ consola6.error(err instanceof Error ? err.message : String(err));
4563
4725
  process.exit(1);
4564
4726
  }
4565
4727
  }
@@ -4569,7 +4731,7 @@ var init_add_repo = __esm({
4569
4731
 
4570
4732
  // src/commands/add-language.ts
4571
4733
  import { defineCommand as defineCommand5 } from "citty";
4572
- import { consola as consola6 } from "consola";
4734
+ import { consola as consola7 } from "consola";
4573
4735
  var addLanguageCommand;
4574
4736
  var init_add_language = __esm({
4575
4737
  "src/commands/add-language.ts"() {
@@ -4608,7 +4770,7 @@ var init_add_language = __esm({
4608
4770
  });
4609
4771
  process.exit(result.status === "aborted" ? 1 : 0);
4610
4772
  } catch (err) {
4611
- consola6.error(err instanceof Error ? err.message : String(err));
4773
+ consola7.error(err instanceof Error ? err.message : String(err));
4612
4774
  process.exit(1);
4613
4775
  }
4614
4776
  }
@@ -4618,7 +4780,7 @@ var init_add_language = __esm({
4618
4780
 
4619
4781
  // src/commands/add-port.ts
4620
4782
  import { defineCommand as defineCommand6 } from "citty";
4621
- import { consola as consola7 } from "consola";
4783
+ import { consola as consola8 } from "consola";
4622
4784
  function coerceToken(raw) {
4623
4785
  const n = Number(raw);
4624
4786
  return Number.isFinite(n) ? n : raw;
@@ -4656,7 +4818,7 @@ var init_add_port = __esm({
4656
4818
  async run({ args }) {
4657
4819
  const tokens = [...getInnerArgs()];
4658
4820
  if (tokens.length === 0) {
4659
- consola7.error(
4821
+ consola8.error(
4660
4822
  "No ports given. Usage: `monoceros add-port <containername> [--yes] [--default] -- <port> [<port> \u2026]`."
4661
4823
  );
4662
4824
  process.exit(1);
@@ -4670,7 +4832,7 @@ var init_add_port = __esm({
4670
4832
  });
4671
4833
  process.exit(result.status === "aborted" ? 1 : 0);
4672
4834
  } catch (err) {
4673
- consola7.error(err instanceof Error ? err.message : String(err));
4835
+ consola8.error(err instanceof Error ? err.message : String(err));
4674
4836
  process.exit(1);
4675
4837
  }
4676
4838
  }
@@ -4680,7 +4842,7 @@ var init_add_port = __esm({
4680
4842
 
4681
4843
  // src/commands/add-service.ts
4682
4844
  import { defineCommand as defineCommand7 } from "citty";
4683
- import { consola as consola8 } from "consola";
4845
+ import { consola as consola9 } from "consola";
4684
4846
  var addServiceCommand;
4685
4847
  var init_add_service = __esm({
4686
4848
  "src/commands/add-service.ts"() {
@@ -4724,7 +4886,7 @@ var init_add_service = __esm({
4724
4886
  });
4725
4887
  process.exit(result.status === "aborted" ? 1 : 0);
4726
4888
  } catch (err) {
4727
- consola8.error(err instanceof Error ? err.message : String(err));
4889
+ consola9.error(err instanceof Error ? err.message : String(err));
4728
4890
  process.exit(1);
4729
4891
  }
4730
4892
  }
@@ -4734,7 +4896,7 @@ var init_add_service = __esm({
4734
4896
 
4735
4897
  // src/config/state.ts
4736
4898
  import { promises as fs9 } from "fs";
4737
- import path11 from "path";
4899
+ import path12 from "path";
4738
4900
  function buildStateFile(opts) {
4739
4901
  return {
4740
4902
  schemaVersion: CONFIG_SCHEMA_VERSION,
@@ -4745,7 +4907,7 @@ function buildStateFile(opts) {
4745
4907
  };
4746
4908
  }
4747
4909
  function stateFilePath(targetDir) {
4748
- return path11.join(targetDir, ".monoceros", "state.json");
4910
+ return path12.join(targetDir, ".monoceros", "state.json");
4749
4911
  }
4750
4912
  async function readStateFile(targetDir) {
4751
4913
  try {
@@ -4756,7 +4918,7 @@ async function readStateFile(targetDir) {
4756
4918
  }
4757
4919
  }
4758
4920
  async function writeStateFile(targetDir, state) {
4759
- const monocerosDir = path11.join(targetDir, ".monoceros");
4921
+ const monocerosDir = path12.join(targetDir, ".monoceros");
4760
4922
  await fs9.mkdir(monocerosDir, { recursive: true });
4761
4923
  await fs9.writeFile(
4762
4924
  stateFilePath(targetDir),
@@ -4868,7 +5030,7 @@ var init_transform = __esm({
4868
5030
 
4869
5031
  // src/apply/apply-log.ts
4870
5032
  import { createWriteStream, mkdirSync } from "fs";
4871
- import path12 from "path";
5033
+ import path13 from "path";
4872
5034
  import { Writable } from "stream";
4873
5035
  function safeIsoStamp(d) {
4874
5036
  return d.toISOString().replace(/[:.]/g, "-");
@@ -4878,7 +5040,7 @@ function createApplyLog(opts) {
4878
5040
  const dir = containerLogsDir(opts.name, opts.home);
4879
5041
  mkdirSync(dir, { recursive: true });
4880
5042
  const file = `apply-${opts.name}-${safeIsoStamp(now)}.log`;
4881
- const fullPath = path12.join(dir, file);
5043
+ const fullPath = path13.join(dir, file);
4882
5044
  const stream = createWriteStream(fullPath, { flags: "w" });
4883
5045
  const header = [
4884
5046
  `# monoceros apply log`,
@@ -5745,7 +5907,7 @@ var init_markers = __esm({
5745
5907
 
5746
5908
  // src/briefing/index.ts
5747
5909
  import { promises as fs10 } from "fs";
5748
- import path13 from "path";
5910
+ import path14 from "path";
5749
5911
  async function writeBriefing(input) {
5750
5912
  const subCommands = input.subCommands ?? await loadSubCommandsDynamic();
5751
5913
  const manifestLoader = input.manifestLoader ?? ((ref) => loadFeatureManifestSummary(ref));
@@ -5758,12 +5920,12 @@ async function writeBriefing(input) {
5758
5920
  );
5759
5921
  const claudeBody = generateClaudeMd();
5760
5922
  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");
5923
+ await writeMarkerAware(path14.join(input.targetDir, "AGENTS.md"), agentsBody);
5924
+ await writeMarkerAware(path14.join(input.targetDir, "CLAUDE.md"), claudeBody);
5925
+ const monocerosDir = path14.join(input.targetDir, ".monoceros");
5764
5926
  await fs10.mkdir(monocerosDir, { recursive: true });
5765
5927
  await fs10.writeFile(
5766
- path13.join(monocerosDir, "commands.md"),
5928
+ path14.join(monocerosDir, "commands.md"),
5767
5929
  commandsBody,
5768
5930
  "utf8"
5769
5931
  );
@@ -5922,7 +6084,7 @@ var init_runtime_pull_hint = __esm({
5922
6084
  import { spawn as spawn4 } from "child_process";
5923
6085
  import { readFileSync as readFileSync4 } from "fs";
5924
6086
  import { createRequire } from "module";
5925
- import path14 from "path";
6087
+ import path15 from "path";
5926
6088
  function devcontainerCliPath() {
5927
6089
  if (cachedBinaryPath) return cachedBinaryPath;
5928
6090
  const pkgJsonPath = require_.resolve("@devcontainers/cli/package.json");
@@ -5931,7 +6093,7 @@ function devcontainerCliPath() {
5931
6093
  if (!binEntry) {
5932
6094
  throw new Error("Could not resolve @devcontainers/cli bin entry.");
5933
6095
  }
5934
- cachedBinaryPath = path14.resolve(path14.dirname(pkgJsonPath), binEntry);
6096
+ cachedBinaryPath = path15.resolve(path15.dirname(pkgJsonPath), binEntry);
5935
6097
  return cachedBinaryPath;
5936
6098
  }
5937
6099
  var require_, cachedBinaryPath, spawnDevcontainer;
@@ -6005,10 +6167,10 @@ var init_cli = __esm({
6005
6167
 
6006
6168
  // src/devcontainer/compose.ts
6007
6169
  import { spawn as spawn5 } from "child_process";
6008
- import { existsSync as existsSync7 } from "fs";
6009
- import path15 from "path";
6170
+ import { existsSync as existsSync8 } from "fs";
6171
+ import path16 from "path";
6010
6172
  import { Writable as Writable3 } from "stream";
6011
- import { consola as consola9 } from "consola";
6173
+ import { consola as consola10 } from "consola";
6012
6174
  async function findContainerIds(filters, exec = spawnDocker) {
6013
6175
  const ids = /* @__PURE__ */ new Set();
6014
6176
  for (const filter of filters) {
@@ -6056,16 +6218,16 @@ async function cleanupDockerObjects(opts) {
6056
6218
  return { exitCode: rmExit, removedIds: ids };
6057
6219
  }
6058
6220
  function composeProjectName(root) {
6059
- return `${path15.basename(root)}_devcontainer`;
6221
+ return `${path16.basename(root)}_devcontainer`;
6060
6222
  }
6061
6223
  function resolveCompose(root) {
6062
- if (!existsSync7(path15.join(root, ".devcontainer"))) {
6224
+ if (!existsSync8(path16.join(root, ".devcontainer"))) {
6063
6225
  throw new Error(
6064
6226
  `No .devcontainer/ at ${root}. Run \`monoceros apply <name>\` first.`
6065
6227
  );
6066
6228
  }
6067
- const composeFile = path15.join(root, ".devcontainer", "compose.yaml");
6068
- if (!existsSync7(composeFile)) {
6229
+ const composeFile = path16.join(root, ".devcontainer", "compose.yaml");
6230
+ if (!existsSync8(composeFile)) {
6069
6231
  throw new Error(
6070
6232
  `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
6233
  );
@@ -6080,7 +6242,7 @@ async function runComposeAction(buildSubArgs, opts) {
6080
6242
  }
6081
6243
  async function runStart(opts) {
6082
6244
  resolveCompose(opts.root);
6083
- const logger = opts.logger ?? { info: (msg) => consola9.info(msg) };
6245
+ const logger = opts.logger ?? { info: (msg) => consola10.info(msg) };
6084
6246
  const spawnFn = opts.spawn ?? spawnDevcontainer;
6085
6247
  logger.info(`Bringing devcontainer up at ${opts.root}\u2026`);
6086
6248
  return spawnFn(
@@ -6326,14 +6488,14 @@ var init_images = __esm({
6326
6488
  });
6327
6489
 
6328
6490
  // src/config/machine-state.ts
6329
- import { promises as fsp3 } from "fs";
6330
- import path16 from "path";
6491
+ import { promises as fsp4 } from "fs";
6492
+ import path17 from "path";
6331
6493
  function machineStatePath(home = monocerosHome()) {
6332
- return path16.join(home, ".machine-state.json");
6494
+ return path17.join(home, ".machine-state.json");
6333
6495
  }
6334
6496
  async function readMachineState(home = monocerosHome()) {
6335
6497
  try {
6336
- const raw = await fsp3.readFile(machineStatePath(home), "utf8");
6498
+ const raw = await fsp4.readFile(machineStatePath(home), "utf8");
6337
6499
  const parsed = JSON.parse(raw);
6338
6500
  if (typeof parsed === "object" && parsed !== null) {
6339
6501
  return parsed;
@@ -6343,7 +6505,7 @@ async function readMachineState(home = monocerosHome()) {
6343
6505
  return {};
6344
6506
  }
6345
6507
  async function writeMachineState(state, home = monocerosHome()) {
6346
- await fsp3.writeFile(
6508
+ await fsp4.writeFile(
6347
6509
  machineStatePath(home),
6348
6510
  `${JSON.stringify(state, null, 2)}
6349
6511
  `
@@ -6455,8 +6617,8 @@ var init_docker_mode = __esm({
6455
6617
  // src/devcontainer/identity.ts
6456
6618
  import { spawn as spawn7 } from "child_process";
6457
6619
  import { promises as fs11 } from "fs";
6458
- import path17 from "path";
6459
- import { consola as consola10 } from "consola";
6620
+ import path18 from "path";
6621
+ import { consola as consola11 } from "consola";
6460
6622
  async function resolveIdentityWithPrompt(options = {}) {
6461
6623
  const spawnFn = options.spawn ?? realGitConfigGet;
6462
6624
  const promptFn = options.prompt ?? realIdentityPrompt;
@@ -6511,8 +6673,8 @@ async function resolveIdentityWithPrompt(options = {}) {
6511
6673
  };
6512
6674
  }
6513
6675
  async function collectGitIdentity(devContainerRoot, options = {}) {
6514
- const gitconfigDir = path17.join(devContainerRoot, ".monoceros");
6515
- const gitconfigPath = path17.join(gitconfigDir, "gitconfig");
6676
+ const gitconfigDir = path18.join(devContainerRoot, ".monoceros");
6677
+ const gitconfigPath = path18.join(gitconfigDir, "gitconfig");
6516
6678
  const logger = options.logger ?? { info: () => {
6517
6679
  }, warn: () => {
6518
6680
  } };
@@ -6605,7 +6767,7 @@ var init_identity = __esm({
6605
6767
  return void 0;
6606
6768
  }
6607
6769
  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" });
6770
+ const value = await consola11.prompt(`${label}:`, { type: "text" });
6609
6771
  if (typeof value !== "string") return void 0;
6610
6772
  const trimmed = value.trim();
6611
6773
  return trimmed.length > 0 ? trimmed : void 0;
@@ -6615,7 +6777,7 @@ var init_identity = __esm({
6615
6777
  return ctx.reason === "prompt" ? "g" : "n";
6616
6778
  }
6617
6779
  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, {
6780
+ const choice = await consola11.prompt(heading, {
6619
6781
  type: "select",
6620
6782
  options: [
6621
6783
  {
@@ -6646,14 +6808,14 @@ var init_identity = __esm({
6646
6808
  });
6647
6809
 
6648
6810
  // src/apply/index.ts
6649
- import { existsSync as existsSync8, promises as fs12 } from "fs";
6650
- import { consola as consola11 } from "consola";
6811
+ import { existsSync as existsSync9, promises as fs12 } from "fs";
6812
+ import { consola as consola12 } from "consola";
6651
6813
  async function runApply(opts) {
6652
6814
  const home = opts.monocerosHome ?? monocerosHome();
6653
6815
  const logger = opts.logger ?? {
6654
- info: (msg) => consola11.info(msg),
6655
- success: (msg) => consola11.success(msg),
6656
- warn: (msg) => consola11.warn(msg),
6816
+ info: (msg) => consola12.info(msg),
6817
+ success: (msg) => consola12.success(msg),
6818
+ warn: (msg) => consola12.warn(msg),
6657
6819
  // Default section renderer: empty line, bold-underlined "▸ Label",
6658
6820
  // empty line. Mirrors install.sh's section visuals.
6659
6821
  section: (label) => process.stderr.write(`
@@ -6668,7 +6830,7 @@ ${sectionLine(label)}
6668
6830
  );
6669
6831
  }
6670
6832
  const ymlPath = containerConfigPath(opts.name, home);
6671
- if (!existsSync8(ymlPath)) {
6833
+ if (!existsSync9(ymlPath)) {
6672
6834
  throw new Error(
6673
6835
  `No such config: ${ymlPath}. Run \`monoceros init <template> ${opts.name}\` first.`
6674
6836
  );
@@ -6941,7 +7103,7 @@ ${stripAnsi(formatted)}
6941
7103
  return { targetDir, configPath: ymlPath, containerExitCode: exitCode };
6942
7104
  }
6943
7105
  async function assertSafeTargetDir(targetDir, expectedOrigin) {
6944
- if (!existsSync8(targetDir)) return;
7106
+ if (!existsSync9(targetDir)) return;
6945
7107
  const entries = await fs12.readdir(targetDir);
6946
7108
  if (entries.length === 0) return;
6947
7109
  const state = await readStateFile(targetDir);
@@ -7071,18 +7233,18 @@ var CLI_VERSION;
7071
7233
  var init_version = __esm({
7072
7234
  "src/version.ts"() {
7073
7235
  "use strict";
7074
- CLI_VERSION = true ? "1.22.2" : "dev";
7236
+ CLI_VERSION = true ? "1.23.1" : "dev";
7075
7237
  }
7076
7238
  });
7077
7239
 
7078
7240
  // src/commands/_dispatch.ts
7079
- import { consola as consola12 } from "consola";
7241
+ import { consola as consola13 } from "consola";
7080
7242
  async function dispatch(runner) {
7081
7243
  try {
7082
7244
  const exitCode = await runner();
7083
7245
  process.exit(exitCode);
7084
7246
  } catch (err) {
7085
- consola12.error(err instanceof Error ? err.message : String(err));
7247
+ consola13.error(err instanceof Error ? err.message : String(err));
7086
7248
  process.exit(1);
7087
7249
  }
7088
7250
  }
@@ -7261,8 +7423,8 @@ var init_completion = __esm({
7261
7423
  });
7262
7424
 
7263
7425
  // src/completion/resolve.ts
7264
- import { existsSync as existsSync9, promises as fs13 } from "fs";
7265
- import path18 from "path";
7426
+ import { existsSync as existsSync10, promises as fs13 } from "fs";
7427
+ import path19 from "path";
7266
7428
  async function resolveCompletions(line, point, opts = {}) {
7267
7429
  const { prev, current } = parseCompletionLine(line, point);
7268
7430
  const ctx = { prev, current, opts };
@@ -7411,8 +7573,8 @@ function filterPrefix(values, fragment) {
7411
7573
  }
7412
7574
  async function listContainerNames(ctx) {
7413
7575
  const home = ctx.opts.monocerosHome ?? monocerosHome();
7414
- const dir = path18.join(home, "container-configs");
7415
- if (!existsSync9(dir)) return [];
7576
+ const dir = path19.join(home, "container-configs");
7577
+ if (!existsSync10(dir)) return [];
7416
7578
  const entries = await fs13.readdir(dir);
7417
7579
  return entries.filter((e) => e.endsWith(".yml")).map((e) => e.slice(0, -".yml".length)).sort();
7418
7580
  }
@@ -8080,14 +8242,14 @@ var init_generator = __esm({
8080
8242
  });
8081
8243
 
8082
8244
  // 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";
8245
+ import { existsSync as existsSync11, promises as fs14 } from "fs";
8246
+ import path20 from "path";
8247
+ import { consola as consola14 } from "consola";
8086
8248
  async function runInit(opts) {
8087
8249
  const home = opts.monocerosHome ?? monocerosHome();
8088
8250
  const logger = opts.logger ?? {
8089
- success: (msg) => consola13.success(msg),
8090
- info: (msg) => consola13.info(msg)
8251
+ success: (msg) => consola14.success(msg),
8252
+ info: (msg) => consola14.info(msg)
8091
8253
  };
8092
8254
  if (!REGEX.solutionName.test(opts.name)) {
8093
8255
  throw new Error(
@@ -8095,12 +8257,12 @@ async function runInit(opts) {
8095
8257
  );
8096
8258
  }
8097
8259
  const dest = containerConfigPath(opts.name, home);
8098
- if (existsSync10(dest)) {
8260
+ if (existsSync11(dest)) {
8099
8261
  throw new Error(
8100
8262
  `Config already exists: ${dest}. Delete it manually before re-running \`monoceros init\` \u2014 this protects any hand-edits.`
8101
8263
  );
8102
8264
  }
8103
- const componentsRoot = opts.workbenchRoot ? path19.join(opts.workbenchRoot, "components") : componentsRootDir();
8265
+ const componentsRoot = opts.workbenchRoot ? path20.join(opts.workbenchRoot, "components") : componentsRootDir();
8104
8266
  const catalog = await loadComponentCatalog(componentsRoot);
8105
8267
  if (catalog.size === 0) {
8106
8268
  throw new Error(
@@ -8191,8 +8353,8 @@ async function runInit(opts) {
8191
8353
  }
8192
8354
  await ensureEnvVars(envPath, opts.name, seedVars);
8193
8355
  const documented = !anyComposed;
8194
- const ymlRel = path19.relative(home, dest);
8195
- const envRel = path19.relative(home, envPath);
8356
+ const ymlRel = path20.relative(home, dest);
8357
+ const envRel = path20.relative(home, envPath);
8196
8358
  if (documented) {
8197
8359
  logger.success(`Wrote documented default to ${ymlRel} and ${envRel}.`);
8198
8360
  logger.info(
@@ -8336,7 +8498,7 @@ var init_init = __esm({
8336
8498
 
8337
8499
  // src/commands/init.ts
8338
8500
  import { defineCommand as defineCommand11 } from "citty";
8339
- import { consola as consola14 } from "consola";
8501
+ import { consola as consola15 } from "consola";
8340
8502
  function collectListFlag(flag, rawArgs) {
8341
8503
  const eq = `${flag}=`;
8342
8504
  const pieces = [];
@@ -8462,7 +8624,7 @@ var init_init2 = __esm({
8462
8624
  ...ports && ports.length > 0 ? { withPorts: ports } : {}
8463
8625
  });
8464
8626
  } catch (err) {
8465
- consola14.error(err instanceof Error ? err.message : String(err));
8627
+ consola15.error(err instanceof Error ? err.message : String(err));
8466
8628
  process.exit(1);
8467
8629
  }
8468
8630
  }
@@ -8511,7 +8673,7 @@ var init_expand = __esm({
8511
8673
 
8512
8674
  // src/commands/list-components.ts
8513
8675
  import { defineCommand as defineCommand12 } from "citty";
8514
- import { consola as consola15 } from "consola";
8676
+ import { consola as consola16 } from "consola";
8515
8677
  var CATEGORY_LABELS, CATEGORY_ORDER, listComponentsCommand;
8516
8678
  var init_list_components = __esm({
8517
8679
  "src/commands/list-components.ts"() {
@@ -8540,7 +8702,7 @@ var init_list_components = __esm({
8540
8702
  try {
8541
8703
  const catalog = expandSelectable(await loadDescriptorCatalog());
8542
8704
  if (catalog.size === 0) {
8543
- consola15.warn(
8705
+ consola16.warn(
8544
8706
  "No components found. The workbench checkout looks incomplete."
8545
8707
  );
8546
8708
  process.exit(0);
@@ -8591,7 +8753,7 @@ var init_list_components = __esm({
8591
8753
  }
8592
8754
  process.exit(0);
8593
8755
  } catch (err) {
8594
- consola15.error(err instanceof Error ? err.message : String(err));
8756
+ consola16.error(err instanceof Error ? err.message : String(err));
8595
8757
  process.exit(1);
8596
8758
  }
8597
8759
  }
@@ -8601,8 +8763,8 @@ var init_list_components = __esm({
8601
8763
 
8602
8764
  // src/commands/logs.ts
8603
8765
  import { spawn as spawn8 } from "child_process";
8604
- import { existsSync as existsSync11 } from "fs";
8605
- import path20 from "path";
8766
+ import { existsSync as existsSync12 } from "fs";
8767
+ import path21 from "path";
8606
8768
  import { defineCommand as defineCommand13 } from "citty";
8607
8769
  function tailLogFile(file, follow) {
8608
8770
  const [cmd, args] = follow ? ["tail", ["-F", file]] : ["cat", [file]];
@@ -8645,8 +8807,8 @@ var init_logs = __esm({
8645
8807
  run({ args }) {
8646
8808
  const service = typeof args.service === "string" ? args.service : void 0;
8647
8809
  if (service) {
8648
- const logFile = path20.join(containerLogsDir(args.name), `${service}.log`);
8649
- if (existsSync11(logFile)) {
8810
+ const logFile = path21.join(containerLogsDir(args.name), `${service}.log`);
8811
+ if (existsSync12(logFile)) {
8650
8812
  return dispatch(() => tailLogFile(logFile, args.follow));
8651
8813
  }
8652
8814
  }
@@ -8664,10 +8826,10 @@ var init_logs = __esm({
8664
8826
 
8665
8827
  // src/commands/port.ts
8666
8828
  import { defineCommand as defineCommand14 } from "citty";
8667
- import { consola as consola16 } from "consola";
8829
+ import { consola as consola17 } from "consola";
8668
8830
  async function runPortListing(opts) {
8669
8831
  const out = opts.out ?? process.stdout;
8670
- const info = opts.info ?? ((m) => consola16.info(m));
8832
+ const info = opts.info ?? ((m) => consola17.info(m));
8671
8833
  const parsed = await readConfig(
8672
8834
  containerConfigPath(opts.name, opts.monocerosHome)
8673
8835
  );
@@ -8743,7 +8905,7 @@ var init_port = __esm({
8743
8905
  const code = await runPortListing({ name: args.name });
8744
8906
  process.exit(code);
8745
8907
  } catch (err) {
8746
- consola16.error(err instanceof Error ? err.message : String(err));
8908
+ consola17.error(err instanceof Error ? err.message : String(err));
8747
8909
  process.exit(1);
8748
8910
  }
8749
8911
  }
@@ -8753,7 +8915,7 @@ var init_port = __esm({
8753
8915
 
8754
8916
  // src/commands/remove-apt-packages.ts
8755
8917
  import { defineCommand as defineCommand15 } from "citty";
8756
- import { consola as consola17 } from "consola";
8918
+ import { consola as consola18 } from "consola";
8757
8919
  var removeAptPackagesCommand;
8758
8920
  var init_remove_apt_packages = __esm({
8759
8921
  "src/commands/remove-apt-packages.ts"() {
@@ -8782,7 +8944,7 @@ var init_remove_apt_packages = __esm({
8782
8944
  async run({ args }) {
8783
8945
  const packages = [...getInnerArgs()];
8784
8946
  if (packages.length === 0) {
8785
- consola17.error(
8947
+ consola18.error(
8786
8948
  "No package names given. Usage: `monoceros remove-apt-packages <containername> [--yes] -- <pkg> [<pkg> \u2026]`."
8787
8949
  );
8788
8950
  process.exit(1);
@@ -8795,7 +8957,7 @@ var init_remove_apt_packages = __esm({
8795
8957
  });
8796
8958
  process.exit(result.status === "aborted" ? 1 : 0);
8797
8959
  } catch (err) {
8798
- consola17.error(err instanceof Error ? err.message : String(err));
8960
+ consola18.error(err instanceof Error ? err.message : String(err));
8799
8961
  process.exit(1);
8800
8962
  }
8801
8963
  }
@@ -8805,7 +8967,7 @@ var init_remove_apt_packages = __esm({
8805
8967
 
8806
8968
  // src/commands/remove-feature.ts
8807
8969
  import { defineCommand as defineCommand16 } from "citty";
8808
- import { consola as consola18 } from "consola";
8970
+ import { consola as consola19 } from "consola";
8809
8971
  var removeFeatureCommand;
8810
8972
  var init_remove_feature = __esm({
8811
8973
  "src/commands/remove-feature.ts"() {
@@ -8844,7 +9006,7 @@ var init_remove_feature = __esm({
8844
9006
  });
8845
9007
  process.exit(result.status === "aborted" ? 1 : 0);
8846
9008
  } catch (err) {
8847
- consola18.error(err instanceof Error ? err.message : String(err));
9009
+ consola19.error(err instanceof Error ? err.message : String(err));
8848
9010
  process.exit(1);
8849
9011
  }
8850
9012
  }
@@ -8853,15 +9015,15 @@ var init_remove_feature = __esm({
8853
9015
  });
8854
9016
 
8855
9017
  // 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";
9018
+ import { existsSync as existsSync13, promises as fs15 } from "fs";
9019
+ import path22 from "path";
9020
+ import { consola as consola20 } from "consola";
8859
9021
  async function runRemove(opts) {
8860
9022
  const home = opts.monocerosHome ?? monocerosHome();
8861
9023
  const logger = opts.logger ?? {
8862
- info: (msg) => consola19.info(msg),
8863
- success: (msg) => consola19.success(msg),
8864
- warn: (msg) => consola19.warn(msg)
9024
+ info: (msg) => consola20.info(msg),
9025
+ success: (msg) => consola20.success(msg),
9026
+ warn: (msg) => consola20.warn(msg)
8865
9027
  };
8866
9028
  if (!REGEX.solutionName.test(opts.name)) {
8867
9029
  throw new Error(
@@ -8871,9 +9033,9 @@ async function runRemove(opts) {
8871
9033
  const ymlPath = containerConfigPath(opts.name, home);
8872
9034
  const envPath = containerEnvPath(opts.name, home);
8873
9035
  const containerPath = containerDir(opts.name, home);
8874
- const hasYml = existsSync12(ymlPath);
8875
- const hasEnv = existsSync12(envPath);
8876
- const hasContainer = existsSync12(containerPath);
9036
+ const hasYml = existsSync13(ymlPath);
9037
+ const hasEnv = existsSync13(envPath);
9038
+ const hasContainer = existsSync13(containerPath);
8877
9039
  if (!hasYml && !hasContainer) {
8878
9040
  throw new Error(
8879
9041
  `Nothing to remove for '${opts.name}': neither ${ymlPath} nor ${containerPath} exists.`
@@ -8899,16 +9061,16 @@ async function runRemove(opts) {
8899
9061
  let backupPath = null;
8900
9062
  if (!opts.noBackup && (hasYml || hasContainer)) {
8901
9063
  const ts = (opts.now ?? /* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
8902
- backupPath = path21.join(home, "container-backups", `${opts.name}-${ts}`);
9064
+ backupPath = path22.join(home, "container-backups", `${opts.name}-${ts}`);
8903
9065
  await fs15.mkdir(backupPath, { recursive: true });
8904
9066
  if (hasYml) {
8905
- await fs15.copyFile(ymlPath, path21.join(backupPath, `${opts.name}.yml`));
9067
+ await fs15.copyFile(ymlPath, path22.join(backupPath, `${opts.name}.yml`));
8906
9068
  }
8907
9069
  if (hasEnv) {
8908
- await fs15.copyFile(envPath, path21.join(backupPath, `${opts.name}.env`));
9070
+ await fs15.copyFile(envPath, path22.join(backupPath, `${opts.name}.env`));
8909
9071
  }
8910
9072
  if (hasContainer) {
8911
- await fs15.cp(containerPath, path21.join(backupPath, "container"), {
9073
+ await fs15.cp(containerPath, path22.join(backupPath, "container"), {
8912
9074
  recursive: true
8913
9075
  });
8914
9076
  }
@@ -8998,7 +9160,7 @@ var init_remove = __esm({
8998
9160
 
8999
9161
  // src/commands/remove.ts
9000
9162
  import { defineCommand as defineCommand17 } from "citty";
9001
- import { consola as consola20 } from "consola";
9163
+ import { consola as consola21 } from "consola";
9002
9164
  import { createInterface } from "readline/promises";
9003
9165
  var removeCommand;
9004
9166
  var init_remove2 = __esm({
@@ -9042,7 +9204,7 @@ var init_remove2 = __esm({
9042
9204
  const skipPrompt = args.yes === true;
9043
9205
  if (!skipPrompt) {
9044
9206
  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);
9207
+ consola21.warn(warning);
9046
9208
  const rl = createInterface({
9047
9209
  input: process.stdin,
9048
9210
  output: process.stdout
@@ -9050,7 +9212,7 @@ var init_remove2 = __esm({
9050
9212
  const answer = await rl.question("Continue? [y/N] ");
9051
9213
  rl.close();
9052
9214
  if (!/^y(es)?$/i.test(answer.trim())) {
9053
- consola20.info("Aborted. Nothing changed.");
9215
+ consola21.info("Aborted. Nothing changed.");
9054
9216
  process.exit(0);
9055
9217
  }
9056
9218
  }
@@ -9059,7 +9221,7 @@ var init_remove2 = __esm({
9059
9221
  ...noBackup ? { noBackup: true } : {}
9060
9222
  });
9061
9223
  } catch (err) {
9062
- consola20.error(err instanceof Error ? err.message : String(err));
9224
+ consola21.error(err instanceof Error ? err.message : String(err));
9063
9225
  process.exit(1);
9064
9226
  }
9065
9227
  }
@@ -9068,17 +9230,17 @@ var init_remove2 = __esm({
9068
9230
  });
9069
9231
 
9070
9232
  // 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";
9233
+ import { existsSync as existsSync14, promises as fs16 } from "fs";
9234
+ import path23 from "path";
9235
+ import { consola as consola22 } from "consola";
9074
9236
  async function runRestore(opts) {
9075
9237
  const home = opts.monocerosHome ?? monocerosHome();
9076
9238
  const logger = opts.logger ?? {
9077
- info: (msg) => consola21.info(msg),
9078
- success: (msg) => consola21.success(msg)
9239
+ info: (msg) => consola22.info(msg),
9240
+ success: (msg) => consola22.success(msg)
9079
9241
  };
9080
- const backup = path22.resolve(opts.backupPath);
9081
- if (!existsSync13(backup)) {
9242
+ const backup = path23.resolve(opts.backupPath);
9243
+ if (!existsSync14(backup)) {
9082
9244
  throw new Error(`Backup not found: ${backup}.`);
9083
9245
  }
9084
9246
  const stat = await fs16.stat(backup);
@@ -9099,24 +9261,24 @@ async function runRestore(opts) {
9099
9261
  }
9100
9262
  const ymlFile = ymlFiles[0];
9101
9263
  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);
9264
+ const containerInBackup = path23.join(backup, "container");
9265
+ const hasContainer = existsSync14(containerInBackup);
9266
+ const envInBackup = path23.join(backup, `${name}.env`);
9267
+ const hasEnv = existsSync14(envInBackup);
9106
9268
  const destYml = containerConfigPath(name, home);
9107
9269
  const destContainer = containerDir(name, home);
9108
- if (existsSync13(destYml)) {
9270
+ if (existsSync14(destYml)) {
9109
9271
  throw new Error(
9110
9272
  `Refusing to restore: ${destYml} already exists. Remove the current container first (\`monoceros remove ${name}\`) or rename the existing config.`
9111
9273
  );
9112
9274
  }
9113
- if (hasContainer && existsSync13(destContainer)) {
9275
+ if (hasContainer && existsSync14(destContainer)) {
9114
9276
  throw new Error(
9115
9277
  `Refusing to restore: ${destContainer} already exists. Remove the current container first (\`monoceros remove ${name}\`).`
9116
9278
  );
9117
9279
  }
9118
9280
  await fs16.mkdir(containerConfigsDir(home), { recursive: true });
9119
- await fs16.copyFile(path22.join(backup, ymlFile), destYml);
9281
+ await fs16.copyFile(path23.join(backup, ymlFile), destYml);
9120
9282
  if (hasEnv) {
9121
9283
  await fs16.copyFile(envInBackup, containerEnvPath(name, home));
9122
9284
  }
@@ -9142,7 +9304,7 @@ var init_restore = __esm({
9142
9304
 
9143
9305
  // src/commands/restore.ts
9144
9306
  import { defineCommand as defineCommand18 } from "citty";
9145
- import { consola as consola22 } from "consola";
9307
+ import { consola as consola23 } from "consola";
9146
9308
  var restoreCommand;
9147
9309
  var init_restore2 = __esm({
9148
9310
  "src/commands/restore.ts"() {
@@ -9165,7 +9327,7 @@ var init_restore2 = __esm({
9165
9327
  try {
9166
9328
  await runRestore({ backupPath: args["backup-path"] });
9167
9329
  } catch (err) {
9168
- consola22.error(err instanceof Error ? err.message : String(err));
9330
+ consola23.error(err instanceof Error ? err.message : String(err));
9169
9331
  process.exit(1);
9170
9332
  }
9171
9333
  }
@@ -9175,7 +9337,7 @@ var init_restore2 = __esm({
9175
9337
 
9176
9338
  // src/commands/remove-from-url.ts
9177
9339
  import { defineCommand as defineCommand19 } from "citty";
9178
- import { consola as consola23 } from "consola";
9340
+ import { consola as consola24 } from "consola";
9179
9341
  var removeFromUrlCommand;
9180
9342
  var init_remove_from_url = __esm({
9181
9343
  "src/commands/remove-from-url.ts"() {
@@ -9214,7 +9376,7 @@ var init_remove_from_url = __esm({
9214
9376
  });
9215
9377
  process.exit(result.status === "aborted" ? 1 : 0);
9216
9378
  } catch (err) {
9217
- consola23.error(err instanceof Error ? err.message : String(err));
9379
+ consola24.error(err instanceof Error ? err.message : String(err));
9218
9380
  process.exit(1);
9219
9381
  }
9220
9382
  }
@@ -9224,7 +9386,7 @@ var init_remove_from_url = __esm({
9224
9386
 
9225
9387
  // src/commands/remove-language.ts
9226
9388
  import { defineCommand as defineCommand20 } from "citty";
9227
- import { consola as consola24 } from "consola";
9389
+ import { consola as consola25 } from "consola";
9228
9390
  var removeLanguageCommand;
9229
9391
  var init_remove_language = __esm({
9230
9392
  "src/commands/remove-language.ts"() {
@@ -9263,7 +9425,7 @@ var init_remove_language = __esm({
9263
9425
  });
9264
9426
  process.exit(result.status === "aborted" ? 1 : 0);
9265
9427
  } catch (err) {
9266
- consola24.error(err instanceof Error ? err.message : String(err));
9428
+ consola25.error(err instanceof Error ? err.message : String(err));
9267
9429
  process.exit(1);
9268
9430
  }
9269
9431
  }
@@ -9273,7 +9435,7 @@ var init_remove_language = __esm({
9273
9435
 
9274
9436
  // src/commands/remove-port.ts
9275
9437
  import { defineCommand as defineCommand21 } from "citty";
9276
- import { consola as consola25 } from "consola";
9438
+ import { consola as consola26 } from "consola";
9277
9439
  function coerceToken2(raw) {
9278
9440
  const n = Number(raw);
9279
9441
  return Number.isFinite(n) ? n : raw;
@@ -9306,7 +9468,7 @@ var init_remove_port = __esm({
9306
9468
  async run({ args }) {
9307
9469
  const tokens = [...getInnerArgs()];
9308
9470
  if (tokens.length === 0) {
9309
- consola25.error(
9471
+ consola26.error(
9310
9472
  "No ports given. Usage: `monoceros remove-port <containername> [--yes] -- <port> [<port> \u2026]`."
9311
9473
  );
9312
9474
  process.exit(1);
@@ -9319,7 +9481,7 @@ var init_remove_port = __esm({
9319
9481
  });
9320
9482
  process.exit(result.status === "aborted" ? 1 : 0);
9321
9483
  } catch (err) {
9322
- consola25.error(err instanceof Error ? err.message : String(err));
9484
+ consola26.error(err instanceof Error ? err.message : String(err));
9323
9485
  process.exit(1);
9324
9486
  }
9325
9487
  }
@@ -9329,7 +9491,7 @@ var init_remove_port = __esm({
9329
9491
 
9330
9492
  // src/commands/remove-repo.ts
9331
9493
  import { defineCommand as defineCommand22 } from "citty";
9332
- import { consola as consola26 } from "consola";
9494
+ import { consola as consola27 } from "consola";
9333
9495
  var removeRepoCommand;
9334
9496
  var init_remove_repo = __esm({
9335
9497
  "src/commands/remove-repo.ts"() {
@@ -9368,7 +9530,7 @@ var init_remove_repo = __esm({
9368
9530
  });
9369
9531
  process.exit(result.status === "aborted" ? 1 : 0);
9370
9532
  } catch (err) {
9371
- consola26.error(err instanceof Error ? err.message : String(err));
9533
+ consola27.error(err instanceof Error ? err.message : String(err));
9372
9534
  process.exit(1);
9373
9535
  }
9374
9536
  }
@@ -9378,7 +9540,7 @@ var init_remove_repo = __esm({
9378
9540
 
9379
9541
  // src/commands/remove-service.ts
9380
9542
  import { defineCommand as defineCommand23 } from "citty";
9381
- import { consola as consola27 } from "consola";
9543
+ import { consola as consola28 } from "consola";
9382
9544
  var removeServiceCommand;
9383
9545
  var init_remove_service = __esm({
9384
9546
  "src/commands/remove-service.ts"() {
@@ -9417,7 +9579,7 @@ var init_remove_service = __esm({
9417
9579
  });
9418
9580
  process.exit(result.status === "aborted" ? 1 : 0);
9419
9581
  } catch (err) {
9420
- consola27.error(err instanceof Error ? err.message : String(err));
9582
+ consola28.error(err instanceof Error ? err.message : String(err));
9421
9583
  process.exit(1);
9422
9584
  }
9423
9585
  }
@@ -9427,9 +9589,9 @@ var init_remove_service = __esm({
9427
9589
 
9428
9590
  // src/devcontainer/browser-bridge.ts
9429
9591
  import { spawn as spawn9 } from "child_process";
9430
- import { existsSync as existsSync14, promises as fsp4, readFileSync as readFileSync5 } from "fs";
9592
+ import { existsSync as existsSync15, promises as fsp5, readFileSync as readFileSync5 } from "fs";
9431
9593
  import http from "http";
9432
- import path23 from "path";
9594
+ import path24 from "path";
9433
9595
  function parseCallbackTarget(authUrl) {
9434
9596
  try {
9435
9597
  const u = new URL(authUrl);
@@ -9463,12 +9625,12 @@ function openInBrowser(url) {
9463
9625
  }
9464
9626
  }
9465
9627
  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(
9628
+ const relayDir = path24.join(opts.root, RELAY_DIRNAME);
9629
+ const relayScript = path24.join(relayDir, "xdg-open");
9630
+ const urlFile = path24.join(relayDir, "url");
9631
+ await fsp5.mkdir(relayDir, { recursive: true });
9632
+ await fsp5.rm(urlFile, { force: true });
9633
+ await fsp5.writeFile(
9472
9634
  relayScript,
9473
9635
  `#!/bin/sh
9474
9636
  printf '%s\\n' "$1" > "$(dirname "$0")/url"
@@ -9476,7 +9638,7 @@ exit 0
9476
9638
  `,
9477
9639
  { mode: 493 }
9478
9640
  );
9479
- await fsp4.chmod(relayScript, 493);
9641
+ await fsp5.chmod(relayScript, 493);
9480
9642
  const servers = [];
9481
9643
  let lastOpened = null;
9482
9644
  const onUrl = (url) => {
@@ -9509,7 +9671,7 @@ exit 0
9509
9671
  servers.push(server);
9510
9672
  };
9511
9673
  const poll = setInterval(() => {
9512
- if (!existsSync14(urlFile)) return;
9674
+ if (!existsSync15(urlFile)) return;
9513
9675
  let content = "";
9514
9676
  try {
9515
9677
  content = readFileSync5(urlFile, "utf8");
@@ -9526,7 +9688,7 @@ exit 0
9526
9688
  async dispose() {
9527
9689
  clearInterval(poll);
9528
9690
  for (const s of servers) s.close();
9529
- await fsp4.rm(relayDir, { recursive: true, force: true });
9691
+ await fsp5.rm(relayDir, { recursive: true, force: true });
9530
9692
  }
9531
9693
  };
9532
9694
  }
@@ -9539,18 +9701,18 @@ var init_browser_bridge = __esm({
9539
9701
  });
9540
9702
 
9541
9703
  // src/devcontainer/claude-trust.ts
9542
- import { existsSync as existsSync15, promises as fsp5 } from "fs";
9543
- import path24 from "path";
9704
+ import { existsSync as existsSync16, promises as fsp6 } from "fs";
9705
+ import path25 from "path";
9544
9706
  function resolveContainerCwd(name, cwd) {
9545
9707
  const workspace = `/workspaces/${name}`;
9546
9708
  if (!cwd) return workspace;
9547
- return path24.posix.isAbsolute(cwd) ? cwd : path24.posix.join(workspace, cwd);
9709
+ return path25.posix.isAbsolute(cwd) ? cwd : path25.posix.join(workspace, cwd);
9548
9710
  }
9549
9711
  async function preApproveClaudeProject(opts) {
9550
- const file = path24.join(opts.root, "home", ".claude.json");
9551
- if (!existsSync15(file)) return;
9712
+ const file = path25.join(opts.root, "home", ".claude.json");
9713
+ if (!existsSync16(file)) return;
9552
9714
  try {
9553
- const raw = await fsp5.readFile(file, "utf8");
9715
+ const raw = await fsp6.readFile(file, "utf8");
9554
9716
  const config = raw.trim() ? JSON.parse(raw) : {};
9555
9717
  if (typeof config !== "object" || config === null) return;
9556
9718
  const dir = resolveContainerCwd(opts.name, opts.cwd);
@@ -9570,7 +9732,7 @@ async function preApproveClaudeProject(opts) {
9570
9732
  if (typeof entry2.projectOnboardingSeenCount !== "number") {
9571
9733
  entry2.projectOnboardingSeenCount = 1;
9572
9734
  }
9573
- await fsp5.writeFile(file, `${JSON.stringify(config, null, 2)}
9735
+ await fsp6.writeFile(file, `${JSON.stringify(config, null, 2)}
9574
9736
  `);
9575
9737
  } catch {
9576
9738
  }
@@ -9582,8 +9744,8 @@ var init_claude_trust = __esm({
9582
9744
  });
9583
9745
 
9584
9746
  // src/devcontainer/shell.ts
9585
- import { existsSync as existsSync16 } from "fs";
9586
- import path25 from "path";
9747
+ import { existsSync as existsSync17 } from "fs";
9748
+ import path26 from "path";
9587
9749
  async function runShell(opts) {
9588
9750
  assertContainerExists(opts.root);
9589
9751
  const spawnFn = opts.spawn ?? spawnDevcontainer;
@@ -9606,7 +9768,7 @@ async function runShell(opts) {
9606
9768
  );
9607
9769
  }
9608
9770
  function assertContainerExists(root) {
9609
- if (!existsSync16(path25.join(root, ".devcontainer"))) {
9771
+ if (!existsSync17(path26.join(root, ".devcontainer"))) {
9610
9772
  throw new Error(
9611
9773
  `No .devcontainer/ at ${root}. Run \`monoceros apply <name>\` first.`
9612
9774
  );
@@ -9696,7 +9858,7 @@ var init_run = __esm({
9696
9858
 
9697
9859
  // src/commands/run.ts
9698
9860
  import { defineCommand as defineCommand24 } from "citty";
9699
- import { consola as consola28 } from "consola";
9861
+ import { consola as consola29 } from "consola";
9700
9862
  var runCommand;
9701
9863
  var init_run2 = __esm({
9702
9864
  "src/commands/run.ts"() {
@@ -9724,7 +9886,7 @@ var init_run2 = __esm({
9724
9886
  async run({ args }) {
9725
9887
  const command = [...getInnerArgs()];
9726
9888
  if (command.length === 0) {
9727
- consola28.error(
9889
+ consola29.error(
9728
9890
  "No command provided. Usage: `monoceros run <containername> -- <cmd> [args\u2026]`."
9729
9891
  );
9730
9892
  process.exit(1);
@@ -9738,7 +9900,7 @@ var init_run2 = __esm({
9738
9900
  });
9739
9901
  process.exit(exitCode);
9740
9902
  } catch (err) {
9741
- consola28.error(err instanceof Error ? err.message : String(err));
9903
+ consola29.error(err instanceof Error ? err.message : String(err));
9742
9904
  process.exit(1);
9743
9905
  }
9744
9906
  }
@@ -9748,7 +9910,7 @@ var init_run2 = __esm({
9748
9910
 
9749
9911
  // src/commands/shell.ts
9750
9912
  import { defineCommand as defineCommand25 } from "citty";
9751
- import { consola as consola29 } from "consola";
9913
+ import { consola as consola30 } from "consola";
9752
9914
  var shellCommand;
9753
9915
  var init_shell2 = __esm({
9754
9916
  "src/commands/shell.ts"() {
@@ -9773,7 +9935,7 @@ var init_shell2 = __esm({
9773
9935
  const exitCode = await runShell({ root: containerDir(args.name) });
9774
9936
  process.exit(exitCode);
9775
9937
  } catch (err) {
9776
- consola29.error(err instanceof Error ? err.message : String(err));
9938
+ consola30.error(err instanceof Error ? err.message : String(err));
9777
9939
  process.exit(1);
9778
9940
  }
9779
9941
  }
@@ -9783,7 +9945,7 @@ var init_shell2 = __esm({
9783
9945
 
9784
9946
  // src/commands/start.ts
9785
9947
  import { defineCommand as defineCommand26 } from "citty";
9786
- import { consola as consola30 } from "consola";
9948
+ import { consola as consola31 } from "consola";
9787
9949
  var startCommand;
9788
9950
  var init_start = __esm({
9789
9951
  "src/commands/start.ts"() {
@@ -9820,7 +9982,7 @@ var init_start = __esm({
9820
9982
  hostPort = proxyHostPort(global);
9821
9983
  }
9822
9984
  } catch (err) {
9823
- consola30.warn(
9985
+ consola31.warn(
9824
9986
  `Could not read container yml ahead of start: ${err instanceof Error ? err.message : String(err)}. Skipping Traefik pre-flight.`
9825
9987
  );
9826
9988
  }
@@ -9875,7 +10037,7 @@ var init_status = __esm({
9875
10037
 
9876
10038
  // src/commands/stop.ts
9877
10039
  import { defineCommand as defineCommand28 } from "citty";
9878
- import { consola as consola31 } from "consola";
10040
+ import { consola as consola32 } from "consola";
9879
10041
  var stopCommand;
9880
10042
  var init_stop = __esm({
9881
10043
  "src/commands/stop.ts"() {
@@ -9909,10 +10071,10 @@ var init_stop = __esm({
9909
10071
  });
9910
10072
  try {
9911
10073
  await maybeStopProxy({
9912
- logger: { info: (msg) => consola31.info(msg) }
10074
+ logger: { info: (msg) => consola32.info(msg) }
9913
10075
  });
9914
10076
  } catch (err) {
9915
- consola31.warn(
10077
+ consola32.warn(
9916
10078
  `Could not tear down the Traefik proxy: ${err instanceof Error ? err.message : String(err)}. Ignored.`
9917
10079
  );
9918
10080
  }
@@ -9924,11 +10086,11 @@ var init_stop = __esm({
9924
10086
  });
9925
10087
 
9926
10088
  // src/tunnel/resolve.ts
9927
- import { existsSync as existsSync17 } from "fs";
9928
- import path26 from "path";
10089
+ import { existsSync as existsSync18 } from "fs";
10090
+ import path27 from "path";
9929
10091
  async function resolveTunnelTarget(opts) {
9930
10092
  const ymlPath = containerConfigPath(opts.name, opts.monocerosHome);
9931
- if (!existsSync17(ymlPath)) {
10093
+ if (!existsSync18(ymlPath)) {
9932
10094
  throw new Error(
9933
10095
  `No yml profile for '${opts.name}' at ${ymlPath}. Run \`monoceros init ${opts.name}\` first.`
9934
10096
  );
@@ -9936,13 +10098,13 @@ async function resolveTunnelTarget(opts) {
9936
10098
  const parsed = await readConfig(ymlPath);
9937
10099
  const config = parsed.config;
9938
10100
  const containerRoot = containerDir(opts.name, opts.monocerosHome);
9939
- if (!existsSync17(containerRoot)) {
10101
+ if (!existsSync18(containerRoot)) {
9940
10102
  throw new Error(
9941
10103
  `Container '${opts.name}' is not materialised at ${containerRoot}. Run \`monoceros apply ${opts.name}\` first.`
9942
10104
  );
9943
10105
  }
9944
- const composePath = path26.join(containerRoot, ".devcontainer", "compose.yaml");
9945
- const isCompose = existsSync17(composePath);
10106
+ const composePath = path27.join(containerRoot, ".devcontainer", "compose.yaml");
10107
+ const isCompose = existsSync18(composePath);
9946
10108
  const parsedTarget = parseTargetArg(opts.target, config);
9947
10109
  const docker = opts.docker ?? defaultDockerExec;
9948
10110
  if (isCompose) {
@@ -10178,7 +10340,7 @@ var init_port_check2 = __esm({
10178
10340
 
10179
10341
  // src/tunnel/run.ts
10180
10342
  import { spawn as spawn10 } from "child_process";
10181
- import { consola as consola32 } from "consola";
10343
+ import { consola as consola33 } from "consola";
10182
10344
  function signalNumber(signal) {
10183
10345
  switch (signal) {
10184
10346
  case "SIGINT":
@@ -10191,8 +10353,8 @@ function signalNumber(signal) {
10191
10353
  }
10192
10354
  async function runTunnel(opts) {
10193
10355
  const log = opts.logger ?? {
10194
- info: (m) => consola32.info(m),
10195
- warn: (m) => consola32.warn(m)
10356
+ info: (m) => consola33.info(m),
10357
+ warn: (m) => consola33.warn(m)
10196
10358
  };
10197
10359
  const resolve = opts.resolve ?? resolveTunnelTarget;
10198
10360
  const resolveArgs3 = {
@@ -10299,7 +10461,7 @@ var init_run3 = __esm({
10299
10461
 
10300
10462
  // src/commands/tunnel.ts
10301
10463
  import { defineCommand as defineCommand29 } from "citty";
10302
- import { consola as consola33 } from "consola";
10464
+ import { consola as consola34 } from "consola";
10303
10465
  function parseLocalPort(raw) {
10304
10466
  if (raw === void 0) return void 0;
10305
10467
  const n = Number(raw);
@@ -10352,7 +10514,7 @@ var init_tunnel = __esm({
10352
10514
  });
10353
10515
  process.exit(exitCode);
10354
10516
  } catch (err) {
10355
- consola33.error(err instanceof Error ? err.message : String(err));
10517
+ consola34.error(err instanceof Error ? err.message : String(err));
10356
10518
  process.exit(1);
10357
10519
  }
10358
10520
  }
@@ -10422,8 +10584,8 @@ var init_prune = __esm({
10422
10584
  });
10423
10585
 
10424
10586
  // src/upgrade/index.ts
10425
- import { existsSync as existsSync18, promises as fs17 } from "fs";
10426
- import { consola as consola34 } from "consola";
10587
+ import { existsSync as existsSync19, promises as fs17 } from "fs";
10588
+ import { consola as consola35 } from "consola";
10427
10589
  async function fetchRuntimeVersions() {
10428
10590
  const tokenUrl = `https://ghcr.io/token?service=ghcr.io&scope=repository:${RUNTIME_REPO}:pull`;
10429
10591
  const tokenRes = await fetch(tokenUrl);
@@ -10461,7 +10623,7 @@ ${yml}`;
10461
10623
  }
10462
10624
  async function runUpgrade(opts) {
10463
10625
  const home = opts.monocerosHome ?? monocerosHome();
10464
- const logger = opts.logger ?? consola34;
10626
+ const logger = opts.logger ?? consola35;
10465
10627
  const fetchVersions = opts.fetchVersions ?? fetchRuntimeVersions;
10466
10628
  if (opts.list) {
10467
10629
  const versions = await fetchVersions();
@@ -10487,7 +10649,7 @@ async function runUpgrade(opts) {
10487
10649
  );
10488
10650
  }
10489
10651
  }
10490
- if (opts.name && !existsSync18(containerConfigPath(opts.name, home))) {
10652
+ if (opts.name && !existsSync19(containerConfigPath(opts.name, home))) {
10491
10653
  throw new Error(
10492
10654
  `No such config: ${containerConfigPath(opts.name, home)}. Run \`monoceros init <template> ${opts.name}\` first.`
10493
10655
  );
@@ -10538,7 +10700,7 @@ async function runUpgrade(opts) {
10538
10700
  let bumped = 0;
10539
10701
  for (const name of targets) {
10540
10702
  const ymlPath = containerConfigPath(name, home);
10541
- if (!existsSync18(ymlPath)) continue;
10703
+ if (!existsSync19(ymlPath)) continue;
10542
10704
  const raw = await fs17.readFile(ymlPath, "utf8");
10543
10705
  const updated = setRuntimeVersion(raw, pinVersion);
10544
10706
  if (updated !== raw) {
@@ -10989,25 +11151,25 @@ function detectHelpRequest(argv, main2) {
10989
11151
  const separatorIdx = argv.indexOf("--");
10990
11152
  if (helpIdx === -1) return null;
10991
11153
  if (separatorIdx !== -1 && separatorIdx < helpIdx) return null;
10992
- const path27 = [];
11154
+ const path28 = [];
10993
11155
  const tokens = argv.slice(
10994
11156
  0,
10995
11157
  separatorIdx === -1 ? argv.length : separatorIdx
10996
11158
  );
10997
11159
  let cursor = main2;
10998
11160
  const mainName = (main2.meta ?? {}).name ?? "monoceros";
10999
- path27.push(mainName);
11161
+ path28.push(mainName);
11000
11162
  for (const tok of tokens) {
11001
11163
  if (tok.startsWith("-")) continue;
11002
11164
  const subs = cursor.subCommands ?? {};
11003
11165
  if (tok in subs) {
11004
11166
  cursor = subs[tok];
11005
- path27.push(tok);
11167
+ path28.push(tok);
11006
11168
  continue;
11007
11169
  }
11008
11170
  break;
11009
11171
  }
11010
- return { path: path27, cmd: cursor };
11172
+ return { path: path28, cmd: cursor };
11011
11173
  }
11012
11174
  async function maybeRenderHelp(argv, main2) {
11013
11175
  const hit = detectHelpRequest(argv, main2);