jaspervault_cli 1.0.26 → 1.0.27

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.
@@ -4,6 +4,8 @@
4
4
  * SKILL.md — compact core rules + activation + intent table
5
5
  * references/ — detailed docs loaded on demand by the agent
6
6
  * scripts/ — helper scripts
7
+ *
8
+ * All content is read from skill-content/ directory (independent .md files).
7
9
  */
8
10
  /** ANSI Shadow style ASCII art banner (plain text, no ANSI colors) */
9
11
  export declare const BANNER: string;
@@ -4,6 +4,8 @@
4
4
  * SKILL.md — compact core rules + activation + intent table
5
5
  * references/ — detailed docs loaded on demand by the agent
6
6
  * scripts/ — helper scripts
7
+ *
8
+ * All content is read from skill-content/ directory (independent .md files).
7
9
  */
8
10
  import { readFileSync } from 'node:fs';
9
11
  import { fileURLToPath } from 'node:url';
@@ -29,490 +31,26 @@ export const BANNER = `
29
31
  ⟐ Skill Installer
30
32
  `.trim();
31
33
  // ---------------------------------------------------------------------------
32
- // Core SKILL.md body kept under 50 lines so critical rules stay prominent
34
+ // Content directory — .md files live here, copied to dist/ at build time
33
35
  // ---------------------------------------------------------------------------
