@agentsmarket/cli 0.1.0 → 0.5.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 +1455 -44
- package/dist/commands/balance.js +3 -3
- package/dist/commands/call.d.ts +23 -1
- package/dist/commands/call.js +187 -45
- package/dist/commands/call.js.map +1 -1
- package/dist/commands/info.d.ts +6 -6
- package/dist/commands/info.js +33 -35
- package/dist/commands/info.js.map +1 -1
- package/dist/commands/init.d.ts +11 -7
- package/dist/commands/init.js +71 -42
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/install.js +2 -2
- package/dist/commands/mcp.js +9 -11
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/pipeline/call.d.ts +18 -0
- package/dist/commands/pipeline/call.js +58 -0
- package/dist/commands/pipeline/call.js.map +1 -0
- package/dist/commands/pipeline/install.d.ts +7 -0
- package/dist/commands/pipeline/install.js +16 -0
- package/dist/commands/pipeline/install.js.map +1 -0
- package/dist/commands/pipeline/publish.d.ts +15 -0
- package/dist/commands/pipeline/publish.js +22 -0
- package/dist/commands/pipeline/publish.js.map +1 -0
- package/dist/commands/publish-openapi.d.ts +16 -0
- package/dist/commands/publish-openapi.js +61 -0
- package/dist/commands/publish-openapi.js.map +1 -0
- package/dist/commands/publish-pipeline.d.ts +15 -0
- package/dist/commands/publish-pipeline.js +141 -0
- package/dist/commands/publish-pipeline.js.map +1 -0
- package/dist/commands/publish.js +37 -42
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/refund.js +15 -17
- package/dist/commands/refund.js.map +1 -1
- package/dist/commands/register.js +6 -27
- package/dist/commands/register.js.map +1 -1
- package/dist/commands/run.d.ts +31 -0
- package/dist/commands/run.js +305 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/scan.js +2 -5
- package/dist/commands/scan.js.map +1 -1
- package/dist/commands/search.js +1 -1
- package/dist/commands/skill/call.d.ts +12 -0
- package/dist/commands/skill/call.js +17 -0
- package/dist/commands/skill/call.js.map +1 -0
- package/dist/commands/skill/install.d.ts +7 -0
- package/dist/commands/skill/install.js +13 -0
- package/dist/commands/skill/install.js.map +1 -0
- package/dist/commands/skill/publish.d.ts +18 -0
- package/dist/commands/skill/publish.js +28 -0
- package/dist/commands/skill/publish.js.map +1 -0
- package/dist/commands/validate.d.ts +20 -0
- package/dist/commands/validate.js +91 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/index.d.ts +4 -6
- package/dist/index.js +90 -29
- package/dist/index.js.map +1 -1
- package/dist/lib/config.d.ts +12 -13
- package/dist/lib/config.js +27 -27
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/http.d.ts +23 -8
- package/dist/lib/http.js +28 -48
- package/dist/lib/http.js.map +1 -1
- package/dist/lib/identity.d.ts +29 -0
- package/dist/lib/identity.js +57 -0
- package/dist/lib/identity.js.map +1 -0
- package/dist/lib/mcp-install.d.ts +36 -0
- package/dist/lib/mcp-install.js +149 -0
- package/dist/lib/mcp-install.js.map +1 -0
- package/dist/lib/pipeline-spec.d.ts +66 -0
- package/dist/lib/pipeline-spec.js +273 -0
- package/dist/lib/pipeline-spec.js.map +1 -0
- package/package.json +12 -4
- package/dist/lib/keys.d.ts +0 -69
- package/dist/lib/keys.js +0 -85
- package/dist/lib/keys.js.map +0 -1
- package/dist/lib/payment-keys.d.ts +0 -25
- package/dist/lib/payment-keys.js +0 -55
- package/dist/lib/payment-keys.js.map +0 -1
- package/dist/lib/payment.d.ts +0 -27
- package/dist/lib/payment.js +0 -123
- package/dist/lib/payment.js.map +0 -1
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent identity: BIP-39 mnemonic → secp256k1 keypair (Ethereum-style).
|
|
3
|
+
*
|
|
4
|
+
* agent_id = 0x<address> (same as payment_address — single identity).
|
|
5
|
+
* Signing format: EIP-191 personal_sign → ecrecover on server.
|
|
6
|
+
*
|
|
7
|
+
* Storage:
|
|
8
|
+
* mnemonic.txt — 12-word phrase (PRIMARY backup, import to Trust Wallet)
|
|
9
|
+
* agent.key — secp256k1 private key hex (convenience, derived from mnemonic)
|
|
10
|
+
*/
|
|
11
|
+
export interface Identity {
|
|
12
|
+
address: string;
|
|
13
|
+
publicKeyHex: string;
|
|
14
|
+
privateKeyHex: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function generateMnemonic(): string;
|
|
17
|
+
export declare function isValidMnemonic(mnemonic: string): boolean;
|
|
18
|
+
export declare function mnemonicToIdentity(mnemonic: string): Identity;
|
|
19
|
+
export declare function addressFromPrivateKey(privateKeyHex: string): string;
|
|
20
|
+
export interface SignedMessage {
|
|
21
|
+
signature: string;
|
|
22
|
+
address: string;
|
|
23
|
+
}
|
|
24
|
+
export declare function signEip191(privateKeyHex: string, message: string): Promise<SignedMessage>;
|
|
25
|
+
export declare function verifyEip191(message: string, signature: string): {
|
|
26
|
+
ok: boolean;
|
|
27
|
+
address?: string;
|
|
28
|
+
error?: string;
|
|
29
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent identity: BIP-39 mnemonic → secp256k1 keypair (Ethereum-style).
|
|
3
|
+
*
|
|
4
|
+
* agent_id = 0x<address> (same as payment_address — single identity).
|
|
5
|
+
* Signing format: EIP-191 personal_sign → ecrecover on server.
|
|
6
|
+
*
|
|
7
|
+
* Storage:
|
|
8
|
+
* mnemonic.txt — 12-word phrase (PRIMARY backup, import to Trust Wallet)
|
|
9
|
+
* agent.key — secp256k1 private key hex (convenience, derived from mnemonic)
|
|
10
|
+
*/
|
|
11
|
+
import { Wallet, HDNodeWallet, verifyMessage } from 'ethers';
|
|
12
|
+
export function generateMnemonic() {
|
|
13
|
+
const wallet = Wallet.createRandom();
|
|
14
|
+
return wallet.mnemonic.phrase;
|
|
15
|
+
}
|
|
16
|
+
export function isValidMnemonic(mnemonic) {
|
|
17
|
+
try {
|
|
18
|
+
HDNodeWallet.fromPhrase(mnemonic);
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export function mnemonicToIdentity(mnemonic) {
|
|
26
|
+
const hdNode = HDNodeWallet.fromPhrase(mnemonic);
|
|
27
|
+
return {
|
|
28
|
+
address: hdNode.address,
|
|
29
|
+
publicKeyHex: hdNode.publicKey.slice(2),
|
|
30
|
+
privateKeyHex: hdNode.privateKey.slice(2),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export function addressFromPrivateKey(privateKeyHex) {
|
|
34
|
+
const key = privateKeyHex.startsWith('0x') ? privateKeyHex : '0x' + privateKeyHex;
|
|
35
|
+
const wallet = new Wallet(key);
|
|
36
|
+
return wallet.address;
|
|
37
|
+
}
|
|
38
|
+
export async function signEip191(privateKeyHex, message) {
|
|
39
|
+
const key = privateKeyHex.startsWith('0x') ? privateKeyHex : '0x' + privateKeyHex;
|
|
40
|
+
const wallet = new Wallet(key);
|
|
41
|
+
const signature = await wallet.signMessage(message);
|
|
42
|
+
const recovered = verifyMessage(message, signature);
|
|
43
|
+
return { signature, address: recovered };
|
|
44
|
+
}
|
|
45
|
+
export function verifyEip191(message, signature) {
|
|
46
|
+
try {
|
|
47
|
+
if (!signature.startsWith('0x') || signature.length !== 132) {
|
|
48
|
+
return { ok: false, error: 'signature must be 0x + 130 hex chars' };
|
|
49
|
+
}
|
|
50
|
+
const address = verifyMessage(message, signature);
|
|
51
|
+
return { ok: true, address };
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
return { ok: false, error: err.message };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/lib/identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAQ7D,MAAM,UAAU,gBAAgB;IAC9B,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC;IACrC,OAAO,MAAM,CAAC,QAAS,CAAC,MAAM,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,IAAI,CAAC;QACH,YAAY,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,MAAM,MAAM,GAAG,YAAY,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IACjD,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,YAAY,EAAE,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QACvC,aAAa,EAAE,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;KAC1C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,aAAqB;IACzD,MAAM,GAAG,GAAG,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,GAAG,aAAa,CAAC;IAClF,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;IAC/B,OAAO,MAAM,CAAC,OAAO,CAAC;AACxB,CAAC;AAOD,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,aAAqB,EAAE,OAAe;IACrE,MAAM,GAAG,GAAG,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,GAAG,aAAa,CAAC;IAClF,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IACpD,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAe,EAAE,SAAiB;IAC7D,IAAI,CAAC;QACH,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,sCAAsC,EAAE,CAAC;QACtE,CAAC;QACD,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAClD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC/B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC;IACtD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-install agentsmarket MCP server into detected agent configs.
|
|
3
|
+
*
|
|
4
|
+
* Detects: OpenCode, Claude Code, Cursor.
|
|
5
|
+
* For each detected, merges { mcpServers: { agentsmarket: {...} } } into the existing config,
|
|
6
|
+
* preserving all other keys and creating a `.bak` backup before writing.
|
|
7
|
+
*
|
|
8
|
+
* If no agents are detected, returns an empty report — caller should instruct user to
|
|
9
|
+
* configure manually per https://agentsmarket.world/INSTRUCTIONS.md.
|
|
10
|
+
*/
|
|
11
|
+
export type AgentName = 'OpenCode' | 'Claude Code' | 'Cursor';
|
|
12
|
+
export type InstallReportEntry = {
|
|
13
|
+
agent: AgentName;
|
|
14
|
+
action: 'installed' | 'updated' | 'unchanged';
|
|
15
|
+
path: string;
|
|
16
|
+
backup?: string;
|
|
17
|
+
} | {
|
|
18
|
+
agent: AgentName;
|
|
19
|
+
action: 'skipped';
|
|
20
|
+
reason: string;
|
|
21
|
+
};
|
|
22
|
+
interface CandidateConfig {
|
|
23
|
+
agent: AgentName;
|
|
24
|
+
path: string;
|
|
25
|
+
}
|
|
26
|
+
export declare function detectCandidates(): CandidateConfig[];
|
|
27
|
+
export declare function stripJsoncComments(input: string): string;
|
|
28
|
+
export declare function readJsonConfig(filePath: string): {
|
|
29
|
+
parsed: Record<string, unknown>;
|
|
30
|
+
hadComments: boolean;
|
|
31
|
+
};
|
|
32
|
+
export declare function sameMcpEntry(a: unknown): boolean;
|
|
33
|
+
export declare function installOne(c: CandidateConfig): InstallReportEntry;
|
|
34
|
+
export declare function installMcpForAll(): InstallReportEntry[];
|
|
35
|
+
export declare function detectAgents(): AgentName[];
|
|
36
|
+
export {};
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-install agentsmarket MCP server into detected agent configs.
|
|
3
|
+
*
|
|
4
|
+
* Detects: OpenCode, Claude Code, Cursor.
|
|
5
|
+
* For each detected, merges { mcpServers: { agentsmarket: {...} } } into the existing config,
|
|
6
|
+
* preserving all other keys and creating a `.bak` backup before writing.
|
|
7
|
+
*
|
|
8
|
+
* If no agents are detected, returns an empty report — caller should instruct user to
|
|
9
|
+
* configure manually per https://agentsmarket.world/INSTRUCTIONS.md.
|
|
10
|
+
*/
|
|
11
|
+
import * as fs from 'node:fs';
|
|
12
|
+
import * as os from 'node:os';
|
|
13
|
+
import * as path from 'node:path';
|
|
14
|
+
const MCP_ENTRY = {
|
|
15
|
+
command: 'npx',
|
|
16
|
+
args: ['-y', '@agentsmarket/cli', 'mcp'],
|
|
17
|
+
};
|
|
18
|
+
export function detectCandidates() {
|
|
19
|
+
const home = os.homedir();
|
|
20
|
+
const found = [];
|
|
21
|
+
const ocJson = path.join(home, '.config', 'opencode', 'opencode.json');
|
|
22
|
+
const ocJsonc = path.join(home, '.config', 'opencode', 'opencode.jsonc');
|
|
23
|
+
const ocDir = path.join(home, '.config', 'opencode');
|
|
24
|
+
if (fs.existsSync(ocJson))
|
|
25
|
+
found.push({ agent: 'OpenCode', path: ocJson });
|
|
26
|
+
else if (fs.existsSync(ocJsonc))
|
|
27
|
+
found.push({ agent: 'OpenCode', path: ocJsonc });
|
|
28
|
+
else if (fs.existsSync(ocDir) && fs.statSync(ocDir).isDirectory()) {
|
|
29
|
+
found.push({ agent: 'OpenCode', path: ocJson });
|
|
30
|
+
}
|
|
31
|
+
const ccJson = path.join(home, '.claude.json');
|
|
32
|
+
const ccDir = path.join(home, '.claude');
|
|
33
|
+
if (fs.existsSync(ccJson))
|
|
34
|
+
found.push({ agent: 'Claude Code', path: ccJson });
|
|
35
|
+
else if (fs.existsSync(ccDir) && fs.statSync(ccDir).isDirectory()) {
|
|
36
|
+
found.push({ agent: 'Claude Code', path: ccJson });
|
|
37
|
+
}
|
|
38
|
+
const curJson = path.join(home, '.cursor', 'mcp.json');
|
|
39
|
+
const curDir = path.join(home, '.cursor');
|
|
40
|
+
if (fs.existsSync(curJson))
|
|
41
|
+
found.push({ agent: 'Cursor', path: curJson });
|
|
42
|
+
else if (fs.existsSync(curDir) && fs.statSync(curDir).isDirectory()) {
|
|
43
|
+
found.push({ agent: 'Cursor', path: curJson });
|
|
44
|
+
}
|
|
45
|
+
return found;
|
|
46
|
+
}
|
|
47
|
+
export function stripJsoncComments(input) {
|
|
48
|
+
let out = '';
|
|
49
|
+
let i = 0;
|
|
50
|
+
let inString = false;
|
|
51
|
+
let stringChar = '';
|
|
52
|
+
while (i < input.length) {
|
|
53
|
+
const ch = input[i];
|
|
54
|
+
const next = input[i + 1];
|
|
55
|
+
if (inString) {
|
|
56
|
+
out += ch;
|
|
57
|
+
if (ch === '\\' && i + 1 < input.length) {
|
|
58
|
+
out += input[i + 1];
|
|
59
|
+
i += 2;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (ch === stringChar)
|
|
63
|
+
inString = false;
|
|
64
|
+
i++;
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (ch === '"' || ch === "'") {
|
|
68
|
+
inString = true;
|
|
69
|
+
stringChar = ch;
|
|
70
|
+
out += ch;
|
|
71
|
+
i++;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (ch === '/' && next === '/') {
|
|
75
|
+
while (i < input.length && input[i] !== '\n')
|
|
76
|
+
i++;
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (ch === '/' && next === '*') {
|
|
80
|
+
i += 2;
|
|
81
|
+
while (i < input.length && !(input[i] === '*' && input[i + 1] === '/'))
|
|
82
|
+
i++;
|
|
83
|
+
i += 2;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
out += ch;
|
|
87
|
+
i++;
|
|
88
|
+
}
|
|
89
|
+
return out;
|
|
90
|
+
}
|
|
91
|
+
export function readJsonConfig(filePath) {
|
|
92
|
+
const raw = fs.readFileSync(filePath, 'utf8');
|
|
93
|
+
const stripped = stripJsoncComments(raw);
|
|
94
|
+
const hadComments = stripped !== raw;
|
|
95
|
+
return { parsed: JSON.parse(stripped), hadComments };
|
|
96
|
+
}
|
|
97
|
+
export function sameMcpEntry(a) {
|
|
98
|
+
if (!a || typeof a !== 'object')
|
|
99
|
+
return false;
|
|
100
|
+
const e = a;
|
|
101
|
+
if (e.command !== MCP_ENTRY.command)
|
|
102
|
+
return false;
|
|
103
|
+
const args = e.args;
|
|
104
|
+
if (!Array.isArray(args))
|
|
105
|
+
return false;
|
|
106
|
+
if (args.length !== MCP_ENTRY.args.length)
|
|
107
|
+
return false;
|
|
108
|
+
return MCP_ENTRY.args.every((v, i) => args[i] === v);
|
|
109
|
+
}
|
|
110
|
+
export function installOne(c) {
|
|
111
|
+
const fileExists = fs.existsSync(c.path);
|
|
112
|
+
if (!fileExists) {
|
|
113
|
+
const dir = path.dirname(c.path);
|
|
114
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
115
|
+
const initial = {
|
|
116
|
+
mcpServers: {
|
|
117
|
+
agentsmarket: MCP_ENTRY,
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
fs.writeFileSync(c.path, JSON.stringify(initial, null, 2) + '\n', { encoding: 'utf8', mode: 0o600 });
|
|
121
|
+
return { agent: c.agent, action: 'installed', path: c.path };
|
|
122
|
+
}
|
|
123
|
+
let parsed;
|
|
124
|
+
try {
|
|
125
|
+
parsed = readJsonConfig(c.path).parsed;
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
const msg = err.message;
|
|
129
|
+
return { agent: c.agent, action: 'skipped', reason: `parse error: ${msg}` };
|
|
130
|
+
}
|
|
131
|
+
const mcpServers = (parsed.mcpServers ?? {});
|
|
132
|
+
if (sameMcpEntry(mcpServers.agentsmarket)) {
|
|
133
|
+
return { agent: c.agent, action: 'unchanged', path: c.path };
|
|
134
|
+
}
|
|
135
|
+
const backupPath = `${c.path}.bak-${new Date().toISOString().replace(/[:.]/g, '-')}`;
|
|
136
|
+
fs.copyFileSync(c.path, backupPath);
|
|
137
|
+
mcpServers.agentsmarket = MCP_ENTRY;
|
|
138
|
+
parsed.mcpServers = mcpServers;
|
|
139
|
+
fs.writeFileSync(c.path, JSON.stringify(parsed, null, 2) + '\n', { encoding: 'utf8' });
|
|
140
|
+
fs.chmodSync(c.path, 0o600);
|
|
141
|
+
return { agent: c.agent, action: 'updated', path: c.path, backup: backupPath };
|
|
142
|
+
}
|
|
143
|
+
export function installMcpForAll() {
|
|
144
|
+
return detectCandidates().map(installOne);
|
|
145
|
+
}
|
|
146
|
+
export function detectAgents() {
|
|
147
|
+
return detectCandidates().map((c) => c.agent);
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=mcp-install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-install.js","sourceRoot":"","sources":["../../src/lib/mcp-install.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pipeline spec validation — shared between `agentsmarket run` and `agentsmarket validate`.
|
|
3
|
+
*
|
|
4
|
+
* Returns:
|
|
5
|
+
* { ok: true, usesStages, warnings } — spec is valid
|
|
6
|
+
* { ok: false, error } — spec has issue
|
|
7
|
+
*
|
|
8
|
+
* v0.2 additions:
|
|
9
|
+
* - `uses@version` syntax validation (semver-like hint; full validation at runtime)
|
|
10
|
+
* - `output_format: structured_json` requires non-empty `fields: [...]`
|
|
11
|
+
* - `mcp_servers`/`mcp_tools` are arrays of strings (declaration-level only)
|
|
12
|
+
* - `working_dir` is a non-empty string
|
|
13
|
+
* - `uses_parallel` (v0.3) is rejected with a clear message
|
|
14
|
+
*
|
|
15
|
+
* v0.3 R6 additions (Provider ≠ Model):
|
|
16
|
+
* - When a stage declares `provider:`, the (provider, model) pair must be
|
|
17
|
+
* registered in `PROVIDER_REGISTRY` (openai, anthropic, minimax,
|
|
18
|
+
* openrouter, replicate). Validated via `validateProviderModel()` from
|
|
19
|
+
* `@agentsmarket/pipeline-runtime`. Auto-dispatch by model name removed.
|
|
20
|
+
*/
|
|
21
|
+
export interface PipelineFileSpec {
|
|
22
|
+
name: string;
|
|
23
|
+
version?: string;
|
|
24
|
+
description?: string;
|
|
25
|
+
inputs?: Record<string, unknown>;
|
|
26
|
+
defaults?: {
|
|
27
|
+
model?: string;
|
|
28
|
+
};
|
|
29
|
+
stages: Array<{
|
|
30
|
+
id: string;
|
|
31
|
+
model?: string;
|
|
32
|
+
system?: string;
|
|
33
|
+
prompt?: string;
|
|
34
|
+
uses?: unknown;
|
|
35
|
+
uses_parallel?: unknown;
|
|
36
|
+
input?: unknown;
|
|
37
|
+
output_format?: string;
|
|
38
|
+
fields?: string[];
|
|
39
|
+
mcp_servers?: string[];
|
|
40
|
+
mcp_tools?: string[];
|
|
41
|
+
working_dir?: string;
|
|
42
|
+
provider?: string;
|
|
43
|
+
retry?: {
|
|
44
|
+
attempts?: number;
|
|
45
|
+
backoff?: 'exponential' | 'linear' | 'fixed';
|
|
46
|
+
retryable_status?: number[];
|
|
47
|
+
initial_ms?: number;
|
|
48
|
+
};
|
|
49
|
+
run_if?: string;
|
|
50
|
+
when?: string | {
|
|
51
|
+
all: string[];
|
|
52
|
+
} | {
|
|
53
|
+
any: string[];
|
|
54
|
+
};
|
|
55
|
+
}>;
|
|
56
|
+
}
|
|
57
|
+
export declare const COST_PER_LLM_CALL_USDC = 0.01;
|
|
58
|
+
export type ValidationResult = {
|
|
59
|
+
ok: true;
|
|
60
|
+
usesStages: string[];
|
|
61
|
+
warnings: string[];
|
|
62
|
+
} | {
|
|
63
|
+
ok: false;
|
|
64
|
+
error: string;
|
|
65
|
+
};
|
|
66
|
+
export declare function validatePipelineSpec(spec: unknown): ValidationResult;
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pipeline spec validation — shared between `agentsmarket run` and `agentsmarket validate`.
|
|
3
|
+
*
|
|
4
|
+
* Returns:
|
|
5
|
+
* { ok: true, usesStages, warnings } — spec is valid
|
|
6
|
+
* { ok: false, error } — spec has issue
|
|
7
|
+
*
|
|
8
|
+
* v0.2 additions:
|
|
9
|
+
* - `uses@version` syntax validation (semver-like hint; full validation at runtime)
|
|
10
|
+
* - `output_format: structured_json` requires non-empty `fields: [...]`
|
|
11
|
+
* - `mcp_servers`/`mcp_tools` are arrays of strings (declaration-level only)
|
|
12
|
+
* - `working_dir` is a non-empty string
|
|
13
|
+
* - `uses_parallel` (v0.3) is rejected with a clear message
|
|
14
|
+
*
|
|
15
|
+
* v0.3 R6 additions (Provider ≠ Model):
|
|
16
|
+
* - When a stage declares `provider:`, the (provider, model) pair must be
|
|
17
|
+
* registered in `PROVIDER_REGISTRY` (openai, anthropic, minimax,
|
|
18
|
+
* openrouter, replicate). Validated via `validateProviderModel()` from
|
|
19
|
+
* `@agentsmarket/pipeline-runtime`. Auto-dispatch by model name removed.
|
|
20
|
+
*/
|
|
21
|
+
import { validateProviderModel } from '@agentsmarket/pipeline-runtime';
|
|
22
|
+
export const COST_PER_LLM_CALL_USDC = 0.01;
|
|
23
|
+
const VERSION_HINT_RE = /^[A-Za-z0-9._+\-]{1,32}$/;
|
|
24
|
+
const MCP_NAME_RE = /^[a-z][a-z0-9_-]{0,63}$/;
|
|
25
|
+
const OUTPUT_FORMAT_VALUES = new Set(['text', 'code', 'markdown', 'structured_json']);
|
|
26
|
+
const WORKING_DIR_HINT_RE = /^[./~A-Za-z0-9_\-/ ]{1,512}$/;
|
|
27
|
+
export function validatePipelineSpec(spec) {
|
|
28
|
+
if (!spec || typeof spec !== 'object') {
|
|
29
|
+
return { ok: false, error: 'spec must be an object' };
|
|
30
|
+
}
|
|
31
|
+
const s = spec;
|
|
32
|
+
if (!s.name || typeof s.name !== 'string') {
|
|
33
|
+
return { ok: false, error: 'spec.name is required (string)' };
|
|
34
|
+
}
|
|
35
|
+
if (!Array.isArray(s.stages) || s.stages.length === 0) {
|
|
36
|
+
return { ok: false, error: 'spec.stages[] is required and must be non-empty' };
|
|
37
|
+
}
|
|
38
|
+
const seenIds = new Set();
|
|
39
|
+
const usesStages = [];
|
|
40
|
+
const warnings = [];
|
|
41
|
+
for (let i = 0; i < s.stages.length; i++) {
|
|
42
|
+
const stage = s.stages[i];
|
|
43
|
+
if (!stage || typeof stage !== 'object') {
|
|
44
|
+
return { ok: false, error: `stages[${i}] must be an object` };
|
|
45
|
+
}
|
|
46
|
+
if (!stage.id || typeof stage.id !== 'string') {
|
|
47
|
+
return { ok: false, error: `stages[${i}].id is required (string)` };
|
|
48
|
+
}
|
|
49
|
+
if (seenIds.has(stage.id)) {
|
|
50
|
+
return { ok: false, error: `duplicate stage id: '${stage.id}'` };
|
|
51
|
+
}
|
|
52
|
+
seenIds.add(stage.id);
|
|
53
|
+
if (stage.uses_parallel !== undefined) {
|
|
54
|
+
return {
|
|
55
|
+
ok: false,
|
|
56
|
+
error: `stage '${stage.id}': 'uses_parallel' is v0.3+ and not supported by v0.2 runtime. Use 'uses:' (sequential) or split into multiple stages.`,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
const hasModel = typeof stage.model === 'string' && stage.model.length > 0;
|
|
60
|
+
const hasUses = stage.uses !== undefined;
|
|
61
|
+
const hasPrompt = typeof stage.prompt === 'string' && stage.prompt.length > 0;
|
|
62
|
+
if (!hasModel && !hasUses && !hasPrompt) {
|
|
63
|
+
return {
|
|
64
|
+
ok: false,
|
|
65
|
+
error: `stage '${stage.id}': must have 'model'+'prompt' (LLM), 'uses' (skill), or just 'prompt'`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
if (hasUses) {
|
|
69
|
+
usesStages.push(stage.id);
|
|
70
|
+
const usesErr = validateUsesSyntax(stage.uses, stage.id);
|
|
71
|
+
if (usesErr)
|
|
72
|
+
return { ok: false, error: usesErr };
|
|
73
|
+
}
|
|
74
|
+
if (stage.output_format !== undefined) {
|
|
75
|
+
if (typeof stage.output_format !== 'string' || !OUTPUT_FORMAT_VALUES.has(stage.output_format)) {
|
|
76
|
+
return {
|
|
77
|
+
ok: false,
|
|
78
|
+
error: `stage '${stage.id}': output_format must be one of text|code|markdown|structured_json`,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
if (stage.output_format === 'structured_json') {
|
|
82
|
+
if (!Array.isArray(stage.fields) || stage.fields.length === 0) {
|
|
83
|
+
return {
|
|
84
|
+
ok: false,
|
|
85
|
+
error: `stage '${stage.id}': output_format=structured_json requires 'fields: [...]' with at least one entry`,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
for (const f of stage.fields) {
|
|
89
|
+
if (typeof f !== 'string' || f.length === 0) {
|
|
90
|
+
return {
|
|
91
|
+
ok: false,
|
|
92
|
+
error: `stage '${stage.id}': every entry in 'fields' must be a non-empty string`,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (stage.mcp_servers !== undefined) {
|
|
99
|
+
if (!Array.isArray(stage.mcp_servers)) {
|
|
100
|
+
return { ok: false, error: `stage '${stage.id}': mcp_servers must be an array of strings` };
|
|
101
|
+
}
|
|
102
|
+
for (const name of stage.mcp_servers) {
|
|
103
|
+
if (typeof name !== 'string' || !MCP_NAME_RE.test(name)) {
|
|
104
|
+
return {
|
|
105
|
+
ok: false,
|
|
106
|
+
error: `stage '${stage.id}': mcp_servers entries must match /^[a-z][a-z0-9_-]{0,63}$/ — got '${String(name)}'`,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
warnings.push(`stage '${stage.id}': mcp_servers declared but not executed in v0.2 (forward-compat for v0.3)`);
|
|
111
|
+
}
|
|
112
|
+
if (stage.mcp_tools !== undefined) {
|
|
113
|
+
if (!Array.isArray(stage.mcp_tools)) {
|
|
114
|
+
return { ok: false, error: `stage '${stage.id}': mcp_tools must be an array of strings` };
|
|
115
|
+
}
|
|
116
|
+
for (const name of stage.mcp_tools) {
|
|
117
|
+
if (typeof name !== 'string' || !MCP_NAME_RE.test(name)) {
|
|
118
|
+
return {
|
|
119
|
+
ok: false,
|
|
120
|
+
error: `stage '${stage.id}': mcp_tools entries must match /^[a-z][a-z0-9_-]{0,63}$/ — got '${String(name)}'`,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
warnings.push(`stage '${stage.id}': mcp_tools declared but not executed in v0.2 (forward-compat for v0.3)`);
|
|
125
|
+
}
|
|
126
|
+
if (stage.working_dir !== undefined && stage.working_dir !== null) {
|
|
127
|
+
if (typeof stage.working_dir !== 'string' || !WORKING_DIR_HINT_RE.test(stage.working_dir)) {
|
|
128
|
+
return {
|
|
129
|
+
ok: false,
|
|
130
|
+
error: `stage '${stage.id}': working_dir must be a non-empty path-like string`,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
warnings.push(`stage '${stage.id}': working_dir is CLI-only — server execution will log 'working_dir_ignored_on_server'`);
|
|
134
|
+
}
|
|
135
|
+
if (stage.provider !== undefined) {
|
|
136
|
+
if (typeof stage.provider !== 'string') {
|
|
137
|
+
return {
|
|
138
|
+
ok: false,
|
|
139
|
+
error: `stage '${stage.id}': provider must be a string (got ${typeof stage.provider})`,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
if (stage.provider.length === 0) {
|
|
143
|
+
return {
|
|
144
|
+
ok: false,
|
|
145
|
+
error: `stage '${stage.id}': provider must be a non-empty string`,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
const stageModel = stage.model ?? s.defaults?.model ?? 'MiniMax-M3';
|
|
149
|
+
try {
|
|
150
|
+
validateProviderModel(stage.provider, stageModel);
|
|
151
|
+
}
|
|
152
|
+
catch (e) {
|
|
153
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
154
|
+
return {
|
|
155
|
+
ok: false,
|
|
156
|
+
error: `stage '${stage.id}': ${msg}`,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
if (stage.retry !== undefined) {
|
|
161
|
+
const err = validateRetryConfig(stage.retry, stage.id);
|
|
162
|
+
if (err)
|
|
163
|
+
return { ok: false, error: err };
|
|
164
|
+
}
|
|
165
|
+
if (stage.run_if !== undefined) {
|
|
166
|
+
if (typeof stage.run_if !== 'string' || stage.run_if.length === 0) {
|
|
167
|
+
return { ok: false, error: `stage '${stage.id}': run_if must be a non-empty string` };
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
if (stage.when !== undefined) {
|
|
171
|
+
const err = validateWhenInSpec(stage.when, stage.id);
|
|
172
|
+
if (err)
|
|
173
|
+
return { ok: false, error: err };
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return { ok: true, usesStages, warnings };
|
|
177
|
+
}
|
|
178
|
+
function validateWhenInSpec(when, stageId) {
|
|
179
|
+
if (typeof when === 'object' && when !== null && !Array.isArray(when)) {
|
|
180
|
+
const w = when;
|
|
181
|
+
if (Array.isArray(w.all)) {
|
|
182
|
+
for (const c of w.all) {
|
|
183
|
+
if (typeof c !== 'string') {
|
|
184
|
+
return `stage '${stageId}': when.all entries must be strings`;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
else if (Array.isArray(w.any)) {
|
|
189
|
+
for (const c of w.any) {
|
|
190
|
+
if (typeof c !== 'string') {
|
|
191
|
+
return `stage '${stageId}': when.any entries must be strings`;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
return `stage '${stageId}': when object must have 'all' or 'any' array`;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
else if (typeof when !== 'string') {
|
|
200
|
+
return `stage '${stageId}': when must be a string or object with all/any`;
|
|
201
|
+
}
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
function validateRetryConfig(retry, stageId) {
|
|
205
|
+
if (typeof retry !== 'object' || retry === null || Array.isArray(retry)) {
|
|
206
|
+
return `stage '${stageId}': retry must be an object`;
|
|
207
|
+
}
|
|
208
|
+
const r = retry;
|
|
209
|
+
if (r.attempts !== undefined) {
|
|
210
|
+
if (typeof r.attempts !== 'number' || r.attempts < 1 || r.attempts > 10 || !Number.isInteger(r.attempts)) {
|
|
211
|
+
return `stage '${stageId}': retry.attempts must be an integer 1..10 (got ${String(r.attempts)})`;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (r.backoff !== undefined && !['exponential', 'linear', 'fixed'].includes(String(r.backoff))) {
|
|
215
|
+
return `stage '${stageId}': retry.backoff must be one of exponential|linear|fixed (got ${String(r.backoff)})`;
|
|
216
|
+
}
|
|
217
|
+
if (r.retryable_status !== undefined) {
|
|
218
|
+
if (!Array.isArray(r.retryable_status)) {
|
|
219
|
+
return `stage '${stageId}': retry.retryable_status must be an array of HTTP status codes`;
|
|
220
|
+
}
|
|
221
|
+
for (const code of r.retryable_status) {
|
|
222
|
+
if (typeof code !== 'number' || code < 100 || code > 599 || !Number.isInteger(code)) {
|
|
223
|
+
return `stage '${stageId}': retry.retryable_status entries must be integers 100..599 (got ${String(code)})`;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
if (r.initial_ms !== undefined) {
|
|
228
|
+
if (typeof r.initial_ms !== 'number' || r.initial_ms < 0) {
|
|
229
|
+
return `stage '${stageId}': retry.initial_ms must be a non-negative number`;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
function validateUsesSyntax(uses, stageId) {
|
|
235
|
+
if (typeof uses === 'string') {
|
|
236
|
+
if (uses.length === 0)
|
|
237
|
+
return `stage '${stageId}': empty 'uses' string`;
|
|
238
|
+
const err = validateUsesEntrySyntax(uses, stageId, 0);
|
|
239
|
+
return err;
|
|
240
|
+
}
|
|
241
|
+
if (Array.isArray(uses)) {
|
|
242
|
+
if (uses.length === 0)
|
|
243
|
+
return `stage '${stageId}': empty 'uses' array`;
|
|
244
|
+
for (let j = 0; j < uses.length; j++) {
|
|
245
|
+
const item = uses[j];
|
|
246
|
+
if (typeof item !== 'string') {
|
|
247
|
+
return `stage '${stageId}': uses[${j}] must be a string (got ${typeof item})`;
|
|
248
|
+
}
|
|
249
|
+
const err = validateUsesEntrySyntax(item, stageId, j);
|
|
250
|
+
if (err)
|
|
251
|
+
return err;
|
|
252
|
+
}
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
return `stage '${stageId}': 'uses' must be a string or array of strings`;
|
|
256
|
+
}
|
|
257
|
+
function validateUsesEntrySyntax(raw, stageId, idx) {
|
|
258
|
+
const at = raw.lastIndexOf('@');
|
|
259
|
+
if (at === -1) {
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
if (at === 0)
|
|
263
|
+
return `stage '${stageId}': uses[${idx}] starts with '@' (empty skill id)`;
|
|
264
|
+
if (at === raw.length - 1)
|
|
265
|
+
return `stage '${stageId}': uses[${idx}] ends with '@' (empty version)`;
|
|
266
|
+
const id = raw.slice(0, at);
|
|
267
|
+
const version = raw.slice(at + 1);
|
|
268
|
+
if (!VERSION_HINT_RE.test(version)) {
|
|
269
|
+
return `stage '${stageId}': uses[${idx}] version part '${version}' is not a valid identifier (allowed: alphanumeric, '.', '_', '+', '-')`;
|
|
270
|
+
}
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
//# sourceMappingURL=pipeline-spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline-spec.js","sourceRoot":"","sources":["../../src/lib/pipeline-spec.ts"],"names":[],"mappings":"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"}
|