stpr 1.0.5 → 1.0.7
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 +84 -49
- package/package.json +1 -1
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
|
@@ -2,19 +2,49 @@
|
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
4
|
import { createRequire } from "module";
|
|
5
|
-
import * as
|
|
5
|
+
import * as path3 from "path";
|
|
6
6
|
import { fileURLToPath } from "url";
|
|
7
7
|
|
|
8
8
|
// src/auth.ts
|
|
9
9
|
import * as childProcess from "child_process";
|
|
10
|
+
import * as crypto2 from "crypto";
|
|
11
|
+
import * as fs2 from "fs";
|
|
12
|
+
import * as os2 from "os";
|
|
13
|
+
import * as path2 from "path";
|
|
14
|
+
import { createServer } from "http";
|
|
15
|
+
|
|
16
|
+
// src/client.ts
|
|
10
17
|
import * as crypto from "crypto";
|
|
11
18
|
import * as fs from "fs";
|
|
12
19
|
import * as os from "os";
|
|
13
20
|
import * as path from "path";
|
|
14
|
-
import { createServer } from "http";
|
|
15
|
-
|
|
16
|
-
// src/client.ts
|
|
17
21
|
var DEFAULT_BASE_URL = "https://mcp.stepper.io";
|
|
22
|
+
var CACHE_DIR = path.join(os.homedir(), ".config", "stepper-skillsets", "cache");
|
|
23
|
+
var CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
24
|
+
function getCachePath(key) {
|
|
25
|
+
const hash = crypto.createHash("sha256").update(key).digest("hex").slice(0, 16);
|
|
26
|
+
return path.join(CACHE_DIR, `${hash}.json`);
|
|
27
|
+
}
|
|
28
|
+
function readCache(key) {
|
|
29
|
+
try {
|
|
30
|
+
const filePath = getCachePath(key);
|
|
31
|
+
const raw = fs.readFileSync(filePath, "utf-8");
|
|
32
|
+
const entry = JSON.parse(raw);
|
|
33
|
+
if (Date.now() - entry.timestamp < CACHE_TTL_MS) {
|
|
34
|
+
return entry.data;
|
|
35
|
+
}
|
|
36
|
+
} catch {
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
function writeCache(key, data) {
|
|
41
|
+
try {
|
|
42
|
+
fs.mkdirSync(CACHE_DIR, { recursive: true, mode: 448 });
|
|
43
|
+
const entry = { timestamp: Date.now(), data };
|
|
44
|
+
fs.writeFileSync(getCachePath(key), JSON.stringify(entry), { mode: 384 });
|
|
45
|
+
} catch {
|
|
46
|
+
}
|
|
47
|
+
}
|
|
18
48
|
var StepperClient = class {
|
|
19
49
|
token;
|
|
20
50
|
baseUrl;
|
|
@@ -63,20 +93,31 @@ var StepperClient = class {
|
|
|
63
93
|
version: serverInfo.version ?? "1.0.0"
|
|
64
94
|
};
|
|
65
95
|
}
|
|
66
|
-
async listTools({ service }) {
|
|
96
|
+
async listTools({ service, noCache }) {
|
|
97
|
+
const cacheKey = `tools-list:${this.baseUrl}:${this.token}`;
|
|
98
|
+
let allTools;
|
|
99
|
+
if (!noCache) {
|
|
100
|
+
const cached = readCache(cacheKey);
|
|
101
|
+
if (cached) {
|
|
102
|
+
allTools = cached;
|
|
103
|
+
return allTools.filter(
|
|
104
|
+
(tool) => service ? tool.service === service : !tool.service.startsWith("__")
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
67
108
|
const res = await this.rpc("tools/list");
|
|
68
109
|
if (res.error) {
|
|
69
110
|
throw new Error(`tools/list failed: ${res.error.message}`);
|
|
70
111
|
}
|
|
71
112
|
const tools = res.result.tools;
|
|
72
|
-
|
|
73
|
-
(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
113
|
+
allTools = tools.map((tool) => ({
|
|
114
|
+
service: tool.name.split(".")[0],
|
|
115
|
+
action: tool.name.split(".")[1],
|
|
116
|
+
description: tool.description,
|
|
117
|
+
inputSchema: tool.inputSchema
|
|
118
|
+
}));
|
|
119
|
+
writeCache(cacheKey, allTools);
|
|
120
|
+
return allTools.filter(
|
|
80
121
|
(tool) => service ? tool.service === service : !tool.service.startsWith("__")
|
|
81
122
|
);
|
|
82
123
|
}
|
|
@@ -121,7 +162,7 @@ var StepperClient = class {
|
|
|
121
162
|
|
|
122
163
|
// src/auth.ts
|
|
123
164
|
function openBrowser(url) {
|
|
124
|
-
const platform2 =
|
|
165
|
+
const platform2 = os2.platform();
|
|
125
166
|
if (platform2 === "darwin") {
|
|
126
167
|
childProcess.spawn("open", [url], { stdio: "ignore", detached: true });
|
|
127
168
|
} else if (platform2 === "win32") {
|
|
@@ -136,51 +177,35 @@ function openBrowser(url) {
|
|
|
136
177
|
var DEFAULT_BASE_URL2 = "https://mcp.stepper.io";
|
|
137
178
|
var OAUTH_CALLBACK_PORT = 3847;
|
|
138
179
|
var CALLBACK_PATH = "/callback";
|
|
139
|
-
var CONFIG_DIR =
|
|
140
|
-
var CONFIG_FILE =
|
|
141
|
-
var LEGACY_CREDENTIALS_FILE = path.join(CONFIG_DIR, "credentials.json");
|
|
180
|
+
var CONFIG_DIR = path2.join(os2.homedir(), ".config", "stepper-skillsets");
|
|
181
|
+
var CONFIG_FILE = path2.join(CONFIG_DIR, "config.json");
|
|
142
182
|
function generatePKCE() {
|
|
143
|
-
const codeVerifier =
|
|
144
|
-
const codeChallenge =
|
|
183
|
+
const codeVerifier = crypto2.randomBytes(32).toString("base64url");
|
|
184
|
+
const codeChallenge = crypto2.createHash("sha256").update(codeVerifier).digest().toString("base64url");
|
|
145
185
|
return { codeVerifier, codeChallenge };
|
|
146
186
|
}
|
|
147
187
|
function loadConfig() {
|
|
148
188
|
try {
|
|
149
|
-
const data =
|
|
189
|
+
const data = fs2.readFileSync(CONFIG_FILE, "utf-8");
|
|
150
190
|
return JSON.parse(data);
|
|
151
191
|
} catch {
|
|
152
192
|
return { active: null, skillsets: {} };
|
|
153
193
|
}
|
|
154
194
|
}
|
|
155
195
|
function saveConfig(config) {
|
|
156
|
-
|
|
157
|
-
|
|
196
|
+
fs2.mkdirSync(CONFIG_DIR, { recursive: true, mode: 448 });
|
|
197
|
+
fs2.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), {
|
|
158
198
|
mode: 384
|
|
159
199
|
});
|
|
160
200
|
}
|
|
161
|
-
function migrateLegacyCredentials() {
|
|
162
|
-
try {
|
|
163
|
-
const data = fs.readFileSync(LEGACY_CREDENTIALS_FILE, "utf-8");
|
|
164
|
-
const creds = JSON.parse(data);
|
|
165
|
-
const config = {
|
|
166
|
-
active: "default",
|
|
167
|
-
skillsets: { default: creds }
|
|
168
|
-
};
|
|
169
|
-
saveConfig(config);
|
|
170
|
-
fs.unlinkSync(LEGACY_CREDENTIALS_FILE);
|
|
171
|
-
} catch {
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
201
|
function getConfigPathForDisplay() {
|
|
175
202
|
return CONFIG_FILE;
|
|
176
203
|
}
|
|
177
204
|
function getActiveSkillset() {
|
|
178
|
-
migrateLegacyCredentials();
|
|
179
205
|
const config = loadConfig();
|
|
180
206
|
return config.active;
|
|
181
207
|
}
|
|
182
208
|
function setActiveSkillset(name) {
|
|
183
|
-
migrateLegacyCredentials();
|
|
184
209
|
const config = loadConfig();
|
|
185
210
|
if (!(name in config.skillsets)) {
|
|
186
211
|
return false;
|
|
@@ -190,7 +215,6 @@ function setActiveSkillset(name) {
|
|
|
190
215
|
return true;
|
|
191
216
|
}
|
|
192
217
|
function listSkillsets() {
|
|
193
|
-
migrateLegacyCredentials();
|
|
194
218
|
const config = loadConfig();
|
|
195
219
|
return Object.entries(config.skillsets).map(([name, creds]) => ({
|
|
196
220
|
name,
|
|
@@ -199,12 +223,10 @@ function listSkillsets() {
|
|
|
199
223
|
}));
|
|
200
224
|
}
|
|
201
225
|
function getCredentials(name) {
|
|
202
|
-
migrateLegacyCredentials();
|
|
203
226
|
const config = loadConfig();
|
|
204
227
|
return config.skillsets[name] ?? null;
|
|
205
228
|
}
|
|
206
229
|
function saveCredentials(name, creds) {
|
|
207
|
-
migrateLegacyCredentials();
|
|
208
230
|
const config = loadConfig();
|
|
209
231
|
config.skillsets[name] = creds;
|
|
210
232
|
if (!config.active || !(config.active in config.skillsets)) {
|
|
@@ -213,7 +235,6 @@ function saveCredentials(name, creds) {
|
|
|
213
235
|
saveConfig(config);
|
|
214
236
|
}
|
|
215
237
|
function deleteSkillset(name) {
|
|
216
|
-
migrateLegacyCredentials();
|
|
217
238
|
const config = loadConfig();
|
|
218
239
|
if (!(name in config.skillsets)) {
|
|
219
240
|
return false;
|
|
@@ -226,7 +247,6 @@ function deleteSkillset(name) {
|
|
|
226
247
|
return true;
|
|
227
248
|
}
|
|
228
249
|
function deleteAllSkillsets() {
|
|
229
|
-
migrateLegacyCredentials();
|
|
230
250
|
const config = loadConfig();
|
|
231
251
|
const count = Object.keys(config.skillsets).length;
|
|
232
252
|
config.skillsets = {};
|
|
@@ -303,7 +323,7 @@ async function runLoginFlow(baseUrl) {
|
|
|
303
323
|
const metadata = await fetchMetadata(normalizedBaseUrl);
|
|
304
324
|
const { codeVerifier, codeChallenge } = generatePKCE();
|
|
305
325
|
const clientId = await registerClient(normalizedBaseUrl, redirectUri);
|
|
306
|
-
const state =
|
|
326
|
+
const state = crypto2.randomBytes(16).toString("hex");
|
|
307
327
|
const authUrl = new URL(metadata.authorization_endpoint);
|
|
308
328
|
authUrl.searchParams.set("response_type", "code");
|
|
309
329
|
authUrl.searchParams.set("client_id", clientId);
|
|
@@ -320,6 +340,18 @@ async function runLoginFlow(baseUrl) {
|
|
|
320
340
|
res.end("Not found");
|
|
321
341
|
return;
|
|
322
342
|
}
|
|
343
|
+
const requestHost = req.headers.host ?? `127.0.0.1:${OAUTH_CALLBACK_PORT}`;
|
|
344
|
+
const callbackUrl = new URL(req.url ?? "/", `http://${requestHost}`);
|
|
345
|
+
const receivedCallbackUrl = `${callbackUrl.origin}${callbackUrl.pathname}`;
|
|
346
|
+
if (receivedCallbackUrl !== redirectUri) {
|
|
347
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
348
|
+
res.end(
|
|
349
|
+
"<html><body><h1>Login failed</h1><p>Redirect URI mismatch</p><p>You can close this tab.</p></body></html>"
|
|
350
|
+
);
|
|
351
|
+
server.close();
|
|
352
|
+
reject(new Error("OAuth redirect URI mismatch"));
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
323
355
|
const code = url.searchParams.get("code");
|
|
324
356
|
const returnedState = url.searchParams.get("state");
|
|
325
357
|
const error = url.searchParams.get("error");
|
|
@@ -412,7 +444,6 @@ async function refreshAccessToken(baseUrl, clientId, refreshToken) {
|
|
|
412
444
|
};
|
|
413
445
|
}
|
|
414
446
|
async function getValidToken(skillsetName, baseUrl) {
|
|
415
|
-
migrateLegacyCredentials();
|
|
416
447
|
const config = loadConfig();
|
|
417
448
|
const name = skillsetName ?? config.active;
|
|
418
449
|
if (!name || !(name in config.skillsets)) {
|
|
@@ -462,9 +493,9 @@ async function getValidToken(skillsetName, baseUrl) {
|
|
|
462
493
|
}
|
|
463
494
|
|
|
464
495
|
// src/cli.ts
|
|
465
|
-
var __dirname =
|
|
496
|
+
var __dirname = path3.dirname(fileURLToPath(import.meta.url));
|
|
466
497
|
var pkg = createRequire(import.meta.url)(
|
|
467
|
-
|
|
498
|
+
path3.join(__dirname, "..", "package.json")
|
|
468
499
|
);
|
|
469
500
|
var VERSION = pkg.version ?? "0.0.0";
|
|
470
501
|
function readStdin() {
|
|
@@ -501,6 +532,8 @@ function parseArgs(argv) {
|
|
|
501
532
|
flags.cursor = argv[++i];
|
|
502
533
|
} else if (arg === "--call") {
|
|
503
534
|
boolFlags.call = true;
|
|
535
|
+
} else if (arg === "--no-cache") {
|
|
536
|
+
boolFlags.noCache = true;
|
|
504
537
|
} else if (arg === "--verbose") {
|
|
505
538
|
boolFlags.verbose = true;
|
|
506
539
|
} else if (arg === "--options" && i + 1 < argv.length) {
|
|
@@ -524,6 +557,7 @@ function parseArgs(argv) {
|
|
|
524
557
|
cursor: flags.cursor,
|
|
525
558
|
call: boolFlags.call ?? false,
|
|
526
559
|
verbose: boolFlags.verbose ?? false,
|
|
560
|
+
noCache: boolFlags.noCache ?? false,
|
|
527
561
|
options: flags.options
|
|
528
562
|
};
|
|
529
563
|
}
|
|
@@ -568,6 +602,7 @@ Options:
|
|
|
568
602
|
--skillset <name> Use a specific skill set
|
|
569
603
|
--call Execute the skill (default is to fetch parameters only)
|
|
570
604
|
--verbose Include inputSchema when listing skills
|
|
605
|
+
--no-cache Bypass the 5-minute tools list cache
|
|
571
606
|
-i, --input <json> JSON input for call, parameters or options (alternative to stdin)
|
|
572
607
|
--search <query> Search query for dynamic dropdown options
|
|
573
608
|
--cursor <cursor> Pagination cursor for dynamic dropdown options
|
|
@@ -575,7 +610,6 @@ Options:
|
|
|
575
610
|
-v, --version Show version
|
|
576
611
|
|
|
577
612
|
Examples:
|
|
578
|
-
|
|
579
613
|
Auth (optional, can use STEPPER_SKILL_TOKEN env var, or --token <token> from https://app.stepper.io/flow/skill-sets):
|
|
580
614
|
stpr login
|
|
581
615
|
|
|
@@ -616,6 +650,7 @@ async function main() {
|
|
|
616
650
|
cursor: cursorFlag,
|
|
617
651
|
call: callFlag,
|
|
618
652
|
verbose: verboseFlag,
|
|
653
|
+
noCache: noCacheFlag,
|
|
619
654
|
options: optionsFlag
|
|
620
655
|
} = parseArgs(process.argv.slice(2));
|
|
621
656
|
if (subcommand === "help") {
|
|
@@ -769,7 +804,7 @@ async function main() {
|
|
|
769
804
|
}
|
|
770
805
|
if (subcommand === "list") {
|
|
771
806
|
const service2 = args[0];
|
|
772
|
-
const tools = await client.listTools({ service: service2 ?? void 0 });
|
|
807
|
+
const tools = await client.listTools({ service: service2 ?? void 0, noCache: noCacheFlag });
|
|
773
808
|
const formatted = formatToolsForList(tools, verboseFlag);
|
|
774
809
|
if (!tools.length) {
|
|
775
810
|
die(
|
|
@@ -787,7 +822,7 @@ async function main() {
|
|
|
787
822
|
return;
|
|
788
823
|
}
|
|
789
824
|
if (!action) {
|
|
790
|
-
const tools = await client.listTools({ service });
|
|
825
|
+
const tools = await client.listTools({ service, noCache: noCacheFlag });
|
|
791
826
|
if (!tools.length) {
|
|
792
827
|
die(
|
|
793
828
|
service ? `No skills found for service "${service}".` : "No skills found."
|