@qodalis/cli-scp 2.0.0-beta.2 → 2.0.0-beta.20

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qodalis/cli-scp",
3
- "version": "2.0.0-beta.2",
3
+ "version": "2.0.0-beta.20",
4
4
  "description": "SCP-like file transfer between browser and remote servers",
5
5
  "author": "Qodalis Solutions",
6
6
  "license": "MIT",
@@ -18,7 +18,7 @@
18
18
  "umd": "./umd/index.global.js",
19
19
  "unpkg": "./umd/index.global.js",
20
20
  "dependencies": {
21
- "@qodalis/cli-core": "2.0.0-beta.2"
21
+ "@qodalis/cli-core": "2.0.0-beta.20"
22
22
  },
23
23
  "sideEffects": false,
24
24
  "main": "./public-api.js",
package/public-api.d.mts CHANGED
@@ -1,11 +1,14 @@
1
- import * as _qodalis_cli_core from '@qodalis/cli-core';
2
1
  import { ICliCommandProcessor, ICliCommandChildProcessor, CliProcessCommand, ICliExecutionContext, ICliModule } from '@qodalis/cli-core';
3
2
 
4
3
  declare class CliScpCommandCommandProcessor implements ICliCommandProcessor {
5
4
  command: string;
6
5
  description: string;
7
- author: _qodalis_cli_core.ICliCommandAuthor;
6
+ author: any;
8
7
  version: string;
8
+ metadata: {
9
+ icon: string;
10
+ module: string;
11
+ };
9
12
  acceptsRawInput: boolean;
10
13
  processors: ICliCommandChildProcessor[];
11
14
  processCommand(command: CliProcessCommand, context: ICliExecutionContext): Promise<void>;
@@ -14,7 +17,7 @@ declare class CliScpCommandCommandProcessor implements ICliCommandProcessor {
14
17
  private doUpload;
15
18
  }
16
19
 
17
- declare const LIBRARY_VERSION = "2.0.0-beta.2";
20
+ declare const LIBRARY_VERSION = "2.0.0-beta.20";
18
21
  declare const API_VERSION = 2;
19
22
 
20
23
  declare const scpModule: ICliModule;
package/public-api.d.ts CHANGED
@@ -1,11 +1,14 @@
1
- import * as _qodalis_cli_core from '@qodalis/cli-core';
2
1
  import { ICliCommandProcessor, ICliCommandChildProcessor, CliProcessCommand, ICliExecutionContext, ICliModule } from '@qodalis/cli-core';
3
2
 
4
3
  declare class CliScpCommandCommandProcessor implements ICliCommandProcessor {
5
4
  command: string;
6
5
  description: string;
7
- author: _qodalis_cli_core.ICliCommandAuthor;
6
+ author: any;
8
7
  version: string;
8
+ metadata: {
9
+ icon: string;
10
+ module: string;
11
+ };
9
12
  acceptsRawInput: boolean;
10
13
  processors: ICliCommandChildProcessor[];
11
14
  processCommand(command: CliProcessCommand, context: ICliExecutionContext): Promise<void>;
@@ -14,7 +17,7 @@ declare class CliScpCommandCommandProcessor implements ICliCommandProcessor {
14
17
  private doUpload;
15
18
  }
16
19
 
17
- declare const LIBRARY_VERSION = "2.0.0-beta.2";
20
+ declare const LIBRARY_VERSION = "2.0.0-beta.20";
18
21
  declare const API_VERSION = 2;
19
22
 
20
23
  declare const scpModule: ICliModule;
package/public-api.js CHANGED
@@ -5,13 +5,9 @@ var cliCore = require('@qodalis/cli-core');
5
5
  // src/lib/processors/cli-scp-command-processor.ts
6
6
 
7
7
  // src/lib/version.ts
8
- var LIBRARY_VERSION = "2.0.0-beta.2";
8
+ var LIBRARY_VERSION = "2.0.0-beta.20";
9
9
  var API_VERSION = 2;
10
-
11
- // src/lib/interfaces/index.ts
12
- var IScpTransferService_TOKEN = "scp-transfer-service";
13
-
14
- // src/lib/processors/scp-utils.ts
10
+ var IScpTransferService_TOKEN = cliCore.createCliToken("scp-transfer-service");
15
11
  function resolveServer(serverName, context) {
16
12
  const servers = context.options?.servers;
17
13
  if (!servers || servers.length === 0) {
@@ -49,10 +45,10 @@ function parseServerAndPath(value, context, args) {
49
45
  if (serverArg && pathArg) {
50
46
  return [String(serverArg), String(pathArg)];
51
47
  }
52
- if (!value?.trim()) {
48
+ const parts = cliCore.splitShellWords(value ?? "");
49
+ if (parts.length === 0) {
53
50
  return null;
54
51
  }
55
- const parts = value.trim().split(/\s+/);
56
52
  if (parts.length < 2) {
57
53
  if (serverArg && parts.length >= 1) {
58
54
  return [String(serverArg), parts.join(" ")];
@@ -64,8 +60,6 @@ function parseServerAndPath(value, context, args) {
64
60
  }
65
61
  return [parts[0], parts.slice(1).join(" ")];
66
62
  }
67
-
68
- // src/lib/processors/cli-scp-ls-processor.ts
69
63
  var CliScpLsProcessor = class {
70
64
  constructor() {
71
65
  this.command = "ls";
@@ -96,7 +90,7 @@ var CliScpLsProcessor = class {
96
90
  const [serverName, path] = parsed;
97
91
  const server = resolveServer(serverName, context);
98
92
  if (!server) return;
99
- const transferService = context.services.get(
93
+ const transferService = context.services.getRequired(
100
94
  IScpTransferService_TOKEN
101
95
  );
102
96
  if (!transferService) {
@@ -108,7 +102,7 @@ var CliScpLsProcessor = class {
108
102
  const entries = await transferService.ls(
109
103
  serverUrl(server),
110
104
  path,
111
- server.headers
105
+ cliCore.resolveServerHeaders(context.services, server.name, server.headers)
112
106
  );
113
107
  context.spinner?.hide();
114
108
  if (entries.length === 0) {
@@ -133,8 +127,6 @@ var CliScpLsProcessor = class {
133
127
  context.writer.writeln("List files and directories on a remote server.");
134
128
  }
135
129
  };
136
-
137
- // src/lib/processors/cli-scp-cat-processor.ts
138
130
  var CliScpCatProcessor = class {
139
131
  constructor() {
140
132
  this.command = "cat";
@@ -165,7 +157,7 @@ var CliScpCatProcessor = class {
165
157
  const [serverName, path] = parsed;
166
158
  const server = resolveServer(serverName, context);
167
159
  if (!server) return;
168
- const transferService = context.services.get(
160
+ const transferService = context.services.getRequired(
169
161
  IScpTransferService_TOKEN
170
162
  );
171
163
  if (!transferService) {
@@ -177,7 +169,7 @@ var CliScpCatProcessor = class {
177
169
  const content = await transferService.cat(
178
170
  serverUrl(server),
179
171
  path,
180
- server.headers
172
+ cliCore.resolveServerHeaders(context.services, server.name, server.headers)
181
173
  );
182
174
  context.spinner?.hide();
183
175
  context.writer.writeln(content);
@@ -235,12 +227,11 @@ var CliScpDownloadProcessor = class {
235
227
  remotePath = String(args["remote-path"] || args["path"]);
236
228
  localPath = args["local-path"] ? String(args["local-path"]) : void 0;
237
229
  } else {
238
- const value = command.value?.trim();
239
- if (!value) {
230
+ const parts = command.positionals ?? [];
231
+ if (parts.length === 0) {
240
232
  context.writer.writeError("Usage: scp download <server> <remote-path> [local-path]");
241
233
  return;
242
234
  }
243
- const parts = value.split(/\s+/);
244
235
  if (parts.length < 2) {
245
236
  context.writer.writeError("Usage: scp download <server> <remote-path> [local-path]");
246
237
  return;
@@ -256,7 +247,7 @@ var CliScpDownloadProcessor = class {
256
247
  localPath = localPath || remotePath.split("/").pop() || "download";
257
248
  const server = resolveServer(serverName, context);
258
249
  if (!server) return;
259
- const transferService = context.services.get(
250
+ const transferService = context.services.getRequired(
260
251
  IScpTransferService_TOKEN
261
252
  );
262
253
  if (!transferService) {
@@ -265,6 +256,7 @@ var CliScpDownloadProcessor = class {
265
256
  }
266
257
  const useBrowserDownload = command.args?.["save"] === true;
267
258
  context.spinner?.show(`Downloading ${remotePath} from ${server.name}...`);
259
+ context.notifier.info(`scp: downloading from ${server.name}`);
268
260
  const abortController = new AbortController();
269
261
  const abortSub = context.onAbort.subscribe(() => abortController.abort());
270
262
  try {
@@ -272,7 +264,7 @@ var CliScpDownloadProcessor = class {
272
264
  const { content, size } = await transferService.download(
273
265
  serverUrl(server),
274
266
  remotePath,
275
- server.headers,
267
+ cliCore.resolveServerHeaders(context.services, server.name, server.headers),
276
268
  (received, total) => {
277
269
  const now = Date.now();
278
270
  if (now - lastProgressUpdate < 200) return;
@@ -282,17 +274,19 @@ var CliScpDownloadProcessor = class {
282
274
  context.spinner?.show(
283
275
  `Downloading ${remotePath}... ${pct}% (${formatBytes(received)}/${formatBytes(total)})`
284
276
  );
277
+ context.notifier.info(`scp: download ${pct}%`);
285
278
  } else {
286
279
  context.spinner?.show(
287
280
  `Downloading ${remotePath}... ${formatBytes(received)}`
288
281
  );
282
+ context.notifier.info(`scp: download ${formatBytes(received)}`);
289
283
  }
290
284
  },
291
285
  abortController.signal
292
286
  );
293
287
  context.spinner?.hide();
294
288
  if (useBrowserDownload) {
295
- const fileService = context.services.get(
289
+ const fileService = context.services.getRequired(
296
290
  cliCore.ICliFileTransferService_TOKEN
297
291
  );
298
292
  if (fileService) {
@@ -304,7 +298,7 @@ var CliScpDownloadProcessor = class {
304
298
  context.writer.writeError("File transfer service not available for browser download.");
305
299
  }
306
300
  } else {
307
- const fileService = context.services.get(
301
+ const fileService = context.services.getRequired(
308
302
  cliCore.ICliFileTransferService_TOKEN
309
303
  );
310
304
  if (fileService) {
@@ -333,7 +327,7 @@ var CliScpUploadProcessor = class {
333
327
  constructor() {
334
328
  this.command = "upload";
335
329
  this.aliases = ["put"];
336
- this.description = "Upload a local file to a remote server";
330
+ this.description = "Upload a file to a remote server (use --local to pick from your machine)";
337
331
  this.acceptsRawInput = true;
338
332
  this.valueRequired = true;
339
333
  this.parameters = [
@@ -345,8 +339,8 @@ var CliScpUploadProcessor = class {
345
339
  },
346
340
  {
347
341
  name: "local-path",
348
- description: "Local file path",
349
- required: true,
342
+ description: "Local file path (from virtual filesystem)",
343
+ required: false,
350
344
  type: "string"
351
345
  },
352
346
  {
@@ -354,71 +348,103 @@ var CliScpUploadProcessor = class {
354
348
  description: "Remote destination path",
355
349
  required: true,
356
350
  type: "string"
351
+ },
352
+ {
353
+ name: "local",
354
+ description: "Pick a file from your local machine via browser file picker",
355
+ required: false,
356
+ type: "boolean"
357
357
  }
358
358
  ];
359
359
  }
360
360
  async processCommand(command, context) {
361
361
  const args = command.args || {};
362
+ const useLocalPicker = !!args["local"];
362
363
  let serverName;
363
364
  let localPath;
364
365
  let remotePath;
365
- if (args["server"] && args["local-path"] && args["remote-path"]) {
366
+ if (args["server"] && args["remote-path"]) {
366
367
  serverName = String(args["server"]);
367
- localPath = String(args["local-path"]);
368
+ localPath = args["local-path"] ? String(args["local-path"]) : void 0;
368
369
  remotePath = String(args["remote-path"]);
369
370
  } else {
370
- const value = command.value?.trim();
371
- if (!value) {
372
- context.writer.writeError("Usage: scp upload <server> <local-path> <remote-path>");
371
+ const parts = command.positionals ?? [];
372
+ if (parts.length === 0) {
373
+ context.writer.writeError(
374
+ useLocalPicker ? "Usage: scp upload --local <server> <remote-path>" : "Usage: scp upload <server> <local-path> <remote-path>"
375
+ );
373
376
  return;
374
377
  }
375
- const parts = value.split(/\s+/);
376
- if (parts.length < 3) {
377
- context.writer.writeError("Usage: scp upload <server> <local-path> <remote-path>");
378
- return;
378
+ if (useLocalPicker) {
379
+ if (parts.length < 2) {
380
+ context.writer.writeError("Usage: scp upload --local <server> <remote-path>");
381
+ return;
382
+ }
383
+ serverName = parts[0];
384
+ remotePath = parts[1];
385
+ } else {
386
+ if (parts.length < 3) {
387
+ context.writer.writeError("Usage: scp upload <server> <local-path> <remote-path>");
388
+ return;
389
+ }
390
+ serverName = parts[0];
391
+ localPath = parts[1];
392
+ remotePath = parts[2];
379
393
  }
380
- serverName = parts[0];
381
- localPath = parts[1];
382
- remotePath = parts[2];
383
394
  }
384
- if (!serverName || !localPath || !remotePath) {
385
- context.writer.writeError("Usage: scp upload <server> <local-path> <remote-path>");
395
+ if (!serverName || !useLocalPicker && !localPath || !remotePath) {
396
+ context.writer.writeError(
397
+ useLocalPicker ? "Usage: scp upload --local <server> <remote-path>" : "Usage: scp upload <server> <local-path> <remote-path>"
398
+ );
386
399
  return;
387
400
  }
388
401
  const server = resolveServer(serverName, context);
389
402
  if (!server) return;
390
- const fileService = context.services.get(
403
+ const fileService = context.services.getRequired(
391
404
  cliCore.ICliFileTransferService_TOKEN
392
405
  );
393
406
  if (!fileService) {
394
407
  context.writer.writeError("File transfer service not available.");
395
408
  return;
396
409
  }
397
- const transferService = context.services.get(
410
+ const transferService = context.services.getRequired(
398
411
  IScpTransferService_TOKEN
399
412
  );
400
413
  if (!transferService) {
401
414
  context.writer.writeError("SCP transfer service not available.");
402
415
  return;
403
416
  }
404
- context.spinner?.show(`Reading local file "${localPath}"...`);
405
- try {
406
- const content = await fileService.readFile(localPath);
417
+ let content;
418
+ let filename;
419
+ if (useLocalPicker) {
420
+ const picked = await fileService.uploadFromBrowser();
421
+ if (!picked) {
422
+ context.writer.writeln("Upload cancelled.");
423
+ return;
424
+ }
425
+ content = picked.content;
426
+ filename = picked.name;
427
+ } else {
428
+ context.spinner?.show(`Reading local file "${localPath}"...`);
429
+ content = await fileService.readFile(localPath);
407
430
  if (content === null) {
408
431
  context.spinner?.hide();
409
432
  context.writer.writeError(`Local file not found: ${localPath}`);
410
433
  return;
411
434
  }
412
- const filename = localPath.split("/").pop() || "file";
413
- context.spinner?.show(
414
- `Uploading "${filename}" (${formatBytes(content.length)}) to ${server.name}:${remotePath}...`
415
- );
435
+ filename = localPath.split("/").pop() || "file";
436
+ }
437
+ context.spinner?.show(
438
+ `Uploading "${filename}" (${formatBytes(content.length)}) to ${server.name}:${remotePath}...`
439
+ );
440
+ context.notifier.info(`scp: uploading to ${server.name}`);
441
+ try {
416
442
  await transferService.upload(
417
443
  serverUrl(server),
418
444
  remotePath,
419
445
  content,
420
446
  filename,
421
- server.headers
447
+ cliCore.resolveServerHeaders(context.services, server.name, server.headers)
422
448
  );
423
449
  context.spinner?.hide();
424
450
  context.writer.writeSuccess(
@@ -430,12 +456,13 @@ var CliScpUploadProcessor = class {
430
456
  }
431
457
  }
432
458
  writeDescription(context) {
433
- context.writer.writeln("Upload a local file to a remote server.");
434
- context.writer.writeln("Usage: scp upload <server> <local-path> <remote-path>");
459
+ context.writer.writeln("Upload a file to a remote server.");
460
+ context.writer.writeln("");
461
+ context.writer.writeln("Usage:");
462
+ context.writer.writeln(" scp upload <server> <local-path> <remote-path> Upload from virtual filesystem");
463
+ context.writer.writeln(" scp upload --local <server> <remote-path> Pick from your machine via browser");
435
464
  }
436
465
  };
437
-
438
- // src/lib/processors/cli-scp-rm-processor.ts
439
466
  var CliScpRmProcessor = class {
440
467
  constructor() {
441
468
  this.command = "rm";
@@ -466,7 +493,7 @@ var CliScpRmProcessor = class {
466
493
  const [serverName, path] = parsed;
467
494
  const server = resolveServer(serverName, context);
468
495
  if (!server) return;
469
- const transferService = context.services.get(
496
+ const transferService = context.services.getRequired(
470
497
  IScpTransferService_TOKEN
471
498
  );
472
499
  if (!transferService) {
@@ -478,7 +505,7 @@ var CliScpRmProcessor = class {
478
505
  await transferService.rm(
479
506
  serverUrl(server),
480
507
  path,
481
- server.headers
508
+ cliCore.resolveServerHeaders(context.services, server.name, server.headers)
482
509
  );
483
510
  context.spinner?.hide();
484
511
  context.writer.writeSuccess(`Deleted: ${server.name}:${path}`);
@@ -491,8 +518,6 @@ var CliScpRmProcessor = class {
491
518
  context.writer.writeln("Delete a file on a remote server.");
492
519
  }
493
520
  };
494
-
495
- // src/lib/processors/cli-scp-mkdir-processor.ts
496
521
  var CliScpMkdirProcessor = class {
497
522
  constructor() {
498
523
  this.command = "mkdir";
@@ -523,7 +548,7 @@ var CliScpMkdirProcessor = class {
523
548
  const [serverName, path] = parsed;
524
549
  const server = resolveServer(serverName, context);
525
550
  if (!server) return;
526
- const transferService = context.services.get(
551
+ const transferService = context.services.getRequired(
527
552
  IScpTransferService_TOKEN
528
553
  );
529
554
  if (!transferService) {
@@ -535,7 +560,7 @@ var CliScpMkdirProcessor = class {
535
560
  await transferService.mkdir(
536
561
  serverUrl(server),
537
562
  path,
538
- server.headers
563
+ cliCore.resolveServerHeaders(context.services, server.name, server.headers)
539
564
  );
540
565
  context.spinner?.hide();
541
566
  context.writer.writeSuccess(`Created directory: ${server.name}:${path}`);
@@ -548,8 +573,6 @@ var CliScpMkdirProcessor = class {
548
573
  context.writer.writeln("Create a directory on a remote server.");
549
574
  }
550
575
  };
551
-
552
- // src/lib/processors/cli-scp-stat-processor.ts
553
576
  var CliScpStatProcessor = class {
554
577
  constructor() {
555
578
  this.command = "stat";
@@ -580,7 +603,7 @@ var CliScpStatProcessor = class {
580
603
  const [serverName, path] = parsed;
581
604
  const server = resolveServer(serverName, context);
582
605
  if (!server) return;
583
- const transferService = context.services.get(
606
+ const transferService = context.services.getRequired(
584
607
  IScpTransferService_TOKEN
585
608
  );
586
609
  if (!transferService) {
@@ -592,7 +615,7 @@ var CliScpStatProcessor = class {
592
615
  const stat = await transferService.stat(
593
616
  serverUrl(server),
594
617
  path,
595
- server.headers
618
+ cliCore.resolveServerHeaders(context.services, server.name, server.headers)
596
619
  );
597
620
  context.spinner?.hide();
598
621
  const entries = {
@@ -623,6 +646,7 @@ var CliScpCommandCommandProcessor = class {
623
646
  this.description = "SCP-like file transfer between browser and remote servers";
624
647
  this.author = cliCore.DefaultLibraryAuthor;
625
648
  this.version = LIBRARY_VERSION;
649
+ this.metadata = { icon: "\u{1F4C1}", module: "file management" };
626
650
  this.acceptsRawInput = true;
627
651
  this.processors = [
628
652
  new CliScpLsProcessor(),
@@ -635,33 +659,25 @@ var CliScpCommandCommandProcessor = class {
635
659
  ];
636
660
  }
637
661
  async processCommand(command, context) {
638
- const value = command.value?.trim();
639
- if (value && value.includes(":") && !value.startsWith("-")) {
640
- const colonIdx = value.indexOf(":");
641
- const spaceBeforeColon = value.lastIndexOf(" ", colonIdx);
642
- if (spaceBeforeColon === -1) {
643
- const serverName = value.substring(0, colonIdx);
644
- const rest = value.substring(colonIdx + 1);
645
- const parts2 = rest.trim().split(/\s+/);
646
- const remotePath = parts2[0];
647
- const localPath = parts2[1] || remotePath.split("/").pop() || "download";
662
+ const [first = "", second] = command.positionals ?? [];
663
+ if (first && !first.startsWith("-")) {
664
+ const colonIdx = first.indexOf(":");
665
+ if (colonIdx !== -1) {
666
+ const serverName = first.substring(0, colonIdx);
667
+ const remotePath = first.substring(colonIdx + 1);
668
+ const localPath = second || remotePath.split("/").pop() || "download";
648
669
  if (remotePath) {
649
670
  await this.doDownload(serverName, remotePath, localPath, command, context);
650
671
  return;
651
672
  }
652
673
  }
653
- const parts = value.split(/\s+/);
654
- if (parts.length >= 2) {
655
- const secondPart = parts[1];
656
- if (secondPart.includes(":")) {
657
- const localPath = parts[0];
658
- const srvColonIdx = secondPart.indexOf(":");
659
- const serverName = secondPart.substring(0, srvColonIdx);
660
- const remotePath = secondPart.substring(srvColonIdx + 1);
661
- if (remotePath) {
662
- await this.doUpload(serverName, localPath, remotePath, context);
663
- return;
664
- }
674
+ if (second?.includes(":")) {
675
+ const srvColonIdx = second.indexOf(":");
676
+ const serverName = second.substring(0, srvColonIdx);
677
+ const remotePath = second.substring(srvColonIdx + 1);
678
+ if (remotePath) {
679
+ await this.doUpload(serverName, first, remotePath, context);
680
+ return;
665
681
  }
666
682
  }
667
683
  }
@@ -673,7 +689,7 @@ var CliScpCommandCommandProcessor = class {
673
689
  async doDownload(serverName, remotePath, localPath, command, context) {
674
690
  const server = resolveServer(serverName, context);
675
691
  if (!server) return;
676
- const transferService = context.services.get(
692
+ const transferService = context.services.getRequired(
677
693
  IScpTransferService_TOKEN
678
694
  );
679
695
  if (!transferService) {
@@ -682,12 +698,13 @@ var CliScpCommandCommandProcessor = class {
682
698
  }
683
699
  const useBrowserDownload = command.args?.["save"] === true;
684
700
  context.spinner?.show(`Downloading ${remotePath} from ${server.name}...`);
701
+ context.notifier.info(`scp: downloading from ${server.name}`);
685
702
  try {
686
703
  let lastProgressUpdate = 0;
687
704
  const { content, size } = await transferService.download(
688
705
  serverUrl(server),
689
706
  remotePath,
690
- server.headers,
707
+ cliCore.resolveServerHeaders(context.services, server.name, server.headers),
691
708
  (received, total) => {
692
709
  const now = Date.now();
693
710
  if (now - lastProgressUpdate < 200) return;
@@ -697,15 +714,17 @@ var CliScpCommandCommandProcessor = class {
697
714
  context.spinner?.show(
698
715
  `Downloading ${remotePath}... ${pct}% (${formatBytes(received)}/${formatBytes(total)})`
699
716
  );
717
+ context.notifier.info(`scp: download ${pct}%`);
700
718
  } else {
701
719
  context.spinner?.show(
702
720
  `Downloading ${remotePath}... ${formatBytes(received)}`
703
721
  );
722
+ context.notifier.info(`scp: download ${formatBytes(received)}`);
704
723
  }
705
724
  }
706
725
  );
707
726
  context.spinner?.hide();
708
- const fileService = context.services.get(
727
+ const fileService = context.services.getRequired(
709
728
  cliCore.ICliFileTransferService_TOKEN
710
729
  );
711
730
  if (!fileService) {
@@ -731,14 +750,14 @@ var CliScpCommandCommandProcessor = class {
731
750
  async doUpload(serverName, localPath, remotePath, context) {
732
751
  const server = resolveServer(serverName, context);
733
752
  if (!server) return;
734
- const fileService = context.services.get(
753
+ const fileService = context.services.getRequired(
735
754
  cliCore.ICliFileTransferService_TOKEN
736
755
  );
737
756
  if (!fileService) {
738
757
  context.writer.writeError("File transfer service not available.");
739
758
  return;
740
759
  }
741
- const transferService = context.services.get(
760
+ const transferService = context.services.getRequired(
742
761
  IScpTransferService_TOKEN
743
762
  );
744
763
  if (!transferService) {
@@ -746,6 +765,7 @@ var CliScpCommandCommandProcessor = class {
746
765
  return;
747
766
  }
748
767
  context.spinner?.show(`Reading local file "${localPath}"...`);
768
+ context.notifier.info(`scp: reading ${localPath}`);
749
769
  try {
750
770
  const content = await fileService.readFile(localPath);
751
771
  if (content === null) {
@@ -757,12 +777,13 @@ var CliScpCommandCommandProcessor = class {
757
777
  context.spinner?.show(
758
778
  `Uploading "${filename}" (${formatBytes(content.length)}) to ${server.name}:${remotePath}...`
759
779
  );
780
+ context.notifier.info(`scp: uploading to ${server.name}`);
760
781
  await transferService.upload(
761
782
  serverUrl(server),
762
783
  remotePath,
763
784
  content,
764
785
  filename,
765
- server.headers
786
+ cliCore.resolveServerHeaders(context.services, server.name, server.headers)
766
787
  );
767
788
  context.spinner?.hide();
768
789
  context.writer.writeSuccess(
@@ -774,32 +795,30 @@ var CliScpCommandCommandProcessor = class {
774
795
  }
775
796
  }
776
797
  };
777
-
778
- // src/lib/services/scp-transfer.service.ts
779
798
  var ScpTransferService = class {
780
799
  async ls(serverUrl2, path, headers) {
781
- const res = await this._fetch(`${serverUrl2}/api/cli/fs/ls?path=${encodeURIComponent(path)}`, {
782
- headers
800
+ const res = await this._fetch(`${serverUrl2}/api/qcli/fs/ls?path=${encodeURIComponent(path)}`, {
801
+ headers: cliCore.resolveHeaders(headers)
783
802
  });
784
803
  const data = await res.json();
785
804
  return data.entries;
786
805
  }
787
806
  async cat(serverUrl2, path, headers) {
788
- const res = await this._fetch(`${serverUrl2}/api/cli/fs/cat?path=${encodeURIComponent(path)}`, {
789
- headers
807
+ const res = await this._fetch(`${serverUrl2}/api/qcli/fs/cat?path=${encodeURIComponent(path)}`, {
808
+ headers: cliCore.resolveHeaders(headers)
790
809
  });
791
810
  const data = await res.json();
792
811
  return data.content;
793
812
  }
794
813
  async stat(serverUrl2, path, headers) {
795
- const res = await this._fetch(`${serverUrl2}/api/cli/fs/stat?path=${encodeURIComponent(path)}`, {
796
- headers
814
+ const res = await this._fetch(`${serverUrl2}/api/qcli/fs/stat?path=${encodeURIComponent(path)}`, {
815
+ headers: cliCore.resolveHeaders(headers)
797
816
  });
798
817
  return await res.json();
799
818
  }
800
819
  async download(serverUrl2, path, headers, onProgress, signal) {
801
- const res = await this._fetch(`${serverUrl2}/api/cli/fs/download?path=${encodeURIComponent(path)}`, {
802
- headers,
820
+ const res = await this._fetch(`${serverUrl2}/api/qcli/fs/download?path=${encodeURIComponent(path)}`, {
821
+ headers: cliCore.resolveHeaders(headers),
803
822
  signal
804
823
  });
805
824
  const contentLength = parseInt(res.headers.get("content-length") || "0", 10);
@@ -832,23 +851,23 @@ var ScpTransferService = class {
832
851
  const formData = new FormData();
833
852
  formData.append("path", remotePath);
834
853
  formData.append("file", new Blob([content]), filename);
835
- await this._fetch(`${serverUrl2}/api/cli/fs/upload`, {
854
+ await this._fetch(`${serverUrl2}/api/qcli/fs/upload`, {
836
855
  method: "POST",
837
856
  body: formData,
838
- headers
857
+ headers: cliCore.resolveHeaders(headers)
839
858
  });
840
859
  }
841
860
  async mkdir(serverUrl2, path, headers) {
842
- await this._fetch(`${serverUrl2}/api/cli/fs/mkdir`, {
861
+ await this._fetch(`${serverUrl2}/api/qcli/fs/mkdir`, {
843
862
  method: "POST",
844
- headers: { "Content-Type": "application/json", ...headers },
863
+ headers: { "Content-Type": "application/json", ...cliCore.resolveHeaders(headers) },
845
864
  body: JSON.stringify({ path })
846
865
  });
847
866
  }
848
867
  async rm(serverUrl2, path, headers) {
849
- await this._fetch(`${serverUrl2}/api/cli/fs/rm?path=${encodeURIComponent(path)}`, {
868
+ await this._fetch(`${serverUrl2}/api/qcli/fs/rm?path=${encodeURIComponent(path)}`, {
850
869
  method: "DELETE",
851
- headers
870
+ headers: cliCore.resolveHeaders(headers)
852
871
  });
853
872
  }
854
873
  async _fetch(url, init) {