@getmonoceros/workbench 1.22.1 → 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/bundled-components/features/atlassian/component.yml +1 -1
- package/bundled-components/features/atlassian/install.sh +16 -4
- package/bundled-components/features/opencode/component.yml +37 -0
- package/bundled-components/features/opencode/install.sh +35 -0
- package/dist/bin.js +386 -231
- package/dist/bin.js.map +1 -1
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -2457,9 +2457,156 @@ var init_claude_settings = __esm({
|
|
|
2457
2457
|
}
|
|
2458
2458
|
});
|
|
2459
2459
|
|
|
2460
|
-
// src/create/
|
|
2461
|
-
import { existsSync as existsSync6, promises as
|
|
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 ?
|
|
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 ?
|
|
2634
|
-
if (descriptor && 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 =
|
|
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 =
|
|
3094
|
-
const monocerosDir =
|
|
3095
|
-
const projectsDir =
|
|
3096
|
-
const homeDir =
|
|
3097
|
-
const dataDir =
|
|
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(
|
|
3254
|
+
await fs7.mkdir(path10.join(dataDir, svc.name), { recursive: true });
|
|
3108
3255
|
}
|
|
3109
3256
|
}
|
|
3110
3257
|
}
|
|
3111
|
-
const containerGitignore =
|
|
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 =
|
|
3117
|
-
if (!
|
|
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
|
-
|
|
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
|
-
|
|
3273
|
+
path10.join(devcontainerDir, "devcontainer.json"),
|
|
3127
3274
|
JSON.stringify(devcontainerJson, null, 2) + "\n"
|
|
3128
3275
|
);
|
|
3129
|
-
const featuresDir =
|
|
3130
|
-
if (
|
|
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 =
|
|
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
|
-
|
|
3146
|
-
|
|
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
|
-
|
|
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(
|
|
3305
|
+
await fs7.mkdir(path10.join(homeDir, sub), { recursive: true });
|
|
3159
3306
|
}
|
|
3160
3307
|
for (const entry2 of f.persistentHomeFiles) {
|
|
3161
|
-
const filePath =
|
|
3162
|
-
await fs7.mkdir(
|
|
3163
|
-
if (!
|
|
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 =
|
|
3318
|
+
const composePath = path10.join(devcontainerDir, "compose.yaml");
|
|
3171
3319
|
if (needsCompose(opts)) {
|
|
3172
3320
|
await writeIfChanged(composePath, buildComposeYaml(opts, dockerMode));
|
|
3173
|
-
} else if (
|
|
3321
|
+
} else if (existsSync7(composePath)) {
|
|
3174
3322
|
await fs7.rm(composePath);
|
|
3175
3323
|
}
|
|
3176
|
-
const workspacePath =
|
|
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 =
|
|
3188
|
-
const settingsPath =
|
|
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
|
|
3664
|
-
const effectivePath = typeof
|
|
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
|
|
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
|
|
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:
|
|
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
|
|
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) =>
|
|
4198
|
-
success: (m) =>
|
|
4199
|
-
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
5030
|
+
const fullPath = path13.join(dir, file);
|
|
4882
5031
|
const stream = createWriteStream(fullPath, { flags: "w" });
|
|
4883
5032
|
const header = [
|
|
4884
5033
|
`# monoceros apply log`,
|
|
@@ -5364,11 +5513,17 @@ function generateAgentsMd(input) {
|
|
|
5364
5513
|
" repo already listed above), add it to the VS Code multi-root workspace so",
|
|
5365
5514
|
` it shows up in the Explorer. Open \`/workspaces/${input.containerName}/${input.containerName}.code-workspace\``,
|
|
5366
5515
|
" and append an entry to the `folders` array, for example",
|
|
5367
|
-
' `{ "path": "projects/<app>", "name": "<app>" }`.
|
|
5368
|
-
"
|
|
5369
|
-
"
|
|
5370
|
-
"
|
|
5371
|
-
"
|
|
5516
|
+
' `{ "path": "projects/<app>", "name": "<app>" }`.',
|
|
5517
|
+
" Add **exactly one** folder entry per directory directly under `projects/`:",
|
|
5518
|
+
" the top-level project directory itself, even when it contains several",
|
|
5519
|
+
" sub-projects (e.g. a `backend/` and a `frontend/`, or a multi-module",
|
|
5520
|
+
" layout). Do **not** register those sub-directories as separate roots \u2014 one",
|
|
5521
|
+
" root per top-level project keeps the Explorer readable as more projects",
|
|
5522
|
+
" land in the container. Cloned repos are added there automatically by the",
|
|
5523
|
+
" apply; projects you create yourself are not, so without this step VS Code",
|
|
5524
|
+
" (opened on the host from the workspace file) would not list them.",
|
|
5525
|
+
" Hand-added folder entries survive `monoceros apply`: the apply merges into",
|
|
5526
|
+
" the file, it does not overwrite your edits.",
|
|
5372
5527
|
"- You run as the `node` user. `sudo` is available but its effects do",
|
|
5373
5528
|
" not persist across rebuilds.",
|
|
5374
5529
|
"- A bare `EXPOSE` directive has no effect on host reachability. Ports",
|
|
@@ -5739,7 +5894,7 @@ var init_markers = __esm({
|
|
|
5739
5894
|
|
|
5740
5895
|
// src/briefing/index.ts
|
|
5741
5896
|
import { promises as fs10 } from "fs";
|
|
5742
|
-
import
|
|
5897
|
+
import path14 from "path";
|
|
5743
5898
|
async function writeBriefing(input) {
|
|
5744
5899
|
const subCommands = input.subCommands ?? await loadSubCommandsDynamic();
|
|
5745
5900
|
const manifestLoader = input.manifestLoader ?? ((ref) => loadFeatureManifestSummary(ref));
|
|
@@ -5752,12 +5907,12 @@ async function writeBriefing(input) {
|
|
|
5752
5907
|
);
|
|
5753
5908
|
const claudeBody = generateClaudeMd();
|
|
5754
5909
|
const commandsBody = generateCommandsMd(subCommands);
|
|
5755
|
-
await writeMarkerAware(
|
|
5756
|
-
await writeMarkerAware(
|
|
5757
|
-
const monocerosDir =
|
|
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");
|
|
5758
5913
|
await fs10.mkdir(monocerosDir, { recursive: true });
|
|
5759
5914
|
await fs10.writeFile(
|
|
5760
|
-
|
|
5915
|
+
path14.join(monocerosDir, "commands.md"),
|
|
5761
5916
|
commandsBody,
|
|
5762
5917
|
"utf8"
|
|
5763
5918
|
);
|
|
@@ -5916,7 +6071,7 @@ var init_runtime_pull_hint = __esm({
|
|
|
5916
6071
|
import { spawn as spawn4 } from "child_process";
|
|
5917
6072
|
import { readFileSync as readFileSync4 } from "fs";
|
|
5918
6073
|
import { createRequire } from "module";
|
|
5919
|
-
import
|
|
6074
|
+
import path15 from "path";
|
|
5920
6075
|
function devcontainerCliPath() {
|
|
5921
6076
|
if (cachedBinaryPath) return cachedBinaryPath;
|
|
5922
6077
|
const pkgJsonPath = require_.resolve("@devcontainers/cli/package.json");
|
|
@@ -5925,7 +6080,7 @@ function devcontainerCliPath() {
|
|
|
5925
6080
|
if (!binEntry) {
|
|
5926
6081
|
throw new Error("Could not resolve @devcontainers/cli bin entry.");
|
|
5927
6082
|
}
|
|
5928
|
-
cachedBinaryPath =
|
|
6083
|
+
cachedBinaryPath = path15.resolve(path15.dirname(pkgJsonPath), binEntry);
|
|
5929
6084
|
return cachedBinaryPath;
|
|
5930
6085
|
}
|
|
5931
6086
|
var require_, cachedBinaryPath, spawnDevcontainer;
|
|
@@ -5999,10 +6154,10 @@ var init_cli = __esm({
|
|
|
5999
6154
|
|
|
6000
6155
|
// src/devcontainer/compose.ts
|
|
6001
6156
|
import { spawn as spawn5 } from "child_process";
|
|
6002
|
-
import { existsSync as
|
|
6003
|
-
import
|
|
6157
|
+
import { existsSync as existsSync8 } from "fs";
|
|
6158
|
+
import path16 from "path";
|
|
6004
6159
|
import { Writable as Writable3 } from "stream";
|
|
6005
|
-
import { consola as
|
|
6160
|
+
import { consola as consola10 } from "consola";
|
|
6006
6161
|
async function findContainerIds(filters, exec = spawnDocker) {
|
|
6007
6162
|
const ids = /* @__PURE__ */ new Set();
|
|
6008
6163
|
for (const filter of filters) {
|
|
@@ -6050,16 +6205,16 @@ async function cleanupDockerObjects(opts) {
|
|
|
6050
6205
|
return { exitCode: rmExit, removedIds: ids };
|
|
6051
6206
|
}
|
|
6052
6207
|
function composeProjectName(root) {
|
|
6053
|
-
return `${
|
|
6208
|
+
return `${path16.basename(root)}_devcontainer`;
|
|
6054
6209
|
}
|
|
6055
6210
|
function resolveCompose(root) {
|
|
6056
|
-
if (!
|
|
6211
|
+
if (!existsSync8(path16.join(root, ".devcontainer"))) {
|
|
6057
6212
|
throw new Error(
|
|
6058
6213
|
`No .devcontainer/ at ${root}. Run \`monoceros apply <name>\` first.`
|
|
6059
6214
|
);
|
|
6060
6215
|
}
|
|
6061
|
-
const composeFile =
|
|
6062
|
-
if (!
|
|
6216
|
+
const composeFile = path16.join(root, ".devcontainer", "compose.yaml");
|
|
6217
|
+
if (!existsSync8(composeFile)) {
|
|
6063
6218
|
throw new Error(
|
|
6064
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.`
|
|
6065
6220
|
);
|
|
@@ -6074,7 +6229,7 @@ async function runComposeAction(buildSubArgs, opts) {
|
|
|
6074
6229
|
}
|
|
6075
6230
|
async function runStart(opts) {
|
|
6076
6231
|
resolveCompose(opts.root);
|
|
6077
|
-
const logger = opts.logger ?? { info: (msg) =>
|
|
6232
|
+
const logger = opts.logger ?? { info: (msg) => consola10.info(msg) };
|
|
6078
6233
|
const spawnFn = opts.spawn ?? spawnDevcontainer;
|
|
6079
6234
|
logger.info(`Bringing devcontainer up at ${opts.root}\u2026`);
|
|
6080
6235
|
return spawnFn(
|
|
@@ -6320,14 +6475,14 @@ var init_images = __esm({
|
|
|
6320
6475
|
});
|
|
6321
6476
|
|
|
6322
6477
|
// src/config/machine-state.ts
|
|
6323
|
-
import { promises as
|
|
6324
|
-
import
|
|
6478
|
+
import { promises as fsp4 } from "fs";
|
|
6479
|
+
import path17 from "path";
|
|
6325
6480
|
function machineStatePath(home = monocerosHome()) {
|
|
6326
|
-
return
|
|
6481
|
+
return path17.join(home, ".machine-state.json");
|
|
6327
6482
|
}
|
|
6328
6483
|
async function readMachineState(home = monocerosHome()) {
|
|
6329
6484
|
try {
|
|
6330
|
-
const raw = await
|
|
6485
|
+
const raw = await fsp4.readFile(machineStatePath(home), "utf8");
|
|
6331
6486
|
const parsed = JSON.parse(raw);
|
|
6332
6487
|
if (typeof parsed === "object" && parsed !== null) {
|
|
6333
6488
|
return parsed;
|
|
@@ -6337,7 +6492,7 @@ async function readMachineState(home = monocerosHome()) {
|
|
|
6337
6492
|
return {};
|
|
6338
6493
|
}
|
|
6339
6494
|
async function writeMachineState(state, home = monocerosHome()) {
|
|
6340
|
-
await
|
|
6495
|
+
await fsp4.writeFile(
|
|
6341
6496
|
machineStatePath(home),
|
|
6342
6497
|
`${JSON.stringify(state, null, 2)}
|
|
6343
6498
|
`
|
|
@@ -6449,8 +6604,8 @@ var init_docker_mode = __esm({
|
|
|
6449
6604
|
// src/devcontainer/identity.ts
|
|
6450
6605
|
import { spawn as spawn7 } from "child_process";
|
|
6451
6606
|
import { promises as fs11 } from "fs";
|
|
6452
|
-
import
|
|
6453
|
-
import { consola as
|
|
6607
|
+
import path18 from "path";
|
|
6608
|
+
import { consola as consola11 } from "consola";
|
|
6454
6609
|
async function resolveIdentityWithPrompt(options = {}) {
|
|
6455
6610
|
const spawnFn = options.spawn ?? realGitConfigGet;
|
|
6456
6611
|
const promptFn = options.prompt ?? realIdentityPrompt;
|
|
@@ -6505,8 +6660,8 @@ async function resolveIdentityWithPrompt(options = {}) {
|
|
|
6505
6660
|
};
|
|
6506
6661
|
}
|
|
6507
6662
|
async function collectGitIdentity(devContainerRoot, options = {}) {
|
|
6508
|
-
const gitconfigDir =
|
|
6509
|
-
const gitconfigPath =
|
|
6663
|
+
const gitconfigDir = path18.join(devContainerRoot, ".monoceros");
|
|
6664
|
+
const gitconfigPath = path18.join(gitconfigDir, "gitconfig");
|
|
6510
6665
|
const logger = options.logger ?? { info: () => {
|
|
6511
6666
|
}, warn: () => {
|
|
6512
6667
|
} };
|
|
@@ -6599,7 +6754,7 @@ var init_identity = __esm({
|
|
|
6599
6754
|
return void 0;
|
|
6600
6755
|
}
|
|
6601
6756
|
const label = key === "user.name" ? "Git user.name for this dev container (full name)" : "Git user.email for this dev container";
|
|
6602
|
-
const value = await
|
|
6757
|
+
const value = await consola11.prompt(`${label}:`, { type: "text" });
|
|
6603
6758
|
if (typeof value !== "string") return void 0;
|
|
6604
6759
|
const trimmed = value.trim();
|
|
6605
6760
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
@@ -6609,7 +6764,7 @@ var init_identity = __esm({
|
|
|
6609
6764
|
return ctx.reason === "prompt" ? "g" : "n";
|
|
6610
6765
|
}
|
|
6611
6766
|
const heading = ctx.reason === "persisted" ? `Found identity in .monoceros/gitconfig: ${ctx.name} <${ctx.email}>. Promote where?` : "Save this identity where?";
|
|
6612
|
-
const choice = await
|
|
6767
|
+
const choice = await consola11.prompt(heading, {
|
|
6613
6768
|
type: "select",
|
|
6614
6769
|
options: [
|
|
6615
6770
|
{
|
|
@@ -6640,14 +6795,14 @@ var init_identity = __esm({
|
|
|
6640
6795
|
});
|
|
6641
6796
|
|
|
6642
6797
|
// src/apply/index.ts
|
|
6643
|
-
import { existsSync as
|
|
6644
|
-
import { consola as
|
|
6798
|
+
import { existsSync as existsSync9, promises as fs12 } from "fs";
|
|
6799
|
+
import { consola as consola12 } from "consola";
|
|
6645
6800
|
async function runApply(opts) {
|
|
6646
6801
|
const home = opts.monocerosHome ?? monocerosHome();
|
|
6647
6802
|
const logger = opts.logger ?? {
|
|
6648
|
-
info: (msg) =>
|
|
6649
|
-
success: (msg) =>
|
|
6650
|
-
warn: (msg) =>
|
|
6803
|
+
info: (msg) => consola12.info(msg),
|
|
6804
|
+
success: (msg) => consola12.success(msg),
|
|
6805
|
+
warn: (msg) => consola12.warn(msg),
|
|
6651
6806
|
// Default section renderer: empty line, bold-underlined "▸ Label",
|
|
6652
6807
|
// empty line. Mirrors install.sh's section visuals.
|
|
6653
6808
|
section: (label) => process.stderr.write(`
|
|
@@ -6662,7 +6817,7 @@ ${sectionLine(label)}
|
|
|
6662
6817
|
);
|
|
6663
6818
|
}
|
|
6664
6819
|
const ymlPath = containerConfigPath(opts.name, home);
|
|
6665
|
-
if (!
|
|
6820
|
+
if (!existsSync9(ymlPath)) {
|
|
6666
6821
|
throw new Error(
|
|
6667
6822
|
`No such config: ${ymlPath}. Run \`monoceros init <template> ${opts.name}\` first.`
|
|
6668
6823
|
);
|
|
@@ -6935,7 +7090,7 @@ ${stripAnsi(formatted)}
|
|
|
6935
7090
|
return { targetDir, configPath: ymlPath, containerExitCode: exitCode };
|
|
6936
7091
|
}
|
|
6937
7092
|
async function assertSafeTargetDir(targetDir, expectedOrigin) {
|
|
6938
|
-
if (!
|
|
7093
|
+
if (!existsSync9(targetDir)) return;
|
|
6939
7094
|
const entries = await fs12.readdir(targetDir);
|
|
6940
7095
|
if (entries.length === 0) return;
|
|
6941
7096
|
const state = await readStateFile(targetDir);
|
|
@@ -7065,18 +7220,18 @@ var CLI_VERSION;
|
|
|
7065
7220
|
var init_version = __esm({
|
|
7066
7221
|
"src/version.ts"() {
|
|
7067
7222
|
"use strict";
|
|
7068
|
-
CLI_VERSION = true ? "1.
|
|
7223
|
+
CLI_VERSION = true ? "1.23.0" : "dev";
|
|
7069
7224
|
}
|
|
7070
7225
|
});
|
|
7071
7226
|
|
|
7072
7227
|
// src/commands/_dispatch.ts
|
|
7073
|
-
import { consola as
|
|
7228
|
+
import { consola as consola13 } from "consola";
|
|
7074
7229
|
async function dispatch(runner) {
|
|
7075
7230
|
try {
|
|
7076
7231
|
const exitCode = await runner();
|
|
7077
7232
|
process.exit(exitCode);
|
|
7078
7233
|
} catch (err) {
|
|
7079
|
-
|
|
7234
|
+
consola13.error(err instanceof Error ? err.message : String(err));
|
|
7080
7235
|
process.exit(1);
|
|
7081
7236
|
}
|
|
7082
7237
|
}
|
|
@@ -7255,8 +7410,8 @@ var init_completion = __esm({
|
|
|
7255
7410
|
});
|
|
7256
7411
|
|
|
7257
7412
|
// src/completion/resolve.ts
|
|
7258
|
-
import { existsSync as
|
|
7259
|
-
import
|
|
7413
|
+
import { existsSync as existsSync10, promises as fs13 } from "fs";
|
|
7414
|
+
import path19 from "path";
|
|
7260
7415
|
async function resolveCompletions(line, point, opts = {}) {
|
|
7261
7416
|
const { prev, current } = parseCompletionLine(line, point);
|
|
7262
7417
|
const ctx = { prev, current, opts };
|
|
@@ -7405,8 +7560,8 @@ function filterPrefix(values, fragment) {
|
|
|
7405
7560
|
}
|
|
7406
7561
|
async function listContainerNames(ctx) {
|
|
7407
7562
|
const home = ctx.opts.monocerosHome ?? monocerosHome();
|
|
7408
|
-
const dir =
|
|
7409
|
-
if (!
|
|
7563
|
+
const dir = path19.join(home, "container-configs");
|
|
7564
|
+
if (!existsSync10(dir)) return [];
|
|
7410
7565
|
const entries = await fs13.readdir(dir);
|
|
7411
7566
|
return entries.filter((e) => e.endsWith(".yml")).map((e) => e.slice(0, -".yml".length)).sort();
|
|
7412
7567
|
}
|
|
@@ -8074,14 +8229,14 @@ var init_generator = __esm({
|
|
|
8074
8229
|
});
|
|
8075
8230
|
|
|
8076
8231
|
// src/init/index.ts
|
|
8077
|
-
import { existsSync as
|
|
8078
|
-
import
|
|
8079
|
-
import { consola as
|
|
8232
|
+
import { existsSync as existsSync11, promises as fs14 } from "fs";
|
|
8233
|
+
import path20 from "path";
|
|
8234
|
+
import { consola as consola14 } from "consola";
|
|
8080
8235
|
async function runInit(opts) {
|
|
8081
8236
|
const home = opts.monocerosHome ?? monocerosHome();
|
|
8082
8237
|
const logger = opts.logger ?? {
|
|
8083
|
-
success: (msg) =>
|
|
8084
|
-
info: (msg) =>
|
|
8238
|
+
success: (msg) => consola14.success(msg),
|
|
8239
|
+
info: (msg) => consola14.info(msg)
|
|
8085
8240
|
};
|
|
8086
8241
|
if (!REGEX.solutionName.test(opts.name)) {
|
|
8087
8242
|
throw new Error(
|
|
@@ -8089,12 +8244,12 @@ async function runInit(opts) {
|
|
|
8089
8244
|
);
|
|
8090
8245
|
}
|
|
8091
8246
|
const dest = containerConfigPath(opts.name, home);
|
|
8092
|
-
if (
|
|
8247
|
+
if (existsSync11(dest)) {
|
|
8093
8248
|
throw new Error(
|
|
8094
8249
|
`Config already exists: ${dest}. Delete it manually before re-running \`monoceros init\` \u2014 this protects any hand-edits.`
|
|
8095
8250
|
);
|
|
8096
8251
|
}
|
|
8097
|
-
const componentsRoot = opts.workbenchRoot ?
|
|
8252
|
+
const componentsRoot = opts.workbenchRoot ? path20.join(opts.workbenchRoot, "components") : componentsRootDir();
|
|
8098
8253
|
const catalog = await loadComponentCatalog(componentsRoot);
|
|
8099
8254
|
if (catalog.size === 0) {
|
|
8100
8255
|
throw new Error(
|
|
@@ -8185,8 +8340,8 @@ async function runInit(opts) {
|
|
|
8185
8340
|
}
|
|
8186
8341
|
await ensureEnvVars(envPath, opts.name, seedVars);
|
|
8187
8342
|
const documented = !anyComposed;
|
|
8188
|
-
const ymlRel =
|
|
8189
|
-
const envRel =
|
|
8343
|
+
const ymlRel = path20.relative(home, dest);
|
|
8344
|
+
const envRel = path20.relative(home, envPath);
|
|
8190
8345
|
if (documented) {
|
|
8191
8346
|
logger.success(`Wrote documented default to ${ymlRel} and ${envRel}.`);
|
|
8192
8347
|
logger.info(
|
|
@@ -8330,7 +8485,7 @@ var init_init = __esm({
|
|
|
8330
8485
|
|
|
8331
8486
|
// src/commands/init.ts
|
|
8332
8487
|
import { defineCommand as defineCommand11 } from "citty";
|
|
8333
|
-
import { consola as
|
|
8488
|
+
import { consola as consola15 } from "consola";
|
|
8334
8489
|
function collectListFlag(flag, rawArgs) {
|
|
8335
8490
|
const eq = `${flag}=`;
|
|
8336
8491
|
const pieces = [];
|
|
@@ -8456,7 +8611,7 @@ var init_init2 = __esm({
|
|
|
8456
8611
|
...ports && ports.length > 0 ? { withPorts: ports } : {}
|
|
8457
8612
|
});
|
|
8458
8613
|
} catch (err) {
|
|
8459
|
-
|
|
8614
|
+
consola15.error(err instanceof Error ? err.message : String(err));
|
|
8460
8615
|
process.exit(1);
|
|
8461
8616
|
}
|
|
8462
8617
|
}
|
|
@@ -8505,7 +8660,7 @@ var init_expand = __esm({
|
|
|
8505
8660
|
|
|
8506
8661
|
// src/commands/list-components.ts
|
|
8507
8662
|
import { defineCommand as defineCommand12 } from "citty";
|
|
8508
|
-
import { consola as
|
|
8663
|
+
import { consola as consola16 } from "consola";
|
|
8509
8664
|
var CATEGORY_LABELS, CATEGORY_ORDER, listComponentsCommand;
|
|
8510
8665
|
var init_list_components = __esm({
|
|
8511
8666
|
"src/commands/list-components.ts"() {
|
|
@@ -8534,7 +8689,7 @@ var init_list_components = __esm({
|
|
|
8534
8689
|
try {
|
|
8535
8690
|
const catalog = expandSelectable(await loadDescriptorCatalog());
|
|
8536
8691
|
if (catalog.size === 0) {
|
|
8537
|
-
|
|
8692
|
+
consola16.warn(
|
|
8538
8693
|
"No components found. The workbench checkout looks incomplete."
|
|
8539
8694
|
);
|
|
8540
8695
|
process.exit(0);
|
|
@@ -8585,7 +8740,7 @@ var init_list_components = __esm({
|
|
|
8585
8740
|
}
|
|
8586
8741
|
process.exit(0);
|
|
8587
8742
|
} catch (err) {
|
|
8588
|
-
|
|
8743
|
+
consola16.error(err instanceof Error ? err.message : String(err));
|
|
8589
8744
|
process.exit(1);
|
|
8590
8745
|
}
|
|
8591
8746
|
}
|
|
@@ -8595,8 +8750,8 @@ var init_list_components = __esm({
|
|
|
8595
8750
|
|
|
8596
8751
|
// src/commands/logs.ts
|
|
8597
8752
|
import { spawn as spawn8 } from "child_process";
|
|
8598
|
-
import { existsSync as
|
|
8599
|
-
import
|
|
8753
|
+
import { existsSync as existsSync12 } from "fs";
|
|
8754
|
+
import path21 from "path";
|
|
8600
8755
|
import { defineCommand as defineCommand13 } from "citty";
|
|
8601
8756
|
function tailLogFile(file, follow) {
|
|
8602
8757
|
const [cmd, args] = follow ? ["tail", ["-F", file]] : ["cat", [file]];
|
|
@@ -8639,8 +8794,8 @@ var init_logs = __esm({
|
|
|
8639
8794
|
run({ args }) {
|
|
8640
8795
|
const service = typeof args.service === "string" ? args.service : void 0;
|
|
8641
8796
|
if (service) {
|
|
8642
|
-
const logFile =
|
|
8643
|
-
if (
|
|
8797
|
+
const logFile = path21.join(containerLogsDir(args.name), `${service}.log`);
|
|
8798
|
+
if (existsSync12(logFile)) {
|
|
8644
8799
|
return dispatch(() => tailLogFile(logFile, args.follow));
|
|
8645
8800
|
}
|
|
8646
8801
|
}
|
|
@@ -8658,10 +8813,10 @@ var init_logs = __esm({
|
|
|
8658
8813
|
|
|
8659
8814
|
// src/commands/port.ts
|
|
8660
8815
|
import { defineCommand as defineCommand14 } from "citty";
|
|
8661
|
-
import { consola as
|
|
8816
|
+
import { consola as consola17 } from "consola";
|
|
8662
8817
|
async function runPortListing(opts) {
|
|
8663
8818
|
const out = opts.out ?? process.stdout;
|
|
8664
|
-
const info = opts.info ?? ((m) =>
|
|
8819
|
+
const info = opts.info ?? ((m) => consola17.info(m));
|
|
8665
8820
|
const parsed = await readConfig(
|
|
8666
8821
|
containerConfigPath(opts.name, opts.monocerosHome)
|
|
8667
8822
|
);
|
|
@@ -8737,7 +8892,7 @@ var init_port = __esm({
|
|
|
8737
8892
|
const code = await runPortListing({ name: args.name });
|
|
8738
8893
|
process.exit(code);
|
|
8739
8894
|
} catch (err) {
|
|
8740
|
-
|
|
8895
|
+
consola17.error(err instanceof Error ? err.message : String(err));
|
|
8741
8896
|
process.exit(1);
|
|
8742
8897
|
}
|
|
8743
8898
|
}
|
|
@@ -8747,7 +8902,7 @@ var init_port = __esm({
|
|
|
8747
8902
|
|
|
8748
8903
|
// src/commands/remove-apt-packages.ts
|
|
8749
8904
|
import { defineCommand as defineCommand15 } from "citty";
|
|
8750
|
-
import { consola as
|
|
8905
|
+
import { consola as consola18 } from "consola";
|
|
8751
8906
|
var removeAptPackagesCommand;
|
|
8752
8907
|
var init_remove_apt_packages = __esm({
|
|
8753
8908
|
"src/commands/remove-apt-packages.ts"() {
|
|
@@ -8776,7 +8931,7 @@ var init_remove_apt_packages = __esm({
|
|
|
8776
8931
|
async run({ args }) {
|
|
8777
8932
|
const packages = [...getInnerArgs()];
|
|
8778
8933
|
if (packages.length === 0) {
|
|
8779
|
-
|
|
8934
|
+
consola18.error(
|
|
8780
8935
|
"No package names given. Usage: `monoceros remove-apt-packages <containername> [--yes] -- <pkg> [<pkg> \u2026]`."
|
|
8781
8936
|
);
|
|
8782
8937
|
process.exit(1);
|
|
@@ -8789,7 +8944,7 @@ var init_remove_apt_packages = __esm({
|
|
|
8789
8944
|
});
|
|
8790
8945
|
process.exit(result.status === "aborted" ? 1 : 0);
|
|
8791
8946
|
} catch (err) {
|
|
8792
|
-
|
|
8947
|
+
consola18.error(err instanceof Error ? err.message : String(err));
|
|
8793
8948
|
process.exit(1);
|
|
8794
8949
|
}
|
|
8795
8950
|
}
|
|
@@ -8799,7 +8954,7 @@ var init_remove_apt_packages = __esm({
|
|
|
8799
8954
|
|
|
8800
8955
|
// src/commands/remove-feature.ts
|
|
8801
8956
|
import { defineCommand as defineCommand16 } from "citty";
|
|
8802
|
-
import { consola as
|
|
8957
|
+
import { consola as consola19 } from "consola";
|
|
8803
8958
|
var removeFeatureCommand;
|
|
8804
8959
|
var init_remove_feature = __esm({
|
|
8805
8960
|
"src/commands/remove-feature.ts"() {
|
|
@@ -8838,7 +8993,7 @@ var init_remove_feature = __esm({
|
|
|
8838
8993
|
});
|
|
8839
8994
|
process.exit(result.status === "aborted" ? 1 : 0);
|
|
8840
8995
|
} catch (err) {
|
|
8841
|
-
|
|
8996
|
+
consola19.error(err instanceof Error ? err.message : String(err));
|
|
8842
8997
|
process.exit(1);
|
|
8843
8998
|
}
|
|
8844
8999
|
}
|
|
@@ -8847,15 +9002,15 @@ var init_remove_feature = __esm({
|
|
|
8847
9002
|
});
|
|
8848
9003
|
|
|
8849
9004
|
// src/remove/index.ts
|
|
8850
|
-
import { existsSync as
|
|
8851
|
-
import
|
|
8852
|
-
import { consola as
|
|
9005
|
+
import { existsSync as existsSync13, promises as fs15 } from "fs";
|
|
9006
|
+
import path22 from "path";
|
|
9007
|
+
import { consola as consola20 } from "consola";
|
|
8853
9008
|
async function runRemove(opts) {
|
|
8854
9009
|
const home = opts.monocerosHome ?? monocerosHome();
|
|
8855
9010
|
const logger = opts.logger ?? {
|
|
8856
|
-
info: (msg) =>
|
|
8857
|
-
success: (msg) =>
|
|
8858
|
-
warn: (msg) =>
|
|
9011
|
+
info: (msg) => consola20.info(msg),
|
|
9012
|
+
success: (msg) => consola20.success(msg),
|
|
9013
|
+
warn: (msg) => consola20.warn(msg)
|
|
8859
9014
|
};
|
|
8860
9015
|
if (!REGEX.solutionName.test(opts.name)) {
|
|
8861
9016
|
throw new Error(
|
|
@@ -8865,9 +9020,9 @@ async function runRemove(opts) {
|
|
|
8865
9020
|
const ymlPath = containerConfigPath(opts.name, home);
|
|
8866
9021
|
const envPath = containerEnvPath(opts.name, home);
|
|
8867
9022
|
const containerPath = containerDir(opts.name, home);
|
|
8868
|
-
const hasYml =
|
|
8869
|
-
const hasEnv =
|
|
8870
|
-
const hasContainer =
|
|
9023
|
+
const hasYml = existsSync13(ymlPath);
|
|
9024
|
+
const hasEnv = existsSync13(envPath);
|
|
9025
|
+
const hasContainer = existsSync13(containerPath);
|
|
8871
9026
|
if (!hasYml && !hasContainer) {
|
|
8872
9027
|
throw new Error(
|
|
8873
9028
|
`Nothing to remove for '${opts.name}': neither ${ymlPath} nor ${containerPath} exists.`
|
|
@@ -8893,16 +9048,16 @@ async function runRemove(opts) {
|
|
|
8893
9048
|
let backupPath = null;
|
|
8894
9049
|
if (!opts.noBackup && (hasYml || hasContainer)) {
|
|
8895
9050
|
const ts = (opts.now ?? /* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8896
|
-
backupPath =
|
|
9051
|
+
backupPath = path22.join(home, "container-backups", `${opts.name}-${ts}`);
|
|
8897
9052
|
await fs15.mkdir(backupPath, { recursive: true });
|
|
8898
9053
|
if (hasYml) {
|
|
8899
|
-
await fs15.copyFile(ymlPath,
|
|
9054
|
+
await fs15.copyFile(ymlPath, path22.join(backupPath, `${opts.name}.yml`));
|
|
8900
9055
|
}
|
|
8901
9056
|
if (hasEnv) {
|
|
8902
|
-
await fs15.copyFile(envPath,
|
|
9057
|
+
await fs15.copyFile(envPath, path22.join(backupPath, `${opts.name}.env`));
|
|
8903
9058
|
}
|
|
8904
9059
|
if (hasContainer) {
|
|
8905
|
-
await fs15.cp(containerPath,
|
|
9060
|
+
await fs15.cp(containerPath, path22.join(backupPath, "container"), {
|
|
8906
9061
|
recursive: true
|
|
8907
9062
|
});
|
|
8908
9063
|
}
|
|
@@ -8992,7 +9147,7 @@ var init_remove = __esm({
|
|
|
8992
9147
|
|
|
8993
9148
|
// src/commands/remove.ts
|
|
8994
9149
|
import { defineCommand as defineCommand17 } from "citty";
|
|
8995
|
-
import { consola as
|
|
9150
|
+
import { consola as consola21 } from "consola";
|
|
8996
9151
|
import { createInterface } from "readline/promises";
|
|
8997
9152
|
var removeCommand;
|
|
8998
9153
|
var init_remove2 = __esm({
|
|
@@ -9036,7 +9191,7 @@ var init_remove2 = __esm({
|
|
|
9036
9191
|
const skipPrompt = args.yes === true;
|
|
9037
9192
|
if (!skipPrompt) {
|
|
9038
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.`;
|
|
9039
|
-
|
|
9194
|
+
consola21.warn(warning);
|
|
9040
9195
|
const rl = createInterface({
|
|
9041
9196
|
input: process.stdin,
|
|
9042
9197
|
output: process.stdout
|
|
@@ -9044,7 +9199,7 @@ var init_remove2 = __esm({
|
|
|
9044
9199
|
const answer = await rl.question("Continue? [y/N] ");
|
|
9045
9200
|
rl.close();
|
|
9046
9201
|
if (!/^y(es)?$/i.test(answer.trim())) {
|
|
9047
|
-
|
|
9202
|
+
consola21.info("Aborted. Nothing changed.");
|
|
9048
9203
|
process.exit(0);
|
|
9049
9204
|
}
|
|
9050
9205
|
}
|
|
@@ -9053,7 +9208,7 @@ var init_remove2 = __esm({
|
|
|
9053
9208
|
...noBackup ? { noBackup: true } : {}
|
|
9054
9209
|
});
|
|
9055
9210
|
} catch (err) {
|
|
9056
|
-
|
|
9211
|
+
consola21.error(err instanceof Error ? err.message : String(err));
|
|
9057
9212
|
process.exit(1);
|
|
9058
9213
|
}
|
|
9059
9214
|
}
|
|
@@ -9062,17 +9217,17 @@ var init_remove2 = __esm({
|
|
|
9062
9217
|
});
|
|
9063
9218
|
|
|
9064
9219
|
// src/restore/index.ts
|
|
9065
|
-
import { existsSync as
|
|
9066
|
-
import
|
|
9067
|
-
import { consola as
|
|
9220
|
+
import { existsSync as existsSync14, promises as fs16 } from "fs";
|
|
9221
|
+
import path23 from "path";
|
|
9222
|
+
import { consola as consola22 } from "consola";
|
|
9068
9223
|
async function runRestore(opts) {
|
|
9069
9224
|
const home = opts.monocerosHome ?? monocerosHome();
|
|
9070
9225
|
const logger = opts.logger ?? {
|
|
9071
|
-
info: (msg) =>
|
|
9072
|
-
success: (msg) =>
|
|
9226
|
+
info: (msg) => consola22.info(msg),
|
|
9227
|
+
success: (msg) => consola22.success(msg)
|
|
9073
9228
|
};
|
|
9074
|
-
const backup =
|
|
9075
|
-
if (!
|
|
9229
|
+
const backup = path23.resolve(opts.backupPath);
|
|
9230
|
+
if (!existsSync14(backup)) {
|
|
9076
9231
|
throw new Error(`Backup not found: ${backup}.`);
|
|
9077
9232
|
}
|
|
9078
9233
|
const stat = await fs16.stat(backup);
|
|
@@ -9093,24 +9248,24 @@ async function runRestore(opts) {
|
|
|
9093
9248
|
}
|
|
9094
9249
|
const ymlFile = ymlFiles[0];
|
|
9095
9250
|
const name = ymlFile.replace(/\.yml$/, "");
|
|
9096
|
-
const containerInBackup =
|
|
9097
|
-
const hasContainer =
|
|
9098
|
-
const envInBackup =
|
|
9099
|
-
const hasEnv =
|
|
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);
|
|
9100
9255
|
const destYml = containerConfigPath(name, home);
|
|
9101
9256
|
const destContainer = containerDir(name, home);
|
|
9102
|
-
if (
|
|
9257
|
+
if (existsSync14(destYml)) {
|
|
9103
9258
|
throw new Error(
|
|
9104
9259
|
`Refusing to restore: ${destYml} already exists. Remove the current container first (\`monoceros remove ${name}\`) or rename the existing config.`
|
|
9105
9260
|
);
|
|
9106
9261
|
}
|
|
9107
|
-
if (hasContainer &&
|
|
9262
|
+
if (hasContainer && existsSync14(destContainer)) {
|
|
9108
9263
|
throw new Error(
|
|
9109
9264
|
`Refusing to restore: ${destContainer} already exists. Remove the current container first (\`monoceros remove ${name}\`).`
|
|
9110
9265
|
);
|
|
9111
9266
|
}
|
|
9112
9267
|
await fs16.mkdir(containerConfigsDir(home), { recursive: true });
|
|
9113
|
-
await fs16.copyFile(
|
|
9268
|
+
await fs16.copyFile(path23.join(backup, ymlFile), destYml);
|
|
9114
9269
|
if (hasEnv) {
|
|
9115
9270
|
await fs16.copyFile(envInBackup, containerEnvPath(name, home));
|
|
9116
9271
|
}
|
|
@@ -9136,7 +9291,7 @@ var init_restore = __esm({
|
|
|
9136
9291
|
|
|
9137
9292
|
// src/commands/restore.ts
|
|
9138
9293
|
import { defineCommand as defineCommand18 } from "citty";
|
|
9139
|
-
import { consola as
|
|
9294
|
+
import { consola as consola23 } from "consola";
|
|
9140
9295
|
var restoreCommand;
|
|
9141
9296
|
var init_restore2 = __esm({
|
|
9142
9297
|
"src/commands/restore.ts"() {
|
|
@@ -9159,7 +9314,7 @@ var init_restore2 = __esm({
|
|
|
9159
9314
|
try {
|
|
9160
9315
|
await runRestore({ backupPath: args["backup-path"] });
|
|
9161
9316
|
} catch (err) {
|
|
9162
|
-
|
|
9317
|
+
consola23.error(err instanceof Error ? err.message : String(err));
|
|
9163
9318
|
process.exit(1);
|
|
9164
9319
|
}
|
|
9165
9320
|
}
|
|
@@ -9169,7 +9324,7 @@ var init_restore2 = __esm({
|
|
|
9169
9324
|
|
|
9170
9325
|
// src/commands/remove-from-url.ts
|
|
9171
9326
|
import { defineCommand as defineCommand19 } from "citty";
|
|
9172
|
-
import { consola as
|
|
9327
|
+
import { consola as consola24 } from "consola";
|
|
9173
9328
|
var removeFromUrlCommand;
|
|
9174
9329
|
var init_remove_from_url = __esm({
|
|
9175
9330
|
"src/commands/remove-from-url.ts"() {
|
|
@@ -9208,7 +9363,7 @@ var init_remove_from_url = __esm({
|
|
|
9208
9363
|
});
|
|
9209
9364
|
process.exit(result.status === "aborted" ? 1 : 0);
|
|
9210
9365
|
} catch (err) {
|
|
9211
|
-
|
|
9366
|
+
consola24.error(err instanceof Error ? err.message : String(err));
|
|
9212
9367
|
process.exit(1);
|
|
9213
9368
|
}
|
|
9214
9369
|
}
|
|
@@ -9218,7 +9373,7 @@ var init_remove_from_url = __esm({
|
|
|
9218
9373
|
|
|
9219
9374
|
// src/commands/remove-language.ts
|
|
9220
9375
|
import { defineCommand as defineCommand20 } from "citty";
|
|
9221
|
-
import { consola as
|
|
9376
|
+
import { consola as consola25 } from "consola";
|
|
9222
9377
|
var removeLanguageCommand;
|
|
9223
9378
|
var init_remove_language = __esm({
|
|
9224
9379
|
"src/commands/remove-language.ts"() {
|
|
@@ -9257,7 +9412,7 @@ var init_remove_language = __esm({
|
|
|
9257
9412
|
});
|
|
9258
9413
|
process.exit(result.status === "aborted" ? 1 : 0);
|
|
9259
9414
|
} catch (err) {
|
|
9260
|
-
|
|
9415
|
+
consola25.error(err instanceof Error ? err.message : String(err));
|
|
9261
9416
|
process.exit(1);
|
|
9262
9417
|
}
|
|
9263
9418
|
}
|
|
@@ -9267,7 +9422,7 @@ var init_remove_language = __esm({
|
|
|
9267
9422
|
|
|
9268
9423
|
// src/commands/remove-port.ts
|
|
9269
9424
|
import { defineCommand as defineCommand21 } from "citty";
|
|
9270
|
-
import { consola as
|
|
9425
|
+
import { consola as consola26 } from "consola";
|
|
9271
9426
|
function coerceToken2(raw) {
|
|
9272
9427
|
const n = Number(raw);
|
|
9273
9428
|
return Number.isFinite(n) ? n : raw;
|
|
@@ -9300,7 +9455,7 @@ var init_remove_port = __esm({
|
|
|
9300
9455
|
async run({ args }) {
|
|
9301
9456
|
const tokens = [...getInnerArgs()];
|
|
9302
9457
|
if (tokens.length === 0) {
|
|
9303
|
-
|
|
9458
|
+
consola26.error(
|
|
9304
9459
|
"No ports given. Usage: `monoceros remove-port <containername> [--yes] -- <port> [<port> \u2026]`."
|
|
9305
9460
|
);
|
|
9306
9461
|
process.exit(1);
|
|
@@ -9313,7 +9468,7 @@ var init_remove_port = __esm({
|
|
|
9313
9468
|
});
|
|
9314
9469
|
process.exit(result.status === "aborted" ? 1 : 0);
|
|
9315
9470
|
} catch (err) {
|
|
9316
|
-
|
|
9471
|
+
consola26.error(err instanceof Error ? err.message : String(err));
|
|
9317
9472
|
process.exit(1);
|
|
9318
9473
|
}
|
|
9319
9474
|
}
|
|
@@ -9323,7 +9478,7 @@ var init_remove_port = __esm({
|
|
|
9323
9478
|
|
|
9324
9479
|
// src/commands/remove-repo.ts
|
|
9325
9480
|
import { defineCommand as defineCommand22 } from "citty";
|
|
9326
|
-
import { consola as
|
|
9481
|
+
import { consola as consola27 } from "consola";
|
|
9327
9482
|
var removeRepoCommand;
|
|
9328
9483
|
var init_remove_repo = __esm({
|
|
9329
9484
|
"src/commands/remove-repo.ts"() {
|
|
@@ -9362,7 +9517,7 @@ var init_remove_repo = __esm({
|
|
|
9362
9517
|
});
|
|
9363
9518
|
process.exit(result.status === "aborted" ? 1 : 0);
|
|
9364
9519
|
} catch (err) {
|
|
9365
|
-
|
|
9520
|
+
consola27.error(err instanceof Error ? err.message : String(err));
|
|
9366
9521
|
process.exit(1);
|
|
9367
9522
|
}
|
|
9368
9523
|
}
|
|
@@ -9372,7 +9527,7 @@ var init_remove_repo = __esm({
|
|
|
9372
9527
|
|
|
9373
9528
|
// src/commands/remove-service.ts
|
|
9374
9529
|
import { defineCommand as defineCommand23 } from "citty";
|
|
9375
|
-
import { consola as
|
|
9530
|
+
import { consola as consola28 } from "consola";
|
|
9376
9531
|
var removeServiceCommand;
|
|
9377
9532
|
var init_remove_service = __esm({
|
|
9378
9533
|
"src/commands/remove-service.ts"() {
|
|
@@ -9411,7 +9566,7 @@ var init_remove_service = __esm({
|
|
|
9411
9566
|
});
|
|
9412
9567
|
process.exit(result.status === "aborted" ? 1 : 0);
|
|
9413
9568
|
} catch (err) {
|
|
9414
|
-
|
|
9569
|
+
consola28.error(err instanceof Error ? err.message : String(err));
|
|
9415
9570
|
process.exit(1);
|
|
9416
9571
|
}
|
|
9417
9572
|
}
|
|
@@ -9421,9 +9576,9 @@ var init_remove_service = __esm({
|
|
|
9421
9576
|
|
|
9422
9577
|
// src/devcontainer/browser-bridge.ts
|
|
9423
9578
|
import { spawn as spawn9 } from "child_process";
|
|
9424
|
-
import { existsSync as
|
|
9579
|
+
import { existsSync as existsSync15, promises as fsp5, readFileSync as readFileSync5 } from "fs";
|
|
9425
9580
|
import http from "http";
|
|
9426
|
-
import
|
|
9581
|
+
import path24 from "path";
|
|
9427
9582
|
function parseCallbackTarget(authUrl) {
|
|
9428
9583
|
try {
|
|
9429
9584
|
const u = new URL(authUrl);
|
|
@@ -9457,12 +9612,12 @@ function openInBrowser(url) {
|
|
|
9457
9612
|
}
|
|
9458
9613
|
}
|
|
9459
9614
|
async function startBrowserBridge(opts) {
|
|
9460
|
-
const relayDir =
|
|
9461
|
-
const relayScript =
|
|
9462
|
-
const urlFile =
|
|
9463
|
-
await
|
|
9464
|
-
await
|
|
9465
|
-
await
|
|
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(
|
|
9466
9621
|
relayScript,
|
|
9467
9622
|
`#!/bin/sh
|
|
9468
9623
|
printf '%s\\n' "$1" > "$(dirname "$0")/url"
|
|
@@ -9470,7 +9625,7 @@ exit 0
|
|
|
9470
9625
|
`,
|
|
9471
9626
|
{ mode: 493 }
|
|
9472
9627
|
);
|
|
9473
|
-
await
|
|
9628
|
+
await fsp5.chmod(relayScript, 493);
|
|
9474
9629
|
const servers = [];
|
|
9475
9630
|
let lastOpened = null;
|
|
9476
9631
|
const onUrl = (url) => {
|
|
@@ -9503,7 +9658,7 @@ exit 0
|
|
|
9503
9658
|
servers.push(server);
|
|
9504
9659
|
};
|
|
9505
9660
|
const poll = setInterval(() => {
|
|
9506
|
-
if (!
|
|
9661
|
+
if (!existsSync15(urlFile)) return;
|
|
9507
9662
|
let content = "";
|
|
9508
9663
|
try {
|
|
9509
9664
|
content = readFileSync5(urlFile, "utf8");
|
|
@@ -9520,7 +9675,7 @@ exit 0
|
|
|
9520
9675
|
async dispose() {
|
|
9521
9676
|
clearInterval(poll);
|
|
9522
9677
|
for (const s of servers) s.close();
|
|
9523
|
-
await
|
|
9678
|
+
await fsp5.rm(relayDir, { recursive: true, force: true });
|
|
9524
9679
|
}
|
|
9525
9680
|
};
|
|
9526
9681
|
}
|
|
@@ -9533,18 +9688,18 @@ var init_browser_bridge = __esm({
|
|
|
9533
9688
|
});
|
|
9534
9689
|
|
|
9535
9690
|
// src/devcontainer/claude-trust.ts
|
|
9536
|
-
import { existsSync as
|
|
9537
|
-
import
|
|
9691
|
+
import { existsSync as existsSync16, promises as fsp6 } from "fs";
|
|
9692
|
+
import path25 from "path";
|
|
9538
9693
|
function resolveContainerCwd(name, cwd) {
|
|
9539
9694
|
const workspace = `/workspaces/${name}`;
|
|
9540
9695
|
if (!cwd) return workspace;
|
|
9541
|
-
return
|
|
9696
|
+
return path25.posix.isAbsolute(cwd) ? cwd : path25.posix.join(workspace, cwd);
|
|
9542
9697
|
}
|
|
9543
9698
|
async function preApproveClaudeProject(opts) {
|
|
9544
|
-
const file =
|
|
9545
|
-
if (!
|
|
9699
|
+
const file = path25.join(opts.root, "home", ".claude.json");
|
|
9700
|
+
if (!existsSync16(file)) return;
|
|
9546
9701
|
try {
|
|
9547
|
-
const raw = await
|
|
9702
|
+
const raw = await fsp6.readFile(file, "utf8");
|
|
9548
9703
|
const config = raw.trim() ? JSON.parse(raw) : {};
|
|
9549
9704
|
if (typeof config !== "object" || config === null) return;
|
|
9550
9705
|
const dir = resolveContainerCwd(opts.name, opts.cwd);
|
|
@@ -9564,7 +9719,7 @@ async function preApproveClaudeProject(opts) {
|
|
|
9564
9719
|
if (typeof entry2.projectOnboardingSeenCount !== "number") {
|
|
9565
9720
|
entry2.projectOnboardingSeenCount = 1;
|
|
9566
9721
|
}
|
|
9567
|
-
await
|
|
9722
|
+
await fsp6.writeFile(file, `${JSON.stringify(config, null, 2)}
|
|
9568
9723
|
`);
|
|
9569
9724
|
} catch {
|
|
9570
9725
|
}
|
|
@@ -9576,8 +9731,8 @@ var init_claude_trust = __esm({
|
|
|
9576
9731
|
});
|
|
9577
9732
|
|
|
9578
9733
|
// src/devcontainer/shell.ts
|
|
9579
|
-
import { existsSync as
|
|
9580
|
-
import
|
|
9734
|
+
import { existsSync as existsSync17 } from "fs";
|
|
9735
|
+
import path26 from "path";
|
|
9581
9736
|
async function runShell(opts) {
|
|
9582
9737
|
assertContainerExists(opts.root);
|
|
9583
9738
|
const spawnFn = opts.spawn ?? spawnDevcontainer;
|
|
@@ -9600,7 +9755,7 @@ async function runShell(opts) {
|
|
|
9600
9755
|
);
|
|
9601
9756
|
}
|
|
9602
9757
|
function assertContainerExists(root) {
|
|
9603
|
-
if (!
|
|
9758
|
+
if (!existsSync17(path26.join(root, ".devcontainer"))) {
|
|
9604
9759
|
throw new Error(
|
|
9605
9760
|
`No .devcontainer/ at ${root}. Run \`monoceros apply <name>\` first.`
|
|
9606
9761
|
);
|
|
@@ -9690,7 +9845,7 @@ var init_run = __esm({
|
|
|
9690
9845
|
|
|
9691
9846
|
// src/commands/run.ts
|
|
9692
9847
|
import { defineCommand as defineCommand24 } from "citty";
|
|
9693
|
-
import { consola as
|
|
9848
|
+
import { consola as consola29 } from "consola";
|
|
9694
9849
|
var runCommand;
|
|
9695
9850
|
var init_run2 = __esm({
|
|
9696
9851
|
"src/commands/run.ts"() {
|
|
@@ -9718,7 +9873,7 @@ var init_run2 = __esm({
|
|
|
9718
9873
|
async run({ args }) {
|
|
9719
9874
|
const command = [...getInnerArgs()];
|
|
9720
9875
|
if (command.length === 0) {
|
|
9721
|
-
|
|
9876
|
+
consola29.error(
|
|
9722
9877
|
"No command provided. Usage: `monoceros run <containername> -- <cmd> [args\u2026]`."
|
|
9723
9878
|
);
|
|
9724
9879
|
process.exit(1);
|
|
@@ -9732,7 +9887,7 @@ var init_run2 = __esm({
|
|
|
9732
9887
|
});
|
|
9733
9888
|
process.exit(exitCode);
|
|
9734
9889
|
} catch (err) {
|
|
9735
|
-
|
|
9890
|
+
consola29.error(err instanceof Error ? err.message : String(err));
|
|
9736
9891
|
process.exit(1);
|
|
9737
9892
|
}
|
|
9738
9893
|
}
|
|
@@ -9742,7 +9897,7 @@ var init_run2 = __esm({
|
|
|
9742
9897
|
|
|
9743
9898
|
// src/commands/shell.ts
|
|
9744
9899
|
import { defineCommand as defineCommand25 } from "citty";
|
|
9745
|
-
import { consola as
|
|
9900
|
+
import { consola as consola30 } from "consola";
|
|
9746
9901
|
var shellCommand;
|
|
9747
9902
|
var init_shell2 = __esm({
|
|
9748
9903
|
"src/commands/shell.ts"() {
|
|
@@ -9767,7 +9922,7 @@ var init_shell2 = __esm({
|
|
|
9767
9922
|
const exitCode = await runShell({ root: containerDir(args.name) });
|
|
9768
9923
|
process.exit(exitCode);
|
|
9769
9924
|
} catch (err) {
|
|
9770
|
-
|
|
9925
|
+
consola30.error(err instanceof Error ? err.message : String(err));
|
|
9771
9926
|
process.exit(1);
|
|
9772
9927
|
}
|
|
9773
9928
|
}
|
|
@@ -9777,7 +9932,7 @@ var init_shell2 = __esm({
|
|
|
9777
9932
|
|
|
9778
9933
|
// src/commands/start.ts
|
|
9779
9934
|
import { defineCommand as defineCommand26 } from "citty";
|
|
9780
|
-
import { consola as
|
|
9935
|
+
import { consola as consola31 } from "consola";
|
|
9781
9936
|
var startCommand;
|
|
9782
9937
|
var init_start = __esm({
|
|
9783
9938
|
"src/commands/start.ts"() {
|
|
@@ -9814,7 +9969,7 @@ var init_start = __esm({
|
|
|
9814
9969
|
hostPort = proxyHostPort(global);
|
|
9815
9970
|
}
|
|
9816
9971
|
} catch (err) {
|
|
9817
|
-
|
|
9972
|
+
consola31.warn(
|
|
9818
9973
|
`Could not read container yml ahead of start: ${err instanceof Error ? err.message : String(err)}. Skipping Traefik pre-flight.`
|
|
9819
9974
|
);
|
|
9820
9975
|
}
|
|
@@ -9869,7 +10024,7 @@ var init_status = __esm({
|
|
|
9869
10024
|
|
|
9870
10025
|
// src/commands/stop.ts
|
|
9871
10026
|
import { defineCommand as defineCommand28 } from "citty";
|
|
9872
|
-
import { consola as
|
|
10027
|
+
import { consola as consola32 } from "consola";
|
|
9873
10028
|
var stopCommand;
|
|
9874
10029
|
var init_stop = __esm({
|
|
9875
10030
|
"src/commands/stop.ts"() {
|
|
@@ -9903,10 +10058,10 @@ var init_stop = __esm({
|
|
|
9903
10058
|
});
|
|
9904
10059
|
try {
|
|
9905
10060
|
await maybeStopProxy({
|
|
9906
|
-
logger: { info: (msg) =>
|
|
10061
|
+
logger: { info: (msg) => consola32.info(msg) }
|
|
9907
10062
|
});
|
|
9908
10063
|
} catch (err) {
|
|
9909
|
-
|
|
10064
|
+
consola32.warn(
|
|
9910
10065
|
`Could not tear down the Traefik proxy: ${err instanceof Error ? err.message : String(err)}. Ignored.`
|
|
9911
10066
|
);
|
|
9912
10067
|
}
|
|
@@ -9918,11 +10073,11 @@ var init_stop = __esm({
|
|
|
9918
10073
|
});
|
|
9919
10074
|
|
|
9920
10075
|
// src/tunnel/resolve.ts
|
|
9921
|
-
import { existsSync as
|
|
9922
|
-
import
|
|
10076
|
+
import { existsSync as existsSync18 } from "fs";
|
|
10077
|
+
import path27 from "path";
|
|
9923
10078
|
async function resolveTunnelTarget(opts) {
|
|
9924
10079
|
const ymlPath = containerConfigPath(opts.name, opts.monocerosHome);
|
|
9925
|
-
if (!
|
|
10080
|
+
if (!existsSync18(ymlPath)) {
|
|
9926
10081
|
throw new Error(
|
|
9927
10082
|
`No yml profile for '${opts.name}' at ${ymlPath}. Run \`monoceros init ${opts.name}\` first.`
|
|
9928
10083
|
);
|
|
@@ -9930,13 +10085,13 @@ async function resolveTunnelTarget(opts) {
|
|
|
9930
10085
|
const parsed = await readConfig(ymlPath);
|
|
9931
10086
|
const config = parsed.config;
|
|
9932
10087
|
const containerRoot = containerDir(opts.name, opts.monocerosHome);
|
|
9933
|
-
if (!
|
|
10088
|
+
if (!existsSync18(containerRoot)) {
|
|
9934
10089
|
throw new Error(
|
|
9935
10090
|
`Container '${opts.name}' is not materialised at ${containerRoot}. Run \`monoceros apply ${opts.name}\` first.`
|
|
9936
10091
|
);
|
|
9937
10092
|
}
|
|
9938
|
-
const composePath =
|
|
9939
|
-
const isCompose =
|
|
10093
|
+
const composePath = path27.join(containerRoot, ".devcontainer", "compose.yaml");
|
|
10094
|
+
const isCompose = existsSync18(composePath);
|
|
9940
10095
|
const parsedTarget = parseTargetArg(opts.target, config);
|
|
9941
10096
|
const docker = opts.docker ?? defaultDockerExec;
|
|
9942
10097
|
if (isCompose) {
|
|
@@ -10172,7 +10327,7 @@ var init_port_check2 = __esm({
|
|
|
10172
10327
|
|
|
10173
10328
|
// src/tunnel/run.ts
|
|
10174
10329
|
import { spawn as spawn10 } from "child_process";
|
|
10175
|
-
import { consola as
|
|
10330
|
+
import { consola as consola33 } from "consola";
|
|
10176
10331
|
function signalNumber(signal) {
|
|
10177
10332
|
switch (signal) {
|
|
10178
10333
|
case "SIGINT":
|
|
@@ -10185,8 +10340,8 @@ function signalNumber(signal) {
|
|
|
10185
10340
|
}
|
|
10186
10341
|
async function runTunnel(opts) {
|
|
10187
10342
|
const log = opts.logger ?? {
|
|
10188
|
-
info: (m) =>
|
|
10189
|
-
warn: (m) =>
|
|
10343
|
+
info: (m) => consola33.info(m),
|
|
10344
|
+
warn: (m) => consola33.warn(m)
|
|
10190
10345
|
};
|
|
10191
10346
|
const resolve = opts.resolve ?? resolveTunnelTarget;
|
|
10192
10347
|
const resolveArgs3 = {
|
|
@@ -10293,7 +10448,7 @@ var init_run3 = __esm({
|
|
|
10293
10448
|
|
|
10294
10449
|
// src/commands/tunnel.ts
|
|
10295
10450
|
import { defineCommand as defineCommand29 } from "citty";
|
|
10296
|
-
import { consola as
|
|
10451
|
+
import { consola as consola34 } from "consola";
|
|
10297
10452
|
function parseLocalPort(raw) {
|
|
10298
10453
|
if (raw === void 0) return void 0;
|
|
10299
10454
|
const n = Number(raw);
|
|
@@ -10346,7 +10501,7 @@ var init_tunnel = __esm({
|
|
|
10346
10501
|
});
|
|
10347
10502
|
process.exit(exitCode);
|
|
10348
10503
|
} catch (err) {
|
|
10349
|
-
|
|
10504
|
+
consola34.error(err instanceof Error ? err.message : String(err));
|
|
10350
10505
|
process.exit(1);
|
|
10351
10506
|
}
|
|
10352
10507
|
}
|
|
@@ -10416,8 +10571,8 @@ var init_prune = __esm({
|
|
|
10416
10571
|
});
|
|
10417
10572
|
|
|
10418
10573
|
// src/upgrade/index.ts
|
|
10419
|
-
import { existsSync as
|
|
10420
|
-
import { consola as
|
|
10574
|
+
import { existsSync as existsSync19, promises as fs17 } from "fs";
|
|
10575
|
+
import { consola as consola35 } from "consola";
|
|
10421
10576
|
async function fetchRuntimeVersions() {
|
|
10422
10577
|
const tokenUrl = `https://ghcr.io/token?service=ghcr.io&scope=repository:${RUNTIME_REPO}:pull`;
|
|
10423
10578
|
const tokenRes = await fetch(tokenUrl);
|
|
@@ -10455,7 +10610,7 @@ ${yml}`;
|
|
|
10455
10610
|
}
|
|
10456
10611
|
async function runUpgrade(opts) {
|
|
10457
10612
|
const home = opts.monocerosHome ?? monocerosHome();
|
|
10458
|
-
const logger = opts.logger ??
|
|
10613
|
+
const logger = opts.logger ?? consola35;
|
|
10459
10614
|
const fetchVersions = opts.fetchVersions ?? fetchRuntimeVersions;
|
|
10460
10615
|
if (opts.list) {
|
|
10461
10616
|
const versions = await fetchVersions();
|
|
@@ -10481,7 +10636,7 @@ async function runUpgrade(opts) {
|
|
|
10481
10636
|
);
|
|
10482
10637
|
}
|
|
10483
10638
|
}
|
|
10484
|
-
if (opts.name && !
|
|
10639
|
+
if (opts.name && !existsSync19(containerConfigPath(opts.name, home))) {
|
|
10485
10640
|
throw new Error(
|
|
10486
10641
|
`No such config: ${containerConfigPath(opts.name, home)}. Run \`monoceros init <template> ${opts.name}\` first.`
|
|
10487
10642
|
);
|
|
@@ -10532,7 +10687,7 @@ async function runUpgrade(opts) {
|
|
|
10532
10687
|
let bumped = 0;
|
|
10533
10688
|
for (const name of targets) {
|
|
10534
10689
|
const ymlPath = containerConfigPath(name, home);
|
|
10535
|
-
if (!
|
|
10690
|
+
if (!existsSync19(ymlPath)) continue;
|
|
10536
10691
|
const raw = await fs17.readFile(ymlPath, "utf8");
|
|
10537
10692
|
const updated = setRuntimeVersion(raw, pinVersion);
|
|
10538
10693
|
if (updated !== raw) {
|
|
@@ -10983,25 +11138,25 @@ function detectHelpRequest(argv, main2) {
|
|
|
10983
11138
|
const separatorIdx = argv.indexOf("--");
|
|
10984
11139
|
if (helpIdx === -1) return null;
|
|
10985
11140
|
if (separatorIdx !== -1 && separatorIdx < helpIdx) return null;
|
|
10986
|
-
const
|
|
11141
|
+
const path28 = [];
|
|
10987
11142
|
const tokens = argv.slice(
|
|
10988
11143
|
0,
|
|
10989
11144
|
separatorIdx === -1 ? argv.length : separatorIdx
|
|
10990
11145
|
);
|
|
10991
11146
|
let cursor = main2;
|
|
10992
11147
|
const mainName = (main2.meta ?? {}).name ?? "monoceros";
|
|
10993
|
-
|
|
11148
|
+
path28.push(mainName);
|
|
10994
11149
|
for (const tok of tokens) {
|
|
10995
11150
|
if (tok.startsWith("-")) continue;
|
|
10996
11151
|
const subs = cursor.subCommands ?? {};
|
|
10997
11152
|
if (tok in subs) {
|
|
10998
11153
|
cursor = subs[tok];
|
|
10999
|
-
|
|
11154
|
+
path28.push(tok);
|
|
11000
11155
|
continue;
|
|
11001
11156
|
}
|
|
11002
11157
|
break;
|
|
11003
11158
|
}
|
|
11004
|
-
return { path:
|
|
11159
|
+
return { path: path28, cmd: cursor };
|
|
11005
11160
|
}
|
|
11006
11161
|
async function maybeRenderHelp(argv, main2) {
|
|
11007
11162
|
const hit = detectHelpRequest(argv, main2);
|