aspera-cli 4.27.5 → 4.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +160 -4
- data/CONTRIBUTING.md +4 -2
- data/README.md +1 -1
- data/bin/asession +1 -1
- data/docs/README.md +1086 -331
- data/docs/test-mcp-with-ai.md +5 -3
- data/lib/aspera/agent/direct.rb +15 -4
- data/lib/aspera/agent/factory.rb +2 -1
- data/lib/aspera/agent/node.rb +1 -1
- data/lib/aspera/api/cos_node.rb +1 -1
- data/lib/aspera/api/faspex.rb +1 -1
- data/lib/aspera/api/node.rb +6 -2
- data/lib/aspera/ascp/installation.rb +47 -11
- data/lib/aspera/ascp/management.rb +89 -43
- data/lib/aspera/cli/ascp_actions.rb +5 -19
- data/lib/aspera/cli/bootstrapper.rb +1 -2
- data/lib/aspera/cli/command_registry.rb +43 -3
- data/lib/aspera/cli/command_spec.rb +3 -0
- data/lib/aspera/cli/completion/ascli.bash +39 -5
- data/lib/aspera/cli/completion/ascli.fish +16 -8
- data/lib/aspera/cli/completion/ascli.ps1 +41 -0
- data/lib/aspera/cli/completion/ascli.zsh +20 -4
- data/lib/aspera/cli/completion_actions.rb +360 -0
- data/lib/aspera/cli/error.rb +42 -0
- data/lib/aspera/cli/extended_value.rb +30 -5
- data/lib/aspera/cli/formatter.rb +118 -56
- data/lib/aspera/cli/hints.rb +0 -1
- data/lib/aspera/cli/http.rb +6 -5
- data/lib/aspera/cli/info.rb +10 -4
- data/lib/aspera/cli/mailer.rb +1 -1
- data/lib/aspera/cli/mcp/http_servlet.rb +156 -0
- data/lib/aspera/cli/mcp/secrets.rb +143 -0
- data/lib/aspera/cli/mcp/tool.rb +231 -0
- data/lib/aspera/cli/option_value.rb +9 -1
- data/lib/aspera/cli/options.schema.yaml +390 -39
- data/lib/aspera/cli/parser.rb +14 -5
- data/lib/aspera/cli/plugins/aoc.rb +8 -11
- data/lib/aspera/cli/plugins/base.rb +36 -15
- data/lib/aspera/cli/plugins/config.rb +15 -44
- data/lib/aspera/cli/plugins/console.rb +3 -1
- data/lib/aspera/cli/plugins/factory.rb +1 -1
- data/lib/aspera/cli/plugins/faspex5.rb +9 -19
- data/lib/aspera/cli/plugins/faspio.rb +36 -5
- data/lib/aspera/cli/plugins/httpgw.rb +1 -0
- data/lib/aspera/cli/plugins/mcp.rb +177 -118
- data/lib/aspera/cli/plugins/node.rb +14 -8
- data/lib/aspera/cli/plugins/orchestrator.rb +351 -38
- data/lib/aspera/cli/plugins/server.rb +3 -1
- data/lib/aspera/cli/plugins/shares.rb +205 -35
- data/lib/aspera/cli/preset_actions.rb +15 -7
- data/lib/aspera/cli/preset_manager.rb +24 -2
- data/lib/aspera/cli/prompt.rb +3 -1
- data/lib/aspera/cli/result.rb +17 -4
- data/lib/aspera/cli/runner.rb +133 -43
- data/lib/aspera/cli/security.rb +134 -0
- data/lib/aspera/cli/table_fitter.rb +116 -0
- data/lib/aspera/cli/terminal_formatter.rb +23 -34
- data/lib/aspera/cli/transfer_agent.rb +4 -1
- data/lib/aspera/cli/vault_manager.rb +6 -5
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/cli/web_secret.html.erb +61 -0
- data/lib/aspera/cli/web_secret.rb +220 -0
- data/lib/aspera/cli/wizard.rb +19 -9
- data/lib/aspera/command_line_builder.rb +26 -0
- data/lib/aspera/data_repository.rb +38 -24
- data/lib/aspera/duration.rb +42 -0
- data/lib/aspera/environment.rb +88 -24
- data/lib/aspera/exec_spec.rb +6 -5
- data/lib/aspera/faspex_gw.rb +98 -32
- data/lib/aspera/faspex_postproc.rb +187 -44
- data/lib/aspera/formatter_interface.rb +0 -1
- data/lib/aspera/id_generator.rb +2 -1
- data/lib/aspera/json_rpc/client.rb +51 -32
- data/lib/aspera/json_rpc/version.rb +1 -0
- data/lib/aspera/keychain/base.rb +5 -0
- data/lib/aspera/keychain/encrypted_hash.rb +6 -2
- data/lib/aspera/keychain/factory.rb +2 -3
- data/lib/aspera/keychain/hashicorp_vault.rb +7 -4
- data/lib/aspera/keychain/macos_security.rb +119 -13
- data/lib/aspera/keychain/one_password_api.rb +8 -3
- data/lib/aspera/keychain/one_password_base.rb +14 -9
- data/lib/aspera/keychain/one_password_cli.rb +4 -2
- data/lib/aspera/log.rb +3 -6
- data/lib/aspera/markdown.rb +152 -115
- data/lib/aspera/mime.rb +6 -0
- data/lib/aspera/nagios.rb +3 -1
- data/lib/aspera/node_emulator.rb +98 -101
- data/lib/aspera/oauth/{base.rb → client/base.rb} +5 -4
- data/lib/aspera/oauth/{boot.rb → client/boot.rb} +3 -2
- data/lib/aspera/oauth/{factory.rb → client/factory.rb} +7 -0
- data/lib/aspera/oauth/{generic.rb → client/generic.rb} +1 -1
- data/lib/aspera/oauth/{json_credentials.rb → client/json_credentials.rb} +1 -1
- data/lib/aspera/oauth/{jwt.rb → client/jwt.rb} +1 -1
- data/lib/aspera/oauth/{url_json.rb → client/url_json.rb} +1 -1
- data/lib/aspera/oauth/{web.rb → client/web.rb} +2 -2
- data/lib/aspera/oauth/server/authorize.html.erb +34 -0
- data/lib/aspera/oauth/server/pkce.rb +426 -0
- data/lib/aspera/orchestrator_workflow_checker.rb +561 -0
- data/lib/aspera/preview/terminal.rb +3 -2
- data/lib/aspera/rainbow.rb +27 -1
- data/lib/aspera/rest/aspera_errors.rb +51 -59
- data/lib/aspera/rest/client.rb +21 -14
- data/lib/aspera/rest/error_analyzer.rb +9 -0
- data/lib/aspera/rest/list.rb +6 -6
- data/lib/aspera/rest/util.rb +7 -1
- data/lib/aspera/rest.rb +0 -1
- data/lib/aspera/schema/IBM Aspera Faspex API-5.0-enhanced.yaml +0 -2
- data/lib/aspera/schema/IBM Aspera Orchestrator API-v1-enhanced.yaml +4001 -0
- data/lib/aspera/schema/IBM Aspera faspio Gateway API-1.0.0-enhanced.yaml +1097 -0
- data/lib/aspera/schema/IBM Aspera on Cloud Automation API-1.0.5-enhanced.yaml +35 -35
- data/lib/aspera/schema/IBM_Aspera_Shares.yaml +819 -7
- data/lib/aspera/schema/documentation.rb +50 -78
- data/lib/aspera/schema/reader.rb +39 -11
- data/lib/aspera/schema/registry.rb +8 -2
- data/lib/aspera/secret_hider.rb +94 -15
- data/lib/aspera/secret_strength.rb +114 -0
- data/lib/aspera/servlet_helpers.rb +111 -0
- data/lib/aspera/sync/args.schema.yaml +3 -1
- data/lib/aspera/sync/conf.schema.yaml +16 -6
- data/lib/aspera/sync/operations.rb +21 -1
- data/lib/aspera/temp_file_manager.rb +79 -20
- data/lib/aspera/transfer/parameters.rb +5 -0
- data/lib/aspera/transfer/spec.rb +52 -12
- data/lib/aspera/transfer/spec.schema.yaml +8 -5
- data/lib/aspera/web_auth/index.html.erb +16 -0
- data/lib/aspera/web_auth/server.rb +18 -10
- data/lib/aspera/web_page.html.erb +262 -0
- data/lib/aspera/web_page.rb +61 -0
- data/lib/aspera/web_server_simple.rb +76 -10
- data.tar.gz.sig +0 -0
- metadata +47 -32
- metadata.gz.sig +0 -0
- data/lib/aspera/cli/mcp_tool.rb +0 -189
- data/lib/aspera/oauth.rb +0 -9
- data/lib/aspera/schema/IBM Aspera Orchestrator API-v1.yaml +0 -1784
- data/lib/aspera/schema/IBM Aspera faspio Gateway API-1.0.0.yaml +0 -249
- data/lib/aspera/web_auth/index.html +0 -147
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: aspera-cli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.
|
|
4
|
+
version: 4.28.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Laurent Martin
|
|
@@ -39,19 +39,19 @@ cert_chain:
|
|
|
39
39
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
40
40
|
dependencies:
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
|
-
name:
|
|
42
|
+
name: base64
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
44
44
|
requirements:
|
|
45
45
|
- - "~>"
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: '3
|
|
47
|
+
version: '0.3'
|
|
48
48
|
type: :runtime
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
52
|
- - "~>"
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: '3
|
|
54
|
+
version: '0.3'
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
56
|
name: chunky_png
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -94,6 +94,20 @@ dependencies:
|
|
|
94
94
|
- - "~>"
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
96
|
version: '2.0'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: jmespath
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - "~>"
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '1.6'
|
|
104
|
+
type: :runtime
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - "~>"
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '1.6'
|
|
97
111
|
- !ruby/object:Gem::Dependency
|
|
98
112
|
name: json_schemer
|
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -290,20 +304,6 @@ dependencies:
|
|
|
290
304
|
- - "~>"
|
|
291
305
|
- !ruby/object:Gem::Version
|
|
292
306
|
version: '1.2'
|
|
293
|
-
- !ruby/object:Gem::Dependency
|
|
294
|
-
name: word_wrap
|
|
295
|
-
requirement: !ruby/object:Gem::Requirement
|
|
296
|
-
requirements:
|
|
297
|
-
- - "~>"
|
|
298
|
-
- !ruby/object:Gem::Version
|
|
299
|
-
version: '1.0'
|
|
300
|
-
type: :runtime
|
|
301
|
-
prerelease: false
|
|
302
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
303
|
-
requirements:
|
|
304
|
-
- - "~>"
|
|
305
|
-
- !ruby/object:Gem::Version
|
|
306
|
-
version: '1.0'
|
|
307
307
|
- !ruby/object:Gem::Dependency
|
|
308
308
|
name: xml-simple
|
|
309
309
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -365,7 +365,9 @@ files:
|
|
|
365
365
|
- lib/aspera/cli/command_spec.rb
|
|
366
366
|
- lib/aspera/cli/completion/ascli.bash
|
|
367
367
|
- lib/aspera/cli/completion/ascli.fish
|
|
368
|
+
- lib/aspera/cli/completion/ascli.ps1
|
|
368
369
|
- lib/aspera/cli/completion/ascli.zsh
|
|
370
|
+
- lib/aspera/cli/completion_actions.rb
|
|
369
371
|
- lib/aspera/cli/context.rb
|
|
370
372
|
- lib/aspera/cli/deprecation.rb
|
|
371
373
|
- lib/aspera/cli/error.rb
|
|
@@ -376,7 +378,9 @@ files:
|
|
|
376
378
|
- lib/aspera/cli/http.rb
|
|
377
379
|
- lib/aspera/cli/info.rb
|
|
378
380
|
- lib/aspera/cli/mailer.rb
|
|
379
|
-
- lib/aspera/cli/
|
|
381
|
+
- lib/aspera/cli/mcp/http_servlet.rb
|
|
382
|
+
- lib/aspera/cli/mcp/secrets.rb
|
|
383
|
+
- lib/aspera/cli/mcp/tool.rb
|
|
380
384
|
- lib/aspera/cli/option_declarator.rb
|
|
381
385
|
- lib/aspera/cli/option_registry.rb
|
|
382
386
|
- lib/aspera/cli/option_types.rb
|
|
@@ -408,14 +412,18 @@ files:
|
|
|
408
412
|
- lib/aspera/cli/result.rb
|
|
409
413
|
- lib/aspera/cli/runner.rb
|
|
410
414
|
- lib/aspera/cli/secret_finder.rb
|
|
415
|
+
- lib/aspera/cli/security.rb
|
|
411
416
|
- lib/aspera/cli/special_values.rb
|
|
412
417
|
- lib/aspera/cli/sync_actions.rb
|
|
418
|
+
- lib/aspera/cli/table_fitter.rb
|
|
413
419
|
- lib/aspera/cli/terminal_formatter.rb
|
|
414
420
|
- lib/aspera/cli/transfer_actions.rb
|
|
415
421
|
- lib/aspera/cli/transfer_agent.rb
|
|
416
422
|
- lib/aspera/cli/transfer_progress.rb
|
|
417
423
|
- lib/aspera/cli/vault_manager.rb
|
|
418
424
|
- lib/aspera/cli/version.rb
|
|
425
|
+
- lib/aspera/cli/web_secret.html.erb
|
|
426
|
+
- lib/aspera/cli/web_secret.rb
|
|
419
427
|
- lib/aspera/cli/wizard.rb
|
|
420
428
|
- lib/aspera/command_line_builder.rb
|
|
421
429
|
- lib/aspera/command_line_converter.rb
|
|
@@ -428,6 +436,7 @@ files:
|
|
|
428
436
|
- lib/aspera/data/6
|
|
429
437
|
- lib/aspera/data_repository.rb
|
|
430
438
|
- lib/aspera/dot_container.rb
|
|
439
|
+
- lib/aspera/duration.rb
|
|
431
440
|
- lib/aspera/environment.rb
|
|
432
441
|
- lib/aspera/exec_spec.rb
|
|
433
442
|
- lib/aspera/faspex_gw.rb
|
|
@@ -453,15 +462,17 @@ files:
|
|
|
453
462
|
- lib/aspera/mime.rb
|
|
454
463
|
- lib/aspera/nagios.rb
|
|
455
464
|
- lib/aspera/node_emulator.rb
|
|
456
|
-
- lib/aspera/oauth.rb
|
|
457
|
-
- lib/aspera/oauth/
|
|
458
|
-
- lib/aspera/oauth/
|
|
459
|
-
- lib/aspera/oauth/
|
|
460
|
-
- lib/aspera/oauth/
|
|
461
|
-
- lib/aspera/oauth/
|
|
462
|
-
- lib/aspera/oauth/
|
|
463
|
-
- lib/aspera/oauth/
|
|
464
|
-
- lib/aspera/oauth/
|
|
465
|
+
- lib/aspera/oauth/client/base.rb
|
|
466
|
+
- lib/aspera/oauth/client/boot.rb
|
|
467
|
+
- lib/aspera/oauth/client/factory.rb
|
|
468
|
+
- lib/aspera/oauth/client/generic.rb
|
|
469
|
+
- lib/aspera/oauth/client/json_credentials.rb
|
|
470
|
+
- lib/aspera/oauth/client/jwt.rb
|
|
471
|
+
- lib/aspera/oauth/client/url_json.rb
|
|
472
|
+
- lib/aspera/oauth/client/web.rb
|
|
473
|
+
- lib/aspera/oauth/server/authorize.html.erb
|
|
474
|
+
- lib/aspera/oauth/server/pkce.rb
|
|
475
|
+
- lib/aspera/orchestrator_workflow_checker.rb
|
|
465
476
|
- lib/aspera/persistency_action_once.rb
|
|
466
477
|
- lib/aspera/persistency_folder.rb
|
|
467
478
|
- lib/aspera/preview/file_types.rb
|
|
@@ -489,8 +500,8 @@ files:
|
|
|
489
500
|
- lib/aspera/schema/IBM Aspera Console-enhanced.yaml
|
|
490
501
|
- lib/aspera/schema/IBM Aspera Faspex API-5.0-enhanced.yaml
|
|
491
502
|
- lib/aspera/schema/IBM Aspera Node API-4.4.6.yaml
|
|
492
|
-
- lib/aspera/schema/IBM Aspera Orchestrator API-v1.yaml
|
|
493
|
-
- lib/aspera/schema/IBM Aspera faspio Gateway API-1.0.0.yaml
|
|
503
|
+
- lib/aspera/schema/IBM Aspera Orchestrator API-v1-enhanced.yaml
|
|
504
|
+
- lib/aspera/schema/IBM Aspera faspio Gateway API-1.0.0-enhanced.yaml
|
|
494
505
|
- lib/aspera/schema/IBM Aspera on Cloud API-0.2.6-enhanced.yaml
|
|
495
506
|
- lib/aspera/schema/IBM Aspera on Cloud Automation API-1.0.5-enhanced.yaml
|
|
496
507
|
- lib/aspera/schema/IBM_Aspera_Shares.yaml
|
|
@@ -500,6 +511,8 @@ files:
|
|
|
500
511
|
- lib/aspera/schema/registry.rb
|
|
501
512
|
- lib/aspera/schema/validator.rb
|
|
502
513
|
- lib/aspera/secret_hider.rb
|
|
514
|
+
- lib/aspera/secret_strength.rb
|
|
515
|
+
- lib/aspera/servlet_helpers.rb
|
|
503
516
|
- lib/aspera/ssh.rb
|
|
504
517
|
- lib/aspera/ssl.rb
|
|
505
518
|
- lib/aspera/string_ext.rb
|
|
@@ -517,8 +530,10 @@ files:
|
|
|
517
530
|
- lib/aspera/transfer/spec.rb
|
|
518
531
|
- lib/aspera/transfer/spec.schema.yaml
|
|
519
532
|
- lib/aspera/uri_reader.rb
|
|
520
|
-
- lib/aspera/web_auth/index.html
|
|
533
|
+
- lib/aspera/web_auth/index.html.erb
|
|
521
534
|
- lib/aspera/web_auth/server.rb
|
|
535
|
+
- lib/aspera/web_page.html.erb
|
|
536
|
+
- lib/aspera/web_page.rb
|
|
522
537
|
- lib/aspera/web_server_simple.rb
|
|
523
538
|
- lib/aspera/yaml.rb
|
|
524
539
|
- lib/transferd_pb.rb
|
|
@@ -540,7 +555,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
540
555
|
requirements:
|
|
541
556
|
- - ">="
|
|
542
557
|
- !ruby/object:Gem::Version
|
|
543
|
-
version: '3.
|
|
558
|
+
version: '3.2'
|
|
544
559
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
545
560
|
requirements:
|
|
546
561
|
- - ">="
|
metadata.gz.sig
CHANGED
|
Binary file
|
data/lib/aspera/cli/mcp_tool.rb
DELETED
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# cspell:ignore ascli
|
|
4
|
-
|
|
5
|
-
require 'json'
|
|
6
|
-
require 'aspera/log'
|
|
7
|
-
require 'aspera/secret_hider'
|
|
8
|
-
require 'aspera/cli/runner'
|
|
9
|
-
require 'aspera/cli/error'
|
|
10
|
-
require 'aspera/schema/reader'
|
|
11
|
-
require 'aspera/schema/registry'
|
|
12
|
-
unless defined?(MCP::Tool)
|
|
13
|
-
begin
|
|
14
|
-
require 'mcp'
|
|
15
|
-
rescue LoadError
|
|
16
|
-
raise Cli::Error, "The 'mcp' and 'rack' gems are required. Install them with: gem install mcp rack"
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
module Aspera
|
|
21
|
-
module Cli
|
|
22
|
-
# MCP Tool: executes an ascli command in-process.
|
|
23
|
-
class McpTool < MCP::Tool
|
|
24
|
-
# Default maximum byte size of the JSON text content returned for list results.
|
|
25
|
-
# Items are appended whole until the limit is reached; the full list is always
|
|
26
|
-
# available in structuredContent.
|
|
27
|
-
DEFAULT_MAX_TEXT_BYTES = 100_000
|
|
28
|
-
# Default extra arguments automatically prepended to every ascli call.
|
|
29
|
-
# Keeps the AI from having to remember mandatory flags on every invocation.
|
|
30
|
-
DEFAULT_EXTRA_ARGS = ['--interactive=no', '--transfer.asynchronous=true'].freeze
|
|
31
|
-
|
|
32
|
-
tool_name 'execute_ascli_command'
|
|
33
|
-
|
|
34
|
-
description <<~DESC.strip
|
|
35
|
-
Execute any ascli (Aspera CLI) command in-process and return its result.
|
|
36
|
-
|
|
37
|
-
SYNTAX
|
|
38
|
-
args is a JSON array of strings mirroring the CLI command line.
|
|
39
|
-
Element 0 : plugin name (aoc, faspex5, node, server, config, …).
|
|
40
|
-
Elements 1+: sub-commands, positional arguments, and --option=value flags in any order.
|
|
41
|
-
Structured values use an extended-value prefix on the relevant element:
|
|
42
|
-
"@json:{...}" — inline JSON object or array (preferred: no shell quoting)
|
|
43
|
-
"@preset:name" — expand a saved preset
|
|
44
|
-
"@env:VAR" — read value from environment variable
|
|
45
|
-
"@file:/path" — read value from a file
|
|
46
|
-
|
|
47
|
-
AUTOMATIC FLAGS
|
|
48
|
-
The server prepends extra_args to every call (default: #{DEFAULT_EXTRA_ARGS.join(' ')}).
|
|
49
|
-
Do NOT repeat them. To override one, include it in args: later values take precedence.
|
|
50
|
-
Commands never prompt: if credentials are missing, an error is returned; report it and stop.
|
|
51
|
-
|
|
52
|
-
DISCOVERY — never guess command or field names from training data
|
|
53
|
-
Step 1 — commands of a plugin, with syntax:
|
|
54
|
-
["config", "commands", "<plugin>"]
|
|
55
|
-
Returns { syntax, description } for every command of that plugin.
|
|
56
|
-
Notation: <arg> mandatory, [<arg>] optional, <a|b> enum, <arg...> variadic, <arg:Hash> typed.
|
|
57
|
-
A line ending with <command...> and "(see: <plugin> <path>)" provides the commands of that path:
|
|
58
|
-
list them with ["config", "commands", "<plugin>", "<command>", ...] (command words only).
|
|
59
|
-
Omit <plugin> to list the commands of all plugins (large).
|
|
60
|
-
Step 2 — schema of a Hash argument (shown <name:Hash>), MANDATORY before calling such a command:
|
|
61
|
-
["<plugin>", "<cmd>", ..., "help"]
|
|
62
|
-
Put the literal "help" in place of the Hash argument. Returns field names, types,
|
|
63
|
-
required flags and descriptions. Never infer fields from server error messages.
|
|
64
|
-
Step 2b — filter parameters of a list command:
|
|
65
|
-
["<plugin>", "<cmd>", ..., "--query=help"]
|
|
66
|
-
Step 3 — all --flags of a plugin, with allowed values:
|
|
67
|
-
["config", "options", "<plugin>"]
|
|
68
|
-
Documentation:
|
|
69
|
-
["config", "documentation", "toc"] → { level, title, anchor } per heading
|
|
70
|
-
["config", "documentation", "local", "<anchor>"] → one README section
|
|
71
|
-
Presets (saved credentials):
|
|
72
|
-
["config", "preset", "overview"]
|
|
73
|
-
|
|
74
|
-
RESULT FORMAT
|
|
75
|
-
Structured data is always in structuredContent (a JSON object; lists are under "items").
|
|
76
|
-
For lists, text content is limited to #{DEFAULT_MAX_TEXT_BYTES} bytes (whole items only);
|
|
77
|
-
when truncated, a WARNING line gives the real total. Read structuredContent.items for
|
|
78
|
-
the full dataset — never report counts or search results from a truncated text block.
|
|
79
|
-
|
|
80
|
-
FILE LIST FOR TRANSFERS
|
|
81
|
-
For all transfers (upload, download, package send, …), append source paths at the
|
|
82
|
-
end of args — no --sources flag needed.
|
|
83
|
-
|
|
84
|
-
EXAMPLES
|
|
85
|
-
["config", "commands", "aoc"]
|
|
86
|
-
["aoc", "admin", "user", "create", "help"]
|
|
87
|
-
["config", "options", "aoc"]
|
|
88
|
-
["config", "documentation", "local", "leveraging-ai-assistance"]
|
|
89
|
-
["aoc", "--preset=myaoc", "packages", "list"]
|
|
90
|
-
["aoc", "--preset=myaoc", "admin", "user", "create", '@json:{"email":"a@b.com","name":"Alice"}']
|
|
91
|
-
["aoc", "--preset=myaoc", "packages", "send",
|
|
92
|
-
'@json:{"name":"pkg","recipients":["user@example.com"]}', "/local/a.txt", "/local/b.txt"]
|
|
93
|
-
["server", "--preset=myserver", "upload", "--to-folder=/uploads", "/local/a.txt"]
|
|
94
|
-
["server", "browse", "/", "--url=ssh://host:33001", "--username=user", "--password=secret"]
|
|
95
|
-
DESC
|
|
96
|
-
|
|
97
|
-
input_schema(
|
|
98
|
-
properties: {
|
|
99
|
-
args: {
|
|
100
|
-
type: 'array',
|
|
101
|
-
items: {type: 'string'},
|
|
102
|
-
minItems: 1,
|
|
103
|
-
description: 'ascli arguments: first element is the plugin name, followed by action and --option=value flags'
|
|
104
|
-
}
|
|
105
|
-
},
|
|
106
|
-
required: ['args']
|
|
107
|
-
)
|
|
108
|
-
|
|
109
|
-
class << self
|
|
110
|
-
attr_accessor :max_text_bytes, :extra_args
|
|
111
|
-
|
|
112
|
-
def call(args:, server_context: nil)
|
|
113
|
-
effective_args = Array(extra_args || DEFAULT_EXTRA_ARGS) + args
|
|
114
|
-
Log.dump(:mcp_execute, effective_args)
|
|
115
|
-
runner = Runner.new(effective_args)
|
|
116
|
-
result = runner.run_with_result
|
|
117
|
-
case result
|
|
118
|
-
when Result::Nothing, Result::Empty, NilClass
|
|
119
|
-
MCP::Tool::Response.new([{type: 'text', text: ''}])
|
|
120
|
-
when Result::SingleObject, Result::ObjectList, Result::ValueList
|
|
121
|
-
# Secrets never reach the AI client, whatever the output format requested in args.
|
|
122
|
-
SecretHider.instance.deep_remove_secret(result.data)
|
|
123
|
-
# Apply --select filter in place (affects both text and structuredContent).
|
|
124
|
-
runner.context.formatter.filter_columns_on_select(result.data) if result.data.is_a?(Array)
|
|
125
|
-
# MCP spec requires structuredContent to be a JSON object (not an array).
|
|
126
|
-
structured = result.data.is_a?(Array) ? {items: result.data} : result.data
|
|
127
|
-
content = if result.data.is_a?(Array)
|
|
128
|
-
text_limit = max_text_bytes || DEFAULT_MAX_TEXT_BYTES
|
|
129
|
-
truncated_items = truncate_items_by_bytes(result.data, text_limit)
|
|
130
|
-
total = result.data.size
|
|
131
|
-
if truncated_items.size < total
|
|
132
|
-
[
|
|
133
|
-
{type: 'text', text: JSON.generate(truncated_items)},
|
|
134
|
-
{type: 'text', text: "WARNING: result truncated to #{truncated_items.size} of #{total} items. Full dataset available in structuredContent."}
|
|
135
|
-
]
|
|
136
|
-
else
|
|
137
|
-
[{type: 'text', text: JSON.generate(result.data)}]
|
|
138
|
-
end
|
|
139
|
-
else
|
|
140
|
-
[{type: 'text', text: JSON.generate(result.data)}]
|
|
141
|
-
end
|
|
142
|
-
MCP::Tool::Response.new(content, structured_content: structured)
|
|
143
|
-
else
|
|
144
|
-
MCP::Tool::Response.new([{type: 'text', text: SecretHider.instance.hide_secrets_in_string(result.data.to_s, all: true)}])
|
|
145
|
-
end
|
|
146
|
-
rescue Cli::SchemaRequest => e
|
|
147
|
-
schema_path = e.path
|
|
148
|
-
if schema_path.nil?
|
|
149
|
-
MCP::Tool::Response.new([{type: 'text', text: "#{e.class}: #{e.message} (no schema available)"}], error: true)
|
|
150
|
-
else
|
|
151
|
-
rows = schema_to_rows(Schema::Registry.instance.reader(schema_path))
|
|
152
|
-
structured = {items: rows}
|
|
153
|
-
MCP::Tool::Response.new([{type: 'text', text: JSON.generate(rows)}], structured_content: structured)
|
|
154
|
-
end
|
|
155
|
-
rescue SystemExit => e
|
|
156
|
-
MCP::Tool::Response.new([{type: 'text', text: "exited with status #{e.status}"}], error: !e.status.zero?)
|
|
157
|
-
rescue => e
|
|
158
|
-
MCP::Tool::Response.new([{type: 'text', text: "#{e.class}: #{dedupe_lines(e.message)}"}], error: true)
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
# Delegate to Schema::Reader#to_rows — semantic fields, no ANSI, MCP/JSON-ready.
|
|
162
|
-
def schema_to_rows(reader)
|
|
163
|
-
reader.to_rows
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
# Collapse consecutive duplicate lines in a multi-line message.
|
|
167
|
-
# Each run of identical lines is replaced by one line + "(×N)" suffix when N > 1.
|
|
168
|
-
def dedupe_lines(msg)
|
|
169
|
-
return msg unless msg.include?("\n")
|
|
170
|
-
msg.split("\n").chunk_while { |a, b| a == b }.map do |group|
|
|
171
|
-
group.size > 1 ? "#{group.first} (x#{group.size})" : group.first
|
|
172
|
-
end.join("\n")
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
# Returns the largest prefix of `items` whose JSON serialization fits within `max_bytes`.
|
|
176
|
-
# Items are appended whole — no item is ever split mid-JSON.
|
|
177
|
-
def truncate_items_by_bytes(items, max_bytes)
|
|
178
|
-
buf = +''
|
|
179
|
-
items.each_with_index do |item, i|
|
|
180
|
-
fragment = (i.zero? ? '[' : ',') + JSON.generate(item)
|
|
181
|
-
break if buf.bytesize + fragment.bytesize + 1 > max_bytes # +1 for closing ']'
|
|
182
|
-
buf << fragment
|
|
183
|
-
end
|
|
184
|
-
buf.empty? ? [] : JSON.parse("#{buf}]")
|
|
185
|
-
end
|
|
186
|
-
end
|
|
187
|
-
end
|
|
188
|
-
end
|
|
189
|
-
end
|
data/lib/aspera/oauth.rb
DELETED