@fastmoss/cli 0.1.6 → 0.1.14
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 +131 -186
- package/README.zh-CN.md +131 -178
- package/bin/fastmoss.js +12 -7
- package/lib/runtime.js +56 -461
- package/lib/targets.js +65 -0
- package/package.json +22 -9
- package/bin/install-skill.js +0 -34
- package/bin/postinstall.js +0 -12
- package/skills/fastmoss-cli/SKILL.md +0 -70
- package/skills/fastmoss-cli/agents/openai.yaml +0 -3
- package/skills/fastmoss-cli/data/tools.json +0 -4014
- package/skills/fastmoss-cli/references/cli.md +0 -70
- package/skills/fastmoss-cli/references/tool-call.md +0 -103
- package/skills/fastmoss-cli/references/tools-advertising.md +0 -48
- package/skills/fastmoss-cli/references/tools-agency.md +0 -145
- package/skills/fastmoss-cli/references/tools-auxiliary-knowledge.md +0 -200
- package/skills/fastmoss-cli/references/tools-creator.md +0 -197
- package/skills/fastmoss-cli/references/tools-market.md +0 -69
- package/skills/fastmoss-cli/references/tools-product.md +0 -230
- package/skills/fastmoss-cli/references/tools-shop.md +0 -200
- package/skills/fastmoss-cli/references/tools.md +0 -26
package/lib/runtime.js
CHANGED
|
@@ -1,494 +1,89 @@
|
|
|
1
1
|
const fs = require("node:fs");
|
|
2
|
-
const os = require("node:os");
|
|
3
2
|
const path = require("node:path");
|
|
4
|
-
const http = require("node:http");
|
|
5
|
-
const https = require("node:https");
|
|
6
|
-
const { pipeline } = require("node:stream/promises");
|
|
7
3
|
const { spawn } = require("node:child_process");
|
|
4
|
+
const { resolvePlatformTarget } = require("./targets");
|
|
8
5
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
`;
|
|
24
|
-
|
|
25
|
-
const PLATFORM_TARGETS = {
|
|
26
|
-
"darwin:x64": {
|
|
27
|
-
assetName: "fastmoss-darwin-amd64",
|
|
28
|
-
binaryName: "fastmoss",
|
|
29
|
-
cacheKey: "darwin-amd64",
|
|
30
|
-
},
|
|
31
|
-
"darwin:arm64": {
|
|
32
|
-
assetName: "fastmoss-darwin-arm64",
|
|
33
|
-
binaryName: "fastmoss",
|
|
34
|
-
cacheKey: "darwin-arm64",
|
|
35
|
-
},
|
|
36
|
-
"linux:x64": {
|
|
37
|
-
assetName: "fastmoss-linux-amd64",
|
|
38
|
-
binaryName: "fastmoss",
|
|
39
|
-
cacheKey: "linux-amd64",
|
|
40
|
-
},
|
|
41
|
-
"linux:arm64": {
|
|
42
|
-
assetName: "fastmoss-linux-arm64",
|
|
43
|
-
binaryName: "fastmoss",
|
|
44
|
-
cacheKey: "linux-arm64",
|
|
45
|
-
},
|
|
46
|
-
"win32:x64": {
|
|
47
|
-
assetName: "fastmoss-windows-amd64.exe",
|
|
48
|
-
binaryName: "fastmoss.exe",
|
|
49
|
-
cacheKey: "windows-amd64",
|
|
50
|
-
},
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
function resolvePlatformTarget({
|
|
54
|
-
platform = process.platform,
|
|
55
|
-
arch = process.arch,
|
|
56
|
-
} = {}) {
|
|
57
|
-
const key = `${platform}:${arch}`;
|
|
58
|
-
const target = PLATFORM_TARGETS[key];
|
|
59
|
-
if (!target) {
|
|
60
|
-
throw new Error(
|
|
61
|
-
`Unsupported platform: ${platform}/${arch}. Supported targets: ${Object.keys(
|
|
62
|
-
PLATFORM_TARGETS,
|
|
63
|
-
)
|
|
64
|
-
.map((value) => value.replace(":", "/"))
|
|
65
|
-
.join(", ")}`,
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
return target;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function resolveCacheRoot({
|
|
72
|
-
env = process.env,
|
|
73
|
-
homeDir = os.homedir(),
|
|
74
|
-
} = {}) {
|
|
75
|
-
const override = String(env.FASTMOSS_CACHE_DIR || "").trim();
|
|
76
|
-
if (override !== "") {
|
|
77
|
-
return override;
|
|
78
|
-
}
|
|
79
|
-
return path.join(homeDir, ".fastmoss", "bin");
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function resolveBinaryPath({ cacheRoot, version, target }) {
|
|
83
|
-
return path.join(cacheRoot, version, target.cacheKey, target.binaryName);
|
|
6
|
+
function reinstallMessage(version) {
|
|
7
|
+
return [
|
|
8
|
+
`Run: npm install -g @fastmoss/cli@${version}`,
|
|
9
|
+
"Do not install with --omit=optional.",
|
|
10
|
+
].join("\n");
|
|
84
11
|
}
|
|
85
12
|
|
|
86
|
-
function
|
|
87
|
-
env = process.env,
|
|
88
|
-
configuredDownloadBaseURL = "",
|
|
89
|
-
} = {}) {
|
|
90
|
-
const envOverride = String(env.FASTMOSS_DOWNLOAD_BASE_URL || "").trim();
|
|
91
|
-
if (envOverride !== "") {
|
|
92
|
-
return envOverride.replace(/\/+$/, "");
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const configured = String(configuredDownloadBaseURL || "").trim();
|
|
96
|
-
if (configured !== "") {
|
|
97
|
-
return configured.replace(/\/+$/, "");
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return DEFAULT_DOWNLOAD_BASE_URL;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function buildDownloadURL({
|
|
13
|
+
function resolvePlatformBinary({
|
|
104
14
|
version,
|
|
105
|
-
target,
|
|
106
|
-
env = process.env,
|
|
107
|
-
configuredDownloadBaseURL = "",
|
|
108
|
-
}) {
|
|
109
|
-
const baseURL = resolveDownloadBaseURL({ env, configuredDownloadBaseURL });
|
|
110
|
-
return `${baseURL}/v${version}/${target.assetName}`;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
async function ensureBinary({
|
|
114
|
-
version,
|
|
115
|
-
env = process.env,
|
|
116
15
|
platform = process.platform,
|
|
117
16
|
arch = process.arch,
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}) {
|
|
123
|
-
const target = resolvePlatformTarget({ platform, arch });
|
|
124
|
-
const cacheRoot = resolveCacheRoot({ env, homeDir });
|
|
125
|
-
const binaryPath = resolveBinaryPath({ cacheRoot, version, target });
|
|
126
|
-
|
|
127
|
-
if (await fileExists(binaryPath)) {
|
|
128
|
-
return { binaryPath, downloaded: false };
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
await fs.promises.mkdir(path.dirname(binaryPath), { recursive: true });
|
|
132
|
-
const downloadURL = buildDownloadURL({
|
|
133
|
-
version,
|
|
134
|
-
target,
|
|
135
|
-
env,
|
|
136
|
-
configuredDownloadBaseURL,
|
|
137
|
-
});
|
|
138
|
-
const tempPath = `${binaryPath}.download`;
|
|
139
|
-
|
|
140
|
-
onDownloadStart(downloadURL);
|
|
141
|
-
await downloadFileFn(downloadURL, tempPath);
|
|
142
|
-
|
|
143
|
-
if (platform !== "win32") {
|
|
144
|
-
await fs.promises.chmod(tempPath, 0o755);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
await fs.promises.rename(tempPath, binaryPath);
|
|
148
|
-
return { binaryPath, downloaded: true, downloadURL };
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function shouldSkipDownload(env = process.env) {
|
|
152
|
-
const value = String(env.FASTMOSS_SKIP_DOWNLOAD || "").trim().toLowerCase();
|
|
153
|
-
return value !== "" && value !== "0" && value !== "false";
|
|
154
|
-
}
|
|
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(),
|
|
17
|
+
resolvePackageJSON = (packageName) =>
|
|
18
|
+
require.resolve(`${packageName}/package.json`),
|
|
19
|
+
readFileSync = fs.readFileSync,
|
|
20
|
+
accessSync = fs.accessSync,
|
|
197
21
|
} = {}) {
|
|
198
|
-
const
|
|
199
|
-
|
|
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
|
-
|
|
306
|
-
async function installCLI({
|
|
307
|
-
version,
|
|
308
|
-
env = process.env,
|
|
309
|
-
platform = process.platform,
|
|
310
|
-
arch = process.arch,
|
|
311
|
-
homeDir = os.homedir(),
|
|
312
|
-
stderr = process.stderr,
|
|
313
|
-
configuredDownloadBaseURL = "",
|
|
314
|
-
} = {}) {
|
|
315
|
-
if (shouldSkipDownload(env)) {
|
|
316
|
-
stderr.write(
|
|
317
|
-
"Skipping fastmoss binary download because FASTMOSS_SKIP_DOWNLOAD is set.\n",
|
|
318
|
-
);
|
|
319
|
-
return { skipped: true };
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
return ensureBinary({
|
|
323
|
-
version,
|
|
324
|
-
env,
|
|
325
|
-
platform,
|
|
326
|
-
arch,
|
|
327
|
-
homeDir,
|
|
328
|
-
configuredDownloadBaseURL,
|
|
329
|
-
onDownloadStart(downloadURL) {
|
|
330
|
-
stderr.write(`Downloading fastmoss ${version} from ${downloadURL}\n`);
|
|
331
|
-
},
|
|
332
|
-
});
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
async function fileExists(filePath) {
|
|
22
|
+
const target = resolvePlatformTarget({ platform, arch });
|
|
23
|
+
let packageJSONPath;
|
|
336
24
|
try {
|
|
337
|
-
|
|
338
|
-
return stat.isFile() && stat.size > 0;
|
|
25
|
+
packageJSONPath = resolvePackageJSON(target.packageName);
|
|
339
26
|
} catch (error) {
|
|
340
|
-
if (error
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
27
|
+
if (!error || error.code !== "MODULE_NOT_FOUND") throw error;
|
|
28
|
+
throw new Error(
|
|
29
|
+
[
|
|
30
|
+
`FastMoss binary package for ${platform}/${arch} is missing: ${target.packageName}.`,
|
|
31
|
+
reinstallMessage(version),
|
|
32
|
+
].join("\n"),
|
|
33
|
+
);
|
|
344
34
|
}
|
|
345
|
-
}
|
|
346
35
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
throw error;
|
|
36
|
+
const platformPackage = JSON.parse(readFileSync(packageJSONPath, "utf8"));
|
|
37
|
+
if (platformPackage.version !== version) {
|
|
38
|
+
throw new Error(
|
|
39
|
+
[
|
|
40
|
+
`FastMoss platform package version mismatch: expected ${version}, found ${platformPackage.version}.`,
|
|
41
|
+
reinstallMessage(version),
|
|
42
|
+
].join("\n"),
|
|
43
|
+
);
|
|
356
44
|
}
|
|
357
|
-
}
|
|
358
45
|
|
|
359
|
-
|
|
46
|
+
const binaryPath = path.join(
|
|
47
|
+
path.dirname(packageJSONPath),
|
|
48
|
+
"bin",
|
|
49
|
+
target.binaryName,
|
|
50
|
+
);
|
|
360
51
|
try {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
throw error;
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
function downloadWithRedirects(url, destination, redirectCount) {
|
|
369
|
-
if (redirectCount > 5) {
|
|
370
|
-
return Promise.reject(new Error("Too many redirects while downloading fastmoss"));
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
return new Promise((resolve, reject) => {
|
|
374
|
-
const client = url.startsWith("https://") ? https : http;
|
|
375
|
-
const request = client.get(
|
|
376
|
-
url,
|
|
377
|
-
{
|
|
378
|
-
headers: {
|
|
379
|
-
"User-Agent": "fastmoss-npm-wrapper",
|
|
380
|
-
},
|
|
381
|
-
},
|
|
382
|
-
async (response) => {
|
|
383
|
-
const statusCode = response.statusCode || 0;
|
|
384
|
-
|
|
385
|
-
if (
|
|
386
|
-
statusCode >= 300 &&
|
|
387
|
-
statusCode < 400 &&
|
|
388
|
-
response.headers.location
|
|
389
|
-
) {
|
|
390
|
-
response.resume();
|
|
391
|
-
try {
|
|
392
|
-
await downloadWithRedirects(
|
|
393
|
-
response.headers.location,
|
|
394
|
-
destination,
|
|
395
|
-
redirectCount + 1,
|
|
396
|
-
);
|
|
397
|
-
resolve();
|
|
398
|
-
} catch (error) {
|
|
399
|
-
reject(error);
|
|
400
|
-
}
|
|
401
|
-
return;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
if (statusCode !== 200) {
|
|
405
|
-
response.resume();
|
|
406
|
-
reject(
|
|
407
|
-
new Error(
|
|
408
|
-
`Failed to download fastmoss binary: HTTP ${statusCode} from ${url}`,
|
|
409
|
-
),
|
|
410
|
-
);
|
|
411
|
-
return;
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
const output = fs.createWriteStream(destination, { mode: 0o755 });
|
|
415
|
-
try {
|
|
416
|
-
await pipeline(response, output);
|
|
417
|
-
resolve();
|
|
418
|
-
} catch (error) {
|
|
419
|
-
reject(error);
|
|
420
|
-
}
|
|
421
|
-
},
|
|
52
|
+
accessSync(
|
|
53
|
+
binaryPath,
|
|
54
|
+
platform === "win32" ? fs.constants.F_OK : fs.constants.X_OK,
|
|
422
55
|
);
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
56
|
+
} catch {
|
|
57
|
+
throw new Error(
|
|
58
|
+
[
|
|
59
|
+
`FastMoss binary is missing or not executable: ${binaryPath}.`,
|
|
60
|
+
reinstallMessage(version),
|
|
61
|
+
].join("\n"),
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
return { binaryPath, target };
|
|
426
65
|
}
|
|
427
66
|
|
|
428
67
|
async function runCLI({
|
|
429
68
|
version,
|
|
430
69
|
args = process.argv.slice(2),
|
|
431
|
-
env = process.env,
|
|
432
70
|
platform = process.platform,
|
|
433
71
|
arch = process.arch,
|
|
434
|
-
homeDir = os.homedir(),
|
|
435
72
|
stdout = process.stdout,
|
|
436
|
-
|
|
437
|
-
|
|
73
|
+
resolveBinary = resolvePlatformBinary,
|
|
74
|
+
spawnFn = spawn,
|
|
438
75
|
} = {}) {
|
|
439
|
-
if (
|
|
440
|
-
args.length === 1 &&
|
|
441
|
-
["--version", "-v", "version"].includes(args[0])
|
|
442
|
-
) {
|
|
76
|
+
if (args.length === 1 && ["--version", "-v", "version"].includes(args[0])) {
|
|
443
77
|
stdout.write(`${version}\n`);
|
|
444
|
-
return;
|
|
78
|
+
return { code: 0, signal: null };
|
|
445
79
|
}
|
|
446
80
|
|
|
447
|
-
const { binaryPath
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
homeDir,
|
|
453
|
-
configuredDownloadBaseURL,
|
|
454
|
-
onDownloadStart(downloadURL) {
|
|
455
|
-
stderr.write(`Downloading fastmoss ${version} from ${downloadURL}\n`);
|
|
456
|
-
},
|
|
457
|
-
});
|
|
458
|
-
|
|
459
|
-
if (downloaded) {
|
|
460
|
-
stderr.write(`Downloaded fastmoss ${version} to ${binaryPath}\n`);
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
await new Promise((resolve, reject) => {
|
|
464
|
-
const child = spawn(binaryPath, args, {
|
|
465
|
-
stdio: ["inherit", stdout, stderr],
|
|
466
|
-
});
|
|
467
|
-
|
|
468
|
-
child.on("error", reject);
|
|
469
|
-
child.on("exit", (code, signal) => {
|
|
470
|
-
if (signal) {
|
|
471
|
-
reject(new Error(`fastmoss exited with signal ${signal}`));
|
|
472
|
-
return;
|
|
473
|
-
}
|
|
474
|
-
process.exitCode = code || 0;
|
|
475
|
-
resolve();
|
|
476
|
-
});
|
|
81
|
+
const { binaryPath } = resolveBinary({ version, platform, arch });
|
|
82
|
+
return new Promise((resolve, reject) => {
|
|
83
|
+
const child = spawnFn(binaryPath, args, { stdio: "inherit" });
|
|
84
|
+
child.once("error", reject);
|
|
85
|
+
child.once("exit", (code, signal) => resolve({ code, signal }));
|
|
477
86
|
});
|
|
478
87
|
}
|
|
479
88
|
|
|
480
|
-
module.exports = {
|
|
481
|
-
DEFAULT_DOWNLOAD_BASE_URL,
|
|
482
|
-
INSTALL_SKILL_USAGE,
|
|
483
|
-
buildDownloadURL,
|
|
484
|
-
ensureBinary,
|
|
485
|
-
installSkill,
|
|
486
|
-
installCLI,
|
|
487
|
-
parseInstallSkillArgs,
|
|
488
|
-
resolveBinaryPath,
|
|
489
|
-
resolveCacheRoot,
|
|
490
|
-
resolveDownloadBaseURL,
|
|
491
|
-
resolveSkillInstallTargets,
|
|
492
|
-
resolvePlatformTarget,
|
|
493
|
-
runCLI,
|
|
494
|
-
};
|
|
89
|
+
module.exports = { reinstallMessage, resolvePlatformBinary, runCLI };
|
package/lib/targets.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const PLATFORM_TARGETS = Object.freeze({
|
|
2
|
+
"darwin:x64": Object.freeze({
|
|
3
|
+
packageName: "@fastmoss/cli-darwin-amd64",
|
|
4
|
+
packageDir: "cli-darwin-amd64",
|
|
5
|
+
assetName: "fastmoss-darwin-amd64",
|
|
6
|
+
binaryName: "fastmoss-darwin-amd64",
|
|
7
|
+
buildPath: "darwin-amd64/fastmoss",
|
|
8
|
+
os: "darwin",
|
|
9
|
+
cpu: "x64",
|
|
10
|
+
}),
|
|
11
|
+
"darwin:arm64": Object.freeze({
|
|
12
|
+
packageName: "@fastmoss/cli-darwin-arm64",
|
|
13
|
+
packageDir: "cli-darwin-arm64",
|
|
14
|
+
assetName: "fastmoss-darwin-arm64",
|
|
15
|
+
binaryName: "fastmoss-darwin-arm64",
|
|
16
|
+
buildPath: "darwin-arm64/fastmoss",
|
|
17
|
+
os: "darwin",
|
|
18
|
+
cpu: "arm64",
|
|
19
|
+
}),
|
|
20
|
+
"linux:x64": Object.freeze({
|
|
21
|
+
packageName: "@fastmoss/cli-linux-amd64",
|
|
22
|
+
packageDir: "cli-linux-amd64",
|
|
23
|
+
assetName: "fastmoss-linux-amd64",
|
|
24
|
+
binaryName: "fastmoss-linux-amd64",
|
|
25
|
+
buildPath: "linux-amd64/fastmoss",
|
|
26
|
+
os: "linux",
|
|
27
|
+
cpu: "x64",
|
|
28
|
+
}),
|
|
29
|
+
"linux:arm64": Object.freeze({
|
|
30
|
+
packageName: "@fastmoss/cli-linux-arm64",
|
|
31
|
+
packageDir: "cli-linux-arm64",
|
|
32
|
+
assetName: "fastmoss-linux-arm64",
|
|
33
|
+
binaryName: "fastmoss-linux-arm64",
|
|
34
|
+
buildPath: "linux-arm64/fastmoss",
|
|
35
|
+
os: "linux",
|
|
36
|
+
cpu: "arm64",
|
|
37
|
+
}),
|
|
38
|
+
"win32:x64": Object.freeze({
|
|
39
|
+
packageName: "@fastmoss/cli-windows-amd64",
|
|
40
|
+
packageDir: "cli-windows-amd64",
|
|
41
|
+
assetName: "fastmoss-windows-amd64.exe",
|
|
42
|
+
binaryName: "fastmoss-windows-amd64.exe",
|
|
43
|
+
buildPath: "windows-amd64/fastmoss.exe",
|
|
44
|
+
os: "win32",
|
|
45
|
+
cpu: "x64",
|
|
46
|
+
}),
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
function resolvePlatformTarget({
|
|
50
|
+
platform = process.platform,
|
|
51
|
+
arch = process.arch,
|
|
52
|
+
} = {}) {
|
|
53
|
+
const target = PLATFORM_TARGETS[`${platform}:${arch}`];
|
|
54
|
+
if (!target) {
|
|
55
|
+
const supported = Object.keys(PLATFORM_TARGETS)
|
|
56
|
+
.map((key) => key.replace(":", "/"))
|
|
57
|
+
.join(", ");
|
|
58
|
+
throw new Error(
|
|
59
|
+
`Unsupported platform: ${platform}/${arch}. Supported targets: ${supported}`,
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
return target;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
module.exports = { PLATFORM_TARGETS, resolvePlatformTarget };
|
package/package.json
CHANGED
|
@@ -1,28 +1,41 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fastmoss/cli",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "FastMoss CLI
|
|
3
|
+
"version": "0.1.14",
|
|
4
|
+
"description": "FastMoss CLI for npm and npx",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"fastmoss",
|
|
7
|
+
"tiktok-shop",
|
|
8
|
+
"ecommerce-research",
|
|
9
|
+
"product-research",
|
|
10
|
+
"creator-analytics",
|
|
11
|
+
"shop-analytics",
|
|
12
|
+
"advertising-analytics",
|
|
13
|
+
"market-intelligence",
|
|
14
|
+
"mcp",
|
|
15
|
+
"ai-agent"
|
|
16
|
+
],
|
|
5
17
|
"license": "UNLICENSED",
|
|
6
18
|
"private": false,
|
|
7
19
|
"bin": {
|
|
8
|
-
"fastmoss": "bin/fastmoss.js"
|
|
9
|
-
"fastmoss-install-skill": "bin/install-skill.js"
|
|
20
|
+
"fastmoss": "bin/fastmoss.js"
|
|
10
21
|
},
|
|
11
22
|
"files": [
|
|
12
23
|
"bin",
|
|
13
24
|
"lib",
|
|
14
|
-
"skills",
|
|
15
25
|
"README.md",
|
|
16
26
|
"README.zh-CN.md"
|
|
17
27
|
],
|
|
18
28
|
"scripts": {
|
|
19
|
-
"postinstall": "node ./bin/postinstall.js",
|
|
20
29
|
"test": "node --test ./test/*.test.js"
|
|
21
30
|
},
|
|
31
|
+
"optionalDependencies": {
|
|
32
|
+
"@fastmoss/cli-darwin-amd64": "0.1.14",
|
|
33
|
+
"@fastmoss/cli-darwin-arm64": "0.1.14",
|
|
34
|
+
"@fastmoss/cli-linux-amd64": "0.1.14",
|
|
35
|
+
"@fastmoss/cli-linux-arm64": "0.1.14",
|
|
36
|
+
"@fastmoss/cli-windows-amd64": "0.1.14"
|
|
37
|
+
},
|
|
22
38
|
"engines": {
|
|
23
39
|
"node": ">=18"
|
|
24
|
-
},
|
|
25
|
-
"fastmoss": {
|
|
26
|
-
"downloadBaseURL": "https://github.com/FastMoss/cli/releases/download"
|
|
27
40
|
}
|
|
28
41
|
}
|
package/bin/install-skill.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
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
|
-
});
|