pandora-cli-skills 1.1.61 → 1.1.63
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/SKILL.md +8 -1
- package/cli/lib/agent_command_service.cjs +222 -0
- package/cli/lib/agent_contract_registry.cjs +133 -4
- package/cli/lib/agent_market_prompt_service.cjs +488 -0
- package/cli/lib/command_router.cjs +3 -0
- package/cli/lib/error_recovery_service.cjs +48 -3
- package/cli/lib/mcp_server_service.cjs +3 -1
- package/cli/lib/mcp_tool_registry.cjs +109 -6
- package/cli/lib/mirror_command_service.cjs +2 -2
- package/cli/lib/mirror_handlers/deploy.cjs +2 -2
- package/cli/lib/mirror_service.cjs +328 -22
- package/cli/lib/pandora_deploy_service.cjs +18 -0
- package/cli/lib/parsers/mirror_deploy_flags.cjs +6 -0
- package/cli/lib/parsers/mirror_go_flags.cjs +6 -0
- package/cli/lib/schema_command_service.cjs +40 -1
- package/cli/pandora.cjs +18 -0
- package/package.json +1 -1
package/SKILL.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: pandora-cli-skills
|
|
3
3
|
summary: Canonical skill and operator guide for Pandora CLI including mirror, polymarket, resolve, and LP flows.
|
|
4
|
-
version: 1.1.
|
|
4
|
+
version: 1.1.63
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Pandora CLI & Skills
|
|
@@ -40,6 +40,9 @@ npm link
|
|
|
40
40
|
- `--output json` is supported for all commands except `launch`/`clone-bet`; those stream script output directly.
|
|
41
41
|
- Agent schema command: `pandora --output json schema`
|
|
42
42
|
- MCP server mode: `pandora mcp`
|
|
43
|
+
- Agent market prompt tools:
|
|
44
|
+
- `pandora --output json agent market autocomplete --question "<text>" [--market-type amm|parimutuel]`
|
|
45
|
+
- `pandora --output json agent market validate --question "<text>" --rules "<text>" --target-timestamp <unix-seconds> [--sources <url...>]`
|
|
43
46
|
- Guided setup command: `pandora setup`
|
|
44
47
|
- Phase 1 discovery command: `pandora scan`
|
|
45
48
|
- Phase 1 lifecycle filters: `pandora markets list --active|--resolved|--expiring-soon`
|
|
@@ -73,6 +76,10 @@ npm link
|
|
|
73
76
|
- `--fork-chain-id <id>`
|
|
74
77
|
- JSON errors can include additive recovery hints:
|
|
75
78
|
- `error.recovery = { action, command, retryable }`
|
|
79
|
+
- Agent/MCP market creation policy:
|
|
80
|
+
- Agent-drafted manual markets should start with `agent market autocomplete` when rules, sources, or timing still need to be generated/refined.
|
|
81
|
+
- Execute/live MCP calls for `sports create run`, `mirror deploy`, and `mirror go` require a PASS attestation from `agent market validate`.
|
|
82
|
+
- Dry-run outputs for those flows include the exact validation ticket that must be echoed back via `agentPreflight` on the execute call.
|
|
76
83
|
- Doctor checks:
|
|
77
84
|
- env presence + format validation
|
|
78
85
|
- RPC reachability and chain id match
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
const {
|
|
2
|
+
buildAgentMarketAutocompletePayload,
|
|
3
|
+
buildAgentMarketValidationPayload,
|
|
4
|
+
} = require('./agent_market_prompt_service.cjs');
|
|
5
|
+
|
|
6
|
+
function requireDep(deps, name) {
|
|
7
|
+
if (!deps || typeof deps[name] !== 'function') {
|
|
8
|
+
throw new Error(`createRunAgentCommand requires deps.${name}()`);
|
|
9
|
+
}
|
|
10
|
+
return deps[name];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function readFlagValue(args, index, flagName) {
|
|
14
|
+
const value = args[index + 1];
|
|
15
|
+
if (typeof value !== 'string' || value.startsWith('--')) {
|
|
16
|
+
const error = new Error(`${flagName} requires a value.`);
|
|
17
|
+
error.code = 'MISSING_FLAG_VALUE';
|
|
18
|
+
throw error;
|
|
19
|
+
}
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function parseAgentMarketAutocompleteFlags(args) {
|
|
24
|
+
const options = {
|
|
25
|
+
question: '',
|
|
26
|
+
marketType: 'amm',
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
30
|
+
const token = args[i];
|
|
31
|
+
if (token === '--question') {
|
|
32
|
+
options.question = readFlagValue(args, i, '--question');
|
|
33
|
+
i += 1;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (token === '--market-type') {
|
|
37
|
+
options.marketType = readFlagValue(args, i, '--market-type');
|
|
38
|
+
i += 1;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
const error = new Error(`Unknown flag for agent market autocomplete: ${token}`);
|
|
42
|
+
error.code = 'UNKNOWN_FLAG';
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!String(options.question || '').trim()) {
|
|
47
|
+
const error = new Error('agent market autocomplete requires --question <text>.');
|
|
48
|
+
error.code = 'MISSING_REQUIRED_FLAG';
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return options;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function parseAgentMarketValidateFlags(args) {
|
|
56
|
+
const options = {
|
|
57
|
+
question: '',
|
|
58
|
+
rules: '',
|
|
59
|
+
sources: [],
|
|
60
|
+
targetTimestamp: 0,
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
64
|
+
const token = args[i];
|
|
65
|
+
if (token === '--question') {
|
|
66
|
+
options.question = readFlagValue(args, i, '--question');
|
|
67
|
+
i += 1;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (token === '--rules') {
|
|
71
|
+
options.rules = readFlagValue(args, i, '--rules');
|
|
72
|
+
i += 1;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (token === '--target-timestamp') {
|
|
76
|
+
const raw = readFlagValue(args, i, '--target-timestamp');
|
|
77
|
+
const numeric = Number(raw);
|
|
78
|
+
if (!Number.isFinite(numeric) || numeric <= 0) {
|
|
79
|
+
const error = new Error('--target-timestamp must be a unix timestamp in seconds.');
|
|
80
|
+
error.code = 'INVALID_FLAG_VALUE';
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
options.targetTimestamp = Math.trunc(numeric);
|
|
84
|
+
i += 1;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (token === '--sources') {
|
|
88
|
+
let consumed = 0;
|
|
89
|
+
for (let j = i + 1; j < args.length; j += 1) {
|
|
90
|
+
const value = args[j];
|
|
91
|
+
if (typeof value !== 'string' || value.startsWith('--')) break;
|
|
92
|
+
options.sources.push(value);
|
|
93
|
+
consumed += 1;
|
|
94
|
+
}
|
|
95
|
+
if (!consumed) {
|
|
96
|
+
const error = new Error('--sources requires at least one URL value.');
|
|
97
|
+
error.code = 'MISSING_FLAG_VALUE';
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
i += consumed;
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
if (token === '--source') {
|
|
104
|
+
options.sources.push(readFlagValue(args, i, '--source'));
|
|
105
|
+
i += 1;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
const error = new Error(`Unknown flag for agent market validate: ${token}`);
|
|
109
|
+
error.code = 'UNKNOWN_FLAG';
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (!String(options.question || '').trim()) {
|
|
114
|
+
const error = new Error('agent market validate requires --question <text>.');
|
|
115
|
+
error.code = 'MISSING_REQUIRED_FLAG';
|
|
116
|
+
throw error;
|
|
117
|
+
}
|
|
118
|
+
if (!String(options.rules || '').trim()) {
|
|
119
|
+
const error = new Error('agent market validate requires --rules <text>.');
|
|
120
|
+
error.code = 'MISSING_REQUIRED_FLAG';
|
|
121
|
+
throw error;
|
|
122
|
+
}
|
|
123
|
+
if (!options.targetTimestamp) {
|
|
124
|
+
const error = new Error('agent market validate requires --target-timestamp <unix-seconds>.');
|
|
125
|
+
error.code = 'MISSING_REQUIRED_FLAG';
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return options;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function renderAgentPromptTable(payload) {
|
|
133
|
+
const lines = [
|
|
134
|
+
`${payload.promptKind} (${payload.promptVersion})`,
|
|
135
|
+
];
|
|
136
|
+
if (payload.ticket) {
|
|
137
|
+
lines.push(`ticket: ${payload.ticket}`);
|
|
138
|
+
}
|
|
139
|
+
lines.push('');
|
|
140
|
+
lines.push('Prompt:');
|
|
141
|
+
lines.push(payload.prompt);
|
|
142
|
+
lines.push('');
|
|
143
|
+
lines.push('Workflow:');
|
|
144
|
+
for (const note of payload.workflow && Array.isArray(payload.workflow.notes) ? payload.workflow.notes : []) {
|
|
145
|
+
lines.push(`- ${note}`);
|
|
146
|
+
}
|
|
147
|
+
if (payload.requiredAttestation) {
|
|
148
|
+
lines.push('');
|
|
149
|
+
lines.push('Required attestation:');
|
|
150
|
+
lines.push(JSON.stringify(payload.requiredAttestation, null, 2));
|
|
151
|
+
}
|
|
152
|
+
// eslint-disable-next-line no-console
|
|
153
|
+
console.log(lines.join('\n'));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function createRunAgentCommand(deps) {
|
|
157
|
+
const CliError = deps.CliError;
|
|
158
|
+
const includesHelpFlag = requireDep(deps, 'includesHelpFlag');
|
|
159
|
+
const emitSuccess = requireDep(deps, 'emitSuccess');
|
|
160
|
+
const commandHelpPayload = requireDep(deps, 'commandHelpPayload');
|
|
161
|
+
|
|
162
|
+
if (typeof CliError !== 'function') {
|
|
163
|
+
throw new Error('createRunAgentCommand requires deps.CliError.');
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async function runAgentCommand(args, context) {
|
|
167
|
+
const rest = Array.isArray(args) ? args : [];
|
|
168
|
+
if (!rest.length || includesHelpFlag(rest)) {
|
|
169
|
+
const usage = [
|
|
170
|
+
'pandora [--output table|json] agent market autocomplete --question <text> [--market-type amm|parimutuel]',
|
|
171
|
+
'pandora [--output table|json] agent market validate --question <text> --rules <text> --target-timestamp <unix-seconds> [--sources <url...>]',
|
|
172
|
+
];
|
|
173
|
+
if (context.outputMode === 'json') {
|
|
174
|
+
emitSuccess(context.outputMode, 'agent.help', commandHelpPayload(usage));
|
|
175
|
+
} else {
|
|
176
|
+
renderAgentPromptTable({
|
|
177
|
+
promptKind: 'agent.help',
|
|
178
|
+
promptVersion: 'n/a',
|
|
179
|
+
ticket: null,
|
|
180
|
+
prompt: usage.join('\n'),
|
|
181
|
+
workflow: {
|
|
182
|
+
notes: [
|
|
183
|
+
'Use agent market autocomplete when the agent must draft market rules or timing.',
|
|
184
|
+
'Use agent market validate before any agent-exposed market execute path.',
|
|
185
|
+
],
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const namespace = rest[0];
|
|
193
|
+
const action = rest[1];
|
|
194
|
+
const actionArgs = rest.slice(2);
|
|
195
|
+
|
|
196
|
+
if (namespace !== 'market') {
|
|
197
|
+
throw new CliError('INVALID_ARGS', 'agent requires subcommand: market autocomplete|validate');
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (action === 'autocomplete') {
|
|
201
|
+
const payload = buildAgentMarketAutocompletePayload(parseAgentMarketAutocompleteFlags(actionArgs));
|
|
202
|
+
emitSuccess(context.outputMode, 'agent.market.autocomplete', payload, renderAgentPromptTable);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (action === 'validate') {
|
|
207
|
+
const payload = buildAgentMarketValidationPayload(parseAgentMarketValidateFlags(actionArgs));
|
|
208
|
+
emitSuccess(context.outputMode, 'agent.market.validate', payload, renderAgentPromptTable);
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
throw new CliError('INVALID_ARGS', 'agent market requires subcommand: autocomplete|validate');
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return {
|
|
216
|
+
runAgentCommand,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
module.exports = {
|
|
221
|
+
createRunAgentCommand,
|
|
222
|
+
};
|
|
@@ -43,6 +43,21 @@ function flexibleArraySchema(itemSchema, description, extras = {}) {
|
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
function buildAgentPreflightSchema(description) {
|
|
47
|
+
return {
|
|
48
|
+
type: 'object',
|
|
49
|
+
properties: {
|
|
50
|
+
validationTicket: stringSchema('Ticket returned by agent.market.validate for the exact market payload.'),
|
|
51
|
+
validationDecision: enumSchema(['PASS', 'FAIL'], 'Validation verdict from the agent AI run.'),
|
|
52
|
+
validationSummary: stringSchema('Short summary of the validation result.'),
|
|
53
|
+
autocompleteTicket: stringSchema('Optional ticket from agent.market.autocomplete when the agent drafted the market.'),
|
|
54
|
+
},
|
|
55
|
+
required: ['validationTicket', 'validationDecision', 'validationSummary'],
|
|
56
|
+
additionalProperties: false,
|
|
57
|
+
...(description ? { description } : {}),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
46
61
|
function buildIntentSchema() {
|
|
47
62
|
return {
|
|
48
63
|
type: 'object',
|
|
@@ -191,6 +206,58 @@ const commandContracts = [
|
|
|
191
206
|
dataSchema: MCP_HELP_SCHEMA_REF,
|
|
192
207
|
helpDataSchema: null,
|
|
193
208
|
}),
|
|
209
|
+
commandContract({
|
|
210
|
+
name: 'agent',
|
|
211
|
+
summary: 'Agent prompt workflow namespace for market drafting and validation.',
|
|
212
|
+
usage: 'pandora [--output table|json] agent market autocomplete|validate ...',
|
|
213
|
+
emits: ['agent.help'],
|
|
214
|
+
dataSchema: COMMAND_HELP_SCHEMA_REF,
|
|
215
|
+
helpDataSchema: null,
|
|
216
|
+
}),
|
|
217
|
+
commandContract({
|
|
218
|
+
name: 'agent.market.autocomplete',
|
|
219
|
+
summary: 'Emit AI prompt text for drafting market rules, sources, and timing.',
|
|
220
|
+
usage:
|
|
221
|
+
'pandora [--output table|json] agent market autocomplete --question <text> [--market-type amm|parimutuel]',
|
|
222
|
+
emits: ['agent.market.autocomplete', 'agent.help'],
|
|
223
|
+
dataSchema: '#/definitions/AgentMarketPromptPayload',
|
|
224
|
+
mcpExposed: true,
|
|
225
|
+
mcp: {
|
|
226
|
+
command: ['agent', 'market', 'autocomplete'],
|
|
227
|
+
description: 'Emit AI autocomplete prompt for market drafting.',
|
|
228
|
+
inputSchema: buildInputSchema({
|
|
229
|
+
flagProperties: {
|
|
230
|
+
question: stringSchema('Seed market question to refine into rules, sources, and timing.'),
|
|
231
|
+
'market-type': enumSchema(['amm', 'parimutuel'], 'Target market type.'),
|
|
232
|
+
},
|
|
233
|
+
requiredFlags: ['question'],
|
|
234
|
+
}),
|
|
235
|
+
preferred: true,
|
|
236
|
+
},
|
|
237
|
+
}),
|
|
238
|
+
commandContract({
|
|
239
|
+
name: 'agent.market.validate',
|
|
240
|
+
summary: 'Emit AI validation prompt text plus the exact attestation ticket required for execute mode.',
|
|
241
|
+
usage:
|
|
242
|
+
'pandora [--output table|json] agent market validate --question <text> --rules <text> --target-timestamp <unix-seconds> [--sources <url...>]',
|
|
243
|
+
emits: ['agent.market.validate', 'agent.help'],
|
|
244
|
+
dataSchema: '#/definitions/AgentMarketPromptPayload',
|
|
245
|
+
mcpExposed: true,
|
|
246
|
+
mcp: {
|
|
247
|
+
command: ['agent', 'market', 'validate'],
|
|
248
|
+
description: 'Emit AI validation prompt and required attestation ticket for market execution.',
|
|
249
|
+
inputSchema: buildInputSchema({
|
|
250
|
+
flagProperties: {
|
|
251
|
+
question: stringSchema('Exact market question to validate.'),
|
|
252
|
+
rules: stringSchema('Exact market rules to validate.'),
|
|
253
|
+
'target-timestamp': integerSchema('Resolution timestamp in unix seconds.', { minimum: 1 }),
|
|
254
|
+
sources: flexibleArraySchema(stringSchema(), 'Source URL list.'),
|
|
255
|
+
},
|
|
256
|
+
requiredFlags: ['question', 'rules', 'target-timestamp'],
|
|
257
|
+
}),
|
|
258
|
+
preferred: true,
|
|
259
|
+
},
|
|
260
|
+
}),
|
|
194
261
|
commandContract({
|
|
195
262
|
name: 'launch',
|
|
196
263
|
summary: 'Launch a one-off market via the interactive/non-JSON deployment flow.',
|
|
@@ -198,6 +265,15 @@ const commandContracts = [
|
|
|
198
265
|
'pandora launch --dry-run|--execute [options] --question "<text>" --rules "<resolution rules>" --sources "<url1>" "<url2>" [more] --target-timestamp <unix-seconds>',
|
|
199
266
|
emits: ['launch.help'],
|
|
200
267
|
outputModes: ['table'],
|
|
268
|
+
agentWorkflow: {
|
|
269
|
+
requiredTools: ['agent.market.validate'],
|
|
270
|
+
recommendedTools: ['agent.market.autocomplete'],
|
|
271
|
+
executeRequiresValidation: true,
|
|
272
|
+
notes: [
|
|
273
|
+
'When an agent drafts or executes a manual launch market, run autocomplete first if rules or timing still need refinement.',
|
|
274
|
+
'Run agent.market.validate on the final payload before any execute path.',
|
|
275
|
+
],
|
|
276
|
+
},
|
|
201
277
|
}),
|
|
202
278
|
commandContract({
|
|
203
279
|
name: 'clone-bet',
|
|
@@ -206,6 +282,14 @@ const commandContracts = [
|
|
|
206
282
|
'pandora clone-bet --dry-run|--execute [options] --question "<text>" --rules "<resolution rules>" --sources "<url1>" "<url2>" [more] --target-timestamp <unix-seconds>',
|
|
207
283
|
emits: ['clone-bet.help'],
|
|
208
284
|
outputModes: ['table'],
|
|
285
|
+
agentWorkflow: {
|
|
286
|
+
requiredTools: ['agent.market.validate'],
|
|
287
|
+
recommendedTools: ['agent.market.autocomplete'],
|
|
288
|
+
executeRequiresValidation: true,
|
|
289
|
+
notes: [
|
|
290
|
+
'When an agent drafts or executes a clone-bet market, validate the final payload before execute mode.',
|
|
291
|
+
],
|
|
292
|
+
},
|
|
209
293
|
}),
|
|
210
294
|
commandContract({
|
|
211
295
|
name: 'markets',
|
|
@@ -1202,6 +1286,15 @@ const commandContracts = [
|
|
|
1202
1286
|
emits: ['sports.create.run', 'sports.help'],
|
|
1203
1287
|
dataSchema: '#/definitions/SportsCreatePayload',
|
|
1204
1288
|
mcpExposed: true,
|
|
1289
|
+
agentWorkflow: {
|
|
1290
|
+
requiredTools: ['agent.market.validate'],
|
|
1291
|
+
recommendedTools: ['agent.market.autocomplete'],
|
|
1292
|
+
executeRequiresValidation: true,
|
|
1293
|
+
notes: [
|
|
1294
|
+
'Use agent.market.autocomplete when the agent must rewrite the question, rules, or timing before market creation.',
|
|
1295
|
+
'Run agent.market.validate on the exact final sports market payload before any execute path.',
|
|
1296
|
+
],
|
|
1297
|
+
},
|
|
1205
1298
|
mcp: {
|
|
1206
1299
|
command: ['sports', 'create', 'run'],
|
|
1207
1300
|
description: 'Execute or dry-run sports market creation.',
|
|
@@ -1217,6 +1310,7 @@ const commandContracts = [
|
|
|
1217
1310
|
'chain-id': commonFlags.chainId,
|
|
1218
1311
|
'rpc-url': commonFlags.rpcUrl,
|
|
1219
1312
|
'private-key': commonFlags.privateKey,
|
|
1313
|
+
agentPreflight: buildAgentPreflightSchema('Agent validation attestation for execute mode.'),
|
|
1220
1314
|
},
|
|
1221
1315
|
requiredFlags: ['event-id'],
|
|
1222
1316
|
}),
|
|
@@ -1224,6 +1318,7 @@ const commandContracts = [
|
|
|
1224
1318
|
mutating: true,
|
|
1225
1319
|
safeFlags: ['--dry-run', '--paper'],
|
|
1226
1320
|
executeFlags: ['--execute'],
|
|
1321
|
+
controlInputNames: ['agentPreflight'],
|
|
1227
1322
|
},
|
|
1228
1323
|
}),
|
|
1229
1324
|
commandContract({
|
|
@@ -1828,10 +1923,20 @@ const commandContracts = [
|
|
|
1828
1923
|
name: 'mirror.deploy',
|
|
1829
1924
|
summary: 'Deploy a mirror market from selector or plan in dry-run or execute mode.',
|
|
1830
1925
|
usage:
|
|
1831
|
-
'pandora [--output table|json] mirror deploy --plan-file <path>|--polymarket-market-id <id>|--polymarket-slug <slug> --dry-run|--execute [--liquidity-usdc <n>] [--fee-tier <500-50000>] [--max-imbalance <n>] [--arbiter <address>] [--category <n>] [--chain-id <id>] [--rpc-url <url>] [--private-key <hex>] [--oracle <address>] [--factory <address>] [--usdc <address>] [--distribution-yes <parts>] [--distribution-no <parts>] [--sources <url...>] [--manifest-file <path>] [--polymarket-host <url>] [--polymarket-gamma-url <url>] [--polymarket-gamma-mock-url <url>] [--polymarket-mock-url <url>] [--min-close-lead-seconds <n>]',
|
|
1926
|
+
'pandora [--output table|json] mirror deploy --plan-file <path>|--polymarket-market-id <id>|--polymarket-slug <slug> --dry-run|--execute [--liquidity-usdc <n>] [--fee-tier <500-50000>] [--max-imbalance <n>] [--arbiter <address>] [--category <n>] [--chain-id <id>] [--rpc-url <url>] [--private-key <hex>] [--oracle <address>] [--factory <address>] [--usdc <address>] [--distribution-yes <parts>] [--distribution-no <parts>] [--sources <url...>] [--validation-ticket <ticket>] [--manifest-file <path>] [--polymarket-host <url>] [--polymarket-gamma-url <url>] [--polymarket-gamma-mock-url <url>] [--polymarket-mock-url <url>] [--min-close-lead-seconds <n>]',
|
|
1832
1927
|
emits: ['mirror.deploy', 'mirror.deploy.help'],
|
|
1833
1928
|
dataSchema: '#/definitions/MirrorDeployPayload',
|
|
1834
1929
|
mcpExposed: true,
|
|
1930
|
+
agentWorkflow: {
|
|
1931
|
+
requiredTools: ['agent.market.validate'],
|
|
1932
|
+
recommendedTools: ['agent.market.autocomplete'],
|
|
1933
|
+
executeRequiresValidation: true,
|
|
1934
|
+
notes: [
|
|
1935
|
+
'Mirror deploy dry-run returns the exact Pandora deployment payload and required validation ticket.',
|
|
1936
|
+
'Mirror deploy never auto-copies Polymarket URLs into sources; pass independent public resolution URLs with --sources.',
|
|
1937
|
+
'Run agent.market.validate on that final payload before rerunning mirror.deploy with execute mode, then pass --validation-ticket locally or agentPreflight in MCP.',
|
|
1938
|
+
],
|
|
1939
|
+
},
|
|
1835
1940
|
mcp: {
|
|
1836
1941
|
command: ['mirror', 'deploy'],
|
|
1837
1942
|
description: 'Dry-run or execute mirror deployment.',
|
|
@@ -1857,18 +1962,21 @@ const commandContracts = [
|
|
|
1857
1962
|
'distribution-yes': numberSchema('Initial YES distribution parts.', { minimum: 0 }),
|
|
1858
1963
|
'distribution-no': numberSchema('Initial NO distribution parts.', { minimum: 0 }),
|
|
1859
1964
|
sources: flexibleArraySchema(stringSchema(), 'Source URL list.'),
|
|
1965
|
+
'validation-ticket': stringSchema('Ticket returned by agent.market.validate for the exact final payload (CLI execute mode).'),
|
|
1860
1966
|
'manifest-file': stringSchema('Mirror manifest path.'),
|
|
1861
1967
|
'polymarket-host': stringSchema('Polymarket host override.'),
|
|
1862
1968
|
'polymarket-gamma-url': stringSchema('Polymarket Gamma API base URL.'),
|
|
1863
1969
|
'polymarket-gamma-mock-url': stringSchema('Polymarket Gamma mock URL.'),
|
|
1864
1970
|
'polymarket-mock-url': stringSchema('Polymarket mock CLOB URL.'),
|
|
1865
1971
|
'min-close-lead-seconds': integerSchema('Minimum close lead time in seconds.', { minimum: 0 }),
|
|
1972
|
+
agentPreflight: buildAgentPreflightSchema('Agent validation attestation for execute mode.'),
|
|
1866
1973
|
},
|
|
1867
1974
|
}),
|
|
1868
1975
|
preferred: true,
|
|
1869
1976
|
mutating: true,
|
|
1870
1977
|
safeFlags: ['--dry-run'],
|
|
1871
1978
|
executeFlags: ['--execute'],
|
|
1979
|
+
controlInputNames: ['agentPreflight'],
|
|
1872
1980
|
},
|
|
1873
1981
|
}),
|
|
1874
1982
|
commandContract({
|
|
@@ -1983,10 +2091,20 @@ const commandContracts = [
|
|
|
1983
2091
|
name: 'mirror.go',
|
|
1984
2092
|
summary: 'Run mirror deploy, verify, and optional sync workflow.',
|
|
1985
2093
|
usage:
|
|
1986
|
-
'pandora [--output table|json] mirror go --polymarket-market-id <id>|--polymarket-slug <slug> [--liquidity-usdc <n>] [--fee-tier <500-50000>] [--max-imbalance <n>] [--arbiter <address>] [--category <n>] [--paper|--dry-run|--execute-live|--execute] [--auto-sync] [--sync-once] [--sync-interval-ms <ms>] [--max-open-exposure-usdc <amount>] [--max-trades-per-day <n>] [--polymarket-rpc-url <url>] [--manifest-file <path>] [--dotenv-path <path>] [--rpc-url <url>] [--private-key <hex>]',
|
|
2094
|
+
'pandora [--output table|json] mirror go --polymarket-market-id <id>|--polymarket-slug <slug> [--liquidity-usdc <n>] [--fee-tier <500-50000>] [--max-imbalance <n>] [--arbiter <address>] [--category <n>] [--paper|--dry-run|--execute-live|--execute] [--auto-sync] [--sync-once] [--sync-interval-ms <ms>] [--max-open-exposure-usdc <amount>] [--max-trades-per-day <n>] [--polymarket-rpc-url <url>] [--sources <url...>] [--validation-ticket <ticket>] [--manifest-file <path>] [--dotenv-path <path>] [--rpc-url <url>] [--private-key <hex>]',
|
|
1987
2095
|
emits: ['mirror.go', 'mirror.go.help'],
|
|
1988
2096
|
dataSchema: '#/definitions/MirrorDeployPayload',
|
|
1989
2097
|
mcpExposed: true,
|
|
2098
|
+
agentWorkflow: {
|
|
2099
|
+
requiredTools: ['agent.market.validate'],
|
|
2100
|
+
recommendedTools: ['agent.market.autocomplete'],
|
|
2101
|
+
executeRequiresValidation: true,
|
|
2102
|
+
notes: [
|
|
2103
|
+
'Mirror go inherits the exact market payload from its deploy stage; use the returned validation ticket from paper/dry-run output.',
|
|
2104
|
+
'When mirror go will execute a fresh deploy, provide independent public --sources and a matching validation ticket.',
|
|
2105
|
+
'Run agent.market.validate on that exact payload before rerunning mirror.go with execute or execute-live.',
|
|
2106
|
+
],
|
|
2107
|
+
},
|
|
1990
2108
|
mcp: {
|
|
1991
2109
|
command: ['mirror', 'go'],
|
|
1992
2110
|
description: 'Plan/deploy/verify/go orchestration.',
|
|
@@ -2010,16 +2128,20 @@ const commandContracts = [
|
|
|
2010
2128
|
'max-open-exposure-usdc': numberSchema('Maximum open exposure in USDC.', { minimum: 0 }),
|
|
2011
2129
|
'max-trades-per-day': integerSchema('Maximum daily trade count.', { minimum: 0 }),
|
|
2012
2130
|
'polymarket-rpc-url': stringSchema('Polygon RPC URL for Polymarket preflight.'),
|
|
2131
|
+
sources: flexibleArraySchema(stringSchema(), 'Independent public source URL list.'),
|
|
2132
|
+
'validation-ticket': stringSchema('Ticket returned by agent.market.validate for the exact final payload (CLI execute mode).'),
|
|
2013
2133
|
'manifest-file': stringSchema('Mirror manifest path.'),
|
|
2014
2134
|
'dotenv-path': stringSchema('Env file path.'),
|
|
2015
2135
|
'rpc-url': commonFlags.rpcUrl,
|
|
2016
2136
|
'private-key': commonFlags.privateKey,
|
|
2137
|
+
agentPreflight: buildAgentPreflightSchema('Agent validation attestation for execute or execute-live mode.'),
|
|
2017
2138
|
},
|
|
2018
2139
|
}),
|
|
2019
2140
|
preferred: true,
|
|
2020
2141
|
mutating: true,
|
|
2021
|
-
safeFlags: ['--paper'],
|
|
2022
|
-
executeFlags: ['--execute-live'],
|
|
2142
|
+
safeFlags: ['--paper', '--dry-run'],
|
|
2143
|
+
executeFlags: ['--execute-live', '--execute'],
|
|
2144
|
+
controlInputNames: ['agentPreflight'],
|
|
2023
2145
|
},
|
|
2024
2146
|
}),
|
|
2025
2147
|
commandContract({
|
|
@@ -2518,6 +2640,11 @@ function buildCommandDescriptors() {
|
|
|
2518
2640
|
preferred: contract.mcp && contract.mcp.preferred === false ? false : Boolean(canonicalTool ? contract.name === canonicalTool : contract.aliasOf ? false : contract.mcpExposed),
|
|
2519
2641
|
mcpMutating: Boolean(contract.mcp && contract.mcp.mutating),
|
|
2520
2642
|
mcpLongRunningBlocked: Boolean(contract.mcp && contract.mcp.longRunningBlocked),
|
|
2643
|
+
controlInputNames:
|
|
2644
|
+
contract.mcp && Array.isArray(contract.mcp.controlInputNames)
|
|
2645
|
+
? [...contract.mcp.controlInputNames]
|
|
2646
|
+
: [],
|
|
2647
|
+
agentWorkflow: contract.agentWorkflow || null,
|
|
2521
2648
|
};
|
|
2522
2649
|
}
|
|
2523
2650
|
return descriptors;
|
|
@@ -2539,6 +2666,8 @@ function buildMcpToolDefinitions() {
|
|
|
2539
2666
|
aliasOf: contract.aliasOf || null,
|
|
2540
2667
|
canonicalTool: contract.canonicalTool || contract.aliasOf || contract.name,
|
|
2541
2668
|
preferred: contract.mcp.preferred !== false,
|
|
2669
|
+
controlInputNames: Array.isArray(contract.mcp.controlInputNames) ? [...contract.mcp.controlInputNames] : undefined,
|
|
2670
|
+
agentWorkflow: contract.agentWorkflow || null,
|
|
2542
2671
|
}));
|
|
2543
2672
|
}
|
|
2544
2673
|
|