stpr 1.0.9 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +159 -0
- package/dist/cli.js +166 -100
- package/package.json +3 -2
package/README.md
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# stpr — Stepper Skills CLI
|
|
2
|
+
|
|
3
|
+
Skill Sets are a Stepper feature that let you bundle integration actions into curated, authenticated toolkits — and expose them to AI agents, CLIs, and any MCP-compatible client.
|
|
4
|
+
|
|
5
|
+
`stpr` is a command-line interface for interacting with [Stepper](https://stepper.io) Skill Sets. Discover, inspect, and execute integration actions directly from your terminal. This is perfect for OpenClaw or agents that can interact with a CLI, or for developers who want to use skills in their own scripts.
|
|
6
|
+
|
|
7
|
+
If you prefer, you can directly use the Stepper MCP server at `https://mcp.stepper.io/skill-sets/mcp`instead of the CLI.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install -g stpr
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Authentication
|
|
16
|
+
|
|
17
|
+
The CLI supports three authentication methods:
|
|
18
|
+
|
|
19
|
+
### OAuth Login (recommended)
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
stpr login
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Opens your browser to authenticate and select a Skill Set. Credentials are saved to `~/.config/stepper-skillsets/config.json` and automatically refreshed when they expire.
|
|
26
|
+
|
|
27
|
+
### Static Token
|
|
28
|
+
|
|
29
|
+
Generate a token from [Stepper](https://app.stepper.io/flow/skill-sets) and pass it directly:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
stpr --token sst_your_token_here list
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Environment Variable
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
export STEPPER_SKILL_TOKEN=sst_your_token_here
|
|
39
|
+
stpr list
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Commands
|
|
43
|
+
|
|
44
|
+
### Profile Management
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
stpr login # Authenticate via OAuth (opens browser)
|
|
48
|
+
stpr logout [name] # Remove a saved profile, or all profiles if no name given
|
|
49
|
+
stpr profiles # List all saved profiles
|
|
50
|
+
stpr use <name> # Switch the active profile
|
|
51
|
+
stpr whoami # Show active profile and server info
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Discovering Skills
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
stpr list # List all available skills, grouped by service
|
|
58
|
+
stpr list --verbose # Include full input schemas
|
|
59
|
+
stpr list <service> # List skills for a specific service
|
|
60
|
+
stpr <service> # Shorthand for listing a service's skills
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Inspecting Parameters
|
|
64
|
+
|
|
65
|
+
Many skills have dynamic parameters — fields that change based on the values of other fields. Calling a skill without `--call` returns its current parameter schema.
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# See what fields are needed for add_row, given a spreadsheet
|
|
69
|
+
stpr google-sheets add_row -i '{"spreadsheet_id": "abc123"}'
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Some parameters have dynamic dropdown options. Fetch them with `--options`:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
stpr google-sheets add_row --options worksheet_id \
|
|
76
|
+
-i '{"spreadsheet_id": "abc123"}' \
|
|
77
|
+
--search "Sheet" \
|
|
78
|
+
--cursor "next_page"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Calling Skills
|
|
82
|
+
|
|
83
|
+
Use the `--call` flag to execute an action:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
stpr google-sheets create_sheet --call \
|
|
87
|
+
-i '{"name": "Q1 Report", "columns": "Name, Email, Phone"}'
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Polling Async Results
|
|
91
|
+
|
|
92
|
+
Component library tools run asynchronously. Poll for results with:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
stpr status <statusId>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Input
|
|
99
|
+
|
|
100
|
+
Pass JSON input via the `-i` / `--input` flag or pipe it through stdin:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
# Flag
|
|
104
|
+
stpr slack send_message --call -i '{"channel": "#general", "text": "Hello!"}'
|
|
105
|
+
|
|
106
|
+
# Stdin
|
|
107
|
+
echo '{"channel": "#general", "text": "Hello!"}' | stpr slack send_message --call
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Options Reference
|
|
111
|
+
|
|
112
|
+
| Flag | Description |
|
|
113
|
+
| -------------------- | --------------------------------------------------------------- |
|
|
114
|
+
| `--token <token>` | Auth token (overrides saved profiles and `STEPPER_SKILL_TOKEN`) |
|
|
115
|
+
| `--base-url <url>` | Override MCP server URL (default: `https://mcp.stepper.io`) |
|
|
116
|
+
| `--skillset <name>` | Use a specific saved profile instead of the active one |
|
|
117
|
+
| `--call` | Execute the skill (default behavior is parameter inspection) |
|
|
118
|
+
| `--verbose` | Include full `inputSchema` when listing skills |
|
|
119
|
+
| `-i, --input <json>` | JSON input for calls, parameter fetches, or option queries |
|
|
120
|
+
| `--options <param>` | Fetch dynamic dropdown options for a parameter |
|
|
121
|
+
| `--search <query>` | Filter dropdown options by search term |
|
|
122
|
+
| `--cursor <cursor>` | Pagination cursor for dropdown options |
|
|
123
|
+
| `-h, --help` | Show help |
|
|
124
|
+
| `-v, --version` | Show version |
|
|
125
|
+
|
|
126
|
+
## Environment Variables
|
|
127
|
+
|
|
128
|
+
| Variable | Description |
|
|
129
|
+
| --------------------- | ------------------------------------------------------------- |
|
|
130
|
+
| `STEPPER_SKILL_TOKEN` | Auth token (used when no `--token` flag and no saved profile) |
|
|
131
|
+
| `STEPPER_URL` | Override the MCP server base URL |
|
|
132
|
+
|
|
133
|
+
## Examples
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
# Authenticate
|
|
137
|
+
stpr login
|
|
138
|
+
|
|
139
|
+
# List everything available
|
|
140
|
+
stpr list
|
|
141
|
+
|
|
142
|
+
# Explore a service
|
|
143
|
+
stpr google-sheets
|
|
144
|
+
|
|
145
|
+
# Inspect dynamic parameters step by step
|
|
146
|
+
stpr google-sheets add_row -i '{}'
|
|
147
|
+
stpr google-sheets add_row -i '{"spreadsheet_id": "abc123"}'
|
|
148
|
+
|
|
149
|
+
# Fetch dropdown options
|
|
150
|
+
stpr google-sheets add_row --options worksheet_id -i '{"spreadsheet_id": "abc123"}'
|
|
151
|
+
|
|
152
|
+
# Execute
|
|
153
|
+
stpr google-sheets add_row --call -i '{"spreadsheet_id": "abc123", "worksheet_id": "Sheet1", "values": {"Name": "Alice"}}'
|
|
154
|
+
|
|
155
|
+
# Switch between skill sets
|
|
156
|
+
stpr profiles
|
|
157
|
+
stpr use "Production Tools"
|
|
158
|
+
stpr list
|
|
159
|
+
```
|
package/dist/cli.js
CHANGED
|
@@ -50,6 +50,19 @@ function writeCache(key, data) {
|
|
|
50
50
|
} catch {
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
|
+
function filterCatalog(catalog, service, connection) {
|
|
54
|
+
if (!service && !connection) return catalog;
|
|
55
|
+
let services = catalog.services;
|
|
56
|
+
let libs = catalog.component_libraries;
|
|
57
|
+
if (service) {
|
|
58
|
+
services = services.filter((s) => s.service === service);
|
|
59
|
+
libs = libs.filter((l) => l.library === service);
|
|
60
|
+
}
|
|
61
|
+
if (connection) {
|
|
62
|
+
services = services.filter((s) => s.connection_slug === connection);
|
|
63
|
+
}
|
|
64
|
+
return { services, component_libraries: libs };
|
|
65
|
+
}
|
|
53
66
|
var StepperClient = class {
|
|
54
67
|
token;
|
|
55
68
|
baseUrl;
|
|
@@ -80,6 +93,19 @@ var StepperClient = class {
|
|
|
80
93
|
}
|
|
81
94
|
return await response.json();
|
|
82
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Calls a static tool via tools/call RPC.
|
|
98
|
+
*/
|
|
99
|
+
async callStaticTool(toolName, args) {
|
|
100
|
+
const res = await this.rpc("tools/call", {
|
|
101
|
+
name: toolName,
|
|
102
|
+
arguments: args
|
|
103
|
+
});
|
|
104
|
+
if (res.error) {
|
|
105
|
+
throw new Error(`tools/call (${toolName}) failed: ${res.error.message}`);
|
|
106
|
+
}
|
|
107
|
+
return res.result;
|
|
108
|
+
}
|
|
83
109
|
async initialize() {
|
|
84
110
|
const res = await this.rpc("initialize");
|
|
85
111
|
if (res.error) {
|
|
@@ -100,73 +126,66 @@ var StepperClient = class {
|
|
|
100
126
|
}
|
|
101
127
|
async listTools({
|
|
102
128
|
service,
|
|
129
|
+
connection,
|
|
103
130
|
noCache
|
|
104
131
|
}) {
|
|
105
|
-
const cacheKey = `
|
|
106
|
-
let
|
|
132
|
+
const cacheKey = `skills-list:${this.baseUrl}:${this.token}`;
|
|
133
|
+
let catalog;
|
|
107
134
|
if (!noCache) {
|
|
108
135
|
const cached = readCache(cacheKey);
|
|
109
136
|
if (cached) {
|
|
110
|
-
|
|
111
|
-
return allTools.filter(
|
|
112
|
-
(tool) => service ? tool.service === service : !tool.service.startsWith("__")
|
|
113
|
-
);
|
|
137
|
+
catalog = cached;
|
|
114
138
|
}
|
|
115
139
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
service: tool.name.split("__")[0],
|
|
124
|
-
action: tool.name.split("__")[1],
|
|
125
|
-
description: tool.description,
|
|
126
|
-
inputSchema: tool.inputSchema
|
|
127
|
-
})
|
|
128
|
-
);
|
|
129
|
-
writeCache(cacheKey, allTools);
|
|
130
|
-
return allTools.filter(
|
|
131
|
-
(tool) => service ? tool.service === service : true
|
|
132
|
-
);
|
|
140
|
+
if (!catalog) {
|
|
141
|
+
const result = await this.callStaticTool("list_skills", {});
|
|
142
|
+
const text = result.content[0]?.text ?? "{}";
|
|
143
|
+
catalog = JSON.parse(text);
|
|
144
|
+
writeCache(cacheKey, catalog);
|
|
145
|
+
}
|
|
146
|
+
return filterCatalog(catalog, service, connection);
|
|
133
147
|
}
|
|
134
|
-
async callTool(
|
|
135
|
-
const
|
|
136
|
-
if (
|
|
137
|
-
|
|
148
|
+
async callTool(service, action, args, connection) {
|
|
149
|
+
const toolArgs = { service, action, args };
|
|
150
|
+
if (connection) {
|
|
151
|
+
toolArgs.connection = connection;
|
|
138
152
|
}
|
|
139
|
-
return
|
|
153
|
+
return this.callStaticTool("call_skill", toolArgs);
|
|
140
154
|
}
|
|
141
155
|
async pollStatus(statusId) {
|
|
142
|
-
|
|
143
|
-
if (res.error) {
|
|
144
|
-
throw new Error(`tools/poll-status failed: ${res.error.message}`);
|
|
145
|
-
}
|
|
146
|
-
return res.result;
|
|
156
|
+
return this.callStaticTool("poll_status", { statusId });
|
|
147
157
|
}
|
|
148
|
-
async getToolParams(
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
});
|
|
153
|
-
if (res.error) {
|
|
154
|
-
throw new Error(`tools/params failed: ${res.error.message}`);
|
|
158
|
+
async getToolParams(service, action, currentValues, connection) {
|
|
159
|
+
const args = { service, action };
|
|
160
|
+
if (connection) {
|
|
161
|
+
args.connection = connection;
|
|
155
162
|
}
|
|
156
|
-
|
|
163
|
+
if (currentValues && Object.keys(currentValues).length > 0) {
|
|
164
|
+
args.current_parameter_values = currentValues;
|
|
165
|
+
}
|
|
166
|
+
return this.callStaticTool("get_skill_params", args);
|
|
157
167
|
}
|
|
158
|
-
async getParameterOptions(
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
if (res.error) {
|
|
167
|
-
throw new Error(`tools/options failed: ${res.error.message}`);
|
|
168
|
+
async getParameterOptions(service, action, parameterId, opts) {
|
|
169
|
+
const args = {
|
|
170
|
+
service,
|
|
171
|
+
action,
|
|
172
|
+
parameter_id: parameterId
|
|
173
|
+
};
|
|
174
|
+
if (opts?.connection) {
|
|
175
|
+
args.connection = opts.connection;
|
|
168
176
|
}
|
|
169
|
-
|
|
177
|
+
if (opts?.currentParameterValues) {
|
|
178
|
+
args.current_parameter_values = opts.currentParameterValues;
|
|
179
|
+
}
|
|
180
|
+
if (opts?.search) {
|
|
181
|
+
args.search = opts.search;
|
|
182
|
+
}
|
|
183
|
+
if (opts?.cursor) {
|
|
184
|
+
args.cursor = opts.cursor;
|
|
185
|
+
}
|
|
186
|
+
const result = await this.callStaticTool("get_parameter_options", args);
|
|
187
|
+
const text = result.content[0]?.text ?? "{}";
|
|
188
|
+
return JSON.parse(text);
|
|
170
189
|
}
|
|
171
190
|
};
|
|
172
191
|
|
|
@@ -540,6 +559,8 @@ function parseArgs(argv) {
|
|
|
540
559
|
flags.search = argv[++i];
|
|
541
560
|
} else if (arg === "--cursor" && i + 1 < argv.length) {
|
|
542
561
|
flags.cursor = argv[++i];
|
|
562
|
+
} else if (arg === "--connection" && i + 1 < argv.length) {
|
|
563
|
+
flags.connection = argv[++i];
|
|
543
564
|
} else if (arg === "--call") {
|
|
544
565
|
boolFlags.call = true;
|
|
545
566
|
} else if (arg === "--no-cache") {
|
|
@@ -565,22 +586,24 @@ function parseArgs(argv) {
|
|
|
565
586
|
input: flags.input,
|
|
566
587
|
search: flags.search,
|
|
567
588
|
cursor: flags.cursor,
|
|
589
|
+
connection: flags.connection,
|
|
568
590
|
call: boolFlags.call ?? false,
|
|
569
591
|
verbose: boolFlags.verbose ?? false,
|
|
570
592
|
noCache: boolFlags.noCache ?? false,
|
|
571
593
|
options: flags.options
|
|
572
594
|
};
|
|
573
595
|
}
|
|
574
|
-
function
|
|
575
|
-
return `${service}__${action}`;
|
|
576
|
-
}
|
|
577
|
-
function formatToolsForList(tools, verbose) {
|
|
596
|
+
function formatCatalogForList(catalog, verbose) {
|
|
578
597
|
if (verbose) {
|
|
579
|
-
return
|
|
598
|
+
return catalog;
|
|
580
599
|
}
|
|
581
600
|
const out = {};
|
|
582
|
-
for (const
|
|
583
|
-
|
|
601
|
+
for (const svc of catalog.services) {
|
|
602
|
+
const key = catalog.services.filter((s) => s.service === svc.service).length > 1 ? `${svc.service}--${svc.connection_slug}` : svc.service;
|
|
603
|
+
out[key] = svc.actions.map((a) => a.action);
|
|
604
|
+
}
|
|
605
|
+
for (const lib of catalog.component_libraries) {
|
|
606
|
+
out[`${lib.library}`] = lib.components.map((c) => c.component);
|
|
584
607
|
}
|
|
585
608
|
return out;
|
|
586
609
|
}
|
|
@@ -596,9 +619,9 @@ Commands:
|
|
|
596
619
|
profiles List all stored skillsets
|
|
597
620
|
use <name> Switch active skillset
|
|
598
621
|
whoami Show active skillset and server info
|
|
599
|
-
list [<service>] List available skills (optionally for a service). Use --verbose for
|
|
622
|
+
list [<service>] List available skills (optionally for a service). Use --verbose for full catalog.
|
|
600
623
|
status <statusId> Poll the status of a component tool run
|
|
601
|
-
<service> List available skills for that service. Use --verbose for
|
|
624
|
+
<service> List available skills for that service. Use --verbose for full catalog.
|
|
602
625
|
<service> <action> (-i <json> | stdin)
|
|
603
626
|
Get the current parameters for a skill (default, for dynamic parameters)
|
|
604
627
|
<service> <action> --call (-i <json> | stdin)
|
|
@@ -610,8 +633,9 @@ Options:
|
|
|
610
633
|
--token <token> Auth token (or set STEPPER_SKILL_TOKEN env var)
|
|
611
634
|
--base-url <url> Override base URL (or set STEPPER_URL env var)
|
|
612
635
|
--skillset <name> Use a specific skill set
|
|
636
|
+
--connection <slug> Connection slug (for multi-connection disambiguation)
|
|
613
637
|
--call Execute the skill (default is to fetch parameters only)
|
|
614
|
-
--verbose Include
|
|
638
|
+
--verbose Include full catalog when listing skills
|
|
615
639
|
--no-cache Bypass the 5-minute tools list cache
|
|
616
640
|
-i, --input <json> JSON input for call, parameters or options (alternative to stdin)
|
|
617
641
|
--search <query> Search query for dynamic dropdown options
|
|
@@ -632,17 +656,37 @@ Examples:
|
|
|
632
656
|
Dynamic dropdown options:
|
|
633
657
|
Some actions have dynamic dropdown options, which change depending on the
|
|
634
658
|
value of other parameters. You can request the current dropdown options for
|
|
635
|
-
a skill by using the --options flag.
|
|
636
|
-
options only, it will not call the skill. Dynamic dropdowns are also often
|
|
637
|
-
searchable and paginated via a cursor.
|
|
659
|
+
a skill by using the --options flag.
|
|
638
660
|
|
|
639
661
|
stpr google-sheets add_row --options worksheet_id -i '{"spreadsheet_id": "abc123"}' --search "Sheet" --cursor "next_page"
|
|
640
|
-
|
|
662
|
+
|
|
663
|
+
Multi-connection disambiguation:
|
|
664
|
+
When multiple connections exist for the same service, use the compound
|
|
665
|
+
format from "stpr list" or the --connection flag:
|
|
666
|
+
|
|
667
|
+
stpr google-sheets--my-sheets add_row --call -i '{"spreadsheet_id": "abc123"}'
|
|
668
|
+
stpr google-sheets add_row --connection my-sheets --call -i '{"spreadsheet_id": "abc123"}'
|
|
669
|
+
|
|
641
670
|
Call a skill:
|
|
642
671
|
stpr google-sheets create_sheet --call -i '{"name": "My Sheet", "columns": "Name, Email, Phone"}'
|
|
643
|
-
|
|
672
|
+
|
|
644
673
|
`);
|
|
645
674
|
}
|
|
675
|
+
function resolveServiceFromCatalog(rawService, catalog) {
|
|
676
|
+
if (catalog.services.some((s) => s.service === rawService)) {
|
|
677
|
+
return null;
|
|
678
|
+
}
|
|
679
|
+
if (catalog.component_libraries.some((l) => l.library === rawService)) {
|
|
680
|
+
return null;
|
|
681
|
+
}
|
|
682
|
+
for (const svc of catalog.services) {
|
|
683
|
+
const compound = `${svc.service}--${svc.connection_slug}`;
|
|
684
|
+
if (compound === rawService) {
|
|
685
|
+
return { service: svc.service, connection: svc.connection_slug };
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
return null;
|
|
689
|
+
}
|
|
646
690
|
function die(message) {
|
|
647
691
|
process.stderr.write(`\x1B[31m[Error] ${message} \x1B[0m
|
|
648
692
|
`);
|
|
@@ -658,6 +702,7 @@ async function main() {
|
|
|
658
702
|
input: inputFlag,
|
|
659
703
|
search: searchFlag,
|
|
660
704
|
cursor: cursorFlag,
|
|
705
|
+
connection: connectionFlag,
|
|
661
706
|
call: callFlag,
|
|
662
707
|
verbose: verboseFlag,
|
|
663
708
|
noCache: noCacheFlag,
|
|
@@ -812,40 +857,53 @@ async function main() {
|
|
|
812
857
|
console.log(result2.content.map((c) => c.text ?? "").join("\n"));
|
|
813
858
|
return;
|
|
814
859
|
}
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
const tools = await client.listTools({
|
|
818
|
-
service: service2 ?? void 0,
|
|
819
|
-
noCache: noCacheFlag
|
|
820
|
-
});
|
|
821
|
-
const formatted = formatToolsForList(tools, verboseFlag);
|
|
822
|
-
if (!tools.length) {
|
|
823
|
-
die(
|
|
824
|
-
service2 ? `No skills found for service "${service2}".` : "No skills found."
|
|
825
|
-
);
|
|
826
|
-
}
|
|
827
|
-
console.log(JSON.stringify(formatted, null, 2));
|
|
828
|
-
return;
|
|
829
|
-
}
|
|
830
|
-
const service = subcommand;
|
|
831
|
-
const action = args[0];
|
|
832
|
-
if (service.startsWith("--")) {
|
|
860
|
+
const rawServiceArg = subcommand === "list" ? args[0] : subcommand;
|
|
861
|
+
if (rawServiceArg?.startsWith("--")) {
|
|
833
862
|
printUsage();
|
|
834
863
|
process.exit(1);
|
|
835
864
|
return;
|
|
836
865
|
}
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
866
|
+
let service = rawServiceArg;
|
|
867
|
+
let connection = connectionFlag;
|
|
868
|
+
const action = subcommand === "list" ? void 0 : args[0];
|
|
869
|
+
if (service && !connection) {
|
|
870
|
+
const fullCatalog = await client.listTools({
|
|
871
|
+
service: void 0,
|
|
872
|
+
noCache: noCacheFlag
|
|
873
|
+
});
|
|
874
|
+
const resolved = resolveServiceFromCatalog(service, fullCatalog);
|
|
875
|
+
if (resolved) {
|
|
876
|
+
service = resolved.service;
|
|
877
|
+
connection = resolved.connection;
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
if (subcommand === "list" || !action) {
|
|
881
|
+
const catalog = await client.listTools({
|
|
882
|
+
service: service ?? void 0,
|
|
883
|
+
connection,
|
|
884
|
+
noCache: noCacheFlag
|
|
885
|
+
});
|
|
886
|
+
const hasContent = catalog.services.length > 0 || catalog.component_libraries.length > 0;
|
|
887
|
+
if (!hasContent) {
|
|
840
888
|
die(
|
|
841
|
-
|
|
889
|
+
rawServiceArg ? `No skills found for service "${rawServiceArg}".` : "No skills found."
|
|
842
890
|
);
|
|
843
891
|
}
|
|
844
|
-
|
|
845
|
-
|
|
892
|
+
if (subcommand === "list" || verboseFlag) {
|
|
893
|
+
const formatted = formatCatalogForList(catalog, verboseFlag);
|
|
894
|
+
console.log(JSON.stringify(formatted, null, 2));
|
|
895
|
+
} else {
|
|
896
|
+
const actions = [];
|
|
897
|
+
for (const svc of catalog.services) {
|
|
898
|
+
actions.push(...svc.actions.map((a) => a.action));
|
|
899
|
+
}
|
|
900
|
+
for (const lib of catalog.component_libraries) {
|
|
901
|
+
actions.push(...lib.components.map((c) => c.component));
|
|
902
|
+
}
|
|
903
|
+
console.log(JSON.stringify(actions, null, 2));
|
|
904
|
+
}
|
|
846
905
|
return;
|
|
847
906
|
}
|
|
848
|
-
const toolName = toToolName(service, action);
|
|
849
907
|
const rawInput = inputFlag ?? await readStdin();
|
|
850
908
|
let input = {};
|
|
851
909
|
if (rawInput.trim()) {
|
|
@@ -856,27 +914,35 @@ async function main() {
|
|
|
856
914
|
}
|
|
857
915
|
}
|
|
858
916
|
if (optionsFlag) {
|
|
859
|
-
const result2 = await client.getParameterOptions(
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
917
|
+
const result2 = await client.getParameterOptions(
|
|
918
|
+
service,
|
|
919
|
+
action,
|
|
920
|
+
optionsFlag,
|
|
921
|
+
{
|
|
922
|
+
currentParameterValues: input,
|
|
923
|
+
search: searchFlag,
|
|
924
|
+
cursor: cursorFlag,
|
|
925
|
+
connection
|
|
926
|
+
}
|
|
927
|
+
);
|
|
864
928
|
console.log(JSON.stringify(result2, null, 2));
|
|
865
929
|
return;
|
|
866
930
|
}
|
|
867
931
|
if (callFlag) {
|
|
868
|
-
const result2 = await client.callTool(
|
|
932
|
+
const result2 = await client.callTool(service, action, input, connection);
|
|
869
933
|
if (result2.isError) {
|
|
870
934
|
die(result2.content.map((c) => c.text).join("\n"));
|
|
871
935
|
}
|
|
872
936
|
console.log(result2.content.map((c) => c.text ?? "").join("\n"));
|
|
873
937
|
return;
|
|
874
938
|
}
|
|
875
|
-
const result = await client.getToolParams(
|
|
939
|
+
const result = await client.getToolParams(service, action, input, connection);
|
|
876
940
|
if (result.isError) {
|
|
877
941
|
die(result.content?.map((c) => c.text).join("\n") ?? "Unknown error");
|
|
878
942
|
}
|
|
879
|
-
console.log(
|
|
943
|
+
console.log(
|
|
944
|
+
result.content?.map((c) => c.text ?? "").join("\n") ?? JSON.stringify(result, null, 2)
|
|
945
|
+
);
|
|
880
946
|
}
|
|
881
947
|
main().then(() => process.exit(0)).catch((err) => {
|
|
882
948
|
console.error(`Error: ${err.message}`);
|