@fastmoss/cli 0.1.4 → 0.1.5

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 CHANGED
@@ -7,13 +7,21 @@ FastMoss CLI lets terminals and AI agents discover and call FastMoss MCP tools f
7
7
  Use the CLI together with the FastMoss CLI Agent Skill:
8
8
 
9
9
  - `@fastmoss/cli` installs the `fastmoss` command and executes tool calls.
10
- - `npx skills add FastMoss/cli -y -g` installs the Agent Skill so your agent knows which FastMoss tools exist, when to use them, and how to call them.
10
+ - `npx skills add FastMoss/cli` installs the Agent Skill so your agent knows which FastMoss tools exist, when to use them, and how to call them.
11
11
 
12
- For agent workflows, install both:
12
+ Install CLI:
13
13
 
14
14
  ```bash
15
15
  npm install -g @fastmoss/cli
16
+ ```
17
+
18
+ Install Skill separately:
19
+
20
+ ```bash
16
21
  npx skills add FastMoss/cli -y -g
22
+ npx skills add FastMoss/cli --agent claude-code
23
+ # If your skills CLI supports --client:
24
+ npx skills add FastMoss/cli --client claude
17
25
  ```
18
26
 
19
27
  ## About FastMoss
package/README.zh-CN.md CHANGED
@@ -7,13 +7,21 @@ FastMoss CLI 用于在终端或 AI Agent 中发现并调用 FastMoss MCP 工具
7
7
  CLI 需要配合 FastMoss CLI Agent Skill 一起使用:
8
8
 
9
9
  - `@fastmoss/cli` 安装 `fastmoss` 命令,用于真正执行工具调用。
10
- - `npx skills add FastMoss/cli -y -g` 安装 Agent Skill,让你的 Agent 知道有哪些 FastMoss 工具、什么时候使用、怎么调用。
10
+ - `npx skills add FastMoss/cli` 安装 Agent Skill,让你的 Agent 知道有哪些 FastMoss 工具、什么时候使用、怎么调用。
11
11
 
12
- Agent 工作流建议两个都安装:
12
+ 安装 CLI:
13
13
 
14
14
  ```bash
15
15
  npm install -g @fastmoss/cli
16
+ ```
17
+
18
+ 单独安装 Skill:
19
+
20
+ ```bash
16
21
  npx skills add FastMoss/cli -y -g
22
+ npx skills add FastMoss/cli --agent claude-code
23
+ # 如果你的 skills CLI 支持 --client:
24
+ npx skills add FastMoss/cli --client claude
17
25
  ```
18
26
 
19
27
  ## 关于 FastMoss
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env node
2
+
3
+ const path = require("node:path");
4
+ const {
5
+ INSTALL_SKILL_USAGE,
6
+ installSkill,
7
+ parseInstallSkillArgs,
8
+ } = require("../lib/runtime");
9
+
10
+ async function main() {
11
+ let options;
12
+ try {
13
+ options = parseInstallSkillArgs(process.argv.slice(2));
14
+ } catch (error) {
15
+ process.stderr.write(`${error.message}\n\n${INSTALL_SKILL_USAGE}`);
16
+ process.exitCode = 1;
17
+ return;
18
+ }
19
+
20
+ if (options.help) {
21
+ process.stdout.write(INSTALL_SKILL_USAGE);
22
+ return;
23
+ }
24
+
25
+ await installSkill({
26
+ packageRoot: path.join(__dirname, ".."),
27
+ agent: options.agent,
28
+ });
29
+ }
30
+
31
+ main().catch((error) => {
32
+ process.stderr.write(`fastmoss-install-skill error: ${error.message}\n`);
33
+ process.exitCode = 1;
34
+ });
package/lib/runtime.js CHANGED
@@ -8,6 +8,19 @@ const { spawn } = require("node:child_process");
8
8
 
9
9
  const DEFAULT_DOWNLOAD_BASE_URL =
10
10
  "https://github.com/FastMoss/cli/releases/download";