34
- const SKILL_CORE_BODY = `
35
- Trade perpetual contracts on JasperVault via the \`jv\` CLI. No private key is ever required.
36
-
37
- ## CRITICAL RULES (MUST FOLLOW — violations cause broken UX)
38
-
39
- 1. **WalletConnect ONLY**: ALWAYS use \`jv vault setup\`. NEVER suggest \`jv vault init\` (private-key mode). NEVER ask the user to set \`PRIVATE_KEY\`.
40
- 2. **QR Code Display**: When \`jv vault setup\` outputs JSON with a \`qrCodeUrl\` field, you MUST display the \`qrCodeUrl\` value as a clickable link to the user. This is the only QR code field in the output — there are no other QR representations.
41
- 3. **Long-running Commands**: \`jv vault setup\` is a long-running command (up to 2 min) that will be auto-backgrounded. After it backgrounds you receive a \`sessionId\` and the first JSON output (QR code). Show the QR link to the user, then poll every 15 seconds with \`process poll\` using that \`sessionId\` until you see the second JSON line containing \`"success":true\` or the process exits. See [references/onboarding.md](references/onboarding.md) for the full step-by-step flow.
42
- 4. **Real-time Prices**: NEVER guess or estimate prices. ALWAYS run \`jv price --symbol JBTC --pretty\` before any price-dependent operation (opening a position by asset quantity, calculating PnL).
43
- 5. **PPO Auto-Cancellation**: When performing any position operation (reduce, close, add size) WITHOUT \`--ppo\`, the smart contract automatically cancels existing PPO hedge options. There is NO separate "cancel PPO" command. NEVER attempt a separate cancellation — it risks unintended position closures.
44
- 6. **Standalone PPO Protection**: To add hedge protection to an **existing position**, use \`jv order protect --order-id <id> --symbol <symbol>\`. Do NOT use \`jv order create --ppo\` for this — that command ADDS POSITION SIZE. \`jv order create --ppo\` is ONLY for opening new positions or adding size with protection. See [references/trading.md](references/trading.md) for details.
45
-
46
- ## Activation Behavior
47
-
48
- 1. Check if vault is initialized: \`jv orders list --pretty\`
49
- 2. If the command fails (exit code 1, or errors like "delegation key not found" / "vault not initialized" / "no profile"):
50
- - Tell the user: "Your vault is not initialized yet. Let me set it up via WalletConnect — no private key needed."
51
- - Immediately run \`jv vault setup --network jaspervault --timeout 120\`.
52
- - Follow the QR code display instructions in [references/onboarding.md](references/onboarding.md).
53
- 3. If the command succeeds → vault is ready. Proceed with the user's request.
54
-
55
- ## Intent → Command Reference
56
-
57
- | User Intent | Command | Details |
58
- |-------------|---------|---------|
59
- | Initialize / connect wallet | \`jv vault setup\` | [references/onboarding.md](references/onboarding.md) |
60
- | Deposit tokens | \`jv deposit info\` + \`jv deposit poll\` | [references/onboarding.md](references/onboarding.md) |
61
- | Get current price | \`jv price --symbol JBTC --pretty\` | [references/trading.md](references/trading.md) |
62
- | Open position (market) | \`jv order create --side long/short ...\` | [references/trading.md](references/trading.md) |
63
- | Open position (limit) | \`jv order create ... --limit-price N\` | [references/trading.md](references/trading.md) |
64
- | Reduce / close position | opposite-side \`jv order create\` | [references/trading.md](references/trading.md) |
65
- | Set take-profit | \`jv tp set --order-id ID --price P\` | [references/trading.md](references/trading.md) |
66
- | Set stop-loss | \`jv sl set --order-id ID --price P\` | [references/trading.md](references/trading.md) |
67
- | Add PPO to existing position | \`jv order protect --order-id <id>\` | [references/trading.md](references/trading.md) |
68
- | Open/add-size with PPO | add \`--ppo\` to \`jv order create\` | [references/trading.md](references/trading.md) |
69
- | Cancel PPO / remove hedge | order without \`--ppo\` (auto-cancels) | [references/trading.md](references/trading.md) |
70
- | Query positions / portfolio | \`jv orders list --pretty\` | [references/queries.md](references/queries.md) |
71
- | Job execution status | \`jv job status <jobId>\` | [references/queries.md](references/queries.md) |
72
- | Manage limit orders | \`jv limit-order list/cancel\` | [references/queries.md](references/queries.md) |
73
-
74
- ## Security
75
-
76
- - Never log or display private keys, signatures, or API keys.
77
- - The CLI signs orders via the delegation wallet in \`~/.jaspervault/keys.json\`.
78
- - Do NOT ask the user to set \`PRIVATE_KEY\`.
79
- `.trim();
80
- // ---------------------------------------------------------------------------
81
- // references/onboarding.md — WalletConnect init + deposit flow
82
- // ---------------------------------------------------------------------------
83
- const ONBOARDING_REFERENCE = `# WalletConnect Onboarding & Deposit
84
-
85
- ## Vault Init via WalletConnect
86
-
87
- \`jv vault setup\` is a long-running command (up to 2 minutes). It will be auto-backgrounded by the exec tool. You MUST use \`process poll\` to retrieve the final result. Follow these three steps exactly:
88
-
89
- ### Step 1: Run the command and show QR code
90
-
91
- \`\`\`bash
92
- jv vault setup --network jaspervault --timeout 120
93
- \`\`\`
94
-
95
- The command will be auto-backgrounded after ~10 seconds. You will receive:
96
- - A \`sessionId\` for the background session
97
- - The first JSON output containing the QR code
98
-
99
- First JSON output:
100
- \`\`\`json
101
- {"status":"awaiting_connection", "qrCodeUrl":"https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=wc%3A...", "uri":"wc:...", "message":"Scan QR code or paste URI in wallet to connect"}
102
- \`\`\`
103
-
104
- Display the \`qrCodeUrl\` value as a clickable link so the user can open it and scan the QR code. Also provide the \`uri\` as a fallback:
105
-
106
- > Or open your wallet app → WalletConnect → paste this URI: \`wc:...\`
107
-
108
- ### Step 2: Poll for completion
109
-
110
- After showing the QR code, poll the background session every 15 seconds using the \`sessionId\`:
111
-
112
- \`\`\`json
113
- {"tool":"process", "action":"poll", "sessionId":"<sessionId from step 1>"}
114
- \`\`\`
115
-
116
- Keep polling until you see the second JSON line in the output containing \`"success":true\`, or the process exits. Do NOT stop polling early — the user needs time to scan the QR code and approve the signature on their phone.
117
-
118
- ### Step 3: Handle the result
119
-
120
- When polling returns the second JSON line:
121
- \`\`\`json
122
- {"success":true, "message":"Vault initialized successfully", ...}
123
- \`\`\`
124
-
125
- Tell the user: "Vault initialized successfully. You can now deposit and trade."
126
-
127
- If polling shows the process exited with an error or \`"success":false\`, report the error message to the user.
128
-
129
- The delegation wallet is saved to \`~/.jaspervault/keys.json\` and vault addresses to \`~/.jaspervault/profile.json\`. Subsequent commands use these automatically — no wallet interaction needed.
130
-
131
- ## Deposit via WalletConnect (Optional)
132
-
133
- If the user wants to deposit:
134
-
135
- 1. **Get unsigned transactions:**
136
- \`\`\`bash
137
- jv deposit info --wallet <walletAddress> --token jusdc --amount 100
138
- \`\`\`
139
-
140
- 2. **Output contains \`transactions\` array.** Each \`tx\` has \`to\`, \`data\`, \`value\`, \`chainId\`. Send each via WalletConnect \`eth_sendTransaction\` to the user's wallet. Execute in order (approve first if present, then transferRemote).
141
-
142
- 3. **After transactions confirm**, poll for arrival:
143
- \`\`\`bash
144
- jv deposit poll --recipient <recipient> --token jusdc
145
- \`\`\`
146
- Use the \`recipient\` from step 1 output.
147
-
148
- 4. Tell the user: "Deposit completed. Your tokens have arrived on JasperVault."
149
- `;
150
- // ---------------------------------------------------------------------------
151
- // references/trading.md — margin, orders, reduce/close, TP/SL, price
152
- // ---------------------------------------------------------------------------
153
- const TRADING_REFERENCE = `# Trading Commands
154
-
155
- ## Getting Market Price
156
-
157
- MUST use before any price-dependent operation (opening position by asset quantity, calculating PnL).
158
-
159
- \`\`\`bash
160
- jv price --symbol JBTC --pretty
161
- jv price --symbol CBBTC --pretty
162
- \`\`\`
163
-
164
- Output:
165
- \`\`\`json
166
- {"symbol":"JBTC","price":"87295.123456","priceWei":"87295123456000000000000","source":"quote_center","timestamp":"2026-03-05T10:30:00.000Z"}
167
- \`\`\`
168
-
169
- Use the \`price\` field (human-readable USD value) for display and calculations. This command does NOT require vault initialization — it can be run anytime.
170
-
171
- ## How \`--margin\` Works
172
-
173
- \`--margin\` = the **actual collateral (margin) in USDC** you deposit. The CLI internally multiplies by leverage to compute the notional position size.
174
-
175
- | Concept | Formula | Example |
176
- |---------|---------|---------|
177
- | Notional value | \`margin × leverage\` | 60 USDC × 50x = $3,000 |
178
- | Position size | \`notional / current_price\` | $3,000 / $70,000 = 0.0428 JBTC |
179
-
180
- ### Translating user intent to \`--margin\`:
181
-
182
- | User says | Calculation | Pass to CLI |
183
- |-----------|-------------|-------------|
184
- | "long with $60 USDC margin at 50x" | already the margin | \`--margin 60\` |
185
- | "open a $3,000 notional position at 50x" | margin = 3000 / 50 = 60 | \`--margin 60\` |
186
- | "long 0.1 BTC at 50x" | margin = (0.1 × current_price) / 50 | \`--margin <result>\` |
187
-
188
- CRITICAL: When the user specifies an asset amount (e.g. "0.1 BTC"), you MUST first run \`jv price --symbol JBTC --pretty\` to get the current price, then compute \`notional = size × price\`, then \`margin = notional / leverage\`.
189
-
190
- ## Creating Orders
191
-
192
- \`\`\`bash
193
- # Market order: Long JBTC, 60 USDC margin at 50x (= $3,000 notional)
194
- jv order create --side long --symbol JBTC --margin 60 --leverage 50 --network jaspervault
195
-
196
- # Market order: Short JBTC, 100 USDC margin at 50x (= $5,000 notional)
197
- jv order create --side short --symbol JBTC --margin 100 --leverage 50 --network jaspervault
198
-
199
- # Limit order: add --limit-price
200
- jv order create --side long --symbol JBTC --margin 60 --leverage 50 --limit-price 65000 --network jaspervault
201
- \`\`\`
202
-
203
- The CLI signs the order internally using the delegation wallet. No pre-signed payload required.
204
-
205
- On success, a market order returns \`jobId\`; a limit order returns \`limitOrderId\`.
206
-
207
- ## Reducing / Closing a Position
208
-
209
- Create an **opposite-side order** with the margin portion you want to close. The system automatically detects existing positions and performs a partial close.
210
-
211
- 1. Query current position: \`jv orders list --pretty\`
212
- 2. Read the \`margin\` field directly from output (e.g. 60 USDC)
213
- 3. To close half: \`close_margin = margin / 2\` (e.g. 30 USDC)
214
- 4. Create opposite-side order with that margin value
215
-
216
- **Reduce LONG by half (30 USDC margin):**
217
- \`\`\`bash
218
- jv order create --side short --symbol JBTC --margin 30 --leverage 50 --network jaspervault
219
- \`\`\`
220
-
221
- **Close entire LONG (60 USDC margin):**
222
- \`\`\`bash
223
- jv order create --side short --symbol JBTC --margin 60 --leverage 50 --network jaspervault
224
- \`\`\`
225
-
226
- IMPORTANT: The \`--margin\` for reduction = the margin portion you want to close (read directly from \`jv orders list\` output \`margin\` field).
227
-
228
- ## Setting Take-Profit
229
-
230
- \`\`\`bash
231
- jv tp set --order-id <orderId> --price <usdc_price> --symbol <symbol> --network jaspervault
232
- \`\`\`
233
-
234
- Example: \`jv tp set --order-id 99 --price 105000 --symbol JBTC --network jaspervault\`
235
-
236
- Returns \`limitOrderId\` on success.
237
-
238
- ## Setting Stop-Loss
239
-
240
- \`\`\`bash
241
- jv sl set --order-id <orderId> --price <usdc_price> --symbol <symbol> --network jaspervault
242
- \`\`\`
243
-
244
- Example: \`jv sl set --order-id 99 --price 90000 --symbol JBTC --network jaspervault\`
245
-
246
- Returns \`limitOrderId\` on success.
247
-
248
- ## PPO Hedge Protection
249
-
250
- There are TWO different commands depending on the scenario:
251
-
252
- | Scenario | Command | Backend Operation |
253
- |----------|---------|-------------------|
254
- | Add protection to **existing position** (no size change) | \`jv order protect --order-id <id>\` | CREATE_OPTION |
255
- | Open new position **with** protection | \`jv order create --ppo ...\` | CREATE_WITH_OPTION |
256
- | Add size to position **with** protection | \`jv order create --ppo ...\` (same side) | ADD_SIZE_OPTION |
257
-
258
- ### Decision Rule (CRITICAL)
259
-
260
- **If the user ALREADY HAS a position and only wants to add/renew hedge protection — use \`jv order protect\`.** Do NOT use \`jv order create --ppo\` for this, as it will add unwanted position size.
261
-
262
- Only use \`jv order create --ppo\` when the user explicitly wants to open a new position or add size AND include protection at the same time.
263
-
264
- ### Adding Protection to Existing Position
265
-
266
- \`\`\`bash
267
- jv order protect --order-id <id> --symbol <symbol> [options] --network jaspervault
268
- \`\`\`
269
-
270
- **Required**: \`--order-id\` (from \`jv orders list\`) and \`--symbol\`.
271
-
272
- **Options:**
273
-
274
- | Flag | Values | Default | Description |
275
- |------|--------|---------|-------------|
276
- | \`--ppo-expire\` | \`30m\` or \`8h\` | \`30m\` | Option duration |
277
- | \`--ppo-category\` | \`ATM\` or \`OTM\` | \`ATM\` | ATM = strike at market price; OTM = strike offset |
278
- | \`--ppo-tier\` | \`1-5\` | (required for OTM) | OTM offset: 1=0.1%, 2=0.2%, 3=0.3%, 4=0.4%, 5=0.5% |
279
-
280
- **Examples:**
281
-
282
- \`\`\`bash
283
- # ATM protection on existing order #99, 30 min (default)
284
- jv order protect --order-id 99 --symbol JBTC --network jaspervault
285
-
286
- # ATM protection, 8 hours
287
- jv order protect --order-id 99 --symbol JBTC --ppo-expire 8h --network jaspervault
288
-
289
- # OTM protection, tier 3
290
- jv order protect --order-id 99 --symbol JBTC --ppo-category OTM --ppo-tier 3 --network jaspervault
291
- \`\`\`
292
-
293
- **Typical flow:**
294
- 1. \`jv orders list --pretty\` → find the order ID
295
- 2. \`jv order protect --order-id <id> --symbol JBTC --network jaspervault\`
296
-
297
- ### Opening/Adding Position WITH Protection
298
-
299
- Add \`--ppo\` to \`jv order create\` when creating a new position or adding size with simultaneous protection:
300
-
301
- \`\`\`bash
302
- # New position with ATM protection
303
- jv order create --side long --symbol JBTC --margin 60 --leverage 50 --ppo --network jaspervault
304
-
305
- # New position with 8h ATM protection
306
- jv order create --side long --symbol JBTC --margin 60 --leverage 50 --ppo --ppo-expire 8h --network jaspervault
307
-
308
- # New position with OTM protection
309
- jv order create --side long --symbol JBTC --margin 60 --leverage 50 --ppo --ppo-category OTM --ppo-tier 5 --network jaspervault
310
- \`\`\`
311
-
312
- ### PPO Parameters (shared by both commands)
313
-
314
- | Flag | Values | Default | Description |
315
- |------|--------|---------|-------------|
316
- | \`--ppo-expire\` | \`30m\` or \`8h\` | \`30m\` | Option duration |
317
- | \`--ppo-category\` | \`ATM\` or \`OTM\` | \`ATM\` | ATM = strike at market price; OTM = strike offset |
318
- | \`--ppo-tier\` | \`1-5\` | (required for OTM) | OTM offset: 1=0.1%, 2=0.2%, 3=0.3%, 4=0.4%, 5=0.5% |
319
-
320
- **AI agent behavior when user wants OTM:**
321
-
322
- 1. First run \`jv price --symbol JBTC --pretty\` to get current price
323
- 2. Calculate strike for each tier based on position side:
324
- - LONG (PUT hedge): \`strike = price × (1 - tier_ratio)\`
325
- - SHORT (CALL hedge): \`strike = price × (1 + tier_ratio)\`
326
- 3. Present options: "Tier 1: $87,208 (0.1%), Tier 2: $87,121 (0.2%), ..., Tier 5: $86,860 (0.5%)"
327
- 4. User picks tier → use \`--ppo-tier N\`
328
-
329
- **Intent mapping:**
330
-
331
- - User says "加保护" / "开保护" / "对冲" / "hedge" / "protect" on an **existing position** → \`jv order protect --order-id <id>\`
332
- - User says "开仓 + 加保护" / "open with protection" → \`jv order create --ppo\`
333
- - User says "加仓 + 加保护" / "add size with protection" → \`jv order create --ppo\` (same side)
334
- - User says "8 hour" / "8小时" → \`--ppo-expire 8h\`
335
- - User says "OTM" / "价外" → \`--ppo-category OTM\`, then present tier options
336
- - User says "ATM" / "平价" or nothing → default ATM, 30 min
337
- - User says "取消PPO" / "cancel PPO" / "取消保护" / "关闭对冲" / "remove hedge" → perform a position operation WITHOUT \`--ppo\`; the existing hedge option is auto-cancelled by the contract
338
-
339
- ## PPO Cancellation (IMPORTANT — read before any reduce/close/add with PPO)
340
-
341
- The smart contract **automatically cancels** existing PPO hedge options when you execute any position operation (reduce, close, add size) **without** the \`--ppo\` flag. There is **NO separate "cancel PPO" command**.
342
-
343
- | User Request | Correct Action | Commands |
344
- |--------------|---------------|----------|
345
- | "减仓一半 + 取消PPO" | Single reduce order without \`--ppo\` | \`jv order create --side <opposite> --margin <half> --leverage 50 --network jaspervault\` |
346
- | "加仓 + 取消PPO" | Single add-size order without \`--ppo\` | \`jv order create --side <same> --margin <amount> --leverage 50 --network jaspervault\` |
347
- | "平仓" (full close) | Close order without \`--ppo\` | \`jv order create --side <opposite> --margin <full> --leverage 50 --network jaspervault\` |
348
- | "减仓一半 + 保留PPO" | Reduce order WITH \`--ppo\` | \`jv order create --side <opposite> --margin <half> --leverage 50 --ppo --network jaspervault\` |
349
-
350
- **NEVER do this:**
351
- - Do NOT try to cancel PPO as a separate step after reducing/closing a position. There is no "cancel PPO" command, and attempting workarounds (e.g. sending an extra opposite-side order) will cause unintended position closures.
352
- - Do NOT send two orders when one suffices. "减仓 + 取消PPO" = ONE order without \`--ppo\`.
353
- `;
354
- // ---------------------------------------------------------------------------
355
- // references/queries.md — positions, job status, limit orders, output, errors
356
- // ---------------------------------------------------------------------------
357
- const QUERIES_REFERENCE = `# Queries, Output Interpretation & Error Handling
358
-
359
- ## Querying Positions
360
-
361
- \`\`\`bash
362
- # List active positions (default — use for "current positions")
363
- jv orders list --pretty
364
-
365
- # Filter by side
366
- jv orders list --position-side LONG
367
-
368
- # Include closed/historical orders
369
- jv orders list --all --pretty
370
-
371
- # Filter by time range
372
- jv orders list --all --since 7d --pretty
373
- jv orders list --since 1w --pretty
374
- jv orders list --all --since 2025-01-01 --until 2025-01-31 --pretty
375
-
376
- # Get a specific position
377
- jv orders get <orderId>
378
-
379
- # Get overall statistics
380
- jv orders stats
381
- \`\`\`
382
-
383
- **Key output fields (human-readable, pre-converted from wei):**
384
-
385
- | Field | Description |
386
- |-------|-------------|
387
- | \`margin\` | Margin deposited in USDC (e.g. \`"60.000000"\`) |
388
- | \`size\` | Position size in underlying asset (e.g. \`"0.04386000"\` JBTC) |
389
- | \`entryPriceUsd\` | Entry price in USD (e.g. \`"68476.000000000000000000"\`) |
390
- | \`strikeAmountUsd\` | Strike amount in USD |
391
- | \`leverage\` | Leverage multiplier (e.g. \`"50"\`) |
392
- | \`createdTime\` | Creation time in ISO 8601 format |
393
- | \`positionSide\` | \`"LONG"\` or \`"SHORT"\` |
394
- | \`isActive\` | \`true\` = open position, \`false\` = closed |
395
- | \`id\` | Order ID (use for TP/SL commands) |
396
-
397
- To calculate notional from output: \`notional = margin × leverage\` (or \`size × current_price\`)
398
-
399
- **Pagination:** use \`--page\` and \`--limit\` (e.g. \`jv orders list --page 2 --limit 10\`).
400
-
401
- ## Calculating Unrealized PnL
402
-
403
- When the user asks about profit/loss, portfolio value, or position health, you MUST fetch the current price first:
404
-
405
- | Step | Formula |
406
- |------|---------|
407
- | 1. Get current price | \`jv price --symbol JBTC --pretty\` → read \`price\` field |
408
- | 2. Get position data | \`jv orders list --pretty\` → read \`size\`, \`entryPriceUsd\`, \`margin\`, \`positionSide\` |
409
- | 3. Compute PnL (LONG) | \`unrealizedPnL = size × (currentPrice − entryPrice)\` |
410
- | 3. Compute PnL (SHORT) | \`unrealizedPnL = size × (entryPrice − currentPrice)\` |
411
- | 4. PnL percentage | \`pnlPercent = unrealizedPnL / margin × 100%\` |
412
- | 5. Effective leverage | \`leveragedPnlPercent = priceChangePercent × leverage\` |
413
-
414
- Example: LONG 0.0428 JBTC, entry $70,000, current $71,000, margin 60 USDC
415
- - PnL = 0.0428 × (71000 − 70000) = +$42.80
416
- - PnL% = 42.80 / 60 = +71.3%
417
-
418
- IMPORTANT: NEVER guess or estimate the current price. ALWAYS use \`jv price\` to get the real-time price.
419
-
420
- ## Job Status
421
-
422
- \`\`\`bash
423
- jv job status <jobId> --pretty
424
- \`\`\`
425
-
426
- Key fields: \`status\` ("completed", "failed", "active", "waiting"), \`result.transactionHash\`, \`result.operationType\` (CREATE, ADD_SIZE, CLOSE_SIZE, etc.).
427
-
428
- ## Market Order Output (IMPORTANT — two JSON lines)
429
-
430
- \`jv order create\` for market orders prints **two JSON lines sequentially**:
431
-
432
- **Line 1 — Order submitted:**
433
- \`\`\`json
434
- {"success":true,"orderType":"market","jobId":"MARKET_ORDER_xxx","statusUrl":"/api/job/status/...","streamUrl":"/api/job/stream/..."}
435
- \`\`\`
436
-
437
- **Line 2 — Execution result (auto-waits up to 60s):**
438
- \`\`\`json
439
- {"jobId":"MARKET_ORDER_xxx","status":"completed","transactionHash":"0x..."}
440
- \`\`\`
441
-
442
- **CRITICAL RULES after order execution:**
443
-
444
- 1. If \`status === "completed"\` → the order IS executed. Do NOT retry or place another order.
445
- 2. If \`status === "failed"\` → report the error.
446
- 3. If \`status === "timeout"\` → use \`jv job status <jobId>\` to check later.
447
- 4. The \`operation\` field (if present) contains raw on-chain data in wei format — do NOT try to interpret it.
448
- 5. **To verify the actual position**, always run \`jv orders list --pretty\` and read the human-readable fields.
449
- 6. Report to the user: "Order executed successfully. Tx: {transactionHash}. Let me check your updated position..." then run \`jv orders list --pretty\`.
450
-
451
- **Limit order output:**
452
- \`\`\`json
453
- {"success":true,"orderType":"limit","limitOrderId":"0x..."}
454
- \`\`\`
455
- Tell the user: "Limit order placed. ID: {limitOrderId}."
456
-
457
- ## Managing Limit Orders
458
-
459
- \`\`\`bash
460
- # List limit orders for a wallet
461
- jv limit-order list --wallet <address>
462
-
463
- # Filter by status
464
- jv limit-order list --wallet <address> --status PENDING
465
-
466
- # Check a specific limit order
467
- jv limit-order status <limitOrderId>
468
-
469
- # Cancel a limit order
470
- jv limit-order cancel <limitOrderId>
471
- \`\`\`
472
-
473
- Possible statuses: PENDING, TRIGGERED, EXECUTING, COMPLETED, FAILED, EXPIRED, CANCELLED.
474
-
475
- ## Error Handling
476
-
477
- | Exit Code | Meaning | Action |
478
- |-----------|---------|--------|
479
- | 1 | Configuration error (e.g. delegation key not found) | Run \`jv vault setup\` first |
480
- | 2 | Network/HTTP error | Tell user the service may be unreachable |
481
- | 3 | Business error (duplicate order, invalid params) | Read stderr, relay message |
482
-
483
- When an error occurs, stderr contains the error message. Never expose raw stack traces or internal URLs to the user.
484
- `;
485
- // ---------------------------------------------------------------------------
486
- // scripts/check-init.sh
487
- // ---------------------------------------------------------------------------
488
- const CHECK_INIT_SCRIPT = `#!/usr/bin/env bash
489
- # Quick vault initialization check — exits 0 if ready, non-zero otherwise
490
- jv orders list --pretty 2>/dev/null
491
- exit $?
492
- `;
36
+ const CONTENT_DIR = join(__dirname, 'skill-content');
37
+ function readContent(relativePath) {
38
+ return readFileSync(join(CONTENT_DIR, relativePath), 'utf-8');
39
+ }
493
40
  // ---------------------------------------------------------------------------
