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 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.61
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