@qodalis/cli 2.0.0-beta.12 → 2.0.0-beta.14
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/assets/cli-panel.css +78 -1
- package/package.json +2 -2
- package/public-api.d.mts +195 -22
- package/public-api.d.ts +195 -22
- package/public-api.js +1027 -453
- package/public-api.js.map +1 -1
- package/public-api.mjs +1023 -455
- package/public-api.mjs.map +1 -1
- package/wasm/qodalis_cli_wasm_bg.wasm +0 -0
package/public-api.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CliLogLevel, DefaultThemes, DefaultThemeInfos, DefaultLibraryAuthor, CliIcon, CliForegroundColor, LIBRARY_VERSION as LIBRARY_VERSION$1, resolveConfigurationCategories, ICliTranslationService_TOKEN, ServerVersionNegotiator, formatJson, visibleLength, stripAnsi, getRightOfWord, CancellablePromise, getParameterValue, CLI_CONFIGURE_STORE_NAME, CliModuleRegistry, initializeBrowserEnvironment, satisfiesVersionRange, ICliDragDropService_TOKEN, ICliCompletionProvider_TOKEN, delay, colorFirstWord, clearTerminalLine } from '@qodalis/cli-core';
|
|
1
|
+
import { CliLogLevel, DefaultThemes, DefaultThemeInfos, DefaultLibraryAuthor, CliIcon, CliForegroundColor, LIBRARY_VERSION as LIBRARY_VERSION$1, resolveConfigurationCategories, ICliTranslationService_TOKEN, ICliAuthorizationService_TOKEN, resolveHeaders, appendQueryParams, buildAuthenticatedWebSocketUrl, ServerVersionNegotiator, CliHttpError, formatJson, visibleLength, stripAnsi, getRightOfWord, CancellablePromise, isCliAccessDeniedError, getParameterValue, ICliCommandGuard_TOKEN, CLI_CONFIGURE_STORE_NAME, CliModuleRegistry, initializeBrowserEnvironment, ICliPermissionRegistry_TOKEN, satisfiesVersionRange, CliServerPermissions, ICliDragDropService_TOKEN, cliAccessMetadataGuards, ICliServerAuthService_TOKEN, ICliCompletionProvider_TOKEN, delay, colorFirstWord, clearTerminalLine, ICliServerAuthTokenProvider_TOKEN } from '@qodalis/cli-core';
|
|
2
2
|
export { ICliUserSessionService_TOKEN, ICliUsersStoreService_TOKEN } from '@qodalis/cli-core';
|
|
3
3
|
import { Subject, BehaviorSubject } from 'rxjs';
|
|
4
4
|
import { map, distinctUntilChanged } from 'rxjs/operators';
|
|
@@ -408,10 +408,31 @@ var ICliPingServerService_TOKEN = "cli-ping-server-service";
|
|
|
408
408
|
var CliModuleRegistry_TOKEN = "cli-module-registry";
|
|
409
409
|
var CliBackgroundServiceRegistry_TOKEN = "cli-background-service-registry";
|
|
410
410
|
var CliPackageManagerService_TOKEN = "cli-package-manager-service";
|
|
411
|
+
var CliKeyValueStore_TOKEN = "cli-key-value-store";
|
|
412
|
+
var SyntaxHighlighterRegistry_TOKEN = "syntax-highlighter-registry";
|
|
411
413
|
|
|
412
414
|
// src/lib/version.ts
|
|
413
|
-
var LIBRARY_VERSION = "2.0.0-beta.
|
|
415
|
+
var LIBRARY_VERSION = "2.0.0-beta.14";
|
|
414
416
|
var API_VERSION = 2;
|
|
417
|
+
var ANONYMOUS = "\0anonymous";
|
|
418
|
+
function aliasOwner(context2) {
|
|
419
|
+
let auth;
|
|
420
|
+
try {
|
|
421
|
+
auth = context2.services.get(ICliAuthorizationService_TOKEN);
|
|
422
|
+
} catch {
|
|
423
|
+
auth = void 0;
|
|
424
|
+
}
|
|
425
|
+
if (!auth) return void 0;
|
|
426
|
+
return auth.getPrincipal()?.name ?? ANONYMOUS;
|
|
427
|
+
}
|
|
428
|
+
function aliasesFor(state, owner) {
|
|
429
|
+
if (owner === void 0) return state?.aliases ?? {};
|
|
430
|
+
return state?.aliasesByUser?.[owner] ?? {};
|
|
431
|
+
}
|
|
432
|
+
function withAliases(state, owner, aliases) {
|
|
433
|
+
if (owner === void 0) return { aliases };
|
|
434
|
+
return { aliasesByUser: { ...state?.aliasesByUser ?? {}, [owner]: aliases } };
|
|
435
|
+
}
|
|
415
436
|
var CliAliasCommandProcessor = class {
|
|
416
437
|
constructor() {
|
|
417
438
|
this.command = "alias";
|
|
@@ -428,26 +449,33 @@ var CliAliasCommandProcessor = class {
|
|
|
428
449
|
},
|
|
429
450
|
storeName: "aliases"
|
|
430
451
|
};
|
|
452
|
+
/** Shared aliases (used when no auth module is loaded) */
|
|
431
453
|
this.userAliases = {};
|
|
454
|
+
this.aliasState = {};
|
|
432
455
|
this.processors = [
|
|
433
456
|
{
|
|
434
457
|
command: "ls",
|
|
435
458
|
description: "List all aliases",
|
|
436
459
|
processCommand: async (_, context2) => {
|
|
437
460
|
const { writer } = context2;
|
|
461
|
+
const visible = this.aliasesFor(context2);
|
|
438
462
|
writer.writeln("Aliases:");
|
|
439
|
-
Object.entries(
|
|
463
|
+
Object.entries(visible).forEach(
|
|
440
464
|
([alias, command2]) => {
|
|
441
465
|
writer.writeInfo(` ${alias} -> ${command2}`);
|
|
442
466
|
}
|
|
443
467
|
);
|
|
444
|
-
if (Object.keys(
|
|
468
|
+
if (Object.keys(visible).length === 0) {
|
|
445
469
|
writer.writeInfo(" No aliases defined");
|
|
446
470
|
}
|
|
447
471
|
}
|
|
448
472
|
}
|
|
449
473
|
];
|
|
450
474
|
}
|
|
475
|
+
/** Aliases visible to the current principal */
|
|
476
|
+
aliasesFor(context2) {
|
|
477
|
+
return aliasesFor(this.aliasState, aliasOwner(context2));
|
|
478
|
+
}
|
|
451
479
|
writeDescription(context2) {
|
|
452
480
|
const { writer, translator: t } = context2;
|
|
453
481
|
writer.writeln(t.t("cli.alias.long_description", "Create shortcut aliases for frequently used commands"));
|
|
@@ -473,7 +501,7 @@ var CliAliasCommandProcessor = class {
|
|
|
473
501
|
);
|
|
474
502
|
}
|
|
475
503
|
async processCommand(command2, context2) {
|
|
476
|
-
const registry = context2.services.
|
|
504
|
+
const registry = context2.services.getRequired(
|
|
477
505
|
CliProcessorsRegistry_TOKEN
|
|
478
506
|
);
|
|
479
507
|
const { writer } = context2;
|
|
@@ -493,18 +521,20 @@ var CliAliasCommandProcessor = class {
|
|
|
493
521
|
}
|
|
494
522
|
context2.writer.writeInfo(`${alias} -> ${command2.args[alias]}`);
|
|
495
523
|
}
|
|
496
|
-
context2
|
|
497
|
-
|
|
498
|
-
|
|
524
|
+
const owner = aliasOwner(context2);
|
|
525
|
+
context2.state.updateState(
|
|
526
|
+
withAliases(this.aliasState, owner, {
|
|
527
|
+
...aliasesFor(this.aliasState, owner),
|
|
499
528
|
...command2.args
|
|
500
|
-
}
|
|
501
|
-
|
|
529
|
+
})
|
|
530
|
+
);
|
|
502
531
|
await context2.state.persist();
|
|
503
532
|
}
|
|
504
533
|
async initialize(context2) {
|
|
505
534
|
this.stateSubscription?.unsubscribe();
|
|
506
|
-
this.stateSubscription = context2.state.select((x) => x
|
|
507
|
-
this.
|
|
535
|
+
this.stateSubscription = context2.state.select((x) => x).subscribe((state) => {
|
|
536
|
+
this.aliasState = state ?? {};
|
|
537
|
+
this.userAliases = this.aliasState.aliases ?? {};
|
|
508
538
|
});
|
|
509
539
|
}
|
|
510
540
|
};
|
|
@@ -1332,7 +1362,9 @@ var CliEvalCommandProcessor = class {
|
|
|
1332
1362
|
this.acceptsRawInput = true;
|
|
1333
1363
|
this.metadata = {
|
|
1334
1364
|
icon: "\u{1F9EE}",
|
|
1335
|
-
module: "misc"
|
|
1365
|
+
module: "misc",
|
|
1366
|
+
// Enforced only when an auth module is loaded (eval also needs allowEval)
|
|
1367
|
+
requiredPermissions: ["system:eval"]
|
|
1336
1368
|
};
|
|
1337
1369
|
}
|
|
1338
1370
|
async processCommand(command, context) {
|
|
@@ -2447,7 +2479,9 @@ var CliUnAliasCommandProcessor = class {
|
|
|
2447
2479
|
async processCommand(command2, context2) {
|
|
2448
2480
|
const { writer } = context2;
|
|
2449
2481
|
const aliasToRemove = command2.value;
|
|
2450
|
-
const
|
|
2482
|
+
const state = context2.state.getState();
|
|
2483
|
+
const owner = aliasOwner(context2);
|
|
2484
|
+
const aliases = aliasesFor(state, owner);
|
|
2451
2485
|
if (!aliases[aliasToRemove]) {
|
|
2452
2486
|
writer.writeError(`Alias ${aliasToRemove} not found`);
|
|
2453
2487
|
context2.process.exit(-1);
|
|
@@ -2457,9 +2491,7 @@ var CliUnAliasCommandProcessor = class {
|
|
|
2457
2491
|
Object.keys(aliases).filter((alias) => alias !== aliasToRemove).forEach((alias) => {
|
|
2458
2492
|
updated[alias] = aliases[alias];
|
|
2459
2493
|
});
|
|
2460
|
-
context2.state.updateState(
|
|
2461
|
-
aliases: updated
|
|
2462
|
-
});
|
|
2494
|
+
context2.state.updateState(withAliases(state, owner, updated));
|
|
2463
2495
|
await context2.state.persist();
|
|
2464
2496
|
}
|
|
2465
2497
|
};
|
|
@@ -2813,7 +2845,7 @@ var CliConfigureCommandProcessor = class _CliConfigureCommandProcessor {
|
|
|
2813
2845
|
];
|
|
2814
2846
|
}
|
|
2815
2847
|
async processCommand(command2, context2) {
|
|
2816
|
-
const registry = context2.services.
|
|
2848
|
+
const registry = context2.services.getRequired(
|
|
2817
2849
|
CliProcessorsRegistry_TOKEN
|
|
2818
2850
|
);
|
|
2819
2851
|
const pluginCategories = resolveConfigurationCategories(registry);
|
|
@@ -2910,10 +2942,10 @@ var CliConfigureCommandProcessor = class _CliConfigureCommandProcessor {
|
|
|
2910
2942
|
if (stateKey === "system") {
|
|
2911
2943
|
const langOption = options.find((o) => o.key === "language");
|
|
2912
2944
|
if (langOption) {
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2945
|
+
const translator = context2.services.get(
|
|
2946
|
+
ICliTranslationService_TOKEN
|
|
2947
|
+
);
|
|
2948
|
+
if (translator) {
|
|
2917
2949
|
const locales = translator.getAvailableLocales();
|
|
2918
2950
|
if (locales.length > 0) {
|
|
2919
2951
|
langOption.options = locales.map((l) => ({
|
|
@@ -2921,7 +2953,6 @@ var CliConfigureCommandProcessor = class _CliConfigureCommandProcessor {
|
|
|
2921
2953
|
value: l
|
|
2922
2954
|
}));
|
|
2923
2955
|
}
|
|
2924
|
-
} catch {
|
|
2925
2956
|
}
|
|
2926
2957
|
}
|
|
2927
2958
|
}
|
|
@@ -3066,13 +3097,10 @@ var CliConfigureCommandProcessor = class _CliConfigureCommandProcessor {
|
|
|
3066
3097
|
}
|
|
3067
3098
|
}
|
|
3068
3099
|
if (settings["language"]) {
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
translator.setLocale(settings["language"]);
|
|
3074
|
-
} catch {
|
|
3075
|
-
}
|
|
3100
|
+
const translator = context2.services.get(
|
|
3101
|
+
ICliTranslationService_TOKEN
|
|
3102
|
+
);
|
|
3103
|
+
translator?.setLocale(settings["language"]);
|
|
3076
3104
|
}
|
|
3077
3105
|
if (context2.terminal?.options) {
|
|
3078
3106
|
if (settings["cursorBlink"] !== void 0) {
|
|
@@ -3102,7 +3130,7 @@ var CliConfigureCommandProcessor = class _CliConfigureCommandProcessor {
|
|
|
3102
3130
|
aliases: ["ls"],
|
|
3103
3131
|
description: "List all configuration options and their current values",
|
|
3104
3132
|
processCommand: async (_, context2) => {
|
|
3105
|
-
const registry = context2.services.
|
|
3133
|
+
const registry = context2.services.getRequired(
|
|
3106
3134
|
CliProcessorsRegistry_TOKEN
|
|
3107
3135
|
);
|
|
3108
3136
|
const allOptions = this.getAllOptions(registry);
|
|
@@ -3164,7 +3192,7 @@ var CliConfigureCommandProcessor = class _CliConfigureCommandProcessor {
|
|
|
3164
3192
|
}
|
|
3165
3193
|
const category = path.substring(0, dotIndex);
|
|
3166
3194
|
const key = path.substring(dotIndex + 1);
|
|
3167
|
-
const registry = context2.services.
|
|
3195
|
+
const registry = context2.services.getRequired(
|
|
3168
3196
|
CliProcessorsRegistry_TOKEN
|
|
3169
3197
|
);
|
|
3170
3198
|
const allOptions = this.getAllOptions(registry);
|
|
@@ -3216,7 +3244,7 @@ var CliConfigureCommandProcessor = class _CliConfigureCommandProcessor {
|
|
|
3216
3244
|
}
|
|
3217
3245
|
const category = path.substring(0, dotIndex);
|
|
3218
3246
|
const key = path.substring(dotIndex + 1);
|
|
3219
|
-
const registry = context2.services.
|
|
3247
|
+
const registry = context2.services.getRequired(
|
|
3220
3248
|
CliProcessorsRegistry_TOKEN
|
|
3221
3249
|
);
|
|
3222
3250
|
const allOptions = this.getAllOptions(registry);
|
|
@@ -3276,7 +3304,7 @@ var CliConfigureCommandProcessor = class _CliConfigureCommandProcessor {
|
|
|
3276
3304
|
t.t("cli.configure.system_reset", "System configuration reset to defaults")
|
|
3277
3305
|
);
|
|
3278
3306
|
} else {
|
|
3279
|
-
const registry = context2.services.
|
|
3307
|
+
const registry = context2.services.getRequired(
|
|
3280
3308
|
CliProcessorsRegistry_TOKEN
|
|
3281
3309
|
);
|
|
3282
3310
|
const categories2 = resolveConfigurationCategories(registry);
|
|
@@ -3672,7 +3700,7 @@ var CliHelpCommandProcessor = class {
|
|
|
3672
3700
|
async processCommand(command2, context2) {
|
|
3673
3701
|
const { writer } = context2;
|
|
3674
3702
|
const t = context2.translator;
|
|
3675
|
-
const registry = context2.services.
|
|
3703
|
+
const registry = context2.services.getRequired(
|
|
3676
3704
|
CliProcessorsRegistry_TOKEN
|
|
3677
3705
|
);
|
|
3678
3706
|
const [_, ...commandsToHelp] = command2.command.split(" ");
|
|
@@ -3772,24 +3800,23 @@ var CliHelpCommandProcessor = class {
|
|
|
3772
3800
|
writeProcessorDescription(processor, context2) {
|
|
3773
3801
|
const { writer } = context2;
|
|
3774
3802
|
const t = context2.translator;
|
|
3775
|
-
const icon = processor.metadata?.icon || "";
|
|
3776
|
-
const name = `${BOLD}${writer.wrapInColor(processor.command, CliForegroundColor.Cyan)}${RESET}`;
|
|
3777
3803
|
const version = `${DIM}v${processor.version || "1.0.0"}${RESET}`;
|
|
3778
|
-
|
|
3779
|
-
writer.writeln(` ${icon}${icon ? " " : ""}${name} ${version}`);
|
|
3804
|
+
const headerLines = [];
|
|
3780
3805
|
if (processor.description) {
|
|
3781
|
-
|
|
3782
|
-
processor.description,
|
|
3783
|
-
processor.command,
|
|
3784
|
-
context2
|
|
3806
|
+
headerLines.push(
|
|
3807
|
+
this.translateDescription(processor.description, processor.command, context2)
|
|
3785
3808
|
);
|
|
3786
|
-
writer.writeln(` ${desc}`);
|
|
3787
3809
|
}
|
|
3788
3810
|
if (processor.aliases?.length) {
|
|
3789
|
-
|
|
3790
|
-
|
|
3811
|
+
headerLines.push(
|
|
3812
|
+
`${DIM}${t.t("cli.help.aliases", "Aliases:")}${RESET} ${processor.aliases.map((a) => writer.wrapInColor(a, CliForegroundColor.Magenta)).join(", ")}`
|
|
3791
3813
|
);
|
|
3792
3814
|
}
|
|
3815
|
+
writer.writeln();
|
|
3816
|
+
writer.writeBox(headerLines, {
|
|
3817
|
+
title: `${writer.wrapInColor(processor.command, CliForegroundColor.Cyan)} ${version}`,
|
|
3818
|
+
borderColor: CliForegroundColor.White
|
|
3819
|
+
});
|
|
3793
3820
|
if (processor.originalProcessor) {
|
|
3794
3821
|
writer.writeln();
|
|
3795
3822
|
writer.writeln(
|
|
@@ -3955,20 +3982,13 @@ var CliVersionCommandProcessor = class {
|
|
|
3955
3982
|
writer.writeln(
|
|
3956
3983
|
writer.wrapInColor(getCliNameArt(context2.terminal.cols), CliForegroundColor.Cyan)
|
|
3957
3984
|
);
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
}
|
|
3966
|
-
writer.writeln(
|
|
3967
|
-
` ${DIM2}Framework${RESET2} ${writer.wrapInColor(framework, CliForegroundColor.Cyan)}`
|
|
3968
|
-
);
|
|
3969
|
-
writer.writeln(
|
|
3970
|
-
` ${DIM2}Docs${RESET2} ${writer.wrapInColor("https://cli.qodalis.com/docs/", CliForegroundColor.Blue)}`
|
|
3971
|
-
);
|
|
3985
|
+
const framework = context2.services.get("cli-framework") ?? "vanilla";
|
|
3986
|
+
writer.writeBox([
|
|
3987
|
+
`${DIM2}CLI${RESET2} ${writer.wrapInColor(`v${LIBRARY_VERSION}`, CliForegroundColor.Green)}`,
|
|
3988
|
+
`${DIM2}Core${RESET2} ${writer.wrapInColor(`v${LIBRARY_VERSION$1}`, CliForegroundColor.Green)}`,
|
|
3989
|
+
`${DIM2}Framework${RESET2} ${writer.wrapInColor(framework, CliForegroundColor.Cyan)}`,
|
|
3990
|
+
`${DIM2}Docs${RESET2} ${writer.wrapInColor("https://cli.qodalis.com/docs/", CliForegroundColor.Blue)}`
|
|
3991
|
+
], { borderColor: CliForegroundColor.White });
|
|
3972
3992
|
writer.writeln();
|
|
3973
3993
|
}
|
|
3974
3994
|
writeDescription(context2) {
|
|
@@ -4026,11 +4046,7 @@ function collectSystemInfo(context2) {
|
|
|
4026
4046
|
const lines = [];
|
|
4027
4047
|
lines.push(`- **CLI Version:** ${LIBRARY_VERSION}`);
|
|
4028
4048
|
lines.push(`- **Core Version:** ${LIBRARY_VERSION$1}`);
|
|
4029
|
-
|
|
4030
|
-
try {
|
|
4031
|
-
framework = context2.services.get("cli-framework");
|
|
4032
|
-
} catch {
|
|
4033
|
-
}
|
|
4049
|
+
const framework = context2.services.get("cli-framework") ?? "vanilla";
|
|
4034
4050
|
lines.push(`- **Framework:** ${framework}`);
|
|
4035
4051
|
lines.push(`- **Terminal:** ${context2.terminal.cols}x${context2.terminal.rows}`);
|
|
4036
4052
|
if (typeof navigator !== "undefined") {
|
|
@@ -4102,12 +4118,8 @@ async function runInteractiveFlow(type, initialTitle, context2) {
|
|
|
4102
4118
|
`${writer.wrapInColor("\u2500\u2500 System Info (auto-attached) \u2500\u2500", CliForegroundColor.Cyan)}`
|
|
4103
4119
|
);
|
|
4104
4120
|
writer.writeln(` CLI: ${LIBRARY_VERSION} Core: ${LIBRARY_VERSION$1}`);
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
framework = context2.services.get("cli-framework");
|
|
4108
|
-
} catch {
|
|
4109
|
-
}
|
|
4110
|
-
writer.writeln(` Framework: ${framework} Terminal: ${context2.terminal.cols}x${context2.terminal.rows}`);
|
|
4121
|
+
const previewFramework = context2.services.get("cli-framework") ?? "vanilla";
|
|
4122
|
+
writer.writeln(` Framework: ${previewFramework} Terminal: ${context2.terminal.cols}x${context2.terminal.rows}`);
|
|
4111
4123
|
if (typeof navigator !== "undefined") {
|
|
4112
4124
|
writer.writeln(` Platform: ${navigator.platform} Language: ${navigator.language}`);
|
|
4113
4125
|
}
|
|
@@ -4249,7 +4261,7 @@ var CliHistoryCommandProcessor = class {
|
|
|
4249
4261
|
command: "clear",
|
|
4250
4262
|
description: "Clears the command history",
|
|
4251
4263
|
processCommand: async (_, context2) => {
|
|
4252
|
-
const commandHistory = context2.services.
|
|
4264
|
+
const commandHistory = context2.services.getRequired(
|
|
4253
4265
|
CliCommandHistory_TOKEN
|
|
4254
4266
|
);
|
|
4255
4267
|
await commandHistory.clearHistory();
|
|
@@ -4272,7 +4284,7 @@ var CliHistoryCommandProcessor = class {
|
|
|
4272
4284
|
description: "Search command history for a pattern",
|
|
4273
4285
|
parameters: searchParameters,
|
|
4274
4286
|
processCommand: async (cmd, context2) => {
|
|
4275
|
-
const commandHistory = context2.services.
|
|
4287
|
+
const commandHistory = context2.services.getRequired(
|
|
4276
4288
|
CliCommandHistory_TOKEN
|
|
4277
4289
|
);
|
|
4278
4290
|
const query = (cmd.value ?? "").trim();
|
|
@@ -4326,7 +4338,7 @@ var CliHistoryCommandProcessor = class {
|
|
|
4326
4338
|
}
|
|
4327
4339
|
async processCommand(_, context2) {
|
|
4328
4340
|
const { writer } = context2;
|
|
4329
|
-
const commandHistory = context2.services.
|
|
4341
|
+
const commandHistory = context2.services.getRequired(
|
|
4330
4342
|
CliCommandHistory_TOKEN
|
|
4331
4343
|
);
|
|
4332
4344
|
const history = commandHistory.getHistory();
|
|
@@ -4715,7 +4727,9 @@ var CliPackagesCommandProcessor = class {
|
|
|
4715
4727
|
this.metadata = {
|
|
4716
4728
|
sealed: true,
|
|
4717
4729
|
icon: "\u{1F4E6}",
|
|
4718
|
-
module: "system"
|
|
4730
|
+
module: "system",
|
|
4731
|
+
// Enforced only when an auth module is loaded
|
|
4732
|
+
requiredPermissions: ["system:packages"]
|
|
4719
4733
|
};
|
|
4720
4734
|
this.stateConfiguration = {
|
|
4721
4735
|
initialState: {
|
|
@@ -4773,7 +4787,7 @@ var CliPackagesCommandProcessor = class {
|
|
|
4773
4787
|
const { progressBar, writer } = context2;
|
|
4774
4788
|
const { signal, cleanup } = scope.createAbortSignal(context2);
|
|
4775
4789
|
progressBar.show();
|
|
4776
|
-
context2.
|
|
4790
|
+
context2.notifier.info("Browsing packages");
|
|
4777
4791
|
const prefix = packagesManager.QODALIS_COMMAND_PREFIX;
|
|
4778
4792
|
const knownShortNames = [
|
|
4779
4793
|
"browser-storage",
|
|
@@ -4966,7 +4980,7 @@ var CliPackagesCommandProcessor = class {
|
|
|
4966
4980
|
const packages = command2.value.split(" ");
|
|
4967
4981
|
for (const pkg of packages) {
|
|
4968
4982
|
if (signal.aborted) break;
|
|
4969
|
-
context2.
|
|
4983
|
+
context2.notifier.info(`Installing ${pkg}`);
|
|
4970
4984
|
await scope.addPackage(pkg, context2, signal);
|
|
4971
4985
|
}
|
|
4972
4986
|
cleanup();
|
|
@@ -5007,7 +5021,7 @@ var CliPackagesCommandProcessor = class {
|
|
|
5007
5021
|
const packages = command2.value.split(" ");
|
|
5008
5022
|
for (const pkg of packages) {
|
|
5009
5023
|
if (signal.aborted) break;
|
|
5010
|
-
context2.
|
|
5024
|
+
context2.notifier.info(`Removing ${pkg}`);
|
|
5011
5025
|
await scope.removePackage(pkg, context2);
|
|
5012
5026
|
}
|
|
5013
5027
|
cleanup();
|
|
@@ -5043,7 +5057,7 @@ var CliPackagesCommandProcessor = class {
|
|
|
5043
5057
|
const fullName = name.startsWith(prefix) ? name : `${prefix}${name}`;
|
|
5044
5058
|
progressBar.show();
|
|
5045
5059
|
progressBar.setText(`Fetching versions for ${name}`);
|
|
5046
|
-
context2.
|
|
5060
|
+
context2.notifier.info(`Fetching versions for ${name}`);
|
|
5047
5061
|
try {
|
|
5048
5062
|
const response = await scriptsLoader.getScript(
|
|
5049
5063
|
`https://registry.npmjs.org/${encodeURIComponent(fullName)}`,
|
|
@@ -5507,11 +5521,11 @@ var CliPackagesCommandProcessor = class {
|
|
|
5507
5521
|
);
|
|
5508
5522
|
}
|
|
5509
5523
|
async initialize(context2) {
|
|
5510
|
-
this.registry = context2.services.
|
|
5524
|
+
this.registry = context2.services.getRequired(
|
|
5511
5525
|
CliProcessorsRegistry_TOKEN
|
|
5512
5526
|
);
|
|
5513
|
-
const store = context2.services.
|
|
5514
|
-
|
|
5527
|
+
const store = context2.services.getRequired(
|
|
5528
|
+
CliKeyValueStore_TOKEN
|
|
5515
5529
|
);
|
|
5516
5530
|
this.packagesManager.setStore(store);
|
|
5517
5531
|
context2.services.set([{
|
|
@@ -5777,10 +5791,11 @@ var CliPackagesCommandProcessor = class {
|
|
|
5777
5791
|
}
|
|
5778
5792
|
};
|
|
5779
5793
|
var CliServerConnection = class _CliServerConnection {
|
|
5780
|
-
constructor(_config, _backgroundServices, _logger) {
|
|
5794
|
+
constructor(_config, _backgroundServices, _logger, _authService) {
|
|
5781
5795
|
this._config = _config;
|
|
5782
5796
|
this._backgroundServices = _backgroundServices;
|
|
5783
5797
|
this._logger = _logger;
|
|
5798
|
+
this._authService = _authService;
|
|
5784
5799
|
this._connected = false;
|
|
5785
5800
|
this._commands = [];
|
|
5786
5801
|
this._capabilities = null;
|
|
@@ -5789,6 +5804,8 @@ var CliServerConnection = class _CliServerConnection {
|
|
|
5789
5804
|
this._basePath = "";
|
|
5790
5805
|
this._wsReconnectAttempts = 0;
|
|
5791
5806
|
this._wsReconnectTimer = null;
|
|
5807
|
+
/** True once this connection registered its `server-events:<name>` background service */
|
|
5808
|
+
this._eventServiceRegistered = false;
|
|
5792
5809
|
this._healthCheckTimer = null;
|
|
5793
5810
|
this._healthCheckAttempts = 0;
|
|
5794
5811
|
}
|
|
@@ -5819,10 +5836,33 @@ var CliServerConnection = class _CliServerConnection {
|
|
|
5819
5836
|
get apiVersion() {
|
|
5820
5837
|
return this._apiVersion;
|
|
5821
5838
|
}
|
|
5839
|
+
/**
|
|
5840
|
+
* Resolve auth headers for this server connection.
|
|
5841
|
+
* Uses the auth service (which merges config headers with registered
|
|
5842
|
+
* ICliServerAuthTokenProviders), or falls back to config headers directly.
|
|
5843
|
+
*/
|
|
5844
|
+
resolveAuthHeaders() {
|
|
5845
|
+
if (this._authService) {
|
|
5846
|
+
return this._authService.getHeaders(this._config.name, this._config.headers);
|
|
5847
|
+
}
|
|
5848
|
+
return resolveHeaders(this._config.headers);
|
|
5849
|
+
}
|
|
5850
|
+
/**
|
|
5851
|
+
* WebSocket URL for this server with auth: single-use upgrade params from
|
|
5852
|
+
* auth providers when available, otherwise headers copied into the URL.
|
|
5853
|
+
*/
|
|
5854
|
+
async buildWebSocketUrl(path) {
|
|
5855
|
+
const url = this.toWebSocketUrl(this.normalizeUrl(this._config.url)) + path;
|
|
5856
|
+
const params = await this._authService?.getWebSocketParams?.(this._config.name);
|
|
5857
|
+
if (params) {
|
|
5858
|
+
return appendQueryParams(url, params);
|
|
5859
|
+
}
|
|
5860
|
+
return buildAuthenticatedWebSocketUrl(url, () => this.resolveAuthHeaders());
|
|
5861
|
+
}
|
|
5822
5862
|
async connect() {
|
|
5823
5863
|
try {
|
|
5824
5864
|
const baseUrl = this.normalizeUrl(this._config.url);
|
|
5825
|
-
const negotiated = await ServerVersionNegotiator.discover(baseUrl);
|
|
5865
|
+
const negotiated = await ServerVersionNegotiator.discover(baseUrl, () => this.resolveAuthHeaders());
|
|
5826
5866
|
if (negotiated) {
|
|
5827
5867
|
this._apiVersion = negotiated.apiVersion;
|
|
5828
5868
|
this._basePath = negotiated.basePath;
|
|
@@ -6010,15 +6050,25 @@ var CliServerConnection = class _CliServerConnection {
|
|
|
6010
6050
|
return;
|
|
6011
6051
|
}
|
|
6012
6052
|
const serviceName = `server-events:${this._config.name}`;
|
|
6053
|
+
if (this._eventServiceRegistered && this._backgroundServices.getStatus(serviceName)) {
|
|
6054
|
+
const status = this._backgroundServices.getStatus(serviceName).status;
|
|
6055
|
+
const restart = status === "running" ? this._backgroundServices.restart(serviceName) : this._backgroundServices.start(serviceName);
|
|
6056
|
+
restart.catch((e) => {
|
|
6057
|
+
this._logger?.debug(`Background event service failed for "${this._config.name}", falling back to direct: ${e}`);
|
|
6058
|
+
this.connectEventSocketDirect();
|
|
6059
|
+
});
|
|
6060
|
+
return;
|
|
6061
|
+
}
|
|
6013
6062
|
try {
|
|
6014
6063
|
this._backgroundServices.register({
|
|
6015
6064
|
name: serviceName,
|
|
6016
6065
|
description: `Event stream for server '${this._config.name}'`,
|
|
6017
6066
|
type: "daemon",
|
|
6018
6067
|
onStart: async (ctx) => {
|
|
6019
|
-
const
|
|
6020
|
-
|
|
6021
|
-
ctx.log(`Connecting to ${wsUrl}`);
|
|
6068
|
+
const wsUrl = await this.buildWebSocketUrl("/ws/v1/qcli/events");
|
|
6069
|
+
if (!this._connected) return;
|
|
6070
|
+
ctx.log(`Connecting to ${wsUrl.split("?")[0]}`);
|
|
6071
|
+
this.closeEventSocketDirect();
|
|
6022
6072
|
this._eventSocket = new WebSocket(wsUrl);
|
|
6023
6073
|
this._eventSocket.onopen = () => {
|
|
6024
6074
|
this._wsReconnectAttempts = 0;
|
|
@@ -6041,7 +6091,11 @@ var CliServerConnection = class _CliServerConnection {
|
|
|
6041
6091
|
} catch {
|
|
6042
6092
|
}
|
|
6043
6093
|
};
|
|
6044
|
-
this._eventSocket.onclose = () => {
|
|
6094
|
+
this._eventSocket.onclose = (event) => {
|
|
6095
|
+
if (this.isSessionEndedClose(event)) {
|
|
6096
|
+
ctx.log("Event socket closed: session ended", "info");
|
|
6097
|
+
return;
|
|
6098
|
+
}
|
|
6045
6099
|
if (this._connected) {
|
|
6046
6100
|
ctx.log("WebSocket closed unexpectedly, scheduling reconnect", "warn");
|
|
6047
6101
|
this.scheduleWsReconnect();
|
|
@@ -6055,6 +6109,7 @@ var CliServerConnection = class _CliServerConnection {
|
|
|
6055
6109
|
this.closeEventSocketDirect();
|
|
6056
6110
|
}
|
|
6057
6111
|
});
|
|
6112
|
+
this._eventServiceRegistered = true;
|
|
6058
6113
|
this._backgroundServices.start(serviceName).catch((e) => {
|
|
6059
6114
|
this._logger?.debug(`Background event service failed for "${this._config.name}", falling back to direct: ${e}`);
|
|
6060
6115
|
this.connectEventSocketDirect();
|
|
@@ -6065,9 +6120,13 @@ var CliServerConnection = class _CliServerConnection {
|
|
|
6065
6120
|
}
|
|
6066
6121
|
}
|
|
6067
6122
|
connectEventSocketDirect() {
|
|
6123
|
+
void this.connectEventSocketDirectAsync();
|
|
6124
|
+
}
|
|
6125
|
+
async connectEventSocketDirectAsync() {
|
|
6068
6126
|
try {
|
|
6069
|
-
const
|
|
6070
|
-
|
|
6127
|
+
const wsUrl = await this.buildWebSocketUrl("/ws/v1/qcli/events");
|
|
6128
|
+
if (!this._connected) return;
|
|
6129
|
+
this.closeEventSocketDirect();
|
|
6071
6130
|
this._eventSocket = new WebSocket(wsUrl);
|
|
6072
6131
|
this._eventSocket.onopen = () => {
|
|
6073
6132
|
this._wsReconnectAttempts = 0;
|
|
@@ -6085,7 +6144,8 @@ var CliServerConnection = class _CliServerConnection {
|
|
|
6085
6144
|
} catch {
|
|
6086
6145
|
}
|
|
6087
6146
|
};
|
|
6088
|
-
this._eventSocket.onclose = () => {
|
|
6147
|
+
this._eventSocket.onclose = (event) => {
|
|
6148
|
+
if (this.isSessionEndedClose(event)) return;
|
|
6089
6149
|
if (this._connected) {
|
|
6090
6150
|
this.scheduleWsReconnect();
|
|
6091
6151
|
}
|
|
@@ -6096,6 +6156,16 @@ var CliServerConnection = class _CliServerConnection {
|
|
|
6096
6156
|
this._logger?.debug(`WebSocket not available for "${this._config.name}": ${e}`);
|
|
6097
6157
|
}
|
|
6098
6158
|
}
|
|
6159
|
+
/**
|
|
6160
|
+
* The server closes the event socket with 4401 when the session behind it
|
|
6161
|
+
* ended (logout, revoke, expiry). Retrying with the same credentials cannot
|
|
6162
|
+
* succeed; the auth layer reconnects the server when the session changes.
|
|
6163
|
+
*/
|
|
6164
|
+
isSessionEndedClose(event) {
|
|
6165
|
+
if (event?.code !== 4401) return false;
|
|
6166
|
+
this.closeEventSocketDirect();
|
|
6167
|
+
return true;
|
|
6168
|
+
}
|
|
6099
6169
|
handleServerDisconnect() {
|
|
6100
6170
|
this._connected = false;
|
|
6101
6171
|
this._commands = [];
|
|
@@ -6170,7 +6240,7 @@ var CliServerConnection = class _CliServerConnection {
|
|
|
6170
6240
|
const controller = new AbortController();
|
|
6171
6241
|
const timer = setTimeout(() => controller.abort(), timeout);
|
|
6172
6242
|
const headers = {
|
|
6173
|
-
...this.
|
|
6243
|
+
...this.resolveAuthHeaders(),
|
|
6174
6244
|
...init?.headers ?? {}
|
|
6175
6245
|
};
|
|
6176
6246
|
return fetch(url, {
|
|
@@ -6251,7 +6321,7 @@ async function executeOnServer(connection, serverName, descriptor, command2, con
|
|
|
6251
6321
|
chainCommands: commandPath && commandPath.length > 1 ? commandPath.slice(1) : []
|
|
6252
6322
|
};
|
|
6253
6323
|
const cmdLabel = commandPath && commandPath.length > 0 ? commandPath.join(" ") : descriptor.command;
|
|
6254
|
-
context2.
|
|
6324
|
+
context2.notifier.info(`executing command: ${cmdLabel} on server ${serverName}`);
|
|
6255
6325
|
try {
|
|
6256
6326
|
if (connection.capabilities?.streaming) {
|
|
6257
6327
|
const result = await connection.executeStream(
|
|
@@ -6306,6 +6376,7 @@ var CliServerProxyProcessor = class _CliServerProxyProcessor {
|
|
|
6306
6376
|
this.processors = descriptor.processors?.map(
|
|
6307
6377
|
(sub) => new _CliServerProxyProcessor(connection, sub, serverName, true, this.commandPath)
|
|
6308
6378
|
);
|
|
6379
|
+
this.acceptsRawInput = !this.processors?.length;
|
|
6309
6380
|
}
|
|
6310
6381
|
async processCommand(command2, context2) {
|
|
6311
6382
|
return executeOnServer(
|
|
@@ -6354,6 +6425,7 @@ var CliServerMultiProxyProcessor = class _CliServerMultiProxyProcessor {
|
|
|
6354
6425
|
}).filter((e) => e !== null);
|
|
6355
6426
|
return new _CliServerMultiProxyProcessor(subEntries, this.provider, this.commandPath);
|
|
6356
6427
|
});
|
|
6428
|
+
this.acceptsRawInput = !this.processors?.length;
|
|
6357
6429
|
}
|
|
6358
6430
|
async processCommand(command2, context2) {
|
|
6359
6431
|
const defaultServer = this.provider.defaultServer;
|
|
@@ -6439,14 +6511,26 @@ var CliServerMultiProxyProcessor = class _CliServerMultiProxyProcessor {
|
|
|
6439
6511
|
// src/lib/server/cli-server-manager.ts
|
|
6440
6512
|
var CliServerManager_TOKEN = "cli-server-manager";
|
|
6441
6513
|
var CliServerManager = class {
|
|
6442
|
-
constructor(registry) {
|
|
6514
|
+
constructor(registry, authService) {
|
|
6443
6515
|
this.registry = registry;
|
|
6516
|
+
this.authService = authService;
|
|
6444
6517
|
this.connections = /* @__PURE__ */ new Map();
|
|
6445
6518
|
this._defaultServer = null;
|
|
6519
|
+
/** Bare-name aliases this manager registered (only these are ever removed) */
|
|
6520
|
+
this._bareAliases = /* @__PURE__ */ new Set();
|
|
6446
6521
|
}
|
|
6447
6522
|
get defaultServer() {
|
|
6448
6523
|
return this._defaultServer;
|
|
6449
6524
|
}
|
|
6525
|
+
preferredServer() {
|
|
6526
|
+
if (this._defaultServer && this.connections.get(this._defaultServer)?.connected) {
|
|
6527
|
+
return this._defaultServer;
|
|
6528
|
+
}
|
|
6529
|
+
for (const [name, connection] of this.connections) {
|
|
6530
|
+
if (connection.connected) return name;
|
|
6531
|
+
}
|
|
6532
|
+
return null;
|
|
6533
|
+
}
|
|
6450
6534
|
setDefaultServer(name) {
|
|
6451
6535
|
if (name !== null && !this.connections.has(name)) {
|
|
6452
6536
|
throw new Error(`Unknown server: ${name}`);
|
|
@@ -6461,7 +6545,7 @@ var CliServerManager = class {
|
|
|
6461
6545
|
this._backgroundServices = backgroundServices;
|
|
6462
6546
|
for (const config of servers) {
|
|
6463
6547
|
if (config.enabled === false) continue;
|
|
6464
|
-
const connection = new CliServerConnection(config, backgroundServices, cliLogger);
|
|
6548
|
+
const connection = new CliServerConnection(config, backgroundServices, cliLogger, this.authService);
|
|
6465
6549
|
this.connections.set(config.name, connection);
|
|
6466
6550
|
connection.onDisconnect = () => {
|
|
6467
6551
|
this.handleDisconnect(config.name);
|
|
@@ -6509,6 +6593,7 @@ var CliServerManager = class {
|
|
|
6509
6593
|
await connection.connect();
|
|
6510
6594
|
if (connection.connected) {
|
|
6511
6595
|
this.registerProxyProcessors(connection, name);
|
|
6596
|
+
this.unregisterBareAliases();
|
|
6512
6597
|
this.registerBareAliases();
|
|
6513
6598
|
return { success: true, commandCount: connection.commands.length };
|
|
6514
6599
|
}
|
|
@@ -6539,11 +6624,12 @@ var CliServerManager = class {
|
|
|
6539
6624
|
this.registerBareAliases();
|
|
6540
6625
|
}
|
|
6541
6626
|
unregisterBareAliases() {
|
|
6542
|
-
for (const p of
|
|
6543
|
-
if (
|
|
6627
|
+
for (const p of this._bareAliases) {
|
|
6628
|
+
if (this.registry.processors.includes(p)) {
|
|
6544
6629
|
this.registry.unregisterProcessor(p);
|
|
6545
6630
|
}
|
|
6546
6631
|
}
|
|
6632
|
+
this._bareAliases.clear();
|
|
6547
6633
|
}
|
|
6548
6634
|
registerProxyProcessors(connection, serverName) {
|
|
6549
6635
|
for (const descriptor of connection.commands) {
|
|
@@ -6567,7 +6653,7 @@ var CliServerManager = class {
|
|
|
6567
6653
|
}
|
|
6568
6654
|
for (const [command2, servers] of commandCounts) {
|
|
6569
6655
|
const existingProcessor = this.registry.findProcessor(command2, []);
|
|
6570
|
-
if (existingProcessor && !existingProcessor
|
|
6656
|
+
if (existingProcessor && !this._bareAliases.has(existingProcessor))
|
|
6571
6657
|
continue;
|
|
6572
6658
|
if (servers.length === 1) {
|
|
6573
6659
|
const serverName = servers[0];
|
|
@@ -6589,6 +6675,7 @@ var CliServerManager = class {
|
|
|
6589
6675
|
alias.command = command2;
|
|
6590
6676
|
alias.aliases = [namespacedCommand];
|
|
6591
6677
|
this.registry.registerProcessor(alias);
|
|
6678
|
+
this._bareAliases.add(alias);
|
|
6592
6679
|
} else {
|
|
6593
6680
|
const entries = servers.map((serverName) => {
|
|
6594
6681
|
const connection = this.connections.get(serverName);
|
|
@@ -6599,6 +6686,7 @@ var CliServerManager = class {
|
|
|
6599
6686
|
});
|
|
6600
6687
|
const multi = new CliServerMultiProxyProcessor(entries, this);
|
|
6601
6688
|
this.registry.registerProcessor(multi);
|
|
6689
|
+
this._bareAliases.add(multi);
|
|
6602
6690
|
}
|
|
6603
6691
|
}
|
|
6604
6692
|
}
|
|
@@ -6744,6 +6832,28 @@ var WASM_SEARCH_PATHS = [
|
|
|
6744
6832
|
"./assets/wasm/qodalis_cli_wasm_bg.wasm",
|
|
6745
6833
|
"/wasm/qodalis_cli_wasm_bg.wasm"
|
|
6746
6834
|
];
|
|
6835
|
+
function wasmCandidates(wasmUrl, baseUri) {
|
|
6836
|
+
const baseUrl = (typeof document !== "undefined" ? document.baseURI : void 0);
|
|
6837
|
+
let base;
|
|
6838
|
+
try {
|
|
6839
|
+
base = baseUrl ? new URL(baseUrl) : void 0;
|
|
6840
|
+
} catch {
|
|
6841
|
+
base = void 0;
|
|
6842
|
+
}
|
|
6843
|
+
const resolve = (url) => {
|
|
6844
|
+
if (!base) return url;
|
|
6845
|
+
try {
|
|
6846
|
+
return new URL(url, base).href;
|
|
6847
|
+
} catch {
|
|
6848
|
+
return url;
|
|
6849
|
+
}
|
|
6850
|
+
};
|
|
6851
|
+
const candidates = [];
|
|
6852
|
+
if (wasmUrl) candidates.push(resolve(wasmUrl));
|
|
6853
|
+
if (base) candidates.push(resolve("assets/wasm/qodalis_cli_wasm_bg.wasm"));
|
|
6854
|
+
candidates.push(...WASM_SEARCH_PATHS.map(resolve));
|
|
6855
|
+
return [...new Set(candidates)];
|
|
6856
|
+
}
|
|
6747
6857
|
var wasm;
|
|
6748
6858
|
var cachedDataViewMemory0 = null;
|
|
6749
6859
|
var cachedInt32ArrayMemory0 = null;
|
|
@@ -6972,7 +7082,7 @@ async function initWasmAccelerator(wasmUrl) {
|
|
|
6972
7082
|
return accelerator;
|
|
6973
7083
|
}
|
|
6974
7084
|
try {
|
|
6975
|
-
const paths = wasmUrl
|
|
7085
|
+
const paths = wasmCandidates(wasmUrl);
|
|
6976
7086
|
const bytes = await fetchWasmBinary(paths);
|
|
6977
7087
|
await instantiateWasm(bytes);
|
|
6978
7088
|
accelerator = createWasmAccelerator();
|
|
@@ -7012,7 +7122,7 @@ var CliDebugCommandProcessor = class {
|
|
|
7012
7122
|
metadata: { icon: CliIcon.Extension, module: "system" },
|
|
7013
7123
|
processCommand: async (_, context2) => {
|
|
7014
7124
|
const { writer } = context2;
|
|
7015
|
-
const registry = context2.services.
|
|
7125
|
+
const registry = context2.services.getRequired(
|
|
7016
7126
|
CliProcessorsRegistry_TOKEN
|
|
7017
7127
|
);
|
|
7018
7128
|
writer.writeln(
|
|
@@ -7063,12 +7173,10 @@ var CliDebugCommandProcessor = class {
|
|
|
7063
7173
|
metadata: { icon: CliIcon.Module, module: "system" },
|
|
7064
7174
|
processCommand: async (_, context2) => {
|
|
7065
7175
|
const { writer } = context2;
|
|
7066
|
-
|
|
7067
|
-
|
|
7068
|
-
|
|
7069
|
-
|
|
7070
|
-
);
|
|
7071
|
-
} catch {
|
|
7176
|
+
const moduleRegistry = context2.services.get(
|
|
7177
|
+
CliModuleRegistry_TOKEN
|
|
7178
|
+
);
|
|
7179
|
+
if (!moduleRegistry) {
|
|
7072
7180
|
writer.writeError("Module registry not available.");
|
|
7073
7181
|
return;
|
|
7074
7182
|
}
|
|
@@ -7109,7 +7217,7 @@ var CliDebugCommandProcessor = class {
|
|
|
7109
7217
|
metadata: { icon: CliIcon.Database, module: "system" },
|
|
7110
7218
|
processCommand: async (_, context2) => {
|
|
7111
7219
|
const { writer } = context2;
|
|
7112
|
-
const storeManager = context2.services.
|
|
7220
|
+
const storeManager = context2.services.getRequired(
|
|
7113
7221
|
CliStateStoreManager_TOKEN
|
|
7114
7222
|
);
|
|
7115
7223
|
const entries = storeManager.getStoreEntries();
|
|
@@ -7188,11 +7296,7 @@ var CliDebugCommandProcessor = class {
|
|
|
7188
7296
|
writer.writeln(
|
|
7189
7297
|
` ${writer.wrapInColor("CLI Version:", CliForegroundColor.Cyan)} ${LIBRARY_VERSION}`
|
|
7190
7298
|
);
|
|
7191
|
-
|
|
7192
|
-
try {
|
|
7193
|
-
framework = context2.services.get("cli-framework");
|
|
7194
|
-
} catch {
|
|
7195
|
-
}
|
|
7299
|
+
const framework = context2.services.get("cli-framework") ?? "vanilla";
|
|
7196
7300
|
writer.writeln(
|
|
7197
7301
|
` ${writer.wrapInColor("Framework:", CliForegroundColor.Cyan)} ${framework}`
|
|
7198
7302
|
);
|
|
@@ -7233,7 +7337,7 @@ var CliDebugCommandProcessor = class {
|
|
|
7233
7337
|
metadata: { icon: CliIcon.Logs, module: "system" },
|
|
7234
7338
|
processCommand: async (_, context2) => {
|
|
7235
7339
|
const { writer } = context2;
|
|
7236
|
-
const history = context2.services.
|
|
7340
|
+
const history = context2.services.getRequired(
|
|
7237
7341
|
CliCommandHistory_TOKEN
|
|
7238
7342
|
);
|
|
7239
7343
|
const commands = history.getHistory();
|
|
@@ -7322,14 +7426,14 @@ var CliDebugCommandProcessor = class {
|
|
|
7322
7426
|
writer.writeln(
|
|
7323
7427
|
` ${online ? CliIcon.CheckIcon : CliIcon.CrossIcon} Network: ${online ? "online" : "offline"}`
|
|
7324
7428
|
);
|
|
7325
|
-
const registry = context2.services.
|
|
7429
|
+
const registry = context2.services.getRequired(
|
|
7326
7430
|
CliProcessorsRegistry_TOKEN
|
|
7327
7431
|
);
|
|
7328
7432
|
writer.writeln(
|
|
7329
7433
|
` ${CliIcon.CheckIcon} Processors: ${registry.processors.length} loaded`
|
|
7330
7434
|
);
|
|
7331
7435
|
try {
|
|
7332
|
-
const moduleRegistry = context2.services.
|
|
7436
|
+
const moduleRegistry = context2.services.getRequired(
|
|
7333
7437
|
CliModuleRegistry_TOKEN
|
|
7334
7438
|
);
|
|
7335
7439
|
const modules = moduleRegistry.getAll();
|
|
@@ -7345,7 +7449,7 @@ var CliDebugCommandProcessor = class {
|
|
|
7345
7449
|
writer.writeln(
|
|
7346
7450
|
` ${wasmActive ? CliIcon.CheckIcon : CliIcon.WarningIcon} WASM Accelerator: ${wasmActive ? "loaded" : "using JS fallback"}`
|
|
7347
7451
|
);
|
|
7348
|
-
const historyService = context2.services.
|
|
7452
|
+
const historyService = context2.services.getRequired(
|
|
7349
7453
|
CliCommandHistory_TOKEN
|
|
7350
7454
|
);
|
|
7351
7455
|
writer.writeln(
|
|
@@ -7359,13 +7463,13 @@ var CliDebugCommandProcessor = class {
|
|
|
7359
7463
|
metadata: { icon: CliIcon.Save, module: "system" },
|
|
7360
7464
|
processCommand: async (_, context2) => {
|
|
7361
7465
|
const { writer } = context2;
|
|
7362
|
-
const registry = context2.services.
|
|
7466
|
+
const registry = context2.services.getRequired(
|
|
7363
7467
|
CliProcessorsRegistry_TOKEN
|
|
7364
7468
|
);
|
|
7365
|
-
const history = context2.services.
|
|
7469
|
+
const history = context2.services.getRequired(
|
|
7366
7470
|
CliCommandHistory_TOKEN
|
|
7367
7471
|
);
|
|
7368
|
-
const storeManager = context2.services.
|
|
7472
|
+
const storeManager = context2.services.getRequired(
|
|
7369
7473
|
CliStateStoreManager_TOKEN
|
|
7370
7474
|
);
|
|
7371
7475
|
const report = {
|
|
@@ -7398,7 +7502,7 @@ var CliDebugCommandProcessor = class {
|
|
|
7398
7502
|
state: storeManager.getStoreEntries()
|
|
7399
7503
|
};
|
|
7400
7504
|
try {
|
|
7401
|
-
const moduleRegistry = context2.services.
|
|
7505
|
+
const moduleRegistry = context2.services.getRequired(
|
|
7402
7506
|
CliModuleRegistry_TOKEN
|
|
7403
7507
|
);
|
|
7404
7508
|
report["modules"] = moduleRegistry.getAll().map((m) => ({
|
|
@@ -7416,7 +7520,7 @@ var CliDebugCommandProcessor = class {
|
|
|
7416
7520
|
report["services"] = container.getRegisteredTokens();
|
|
7417
7521
|
}
|
|
7418
7522
|
try {
|
|
7419
|
-
const serverManager = context2.services.
|
|
7523
|
+
const serverManager = context2.services.getRequired(
|
|
7420
7524
|
CliServerManager_TOKEN
|
|
7421
7525
|
);
|
|
7422
7526
|
if (serverManager && serverManager.connections.size > 0) {
|
|
@@ -7440,13 +7544,9 @@ var CliDebugCommandProcessor = class {
|
|
|
7440
7544
|
metadata: { icon: CliIcon.Server, module: "system" },
|
|
7441
7545
|
processCommand: async (_, context2) => {
|
|
7442
7546
|
const { writer } = context2;
|
|
7443
|
-
|
|
7444
|
-
|
|
7445
|
-
|
|
7446
|
-
CliServerManager_TOKEN
|
|
7447
|
-
);
|
|
7448
|
-
} catch {
|
|
7449
|
-
}
|
|
7547
|
+
const manager = context2.services.get(
|
|
7548
|
+
CliServerManager_TOKEN
|
|
7549
|
+
);
|
|
7450
7550
|
if (!manager || manager.connections.size === 0) {
|
|
7451
7551
|
writer.writeInfo("No servers configured.");
|
|
7452
7552
|
return;
|
|
@@ -7486,70 +7586,48 @@ var CliDebugCommandProcessor = class {
|
|
|
7486
7586
|
}
|
|
7487
7587
|
async processCommand(_, context2) {
|
|
7488
7588
|
const { writer } = context2;
|
|
7489
|
-
const registry = context2.services.
|
|
7589
|
+
const registry = context2.services.getRequired(
|
|
7490
7590
|
CliProcessorsRegistry_TOKEN
|
|
7491
7591
|
);
|
|
7492
|
-
|
|
7493
|
-
|
|
7494
|
-
|
|
7495
|
-
CliForegroundColor.Yellow
|
|
7496
|
-
)
|
|
7497
|
-
);
|
|
7498
|
-
writer.writeDivider({ char: "=" });
|
|
7499
|
-
writer.writeln(
|
|
7500
|
-
` ${writer.wrapInColor("Core Version:", CliForegroundColor.Cyan)} ${LIBRARY_VERSION$1}`
|
|
7501
|
-
);
|
|
7502
|
-
writer.writeln(
|
|
7503
|
-
` ${writer.wrapInColor("CLI Version:", CliForegroundColor.Cyan)} ${LIBRARY_VERSION}`
|
|
7592
|
+
const summaryFramework = context2.services.get("cli-framework") ?? "vanilla";
|
|
7593
|
+
const summaryModuleRegistry = context2.services.get(
|
|
7594
|
+
CliModuleRegistry_TOKEN
|
|
7504
7595
|
);
|
|
7505
|
-
|
|
7506
|
-
|
|
7507
|
-
framework = context2.services.get("cli-framework");
|
|
7508
|
-
} catch {
|
|
7509
|
-
}
|
|
7510
|
-
writer.writeln(
|
|
7511
|
-
` ${writer.wrapInColor("Framework:", CliForegroundColor.Cyan)} ${framework}`
|
|
7512
|
-
);
|
|
7513
|
-
writer.writeln(
|
|
7514
|
-
` ${writer.wrapInColor("Terminal:", CliForegroundColor.Cyan)} ${context2.terminal.cols}x${context2.terminal.rows}`
|
|
7596
|
+
const summaryServerManager = context2.services.get(
|
|
7597
|
+
CliServerManager_TOKEN
|
|
7515
7598
|
);
|
|
7516
|
-
|
|
7517
|
-
|
|
7599
|
+
const history = context2.services.getRequired(
|
|
7600
|
+
CliCommandHistory_TOKEN
|
|
7518
7601
|
);
|
|
7519
|
-
|
|
7520
|
-
|
|
7521
|
-
|
|
7522
|
-
)
|
|
7523
|
-
writer.
|
|
7524
|
-
|
|
7602
|
+
const wasmStatus = isWasmAccelerated() ? "active" : "inactive (JS fallback)";
|
|
7603
|
+
const lines = [
|
|
7604
|
+
`${writer.wrapInColor("Core Version:", CliForegroundColor.Cyan)} ${LIBRARY_VERSION$1}`,
|
|
7605
|
+
`${writer.wrapInColor("CLI Version:", CliForegroundColor.Cyan)} ${LIBRARY_VERSION}`,
|
|
7606
|
+
`${writer.wrapInColor("Framework:", CliForegroundColor.Cyan)} ${summaryFramework}`,
|
|
7607
|
+
`${writer.wrapInColor("Terminal:", CliForegroundColor.Cyan)} ${context2.terminal.cols}x${context2.terminal.rows}`,
|
|
7608
|
+
`${writer.wrapInColor("Processors:", CliForegroundColor.Cyan)} ${registry.processors.length}`
|
|
7609
|
+
];
|
|
7610
|
+
if (summaryModuleRegistry) {
|
|
7611
|
+
lines.push(
|
|
7612
|
+
`${writer.wrapInColor("Modules:", CliForegroundColor.Cyan)} ${summaryModuleRegistry.getAll().length}`
|
|
7525
7613
|
);
|
|
7526
|
-
} catch {
|
|
7527
7614
|
}
|
|
7528
|
-
|
|
7529
|
-
const
|
|
7530
|
-
|
|
7615
|
+
if (summaryServerManager && summaryServerManager.connections.size > 0) {
|
|
7616
|
+
const connected = Array.from(
|
|
7617
|
+
summaryServerManager.connections.values()
|
|
7618
|
+
).filter((c) => c.connected).length;
|
|
7619
|
+
lines.push(
|
|
7620
|
+
`${writer.wrapInColor("Servers:", CliForegroundColor.Cyan)} ${connected}/${summaryServerManager.connections.size} connected`
|
|
7531
7621
|
);
|
|
7532
|
-
if (serverManager && serverManager.connections.size > 0) {
|
|
7533
|
-
const connected = Array.from(
|
|
7534
|
-
serverManager.connections.values()
|
|
7535
|
-
).filter((c) => c.connected).length;
|
|
7536
|
-
writer.writeln(
|
|
7537
|
-
` ${writer.wrapInColor("Servers:", CliForegroundColor.Cyan)} ${connected}/${serverManager.connections.size} connected`
|
|
7538
|
-
);
|
|
7539
|
-
}
|
|
7540
|
-
} catch {
|
|
7541
7622
|
}
|
|
7542
|
-
|
|
7543
|
-
|
|
7623
|
+
lines.push(
|
|
7624
|
+
`${writer.wrapInColor("History:", CliForegroundColor.Cyan)} ${history.getHistory().length} commands`,
|
|
7625
|
+
`${writer.wrapInColor("WASM Accelerator:", CliForegroundColor.Cyan)} ${wasmStatus}`
|
|
7544
7626
|
);
|
|
7545
|
-
writer.
|
|
7546
|
-
|
|
7547
|
-
|
|
7548
|
-
|
|
7549
|
-
writer.writeln(
|
|
7550
|
-
` ${writer.wrapInColor("WASM Accelerator:", CliForegroundColor.Cyan)} ${wasmStatus}`
|
|
7551
|
-
);
|
|
7552
|
-
writer.writeDivider({ char: "=" });
|
|
7627
|
+
writer.writeBox(lines, {
|
|
7628
|
+
title: "CLI Debug Info",
|
|
7629
|
+
borderColor: CliForegroundColor.Yellow
|
|
7630
|
+
});
|
|
7553
7631
|
writer.writeln();
|
|
7554
7632
|
writer.writeln(`${CliIcon.Light} Subcommands:`);
|
|
7555
7633
|
for (const sub of this.processors || []) {
|
|
@@ -8135,7 +8213,7 @@ var CliNanoCommandProcessor = class {
|
|
|
8135
8213
|
this.replaceWith = "";
|
|
8136
8214
|
this.statusMessage = void 0;
|
|
8137
8215
|
try {
|
|
8138
|
-
this.fs = context2.services.
|
|
8216
|
+
this.fs = context2.services.getRequired(FS_TOKEN);
|
|
8139
8217
|
} catch {
|
|
8140
8218
|
this.fs = null;
|
|
8141
8219
|
}
|
|
@@ -8474,8 +8552,8 @@ var CliNanoCommandProcessor = class {
|
|
|
8474
8552
|
return;
|
|
8475
8553
|
}
|
|
8476
8554
|
try {
|
|
8477
|
-
const registry = this.context.services.
|
|
8478
|
-
|
|
8555
|
+
const registry = this.context.services.getRequired(
|
|
8556
|
+
SyntaxHighlighterRegistry_TOKEN
|
|
8479
8557
|
);
|
|
8480
8558
|
const ext = "." + filePath.split(".").pop()?.toLowerCase();
|
|
8481
8559
|
const highlighter = registry.getByExtension(ext);
|
|
@@ -8740,7 +8818,9 @@ var CliServicesCommandProcessor = class {
|
|
|
8740
8818
|
this.metadata = {
|
|
8741
8819
|
sealed: true,
|
|
8742
8820
|
icon: "\u2699",
|
|
8743
|
-
module: "system"
|
|
8821
|
+
module: "system",
|
|
8822
|
+
// Enforced only when an auth module is loaded
|
|
8823
|
+
requiredPermissions: ["system:services"]
|
|
8744
8824
|
};
|
|
8745
8825
|
this.processors = [
|
|
8746
8826
|
// ── list ──────────────────────────────────────────────
|
|
@@ -9112,7 +9192,7 @@ var CliPsCommandProcessor = class {
|
|
|
9112
9192
|
async processCommand(_command, context2) {
|
|
9113
9193
|
let registry;
|
|
9114
9194
|
try {
|
|
9115
|
-
registry = context2.services.
|
|
9195
|
+
registry = context2.services.getRequired(
|
|
9116
9196
|
CliProcessRegistry_TOKEN
|
|
9117
9197
|
);
|
|
9118
9198
|
} catch {
|
|
@@ -9151,7 +9231,7 @@ var CliKillCommandProcessor = class {
|
|
|
9151
9231
|
async processCommand(command2, context2) {
|
|
9152
9232
|
let registry;
|
|
9153
9233
|
try {
|
|
9154
|
-
registry = context2.services.
|
|
9234
|
+
registry = context2.services.getRequired(
|
|
9155
9235
|
CliProcessRegistry_TOKEN
|
|
9156
9236
|
);
|
|
9157
9237
|
} catch {
|
|
@@ -9266,11 +9346,10 @@ var CliHtopCommandProcessor = class {
|
|
|
9266
9346
|
this.errorTimeout = null;
|
|
9267
9347
|
}
|
|
9268
9348
|
async processCommand(_command, context2) {
|
|
9269
|
-
|
|
9270
|
-
|
|
9271
|
-
|
|
9272
|
-
|
|
9273
|
-
} catch {
|
|
9349
|
+
this.registry = context2.services.get(
|
|
9350
|
+
CliProcessRegistry_TOKEN
|
|
9351
|
+
) ?? null;
|
|
9352
|
+
if (!this.registry) {
|
|
9274
9353
|
context2.writer.writeError("Process registry not available");
|
|
9275
9354
|
return;
|
|
9276
9355
|
}
|
|
@@ -10410,7 +10489,7 @@ var CliPingCommandProcessor = class {
|
|
|
10410
10489
|
context2.writer.writeln(
|
|
10411
10490
|
`PING ${host} (${url}):`
|
|
10412
10491
|
);
|
|
10413
|
-
context2.
|
|
10492
|
+
context2.notifier.info(`ping ${host}`);
|
|
10414
10493
|
const times = [];
|
|
10415
10494
|
let transmitted = 0;
|
|
10416
10495
|
let received = 0;
|
|
@@ -10425,18 +10504,17 @@ var CliPingCommandProcessor = class {
|
|
|
10425
10504
|
transmitted++;
|
|
10426
10505
|
const start = performance.now();
|
|
10427
10506
|
try {
|
|
10428
|
-
const response = await fetch(url, {
|
|
10507
|
+
const response = await context2.http.fetch(url, {
|
|
10429
10508
|
method: "HEAD",
|
|
10430
10509
|
mode: "no-cors",
|
|
10431
|
-
cache: "no-store"
|
|
10432
|
-
signal: context2.signal
|
|
10510
|
+
cache: "no-store"
|
|
10433
10511
|
});
|
|
10434
10512
|
const elapsed = performance.now() - start;
|
|
10435
10513
|
const ms = elapsed.toFixed(1);
|
|
10436
10514
|
received++;
|
|
10437
10515
|
times.push(elapsed);
|
|
10438
10516
|
const status = response.type === "opaque" ? "ok" : `status=${response.status}`;
|
|
10439
|
-
context2.
|
|
10517
|
+
context2.notifier.info(`ping ${host}: seq=${seq} time=${ms}ms`);
|
|
10440
10518
|
context2.writer.writeln(
|
|
10441
10519
|
`${url}: seq=${seq} ${status} time=${ms} ms`
|
|
10442
10520
|
);
|
|
@@ -10570,7 +10648,7 @@ var CliExportCommandProcessor = class {
|
|
|
10570
10648
|
this.metadata = { icon: "\u{1F4E6}", module: "system" };
|
|
10571
10649
|
}
|
|
10572
10650
|
async processCommand(command2, context2) {
|
|
10573
|
-
const env = context2.services.
|
|
10651
|
+
const env = context2.services.getRequired(
|
|
10574
10652
|
ICliEnvironment_TOKEN
|
|
10575
10653
|
);
|
|
10576
10654
|
const raw = (command2.value || "").trim();
|
|
@@ -10624,7 +10702,7 @@ var CliUnsetCommandProcessor = class {
|
|
|
10624
10702
|
this.metadata = { icon: "\u{1F5D1}\uFE0F", module: "system" };
|
|
10625
10703
|
}
|
|
10626
10704
|
async processCommand(command2, context2) {
|
|
10627
|
-
const env = context2.services.
|
|
10705
|
+
const env = context2.services.getRequired(
|
|
10628
10706
|
ICliEnvironment_TOKEN
|
|
10629
10707
|
);
|
|
10630
10708
|
const varName = (command2.value || "").trim();
|
|
@@ -10658,7 +10736,7 @@ var CliEnvCommandProcessor = class {
|
|
|
10658
10736
|
this.metadata = { icon: "\u{1F30D}", module: "system" };
|
|
10659
10737
|
}
|
|
10660
10738
|
async processCommand(command2, context2) {
|
|
10661
|
-
const env = context2.services.
|
|
10739
|
+
const env = context2.services.getRequired(
|
|
10662
10740
|
ICliEnvironment_TOKEN
|
|
10663
10741
|
);
|
|
10664
10742
|
const varName = (command2.value || "").trim();
|
|
@@ -10906,16 +10984,9 @@ var CliCommandExecutionContext = class {
|
|
|
10906
10984
|
this.createInterval = (cb, ms) => context2.createInterval(cb, ms);
|
|
10907
10985
|
this.createTimeout = (cb, ms) => context2.createTimeout(cb, ms);
|
|
10908
10986
|
this.backgroundServices = context2.backgroundServices;
|
|
10909
|
-
this.
|
|
10910
|
-
|
|
10911
|
-
|
|
10912
|
-
this.context.setStatusText(text);
|
|
10913
|
-
}
|
|
10914
|
-
clearStatusText() {
|
|
10915
|
-
this.context.clearStatusText();
|
|
10916
|
-
}
|
|
10917
|
-
getStatusText() {
|
|
10918
|
-
return this.context.getStatusText();
|
|
10987
|
+
this.http = context2.http;
|
|
10988
|
+
this.notifier = context2.notifier;
|
|
10989
|
+
this.state = context2.services.getRequired(CliStateStoreManager_TOKEN).getProcessorStateStore(processor);
|
|
10919
10990
|
}
|
|
10920
10991
|
get promptLength() {
|
|
10921
10992
|
return this.context.promptLength;
|
|
@@ -11465,6 +11536,175 @@ var CliBackgroundServiceRegistry = class {
|
|
|
11465
11536
|
}
|
|
11466
11537
|
}
|
|
11467
11538
|
};
|
|
11539
|
+
var CliHttpClient = class {
|
|
11540
|
+
constructor(signal) {
|
|
11541
|
+
this.signal = signal;
|
|
11542
|
+
}
|
|
11543
|
+
async fetch(url, init) {
|
|
11544
|
+
return fetch(url, {
|
|
11545
|
+
...init,
|
|
11546
|
+
signal: this.mergeSignal(init?.signal)
|
|
11547
|
+
});
|
|
11548
|
+
}
|
|
11549
|
+
async get(url, options) {
|
|
11550
|
+
return this.jsonRequest("GET", url, void 0, options);
|
|
11551
|
+
}
|
|
11552
|
+
async post(url, body, options) {
|
|
11553
|
+
return this.jsonRequest("POST", url, body, options);
|
|
11554
|
+
}
|
|
11555
|
+
async put(url, body, options) {
|
|
11556
|
+
return this.jsonRequest("PUT", url, body, options);
|
|
11557
|
+
}
|
|
11558
|
+
async patch(url, body, options) {
|
|
11559
|
+
return this.jsonRequest("PATCH", url, body, options);
|
|
11560
|
+
}
|
|
11561
|
+
async delete(url, options) {
|
|
11562
|
+
return this.jsonRequest("DELETE", url, void 0, options);
|
|
11563
|
+
}
|
|
11564
|
+
async head(url, options) {
|
|
11565
|
+
const { timeout, signal: callerSignal, ...fetchOptions } = options ?? {};
|
|
11566
|
+
let timeoutController;
|
|
11567
|
+
let timeoutId;
|
|
11568
|
+
if (timeout) {
|
|
11569
|
+
timeoutController = new AbortController();
|
|
11570
|
+
timeoutId = setTimeout(() => timeoutController.abort(), timeout);
|
|
11571
|
+
}
|
|
11572
|
+
try {
|
|
11573
|
+
return await fetch(url, {
|
|
11574
|
+
...fetchOptions,
|
|
11575
|
+
method: "HEAD",
|
|
11576
|
+
signal: this.mergeSignal(callerSignal, timeoutController?.signal)
|
|
11577
|
+
});
|
|
11578
|
+
} finally {
|
|
11579
|
+
if (timeoutId !== void 0) clearTimeout(timeoutId);
|
|
11580
|
+
}
|
|
11581
|
+
}
|
|
11582
|
+
async options(url, options) {
|
|
11583
|
+
return this.jsonRequest("OPTIONS", url, void 0, options);
|
|
11584
|
+
}
|
|
11585
|
+
// ── Internals ────────────────────────────────────────────────────
|
|
11586
|
+
async jsonRequest(method, url, body, options) {
|
|
11587
|
+
const { timeout, ...fetchOptions } = options ?? {};
|
|
11588
|
+
const headers = new Headers(fetchOptions.headers);
|
|
11589
|
+
let resolvedBody;
|
|
11590
|
+
if (body !== void 0 && body !== null) {
|
|
11591
|
+
if (this.isRawBody(body)) {
|
|
11592
|
+
resolvedBody = body;
|
|
11593
|
+
} else {
|
|
11594
|
+
resolvedBody = JSON.stringify(body);
|
|
11595
|
+
if (!headers.has("Content-Type")) {
|
|
11596
|
+
headers.set("Content-Type", "application/json");
|
|
11597
|
+
}
|
|
11598
|
+
}
|
|
11599
|
+
}
|
|
11600
|
+
let timeoutId;
|
|
11601
|
+
let timeoutController;
|
|
11602
|
+
if (timeout) {
|
|
11603
|
+
timeoutController = new AbortController();
|
|
11604
|
+
timeoutId = setTimeout(() => timeoutController.abort(), timeout);
|
|
11605
|
+
}
|
|
11606
|
+
const signal = this.mergeSignal(
|
|
11607
|
+
fetchOptions.signal,
|
|
11608
|
+
timeoutController?.signal
|
|
11609
|
+
);
|
|
11610
|
+
try {
|
|
11611
|
+
const response = await fetch(url, {
|
|
11612
|
+
...fetchOptions,
|
|
11613
|
+
method,
|
|
11614
|
+
headers,
|
|
11615
|
+
body: resolvedBody,
|
|
11616
|
+
signal
|
|
11617
|
+
});
|
|
11618
|
+
if (!response.ok) {
|
|
11619
|
+
let errorMessage = `${response.status} ${response.statusText}`;
|
|
11620
|
+
let errorBody;
|
|
11621
|
+
try {
|
|
11622
|
+
errorBody = await response.json();
|
|
11623
|
+
const parsed = errorBody;
|
|
11624
|
+
if (parsed.error) {
|
|
11625
|
+
errorMessage = parsed.error;
|
|
11626
|
+
} else if (parsed.message) {
|
|
11627
|
+
errorMessage = parsed.message;
|
|
11628
|
+
}
|
|
11629
|
+
} catch {
|
|
11630
|
+
}
|
|
11631
|
+
throw new CliHttpError(
|
|
11632
|
+
errorMessage,
|
|
11633
|
+
response.status,
|
|
11634
|
+
response.statusText,
|
|
11635
|
+
errorBody
|
|
11636
|
+
);
|
|
11637
|
+
}
|
|
11638
|
+
const text = await response.text();
|
|
11639
|
+
if (!text) {
|
|
11640
|
+
return void 0;
|
|
11641
|
+
}
|
|
11642
|
+
return JSON.parse(text);
|
|
11643
|
+
} finally {
|
|
11644
|
+
if (timeoutId !== void 0) {
|
|
11645
|
+
clearTimeout(timeoutId);
|
|
11646
|
+
}
|
|
11647
|
+
}
|
|
11648
|
+
}
|
|
11649
|
+
isRawBody(body) {
|
|
11650
|
+
return typeof body === "string" || body instanceof FormData || body instanceof Blob || body instanceof ArrayBuffer || body instanceof URLSearchParams || body instanceof ReadableStream;
|
|
11651
|
+
}
|
|
11652
|
+
/**
|
|
11653
|
+
* Merge the command signal with any additional signals (caller, timeout).
|
|
11654
|
+
* Uses AbortSignal.any() when available, falls back to a manual composite
|
|
11655
|
+
* controller for older browsers (pre-Chrome 116 / Safari 17.4).
|
|
11656
|
+
*/
|
|
11657
|
+
mergeSignal(...additional) {
|
|
11658
|
+
const signals = [];
|
|
11659
|
+
if (this.signal) signals.push(this.signal);
|
|
11660
|
+
for (const s of additional) {
|
|
11661
|
+
if (s) signals.push(s);
|
|
11662
|
+
}
|
|
11663
|
+
if (signals.length === 0) return void 0;
|
|
11664
|
+
if (signals.length === 1) return signals[0];
|
|
11665
|
+
if (typeof AbortSignal.any === "function") {
|
|
11666
|
+
return AbortSignal.any(signals);
|
|
11667
|
+
}
|
|
11668
|
+
const controller = new AbortController();
|
|
11669
|
+
for (const s of signals) {
|
|
11670
|
+
if (s.aborted) {
|
|
11671
|
+
controller.abort(s.reason);
|
|
11672
|
+
return controller.signal;
|
|
11673
|
+
}
|
|
11674
|
+
s.addEventListener("abort", () => controller.abort(s.reason), { once: true });
|
|
11675
|
+
}
|
|
11676
|
+
return controller.signal;
|
|
11677
|
+
}
|
|
11678
|
+
};
|
|
11679
|
+
var CliNotifier = class {
|
|
11680
|
+
constructor() {
|
|
11681
|
+
this._change$ = new Subject();
|
|
11682
|
+
this.change$ = this._change$.asObservable();
|
|
11683
|
+
}
|
|
11684
|
+
get current() {
|
|
11685
|
+
return this._current;
|
|
11686
|
+
}
|
|
11687
|
+
info(message) {
|
|
11688
|
+
this.set("info", message);
|
|
11689
|
+
}
|
|
11690
|
+
success(message) {
|
|
11691
|
+
this.set("success", message);
|
|
11692
|
+
}
|
|
11693
|
+
warn(message) {
|
|
11694
|
+
this.set("warn", message);
|
|
11695
|
+
}
|
|
11696
|
+
error(message) {
|
|
11697
|
+
this.set("error", message);
|
|
11698
|
+
}
|
|
11699
|
+
clear() {
|
|
11700
|
+
this._current = void 0;
|
|
11701
|
+
this._change$.next(void 0);
|
|
11702
|
+
}
|
|
11703
|
+
set(level, message) {
|
|
11704
|
+
this._current = { level, message, timestamp: Date.now() };
|
|
11705
|
+
this._change$.next(this._current);
|
|
11706
|
+
}
|
|
11707
|
+
};
|
|
11468
11708
|
|
|
11469
11709
|
// src/lib/context/cli-fullscreen-manager.ts
|
|
11470
11710
|
var CliFullScreenManager = class {
|
|
@@ -14426,7 +14666,7 @@ var CliTerminalLineRenderer = class {
|
|
|
14426
14666
|
*/
|
|
14427
14667
|
getPromptString(options) {
|
|
14428
14668
|
const name = options.userName ?? "";
|
|
14429
|
-
let promptStart = options.hideUserName
|
|
14669
|
+
let promptStart = options.hideUserName ? "" : name ? `\x1B[32m${name}\x1B[0m:` : options.anonymousName ? `\x1B[90m${options.anonymousName}\x1B[0m:` : "";
|
|
14430
14670
|
if (options.contextProcessor) {
|
|
14431
14671
|
promptStart = `${options.contextProcessor}`;
|
|
14432
14672
|
}
|
|
@@ -14488,7 +14728,6 @@ var CliExecutionContext = class {
|
|
|
14488
14728
|
* Set by the command executor at start/end of executeCommand().
|
|
14489
14729
|
*/
|
|
14490
14730
|
this.isExecuting = false;
|
|
14491
|
-
this.statusTextChange$ = new Subject();
|
|
14492
14731
|
this.lineBuffer = new CliLineBuffer();
|
|
14493
14732
|
this.modeStack = [];
|
|
14494
14733
|
this.timerManager = new CliTimerManager();
|
|
@@ -14533,6 +14772,8 @@ var CliExecutionContext = class {
|
|
|
14533
14772
|
this.logger.setCliLogLevel(cliOptions?.logLevel || CliLogLevel.ERROR);
|
|
14534
14773
|
this.commandHistory = deps.commandHistory;
|
|
14535
14774
|
this.lineRenderer = new CliTerminalLineRenderer(terminal, this.writer);
|
|
14775
|
+
this.http = new CliHttpClient();
|
|
14776
|
+
this.notifier = new CliNotifier();
|
|
14536
14777
|
this.backgroundServices = new CliBackgroundServiceRegistry(
|
|
14537
14778
|
this.state,
|
|
14538
14779
|
deps.services,
|
|
@@ -14543,17 +14784,6 @@ var CliExecutionContext = class {
|
|
|
14543
14784
|
this.backgroundServices
|
|
14544
14785
|
);
|
|
14545
14786
|
}
|
|
14546
|
-
setStatusText(text) {
|
|
14547
|
-
this._statusText = text;
|
|
14548
|
-
this.statusTextChange$.next(text);
|
|
14549
|
-
}
|
|
14550
|
-
clearStatusText() {
|
|
14551
|
-
this._statusText = void 0;
|
|
14552
|
-
this.statusTextChange$.next(void 0);
|
|
14553
|
-
}
|
|
14554
|
-
getStatusText() {
|
|
14555
|
-
return this._statusText;
|
|
14556
|
-
}
|
|
14557
14787
|
// -- Public API (ICliExecutionContext) --
|
|
14558
14788
|
writeToTerminal(text) {
|
|
14559
14789
|
this.terminal.write(text);
|
|
@@ -14747,15 +14977,13 @@ var CliExecutionContext = class {
|
|
|
14747
14977
|
}
|
|
14748
14978
|
// -- CommandLineModeHost interface --
|
|
14749
14979
|
getPromptOptions() {
|
|
14750
|
-
|
|
14751
|
-
|
|
14752
|
-
|
|
14753
|
-
hideUserName = config?.hideUserName ?? false;
|
|
14754
|
-
} catch {
|
|
14755
|
-
}
|
|
14980
|
+
const usersConfig = this.services.get("cli-users-module-config");
|
|
14981
|
+
const hideUserName = usersConfig?.hideUserName ?? false;
|
|
14982
|
+
const anonymousName = usersConfig && !this.userSession ? (usersConfig.anonymousName ?? "anonymous") || void 0 : void 0;
|
|
14756
14983
|
return {
|
|
14757
14984
|
userName: this.userSession?.displayName,
|
|
14758
14985
|
hideUserName,
|
|
14986
|
+
anonymousName,
|
|
14759
14987
|
contextProcessor: this.contextProcessor?.command,
|
|
14760
14988
|
pathProvider: this.promptPathProvider
|
|
14761
14989
|
};
|
|
@@ -15000,10 +15228,8 @@ var contextGlobalParameter = {
|
|
|
15000
15228
|
// src/lib/executor/cli-io-redirect-handler.ts
|
|
15001
15229
|
var FS_TOKEN2 = "cli-file-system-service";
|
|
15002
15230
|
async function writeOutputToFile(filePath, context2) {
|
|
15003
|
-
|
|
15004
|
-
|
|
15005
|
-
fs = context2.services.get(FS_TOKEN2);
|
|
15006
|
-
} catch {
|
|
15231
|
+
const fs = context2.services.get(FS_TOKEN2);
|
|
15232
|
+
if (!fs) {
|
|
15007
15233
|
context2.writer.writeError(
|
|
15008
15234
|
"> redirect requires @qodalis/cli-files plugin"
|
|
15009
15235
|
);
|
|
@@ -15027,10 +15253,8 @@ async function writeOutputToFile(filePath, context2) {
|
|
|
15027
15253
|
}
|
|
15028
15254
|
}
|
|
15029
15255
|
async function appendOutputToFile(filePath, context2) {
|
|
15030
|
-
|
|
15031
|
-
|
|
15032
|
-
fs = context2.services.get(FS_TOKEN2);
|
|
15033
|
-
} catch {
|
|
15256
|
+
const fs = context2.services.get(FS_TOKEN2);
|
|
15257
|
+
if (!fs) {
|
|
15034
15258
|
context2.writer.writeError(
|
|
15035
15259
|
">> redirect requires @qodalis/cli-files plugin"
|
|
15036
15260
|
);
|
|
@@ -15056,10 +15280,8 @@ async function appendOutputToFile(filePath, context2) {
|
|
|
15056
15280
|
async function writeStderrToFile(filePath, context2, capturingWriter) {
|
|
15057
15281
|
const stderr = capturingWriter?.getCapturedStderr();
|
|
15058
15282
|
if (!stderr) return;
|
|
15059
|
-
|
|
15060
|
-
|
|
15061
|
-
fs = context2.services.get(FS_TOKEN2);
|
|
15062
|
-
} catch {
|
|
15283
|
+
const fs = context2.services.get(FS_TOKEN2);
|
|
15284
|
+
if (!fs) {
|
|
15063
15285
|
context2.writer.writeError(
|
|
15064
15286
|
"2> redirect requires @qodalis/cli-files plugin"
|
|
15065
15287
|
);
|
|
@@ -15080,10 +15302,8 @@ async function writeStderrToFile(filePath, context2, capturingWriter) {
|
|
|
15080
15302
|
async function appendStderrToFile(filePath, context2, capturingWriter) {
|
|
15081
15303
|
const stderr = capturingWriter?.getCapturedStderr();
|
|
15082
15304
|
if (!stderr) return;
|
|
15083
|
-
|
|
15084
|
-
|
|
15085
|
-
fs = context2.services.get(FS_TOKEN2);
|
|
15086
|
-
} catch {
|
|
15305
|
+
const fs = context2.services.get(FS_TOKEN2);
|
|
15306
|
+
if (!fs) {
|
|
15087
15307
|
context2.writer.writeError(
|
|
15088
15308
|
"2>> redirect requires @qodalis/cli-files plugin"
|
|
15089
15309
|
);
|
|
@@ -15103,10 +15323,8 @@ async function appendStderrToFile(filePath, context2, capturingWriter) {
|
|
|
15103
15323
|
}
|
|
15104
15324
|
async function tryExecuteScript(filePath, context2, executeCommand) {
|
|
15105
15325
|
const FS_TOKEN3 = "cli-file-system-service";
|
|
15106
|
-
|
|
15107
|
-
|
|
15108
|
-
fs = context2.services.get(FS_TOKEN3);
|
|
15109
|
-
} catch {
|
|
15326
|
+
const fs = context2.services.get(FS_TOKEN3);
|
|
15327
|
+
if (!fs) {
|
|
15110
15328
|
return false;
|
|
15111
15329
|
}
|
|
15112
15330
|
const resolved = fs.resolvePath(filePath);
|
|
@@ -15183,10 +15401,8 @@ function substituteVars(input, variables) {
|
|
|
15183
15401
|
return result;
|
|
15184
15402
|
}
|
|
15185
15403
|
function expandEnvironmentVars(command2, context2) {
|
|
15186
|
-
|
|
15187
|
-
|
|
15188
|
-
env = context2.services.get(ICliEnvironment_TOKEN);
|
|
15189
|
-
} catch {
|
|
15404
|
+
const env = context2.services.get(ICliEnvironment_TOKEN);
|
|
15405
|
+
if (!env) {
|
|
15190
15406
|
return command2;
|
|
15191
15407
|
}
|
|
15192
15408
|
const parts = command2.split("'");
|
|
@@ -15331,7 +15547,7 @@ var CliCommandExecutor = class {
|
|
|
15331
15547
|
}
|
|
15332
15548
|
} finally {
|
|
15333
15549
|
rootContext.isExecuting = false;
|
|
15334
|
-
rootContext.
|
|
15550
|
+
rootContext.notifier?.clear();
|
|
15335
15551
|
}
|
|
15336
15552
|
}
|
|
15337
15553
|
async executeSingleCommand(command2, data, context2) {
|
|
@@ -15339,8 +15555,8 @@ var CliCommandExecutor = class {
|
|
|
15339
15555
|
command2 = expandEnvironmentVars(command2, context2);
|
|
15340
15556
|
const assignMatch = command2.match(/^([A-Za-z_][A-Za-z0-9_]*)=(.*)$/);
|
|
15341
15557
|
if (assignMatch) {
|
|
15342
|
-
|
|
15343
|
-
|
|
15558
|
+
const env = context2.services.get(ICliEnvironment_TOKEN);
|
|
15559
|
+
if (env) {
|
|
15344
15560
|
let val = assignMatch[2];
|
|
15345
15561
|
if (val.startsWith('"') && val.endsWith('"') || val.startsWith("'") && val.endsWith("'")) {
|
|
15346
15562
|
val = val.slice(1, -1);
|
|
@@ -15349,15 +15565,13 @@ var CliCommandExecutor = class {
|
|
|
15349
15565
|
process.start();
|
|
15350
15566
|
process.end();
|
|
15351
15567
|
return;
|
|
15352
|
-
} catch {
|
|
15353
15568
|
}
|
|
15354
15569
|
}
|
|
15355
15570
|
process.start();
|
|
15356
15571
|
let processEntry;
|
|
15357
|
-
|
|
15358
|
-
|
|
15572
|
+
const procRegistry = context2.services.get(CliProcessRegistry_TOKEN);
|
|
15573
|
+
if (procRegistry) {
|
|
15359
15574
|
processEntry = procRegistry.register(command2);
|
|
15360
|
-
} catch {
|
|
15361
15575
|
}
|
|
15362
15576
|
const parsed = this.commandParser.parse(command2);
|
|
15363
15577
|
let { commandName } = parsed;
|
|
@@ -15380,7 +15594,7 @@ var CliCommandExecutor = class {
|
|
|
15380
15594
|
}
|
|
15381
15595
|
if (!processor) {
|
|
15382
15596
|
const aliasProcessor = this.registry.findProcessor("alias", []);
|
|
15383
|
-
const aliases = aliasProcessor?.userAliases ?? {};
|
|
15597
|
+
const aliases = aliasProcessor?.aliasesFor?.(context2) ?? aliasProcessor?.userAliases ?? {};
|
|
15384
15598
|
if (aliases[mainCommand]) {
|
|
15385
15599
|
this.completeProcess(processEntry, context2, 0);
|
|
15386
15600
|
return await this.executeSingleCommand(
|
|
@@ -15437,13 +15651,21 @@ var CliCommandExecutor = class {
|
|
|
15437
15651
|
}
|
|
15438
15652
|
const value = processor.acceptsRawInput || processor.valueRequired ? getRightOfWord(commandName, processor.command) : void 0;
|
|
15439
15653
|
commandToProcess.value = value;
|
|
15654
|
+
const blockedBy = await this.runGuards(commandToProcess, processor, context2);
|
|
15655
|
+
if (blockedBy) {
|
|
15656
|
+
context2.writer.writeError(blockedBy);
|
|
15657
|
+
this.failProcess(processEntry, context2);
|
|
15658
|
+
context2.process.exit(-1, { silent: true });
|
|
15659
|
+
return;
|
|
15660
|
+
}
|
|
15440
15661
|
const hasPositionalInput = !!value || !!data;
|
|
15441
15662
|
const hasNamedArgs = Object.keys(args).length > 0;
|
|
15442
15663
|
if (processor.valueRequired && !hasPositionalInput && !hasNamedArgs) {
|
|
15443
15664
|
context2.writer.writeError(
|
|
15444
15665
|
`Value required: ${context2.writer.wrapInColor(`${commandName} <value>`, CliForegroundColor.Cyan)}`
|
|
15445
15666
|
);
|
|
15446
|
-
|
|
15667
|
+
this.failProcess(processEntry, context2);
|
|
15668
|
+
context2.process.exit(-1, { silent: true });
|
|
15447
15669
|
return;
|
|
15448
15670
|
}
|
|
15449
15671
|
if (!this.validateBeforeExecution(context2, processor, args, hasPositionalInput)) {
|
|
@@ -15459,7 +15681,8 @@ var CliCommandExecutor = class {
|
|
|
15459
15681
|
context2.writer.writeError(
|
|
15460
15682
|
validationResult?.message || "An error occurred while validating the command."
|
|
15461
15683
|
);
|
|
15462
|
-
|
|
15684
|
+
this.failProcess(processEntry, context2);
|
|
15685
|
+
context2.process.exit(-1, { silent: true });
|
|
15463
15686
|
return;
|
|
15464
15687
|
}
|
|
15465
15688
|
}
|
|
@@ -15470,6 +15693,7 @@ var CliCommandExecutor = class {
|
|
|
15470
15693
|
);
|
|
15471
15694
|
const commandAbortController = new AbortController();
|
|
15472
15695
|
commandContext.signal = commandAbortController.signal;
|
|
15696
|
+
commandContext.http = new CliHttpClient(commandAbortController.signal);
|
|
15473
15697
|
const abortSub = context2.onAbort.subscribe(() => {
|
|
15474
15698
|
commandAbortController.abort();
|
|
15475
15699
|
});
|
|
@@ -15522,6 +15746,10 @@ var CliCommandExecutor = class {
|
|
|
15522
15746
|
"Process exited successfully with code 0"
|
|
15523
15747
|
);
|
|
15524
15748
|
}
|
|
15749
|
+
} else if (isCliAccessDeniedError(e)) {
|
|
15750
|
+
this.failProcess(processEntry, context2);
|
|
15751
|
+
context2.writer.writeError(e.message);
|
|
15752
|
+
context2.process.exit(-1);
|
|
15525
15753
|
} else {
|
|
15526
15754
|
this.failProcess(processEntry, context2);
|
|
15527
15755
|
context2.writer.writeError(`Error executing command: ${e}`);
|
|
@@ -15534,19 +15762,13 @@ var CliCommandExecutor = class {
|
|
|
15534
15762
|
}
|
|
15535
15763
|
completeProcess(processEntry, context2, exitCode) {
|
|
15536
15764
|
if (!processEntry) return;
|
|
15537
|
-
|
|
15538
|
-
|
|
15539
|
-
procRegistry.complete(processEntry.pid, exitCode);
|
|
15540
|
-
} catch {
|
|
15541
|
-
}
|
|
15765
|
+
const procRegistry = context2.services.get(CliProcessRegistry_TOKEN);
|
|
15766
|
+
procRegistry?.complete(processEntry.pid, exitCode);
|
|
15542
15767
|
}
|
|
15543
15768
|
failProcess(processEntry, context2) {
|
|
15544
15769
|
if (!processEntry) return;
|
|
15545
|
-
|
|
15546
|
-
|
|
15547
|
-
procRegistry.fail(processEntry.pid);
|
|
15548
|
-
} catch {
|
|
15549
|
-
}
|
|
15770
|
+
const failRegistry = context2.services.get(CliProcessRegistry_TOKEN);
|
|
15771
|
+
failRegistry?.fail(processEntry.pid);
|
|
15550
15772
|
}
|
|
15551
15773
|
async showHelp(command2, context2) {
|
|
15552
15774
|
try {
|
|
@@ -15612,6 +15834,52 @@ var CliCommandExecutor = class {
|
|
|
15612
15834
|
* parameter. In that case the global handler must be skipped so the
|
|
15613
15835
|
* processor can handle the flag itself.
|
|
15614
15836
|
*/
|
|
15837
|
+
/**
|
|
15838
|
+
* Runs all registered {@link ICliCommandGuard}s that apply to this command,
|
|
15839
|
+
* in priority order. Returns the block message of the first guard that
|
|
15840
|
+
* denies the command, or `undefined` when every guard allows it.
|
|
15841
|
+
* A guard that throws is treated as a denial (fail closed).
|
|
15842
|
+
*/
|
|
15843
|
+
async runGuards(command2, processor, context2) {
|
|
15844
|
+
let guards;
|
|
15845
|
+
try {
|
|
15846
|
+
guards = context2.services.getAll(ICliCommandGuard_TOKEN);
|
|
15847
|
+
} catch {
|
|
15848
|
+
return void 0;
|
|
15849
|
+
}
|
|
15850
|
+
if (!guards.length) {
|
|
15851
|
+
return void 0;
|
|
15852
|
+
}
|
|
15853
|
+
const ordered = [...guards].sort(
|
|
15854
|
+
(a, b) => (a.priority ?? 0) - (b.priority ?? 0)
|
|
15855
|
+
);
|
|
15856
|
+
for (const guard of ordered) {
|
|
15857
|
+
let result;
|
|
15858
|
+
try {
|
|
15859
|
+
if (guard.appliesTo && !await guard.appliesTo(processor, command2, context2)) {
|
|
15860
|
+
continue;
|
|
15861
|
+
}
|
|
15862
|
+
result = await guard.canActivate(command2, processor, context2);
|
|
15863
|
+
} catch (e) {
|
|
15864
|
+
return `${processor.command}: blocked by guard '${guard.name}' (${e?.message ?? e})`;
|
|
15865
|
+
}
|
|
15866
|
+
const denial = this.guardDenial(result, processor.command);
|
|
15867
|
+
if (denial) {
|
|
15868
|
+
return denial;
|
|
15869
|
+
}
|
|
15870
|
+
}
|
|
15871
|
+
return void 0;
|
|
15872
|
+
}
|
|
15873
|
+
guardDenial(result, commandName) {
|
|
15874
|
+
const denied = `${commandName}: permission denied`;
|
|
15875
|
+
if (result === void 0 || result === true) return void 0;
|
|
15876
|
+
if (result === false) return denied;
|
|
15877
|
+
if (typeof result === "string") return result || denied;
|
|
15878
|
+
if (typeof result === "object" && result !== null) {
|
|
15879
|
+
return result.allowed ? void 0 : result.message || denied;
|
|
15880
|
+
}
|
|
15881
|
+
return void 0;
|
|
15882
|
+
}
|
|
15615
15883
|
processorOwnsParameter(processor, globalParam) {
|
|
15616
15884
|
const globalNames = /* @__PURE__ */ new Set([
|
|
15617
15885
|
globalParam.name,
|
|
@@ -15628,29 +15896,94 @@ var CliCommandExecutor = class {
|
|
|
15628
15896
|
// src/lib/services/cli-service-container.ts
|
|
15629
15897
|
var CliServiceContainer = class {
|
|
15630
15898
|
constructor() {
|
|
15631
|
-
/** Stores single-value providers (resolved
|
|
15899
|
+
/** Stores single-value providers (resolved singletons). */
|
|
15632
15900
|
this.services = /* @__PURE__ */ new Map();
|
|
15633
15901
|
/** Stores multi-provider arrays. */
|
|
15634
15902
|
this.multiServices = /* @__PURE__ */ new Map();
|
|
15903
|
+
/** Tokens that cannot be overwritten by subsequent `set()` calls. */
|
|
15904
|
+
this.sealedTokens = /* @__PURE__ */ new Set();
|
|
15905
|
+
/** Stores provider recipes for transient tokens (re-resolved on every get). */
|
|
15906
|
+
this.transientRecipes = /* @__PURE__ */ new Map();
|
|
15635
15907
|
}
|
|
15636
15908
|
/**
|
|
15637
15909
|
* Retrieve a service by its token.
|
|
15910
|
+
* Returns `undefined` when no provider is registered for the token.
|
|
15911
|
+
* For multi-provider tokens, returns the last registered value (use `getAll` for the full array).
|
|
15638
15912
|
*
|
|
15639
15913
|
* @param token The token used to register the service.
|
|
15640
|
-
* @returns The resolved service instance
|
|
15641
|
-
* @throws Error if the token has not been registered.
|
|
15914
|
+
* @returns The resolved service instance, or `undefined` if not registered.
|
|
15642
15915
|
*/
|
|
15643
15916
|
get(token) {
|
|
15917
|
+
if (this.transientRecipes.has(token)) {
|
|
15918
|
+
return this.resolveProvider(this.transientRecipes.get(token));
|
|
15919
|
+
}
|
|
15644
15920
|
if (this.multiServices.has(token)) {
|
|
15645
|
-
|
|
15921
|
+
const arr = this.multiServices.get(token);
|
|
15922
|
+
return arr[arr.length - 1];
|
|
15646
15923
|
}
|
|
15647
15924
|
if (this.services.has(token)) {
|
|
15648
15925
|
return this.services.get(token);
|
|
15649
15926
|
}
|
|
15650
|
-
|
|
15651
|
-
|
|
15652
|
-
|
|
15653
|
-
|
|
15927
|
+
return void 0;
|
|
15928
|
+
}
|
|
15929
|
+
/**
|
|
15930
|
+
* Retrieve all registered services for a multi-provider token.
|
|
15931
|
+
* Returns an empty array when no provider is registered for the token.
|
|
15932
|
+
*
|
|
15933
|
+
* @param token The token used to register the service.
|
|
15934
|
+
* @returns Array of all resolved service instances.
|
|
15935
|
+
*/
|
|
15936
|
+
getAll(token) {
|
|
15937
|
+
if (this.multiServices.has(token)) {
|
|
15938
|
+
return this.multiServices.get(token);
|
|
15939
|
+
}
|
|
15940
|
+
const single = this.get(token);
|
|
15941
|
+
return single !== void 0 ? [single] : [];
|
|
15942
|
+
}
|
|
15943
|
+
/**
|
|
15944
|
+
* Retrieve a service by its token, throwing if not registered.
|
|
15945
|
+
* Use this when the service is required and its absence is a programming error.
|
|
15946
|
+
* For multi-provider tokens, returns the last registered value (use `getAll` for the full array).
|
|
15947
|
+
*
|
|
15948
|
+
* @param token The token used to register the service.
|
|
15949
|
+
* @returns The resolved service instance.
|
|
15950
|
+
* @throws Error if the token has not been registered.
|
|
15951
|
+
*/
|
|
15952
|
+
getRequired(token) {
|
|
15953
|
+
const value = this.get(token);
|
|
15954
|
+
if (value === void 0 && !this.has(token)) {
|
|
15955
|
+
throw new Error(
|
|
15956
|
+
`CliServiceContainer: No provider found for token "${this.tokenToString(token)}".`
|
|
15957
|
+
);
|
|
15958
|
+
}
|
|
15959
|
+
return value;
|
|
15960
|
+
}
|
|
15961
|
+
/**
|
|
15962
|
+
* Check whether a service is registered for the given token.
|
|
15963
|
+
*/
|
|
15964
|
+
has(token) {
|
|
15965
|
+
return this.services.has(token) || this.multiServices.has(token) || this.transientRecipes.has(token);
|
|
15966
|
+
}
|
|
15967
|
+
/**
|
|
15968
|
+
* Mark a token as sealed so it cannot be overwritten by future `set()` calls.
|
|
15969
|
+
* Only available on the concrete container — not exposed on `ICliServiceProvider`.
|
|
15970
|
+
*/
|
|
15971
|
+
seal(token) {
|
|
15972
|
+
this.sealedTokens.add(token);
|
|
15973
|
+
}
|
|
15974
|
+
/**
|
|
15975
|
+
* Mark multiple tokens as sealed at once.
|
|
15976
|
+
*/
|
|
15977
|
+
sealAll(tokens) {
|
|
15978
|
+
for (const token of tokens) {
|
|
15979
|
+
this.sealedTokens.add(token);
|
|
15980
|
+
}
|
|
15981
|
+
}
|
|
15982
|
+
/**
|
|
15983
|
+
* Check whether a token is sealed.
|
|
15984
|
+
*/
|
|
15985
|
+
isSealed(token) {
|
|
15986
|
+
return this.sealedTokens.has(token);
|
|
15654
15987
|
}
|
|
15655
15988
|
/**
|
|
15656
15989
|
* Register one or more providers.
|
|
@@ -15672,13 +16005,13 @@ var CliServiceContainer = class {
|
|
|
15672
16005
|
getRegisteredTokens() {
|
|
15673
16006
|
const tokens = [];
|
|
15674
16007
|
for (const key of this.services.keys()) {
|
|
15675
|
-
tokens.push(
|
|
15676
|
-
|
|
15677
|
-
|
|
16008
|
+
tokens.push(this.tokenToString(key));
|
|
16009
|
+
}
|
|
16010
|
+
for (const key of this.transientRecipes.keys()) {
|
|
16011
|
+
tokens.push(`${this.tokenToString(key)} (transient)`);
|
|
15678
16012
|
}
|
|
15679
16013
|
for (const key of this.multiServices.keys()) {
|
|
15680
|
-
|
|
15681
|
-
tokens.push(`${name} (multi)`);
|
|
16014
|
+
tokens.push(`${this.tokenToString(key)} (multi)`);
|
|
15682
16015
|
}
|
|
15683
16016
|
return tokens;
|
|
15684
16017
|
}
|
|
@@ -15689,20 +16022,34 @@ var CliServiceContainer = class {
|
|
|
15689
16022
|
const details = [];
|
|
15690
16023
|
for (const [key, value] of this.services.entries()) {
|
|
15691
16024
|
details.push({
|
|
15692
|
-
token:
|
|
16025
|
+
token: this.tokenToString(key),
|
|
15693
16026
|
type: this.describeValue(value),
|
|
15694
16027
|
multi: false
|
|
15695
16028
|
});
|
|
15696
16029
|
}
|
|
16030
|
+
for (const [key, provider] of this.transientRecipes.entries()) {
|
|
16031
|
+
const className = provider["useClass"]?.name ?? provider["useFactory"]?.name ?? "transient";
|
|
16032
|
+
details.push({
|
|
16033
|
+
token: this.tokenToString(key),
|
|
16034
|
+
type: `transient(${className})`,
|
|
16035
|
+
multi: false
|
|
16036
|
+
});
|
|
16037
|
+
}
|
|
15697
16038
|
for (const [key, values] of this.multiServices.entries()) {
|
|
15698
16039
|
details.push({
|
|
15699
|
-
token:
|
|
16040
|
+
token: this.tokenToString(key),
|
|
15700
16041
|
type: `[${values.map((v) => this.describeValue(v)).join(", ")}]`,
|
|
15701
16042
|
multi: true
|
|
15702
16043
|
});
|
|
15703
16044
|
}
|
|
15704
16045
|
return details;
|
|
15705
16046
|
}
|
|
16047
|
+
/**
|
|
16048
|
+
* Convert a token to a human-readable string for diagnostics/errors.
|
|
16049
|
+
*/
|
|
16050
|
+
tokenToString(token) {
|
|
16051
|
+
return typeof token === "string" ? token : typeof token === "function" ? token.name : String(token);
|
|
16052
|
+
}
|
|
15706
16053
|
/**
|
|
15707
16054
|
* Describe a resolved value for diagnostic display.
|
|
15708
16055
|
*/
|
|
@@ -15722,27 +16069,45 @@ var CliServiceContainer = class {
|
|
|
15722
16069
|
* Register a single provider.
|
|
15723
16070
|
*/
|
|
15724
16071
|
registerProvider(provider) {
|
|
15725
|
-
|
|
15726
|
-
|
|
15727
|
-
|
|
15728
|
-
|
|
15729
|
-
|
|
16072
|
+
if (!provider.multi && this.sealedTokens.has(provider.provide)) {
|
|
16073
|
+
throw new Error(
|
|
16074
|
+
`CliServiceContainer: Cannot override sealed service "${this.tokenToString(provider.provide)}".`
|
|
16075
|
+
);
|
|
16076
|
+
}
|
|
16077
|
+
if (provider["transient"] && !provider.multi) {
|
|
16078
|
+
this.transientRecipes.set(provider.provide, provider);
|
|
16079
|
+
this.services.delete(provider.provide);
|
|
15730
16080
|
} else {
|
|
15731
|
-
this.
|
|
16081
|
+
const value = this.resolveProvider(provider);
|
|
16082
|
+
if (provider.multi) {
|
|
16083
|
+
const existing = this.multiServices.get(provider.provide) ?? [];
|
|
16084
|
+
existing.push(value);
|
|
16085
|
+
this.multiServices.set(provider.provide, existing);
|
|
16086
|
+
} else {
|
|
16087
|
+
this.services.set(provider.provide, value);
|
|
16088
|
+
this.transientRecipes.delete(provider.provide);
|
|
16089
|
+
}
|
|
16090
|
+
}
|
|
16091
|
+
if (provider.sealed) {
|
|
16092
|
+
this.sealedTokens.add(provider.provide);
|
|
15732
16093
|
}
|
|
15733
16094
|
}
|
|
15734
16095
|
/**
|
|
15735
16096
|
* Resolve a provider definition to a concrete value.
|
|
16097
|
+
*
|
|
16098
|
+
* Note: `deps` are resolved eagerly at registration time, so
|
|
16099
|
+
* dependency tokens must be registered before the provider that needs them.
|
|
15736
16100
|
*/
|
|
15737
16101
|
resolveProvider(provider) {
|
|
15738
16102
|
if ("useValue" in provider) {
|
|
15739
16103
|
return provider.useValue;
|
|
15740
16104
|
}
|
|
16105
|
+
const deps = (provider["deps"] ?? []).map((dep) => this.getRequired(dep));
|
|
15741
16106
|
if ("useFactory" in provider) {
|
|
15742
|
-
return provider.useFactory();
|
|
16107
|
+
return provider.useFactory(...deps);
|
|
15743
16108
|
}
|
|
15744
16109
|
if ("useClass" in provider) {
|
|
15745
|
-
return new provider.useClass();
|
|
16110
|
+
return new provider.useClass(...deps);
|
|
15746
16111
|
}
|
|
15747
16112
|
throw new Error(
|
|
15748
16113
|
"CliServiceContainer: Provider must specify useValue, useFactory, or useClass."
|
|
@@ -15883,10 +16248,10 @@ var welcomeModule = {
|
|
|
15883
16248
|
async onAfterBoot(context2) {
|
|
15884
16249
|
const config = this.config || {};
|
|
15885
16250
|
let showOption = config.show;
|
|
15886
|
-
|
|
15887
|
-
|
|
15888
|
-
|
|
15889
|
-
|
|
16251
|
+
const storeManager = context2.services.get(
|
|
16252
|
+
CliStateStoreManager_TOKEN
|
|
16253
|
+
);
|
|
16254
|
+
if (storeManager) {
|
|
15890
16255
|
const configureStore = storeManager.getStateStore(
|
|
15891
16256
|
CLI_CONFIGURE_STORE_NAME
|
|
15892
16257
|
);
|
|
@@ -15895,7 +16260,6 @@ var welcomeModule = {
|
|
|
15895
16260
|
if (state?.["system"]?.["welcomeMessage"]) {
|
|
15896
16261
|
showOption = state["system"]["welcomeMessage"];
|
|
15897
16262
|
}
|
|
15898
|
-
} catch {
|
|
15899
16263
|
}
|
|
15900
16264
|
if (showOption) {
|
|
15901
16265
|
if (!shouldDisplayWelcomeMessage(showOption)) {
|
|
@@ -15923,11 +16287,11 @@ var welcomeModule = {
|
|
|
15923
16287
|
recordWelcomeMessageDisplay();
|
|
15924
16288
|
context2.showPrompt();
|
|
15925
16289
|
let showGreeting = true;
|
|
15926
|
-
|
|
15927
|
-
|
|
15928
|
-
|
|
15929
|
-
|
|
15930
|
-
const configureStore =
|
|
16290
|
+
const greetingStoreManager = context2.services.get(
|
|
16291
|
+
CliStateStoreManager_TOKEN
|
|
16292
|
+
);
|
|
16293
|
+
if (greetingStoreManager) {
|
|
16294
|
+
const configureStore = greetingStoreManager.getStateStore(
|
|
15931
16295
|
CLI_CONFIGURE_STORE_NAME
|
|
15932
16296
|
);
|
|
15933
16297
|
await configureStore.initialize();
|
|
@@ -15935,7 +16299,6 @@ var welcomeModule = {
|
|
|
15935
16299
|
if (configState?.["system"]?.["greeting"] === false) {
|
|
15936
16300
|
showGreeting = false;
|
|
15937
16301
|
}
|
|
15938
|
-
} catch {
|
|
15939
16302
|
}
|
|
15940
16303
|
if (showGreeting) {
|
|
15941
16304
|
await context2.textAnimator?.showText(getGreetingBasedOnTime(), {
|
|
@@ -16039,6 +16402,18 @@ var CliBoot = class {
|
|
|
16039
16402
|
if (module.services && module.services.length > 0) {
|
|
16040
16403
|
this.services.set(module.services);
|
|
16041
16404
|
}
|
|
16405
|
+
if (module.guards && module.guards.length > 0) {
|
|
16406
|
+
this.services.set(
|
|
16407
|
+
module.guards.map((guard) => ({
|
|
16408
|
+
provide: ICliCommandGuard_TOKEN,
|
|
16409
|
+
useValue: guard,
|
|
16410
|
+
multi: true
|
|
16411
|
+
}))
|
|
16412
|
+
);
|
|
16413
|
+
}
|
|
16414
|
+
if (module.permissions && module.permissions.length > 0) {
|
|
16415
|
+
this.services.get(ICliPermissionRegistry_TOKEN)?.register(module.permissions, module.name);
|
|
16416
|
+
}
|
|
16042
16417
|
if (module.translations) {
|
|
16043
16418
|
for (const [locale, translations] of Object.entries(module.translations)) {
|
|
16044
16419
|
context2.translator.addTranslations(locale, translations);
|
|
@@ -16055,8 +16430,8 @@ var CliBoot = class {
|
|
|
16055
16430
|
}
|
|
16056
16431
|
}
|
|
16057
16432
|
if (module.onSetup) {
|
|
16058
|
-
const kvStore = context2.services.
|
|
16059
|
-
|
|
16433
|
+
const kvStore = context2.services.getRequired(
|
|
16434
|
+
CliKeyValueStore_TOKEN
|
|
16060
16435
|
);
|
|
16061
16436
|
const setupKey = `cli-module-setup:${module.name}`;
|
|
16062
16437
|
const setupState = await kvStore.get(setupKey);
|
|
@@ -16086,19 +16461,47 @@ var CliBoot = class {
|
|
|
16086
16461
|
this.registry.registerProcessor(processor);
|
|
16087
16462
|
}
|
|
16088
16463
|
await this.initializeProcessorsInternal(context2, filtered);
|
|
16464
|
+
this.adoptMergedSubProcessors(filtered);
|
|
16089
16465
|
}
|
|
16090
16466
|
this.bootedModules.add(module.name);
|
|
16091
16467
|
if (!this.moduleRegistry.has(module.name)) {
|
|
16092
16468
|
this.moduleRegistry.track(module);
|
|
16093
16469
|
}
|
|
16094
16470
|
}
|
|
16471
|
+
/**
|
|
16472
|
+
* Sub-processors of an `extendsProcessor` processor are merged into the
|
|
16473
|
+
* processor it extends, so they belong to that one: re-parent them so they
|
|
16474
|
+
* inherit its access rules (`requiredPermissions` etc.) and help/root
|
|
16475
|
+
* lookups resolve to the registered processor.
|
|
16476
|
+
*/
|
|
16477
|
+
adoptMergedSubProcessors(processors) {
|
|
16478
|
+
for (const processor of processors) {
|
|
16479
|
+
if (!processor.extendsProcessor) continue;
|
|
16480
|
+
const name = processor.command.toLowerCase();
|
|
16481
|
+
const host = this.registry.processors.find(
|
|
16482
|
+
(p) => p.command.toLowerCase() === name
|
|
16483
|
+
);
|
|
16484
|
+
if (!host || host === processor) continue;
|
|
16485
|
+
for (const sub of processor.processors ?? []) {
|
|
16486
|
+
if (host.processors?.includes(sub)) {
|
|
16487
|
+
sub.parent = host;
|
|
16488
|
+
}
|
|
16489
|
+
}
|
|
16490
|
+
}
|
|
16491
|
+
}
|
|
16095
16492
|
buildCoreModule() {
|
|
16096
16493
|
return {
|
|
16097
16494
|
apiVersion: API_VERSION,
|
|
16098
16495
|
name: "@qodalis/cli-core",
|
|
16099
16496
|
version: LIBRARY_VERSION$1,
|
|
16100
16497
|
description: "Core CLI services and utilities",
|
|
16101
|
-
processors: [...builtinProcessors]
|
|
16498
|
+
processors: [...builtinProcessors],
|
|
16499
|
+
permissions: [
|
|
16500
|
+
{ name: "system:packages", description: "Install, update and remove packages (pkg)" },
|
|
16501
|
+
{ name: "system:services", description: "Start and stop background services" },
|
|
16502
|
+
{ name: "system:eval", description: "Evaluate JavaScript (eval, also requires allowEval)" },
|
|
16503
|
+
{ name: "shell:execute", description: "Open a remote shell on a server (ssh)" }
|
|
16504
|
+
]
|
|
16102
16505
|
};
|
|
16103
16506
|
}
|
|
16104
16507
|
/**
|
|
@@ -16230,6 +16633,29 @@ var CliDragDropService = class {
|
|
|
16230
16633
|
}
|
|
16231
16634
|
};
|
|
16232
16635
|
|
|
16636
|
+
// src/lib/services/cli-permission-registry.ts
|
|
16637
|
+
var CliPermissionRegistry = class {
|
|
16638
|
+
constructor() {
|
|
16639
|
+
this.definitions = /* @__PURE__ */ new Map();
|
|
16640
|
+
}
|
|
16641
|
+
register(definitions, module) {
|
|
16642
|
+
for (const def of definitions ?? []) {
|
|
16643
|
+
const name = def?.name?.trim();
|
|
16644
|
+
if (!name) continue;
|
|
16645
|
+
const key = name.toLowerCase();
|
|
16646
|
+
if (!this.definitions.has(key)) {
|
|
16647
|
+
this.definitions.set(key, { ...def, name, module: def.module ?? module });
|
|
16648
|
+
}
|
|
16649
|
+
}
|
|
16650
|
+
}
|
|
16651
|
+
list() {
|
|
16652
|
+
return [...this.definitions.values()].sort((a, b) => a.name.localeCompare(b.name));
|
|
16653
|
+
}
|
|
16654
|
+
get(name) {
|
|
16655
|
+
return this.definitions.get(name.trim().toLowerCase());
|
|
16656
|
+
}
|
|
16657
|
+
};
|
|
16658
|
+
|
|
16233
16659
|
// src/lib/addons/overlay.ts
|
|
16234
16660
|
var OverlayAddon = class {
|
|
16235
16661
|
constructor() {
|
|
@@ -16436,16 +16862,19 @@ var CliStateStore = class {
|
|
|
16436
16862
|
this.state$.next(this.initialState);
|
|
16437
16863
|
}
|
|
16438
16864
|
async persist() {
|
|
16439
|
-
const keyValueStore = this.services.
|
|
16440
|
-
|
|
16865
|
+
const keyValueStore = this.services.getRequired(
|
|
16866
|
+
CliKeyValueStore_TOKEN
|
|
16441
16867
|
);
|
|
16442
16868
|
await keyValueStore.set(this.storageKey, this.getState());
|
|
16443
16869
|
}
|
|
16444
16870
|
async initialize() {
|
|
16871
|
+
const keyValueStore = this.services.get(
|
|
16872
|
+
CliKeyValueStore_TOKEN
|
|
16873
|
+
);
|
|
16874
|
+
if (!keyValueStore) {
|
|
16875
|
+
return;
|
|
16876
|
+
}
|
|
16445
16877
|
try {
|
|
16446
|
-
const keyValueStore = this.services.get(
|
|
16447
|
-
"cli-key-value-store"
|
|
16448
|
-
);
|
|
16449
16878
|
const state = await keyValueStore.get(this.storageKey);
|
|
16450
16879
|
if (state) {
|
|
16451
16880
|
this.state$.next(state);
|
|
@@ -16512,6 +16941,39 @@ var CliStateStoreManager = class {
|
|
|
16512
16941
|
this.stores.clear();
|
|
16513
16942
|
}
|
|
16514
16943
|
};
|
|
16944
|
+
var CliServerAuthService = class {
|
|
16945
|
+
constructor(services) {
|
|
16946
|
+
this.services = services;
|
|
16947
|
+
}
|
|
16948
|
+
getHeaders(serverName, configHeaders) {
|
|
16949
|
+
const merged = {
|
|
16950
|
+
...resolveHeaders(configHeaders)
|
|
16951
|
+
};
|
|
16952
|
+
const providers = this.services.getAll(
|
|
16953
|
+
ICliServerAuthTokenProvider_TOKEN
|
|
16954
|
+
);
|
|
16955
|
+
for (const provider of providers) {
|
|
16956
|
+
Object.assign(merged, provider.getHeaders(serverName));
|
|
16957
|
+
}
|
|
16958
|
+
return merged;
|
|
16959
|
+
}
|
|
16960
|
+
async getWebSocketParams(serverName) {
|
|
16961
|
+
const providers = this.services.getAll(
|
|
16962
|
+
ICliServerAuthTokenProvider_TOKEN
|
|
16963
|
+
);
|
|
16964
|
+
let handled = false;
|
|
16965
|
+
const merged = {};
|
|
16966
|
+
for (const provider of providers) {
|
|
16967
|
+
if (!provider.getWebSocketParams) continue;
|
|
16968
|
+
const params = await provider.getWebSocketParams(serverName);
|
|
16969
|
+
if (params) {
|
|
16970
|
+
handled = true;
|
|
16971
|
+
Object.assign(merged, params);
|
|
16972
|
+
}
|
|
16973
|
+
}
|
|
16974
|
+
return handled ? merged : void 0;
|
|
16975
|
+
}
|
|
16976
|
+
};
|
|
16515
16977
|
|
|
16516
16978
|
// src/lib/completion/cli-command-completion-provider.ts
|
|
16517
16979
|
var CliCommandCompletionProvider = class {
|
|
@@ -16659,12 +17121,10 @@ var CliPackageNameCompletionProvider = class {
|
|
|
16659
17121
|
if (!INSTALLED_PKG_SUBCOMMANDS.has(subCommand)) {
|
|
16660
17122
|
return [];
|
|
16661
17123
|
}
|
|
16662
|
-
|
|
16663
|
-
|
|
16664
|
-
|
|
16665
|
-
|
|
16666
|
-
);
|
|
16667
|
-
} catch {
|
|
17124
|
+
const manager = this.services.get(
|
|
17125
|
+
CliPackageManagerService_TOKEN
|
|
17126
|
+
);
|
|
17127
|
+
if (!manager) {
|
|
16668
17128
|
return [];
|
|
16669
17129
|
}
|
|
16670
17130
|
const packages = await manager.getPackages();
|
|
@@ -16867,7 +17327,7 @@ var ServerListProcessor = class {
|
|
|
16867
17327
|
this.description = "Show configured servers and their connection status";
|
|
16868
17328
|
}
|
|
16869
17329
|
async processCommand(_command, context2) {
|
|
16870
|
-
const manager = context2.services.
|
|
17330
|
+
const manager = context2.services.getRequired(
|
|
16871
17331
|
CliServerManager_TOKEN
|
|
16872
17332
|
);
|
|
16873
17333
|
if (!manager || manager.connections.size === 0) {
|
|
@@ -16906,7 +17366,7 @@ var ServerStatusProcessor = class {
|
|
|
16906
17366
|
context2.process.exit(1);
|
|
16907
17367
|
return;
|
|
16908
17368
|
}
|
|
16909
|
-
const manager = context2.services.
|
|
17369
|
+
const manager = context2.services.getRequired(
|
|
16910
17370
|
CliServerManager_TOKEN
|
|
16911
17371
|
);
|
|
16912
17372
|
const connection = manager?.getConnection(serverName);
|
|
@@ -16916,7 +17376,7 @@ var ServerStatusProcessor = class {
|
|
|
16916
17376
|
return;
|
|
16917
17377
|
}
|
|
16918
17378
|
context2.spinner?.show(`Pinging ${serverName}...`);
|
|
16919
|
-
context2.
|
|
17379
|
+
context2.notifier.info(`Pinging ${serverName}`);
|
|
16920
17380
|
const reachable = await connection.ping();
|
|
16921
17381
|
context2.spinner?.hide();
|
|
16922
17382
|
if (reachable) {
|
|
@@ -16947,7 +17407,7 @@ var ServerReconnectProcessor = class {
|
|
|
16947
17407
|
context2.process.exit(1);
|
|
16948
17408
|
return;
|
|
16949
17409
|
}
|
|
16950
|
-
const manager = context2.services.
|
|
17410
|
+
const manager = context2.services.getRequired(
|
|
16951
17411
|
CliServerManager_TOKEN
|
|
16952
17412
|
);
|
|
16953
17413
|
if (!manager) {
|
|
@@ -16956,7 +17416,7 @@ var ServerReconnectProcessor = class {
|
|
|
16956
17416
|
return;
|
|
16957
17417
|
}
|
|
16958
17418
|
context2.spinner?.show(`Reconnecting to ${serverName}...`);
|
|
16959
|
-
context2.
|
|
17419
|
+
context2.notifier.info(`Reconnecting to ${serverName}`);
|
|
16960
17420
|
const result = await manager.reconnect(serverName);
|
|
16961
17421
|
context2.spinner?.hide();
|
|
16962
17422
|
if (result.success) {
|
|
@@ -16986,7 +17446,7 @@ var ServerDefaultProcessor = class {
|
|
|
16986
17446
|
];
|
|
16987
17447
|
}
|
|
16988
17448
|
async processCommand(command2, context2) {
|
|
16989
|
-
const manager = context2.services.
|
|
17449
|
+
const manager = context2.services.getRequired(
|
|
16990
17450
|
CliServerManager_TOKEN
|
|
16991
17451
|
);
|
|
16992
17452
|
if (!manager) {
|
|
@@ -17022,8 +17482,6 @@ var ServerDefaultProcessor = class {
|
|
|
17022
17482
|
}
|
|
17023
17483
|
}
|
|
17024
17484
|
};
|
|
17025
|
-
|
|
17026
|
-
// src/lib/server/cli-ssh-command-processor.ts
|
|
17027
17485
|
var CliSshCommandProcessor = class {
|
|
17028
17486
|
constructor() {
|
|
17029
17487
|
this.command = "ssh";
|
|
@@ -17032,7 +17490,9 @@ var CliSshCommandProcessor = class {
|
|
|
17032
17490
|
this.valueRequired = false;
|
|
17033
17491
|
this.metadata = {
|
|
17034
17492
|
module: "@qodalis/cli-server",
|
|
17035
|
-
icon: "\u{1F5A5}"
|
|
17493
|
+
icon: "\u{1F5A5}",
|
|
17494
|
+
// Enforced only when an auth module is loaded; the server checks it too
|
|
17495
|
+
requiredPermissions: [CliServerPermissions.ShellExecute]
|
|
17036
17496
|
};
|
|
17037
17497
|
this.parameters = [
|
|
17038
17498
|
{
|
|
@@ -17042,12 +17502,9 @@ var CliSshCommandProcessor = class {
|
|
|
17042
17502
|
type: "string"
|
|
17043
17503
|
}
|
|
17044
17504
|
];
|
|
17045
|
-
this.socket = null;
|
|
17046
|
-
this.context = null;
|
|
17047
|
-
this.resolved = false;
|
|
17048
17505
|
}
|
|
17049
17506
|
async processCommand(command2, context2) {
|
|
17050
|
-
const manager = context2.services.
|
|
17507
|
+
const manager = context2.services.getRequired(
|
|
17051
17508
|
CliServerManager_TOKEN
|
|
17052
17509
|
);
|
|
17053
17510
|
if (!manager) {
|
|
@@ -17076,26 +17533,34 @@ var CliSshCommandProcessor = class {
|
|
|
17076
17533
|
await this.executeInteractive(connection, serverName, context2);
|
|
17077
17534
|
}
|
|
17078
17535
|
}
|
|
17079
|
-
|
|
17080
|
-
|
|
17081
|
-
|
|
17082
|
-
|
|
17083
|
-
|
|
17084
|
-
|
|
17085
|
-
|
|
17086
|
-
|
|
17087
|
-
|
|
17088
|
-
|
|
17089
|
-
}
|
|
17090
|
-
}
|
|
17091
|
-
onDispose(_context) {
|
|
17092
|
-
if (this.socket) {
|
|
17093
|
-
if (this.socket.readyState === WebSocket.OPEN || this.socket.readyState === WebSocket.CONNECTING) {
|
|
17094
|
-
this.socket.close();
|
|
17536
|
+
/**
|
|
17537
|
+
* Full-screen handler for one session: input, resize and disposal go to
|
|
17538
|
+
* that session's socket only.
|
|
17539
|
+
*/
|
|
17540
|
+
fullScreenHandler(session) {
|
|
17541
|
+
const handler = Object.create(this);
|
|
17542
|
+
handler.onData = async (data) => {
|
|
17543
|
+
if (session.socket?.readyState === WebSocket.OPEN) {
|
|
17544
|
+
const msg = { type: "stdin", data };
|
|
17545
|
+
session.socket.send(JSON.stringify(msg));
|
|
17095
17546
|
}
|
|
17096
|
-
|
|
17097
|
-
|
|
17098
|
-
|
|
17547
|
+
};
|
|
17548
|
+
handler.onResize = (cols, rows) => {
|
|
17549
|
+
if (session.socket?.readyState === WebSocket.OPEN) {
|
|
17550
|
+
const msg = { type: "resize", cols, rows };
|
|
17551
|
+
session.socket.send(JSON.stringify(msg));
|
|
17552
|
+
}
|
|
17553
|
+
};
|
|
17554
|
+
handler.onDispose = () => {
|
|
17555
|
+
session.disposed = true;
|
|
17556
|
+
if (session.socket) {
|
|
17557
|
+
if (session.socket.readyState === WebSocket.OPEN || session.socket.readyState === WebSocket.CONNECTING) {
|
|
17558
|
+
session.socket.close();
|
|
17559
|
+
}
|
|
17560
|
+
session.socket = null;
|
|
17561
|
+
}
|
|
17562
|
+
};
|
|
17563
|
+
return handler;
|
|
17099
17564
|
}
|
|
17100
17565
|
async resolveServer(command2, shellServers, context2) {
|
|
17101
17566
|
const empty = { serverName: null, oneShotCmd: null, connection: null };
|
|
@@ -17121,7 +17586,7 @@ var CliSshCommandProcessor = class {
|
|
|
17121
17586
|
const candidateName = parts[0];
|
|
17122
17587
|
const entry2 = shellServers.find((s) => s.name === candidateName);
|
|
17123
17588
|
if (entry2) {
|
|
17124
|
-
const oneShotCmd = parts.slice(1).join(" ") || null;
|
|
17589
|
+
const oneShotCmd = this.remoteCommandFromRaw(command2.rawCommand, candidateName) ?? (parts.slice(1).join(" ") || null);
|
|
17125
17590
|
return {
|
|
17126
17591
|
serverName: candidateName,
|
|
17127
17592
|
oneShotCmd,
|
|
@@ -17141,7 +17606,7 @@ var CliSshCommandProcessor = class {
|
|
|
17141
17606
|
connection: shellServers[0].connection
|
|
17142
17607
|
};
|
|
17143
17608
|
}
|
|
17144
|
-
const manager = context2.services.
|
|
17609
|
+
const manager = context2.services.getRequired(
|
|
17145
17610
|
CliServerManager_TOKEN
|
|
17146
17611
|
);
|
|
17147
17612
|
if (manager?.defaultServer) {
|
|
@@ -17175,41 +17640,57 @@ var CliSshCommandProcessor = class {
|
|
|
17175
17640
|
};
|
|
17176
17641
|
}
|
|
17177
17642
|
async executeInteractive(connection, serverName, context2) {
|
|
17178
|
-
|
|
17643
|
+
const session = { socket: null, resolved: false, disposed: false };
|
|
17179
17644
|
const cols = context2.terminal.cols;
|
|
17180
17645
|
const rows = context2.terminal.rows;
|
|
17181
|
-
const wsUrl = this.buildShellUrl(connection, cols, rows);
|
|
17646
|
+
const wsUrl = await this.buildShellUrl(connection, cols, rows);
|
|
17182
17647
|
context2.spinner?.show(`Connecting to ${serverName}...`);
|
|
17183
|
-
|
|
17648
|
+
let fullScreen = false;
|
|
17184
17649
|
return new Promise((resolve) => {
|
|
17650
|
+
const signal = context2.signal;
|
|
17185
17651
|
const resolveOnce = () => {
|
|
17186
|
-
|
|
17187
|
-
|
|
17652
|
+
signal?.removeEventListener("abort", onAbort);
|
|
17653
|
+
if (!session.resolved) {
|
|
17654
|
+
session.resolved = true;
|
|
17188
17655
|
resolve();
|
|
17189
17656
|
}
|
|
17190
17657
|
};
|
|
17658
|
+
const onAbort = () => {
|
|
17659
|
+
context2.spinner?.hide();
|
|
17660
|
+
this.cleanup(session);
|
|
17661
|
+
if (fullScreen) context2.exitFullScreenMode();
|
|
17662
|
+
context2.process.exit(130, { silent: true });
|
|
17663
|
+
resolveOnce();
|
|
17664
|
+
};
|
|
17665
|
+
if (signal?.aborted) {
|
|
17666
|
+
onAbort();
|
|
17667
|
+
return;
|
|
17668
|
+
}
|
|
17669
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
17191
17670
|
try {
|
|
17192
|
-
|
|
17671
|
+
session.socket = new WebSocket(wsUrl);
|
|
17193
17672
|
} catch (e) {
|
|
17194
17673
|
context2.spinner?.hide();
|
|
17195
17674
|
context2.writer.writeError(
|
|
17196
17675
|
`Failed to connect to '${serverName}': ${e.message}`
|
|
17197
17676
|
);
|
|
17198
|
-
context2.process.exit(1);
|
|
17677
|
+
context2.process.exit(1, { silent: true });
|
|
17199
17678
|
resolveOnce();
|
|
17200
17679
|
return;
|
|
17201
17680
|
}
|
|
17202
|
-
|
|
17681
|
+
session.socket.onopen = () => {
|
|
17203
17682
|
};
|
|
17204
|
-
|
|
17205
|
-
const msg =
|
|
17683
|
+
session.socket.onmessage = (event) => {
|
|
17684
|
+
const msg = parseShellMessage(event.data);
|
|
17685
|
+
if (!msg) return;
|
|
17206
17686
|
switch (msg.type) {
|
|
17207
17687
|
case "ready":
|
|
17208
17688
|
context2.spinner?.hide();
|
|
17209
17689
|
context2.writer.writeInfo(
|
|
17210
17690
|
`Connected to ${serverName} (${msg.os}, ${msg.shell})`
|
|
17211
17691
|
);
|
|
17212
|
-
context2.enterFullScreenMode(this);
|
|
17692
|
+
context2.enterFullScreenMode(this.fullScreenHandler(session));
|
|
17693
|
+
fullScreen = true;
|
|
17213
17694
|
context2.terminal.write("\x1B[2J\x1B[H\x1B[?25h");
|
|
17214
17695
|
break;
|
|
17215
17696
|
case "stdout":
|
|
@@ -17219,70 +17700,82 @@ var CliSshCommandProcessor = class {
|
|
|
17219
17700
|
context2.terminal.write(msg.data);
|
|
17220
17701
|
break;
|
|
17221
17702
|
case "exit":
|
|
17222
|
-
context2.exitFullScreenMode();
|
|
17703
|
+
if (fullScreen) context2.exitFullScreenMode();
|
|
17223
17704
|
context2.writer.writeInfo(
|
|
17224
17705
|
`Shell exited with code ${msg.code}.`
|
|
17225
17706
|
);
|
|
17226
|
-
context2.process.exit(msg.code);
|
|
17227
|
-
this.cleanup();
|
|
17707
|
+
context2.process.exit(msg.code, { silent: true });
|
|
17708
|
+
this.cleanup(session);
|
|
17228
17709
|
resolveOnce();
|
|
17229
17710
|
break;
|
|
17230
17711
|
case "error":
|
|
17231
17712
|
context2.spinner?.hide();
|
|
17232
|
-
context2.exitFullScreenMode();
|
|
17713
|
+
if (fullScreen) context2.exitFullScreenMode();
|
|
17233
17714
|
context2.writer.writeError(
|
|
17234
17715
|
`Server error: ${msg.message}`
|
|
17235
17716
|
);
|
|
17236
|
-
context2.process.exit(1);
|
|
17237
|
-
this.cleanup();
|
|
17717
|
+
context2.process.exit(1, { silent: true });
|
|
17718
|
+
this.cleanup(session);
|
|
17238
17719
|
resolveOnce();
|
|
17239
17720
|
break;
|
|
17240
17721
|
}
|
|
17241
17722
|
};
|
|
17242
|
-
|
|
17723
|
+
let errored = false;
|
|
17724
|
+
session.socket.onclose = (event) => {
|
|
17243
17725
|
context2.spinner?.hide();
|
|
17244
|
-
if (
|
|
17245
|
-
context2.exitFullScreenMode();
|
|
17246
|
-
|
|
17247
|
-
|
|
17248
|
-
);
|
|
17249
|
-
context2.
|
|
17726
|
+
if (!session.disposed && !session.resolved) {
|
|
17727
|
+
if (fullScreen) context2.exitFullScreenMode();
|
|
17728
|
+
const reason = describeShellClose(event ?? {}, serverName);
|
|
17729
|
+
if (reason) context2.writer.writeError(reason);
|
|
17730
|
+
else if (errored) context2.writer.writeError(`WebSocket error connecting to '${serverName}'.`);
|
|
17731
|
+
else context2.writer.writeWarning(`Connection to '${serverName}' closed.`);
|
|
17732
|
+
context2.process.exit(1, { silent: true });
|
|
17250
17733
|
}
|
|
17251
|
-
this.cleanup();
|
|
17734
|
+
this.cleanup(session);
|
|
17252
17735
|
resolveOnce();
|
|
17253
17736
|
};
|
|
17254
|
-
|
|
17255
|
-
|
|
17256
|
-
if (!this.resolved) {
|
|
17257
|
-
context2.writer.writeError(
|
|
17258
|
-
`WebSocket error connecting to '${serverName}'.`
|
|
17259
|
-
);
|
|
17260
|
-
context2.process.exit(1);
|
|
17261
|
-
}
|
|
17262
|
-
this.cleanup();
|
|
17263
|
-
resolveOnce();
|
|
17737
|
+
session.socket.onerror = () => {
|
|
17738
|
+
errored = true;
|
|
17264
17739
|
};
|
|
17265
17740
|
});
|
|
17266
17741
|
}
|
|
17267
17742
|
async executeOneShot(connection, serverName, cmd, context2) {
|
|
17268
17743
|
const cols = context2.terminal.cols;
|
|
17269
17744
|
const rows = context2.terminal.rows;
|
|
17270
|
-
const wsUrl = this.buildShellUrl(connection, cols, rows, cmd);
|
|
17745
|
+
const wsUrl = await this.buildShellUrl(connection, cols, rows, cmd);
|
|
17271
17746
|
context2.spinner?.show(`Running on ${serverName}...`);
|
|
17272
|
-
|
|
17747
|
+
const session = { socket: null, resolved: false, disposed: false };
|
|
17748
|
+
return new Promise((resolvePromise) => {
|
|
17749
|
+
const signal = context2.signal;
|
|
17750
|
+
const resolve = () => {
|
|
17751
|
+
signal?.removeEventListener("abort", onAbort);
|
|
17752
|
+
resolvePromise();
|
|
17753
|
+
};
|
|
17754
|
+
const onAbort = () => {
|
|
17755
|
+
context2.spinner?.hide();
|
|
17756
|
+
this.cleanup(session);
|
|
17757
|
+
context2.process.exit(130, { silent: true });
|
|
17758
|
+
resolve();
|
|
17759
|
+
};
|
|
17760
|
+
if (signal?.aborted) {
|
|
17761
|
+
onAbort();
|
|
17762
|
+
return;
|
|
17763
|
+
}
|
|
17764
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
17273
17765
|
try {
|
|
17274
|
-
|
|
17766
|
+
session.socket = new WebSocket(wsUrl);
|
|
17275
17767
|
} catch (e) {
|
|
17276
17768
|
context2.spinner?.hide();
|
|
17277
17769
|
context2.writer.writeError(
|
|
17278
17770
|
`Failed to connect to '${serverName}': ${e.message}`
|
|
17279
17771
|
);
|
|
17280
|
-
context2.process.exit(1);
|
|
17772
|
+
context2.process.exit(1, { silent: true });
|
|
17281
17773
|
resolve();
|
|
17282
17774
|
return;
|
|
17283
17775
|
}
|
|
17284
|
-
|
|
17285
|
-
const msg =
|
|
17776
|
+
session.socket.onmessage = (event) => {
|
|
17777
|
+
const msg = parseShellMessage(event.data);
|
|
17778
|
+
if (!msg) return;
|
|
17286
17779
|
switch (msg.type) {
|
|
17287
17780
|
case "ready":
|
|
17288
17781
|
context2.spinner?.hide();
|
|
@@ -17295,9 +17788,9 @@ var CliSshCommandProcessor = class {
|
|
|
17295
17788
|
break;
|
|
17296
17789
|
case "exit":
|
|
17297
17790
|
if (msg.code !== 0) {
|
|
17298
|
-
context2.process.exit(msg.code);
|
|
17791
|
+
context2.process.exit(msg.code, { silent: true });
|
|
17299
17792
|
}
|
|
17300
|
-
this.cleanup();
|
|
17793
|
+
this.cleanup(session);
|
|
17301
17794
|
resolve();
|
|
17302
17795
|
break;
|
|
17303
17796
|
case "error":
|
|
@@ -17305,50 +17798,82 @@ var CliSshCommandProcessor = class {
|
|
|
17305
17798
|
context2.writer.writeError(
|
|
17306
17799
|
`Server error: ${msg.message}`
|
|
17307
17800
|
);
|
|
17308
|
-
context2.process.exit(1);
|
|
17309
|
-
this.cleanup();
|
|
17801
|
+
context2.process.exit(1, { silent: true });
|
|
17802
|
+
this.cleanup(session);
|
|
17310
17803
|
resolve();
|
|
17311
17804
|
break;
|
|
17312
17805
|
}
|
|
17313
17806
|
};
|
|
17314
|
-
|
|
17807
|
+
let errored = false;
|
|
17808
|
+
session.socket.onclose = (event) => {
|
|
17315
17809
|
context2.spinner?.hide();
|
|
17316
|
-
|
|
17810
|
+
const reason = describeShellClose(event ?? {}, serverName);
|
|
17811
|
+
if (reason || errored) {
|
|
17812
|
+
context2.writer.writeError(reason ?? `WebSocket error connecting to '${serverName}'.`);
|
|
17813
|
+
context2.process.exit(1, { silent: true });
|
|
17814
|
+
}
|
|
17815
|
+
this.cleanup(session);
|
|
17317
17816
|
resolve();
|
|
17318
17817
|
};
|
|
17319
|
-
|
|
17320
|
-
|
|
17321
|
-
context2.writer.writeError(
|
|
17322
|
-
`WebSocket error connecting to '${serverName}'.`
|
|
17323
|
-
);
|
|
17324
|
-
context2.process.exit(1);
|
|
17325
|
-
this.cleanup();
|
|
17326
|
-
resolve();
|
|
17818
|
+
session.socket.onerror = () => {
|
|
17819
|
+
errored = true;
|
|
17327
17820
|
};
|
|
17328
17821
|
});
|
|
17329
17822
|
}
|
|
17823
|
+
/** `ssh <server> <cmd...>` → `<cmd...>` exactly as typed */
|
|
17824
|
+
remoteCommandFromRaw(raw, serverName) {
|
|
17825
|
+
const match = raw?.trim().match(/^\S+\s+(\S+)\s+([\s\S]+)$/);
|
|
17826
|
+
return match && match[1] === serverName ? match[2].trim() : null;
|
|
17827
|
+
}
|
|
17330
17828
|
buildShellUrl(connection, cols, rows, cmd) {
|
|
17331
|
-
|
|
17332
|
-
const wsBase = baseUrl.replace(/^https:/, "wss:").replace(/^http:/, "ws:");
|
|
17333
|
-
let url = `${wsBase}/ws/v1/qcli/shell?cols=${cols}&rows=${rows}`;
|
|
17829
|
+
let path = `/ws/v1/qcli/shell?cols=${cols}&rows=${rows}`;
|
|
17334
17830
|
if (cmd) {
|
|
17335
|
-
|
|
17831
|
+
path += `&cmd=${encodeURIComponent(cmd)}`;
|
|
17336
17832
|
}
|
|
17337
|
-
return
|
|
17833
|
+
return connection.buildWebSocketUrl(path);
|
|
17338
17834
|
}
|
|
17339
|
-
cleanup() {
|
|
17340
|
-
|
|
17341
|
-
|
|
17342
|
-
|
|
17343
|
-
|
|
17344
|
-
|
|
17345
|
-
|
|
17835
|
+
cleanup(session) {
|
|
17836
|
+
const socket = session.socket;
|
|
17837
|
+
if (socket) {
|
|
17838
|
+
socket.onmessage = null;
|
|
17839
|
+
socket.onclose = null;
|
|
17840
|
+
socket.onerror = null;
|
|
17841
|
+
if (socket.readyState === WebSocket.OPEN || socket.readyState === WebSocket.CONNECTING) {
|
|
17842
|
+
socket.close();
|
|
17346
17843
|
}
|
|
17347
|
-
|
|
17844
|
+
session.socket = null;
|
|
17348
17845
|
}
|
|
17349
|
-
this.context = null;
|
|
17350
17846
|
}
|
|
17351
17847
|
};
|
|
17848
|
+
function parseShellMessage(data) {
|
|
17849
|
+
try {
|
|
17850
|
+
const msg = typeof data === "string" ? JSON.parse(data) : null;
|
|
17851
|
+
return msg && typeof msg === "object" && typeof msg.type === "string" ? msg : null;
|
|
17852
|
+
} catch {
|
|
17853
|
+
return null;
|
|
17854
|
+
}
|
|
17855
|
+
}
|
|
17856
|
+
function describeShellClose(event, serverName) {
|
|
17857
|
+
const reason = (event.reason ?? "").toLowerCase();
|
|
17858
|
+
switch (event.code) {
|
|
17859
|
+
case 4401:
|
|
17860
|
+
if (reason === "session ended") return `ssh: shell closed by '${serverName}' (session ended or shell access revoked)`;
|
|
17861
|
+
if (reason === "shell access is not configured") {
|
|
17862
|
+
return `ssh: shell access is not configured on '${serverName}'`;
|
|
17863
|
+
}
|
|
17864
|
+
return `ssh: login required on '${serverName}'`;
|
|
17865
|
+
case 4403:
|
|
17866
|
+
return `ssh: permission denied on '${serverName}' (requires shell:execute or a valid shell token)`;
|
|
17867
|
+
case 4404:
|
|
17868
|
+
return `ssh: the shell is disabled on '${serverName}'`;
|
|
17869
|
+
case 4408:
|
|
17870
|
+
return `ssh: shell timed out on '${serverName}'`;
|
|
17871
|
+
case 4429:
|
|
17872
|
+
return `ssh: too many shell sessions on '${serverName}'`;
|
|
17873
|
+
default:
|
|
17874
|
+
return null;
|
|
17875
|
+
}
|
|
17876
|
+
}
|
|
17352
17877
|
|
|
17353
17878
|
// src/lib/server/cli-server-module.ts
|
|
17354
17879
|
function createServerModule() {
|
|
@@ -17383,6 +17908,11 @@ function initializeTerminal(container, opts) {
|
|
|
17383
17908
|
terminal.open(container);
|
|
17384
17909
|
fitAddon.fit();
|
|
17385
17910
|
requestAnimationFrame(() => fitAddon.fit());
|
|
17911
|
+
if (document.fonts?.ready) {
|
|
17912
|
+
document.fonts.ready.then(() => {
|
|
17913
|
+
requestAnimationFrame(() => fitAddon.fit());
|
|
17914
|
+
});
|
|
17915
|
+
}
|
|
17386
17916
|
container.classList.add("terminal-container");
|
|
17387
17917
|
container.style.background = opts.theme?.background ?? "#000";
|
|
17388
17918
|
const wheelListener = (e) => e.preventDefault();
|
|
@@ -17625,19 +18155,21 @@ async function initializeServices(options) {
|
|
|
17625
18155
|
const logger = new CliLogger();
|
|
17626
18156
|
const commandHistory = new CliCommandHistory(store);
|
|
17627
18157
|
await commandHistory.initialize();
|
|
17628
|
-
services.set([{ provide:
|
|
18158
|
+
services.set([{ provide: CliKeyValueStore_TOKEN, useValue: store, sealed: true }]);
|
|
17629
18159
|
const stateStoreManager = new CliStateStoreManager(services, registry);
|
|
17630
18160
|
const processRegistry = new CliProcessRegistry();
|
|
17631
18161
|
services.set([
|
|
17632
18162
|
{
|
|
17633
18163
|
provide: CliStateStoreManager_TOKEN,
|
|
17634
|
-
useValue: stateStoreManager
|
|
18164
|
+
useValue: stateStoreManager,
|
|
18165
|
+
sealed: true
|
|
17635
18166
|
},
|
|
17636
|
-
{ provide: CliProcessorsRegistry_TOKEN, useValue: registry },
|
|
17637
|
-
{ provide: CliCommandHistory_TOKEN, useValue: commandHistory },
|
|
18167
|
+
{ provide: CliProcessorsRegistry_TOKEN, useValue: registry, sealed: true },
|
|
18168
|
+
{ provide: CliCommandHistory_TOKEN, useValue: commandHistory, sealed: true },
|
|
17638
18169
|
{
|
|
17639
18170
|
provide: CliProcessRegistry_TOKEN,
|
|
17640
|
-
useValue: processRegistry
|
|
18171
|
+
useValue: processRegistry,
|
|
18172
|
+
sealed: true
|
|
17641
18173
|
}
|
|
17642
18174
|
]);
|
|
17643
18175
|
if (pendingServices.length > 0) {
|
|
@@ -17648,7 +18180,8 @@ async function initializeServices(options) {
|
|
|
17648
18180
|
services.set([
|
|
17649
18181
|
{
|
|
17650
18182
|
provide: ICliPingServerService_TOKEN,
|
|
17651
|
-
|
|
18183
|
+
useClass: CliDefaultPingServerService,
|
|
18184
|
+
sealed: true
|
|
17652
18185
|
}
|
|
17653
18186
|
]);
|
|
17654
18187
|
}
|
|
@@ -17658,25 +18191,41 @@ async function initializeServices(options) {
|
|
|
17658
18191
|
syntaxRegistry.register(new MarkdownHighlighter());
|
|
17659
18192
|
syntaxRegistry.register(new YamlHighlighter());
|
|
17660
18193
|
services.set([
|
|
17661
|
-
{ provide:
|
|
18194
|
+
{ provide: SyntaxHighlighterRegistry_TOKEN, useValue: syntaxRegistry, sealed: true }
|
|
17662
18195
|
]);
|
|
17663
18196
|
if (!pendingTokens.has(ICliEnvironment_TOKEN)) {
|
|
17664
18197
|
services.set([
|
|
17665
18198
|
{
|
|
17666
18199
|
provide: ICliEnvironment_TOKEN,
|
|
17667
|
-
|
|
18200
|
+
useClass: CliEnvironment,
|
|
18201
|
+
sealed: true
|
|
17668
18202
|
}
|
|
17669
18203
|
]);
|
|
17670
18204
|
}
|
|
17671
18205
|
services.set([
|
|
17672
18206
|
{
|
|
17673
18207
|
provide: ICliDragDropService_TOKEN,
|
|
17674
|
-
useValue: dragDropService
|
|
18208
|
+
useValue: dragDropService,
|
|
18209
|
+
sealed: true
|
|
18210
|
+
}
|
|
18211
|
+
]);
|
|
18212
|
+
services.set(
|
|
18213
|
+
cliAccessMetadataGuards.map((guard) => ({
|
|
18214
|
+
provide: ICliCommandGuard_TOKEN,
|
|
18215
|
+
useValue: guard,
|
|
18216
|
+
multi: true
|
|
18217
|
+
}))
|
|
18218
|
+
);
|
|
18219
|
+
services.set([
|
|
18220
|
+
{
|
|
18221
|
+
provide: ICliPermissionRegistry_TOKEN,
|
|
18222
|
+
useValue: new CliPermissionRegistry(),
|
|
18223
|
+
sealed: true
|
|
17675
18224
|
}
|
|
17676
18225
|
]);
|
|
17677
18226
|
const translator = new CliTranslationService();
|
|
17678
18227
|
services.set([
|
|
17679
|
-
{ provide: ICliTranslationService_TOKEN, useValue: translator }
|
|
18228
|
+
{ provide: ICliTranslationService_TOKEN, useValue: translator, sealed: true }
|
|
17680
18229
|
]);
|
|
17681
18230
|
return {
|
|
17682
18231
|
services,
|
|
@@ -17745,7 +18294,7 @@ var CliEngine = class {
|
|
|
17745
18294
|
* Initialize the terminal, wire up services, boot modules, and show welcome message.
|
|
17746
18295
|
*/
|
|
17747
18296
|
async start() {
|
|
17748
|
-
initWasmAccelerator().catch(() => {
|
|
18297
|
+
initWasmAccelerator(this.options?.wasmUrl).catch(() => {
|
|
17749
18298
|
});
|
|
17750
18299
|
await waitForLayout(this.container);
|
|
17751
18300
|
const terminalOpts = getTerminalOptions(this.options?.terminalOptions);
|
|
@@ -17788,10 +18337,18 @@ var CliEngine = class {
|
|
|
17788
18337
|
provide: CliBackgroundServiceRegistry_TOKEN,
|
|
17789
18338
|
useValue: this.executionContext.backgroundServices
|
|
17790
18339
|
}]);
|
|
17791
|
-
const
|
|
18340
|
+
const serverAuthService = new CliServerAuthService(services);
|
|
17792
18341
|
services.set([
|
|
17793
|
-
{ provide:
|
|
18342
|
+
{ provide: ICliServerAuthService_TOKEN, useValue: serverAuthService, sealed: true }
|
|
18343
|
+
]);
|
|
18344
|
+
services.set([
|
|
18345
|
+
{
|
|
18346
|
+
provide: CliServerManager_TOKEN,
|
|
18347
|
+
useClass: CliServerManager,
|
|
18348
|
+
deps: [CliProcessorsRegistry_TOKEN, ICliServerAuthService_TOKEN]
|
|
18349
|
+
}
|
|
17794
18350
|
]);
|
|
18351
|
+
const serverManager = services.getRequired(CliServerManager_TOKEN);
|
|
17795
18352
|
if (this.options?.servers && this.options.servers.length > 0) {
|
|
17796
18353
|
await serverManager.connectAll(this.options.servers, {
|
|
17797
18354
|
warn: (msg) => this.executionContext.logger.warn(msg),
|
|
@@ -17811,13 +18368,9 @@ var CliEngine = class {
|
|
|
17811
18368
|
new CliCommandCompletionProvider(this.registry),
|
|
17812
18369
|
new CliParameterCompletionProvider(this.registry, executor)
|
|
17813
18370
|
];
|
|
17814
|
-
|
|
17815
|
-
|
|
17816
|
-
|
|
17817
|
-
ICliCompletionProvider_TOKEN
|
|
17818
|
-
) ?? [];
|
|
17819
|
-
} catch {
|
|
17820
|
-
}
|
|
18371
|
+
const pluginProviders = services.getAll(
|
|
18372
|
+
ICliCompletionProvider_TOKEN
|
|
18373
|
+
);
|
|
17821
18374
|
this.executionContext.completionEngine.setProviders([
|
|
17822
18375
|
...pluginProviders,
|
|
17823
18376
|
...defaultProviders
|
|
@@ -17925,7 +18478,7 @@ var CliEngine = class {
|
|
|
17925
18478
|
if (!this.executionContext) {
|
|
17926
18479
|
throw new Error("Cannot snapshot before engine has started");
|
|
17927
18480
|
}
|
|
17928
|
-
const stateStoreManager = this.executionContext.services.
|
|
18481
|
+
const stateStoreManager = this.executionContext.services.getRequired(
|
|
17929
18482
|
CliStateStoreManager_TOKEN
|
|
17930
18483
|
);
|
|
17931
18484
|
return {
|
|
@@ -17952,7 +18505,7 @@ var CliEngine = class {
|
|
|
17952
18505
|
});
|
|
17953
18506
|
}
|
|
17954
18507
|
await this.executionContext.commandHistory.setHistory(snap.commandHistory);
|
|
17955
|
-
const stateStoreManager = this.executionContext.services.
|
|
18508
|
+
const stateStoreManager = this.executionContext.services.getRequired(
|
|
17956
18509
|
CliStateStoreManager_TOKEN
|
|
17957
18510
|
);
|
|
17958
18511
|
for (const entry of snap.stateStores) {
|
|
@@ -18012,7 +18565,7 @@ var CliTestHarness = class {
|
|
|
18012
18565
|
this.services = new CliServiceContainer();
|
|
18013
18566
|
this.processRegistry = new CliProcessRegistry();
|
|
18014
18567
|
this.services.set({
|
|
18015
|
-
provide:
|
|
18568
|
+
provide: CliKeyValueStore_TOKEN,
|
|
18016
18569
|
useValue: createInMemoryKvStore()
|
|
18017
18570
|
});
|
|
18018
18571
|
this.services.set({
|
|
@@ -18035,6 +18588,24 @@ var CliTestHarness = class {
|
|
|
18035
18588
|
provide: ICliEnvironment_TOKEN,
|
|
18036
18589
|
useValue: new CliEnvironment()
|
|
18037
18590
|
});
|
|
18591
|
+
this.services.set({
|
|
18592
|
+
provide: ICliPermissionRegistry_TOKEN,
|
|
18593
|
+
useValue: new CliPermissionRegistry()
|
|
18594
|
+
});
|
|
18595
|
+
this.services.set(
|
|
18596
|
+
cliAccessMetadataGuards.map((guard) => ({
|
|
18597
|
+
provide: ICliCommandGuard_TOKEN,
|
|
18598
|
+
useValue: guard,
|
|
18599
|
+
multi: true
|
|
18600
|
+
}))
|
|
18601
|
+
);
|
|
18602
|
+
}
|
|
18603
|
+
/**
|
|
18604
|
+
* Resolve `context.userSession` on every command from this function
|
|
18605
|
+
* (e.g. a session service), instead of the value set via setUserSession().
|
|
18606
|
+
*/
|
|
18607
|
+
setUserSessionProvider(provider) {
|
|
18608
|
+
this.userSessionProvider = provider;
|
|
18038
18609
|
}
|
|
18039
18610
|
/**
|
|
18040
18611
|
* Register a service in the test container.
|
|
@@ -18119,9 +18690,10 @@ var CliTestHarness = class {
|
|
|
18119
18690
|
options: void 0,
|
|
18120
18691
|
logger: createNoopLogger(),
|
|
18121
18692
|
process,
|
|
18122
|
-
userSession: this.userSession,
|
|
18693
|
+
userSession: this.userSessionProvider ? this.userSessionProvider() : this.userSession,
|
|
18123
18694
|
state: this.stateStoreManager.getStateStore("shared"),
|
|
18124
18695
|
backgroundServices: createNoopBackgroundServices(),
|
|
18696
|
+
http: new CliHttpClient(),
|
|
18125
18697
|
promptLength: 0,
|
|
18126
18698
|
currentLine: "",
|
|
18127
18699
|
cursorPosition: 0,
|
|
@@ -18144,11 +18716,7 @@ var CliTestHarness = class {
|
|
|
18144
18716
|
submitCommand: async (command2) => {
|
|
18145
18717
|
await this.executor.executeCommand(command2, context2);
|
|
18146
18718
|
},
|
|
18147
|
-
|
|
18148
|
-
},
|
|
18149
|
-
clearStatusText: () => {
|
|
18150
|
-
},
|
|
18151
|
-
getStatusText: () => void 0,
|
|
18719
|
+
notifier: new CliNotifier(),
|
|
18152
18720
|
createInterval: (cb, ms) => {
|
|
18153
18721
|
const id = setInterval(cb, ms);
|
|
18154
18722
|
return {
|
|
@@ -18354,6 +18922,6 @@ function createInMemoryKvStore() {
|
|
|
18354
18922
|
};
|
|
18355
18923
|
}
|
|
18356
18924
|
|
|
18357
|
-
export { API_VERSION, CLi_Name_Art, CapturingTerminalWriter, CliAliasCommandProcessor, CliArgsParser, CliBackgroundServiceRegistry_TOKEN, CliBoot, CliCalCommandProcessor, CliCaptureCommandProcessor, CliClearCommandProcessor, CliClipboard, CliClipboardCommandProcessor, CliColorCommandProcessor, CliCommandExecutionContext, CliCommandExecutor, CliCommandHistory, CliCommandHistory_TOKEN, CliCommandProcessorRegistry, CliConfigureCommandProcessor, CliConvertCommandProcessor, CliDebugCommandProcessor, CliDefaultPingServerService, CliDiffCommandProcessor, CliDragDropService, CliEchoCommandProcessor, CliEngine, CliEnvCommandProcessor, CliEnvironment, CliEvalCommandProcessor, CliExecutionContext, CliExecutionProcess, CliExportCommandProcessor, CliFeedbackCommandProcessor, CliFontSizeCommandProcessor, CliFullScreenManager, CliHelpCommandProcessor, CliHistoryCommandProcessor, CliHotKeysCommandProcessor, CliHtopCommandProcessor, CliInputReader, CliJsonCommandProcessor, CliKeyValueStore, CliKillCommandProcessor, CliLogger, CliLoremCommandProcessor, CliModuleRegistry_TOKEN, CliNanoCommandProcessor, CliOpenCommandProcessor, CliPackageManagerService, CliPackageManagerService_TOKEN, CliPackagesCommandProcessor, CliPingCommandProcessor, CliProcessRegistry, CliProcessRegistry_TOKEN, CliProcessorsRegistry_TOKEN, CliPsCommandProcessor, CliRandomCommandProcessor, CliScreenCommandProcessor, CliSeqCommandProcessor, CliServerCommandProcessor, CliServerConnection, CliServerManager, CliServerManager_TOKEN, CliServerMultiProxyProcessor, CliServerProxyProcessor, CliServiceContainer, CliServicesCommandProcessor, CliSleepCommandProcessor, CliSnippetCommandProcessor, CliSshCommandProcessor, CliStateStore, CliStateStoreManager, CliStateStoreManager_TOKEN, CliTerminalProgressBar, CliTerminalSpinner, CliTerminalTextAnimator, CliTerminalWriter, CliTestHarness, CliThemeCommandProcessor, CliTimeCommandProcessor, CliTimerManager, CliTimestampCommandProcessor, CliUnAliasCommandProcessor, CliUnameCommandProcessor, CliUnsetCommandProcessor, CliUptimeCommandProcessor, CliVersionCommandProcessor, CliYesCommandProcessor, CommandParser, ICliEnvironment_TOKEN, ICliPingServerService_TOKEN, JsFallbackAccelerator, LIBRARY_VERSION, OverlayAddon, ProcessExitedError, ScriptLoaderService, appendOutputToFile, appendStderrToFile, builtinProcessors, computeDiff, contextGlobalParameter, createServerModule, executeOnServer, expandEnvironmentVars, formatDiff, getAccelerator, getCliNameArt, getGreetingBasedOnTime, getTerminalOptions, groupBy, helpGlobalParameter, hotkeysInfo, initWasmAccelerator, initializeServices, initializeTerminal, isWasmAccelerated, miscProcessors, openLink, reconcileArgs, renderServerResponse, renderSingleOutput, substituteVars, systemProcessors, themeInfos, themes, tryExecuteScript, versionGlobalParameter, waitForLayout, welcomeModule, writeOutputToFile, writeStderrToFile };
|
|
18925
|
+
export { API_VERSION, CLi_Name_Art, CapturingTerminalWriter, CliAliasCommandProcessor, CliArgsParser, CliBackgroundServiceRegistry_TOKEN, CliBoot, CliCalCommandProcessor, CliCaptureCommandProcessor, CliClearCommandProcessor, CliClipboard, CliClipboardCommandProcessor, CliColorCommandProcessor, CliCommandExecutionContext, CliCommandExecutor, CliCommandHistory, CliCommandHistory_TOKEN, CliCommandProcessorRegistry, CliConfigureCommandProcessor, CliConvertCommandProcessor, CliDebugCommandProcessor, CliDefaultPingServerService, CliDiffCommandProcessor, CliDragDropService, CliEchoCommandProcessor, CliEngine, CliEnvCommandProcessor, CliEnvironment, CliEvalCommandProcessor, CliExecutionContext, CliExecutionProcess, CliExportCommandProcessor, CliFeedbackCommandProcessor, CliFontSizeCommandProcessor, CliFullScreenManager, CliHelpCommandProcessor, CliHistoryCommandProcessor, CliHotKeysCommandProcessor, CliHtopCommandProcessor, CliHttpClient, CliInputReader, CliJsonCommandProcessor, CliKeyValueStore, CliKeyValueStore_TOKEN, CliKillCommandProcessor, CliLogger, CliLoremCommandProcessor, CliModuleRegistry_TOKEN, CliNanoCommandProcessor, CliNotifier, CliOpenCommandProcessor, CliPackageManagerService, CliPackageManagerService_TOKEN, CliPackagesCommandProcessor, CliPermissionRegistry, CliPingCommandProcessor, CliProcessRegistry, CliProcessRegistry_TOKEN, CliProcessorsRegistry_TOKEN, CliPsCommandProcessor, CliRandomCommandProcessor, CliScreenCommandProcessor, CliSeqCommandProcessor, CliServerCommandProcessor, CliServerConnection, CliServerManager, CliServerManager_TOKEN, CliServerMultiProxyProcessor, CliServerProxyProcessor, CliServiceContainer, CliServicesCommandProcessor, CliSleepCommandProcessor, CliSnippetCommandProcessor, CliSshCommandProcessor, CliStateStore, CliStateStoreManager, CliStateStoreManager_TOKEN, CliTerminalProgressBar, CliTerminalSpinner, CliTerminalTextAnimator, CliTerminalWriter, CliTestHarness, CliThemeCommandProcessor, CliTimeCommandProcessor, CliTimerManager, CliTimestampCommandProcessor, CliUnAliasCommandProcessor, CliUnameCommandProcessor, CliUnsetCommandProcessor, CliUptimeCommandProcessor, CliVersionCommandProcessor, CliYesCommandProcessor, CommandParser, ICliEnvironment_TOKEN, ICliPingServerService_TOKEN, JsFallbackAccelerator, LIBRARY_VERSION, OverlayAddon, ProcessExitedError, ScriptLoaderService, SyntaxHighlighterRegistry_TOKEN, appendOutputToFile, appendStderrToFile, builtinProcessors, computeDiff, contextGlobalParameter, createServerModule, describeShellClose, executeOnServer, expandEnvironmentVars, formatDiff, getAccelerator, getCliNameArt, getGreetingBasedOnTime, getTerminalOptions, groupBy, helpGlobalParameter, hotkeysInfo, initWasmAccelerator, initializeServices, initializeTerminal, isWasmAccelerated, miscProcessors, openLink, reconcileArgs, renderServerResponse, renderSingleOutput, substituteVars, systemProcessors, themeInfos, themes, tryExecuteScript, versionGlobalParameter, waitForLayout, welcomeModule, writeOutputToFile, writeStderrToFile };
|
|
18358
18926
|
//# sourceMappingURL=public-api.mjs.map
|
|
18359
18927
|
//# sourceMappingURL=public-api.mjs.map
|