11
+ const SKILL_NAME = "fastmoss-cli";
12
+ const INSTALL_SKILL_USAGE = `Usage: fastmoss-install-skill [--agent codex|claude|agents|all]
13
+
14
+ Options:
15
+ -a, --agent <agent> Install for a specific agent client.
16
+ Supported: codex, claude, agents, all.
17
+ -h, --help Show this help message.
18
+
19
+ Environment:
20
+ FASTMOSS_SKILL_AGENT Default agent for this command.
21
+ FASTMOSS_SKILL_DIR Override the target skills directory.
22
+ FASTMOSS_SKIP_SKILL_INSTALL Skip skill installation.
23
+ `;
11
24
 
12
25
  const PLATFORM_TARGETS = {
13
26
  "darwin:x64": {
@@ -140,6 +153,156 @@ function shouldSkipDownload(env = process.env) {
140
153
  return value !== "" && value !== "0" && value !== "false";
141
154
  }
142
155
 
156
+ function isTruthyEnv(value) {
157
+ const normalized = String(value || "").trim().toLowerCase();
158
+ return normalized !== "" && normalized !== "0" && normalized !== "false";
159
+ }
160
+
161
+ function shouldSkipSkillInstall(env = process.env) {
162
+ return isTruthyEnv(env.FASTMOSS_SKIP_SKILL_INSTALL);
163
+ }
164
+
165
+ function normalizeSkillAgent(agent = "") {
166
+ const normalized = String(agent || "").trim().toLowerCase();
167
+ if (normalized === "" || normalized === "auto") {
168
+ return "auto";
169
+ }
170
+ if (normalized === "claude-code") {
171
+ return "claude";
172
+ }
173
+ if (normalized === "agent") {
174
+ return "agents";
175
+ }
176
+ return normalized;
177
+ }
178
+
179
+ function knownSkillTargets({ env = process.env, homeDir = os.homedir() } = {}) {
180
+ return {
181
+ codex: path.join(env.CODEX_HOME || path.join(homeDir, ".codex"), "skills"),
182
+ claude: path.join(
183
+ env.CLAUDE_HOME || path.join(homeDir, ".claude"),
184
+ "skills",
185
+ ),
186
+ agents: path.join(
187
+ env.AGENTS_HOME || path.join(homeDir, ".agents"),
188
+ "skills",
189
+ ),
190
+ };
191
+ }
192
+
193
+ function resolveSkillInstallTargets({
194
+ agent = "auto",
195
+ env = process.env,
196
+ homeDir = os.homedir(),
197
+ } = {}) {
198
+ const override = String(env.FASTMOSS_SKILL_DIR || "").trim();
199
+ if (override !== "") {
200
+ return [override];
201
+ }
202
+
203
+ const targets = knownSkillTargets({ env, homeDir });
204
+ const normalizedAgent = normalizeSkillAgent(agent || env.FASTMOSS_SKILL_AGENT);
205
+
206
+ if (normalizedAgent === "all") {
207
+ return [targets.codex, targets.claude, targets.agents];
208
+ }
209
+ if (normalizedAgent === "auto") {
210
+ return Object.values(targets);
211
+ }
212
+ if (targets[normalizedAgent]) {
213
+ return [targets[normalizedAgent]];
214
+ }
215
+
216
+ throw new Error(
217
+ `Unsupported FastMoss skill agent: ${agent}. Supported agents: codex, claude, agents, all`,
218
+ );
219
+ }
220
+
221
+ function parseInstallSkillArgs(args = []) {
222
+ const result = {
223
+ agent: "",
224
+ help: false,
225
+ };
226
+
227
+ for (let index = 0; index < args.length; index += 1) {
228
+ const arg = args[index];
229
+ if (arg === "--help" || arg === "-h") {
230
+ result.help = true;
231
+ continue;
232
+ }
233
+ if (arg === "--agent" || arg === "-a") {
234
+ const value = args[index + 1];
235
+ if (!value || value.startsWith("-")) {
236
+ throw new Error(`${arg} requires an agent value`);
237
+ }
238
+ result.agent = value;
239
+ index += 1;
240
+ continue;
241
+ }
242
+ throw new Error(`Unknown option: ${arg}`);
243
+ }
244
+
245
+ return result;
246
+ }
247
+
248
+ async function installSkill({
249
+ packageRoot = path.join(__dirname, ".."),
250
+ agent = "",
251
+ env = process.env,
252
+ homeDir = os.homedir(),
253
+ stderr = process.stderr,
254
+ } = {}) {
255
+ if (shouldSkipSkillInstall(env)) {
256
+ stderr.write(
257
+ "Skipping FastMoss CLI skill installation because FASTMOSS_SKIP_SKILL_INSTALL is set.\n",
258
+ );
259
+ return { installed: [], skipped: true };
260
+ }
261
+
262
+ const sourceSkillDir = path.join(packageRoot, "skills", SKILL_NAME);
263
+ if (!(await directoryExists(sourceSkillDir))) {
264
+ throw new Error(`FastMoss CLI skill not found: ${sourceSkillDir}`);
265
+ }
266
+
267
+ let targetRoots = resolveSkillInstallTargets({
268
+ agent: agent || env.FASTMOSS_SKILL_AGENT || "auto",
269
+ env,
270
+ homeDir,
271
+ });
272
+
273
+ const isAuto =
274
+ String(env.FASTMOSS_SKILL_DIR || "").trim() === "" &&
275
+ normalizeSkillAgent(agent || env.FASTMOSS_SKILL_AGENT) === "auto";
276
+ if (isAuto) {
277
+ const existingRoots = [];
278
+ for (const targetRoot of targetRoots) {
279
+ if (await directoryExists(targetRoot)) {
280
+ existingRoots.push(targetRoot);
281
+ }
282
+ }
283
+ targetRoots = existingRoots;
284
+ }
285
+
286
+ if (targetRoots.length === 0) {
287
+ stderr.write(
288
+ "Skipping FastMoss CLI skill installation because no supported agent skill directory was found. Set FASTMOSS_SKILL_AGENT=codex or FASTMOSS_SKILL_DIR to install explicitly.\n",
289
+ );
290
+ return { installed: [], skipped: true };
291
+ }
292
+
293
+ const installed = [];
294
+ for (const targetRoot of targetRoots) {
295
+ const targetSkillDir = path.join(targetRoot, SKILL_NAME);
296
+ await fs.promises.mkdir(targetRoot, { recursive: true });
297
+ await fs.promises.rm(targetSkillDir, { recursive: true, force: true });
298
+ await fs.promises.cp(sourceSkillDir, targetSkillDir, { recursive: true });
299
+ installed.push(targetSkillDir);
300
+ stderr.write(`Installed FastMoss CLI skill to ${targetSkillDir}\n`);
301
+ }
302
+
303
+ return { installed, skipped: false };
304
+ }
305
+
143
306
  async function installCLI({
144
307
  version,
145
308
  env = process.env,
@@ -181,6 +344,18 @@ async function fileExists(filePath) {
181
344
  }
182
345
  }
183
346
 
347
+ async function directoryExists(directoryPath) {
348
+ try {
349
+ const stat = await fs.promises.stat(directoryPath);
350
+ return stat.isDirectory();
351
+ } catch (error) {
352
+ if (error && error.code === "ENOENT") {
353
+ return false;
354
+ }
355
+ throw error;
356
+ }
357
+ }
358
+
184
359
  async function downloadFile(url, destination) {
185
360
  try {
186
361
  await downloadWithRedirects(url, destination, 0);
@@ -304,12 +479,16 @@ async function runCLI({
304
479
 
305
480
  module.exports = {
306
481
  DEFAULT_DOWNLOAD_BASE_URL,
482
+ INSTALL_SKILL_USAGE,
307
483
  buildDownloadURL,
308
484
  ensureBinary,
485
+ installSkill,
309
486
  installCLI,
487
+ parseInstallSkillArgs,
310
488
  resolveBinaryPath,
311
489
  resolveCacheRoot,
312
490
  resolveDownloadBaseURL,
491
+ resolveSkillInstallTargets,
313
492
  resolvePlatformTarget,
314
493
  runCLI,
315
494
  };
package/package.json CHANGED
@@ -1,15 +1,17 @@
1
1
  {
2
2
  "name": "@fastmoss/cli",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "FastMoss CLI launcher for npm and npx",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,
7
7
  "bin": {
8
- "fastmoss": "bin/fastmoss.js"
8
+ "fastmoss": "bin/fastmoss.js",
9
+ "fastmoss-install-skill": "bin/install-skill.js"
9
10
  },
10
11
  "files": [
11
12
  "bin",
12
13
  "lib",
14
+ "skills",
13
15
  "README.md",
14
16
  "README.zh-CN.md"
15
17
  ],
@@ -0,0 +1,70 @@
1
+ ---
2
+ name: fastmoss-cli
3
+ description: Use when working with FastMoss CLI, FastMoss MCP tools, TikTok Shop product, creator, shop, video, ad, category, or market data, or when the user asks an agent to call FastMoss tools from the command line.
4
+ ---
5
+
6
+ # FastMoss CLI
7
+
8
+ Use the `fastmoss` command to discover and call FastMoss tools.
9
+
10
+ ## Startup checks
11
+
12
+ 1. Check the CLI is available:
13
+
14
+ ```bash
15
+ fastmoss --version
16
+ ```
17
+
18
+ If the FastMoss CLI is not installed or the command is not found, install it first:
19
+
20
+ ```bash
21
+ npm install -g @fastmoss/cli
22
+ ```
23
+
24
+ To update an existing FastMoss CLI installation to the latest package version, run:
25
+
26
+ ```bash
27
+ npm install -g @fastmoss/cli@latest
28
+ ```
29
+
30
+ Then continue to the login check.
31
+
32
+ 2. Check login status:
33
+
34
+ ```bash
35
+ fastmoss whoami
36
+ ```
37
+
38
+ 3. If not logged in, ask the user to provide or configure an API key:
39
+
40
+ ```bash
41
+ fastmoss login --api-key <your-api-key>
42
+ ```
43
+
44
+ ## Tool workflow
45
+
46
+ 1. Read `references/tool-call.md` before invoking a tool.
47
+ 2. Read `references/tools.md` to choose the tool and understand its parameters.
48
+ 3. Every `fastmoss call` MUST include agent client metadata. Prefer environment variables when making one or more calls in the same shell session:
49
+
50
+ ```bash
51
+ FASTMOSS_CLIENT_NAME="<client-name>" FASTMOSS_CLIENT_VERSION="<client-version>" fastmoss call --tool <tool_name> --args '<json>' --output mcp
52
+ ```
53
+
54
+ Or pass explicit flags for a single call:
55
+
56
+ ```bash
57
+ fastmoss call --client-name "<client-name>" --client-version "<client-version>" --tool <tool_name> --args '<json>' --output mcp
58
+ ```
59
+
60
+ Use the actual client name and version when available. Do not invent a version number; if the runtime does not expose a version, use the client name and omit the version only if the CLI allows it.
61
+
62
+ Prefer `--output mcp` when an LLM or agent will read and reason over the tool response. Use `--output data` when the user needs a concise end-user payload. Use `--output rpc` only when debugging raw RPC responses.
63
+
64
+ If the analysis result needs FastMoss detail-page links, call `fastmoss_detail_url_examples` first to get the link assembly rules, then build links from the returned examples and IDs in the analysis result.
65
+
66
+ ## References
67
+
68
+ - `references/cli.md`: CLI command reference.
69
+ - `references/tool-call.md`: safe calling patterns, quoting, output modes, and error handling.
70
+ - `references/tools.md`: static FastMoss tool catalog index. Read the matching category file from this index instead of loading all tools at once.
@@ -0,0 +1,3 @@
1
+ display_name: FastMoss CLI
2
+ short_description: Use FastMoss command-line tools from an agent.
3
+ default_prompt: Use FastMoss CLI to find the right FastMoss tool, call it with JSON arguments, and summarize the result for the user.