494
41
  // Platform-specific frontmatter
495
42
  // ---------------------------------------------------------------------------
496
- function getOpenClawFrontmatter() {
497
- return `---
498
- name: jasper-vault-cli
499
- description: "Trade perpetual contracts (perps) on JasperVault — open/close positions, set TP/SL, manage limit orders, deposit, and query portfolio via the \`jv\` CLI. Initialize wallet via WalletConnect QR scan (no private key needed). 在 JasperVault 上交易永续合约 — 做多做空、开仓平仓、止盈止损、限价单、持仓查询、充值,使用 WalletConnect 扫码初始化(无需私钥)。"
500
- trigger: "jaspervault|jasper vault|jasper trading|jv|jv trade|jv order|在jasper交易|jasper 交易|初始化钱包|连接钱包|开仓|平仓|做多|做空|止盈|止损|查看持仓|永续合约"
501
- tools: [shell, process]
502
- metadata:
503
- openclaw:
504
- requires:
505
- bins:
506
- - jv
507
- ---
508
- `;
509
- }
510
- function getClaudeFrontmatter() {
511
- return `---
512
- name: jasper-vault-cli
513
- description: "Trade perpetual contracts (perps) on JasperVault — open/close positions, set TP/SL, manage limit orders, deposit, and query portfolio via the \`jv\` CLI. Initialize wallet via WalletConnect QR scan (no private key needed)."
514
- ---
515
- `;
43
+ function getFrontmatter(platform) {
44
+ switch (platform) {
45
+ case 'openclaw':
46
+ return readContent('frontmatter/openclaw.md');
47
+ case 'claude':
48
+ return readContent('frontmatter/claude.md');
49
+ case 'cursor':
50
+ return ''; // Cursor uses no frontmatter, just the heading
51
+ default:
52
+ throw new Error(`Unknown platform: ${platform}`);
53
+ }
516
54
  }
517
55
  // ---------------------------------------------------------------------------
518
56
  // Public API
@@ -523,26 +61,21 @@ description: "Trade perpetual contracts (perps) on JasperVault — open/close po
523
61
  * @param platform - One of: openclaw, cursor, claude
524
62
  */
525
63
  export function buildSkillContent(platform) {
64
+ const coreBody = readContent('SKILL.core.md').replace(/\{\{CLI_VERSION\}\}/g, CLI_VERSION);
65
+ const frontmatter = getFrontmatter(platform);
526
66
  let skillMd;
527
- switch (platform) {
528
- case 'openclaw':
529
- skillMd = getOpenClawFrontmatter() + '\n# JasperVault Trading Skill\n\n' + SKILL_CORE_BODY;
530
- break;
531
- case 'claude':
532
- skillMd = getClaudeFrontmatter() + '\n# JasperVault Trading Skill\n\n' + SKILL_CORE_BODY;
533
- break;
534
- case 'cursor':
535
- skillMd = '# jasper-vault-cli\n\n' + SKILL_CORE_BODY;
536
- break;
537
- default:
538
- throw new Error(`Unknown platform: ${platform}`);
67
+ if (platform === 'cursor') {
68
+ skillMd = '# jasper-vault-cli\n\n' + coreBody;
69
+ }
70
+ else {
71
+ skillMd = frontmatter + '\n' + coreBody;
539
72
  }
540
73
  return {
541
74
  'SKILL.md': skillMd,
542
- 'references/onboarding.md': ONBOARDING_REFERENCE,
543
- 'references/trading.md': TRADING_REFERENCE,
544
- 'references/queries.md': QUERIES_REFERENCE,
545
- 'scripts/check-init.sh': CHECK_INIT_SCRIPT,
75
+ 'references/onboarding.md': readContent('references/onboarding.md'),
76
+ 'references/trading.md': readContent('references/trading.md'),
77
+ 'references/queries.md': readContent('references/queries.md'),
78
+ 'scripts/check-init.sh': readContent('scripts/check-init.sh'),
546
79
  };
547
80
  }
548
81
  //# sourceMappingURL=skill-body.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"skill-body.js","sourceRoot":"","sources":["../../../src/templates/skill-body.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CACzC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,uBAAuB,CAAC,EAAE,OAAO,CAAC,CACzC,CAAC;AAEzB,sEAAsE;AACtE,MAAM,CAAC,MAAM,MAAM,GAAG;;;;;;;;;;;;;;wBAcE,WAAW;;CAElC,CAAC,IAAI,EAAE,CAAC;AAIT,8EAA8E;AAC9E,4EAA4E;AAC5E,8EAA8E;AAE9E,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6CvB,CAAC,IAAI,EAAE,CAAC;AAET,8EAA8E;AAC9E,+DAA+D;AAC/D,8EAA8E;AAE9E,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkE5B,CAAC;AAEF,8EAA8E;AAC9E,qEAAqE;AACrE,8EAA8E;AAE9E,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwMzB,CAAC;AAEF,8EAA8E;AAC9E,8EAA8E;AAC9E,8EAA8E;AAE9E,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+HzB,CAAC;AAEF,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAE9E,MAAM,iBAAiB,GAAG;;;;CAIzB,CAAC;AAEF,8EAA8E;AAC9E,gCAAgC;AAChC,8EAA8E;AAE9E,SAAS,sBAAsB;IAC7B,OAAO;;;;;;;;;;;CAWR,CAAC;AACF,CAAC;AAED,SAAS,oBAAoB;IAC3B,OAAO;;;;CAIR,CAAC;AACF,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,IAAI,OAAe,CAAC;IAEpB,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,UAAU;YACb,OAAO,GAAG,sBAAsB,EAAE,GAAG,mCAAmC,GAAG,eAAe,CAAC;YAC3F,MAAM;QACR,KAAK,QAAQ;YACX,OAAO,GAAG,oBAAoB,EAAE,GAAG,mCAAmC,GAAG,eAAe,CAAC;YACzF,MAAM;QACR,KAAK,QAAQ;YACX,OAAO,GAAG,wBAAwB,GAAG,eAAe,CAAC;YACrD,MAAM;QACR;YACE,MAAM,IAAI,KAAK,CAAC,qBAAqB,QAAQ,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,OAAO;QACL,UAAU,EAAE,OAAO;QACnB,0BAA0B,EAAE,oBAAoB;QAChD,uBAAuB,EAAE,iBAAiB;QAC1C,uBAAuB,EAAE,iBAAiB;QAC1C,uBAAuB,EAAE,iBAAiB;KAC3C,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"skill-body.js","sourceRoot":"","sources":["../../../src/templates/skill-body.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CACzC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,uBAAuB,CAAC,EAAE,OAAO,CAAC,CACzC,CAAC;AAEzB,sEAAsE;AACtE,MAAM,CAAC,MAAM,MAAM,GAAG;;;;;;;;;;;;;;wBAcE,WAAW;;CAElC,CAAC,IAAI,EAAE,CAAC;AAIT,8EAA8E;AAC9E,yEAAyE;AACzE,8EAA8E;AAE9E,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;AAErD,SAAS,WAAW,CAAC,YAAoB;IACvC,OAAO,YAAY,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,EAAE,OAAO,CAAC,CAAC;AAChE,CAAC;AAED,8EAA8E;AAC9E,gCAAgC;AAChC,8EAA8E;AAE9E,SAAS,cAAc,CAAC,QAAgB;IACtC,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,UAAU;YACb,OAAO,WAAW,CAAC,yBAAyB,CAAC,CAAC;QAChD,KAAK,QAAQ;YACX,OAAO,WAAW,CAAC,uBAAuB,CAAC,CAAC;QAC9C,KAAK,QAAQ;YACX,OAAO,EAAE,CAAC,CAAC,+CAA+C;QAC5D;YACE,MAAM,IAAI,KAAK,CAAC,qBAAqB,QAAQ,EAAE,CAAC,CAAC;IACrD,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,MAAM,QAAQ,GAAG,WAAW,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,sBAAsB,EAAE,WAAW,CAAC,CAAC;IAC3F,MAAM,WAAW,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IAE7C,IAAI,OAAe,CAAC;IACpB,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO,GAAG,wBAAwB,GAAG,QAAQ,CAAC;IAChD,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,WAAW,GAAG,IAAI,GAAG,QAAQ,CAAC;IAC1C,CAAC;IAED,OAAO;QACL,UAAU,EAAE,OAAO;QACnB,0BAA0B,EAAE,WAAW,CAAC,0BAA0B,CAAC;QACnE,uBAAuB,EAAE,WAAW,CAAC,uBAAuB,CAAC;QAC7D,uBAAuB,EAAE,WAAW,CAAC,uBAAuB,CAAC;QAC7D,uBAAuB,EAAE,WAAW,CAAC,uBAAuB,CAAC;KAC9D,CAAC;AACJ,CAAC"}
@@ -0,0 +1,51 @@
1
+ # JasperVault Trading Skill
2
+
3
+ Trade perpetual contracts on JasperVault via the `jv` CLI (v{{CLI_VERSION}}). No private key is ever required.
4
+
5
+ ## CRITICAL RULES (MUST FOLLOW — violations cause broken UX)
6
+
7
+ 1. **WalletConnect ONLY**: ALWAYS use `jv vault setup`. NEVER suggest `jv vault init` (private-key mode). NEVER ask the user to set `PRIVATE_KEY`.
8
+ 2. **QR Code Display**: When `jv vault setup` outputs JSON with a `qrCodeUrl` field, you MUST display the `qrCodeUrl` value as a clickable link to the user. This is the only QR code field in the output — there are no other QR representations.
9
+ 3. **Long-running Commands**: `jv vault setup` is a long-running command (up to 2 min) that will be auto-backgrounded. After it backgrounds you receive a `sessionId` and the first JSON output (QR code). Show the QR link to the user, then poll every 15 seconds with `process poll` using that `sessionId` until you see the second JSON line containing `"success":true` or the process exits. See [references/onboarding.md](references/onboarding.md) for the full step-by-step flow.
10
+ 4. **Real-time Prices**: NEVER guess or estimate prices. ALWAYS run `jv price --symbol JBTC --pretty` before any price-dependent operation (opening a position by asset quantity, calculating PnL).
11
+ 5. **PPO Auto-Cancellation**: When performing any position operation (reduce, close, add size) WITHOUT `--ppo`, the smart contract automatically cancels existing PPO hedge options. There is NO separate "cancel PPO" command. NEVER attempt a separate cancellation — it risks unintended position closures.
12
+ 6. **Standalone PPO Protection**: To add hedge protection to an **existing position**, use `jv order protect --order-id <id> --symbol <symbol>`. Do NOT use `jv order create --ppo` for this — that command ADDS POSITION SIZE. `jv order create --ppo` is ONLY for opening new positions or adding size with protection. See [references/trading.md](references/trading.md) for details.
13
+ 7. **Market Order Output**: `jv order create` (market) prints TWO JSON lines — first the submission, then the execution result (auto-waits up to 60s). If `status === "completed"`, the order IS executed. Do NOT retry or place another order. See [references/trading.md](references/trading.md).
14
+ 8. **Deposit via WalletConnect**: `jv deposit` auto-detects signing mode. Without `PRIVATE_KEY`, it uses WalletConnect (QR scan). Follow the same QR display rules as `jv vault setup`. See [references/onboarding.md](references/onboarding.md).
15
+
16
+ ## Activation Behavior
17
+
18
+ 1. Check if vault is initialized: `jv orders list --pretty`
19
+ 2. If the command fails (exit code 1, or errors like "delegation key not found" / "vault not initialized" / "no profile"):
20
+ - Tell the user: "Your vault is not initialized yet. Let me set it up via WalletConnect — no private key needed."
21
+ - Immediately run `jv vault setup --network jaspervault --timeout 120`.
22
+ - Follow the QR code display instructions in [references/onboarding.md](references/onboarding.md).
23
+ 3. If the command succeeds → vault is ready. Proceed with the user's request.
24
+
25
+ ## Intent → Command Reference
26
+
27
+ | User Intent | Command | Details |
28
+ |-------------|---------|---------|
29
+ | Initialize / connect wallet | `jv vault setup` | [references/onboarding.md](references/onboarding.md) |
30
+ | Deposit tokens from Base | `jv deposit --token <T> --amount <N>` | [references/onboarding.md](references/onboarding.md) |
31
+ | Get current price | `jv price --symbol JBTC --pretty` | [references/queries.md](references/queries.md) |
32
+ | Open position (market) | `jv order create --side long/short -m <usdc> --symbol JBTC` | [references/trading.md](references/trading.md) |
33
+ | Open position (limit) | `jv order create ... --limit-price <N>` | [references/trading.md](references/trading.md) |
34
+ | Reduce / close position | opposite-side `jv order create` | [references/trading.md](references/trading.md) |
35
+ | Add size to position | same-side `jv order create` | [references/trading.md](references/trading.md) |
36
+ | Set take-profit | `jv tp set --order-id <ID> --price <P> --symbol <S>` | [references/trading.md](references/trading.md) |
37
+ | Set stop-loss | `jv sl set --order-id <ID> --price <P> --symbol <S>` | [references/trading.md](references/trading.md) |
38
+ | Add PPO to existing position | `jv order protect --order-id <id> --symbol <S>` | [references/trading.md](references/trading.md) |
39
+ | Open/add-size with PPO | add `--ppo` to `jv order create` | [references/trading.md](references/trading.md) |
40
+ | Cancel PPO / remove hedge | order without `--ppo` (auto-cancels) | [references/trading.md](references/trading.md) |
41
+ | Query positions / portfolio | `jv orders list --pretty` | [references/queries.md](references/queries.md) |
42
+ | Get specific position | `jv orders get <orderId> --pretty` | [references/queries.md](references/queries.md) |
43
+ | Portfolio statistics | `jv orders stats --pretty` | [references/queries.md](references/queries.md) |
44
+ | Job execution status | `jv job status <jobId> --pretty` | [references/queries.md](references/queries.md) |
45
+ | Manage limit orders | `jv limit-order list/status/cancel` | [references/queries.md](references/queries.md) |
46
+
47
+ ## Security
48
+
49
+ - Never log or display private keys, signatures, or API keys.
50
+ - The CLI signs orders via the delegation wallet in `~/.jaspervault/keys.json`.
51
+ - Do NOT ask the user to set `PRIVATE_KEY`.
@@ -0,0 +1,4 @@
1
+ ---
2
+ name: jasper-vault-cli
3
+ description: "Trade perpetual contracts (perps) on JasperVault — open/close positions, set TP/SL, manage limit orders, deposit, and query portfolio via the `jv` CLI. Initialize wallet via WalletConnect QR scan (no private key needed)."
4
+ ---
@@ -0,0 +1,11 @@
1
+ ---
2
+ name: jasper-vault-cli
3
+ description: "Trade perpetual contracts (perps) on JasperVault — open/close positions, set TP/SL, manage limit orders, deposit, and query portfolio via the `jv` CLI. Initialize wallet via WalletConnect QR scan (no private key needed). 在 JasperVault 上交易永续合约 — 做多做空、开仓平仓、止盈止损、限价单、持仓查询、充值,使用 WalletConnect 扫码初始化(无需私钥)。"
4
+ trigger: "jaspervault|jasper vault|jasper trading|jv|jv trade|jv order|在jasper交易|jasper 交易|初始化钱包|连接钱包|开仓|平仓|做多|做空|止盈|止损|查看持仓|永续合约"
5
+ tools: [shell, process]
6
+ metadata:
7
+ openclaw:
8
+ requires:
9
+ bins:
10
+ - jv
11
+ ---