@aisa-one/cli 0.2.2 → 0.2.3
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/CHANGELOG.md +134 -1
- package/README.md +249 -103
- package/dist/api.d.ts +46 -1
- package/dist/api.js +77 -8
- package/dist/cache.d.ts +18 -0
- package/dist/cache.js +65 -0
- package/dist/catalog.d.ts +90 -0
- package/dist/catalog.js +101 -0
- package/dist/commands/account.js +3 -1
- package/dist/commands/api.d.ts +18 -4
- package/dist/commands/api.js +357 -24
- package/dist/commands/cacheCmd.d.ts +2 -0
- package/dist/commands/cacheCmd.js +10 -0
- package/dist/commands/completionCmd.d.ts +7 -0
- package/dist/commands/completionCmd.js +37 -0
- package/dist/commands/configCmd.js +19 -1
- package/dist/commands/finance.d.ts +4 -0
- package/dist/commands/finance.js +212 -29
- package/dist/commands/models.js +6 -0
- package/dist/commands/run.d.ts +21 -0
- package/dist/commands/run.js +113 -6
- package/dist/commands/search.js +8 -3
- package/dist/commands/skills.d.ts +6 -2
- package/dist/commands/skills.js +189 -134
- package/dist/commands/twitter.js +2 -3
- package/dist/commands/video.d.ts +40 -0
- package/dist/commands/video.js +272 -55
- package/dist/completion.d.ts +26 -0
- package/dist/completion.js +293 -0
- package/dist/constants.d.ts +55 -5
- package/dist/constants.js +136 -11
- package/dist/index.js +84 -22
- package/dist/skills-registry.d.ts +64 -0
- package/dist/skills-registry.js +219 -0
- package/dist/types.d.ts +24 -0
- package/dist/utils/file.d.ts +5 -1
- package/dist/utils/file.js +5 -1
- package/dist/utils/pool.d.ts +8 -0
- package/dist/utils/pool.js +27 -0
- package/package.json +9 -3
- package/tests/account.test.ts +0 -89
- package/tests/streaming.test.ts +0 -73
package/dist/constants.d.ts
CHANGED
|
@@ -1,15 +1,65 @@
|
|
|
1
|
-
export declare const VERSION = "0.2.
|
|
1
|
+
export declare const VERSION = "0.2.3";
|
|
2
|
+
/** Root of the platform. Per-surface bases are derived in api.ts#resolveBases. */
|
|
2
3
|
export declare const BASE_URL = "https://api.aisa.one";
|
|
3
|
-
export declare const CLI_BASE_URL = "https://api.aisa.one/v1";
|
|
4
|
-
export declare const APIS_BASE_URL = "https://api.aisa.one/apis/v1";
|
|
5
4
|
export declare const ENV_VAR_NAME = "AISA_API_KEY";
|
|
6
5
|
export declare const MCP_URL = "https://docs.aisa.one/mcp";
|
|
6
|
+
/**
|
|
7
|
+
* First path segment of every route the LLM gateway serves under /v1 (plus
|
|
8
|
+
* /v1beta for Gemini). Everything else is an integration API under /apis/v1.
|
|
9
|
+
*
|
|
10
|
+
* This list is deliberately the whitelist rather than the provider slugs: the
|
|
11
|
+
* gateway routes are hardcoded server-side and change about once a year, while
|
|
12
|
+
* provider slugs are data that operations add and remove continuously. Keeping
|
|
13
|
+
* the whitelist on the slow-moving side means a newly added provider works
|
|
14
|
+
* without a CLI release.
|
|
15
|
+
*/
|
|
16
|
+
export declare const LLM_ROUTE_PREFIXES: readonly string[];
|
|
7
17
|
export declare const AGENT_DIRS: Record<string, string>;
|
|
8
18
|
export declare const MCP_CONFIGS: Record<string, {
|
|
9
19
|
path: string;
|
|
10
20
|
key: string;
|
|
11
21
|
}>;
|
|
12
|
-
|
|
13
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Ticker symbol → CoinGecko coin id.
|
|
24
|
+
*
|
|
25
|
+
* CoinGecko keys everything by id ("bitcoin"), not symbol ("BTC"), and dozens
|
|
26
|
+
* of unrelated tokens share popular symbols — resolving by symbol alone would
|
|
27
|
+
* happily return the price of the wrong coin. This table covers the symbols
|
|
28
|
+
* people actually type; anything else falls back to an explicit lookup.
|
|
29
|
+
*/
|
|
30
|
+
export declare const COINGECKO_IDS: Record<string, string>;
|
|
31
|
+
/**
|
|
32
|
+
* Models routed to /v1/video/generations, and the request body each one wants.
|
|
33
|
+
*
|
|
34
|
+
* The gateway only rewrites the top-level `model` and passes the rest through,
|
|
35
|
+
* so the body shape belongs to whichever vendor owns the model — a Bailian-style
|
|
36
|
+
* `{input, parameters}` sent to Seedance is rejected outright with a 400.
|
|
37
|
+
*
|
|
38
|
+
* `requiresMedia` records the `input.media[].type` an image/clip-driven model
|
|
39
|
+
* needs. Without it the upstream accepts the submission and only fails a minute
|
|
40
|
+
* later, after billing, so the CLI refuses up front instead.
|
|
41
|
+
*/
|
|
42
|
+
export type VideoFamily = "bailian" | "seedance";
|
|
43
|
+
export interface VideoModelSpec {
|
|
44
|
+
family: VideoFamily;
|
|
45
|
+
requiresMedia?: MediaType;
|
|
46
|
+
}
|
|
47
|
+
/** Accepted values for `input.media[].type` (enumerated by the upstream error). */
|
|
48
|
+
export declare const MEDIA_TYPES: readonly ["first_frame", "last_frame", "driving_audio", "first_clip"];
|
|
49
|
+
export type MediaType = (typeof MEDIA_TYPES)[number];
|
|
50
|
+
export declare const VIDEO_MODELS: Record<string, VideoModelSpec>;
|
|
51
|
+
export declare const DEFAULT_VIDEO_MODEL = "wan2.7-t2v";
|
|
52
|
+
/** Model families are matched by prefix so new revisions work without a release. */
|
|
53
|
+
export declare function videoModelSpec(model: string): VideoModelSpec;
|
|
54
|
+
/**
|
|
55
|
+
* Client-side grouping of integration providers.
|
|
56
|
+
*
|
|
57
|
+
* The catalog returns no description or tags — `buildCatalogItem` never
|
|
58
|
+
* populates them — so there is nothing server-side to filter on. Entries are
|
|
59
|
+
* matched by prefix, which keeps the polymarket-* family together.
|
|
60
|
+
*/
|
|
61
|
+
export declare const PROVIDER_CATEGORIES: Record<string, string[]>;
|
|
62
|
+
export declare function categoryOf(providerId: string): string;
|
|
63
|
+
export declare const API_CATEGORIES: readonly [...string[], "other"];
|
|
14
64
|
export declare const MODEL_PROVIDERS: readonly ["openai", "anthropic", "google", "deepseek", "xai", "moonshot", "alibaba", "bytedance"];
|
|
15
65
|
export type ModelProvider = (typeof MODEL_PROVIDERS)[number];
|
package/dist/constants.js
CHANGED
|
@@ -1,9 +1,31 @@
|
|
|
1
|
-
export const VERSION = "0.2.
|
|
1
|
+
export const VERSION = "0.2.3";
|
|
2
|
+
/** Root of the platform. Per-surface bases are derived in api.ts#resolveBases. */
|
|
2
3
|
export const BASE_URL = "https://api.aisa.one";
|
|
3
|
-
export const CLI_BASE_URL = `${BASE_URL}/v1`;
|
|
4
|
-
export const APIS_BASE_URL = `${BASE_URL}/apis/v1`;
|
|
5
4
|
export const ENV_VAR_NAME = "AISA_API_KEY";
|
|
6
5
|
export const MCP_URL = "https://docs.aisa.one/mcp";
|
|
6
|
+
/**
|
|
7
|
+
* First path segment of every route the LLM gateway serves under /v1 (plus
|
|
8
|
+
* /v1beta for Gemini). Everything else is an integration API under /apis/v1.
|
|
9
|
+
*
|
|
10
|
+
* This list is deliberately the whitelist rather than the provider slugs: the
|
|
11
|
+
* gateway routes are hardcoded server-side and change about once a year, while
|
|
12
|
+
* provider slugs are data that operations add and remove continuously. Keeping
|
|
13
|
+
* the whitelist on the slow-moving side means a newly added provider works
|
|
14
|
+
* without a CLI release.
|
|
15
|
+
*/
|
|
16
|
+
export const LLM_ROUTE_PREFIXES = [
|
|
17
|
+
"chat",
|
|
18
|
+
"responses",
|
|
19
|
+
"embeddings",
|
|
20
|
+
"messages",
|
|
21
|
+
"models",
|
|
22
|
+
"rerank",
|
|
23
|
+
"classify",
|
|
24
|
+
"images",
|
|
25
|
+
"credits",
|
|
26
|
+
"video",
|
|
27
|
+
"v1beta",
|
|
28
|
+
];
|
|
7
29
|
export const AGENT_DIRS = {
|
|
8
30
|
claude: "~/.claude/skills/",
|
|
9
31
|
cursor: "~/.cursor/skills/",
|
|
@@ -24,14 +46,117 @@ export const MCP_CONFIGS = {
|
|
|
24
46
|
key: "mcpServers",
|
|
25
47
|
},
|
|
26
48
|
};
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Ticker symbol → CoinGecko coin id.
|
|
51
|
+
*
|
|
52
|
+
* CoinGecko keys everything by id ("bitcoin"), not symbol ("BTC"), and dozens
|
|
53
|
+
* of unrelated tokens share popular symbols — resolving by symbol alone would
|
|
54
|
+
* happily return the price of the wrong coin. This table covers the symbols
|
|
55
|
+
* people actually type; anything else falls back to an explicit lookup.
|
|
56
|
+
*/
|
|
57
|
+
export const COINGECKO_IDS = {
|
|
58
|
+
btc: "bitcoin",
|
|
59
|
+
eth: "ethereum",
|
|
60
|
+
usdt: "tether",
|
|
61
|
+
bnb: "binancecoin",
|
|
62
|
+
sol: "solana",
|
|
63
|
+
usdc: "usd-coin",
|
|
64
|
+
xrp: "ripple",
|
|
65
|
+
doge: "dogecoin",
|
|
66
|
+
ada: "cardano",
|
|
67
|
+
trx: "tron",
|
|
68
|
+
avax: "avalanche-2",
|
|
69
|
+
shib: "shiba-inu",
|
|
70
|
+
dot: "polkadot",
|
|
71
|
+
link: "chainlink",
|
|
72
|
+
bch: "bitcoin-cash",
|
|
73
|
+
near: "near",
|
|
74
|
+
matic: "matic-network",
|
|
75
|
+
ltc: "litecoin",
|
|
76
|
+
icp: "internet-computer",
|
|
77
|
+
uni: "uniswap",
|
|
78
|
+
leo: "leo-token",
|
|
79
|
+
dai: "dai",
|
|
80
|
+
etc: "ethereum-classic",
|
|
81
|
+
apt: "aptos",
|
|
82
|
+
render: "render-token",
|
|
83
|
+
hbar: "hedera-hashgraph",
|
|
84
|
+
fil: "filecoin",
|
|
85
|
+
arb: "arbitrum",
|
|
86
|
+
atom: "cosmos",
|
|
87
|
+
imx: "immutable-x",
|
|
88
|
+
op: "optimism",
|
|
89
|
+
vet: "vechain",
|
|
90
|
+
inj: "injective-protocol",
|
|
91
|
+
sui: "sui",
|
|
92
|
+
ton: "the-open-network",
|
|
93
|
+
pepe: "pepe",
|
|
94
|
+
tao: "bittensor",
|
|
95
|
+
sei: "sei-network",
|
|
96
|
+
aave: "aave",
|
|
97
|
+
algo: "algorand",
|
|
98
|
+
xlm: "stellar",
|
|
99
|
+
cro: "crypto-com-chain",
|
|
100
|
+
mnt: "mantle",
|
|
101
|
+
wld: "worldcoin-wld",
|
|
102
|
+
};
|
|
103
|
+
/** Accepted values for `input.media[].type` (enumerated by the upstream error). */
|
|
104
|
+
export const MEDIA_TYPES = ["first_frame", "last_frame", "driving_audio", "first_clip"];
|
|
105
|
+
export const VIDEO_MODELS = {
|
|
106
|
+
"wan2.7-t2v": { family: "bailian" },
|
|
107
|
+
"wan2.7-i2v": { family: "bailian", requiresMedia: "first_frame" },
|
|
108
|
+
"wan2.7-r2v": { family: "bailian", requiresMedia: "first_clip" },
|
|
109
|
+
"happyhorse-1.1-t2v": { family: "bailian" },
|
|
110
|
+
"happyhorse-1.1-i2v": { family: "bailian", requiresMedia: "first_frame" },
|
|
111
|
+
"happyhorse-1.1-r2v": { family: "bailian", requiresMedia: "first_clip" },
|
|
112
|
+
"dreamina-seedance-2-0-260128": { family: "seedance" },
|
|
113
|
+
"dreamina-seedance-2-0-fast-260128": { family: "seedance" },
|
|
114
|
+
};
|
|
115
|
+
export const DEFAULT_VIDEO_MODEL = "wan2.7-t2v";
|
|
116
|
+
/** Model families are matched by prefix so new revisions work without a release. */
|
|
117
|
+
export function videoModelSpec(model) {
|
|
118
|
+
if (VIDEO_MODELS[model])
|
|
119
|
+
return VIDEO_MODELS[model];
|
|
120
|
+
const family = model.startsWith("dreamina-seedance") ? "seedance" : "bailian";
|
|
121
|
+
if (/-i2v\b|-i2v$/.test(model))
|
|
122
|
+
return { family, requiresMedia: "first_frame" };
|
|
123
|
+
if (/-r2v\b|-r2v$/.test(model))
|
|
124
|
+
return { family, requiresMedia: "first_clip" };
|
|
125
|
+
return { family };
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Client-side grouping of integration providers.
|
|
129
|
+
*
|
|
130
|
+
* The catalog returns no description or tags — `buildCatalogItem` never
|
|
131
|
+
* populates them — so there is nothing server-side to filter on. Entries are
|
|
132
|
+
* matched by prefix, which keeps the polymarket-* family together.
|
|
133
|
+
*/
|
|
134
|
+
export const PROVIDER_CATEGORIES = {
|
|
135
|
+
finance: ["financial", "fred", "edinet", "coingecko", "polymarket", "kalshi"],
|
|
136
|
+
search: [
|
|
137
|
+
"search",
|
|
138
|
+
"tavily",
|
|
139
|
+
"brave",
|
|
140
|
+
"exa",
|
|
141
|
+
"perplexity",
|
|
142
|
+
"querit",
|
|
143
|
+
"parallel",
|
|
144
|
+
"dataforseo",
|
|
145
|
+
"jina",
|
|
146
|
+
"scholar",
|
|
147
|
+
],
|
|
148
|
+
social: ["twitter", "aisa-twitter", "youtube", "scrape-creators", "waveinflu"],
|
|
149
|
+
productivity: ["agentmail", "apollo", "composio"],
|
|
150
|
+
};
|
|
151
|
+
export function categoryOf(providerId) {
|
|
152
|
+
for (const [category, prefixes] of Object.entries(PROVIDER_CATEGORIES)) {
|
|
153
|
+
if (prefixes.some((p) => providerId === p || providerId.startsWith(`${p}-`) || providerId.startsWith(`${p}.`))) {
|
|
154
|
+
return category;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return "other";
|
|
158
|
+
}
|
|
159
|
+
export const API_CATEGORIES = [...Object.keys(PROVIDER_CATEGORIES), "other"];
|
|
35
160
|
export const MODEL_PROVIDERS = [
|
|
36
161
|
"openai",
|
|
37
162
|
"anthropic",
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from "commander";
|
|
3
|
-
import { VERSION } from "./constants.js";
|
|
3
|
+
import { VERSION, DEFAULT_VIDEO_MODEL } from "./constants.js";
|
|
4
4
|
// Auth
|
|
5
5
|
import { loginAction, logoutAction, whoamiAction } from "./commands/auth.js";
|
|
6
6
|
// Account
|
|
@@ -27,6 +27,10 @@ import { skillsListAction, skillsSearchAction, skillsShowAction, skillsInstallAc
|
|
|
27
27
|
import { mcpSetupAction, mcpStatusAction } from "./commands/mcp.js";
|
|
28
28
|
// Config
|
|
29
29
|
import { configSetAction, configGetAction, configListAction, configResetAction } from "./commands/configCmd.js";
|
|
30
|
+
// Cache
|
|
31
|
+
import { cacheClearAction, cachePathAction } from "./commands/cacheCmd.js";
|
|
32
|
+
// Completion
|
|
33
|
+
import { completionAction, completeAction } from "./commands/completionCmd.js";
|
|
30
34
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
31
35
|
function wrap(fn) {
|
|
32
36
|
return (...args) => {
|
|
@@ -63,30 +67,43 @@ program
|
|
|
63
67
|
.action(wrap(balanceAction));
|
|
64
68
|
program
|
|
65
69
|
.command("usage")
|
|
66
|
-
.description("Show usage history (
|
|
70
|
+
.description("Show usage history (awaiting gateway support)")
|
|
67
71
|
.option("--limit <n>", "Max records")
|
|
68
72
|
.option("--days <n>", "Lookback days")
|
|
69
73
|
.action(wrap(usageAction));
|
|
70
74
|
// ── API ──
|
|
71
|
-
const api = program.command("api").description("Discover and inspect APIs
|
|
75
|
+
const api = program.command("api").description("Discover and inspect APIs");
|
|
72
76
|
api
|
|
73
77
|
.command("list")
|
|
74
|
-
.description("List available
|
|
75
|
-
.option("--category <cat>", "Filter by category (
|
|
78
|
+
.description("List available APIs")
|
|
79
|
+
.option("--category <cat>", "Filter by category (client-side grouping): finance, search, social, productivity, other")
|
|
80
|
+
.option("--health", "Include provider health status")
|
|
81
|
+
.option("--json", "Output raw JSON")
|
|
82
|
+
.option("--refresh", "Bypass the cached catalog")
|
|
76
83
|
.action(wrap(apiListAction));
|
|
77
84
|
api
|
|
78
85
|
.command("search <query>")
|
|
79
|
-
.description("Search APIs by keyword
|
|
80
|
-
.option("--
|
|
86
|
+
.description("Search APIs and endpoints by keyword")
|
|
87
|
+
.option("--provider <id>", "Restrict to one API")
|
|
88
|
+
.option("--limit <n>", "Max results", "20")
|
|
89
|
+
.option("--json", "Output raw JSON")
|
|
90
|
+
.option("--refresh", "Bypass the cached catalog")
|
|
81
91
|
.action(wrap(apiSearchAction));
|
|
82
92
|
api
|
|
83
|
-
.command("show <
|
|
84
|
-
.description("Show API endpoint details
|
|
93
|
+
.command("show <api> [path]")
|
|
94
|
+
.description("Show an API's endpoints, or one endpoint's details")
|
|
95
|
+
.option("--all", "Show every endpoint instead of the first 40")
|
|
96
|
+
.option("--group", "Group by the provider's raw endpoint groups")
|
|
97
|
+
.option("--health", "Include provider health status")
|
|
98
|
+
.option("--json", "Output raw JSON")
|
|
99
|
+
.option("--refresh", "Bypass the cached catalog")
|
|
85
100
|
.action(wrap(apiShowAction));
|
|
86
101
|
api
|
|
87
102
|
.command("code <slug> <path>")
|
|
88
|
-
.description("Generate
|
|
89
|
-
.option("--lang <language>", "Language:
|
|
103
|
+
.description("Generate a request snippet for an endpoint")
|
|
104
|
+
.option("--lang <language>", "Language: curl, python, node, typescript", "curl")
|
|
105
|
+
.option("--method <method>", "HTTP method (the catalog's method is advisory)", "GET")
|
|
106
|
+
.option("--refresh", "Bypass the cached catalog")
|
|
90
107
|
.action(wrap(apiCodeAction));
|
|
91
108
|
// ── Run ──
|
|
92
109
|
program
|
|
@@ -97,12 +114,18 @@ program
|
|
|
97
114
|
.option("--method <method>", "HTTP method")
|
|
98
115
|
.option("--raw", "Raw JSON output")
|
|
99
116
|
.option("--stream", "Stream response")
|
|
117
|
+
.option("--domain", "Force the integration API base (/apis/v1) — the default")
|
|
118
|
+
.option("--llm", "Force the LLM gateway base (/v1)")
|
|
119
|
+
.option("--show-cost", "Print the billing headers the gateway reported (stderr)")
|
|
100
120
|
.action((slug, path, opts) => wrap(runAction)(slug, path, {
|
|
101
121
|
q: opts.query,
|
|
102
122
|
d: opts.data,
|
|
103
123
|
method: opts.method,
|
|
104
124
|
raw: opts.raw,
|
|
105
125
|
stream: opts.stream,
|
|
126
|
+
llm: opts.llm,
|
|
127
|
+
domain: opts.domain,
|
|
128
|
+
showCost: opts.showCost,
|
|
106
129
|
}));
|
|
107
130
|
// ── Chat (LLM Gateway) ──
|
|
108
131
|
program
|
|
@@ -130,7 +153,7 @@ models
|
|
|
130
153
|
program
|
|
131
154
|
.command("web-search <query>")
|
|
132
155
|
.description("Search the web")
|
|
133
|
-
.option("--type <type>", "Search type:
|
|
156
|
+
.option("--type <type>", "Search type: tavily, youtube, scholar, smart (degraded), full (degraded)", "tavily")
|
|
134
157
|
.option("--limit <n>", "Max results")
|
|
135
158
|
.option("--raw", "Raw JSON output")
|
|
136
159
|
.action(wrap(webSearchAction));
|
|
@@ -150,13 +173,17 @@ program
|
|
|
150
173
|
program
|
|
151
174
|
.command("crypto <symbol>")
|
|
152
175
|
.description("Look up crypto price")
|
|
153
|
-
.option("--period <period>", "Time period: current, 1d, 7d, 30d, 1y")
|
|
176
|
+
.option("--period <period>", "Time period: current, 1d, 7d, 30d, 90d, 1y")
|
|
177
|
+
.option("--id <coingecko-id>", "Use an exact CoinGecko id instead of resolving the symbol")
|
|
178
|
+
.option("--source <source>", "Data source: coingecko (default) or financial")
|
|
154
179
|
.option("--raw", "Raw JSON output")
|
|
155
180
|
.action(wrap(cryptoAction));
|
|
156
181
|
program
|
|
157
182
|
.command("screener")
|
|
158
183
|
.description("Screen stocks by criteria")
|
|
159
|
-
.option("--sector <sector>", "Filter by sector")
|
|
184
|
+
.option("--sector <sector>", "Filter by GICS sector (e.g. 'Information Technology')")
|
|
185
|
+
.option("--min-market-cap <n>", "Minimum market cap in USD")
|
|
186
|
+
.option("--filter <f...>", "Extra filter as field:operator:value (e.g. market_cap:gt:1e12)")
|
|
160
187
|
.option("--limit <n>", "Max results")
|
|
161
188
|
.option("--raw", "Raw JSON output")
|
|
162
189
|
.action(wrap(screenerAction));
|
|
@@ -388,14 +415,20 @@ const video = program.command("video").description("AI video generation");
|
|
|
388
415
|
video
|
|
389
416
|
.command("create <prompt>")
|
|
390
417
|
.description("Create a video generation task")
|
|
391
|
-
.option("--model <model>",
|
|
418
|
+
.option("--model <model>", `Generation model (default: ${DEFAULT_VIDEO_MODEL})`)
|
|
419
|
+
.option("--image <url...>", "Source image for i2v models (shorthand for --media first_frame=<url>)")
|
|
420
|
+
.option("--media <type=url...>", "Source media: first_frame, last_frame, driving_audio, first_clip")
|
|
421
|
+
.option("--resolution <res>", "Resolution, e.g. 720P or 1080P", "720P")
|
|
422
|
+
.option("--duration <seconds>", "Clip duration in seconds", "5")
|
|
423
|
+
.option("--body <json>", "Send this request body verbatim (escape hatch for unmodelled vendors)")
|
|
392
424
|
.option("--wait", "Wait for completion")
|
|
393
|
-
.option("--output <path>", "Download
|
|
425
|
+
.option("--output <path>", "Download the finished video to this path (implies --wait)")
|
|
394
426
|
.option("--raw", "Raw JSON output")
|
|
395
|
-
.action(wrap(videoCreateAction));
|
|
427
|
+
.action((prompt, opts) => wrap(videoCreateAction)(prompt, { ...opts, wait: Boolean(opts.wait || opts.output) }));
|
|
396
428
|
video
|
|
397
429
|
.command("status <task-id>")
|
|
398
430
|
.description("Check video task status")
|
|
431
|
+
.option("--output <path>", "Download the finished video to this path")
|
|
399
432
|
.option("--raw", "Raw JSON output")
|
|
400
433
|
.action(wrap(videoStatusAction));
|
|
401
434
|
// ── Skills ──
|
|
@@ -403,13 +436,15 @@ const skills = program.command("skills").description("Browse and manage agent sk
|
|
|
403
436
|
skills
|
|
404
437
|
.command("list")
|
|
405
438
|
.description("List available skills")
|
|
406
|
-
.option("--category <cat>", "Filter by category")
|
|
439
|
+
.option("--category <cat>", "Filter by category (ai-models, financial, marketing, ...)")
|
|
407
440
|
.option("--limit <n>", "Max results")
|
|
441
|
+
.option("--refresh", "Bypass the cached skill index")
|
|
408
442
|
.action(wrap(skillsListAction));
|
|
409
443
|
skills
|
|
410
444
|
.command("search <query>")
|
|
411
445
|
.description("Search skills by keyword")
|
|
412
446
|
.option("--limit <n>", "Max results")
|
|
447
|
+
.option("--refresh", "Bypass the cached skill index")
|
|
413
448
|
.action(wrap(skillsSearchAction));
|
|
414
449
|
skills
|
|
415
450
|
.command("show <slug>")
|
|
@@ -419,11 +454,13 @@ skills
|
|
|
419
454
|
.command("install <slug>")
|
|
420
455
|
.description("Install a skill to agent directories")
|
|
421
456
|
.option("--agent <agent>", "Target agent: claude, cursor, copilot, windsurf, codex, gemini, openclaw, all")
|
|
457
|
+
.option("--force", "Overwrite a directory holding a different skill")
|
|
422
458
|
.action(wrap(skillsInstallAction));
|
|
423
459
|
skills
|
|
424
460
|
.command("remove <slug>")
|
|
425
461
|
.description("Remove an installed skill")
|
|
426
462
|
.option("--agent <agent>", "Target agent")
|
|
463
|
+
.option("--force", "Remove even if the directory holds a different skill")
|
|
427
464
|
.action(skillsRemoveAction);
|
|
428
465
|
skills
|
|
429
466
|
.command("init <name>")
|
|
@@ -463,13 +500,38 @@ configCmd
|
|
|
463
500
|
// ── Top-level aliases ──
|
|
464
501
|
program
|
|
465
502
|
.command("search <query>")
|
|
466
|
-
.description("Search APIs (alias for 'api search')
|
|
467
|
-
.option("--
|
|
503
|
+
.description("Search APIs (alias for 'api search')")
|
|
504
|
+
.option("--provider <id>", "Restrict to one API")
|
|
505
|
+
.option("--limit <n>", "Max results", "20")
|
|
506
|
+
.option("--json", "Output raw JSON")
|
|
507
|
+
.option("--refresh", "Bypass the cached catalog")
|
|
468
508
|
.action(wrap(apiSearchAction));
|
|
469
509
|
program
|
|
470
510
|
.command("code <slug> <path>")
|
|
471
|
-
.description("Generate
|
|
472
|
-
.option("--lang <language>", "Language", "
|
|
511
|
+
.description("Generate a request snippet (alias for 'api code')")
|
|
512
|
+
.option("--lang <language>", "Language: curl, python, node, typescript", "curl")
|
|
513
|
+
.option("--method <method>", "HTTP method")
|
|
473
514
|
.action(wrap(apiCodeAction));
|
|
515
|
+
const cache = program.command("cache").description("Manage the local catalog and skills cache");
|
|
516
|
+
cache
|
|
517
|
+
.command("clear")
|
|
518
|
+
.description("Delete all cached catalog and skills data")
|
|
519
|
+
.action(cacheClearAction);
|
|
520
|
+
cache
|
|
521
|
+
.command("path")
|
|
522
|
+
.description("Print the cache directory")
|
|
523
|
+
.action(cachePathAction);
|
|
524
|
+
// ── Shell completion ──
|
|
525
|
+
program
|
|
526
|
+
.command("completion [shell]")
|
|
527
|
+
.description("Print a shell completion script (bash, zsh, fish)")
|
|
528
|
+
.action(completionAction);
|
|
529
|
+
// Called by the generated scripts on every Tab press. Hidden, and tolerant of
|
|
530
|
+
// whatever half-typed input the shell hands it.
|
|
531
|
+
program
|
|
532
|
+
.command("__complete [words...]", { hidden: true })
|
|
533
|
+
.allowUnknownOption()
|
|
534
|
+
.allowExcessArguments()
|
|
535
|
+
.action((words = []) => completeAction(program, words));
|
|
474
536
|
// ── Parse ──
|
|
475
537
|
program.parse();
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub-backed skill registry.
|
|
3
|
+
*
|
|
4
|
+
* The repo nests skills two levels deep (`<category>/<name>/SKILL.md`), so the
|
|
5
|
+
* canonical slug is the repo-relative directory. Everything here is driven off
|
|
6
|
+
* a single recursive tree fetch: api.github.com allows only 60 unauthenticated
|
|
7
|
+
* requests per hour per IP, and the previous per-command fetching burned
|
|
8
|
+
* several of those on every invocation.
|
|
9
|
+
*/
|
|
10
|
+
export declare const SKILLS_REPO = "AIsa-team/agent-skills";
|
|
11
|
+
export declare const GH_RAW = "https://raw.githubusercontent.com/AIsa-team/agent-skills/main";
|
|
12
|
+
export interface SkillBlob {
|
|
13
|
+
path: string;
|
|
14
|
+
sha: string;
|
|
15
|
+
}
|
|
16
|
+
export interface SkillIndex {
|
|
17
|
+
/** Canonical slugs (`<category>/<name>`), sorted. */
|
|
18
|
+
slugs: string[];
|
|
19
|
+
/** All blobs under each slug, including SKILL.md. */
|
|
20
|
+
blobs: Record<string, SkillBlob[]>;
|
|
21
|
+
}
|
|
22
|
+
export interface SkillInfo {
|
|
23
|
+
slug: string;
|
|
24
|
+
name: string;
|
|
25
|
+
description: string;
|
|
26
|
+
emoji: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Fetch (or reuse) the skill index. Memoized per process on top of a 1h disk
|
|
30
|
+
* cache with ETag revalidation, so repeated commands cost at most one
|
|
31
|
+
* conditional request.
|
|
32
|
+
*/
|
|
33
|
+
export declare function getSkillIndex(options?: {
|
|
34
|
+
refresh?: boolean;
|
|
35
|
+
}): Promise<SkillIndex>;
|
|
36
|
+
/** Last path segment — what the skill is called once installed. */
|
|
37
|
+
export declare function leafName(slug: string): string;
|
|
38
|
+
/**
|
|
39
|
+
* Accept either a canonical `<category>/<name>` slug or a bare name. A bare
|
|
40
|
+
* name that matches several skills is an error rather than a guess: installing
|
|
41
|
+
* the wrong skill silently is worse than asking.
|
|
42
|
+
*/
|
|
43
|
+
export declare function resolveSlug(input: string, index: SkillIndex): string;
|
|
44
|
+
/** Parse YAML frontmatter from SKILL.md content. */
|
|
45
|
+
export declare function parseSkillFrontmatter(slug: string, content: string): SkillInfo;
|
|
46
|
+
export declare function fetchSkillMarkdown(slug: string): Promise<string>;
|
|
47
|
+
/**
|
|
48
|
+
* Metadata for every skill. Cached by blob sha, so a warm cache needs zero
|
|
49
|
+
* content requests and only re-fetches the skills that actually changed.
|
|
50
|
+
*/
|
|
51
|
+
export declare function listSkills(index: SkillIndex): Promise<SkillInfo[]>;
|
|
52
|
+
export interface SkillFile {
|
|
53
|
+
path: string;
|
|
54
|
+
content: Buffer;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Download every file in a skill directory. Content is kept as bytes: skills
|
|
58
|
+
* may ship images or fonts, and decoding those as UTF-8 corrupts them.
|
|
59
|
+
*
|
|
60
|
+
* A partial download is an error, not a smaller skill. Installing replaces the
|
|
61
|
+
* target directory, so silently dropping failed files would delete a working
|
|
62
|
+
* skill and leave a broken one — possibly without its SKILL.md.
|
|
63
|
+
*/
|
|
64
|
+
export declare function fetchSkillFiles(slug: string, index: SkillIndex): Promise<SkillFile[]>;
|