@wowok/agent-mcp 3.1.6 → 3.1.7
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/dist/harness/recover.js +1 -1
- package/dist/knowledge/tools-reference.js +1 -1
- package/dist/schema/call/base.d.ts +4 -0
- package/dist/schema/call/bridge.d.ts +1 -0
- package/dist/schema/call/error-codes.d.ts +1 -1
- package/dist/schema/call/error-codes.js +1 -1
- package/dist/schema/call/semantic.js +1 -1
- package/dist/schema/local/index.d.ts +8 -0
- package/dist/schema/local/wip.d.ts +73 -0
- package/dist/schema/local/wip.js +1 -1
- package/dist/schema/operations.d.ts +18 -0
- package/dist/schema/operations.js +1 -1
- package/dist/schema/query/index.d.ts +3 -3
- package/dist/schemas/account_operation.output.json +1 -0
- package/dist/schemas/bridge_operation.output.json +1 -0
- package/dist/schemas/index.json +1 -1
- package/dist/schemas/local_history_operation.output.json +1 -0
- package/dist/schemas/local_info_operation.output.json +1 -0
- package/dist/schemas/local_mark_operation.output.json +1 -0
- package/dist/schemas/onchain_operations.output.json +1 -0
- package/dist/schemas/wip_file.output.json +221 -0
- package/dist/schemas/wip_file.schema.json +125 -0
- package/dist/tools/handlers/wip-upload.d.ts +22 -0
- package/dist/tools/handlers/wip-upload.js +1 -0
- package/dist/tools/handlers/wip.js +1 -1
- package/dist/tools/registry/files.js +1 -1
- package/dist/tools/wip-deploy-assist.js +1 -1
- package/package.json +2 -2
|
@@ -119,6 +119,227 @@
|
|
|
119
119
|
"type"
|
|
120
120
|
],
|
|
121
121
|
"additionalProperties": false
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"type": "object",
|
|
125
|
+
"properties": {
|
|
126
|
+
"type": {
|
|
127
|
+
"type": "string",
|
|
128
|
+
"const": "upload"
|
|
129
|
+
},
|
|
130
|
+
"storage": {
|
|
131
|
+
"type": "string"
|
|
132
|
+
},
|
|
133
|
+
"base_url": {
|
|
134
|
+
"type": "string",
|
|
135
|
+
"description": "Storage service base URL"
|
|
136
|
+
},
|
|
137
|
+
"address": {
|
|
138
|
+
"description": "Signing account address",
|
|
139
|
+
"type": "string"
|
|
140
|
+
},
|
|
141
|
+
"hash": {
|
|
142
|
+
"description": "Stored file hash (meta.hash)",
|
|
143
|
+
"type": "string"
|
|
144
|
+
},
|
|
145
|
+
"url": {
|
|
146
|
+
"description": "Public download URL",
|
|
147
|
+
"type": "string"
|
|
148
|
+
},
|
|
149
|
+
"size": {
|
|
150
|
+
"type": "number"
|
|
151
|
+
},
|
|
152
|
+
"name": {
|
|
153
|
+
"type": "string"
|
|
154
|
+
},
|
|
155
|
+
"signed": {
|
|
156
|
+
"description": "Whether the WIP file carries embedded signatures",
|
|
157
|
+
"type": "boolean"
|
|
158
|
+
},
|
|
159
|
+
"deduplicated": {
|
|
160
|
+
"description": "True when the same account had already stored this hash",
|
|
161
|
+
"type": "boolean"
|
|
162
|
+
},
|
|
163
|
+
"error": {
|
|
164
|
+
"description": "Error code (e.g. QUOTA_EXCEEDED when the store account file limit is reached)",
|
|
165
|
+
"type": "string"
|
|
166
|
+
},
|
|
167
|
+
"message": {
|
|
168
|
+
"type": "string"
|
|
169
|
+
},
|
|
170
|
+
"count": {
|
|
171
|
+
"description": "Files currently stored by the account",
|
|
172
|
+
"type": "number"
|
|
173
|
+
},
|
|
174
|
+
"limit": {
|
|
175
|
+
"description": "Per-account file limit on the storage service",
|
|
176
|
+
"type": "number"
|
|
177
|
+
},
|
|
178
|
+
"files": {
|
|
179
|
+
"description": "Current stored files (provided on QUOTA_EXCEEDED for deletion)",
|
|
180
|
+
"type": "array",
|
|
181
|
+
"items": {
|
|
182
|
+
"type": "object",
|
|
183
|
+
"properties": {
|
|
184
|
+
"hash": {
|
|
185
|
+
"type": "string",
|
|
186
|
+
"description": "WIP file hash (meta.hash)"
|
|
187
|
+
},
|
|
188
|
+
"name": {
|
|
189
|
+
"description": "Optional display name",
|
|
190
|
+
"type": "string"
|
|
191
|
+
},
|
|
192
|
+
"size": {
|
|
193
|
+
"description": "File size in bytes",
|
|
194
|
+
"type": "number"
|
|
195
|
+
},
|
|
196
|
+
"created_at": {
|
|
197
|
+
"description": "Upload time (ms epoch)",
|
|
198
|
+
"type": "number"
|
|
199
|
+
},
|
|
200
|
+
"url": {
|
|
201
|
+
"description": "Public download URL",
|
|
202
|
+
"type": "string"
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
"required": [
|
|
206
|
+
"hash"
|
|
207
|
+
],
|
|
208
|
+
"additionalProperties": false,
|
|
209
|
+
"description": "A WIP file stored on a wip storage service"
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
"guidance": {
|
|
213
|
+
"description": "Actionable guidance (delete files or switch to self-hosted storage)",
|
|
214
|
+
"type": "string"
|
|
215
|
+
},
|
|
216
|
+
"network_advisory": {
|
|
217
|
+
"description": "Generic advisory for large, network-sensitive WIP files (size reduction, retry, reachability check)",
|
|
218
|
+
"type": "string"
|
|
219
|
+
},
|
|
220
|
+
"retention_notice": {
|
|
221
|
+
"description": "Free-store terms (storage='store' only): 6-month retention, best-effort/force-majeure disclaimer, no automatic deletion",
|
|
222
|
+
"type": "string"
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
"required": [
|
|
226
|
+
"type",
|
|
227
|
+
"storage",
|
|
228
|
+
"base_url"
|
|
229
|
+
],
|
|
230
|
+
"additionalProperties": false
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
"type": "object",
|
|
234
|
+
"properties": {
|
|
235
|
+
"type": {
|
|
236
|
+
"type": "string",
|
|
237
|
+
"const": "storage_list"
|
|
238
|
+
},
|
|
239
|
+
"storage": {
|
|
240
|
+
"type": "string"
|
|
241
|
+
},
|
|
242
|
+
"base_url": {
|
|
243
|
+
"type": "string"
|
|
244
|
+
},
|
|
245
|
+
"address": {
|
|
246
|
+
"type": "string"
|
|
247
|
+
},
|
|
248
|
+
"count": {
|
|
249
|
+
"type": "number"
|
|
250
|
+
},
|
|
251
|
+
"limit": {
|
|
252
|
+
"type": "number"
|
|
253
|
+
},
|
|
254
|
+
"files": {
|
|
255
|
+
"type": "array",
|
|
256
|
+
"items": {
|
|
257
|
+
"type": "object",
|
|
258
|
+
"properties": {
|
|
259
|
+
"hash": {
|
|
260
|
+
"type": "string",
|
|
261
|
+
"description": "WIP file hash (meta.hash)"
|
|
262
|
+
},
|
|
263
|
+
"name": {
|
|
264
|
+
"description": "Optional display name",
|
|
265
|
+
"type": "string"
|
|
266
|
+
},
|
|
267
|
+
"size": {
|
|
268
|
+
"description": "File size in bytes",
|
|
269
|
+
"type": "number"
|
|
270
|
+
},
|
|
271
|
+
"created_at": {
|
|
272
|
+
"description": "Upload time (ms epoch)",
|
|
273
|
+
"type": "number"
|
|
274
|
+
},
|
|
275
|
+
"url": {
|
|
276
|
+
"description": "Public download URL",
|
|
277
|
+
"type": "string"
|
|
278
|
+
}
|
|
279
|
+
},
|
|
280
|
+
"required": [
|
|
281
|
+
"hash"
|
|
282
|
+
],
|
|
283
|
+
"additionalProperties": false,
|
|
284
|
+
"description": "A WIP file stored on a wip storage service"
|
|
285
|
+
},
|
|
286
|
+
"description": "Stored WIP file list"
|
|
287
|
+
},
|
|
288
|
+
"error": {
|
|
289
|
+
"type": "string"
|
|
290
|
+
},
|
|
291
|
+
"message": {
|
|
292
|
+
"type": "string"
|
|
293
|
+
},
|
|
294
|
+
"retention_notice": {
|
|
295
|
+
"description": "Free-store terms (storage='store' only): 6-month retention, best-effort/force-majeure disclaimer, no automatic deletion",
|
|
296
|
+
"type": "string"
|
|
297
|
+
}
|
|
298
|
+
},
|
|
299
|
+
"required": [
|
|
300
|
+
"type",
|
|
301
|
+
"storage",
|
|
302
|
+
"base_url"
|
|
303
|
+
],
|
|
304
|
+
"additionalProperties": false
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
"type": "object",
|
|
308
|
+
"properties": {
|
|
309
|
+
"type": {
|
|
310
|
+
"type": "string",
|
|
311
|
+
"const": "storage_delete"
|
|
312
|
+
},
|
|
313
|
+
"storage": {
|
|
314
|
+
"type": "string"
|
|
315
|
+
},
|
|
316
|
+
"base_url": {
|
|
317
|
+
"type": "string"
|
|
318
|
+
},
|
|
319
|
+
"address": {
|
|
320
|
+
"type": "string"
|
|
321
|
+
},
|
|
322
|
+
"deleted": {
|
|
323
|
+
"description": "Hash of the deleted file",
|
|
324
|
+
"type": "string"
|
|
325
|
+
},
|
|
326
|
+
"remaining": {
|
|
327
|
+
"description": "Files remaining for the account after deletion",
|
|
328
|
+
"type": "number"
|
|
329
|
+
},
|
|
330
|
+
"error": {
|
|
331
|
+
"type": "string"
|
|
332
|
+
},
|
|
333
|
+
"message": {
|
|
334
|
+
"type": "string"
|
|
335
|
+
}
|
|
336
|
+
},
|
|
337
|
+
"required": [
|
|
338
|
+
"type",
|
|
339
|
+
"storage",
|
|
340
|
+
"base_url"
|
|
341
|
+
],
|
|
342
|
+
"additionalProperties": false
|
|
122
343
|
}
|
|
123
344
|
],
|
|
124
345
|
"description": "WIP operation output schema with discriminator"
|
|
@@ -169,6 +169,131 @@
|
|
|
169
169
|
],
|
|
170
170
|
"additionalProperties": false,
|
|
171
171
|
"description": "Convert WIP file to HTML format"
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"type": "object",
|
|
175
|
+
"properties": {
|
|
176
|
+
"type": {
|
|
177
|
+
"type": "string",
|
|
178
|
+
"const": "upload"
|
|
179
|
+
},
|
|
180
|
+
"wipFilePath": {
|
|
181
|
+
"type": "string",
|
|
182
|
+
"description": "WIP file to upload. Supports: 1) Local file path, 2) Network URL, 3) Data URL"
|
|
183
|
+
},
|
|
184
|
+
"account": {
|
|
185
|
+
"description": "Account used to sign the upload (name or address). If omitted, uses the default account",
|
|
186
|
+
"type": "string"
|
|
187
|
+
},
|
|
188
|
+
"storage": {
|
|
189
|
+
"description": "Storage backend: 'store' = official free wip.store.wowok.net (zero setup, max 10 files per account, files retained 6 months — free best-effort service, force majeure excepted, expired files are purged only by manual admin action, never automatically); 'custom' = your own or a third-party wip storage service via customBaseUrl (recommended: no store quota, full control). Default: 'store'",
|
|
190
|
+
"anyOf": [
|
|
191
|
+
{
|
|
192
|
+
"type": "string",
|
|
193
|
+
"const": "store",
|
|
194
|
+
"description": "Official free wip.store.wowok.net storage (zero setup, max 10 files per account, files retained 6 months). Declaration: free best-effort service — availability and data survival are not guaranteed (force majeure excepted); expired files are deleted ONLY by a manual administrator purge, never automatically"
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"type": "string",
|
|
198
|
+
"const": "custom",
|
|
199
|
+
"description": "Your own or a third-party wip storage service (recommended: no store quota, full control, permanent self-managed hosting)"
|
|
200
|
+
}
|
|
201
|
+
]
|
|
202
|
+
},
|
|
203
|
+
"customBaseUrl": {
|
|
204
|
+
"description": "Base URL of your own or a third-party wip storage deployment (required when storage='custom'), e.g. 'https://wip.example.com'",
|
|
205
|
+
"type": "string"
|
|
206
|
+
},
|
|
207
|
+
"name": {
|
|
208
|
+
"description": "Optional display name recorded with the stored file",
|
|
209
|
+
"type": "string"
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
"required": [
|
|
213
|
+
"type",
|
|
214
|
+
"wipFilePath"
|
|
215
|
+
],
|
|
216
|
+
"additionalProperties": false,
|
|
217
|
+
"description": "Upload a signed WIP file to a wip storage service. The upload request is signed with the account's Falcon512 key; the file is validated (format, size limits, content hash, signatures) and stored under its content hash with a public download URL. When the per-account file limit is reached, the error carries the account's stored file list for deletion. Large, image-heavy WIP files are network-sensitive: keep them small (compress images before generate) and retry on transient network failures. WIP files are off-chain and network-independent: the returned public URL works on both testnet and mainnet"
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
"type": "object",
|
|
221
|
+
"properties": {
|
|
222
|
+
"type": {
|
|
223
|
+
"type": "string",
|
|
224
|
+
"const": "storage_list"
|
|
225
|
+
},
|
|
226
|
+
"account": {
|
|
227
|
+
"description": "Account used to sign the request (name or address). If omitted, uses the default account",
|
|
228
|
+
"type": "string"
|
|
229
|
+
},
|
|
230
|
+
"storage": {
|
|
231
|
+
"description": "Storage backend (default 'store')",
|
|
232
|
+
"anyOf": [
|
|
233
|
+
{
|
|
234
|
+
"type": "string",
|
|
235
|
+
"const": "store",
|
|
236
|
+
"description": "Official free wip.store.wowok.net storage (zero setup, max 10 files per account, files retained 6 months). Declaration: free best-effort service — availability and data survival are not guaranteed (force majeure excepted); expired files are deleted ONLY by a manual administrator purge, never automatically"
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
"type": "string",
|
|
240
|
+
"const": "custom",
|
|
241
|
+
"description": "Your own or a third-party wip storage service (recommended: no store quota, full control, permanent self-managed hosting)"
|
|
242
|
+
}
|
|
243
|
+
]
|
|
244
|
+
},
|
|
245
|
+
"customBaseUrl": {
|
|
246
|
+
"description": "Base URL of your own or a third-party wip storage deployment (required when storage='custom')",
|
|
247
|
+
"type": "string"
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
"required": [
|
|
251
|
+
"type"
|
|
252
|
+
],
|
|
253
|
+
"additionalProperties": false,
|
|
254
|
+
"description": "List the WIP files an account currently stores on a wip storage service (signed request). Off-chain and network-independent: the account's stored files are identical on testnet and mainnet — no chain call is involved"
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
"type": "object",
|
|
258
|
+
"properties": {
|
|
259
|
+
"type": {
|
|
260
|
+
"type": "string",
|
|
261
|
+
"const": "storage_delete"
|
|
262
|
+
},
|
|
263
|
+
"hash": {
|
|
264
|
+
"type": "string",
|
|
265
|
+
"description": "Hash (meta.hash) of the WIP file to delete"
|
|
266
|
+
},
|
|
267
|
+
"account": {
|
|
268
|
+
"description": "Account used to sign the request (name or address). If omitted, uses the default account",
|
|
269
|
+
"type": "string"
|
|
270
|
+
},
|
|
271
|
+
"storage": {
|
|
272
|
+
"description": "Storage backend (default 'store')",
|
|
273
|
+
"anyOf": [
|
|
274
|
+
{
|
|
275
|
+
"type": "string",
|
|
276
|
+
"const": "store",
|
|
277
|
+
"description": "Official free wip.store.wowok.net storage (zero setup, max 10 files per account, files retained 6 months). Declaration: free best-effort service — availability and data survival are not guaranteed (force majeure excepted); expired files are deleted ONLY by a manual administrator purge, never automatically"
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
"type": "string",
|
|
281
|
+
"const": "custom",
|
|
282
|
+
"description": "Your own or a third-party wip storage service (recommended: no store quota, full control, permanent self-managed hosting)"
|
|
283
|
+
}
|
|
284
|
+
]
|
|
285
|
+
},
|
|
286
|
+
"customBaseUrl": {
|
|
287
|
+
"description": "Base URL of your own or a third-party wip storage deployment (required when storage='custom')",
|
|
288
|
+
"type": "string"
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
"required": [
|
|
292
|
+
"type",
|
|
293
|
+
"hash"
|
|
294
|
+
],
|
|
295
|
+
"additionalProperties": false,
|
|
296
|
+
"description": "Delete a stored WIP file from a wip storage service. Only files owned by the signing account can be deleted (signed request; off-chain, works identically on testnet and mainnet)"
|
|
172
297
|
}
|
|
173
298
|
]
|
|
174
299
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare const DEFAULT_WIP_STORE_URL: string;
|
|
2
|
+
export declare const FREE_STORE_RETENTION_DAYS = 180;
|
|
3
|
+
export declare const FREE_STORE_RETENTION_NOTICE: string;
|
|
4
|
+
export interface WipStorageTarget {
|
|
5
|
+
storage?: "store" | "custom";
|
|
6
|
+
customBaseUrl?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface WipUploadArgs extends WipStorageTarget {
|
|
9
|
+
wipFilePath: string;
|
|
10
|
+
account?: string;
|
|
11
|
+
name?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function wipStorageUpload(args: WipUploadArgs): Promise<Record<string, unknown>>;
|
|
14
|
+
export interface WipStorageListArgs extends WipStorageTarget {
|
|
15
|
+
account?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function wipStorageList(args: WipStorageListArgs): Promise<Record<string, unknown>>;
|
|
18
|
+
export interface WipStorageDeleteArgs extends WipStorageTarget {
|
|
19
|
+
hash: string;
|
|
20
|
+
account?: string;
|
|
21
|
+
}
|
|
22
|
+
export declare function wipStorageDelete(args: WipStorageDeleteArgs): Promise<Record<string, unknown>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createHash,randomBytes}from'node:crypto';import{readFileSync}from'node:fs';import{Account,verify_wip}from'@wowok/wowok';export const DEFAULT_WIP_STORE_URL=process['env']['WOWOK_WIP_STORE_URL']??'https://wip.store.wowok.net';const MAX_UPLOAD_BYTES=0xc*0x400*0x400,QUOTA_GUIDANCE='Delete\x20one\x20or\x20more\x20stored\x20files\x20with\x20wip_file\x20type=\x27storage_delete\x27\x20(the\x20\x27files\x27\x20list\x20above\x20provides\x20the\x20hashes),\x20then\x20retry\x20the\x20upload.\x20'+'Alternatively,\x20use\x20your\x20own\x20or\x20a\x20third-party\x20wip\x20storage\x20service\x20and\x20upload\x20with\x20storage=\x27custom\x27\x20(recommended:\x20no\x20store\x20quota\x20and\x20full\x20control\x20over\x20your\x20documents).',LARGE_FILE_ADVISORY_BYTES=0x2*0x400*0x400,NETWORK_ADVISORY='This\x20WIP\x20file\x20is\x20large\x20(multi-MB,\x20image-heavy)\x20and\x20therefore\x20sensitive\x20to\x20network\x20conditions:\x20'+'uploads\x20may\x20be\x20slow\x20or\x20fail\x20mid-transfer,\x20and\x20customers\x20fetch\x20the\x20file\x20again\x20when\x20placing\x20orders.\x20'+'Solutions:\x20keep\x20WIP\x20files\x20small\x20(compress\x20images\x20before\x20generate;\x20each\x20image\x20<=\x202MB,\x20total\x20<=\x2010MB),\x20'+'retry\x20the\x20upload\x20on\x20transient\x20network\x20failures,\x20and\x20confirm\x20the\x20returned\x20public\x20URL\x20is\x20reachable\x20'+'afterwards\x20(wip_file\x20type=\x27verify\x27\x20with\x20the\x20URL).';export const FREE_STORE_RETENTION_DAYS=0xb4;export const FREE_STORE_RETENTION_NOTICE='Official\x20free\x20store\x20(wip.store.wowok.net):\x20files\x20are\x20retained\x20for\x20at\x20least\x206\x20months\x20(180\x20days)\x20from\x20upload.\x20'+'This\x20is\x20a\x20free,\x20best-effort\x20service\x20provided\x20as-is\x20—\x20availability\x20and\x20data\x20survival\x20are\x20not\x20guaranteed\x20(force\x20majeure\x20excepted).\x20'+'Expired\x20files\x20are\x20NEVER\x20deleted\x20automatically;\x20deletion\x20past\x20the\x20retention\x20window\x20is\x20a\x20manual\x20administrator\x20action\x20on\x20the\x20storage\x20service.\x20'+'For\x20permanent,\x20self-controlled\x20hosting\x20use\x20storage=\x27custom\x27\x20(recommended).';function resolveBaseUrl(a){const b=a['storage']==='custom'?'custom':'store';if(b==='custom'){if(!a['customBaseUrl'])throw new Error('storage=\x27custom\x27\x20requires\x20\x27customBaseUrl\x27\x20—\x20the\x20base\x20URL\x20of\x20your\x20own\x20or\x20a\x20third-party\x20wip\x20storage\x20service\x20deployment');return{'baseUrl':a['customBaseUrl']['replace'](/\/+$/,''),'storage':b};}return{'baseUrl':DEFAULT_WIP_STORE_URL['replace'](/\/+$/,''),'storage':b};}function sha256Hex(a){return createHash('sha256')['update'](a)['digest']('hex');}async function loadWipBytes(a){if(a['startsWith']('data:')){const b=a['match'](/^data:[^;,]*(?:;charset=[\w-]+)?;base64,(.+)$/);if(!b)throw new Error('Unsupported\x20data\x20URL\x20format\x20for\x20WIP\x20file\x20(expected\x20base64\x20data\x20URL)');return Buffer['from'](b[0x1],'base64');}if(/^https?:\/\//i['test'](a)){const c=await fetch(a);if(!c['ok'])throw new Error('Failed\x20to\x20fetch\x20WIP\x20file\x20from\x20'+a+':\x20'+c['status']+'\x20'+c['statusText']);const d=Buffer['from'](await c['arrayBuffer']());if(d['length']>MAX_UPLOAD_BYTES)throw new Error('WIP\x20file\x20at\x20'+a+'\x20exceeds\x20the\x20'+MAX_UPLOAD_BYTES+'\x20byte\x20transport\x20limit');return d;}return readFileSync(a);}async function signedHeaders(a,b,c){const d=Date['now'](),e=randomBytes(0x10)['toString']('hex'),f=c?'wip:'+b+':'+d+':'+e+':'+c:'wip:'+b+':'+d+':'+e,g=await Account['Instance']()['signData'](a??null,f);return{'address':g['address'],'headers':{'x-wip-timestamp':String(d),'x-wip-nonce':e,'x-wip-public-key':g['publicKey'],'x-wip-signature':g['signature'],'x-wip-address':g['address']}};}async function storagePost(a,b,c,d,e){let f;try{f=await fetch(a+b,{'method':'POST','headers':e?{...c,'content-type':e}:c,'body':d===null?undefined:typeof d==='string'?d:new Uint8Array(d)});}catch(h){throw new Error('WIP\x20storage\x20request\x20to\x20'+a+b+'\x20failed:\x20network\x20error\x20('+(h instanceof Error?h['message']:String(h))+').\x20'+'Large\x20WIP\x20files\x20are\x20sensitive\x20to\x20network\x20conditions\x20—\x20retry\x20the\x20request;\x20if\x20it\x20keeps\x20failing,\x20'+'check\x20connectivity\x20or\x20reduce\x20the\x20file\x20size\x20(compress\x20images\x20before\x20generate).');}let g=null;try{g=await f['json']();}catch{g=null;}return{'status':f['status'],'json':g};}function serverError(a,b,c){const d=c?.['message']??c?.['error']??'unknown\x20error';throw new Error('WIP\x20storage\x20'+a+'\x20failed\x20('+b+'):\x20'+d);}export async function wipStorageUpload(a){const {baseUrl:b,storage:c}=resolveBaseUrl(a),d=await verify_wip(a['wipFilePath'],undefined,undefined);if(!d['valid'])throw new Error('WIP\x20file\x20failed\x20verification\x20and\x20was\x20not\x20uploaded:\x20'+d['error']);const e=await loadWipBytes(a['wipFilePath']);if(e['length']>MAX_UPLOAD_BYTES)throw new Error('WIP\x20file\x20exceeds\x20the\x20'+MAX_UPLOAD_BYTES+'\x20byte\x20transport\x20limit');const {address:f,headers:g}=await signedHeaders(a['account'],'upload',sha256Hex(e)),h={};if(a['name'])h['x-wip-name']=encodeURIComponent(a['name']);const {status:i,json:j}=await storagePost(b,'/api/upload',{...g,...h},e,'application/octet-stream');if(i===0x199&&j?.['error']==='QUOTA_EXCEEDED')return{'type':'upload','storage':c,'base_url':b,'address':f,'error':'QUOTA_EXCEEDED','message':j['message']??'Storage\x20quota\x20exceeded','count':j['count'],'limit':j['limit'],'files':j['files']??[],'guidance':QUOTA_GUIDANCE};i!==0xc8&&i!==0xc9&&serverError('upload',i,j);const k={'type':'upload','storage':c,'base_url':b,'address':f,'hash':j['hash'],'url':j['url'],'size':j['size'],'name':j['name']??a['name'],'signed':j['signed'],'deduplicated':j['deduplicated']===!![]};return e['length']>LARGE_FILE_ADVISORY_BYTES&&(k['network_advisory']=NETWORK_ADVISORY),c==='store'&&(k['retention_notice']=FREE_STORE_RETENTION_NOTICE),k;}export async function wipStorageList(a){const {baseUrl:b,storage:c}=resolveBaseUrl(a),{address:d,headers:e}=await signedHeaders(a['account'],'list',null),{status:f,json:g}=await storagePost(b,'/api/list',e,null);if(f!==0xc8)serverError('list',f,g);const h={'type':'storage_list','storage':c,'base_url':b,'address':g['address']??d,'count':g['count'],'limit':g['limit'],'files':g['files']??[]};return c==='store'&&(h['retention_notice']=FREE_STORE_RETENTION_NOTICE),h;}export async function wipStorageDelete(a){const {baseUrl:b,storage:c}=resolveBaseUrl(a),d=a['hash']['toLowerCase']()['replace'](/^sha256:/,'');if(!/^[0-9a-f]{64}$/['test'](d))throw new Error('Invalid\x20hash\x20\x27'+a['hash']+'\x27\x20—\x20expected\x20a\x2064-character\x20hex\x20sha256\x20digest\x20(meta.hash)');const {address:e,headers:f}=await signedHeaders(a['account'],'delete',d),{status:g,json:h}=await storagePost(b,'/api/delete',f,JSON['stringify']({'hash':d}),'application/json');if(g!==0xc8)serverError('delete',g,h);return{'type':'storage_delete','storage':c,'base_url':b,'address':h['address']??e,'deleted':h['deleted']??d,'remaining':h['remaining']};}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{strictParse,WipOperationsSchema}from'../../schema/index.js';import{generate_wip,verify_wip,sign_wip,wip2html}from'@wowok/wowok';import{analyzeWipDeployment,formatDeployHints}from'../wip-deploy-assist.js';export async function handleWipOperations(a){if(typeof a==='object'&&a!==null&&a['type']==='deploy_assist'){const d=a['wipFilePath'];if(typeof d!=='string')return{'content':[{'type':'text','text':'Error:\x20\x27wipFilePath\x27\x20is\x20required\x20for\x20deploy_assist\x20action'}],'structuredContent':{'result':{'type':'error','error':'\x27wipFilePath\x27\x20is\x20required\x20for\x20deploy_assist\x20action'}}};const e=analyzeWipDeployment(d),f=formatDeployHints(e);return{'content':[{'type':'text','text':f||'No\x20deployment\x20needed.'}],'structuredContent':{'result':{'type':'deploy_assist',...e}}};}const b=strictParse(WipOperationsSchema,a,'wip_file\x20input');let c;switch(b['type']){case'generate':{const g=await generate_wip(b['options'],b['outputPath']);c={'result':{'type':'generate','filePath':g}};break;}case'verify':{const h=analyzeWipDeployment(b['wipFilePath']),i=await verify_wip(b['wipFilePath'],b['hash_equal'],b['requireSignature']),j=h['needs_deployment']||!i['valid']&&h['classification']['type']!=='data_url';if(j){const k=formatDeployHints(h);c={'result':{'type':'verify',...i,'deployment_assistance':h},'deployment_hints':k};}else c={'result':{'type':'verify',...i}};break;}case'sign':{const l=await sign_wip(b['wipFilePath'],b['account'],b['outputPath']);c={'result':{'type':'sign','filePath':l}};break;}case'wip2html':{const m=await wip2html(b['wipPath'],b['options']),n={'type':'wip2html'};Array['isArray'](m)?n['files']=m:n['filePath']=m;c={'result':n};break;}default:throw new Error('Unknown\x20WIP\x20operation\x20type');}return{'content':[{'type':'text','text':JSON['stringify'](c)}],'structuredContent':c};}
|
|
1
|
+
import{strictParse,WipOperationsSchema}from'../../schema/index.js';import{generate_wip,verify_wip,sign_wip,wip2html}from'@wowok/wowok';import{analyzeWipDeployment,formatDeployHints}from'../wip-deploy-assist.js';import{wipStorageUpload,wipStorageList,wipStorageDelete}from'./wip-upload.js';export async function handleWipOperations(a){if(typeof a==='object'&&a!==null&&a['type']==='deploy_assist'){const d=a['wipFilePath'];if(typeof d!=='string')return{'content':[{'type':'text','text':'Error:\x20\x27wipFilePath\x27\x20is\x20required\x20for\x20deploy_assist\x20action'}],'structuredContent':{'result':{'type':'error','error':'\x27wipFilePath\x27\x20is\x20required\x20for\x20deploy_assist\x20action'}}};const e=analyzeWipDeployment(d),f=formatDeployHints(e);return{'content':[{'type':'text','text':f||'No\x20deployment\x20needed.'}],'structuredContent':{'result':{'type':'deploy_assist',...e}}};}const b=strictParse(WipOperationsSchema,a,'wip_file\x20input');let c;switch(b['type']){case'generate':{const g=await generate_wip(b['options'],b['outputPath']);c={'result':{'type':'generate','filePath':g}};break;}case'verify':{const h=analyzeWipDeployment(b['wipFilePath']),i=await verify_wip(b['wipFilePath'],b['hash_equal'],b['requireSignature']),j=h['needs_deployment']||!i['valid']&&h['classification']['type']!=='data_url';if(j){const k=formatDeployHints(h);c={'result':{'type':'verify',...i,'deployment_assistance':h},'deployment_hints':k};}else c={'result':{'type':'verify',...i}};break;}case'sign':{const l=await sign_wip(b['wipFilePath'],b['account'],b['outputPath']);c={'result':{'type':'sign','filePath':l}};break;}case'wip2html':{const m=await wip2html(b['wipPath'],b['options']),n={'type':'wip2html'};Array['isArray'](m)?n['files']=m:n['filePath']=m;c={'result':n};break;}case'upload':{c={'result':await wipStorageUpload(b)};break;}case'storage_list':{c={'result':await wipStorageList(b)};break;}case'storage_delete':{c={'result':await wipStorageDelete(b)};break;}default:throw new Error('Unknown\x20WIP\x20operation\x20type');}return{'content':[{'type':'text','text':JSON['stringify'](c)}],'structuredContent':c};}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{z}from'zod';import{handleWipOperations}from'../handlers/wip.js';import{handleGuard2File,handleMachineNode2File}from'../handlers/file-export.js';import{strictStatusErrorShape}from'../wrap.js';import{createToolMeta,WipOperationsSchema,WipOperationOutputSchema,Guard2File_InputSchema,Guard2File_OutputWrappedSchema,MachineNode2File_InputSchema,MachineNode2File_OutputWrappedSchema}from'../../schema/index.js';export const FILE_TOOLS=[{'name':'wip_file','handler':handleWipOperations,'config':{'title':'🤝\x20Witness\x20Immutable\x20Promise\x20File\x20Operations','summary':'WIP\x20promise\x20file\x20operations:\x20generate,\x20verify,\x20sign,\x20wip2html.','description':'generate\x20(create\x20WIP\x20files\x20from\x20markdown\x20and\x20images),\x20verify\x20(integrity\x20check),\x20sign\x20(add\x20signatures),\
|
|
1
|
+
import{z}from'zod';import{handleWipOperations}from'../handlers/wip.js';import{handleGuard2File,handleMachineNode2File}from'../handlers/file-export.js';import{strictStatusErrorShape}from'../wrap.js';import{createToolMeta,WipOperationsSchema,WipOperationOutputSchema,Guard2File_InputSchema,Guard2File_OutputWrappedSchema,MachineNode2File_InputSchema,MachineNode2File_OutputWrappedSchema}from'../../schema/index.js';export const FILE_TOOLS=[{'name':'wip_file','handler':handleWipOperations,'config':{'title':'🤝\x20Witness\x20Immutable\x20Promise\x20File\x20Operations','summary':'WIP\x20promise\x20file\x20operations:\x20generate,\x20verify,\x20sign,\x20wip2html,\x20upload/list/delete\x20on\x20wip\x20storage.','description':'generate\x20(create\x20WIP\x20files\x20from\x20markdown\x20and\x20images),\x20verify\x20(integrity\x20check),\x20sign\x20(add\x20signatures),\x20wip2html\x20(convert\x20to\x20HTML),\x20or\x20storage\x20operations:\x20upload\x20/\x20storage_list\x20/\x20storage_delete.\x0a\x0aStorage\x20options\x20for\x20type=\x27upload\x27:\x0a\x20\x20•\x20storage=\x27store\x27\x20(default):\x20official\x20FREE\x20store\x20wip.store.wowok.net\x20—\x20zero\x20setup,\x20files\x20get\x20a\x20public\x20hash-addressed\x20URL\x20(https://wip.store.wowok.net/f/{hash}).\x20Free\x20tier\x20limited\x20to\x2010\x20files\x20per\x20account;\x20when\x20the\x20quota\x20is\x20hit\x20the\x20error\x20returns\x20the\x20stored\x20file\x20list\x20for\x20deletion\x20(use\x20storage_delete).\x20Declaration:\x20files\x20are\x20retained\x20for\x206\x20months\x20(180\x20days);\x20free\x20best-effort\x20service\x20—\x20availability\x20and\x20data\x20survival\x20are\x20not\x20guaranteed\x20(force\x20majeure\x20excepted);\x20expired\x20files\x20are\x20NEVER\x20deleted\x20automatically\x20(manual\x20administrator\x20purge\x20only).\x0a\x20\x20•\x20storage=\x27custom\x27\x20(recommended):\x20your\x20own\x20or\x20any\x20third-party\x20wip-storage-compatible\x20service\x20via\x20customBaseUrl\x20—\x20no\x20store\x20quota,\x20full\x20control,\x20permanent\x20self-managed\x20hosting.\x0a\x0a🌐\x20Network\x20independence:\x20WIP\x20files\x20are\x20OFF-CHAIN\x20—\x20the\x20same\x20public\x20URL\x20and\x20the\x20same\x20stored\x20files\x20work\x20on\x20BOTH\x20testnet\x20and\x20mainnet;\x20storage_list/storage_delete\x20authenticate\x20with\x20the\x20account\x20key\x20and\x20never\x20touch\x20the\x20chain.\x0a\x0a⚠️\x20Large\x20WIP\x20files\x20(multi-MB,\x20image-heavy)\x20are\x20sensitive\x20to\x20network\x20conditions:\x20keep\x20files\x20small\x20(compress\x20images\x20before\x20generate;\x20each\x20image\x20≤\x202MB,\x20total\x20≤\x2010MB),\x20expect\x20longer\x20upload\x20times,\x20retry\x20on\x20transient\x20network\x20failures,\x20and\x20confirm\x20reachability\x20afterwards\x20with\x20type=\x27verify\x27\x20on\x20the\x20returned\x20public\x20URL.\x0a\x0a⚠️\x20IMPORTANT\x20—\x20On-chain\x20WIP\x20URL\x20requirement:\x20When\x20using\x20a\x20WIP\x20file\x20URL\x20in\x20`service.sales[].wip`\x20(stored\x20on-chain),\x20the\x20URL\x20MUST\x20be\x20publicly\x20reachable.\x20Local\x20file\x20paths\x20(e.g.,\x20\x27C:\x5c\x5cpath\x5c\x5cfile.wip\x27\x20or\x20\x27/home/user/file.wip\x27)\x20are\x20NOT\x20acceptable\x20on-chain\x20—\x20they\x20only\x20work\x20locally\x20and\x20will\x20fail\x20verification\x20for\x20buyers.\x0a\x0aDeployment\x20options\x20for\x20the\x20.wip\x20file:\x0a\x20\x20•\x20wip\x20storage\x20service\x20(type=\x27upload\x27)\x20—\x20preferred,\x20gives\x20a\x20stable\x20public\x20URL\x0a\x20\x20•\x20GitHub\x20Pages:\x20https://raw.githubusercontent.com/<user>/<repo>/<branch>/<file>.wip\x0a\x20\x20•\x20IPFS:\x20https://ipfs.io/ipfs/<CID>\x20or\x20https://cloudflare-ipfs.com/ipfs/<CID>\x20(upload\x20via\x20pinata.cloud)\x0a\x20\x20•\x20User\x27s\x20own\x20static\x20website\x20URL\x0a\x0aUse\x20type=\x27generate\x27\x20to\x20create\x20the\x20WIP\x20file,\x20sign\x20it\x20with\x20type=\x27sign\x27,\x20upload\x20with\x20type=\x27upload\x27,\x20then\x20use\x20the\x20resulting\x20URL\x20in\x20service.sales[].wip.\x0a\x0a💡\x20Schema\x20hint:\x20Use\x20schema_query\x20with\x20action=\x27get\x27\x20and\x20name=\x27wip_file\x27\x20to\x20retrieve\x20the\x20exact\x20parameter\x20schema\x20before\x20calling.','inputSchema':WipOperationsSchema,'outputSchema':z['object']({'result':WipOperationOutputSchema}),'annotations':{'readOnlyHint':![],'destructiveHint':![],'idempotentHint':![],'openWorldHint':!![]},'_meta':createToolMeta('operation',['wip','promise','file-generation','verification','signature','upload','storage','wip.store.wowok.net'])}},{'name':'guard2file','handler':handleGuard2File,'config':{'title':'📄\x20Guard\x20to\x20File\x20-\x20Export\x20Guard\x20Definition','summary':'Export\x20guard\x20rules\x20to\x20a\x20local\x20JSON/Markdown\x20file.','description':'Export\x20a\x20Guard\x20object\x27s\x20definition\x20from\x20the\x20blockchain\x20to\x20a\x20local\x20JSON\x20or\x20Markdown\x20file\x20for\x20editing\x20and\x20creating\x20new\x20Guard\x20objects.\x20Note:\x20To\x20query\x20on-chain\x20object\x20information,\x20use\x20the\x20\x27query_toolkit\x27\x20tool\x20instead.\x0a\x0a💡\x20Schema\x20hint:\x20Use\x20schema_query\x20with\x20action=\x27get\x27\x20and\x20name=\x27guard2file\x27\x20to\x20retrieve\x20the\x20exact\x20parameter\x20schema\x20before\x20calling.','inputSchema':Guard2File_InputSchema,'outputSchema':Guard2File_OutputWrappedSchema,'annotations':{'readOnlyHint':!![],'destructiveHint':![],'idempotentHint':!![],'openWorldHint':!![]},'_meta':createToolMeta('generate\x20file',['guard','export','file','json','markdown','on-chain'])},'errorShapeBuilder':strictStatusErrorShape},{'name':'machineNode2file','handler':handleMachineNode2File,'config':{'title':'⚙️\x20Machine\x20Node\x20to\x20File\x20-\x20Export\x20Machine\x20Node\x20Definition','summary':'Export\x20machine\x20nodes\x20to\x20a\x20local\x20JSON/Markdown\x20file.','description':'Export\x20a\x20Machine\x20object\x27s\x20node\x20definition\x20from\x20the\x20blockchain\x20to\x20a\x20local\x20JSON\x20or\x20Markdown\x20file\x20for\x20editing\x20and\x20creating\x20new\x20Machine\x20objects.\x20Note:\x20To\x20query\x20on-chain\x20object\x20information,\x20use\x20the\x20\x27query_toolkit\x27\x20tool\x20instead.\x0a\x0a💡\x20Schema\x20hint:\x20Use\x20schema_query\x20with\x20action=\x27get\x27\x20and\x20name=\x27machineNode2file\x27\x20to\x20retrieve\x20the\x20exact\x20parameter\x20schema\x20before\x20calling.','inputSchema':MachineNode2File_InputSchema,'outputSchema':MachineNode2File_OutputWrappedSchema,'annotations':{'readOnlyHint':!![],'destructiveHint':![],'idempotentHint':!![],'openWorldHint':!![]},'_meta':createToolMeta('generate\x20file',['machine','export','file','json','markdown','on-chain','workflow'])},'errorShapeBuilder':strictStatusErrorShape}];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export function classifyWipPath(a){if(!a||typeof a!=='string')return{'type':'unknown','is_local':![],'is_network':![],'description':'Empty\x20or\x20invalid\x20path'};if(a['startsWith']('data:'))return{'type':'data_url','is_local':![],'is_network':!![],'description':'Data\x20URL\x20—\x20embedded\x20content,\x20globally\x20reachable'};if(a['startsWith']('ipfs://'))return{'type':'ipfs','is_local':![],'is_network':!![],'description':'IPFS\x20URI\x20—\x20resolve\x20via\x20any\x20public\x20gateway'};const b=[/^https?:\/\/ipfs\.io\//i,/^https?:\/\/cloudflare-ipfs\.com\//i,/^https?:\/\/gateway\.pinata\.cloud\//i,/^https?:\/\/dweb\.link\//i,/^https?:\/\/[^/]*pinata\.cloud\//i];if(b['some'](d=>d['test'](a)))return{'type':'ipfs','is_local':![],'is_network':!![],'description':'IPFS\x20HTTP\x20gateway\x20URL\x20—\x20globally\x20reachable'};if(/^https?:\/\/(localhost|127\.0\.0\.1|\[::1\]|0\.0\.0\.0)([:/]|$)/i['test'](a))return{'type':'local_http','is_local':!![],'is_network':![],'description':'Local\x20HTTP\x20URL\x20(localhost/loopback)\x20—\x20reachable\x20only\x20on\x20this\x20machine,\x20NOT\x20by\x20customers'};const c=/^https?:\/\/(10\.\d{1,3}\.\d{1,3}\.\d{1,3}|172\.(1[6-9]|2\d|3[01])\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3})([:/]|$)/i;if(c['test'](a))return{'type':'local_http','is_local':!![],'is_network':![],'description':'LAN\x20HTTP\x20URL\x20(private\x20IP)\x20—\x20reachable\x20only\x20on\x20the\x20local\x20network,\x20NOT\x20by\x20customers'};if(/^https?:\/\//i['test'](a))return{'type':'http_url','is_local':![],'is_network':!![],'description':'HTTP(S)\x20URL\x20—\x20globally\x20reachable\x20if\x20server\x20returns\x20200'};if(/^[A-Za-z]:[\\/]/['test'](a))return{'type':'local_windows','is_local':!![],'is_network':![],'description':'Windows\x20local\x20path\x20—\x20NOT\x20reachable\x20by\x20customers/AI'};if(a['startsWith']('/'))return{'type':'local_unix','is_local':!![],'is_network':![],'description':'Unix\x20local\x20path\x20—\x20NOT\x20reachable\x20by\x20customers/AI'};if(a['startsWith']('./')||a['startsWith']('../')||a==='.'||a==='..')return{'type':'local_relative','is_local':!![],'is_network':![],'description':'Relative\x20local\x20path\x20—\x20NOT\x20reachable\x20by\x20customers/AI'};if(!a['includes']('://')&&!a['startsWith']('data:'))return{'type':'local_relative','is_local':!![],'is_network':![],'description':'Local\x20file\x20path\x20(no\x20scheme)\x20—\x20NOT\x20reachable\x20by\x20customers/AI'};return{'type':'unknown','is_local':![],'is_network':![],'description':'Unrecognized\x20path\x20format'};}export function getDeployOptions(a){const b=a['replace'](/'/g,'\x27\x5c\x27\x27'),c=a['split'](/[\\/]/)['pop']()||'file.wip';return[{'name':'GitHub\x20Pages\x20(Recommended)','description':'Upload\x20the\x20.wip\x20file\x20to\x20a\x20GitHub\x20repository\x20and\x20serve\x20it\x20via\x20GitHub\x20Pages.\x20'+'Free,\x20stable,\x20HTTPS-enabled,\x20no\x20expiration.','difficulty':'easy','free':!![],'result_url_pattern':'https://<your-username>.github.io/<repo>/<file>.wip','steps':['//\x201.\x20Create\x20a\x20new\x20GitHub\x20repository\x20(e.g.,\x20\x27wowok-wip\x27)\x20via\x20https://github.com/new','//\x202.\x20Make\x20it\x20PUBLIC\x20so\x20the\x20file\x20is\x20world-readable.','//\x203.\x20Copy\x20your\x20local\x20WIP\x20file\x20into\x20the\x20repo:','git\x20clone\x20https://github.com/<your-username>/wowok-wip.git','cp\x20\x27'+b+'\x27\x20wowok-wip/'+c,'cd\x20wowok-wip','git\x20add\x20'+c,'git\x20commit\x20-m\x20\x22Add\x20WIP\x20file\x22','git\x20push\x20origin\x20main','//\x204.\x20Enable\x20GitHub\x20Pages:\x20repo\x20→\x20Settings\x20→\x20Pages\x20→\x20Source\x20→\x20\x27main\x27\x20branch\x20→\x20/(root)\x20→\x20Save','//\x205.\x20Wait\x2030-60\x20seconds\x20for\x20deployment,\x20then\x20verify\x20the\x20URL\x20is\x20reachable:','curl\x20-I\x20https://<your-username>.github.io/wowok-wip/'+c,'//\x206.\x20Update\x20your\x20Service\x20on-chain\x20with\x20the\x20new\x20public\x20URL:','//\x20\x20\x20\x20Call\x20onchain_operations\x20{\x20operation_type:\x20\x27service\x27,\x20data:\x20{\x20object:\x20\x27<service-id>\x27,\x20sales:\x20{\x20op:\x20\x27set\x27,\x20sales:\x20[{\x20...,\x20wip_url:\x20\x27https://...\x27,\x20wip_hash:\x20\x27<hash>\x27\x20}]\x20}\x20}\x20}'],'notes':['If\x20the\x20repo\x20already\x20has\x20Pages\x20enabled\x20on\x20the\x20main\x20branch,\x20step\x204\x20can\x20be\x20skipped.','GitHub\x20Pages\x20serves\x20files\x20up\x20to\x2025\x20MB\x20—\x20well\x20above\x20typical\x20WIP\x20sizes\x20(<\x201\x20MB).','URL\x20is\x20case-sensitive;\x20ensure\x20the\x20filename\x20in\x20the\x20URL\x20matches\x20exactly.']},{'name':'IPFS\x20via\x20Pinata\x20(Free\x20gateway)','description':'Upload\x20the\x20.wip\x20file\x20to\x20IPFS\x20through\x20Pinata\x27s\x20free\x20gateway.\x20'+'Content-addressed\x20—\x20the\x20CID\x20hash\x20also\x20serves\x20as\x20an\x20integrity\x20check.','difficulty':'medium','free':!![],'result_url_pattern':'https://gateway.pinata.cloud/ipfs/<CID>\x20\x20(or\x20\x20https://ipfs.io/ipfs/<CID>)','steps':['//\x201.\x20Sign\x20up\x20for\x20a\x20free\x20Pinata\x20account\x20at\x20https://app.pinata.cloud/\x20(1\x20GB\x20free\x20storage).','//\x202.\x20Get\x20your\x20API\x20key\x20from\x20https://app.pinata.cloud/keys\x20(generate\x20a\x20new\x20key\x20with\x20\x27pinFileToIPFS\x27\x20scope).','//\x203.\x20Upload\x20your\x20local\x20WIP\x20file\x20via\x20curl:','curl\x20-X\x20POST\x20https://api.pinata.cloud/pinning/pinFileToIPFS\x20\x5c','\x20\x20-H\x20\x22Authorization:\x20Bearer\x20<YOUR_PINATA_API_KEY>\x22\x20\x5c','\x20\x20-F\x20\x22file=@\x27'+b+'\x27\x22','//\x204.\x20Pinata\x20returns\x20JSON\x20with\x20\x27IpfsHash\x27\x20(the\x20CID).\x20Extract\x20it:','//\x20\x20\x20\x20Example\x20response:\x20{\x20\x22IpfsHash\x22:\x20\x22QmXYZ...\x22,\x20\x22PinSize\x22:\x2012345,\x20\x22Timestamp\x22:\x20\x22...\x22\x20}','//\x205.\x20Verify\x20the\x20file\x20is\x20reachable\x20via\x20the\x20public\x20gateway:','curl\x20-I\x20https://gateway.pinata.cloud/ipfs/<CID>','//\x206.\x20(Optional)\x20Use\x20ipfs://<CID>\x20as\x20the\x20wip_url\x20—\x20the\x20SDK\x20resolves\x20it.','//\x207.\x20Update\x20your\x20Service\x20on-chain\x20with\x20the\x20IPFS\x20URL\x20or\x20CID:','//\x20\x20\x20\x20Call\x20onchain_operations\x20{\x20operation_type:\x20\x27service\x27,\x20data:\x20{\x20object:\x20\x27<service-id>\x27,\x20sales:\x20{\x20op:\x20\x27set\x27,\x20sales:\x20[{\x20...,\x20wip_url:\x20\x27https://gateway.pinata.cloud/ipfs/<CID>\x27,\x20wip_hash:\x20\x27<hash>\x27\x20}]\x20}\x20}\x20}'],'notes':['Pinata\x20free\x20tier:\x201\x20GB\x20storage,\x20100\x20uploads/day\x20—\x20sufficient\x20for\x20WIP\x20files.','For\x20long-term\x20durability,\x20also\x20pin\x20via\x20another\x20gateway\x20(e.g.,\x20nft.storage).','IPFS\x20CIDs\x20are\x20content-addressed\x20—\x20if\x20the\x20file\x20changes,\x20the\x20CID\x20changes.\x20This\x20is\x20a\x20feature,\x20not\x20a\x20bug.']},{'name':'User\x27s\x20own\x20website\x20/\x20static\x20host','description':'If\x20you\x20already\x20operate\x20a\x20website\x20or\x20static\x20host\x20(e.g.,\x20nginx,\x20Vercel,\x20Netlify,\x20Cloudflare\x20Pages),\x20'+'upload\x20the\x20.wip\x20file\x20there\x20and\x20use\x20its\x20public\x20URL.','difficulty':'medium','free':!![],'result_url_pattern':'https://<your-domain>/<path>/<file>.wip','steps':['//\x201.\x20Copy\x20your\x20local\x20WIP\x20file\x20to\x20your\x20web\x20server\x27s\x20static\x20directory:','scp\x20\x27'+b+'\x27\x20user@your-server:/var/www/html/wowok/'+c,'//\x202.\x20Ensure\x20the\x20server\x20sets\x20Content-Type:\x20application/json\x20(or\x20application/octet-stream)\x20for\x20.wip\x20files.','//\x20\x20\x20\x20For\x20nginx,\x20add\x20to\x20your\x20server\x20block:','//\x20\x20\x20\x20\x20\x20\x20\x20location\x20~\x20\x5c.wip$\x20{\x20default_type\x20application/json;\x20}','//\x203.\x20Verify\x20the\x20file\x20is\x20reachable:','curl\x20-I\x20https://<your-domain>/wowok/'+c,'//\x204.\x20Update\x20your\x20Service\x20on-chain\x20with\x20the\x20new\x20public\x20URL:','//\x20\x20\x20\x20Call\x20onchain_operations\x20{\x20operation_type:\x20\x27service\x27,\x20data:\x20{\x20object:\x20\x27<service-id>\x27,\x20sales:\x20{\x20op:\x20\x27set\x27,\x20sales:\x20[{\x20...,\x20wip_url:\x20\x27https://<your-domain>/wowok/<file>.wip\x27,\x20wip_hash:\x20\x27<hash>\x27\x20}]\x20}\x20}\x20}'],'notes':['Make\x20sure\x20CORS\x20is\x20permissive\x20if\x20the\x20verifier\x20fetches\x20via\x20browser\x20(Access-Control-Allow-Origin:\x20*).','Ensure\x20HTTPS\x20is\x20enabled\x20—\x20most\x20verifiers\x20reject\x20plain\x20HTTP.']},{'name':'Data\x20URL\x20embedding\x20(small\x20files\x20only)','description':'Embed\x20the\x20entire\x20WIP\x20file\x20as\x20a\x20base64\x20data\x20URL\x20directly\x20in\x20the\x20wip_url\x20field.\x20'+'No\x20external\x20hosting\x20required,\x20but\x20on-chain\x20storage\x20cost\x20grows\x20with\x20file\x20size.','difficulty':'easy','free':!![],'result_url_pattern':'data:application/json;base64,<base64-encoded-content>','steps':['//\x201.\x20Encode\x20your\x20local\x20WIP\x20file\x20as\x20a\x20base64\x20data\x20URL:','//\x20\x20\x20\x20On\x20Linux/macOS:','echo\x20\x22data:application/json;base64,$(base64\x20-w0\x20\x27'+b+'\x27)\x22','//\x20\x20\x20\x20On\x20Windows\x20(PowerShell):','$bytes\x20=\x20[System.IO.File]::ReadAllBytes(\x27'+a+'\x27);\x20$b64\x20=\x20[System.Convert]::ToBase64String($bytes);\x20Write-Output\x20\x22data:application/json;base64,$b64\x22','//\x202.\x20Use\x20the\x20resulting\x20data\x20URL\x20as\x20the\x20wip_url\x20field\x20when\x20updating\x20the\x20Service.','//\x203.\x20Note:\x20data\x20URLs\x20are\x20NOT\x20recommended\x20for\x20files\x20>\x2050\x20KB\x20due\x20to\x20on-chain\x20storage\x20cost.'],'notes':['Only\x20suitable\x20for\x20very\x20small\x20WIP\x20files\x20(typically\x20<\x2010\x20KB).','Data\x20URLs\x20cannot\x20be\x20updated\x20without\x20an\x20on-chain\x20transaction\x20—\x20content\x20is\x20literally\x20embedded.','Prefer\x20GitHub\x20Pages\x20or\x20IPFS\x20for\x20files\x20>\x2010\x20KB.']}];}export function analyzeWipDeployment(a){const b=classifyWipPath(a),c=b['is_local'];let d,e=[];if(c)b['type']==='local_http'?d='The\x20WIP\x20URL\x20\x27'+a+'\x27\x20is\x20a\x20'+b['description']+'.\x20'+'It\x20is\x20reachable\x20only\x20from\x20the\x20merchant\x27s\x20own\x20machine/LAN\x20—\x20customers\x20and\x20'+'on-chain\x20verifiers\x20on\x20other\x20machines\x20CANNOT\x20fetch\x20it.\x20Storing\x20it\x20on-chain\x20'+'makes\x20every\x20customer\x20order\x20fail.\x20'+'Deploy\x20the\x20.wip\x20file\x20to\x20a\x20public\x20host\x20(GitHub\x20Pages,\x20IPFS,\x20or\x20your\x20own\x20website)\x20'+'and\x20update\x20the\x20Service\x27s\x20wip_url\x20with\x20the\x20public\x20URL.':d='The\x20WIP\x20path\x20\x27'+a+'\x27\x20is\x20a\x20LOCAL\x20'+b['type']+'\x20path.\x20'+'Local\x20paths\x20stored\x20on-chain\x20are\x20unreachable\x20by\x20customers\x20and\x20verifiers.\x20'+'Deploy\x20the\x20.wip\x20file\x20to\x20a\x20public\x20host\x20(GitHub\x20Pages,\x20IPFS,\x20or\x20your\x20own\x20website)\x20'+'and\x20update\x20the\x20Service\x27s\x20wip_url\x20with\x20the\x20public\x20URL.',e=getDeployOptions(a);else{if(b['type']==='http_url')d='The\x20WIP\x20path\x20is\x20an\x20HTTP(S)\x20URL\x20—\x20verify\x20the\x20server\x20returns\x20200.\x20'+'If\x20the\x20URL\x20returns\x20404/403,\x20the\x20file\x20may\x20have\x20been\x20moved\x20or\x20deleted.',e=[];else{if(b['type']==='ipfs')d='The\x20WIP\x20path\x20is\x20an\x20IPFS\x20URL\x20—\x20verify\x20the\x20gateway\x20is\x20responsive.\x20'+'If\x20the\x20CID\x20is\x20unreachable,\x20the\x20file\x20may\x20have\x20been\x20unpinned.',e=[];else b['type']==='data_url'?(d='The\x20WIP\x20path\x20is\x20a\x20data\x20URL\x20—\x20content\x20is\x20embedded,\x20no\x20deployment\x20needed.',e=[]):(d='Unrecognized\x20WIP\x20path\x20format:\x20\x27'+a+'\x27',e=[]);}}return{'path':a,'classification':b,'needs_deployment':c,'reason':d,'options':e,'remind_update_hash':c};}export function formatDeployHints(a){if(!a['needs_deployment']&&a['options']['length']===0x0)return'';const b=[];b['push']('===\x20WIP\x20Deployment\x20Assistance\x20==='),b['push'](''),b['push']('Path:\x20'+a['path']),b['push']('Type:\x20'+a['classification']['description']),b['push']('Reason:\x20'+a['reason']),b['push']('');if(a['options']['length']>0x0){b['push']('Recommended\x20deployment\x20options:'),b['push']('');for(const c of a['options']){b['push']('▶\x20'+c['name']+'\x20(difficulty:\x20'+c['difficulty']+',\x20free:\x20'+c['free']+')'),b['push']('\x20\x20'+c['description']),b['push']('\x20\x20Resulting\x20URL\x20pattern:\x20'+c['result_url_pattern']),b['push']('\x20\x20Steps:');for(const d of c['steps']){b['push']('\x20\x20\x20\x20'+d);}if(c['notes']&&c['notes']['length']>0x0){b['push']('\x20\x20Notes:');for(const e of c['notes']){b['push']('\x20\x20\x20\x20-\x20'+e);}}b['push']('');}}return a['remind_update_hash']&&(b['push']('⚠️\x20After\x20deploying,\x20compute\x20the\x20new\x20WIP\x20hash\x20and\x20update\x20the\x20Service:'),b['push']('\x20\x201.\x20Re-run\x20wip_file\x20{\x20type:\x20\x27verify\x27,\x20wipFilePath:\x20\x27<new-public-url>\x27\x20}\x20to\x20confirm\x20the\x20file\x20is\x20reachable.'),b['push']('\x20\x202.\x20Extract\x20the\x20meta.hash\x20from\x20the\x20WIP\x20file\x20(or\x20use\x20wip_file\x20{\x20type:\x20\x27verify\x27\x20}\x20result).'),b['push']('\x20\x203.\x20Update\x20the\x20Service\x20on-chain:\x20onchain_operations\x20{\x20operation_type:\x20\x27service\x27,\x20data:\x20{\x20object:\x20\x27<service-id>\x27,\x20sales:\x20{\x20op:\x20\x27set\x27,\x20sales:\x20[{\x20...,\x20wip_url:\x20\x27<new-public-url>\x27,\x20wip_hash:\x20\x27<hash>\x27\x20}]\x20}\x20}\x20}'),b['push']('')),b['push']('==============================='),b['join']('\x0a');}
|
|
1
|
+
export function classifyWipPath(a){if(!a||typeof a!=='string')return{'type':'unknown','is_local':![],'is_network':![],'description':'Empty\x20or\x20invalid\x20path'};if(a['startsWith']('data:'))return{'type':'data_url','is_local':![],'is_network':!![],'description':'Data\x20URL\x20—\x20embedded\x20content,\x20globally\x20reachable'};if(a['startsWith']('ipfs://'))return{'type':'ipfs','is_local':![],'is_network':!![],'description':'IPFS\x20URI\x20—\x20resolve\x20via\x20any\x20public\x20gateway'};const b=[/^https?:\/\/ipfs\.io\//i,/^https?:\/\/cloudflare-ipfs\.com\//i,/^https?:\/\/gateway\.pinata\.cloud\//i,/^https?:\/\/dweb\.link\//i,/^https?:\/\/[^/]*pinata\.cloud\//i];if(b['some'](d=>d['test'](a)))return{'type':'ipfs','is_local':![],'is_network':!![],'description':'IPFS\x20HTTP\x20gateway\x20URL\x20—\x20globally\x20reachable'};if(/^https?:\/\/(localhost|127\.0\.0\.1|\[::1\]|0\.0\.0\.0)([:/]|$)/i['test'](a))return{'type':'local_http','is_local':!![],'is_network':![],'description':'Local\x20HTTP\x20URL\x20(localhost/loopback)\x20—\x20reachable\x20only\x20on\x20this\x20machine,\x20NOT\x20by\x20customers'};const c=/^https?:\/\/(10\.\d{1,3}\.\d{1,3}\.\d{1,3}|172\.(1[6-9]|2\d|3[01])\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3})([:/]|$)/i;if(c['test'](a))return{'type':'local_http','is_local':!![],'is_network':![],'description':'LAN\x20HTTP\x20URL\x20(private\x20IP)\x20—\x20reachable\x20only\x20on\x20the\x20local\x20network,\x20NOT\x20by\x20customers'};if(/^https?:\/\//i['test'](a))return{'type':'http_url','is_local':![],'is_network':!![],'description':'HTTP(S)\x20URL\x20—\x20globally\x20reachable\x20if\x20server\x20returns\x20200'};if(/^[A-Za-z]:[\\/]/['test'](a))return{'type':'local_windows','is_local':!![],'is_network':![],'description':'Windows\x20local\x20path\x20—\x20NOT\x20reachable\x20by\x20customers/AI'};if(a['startsWith']('/'))return{'type':'local_unix','is_local':!![],'is_network':![],'description':'Unix\x20local\x20path\x20—\x20NOT\x20reachable\x20by\x20customers/AI'};if(a['startsWith']('./')||a['startsWith']('../')||a==='.'||a==='..')return{'type':'local_relative','is_local':!![],'is_network':![],'description':'Relative\x20local\x20path\x20—\x20NOT\x20reachable\x20by\x20customers/AI'};if(!a['includes']('://')&&!a['startsWith']('data:'))return{'type':'local_relative','is_local':!![],'is_network':![],'description':'Local\x20file\x20path\x20(no\x20scheme)\x20—\x20NOT\x20reachable\x20by\x20customers/AI'};return{'type':'unknown','is_local':![],'is_network':![],'description':'Unrecognized\x20path\x20format'};}export function getDeployOptions(a){const b=a['replace'](/'/g,'\x27\x5c\x27\x27'),c=a['split'](/[\\/]/)['pop']()||'file.wip';return[{'name':'Wowok\x20WIP\x20storage\x20service\x20(Recommended)','description':'Upload\x20the\x20.wip\x20file\x20directly\x20from\x20the\x20MCP\x20with\x20wip_file\x20type=\x27upload\x27.\x20'+'Default\x20is\x20the\x20official\x20FREE\x20store\x20wip.store.wowok.net\x20(limited\x20to\x2010\x20files\x20per\x20account);\x20'+'with\x20storage=\x27custom\x27\x20any\x20self-hosted\x20or\x20third-party\x20wip\x20storage\x20service\x20works\x20(no\x20store\x20quota,\x20full\x20control).','difficulty':'easy','free':!![],'result_url_pattern':'https://wip.store.wowok.net/f/{hash}\x20\x20\x20(or\x20your\x20custom\x20service\x20base\x20URL\x20+\x20/f/{hash})','steps':['//\x201.\x20Generate\x20the\x20WIP\x20file:\x20wip_file\x20{\x20type:\x20\x27generate\x27,\x20options:\x20{\x20markdown_text:\x20\x27...\x27\x20}\x20}','//\x202.\x20Sign\x20it\x20with\x20your\x20account:\x20wip_file\x20{\x20type:\x20\x27sign\x27,\x20wipFilePath:\x20\x27<file>\x27,\x20account:\x20\x27<account>\x27\x20}','//\x203.\x20Upload\x20to\x20the\x20official\x20free\x20store:\x20wip_file\x20{\x20type:\x20\x27upload\x27,\x20wipFilePath:\x20\x27<file>\x27,\x20account:\x20\x27<account>\x27\x20}','//\x20\x20\x20\x20Or\x20use\x20your\x20own\x20/\x20a\x20third-party\x20service:\x20wip_file\x20{\x20type:\x20\x27upload\x27,\x20wipFilePath:\x20\x27<file>\x27,\x20storage:\x20\x27custom\x27,\x20customBaseUrl:\x20\x27https://your-wip-service.example.com\x27\x20}','//\x204.\x20Use\x20the\x20returned\x20URL\x20(base_url\x20+\x20/f/{hash})\x20as\x20the\x20Service\x27s\x20wip_url:','//\x20\x20\x20\x20onchain_operations\x20{\x20operation_type:\x20\x27service\x27,\x20data:\x20{\x20object:\x20\x27<service-id>\x27,\x20sales:\x20{\x20op:\x20\x27set\x27,\x20sales:\x20[{\x20...,\x20wip_url:\x20\x27<public-url>\x27,\x20wip_hash:\x20\x27<hash>\x27\x20}]\x20}\x20}\x20}','//\x205.\x20Confirm\x20reachability:\x20wip_file\x20{\x20type:\x20\x27verify\x27,\x20wipFilePath:\x20\x27<public-url>\x27\x20}'],'notes':['Official\x20free\x20store\x20is\x20limited\x20to\x2010\x20files\x20per\x20account\x20—\x20free\x20up\x20space\x20with\x20wip_file\x20type=\x27storage_delete\x27\x20when\x20the\x20quota\x20is\x20hit.','Official\x20free\x20store\x20declaration:\x20files\x20are\x20retained\x20for\x206\x20months\x20(180\x20days);\x20free\x20best-effort\x20service\x20—\x20force\x20majeure\x20excepted;\x20expired\x20files\x20are\x20NEVER\x20deleted\x20automatically\x20(manual\x20admin\x20purge\x20only).\x20For\x20permanent\x20hosting\x20use\x20storage=\x27custom\x27.','The\x20public\x20WIP\x20URL\x20is\x20network-independent:\x20the\x20same\x20file\x20serves\x20buyers\x20on\x20both\x20testnet\x20and\x20mainnet.','Large\x20WIP\x20files\x20(multi-MB,\x20image-heavy)\x20are\x20network-sensitive:\x20compress\x20images\x20before\x20generate\x20and\x20retry\x20transient\x20upload\x20failures.']},{'name':'GitHub\x20Pages','description':'Upload\x20the\x20.wip\x20file\x20to\x20a\x20GitHub\x20repository\x20and\x20serve\x20it\x20via\x20GitHub\x20Pages.\x20'+'Free,\x20stable,\x20HTTPS-enabled,\x20no\x20expiration.','difficulty':'easy','free':!![],'result_url_pattern':'https://<your-username>.github.io/<repo>/<file>.wip','steps':['//\x201.\x20Create\x20a\x20new\x20GitHub\x20repository\x20(e.g.,\x20\x27wowok-wip\x27)\x20via\x20https://github.com/new','//\x202.\x20Make\x20it\x20PUBLIC\x20so\x20the\x20file\x20is\x20world-readable.','//\x203.\x20Copy\x20your\x20local\x20WIP\x20file\x20into\x20the\x20repo:','git\x20clone\x20https://github.com/<your-username>/wowok-wip.git','cp\x20\x27'+b+'\x27\x20wowok-wip/'+c,'cd\x20wowok-wip','git\x20add\x20'+c,'git\x20commit\x20-m\x20\x22Add\x20WIP\x20file\x22','git\x20push\x20origin\x20main','//\x204.\x20Enable\x20GitHub\x20Pages:\x20repo\x20→\x20Settings\x20→\x20Pages\x20→\x20Source\x20→\x20\x27main\x27\x20branch\x20→\x20/(root)\x20→\x20Save','//\x205.\x20Wait\x2030-60\x20seconds\x20for\x20deployment,\x20then\x20verify\x20the\x20URL\x20is\x20reachable:','curl\x20-I\x20https://<your-username>.github.io/wowok-wip/'+c,'//\x206.\x20Update\x20your\x20Service\x20on-chain\x20with\x20the\x20new\x20public\x20URL:','//\x20\x20\x20\x20Call\x20onchain_operations\x20{\x20operation_type:\x20\x27service\x27,\x20data:\x20{\x20object:\x20\x27<service-id>\x27,\x20sales:\x20{\x20op:\x20\x27set\x27,\x20sales:\x20[{\x20...,\x20wip_url:\x20\x27https://...\x27,\x20wip_hash:\x20\x27<hash>\x27\x20}]\x20}\x20}\x20}'],'notes':['If\x20the\x20repo\x20already\x20has\x20Pages\x20enabled\x20on\x20the\x20main\x20branch,\x20step\x204\x20can\x20be\x20skipped.','GitHub\x20Pages\x20serves\x20files\x20up\x20to\x2025\x20MB\x20—\x20well\x20above\x20typical\x20WIP\x20sizes\x20(<\x201\x20MB).','URL\x20is\x20case-sensitive;\x20ensure\x20the\x20filename\x20in\x20the\x20URL\x20matches\x20exactly.']},{'name':'IPFS\x20via\x20Pinata\x20(Free\x20gateway)','description':'Upload\x20the\x20.wip\x20file\x20to\x20IPFS\x20through\x20Pinata\x27s\x20free\x20gateway.\x20'+'Content-addressed\x20—\x20the\x20CID\x20hash\x20also\x20serves\x20as\x20an\x20integrity\x20check.','difficulty':'medium','free':!![],'result_url_pattern':'https://gateway.pinata.cloud/ipfs/<CID>\x20\x20(or\x20\x20https://ipfs.io/ipfs/<CID>)','steps':['//\x201.\x20Sign\x20up\x20for\x20a\x20free\x20Pinata\x20account\x20at\x20https://app.pinata.cloud/\x20(1\x20GB\x20free\x20storage).','//\x202.\x20Get\x20your\x20API\x20key\x20from\x20https://app.pinata.cloud/keys\x20(generate\x20a\x20new\x20key\x20with\x20\x27pinFileToIPFS\x27\x20scope).','//\x203.\x20Upload\x20your\x20local\x20WIP\x20file\x20via\x20curl:','curl\x20-X\x20POST\x20https://api.pinata.cloud/pinning/pinFileToIPFS\x20\x5c','\x20\x20-H\x20\x22Authorization:\x20Bearer\x20<YOUR_PINATA_API_KEY>\x22\x20\x5c','\x20\x20-F\x20\x22file=@\x27'+b+'\x27\x22','//\x204.\x20Pinata\x20returns\x20JSON\x20with\x20\x27IpfsHash\x27\x20(the\x20CID).\x20Extract\x20it:','//\x20\x20\x20\x20Example\x20response:\x20{\x20\x22IpfsHash\x22:\x20\x22QmXYZ...\x22,\x20\x22PinSize\x22:\x2012345,\x20\x22Timestamp\x22:\x20\x22...\x22\x20}','//\x205.\x20Verify\x20the\x20file\x20is\x20reachable\x20via\x20the\x20public\x20gateway:','curl\x20-I\x20https://gateway.pinata.cloud/ipfs/<CID>','//\x206.\x20(Optional)\x20Use\x20ipfs://<CID>\x20as\x20the\x20wip_url\x20—\x20the\x20SDK\x20resolves\x20it.','//\x207.\x20Update\x20your\x20Service\x20on-chain\x20with\x20the\x20IPFS\x20URL\x20or\x20CID:','//\x20\x20\x20\x20Call\x20onchain_operations\x20{\x20operation_type:\x20\x27service\x27,\x20data:\x20{\x20object:\x20\x27<service-id>\x27,\x20sales:\x20{\x20op:\x20\x27set\x27,\x20sales:\x20[{\x20...,\x20wip_url:\x20\x27https://gateway.pinata.cloud/ipfs/<CID>\x27,\x20wip_hash:\x20\x27<hash>\x27\x20}]\x20}\x20}\x20}'],'notes':['Pinata\x20free\x20tier:\x201\x20GB\x20storage,\x20100\x20uploads/day\x20—\x20sufficient\x20for\x20WIP\x20files.','For\x20long-term\x20durability,\x20also\x20pin\x20via\x20another\x20gateway\x20(e.g.,\x20nft.storage).','IPFS\x20CIDs\x20are\x20content-addressed\x20—\x20if\x20the\x20file\x20changes,\x20the\x20CID\x20changes.\x20This\x20is\x20a\x20feature,\x20not\x20a\x20bug.']},{'name':'User\x27s\x20own\x20website\x20/\x20static\x20host','description':'If\x20you\x20already\x20operate\x20a\x20website\x20or\x20static\x20host\x20(e.g.,\x20nginx,\x20Vercel,\x20Netlify,\x20Cloudflare\x20Pages),\x20'+'upload\x20the\x20.wip\x20file\x20there\x20and\x20use\x20its\x20public\x20URL.','difficulty':'medium','free':!![],'result_url_pattern':'https://<your-domain>/<path>/<file>.wip','steps':['//\x201.\x20Copy\x20your\x20local\x20WIP\x20file\x20to\x20your\x20web\x20server\x27s\x20static\x20directory:','scp\x20\x27'+b+'\x27\x20user@your-server:/var/www/html/wowok/'+c,'//\x202.\x20Ensure\x20the\x20server\x20sets\x20Content-Type:\x20application/json\x20(or\x20application/octet-stream)\x20for\x20.wip\x20files.','//\x20\x20\x20\x20For\x20nginx,\x20add\x20to\x20your\x20server\x20block:','//\x20\x20\x20\x20\x20\x20\x20\x20location\x20~\x20\x5c.wip$\x20{\x20default_type\x20application/json;\x20}','//\x203.\x20Verify\x20the\x20file\x20is\x20reachable:','curl\x20-I\x20https://<your-domain>/wowok/'+c,'//\x204.\x20Update\x20your\x20Service\x20on-chain\x20with\x20the\x20new\x20public\x20URL:','//\x20\x20\x20\x20Call\x20onchain_operations\x20{\x20operation_type:\x20\x27service\x27,\x20data:\x20{\x20object:\x20\x27<service-id>\x27,\x20sales:\x20{\x20op:\x20\x27set\x27,\x20sales:\x20[{\x20...,\x20wip_url:\x20\x27https://<your-domain>/wowok/<file>.wip\x27,\x20wip_hash:\x20\x27<hash>\x27\x20}]\x20}\x20}\x20}'],'notes':['Make\x20sure\x20CORS\x20is\x20permissive\x20if\x20the\x20verifier\x20fetches\x20via\x20browser\x20(Access-Control-Allow-Origin:\x20*).','Ensure\x20HTTPS\x20is\x20enabled\x20—\x20most\x20verifiers\x20reject\x20plain\x20HTTP.']},{'name':'Data\x20URL\x20embedding\x20(small\x20files\x20only)','description':'Embed\x20the\x20entire\x20WIP\x20file\x20as\x20a\x20base64\x20data\x20URL\x20directly\x20in\x20the\x20wip_url\x20field.\x20'+'No\x20external\x20hosting\x20required,\x20but\x20on-chain\x20storage\x20cost\x20grows\x20with\x20file\x20size.','difficulty':'easy','free':!![],'result_url_pattern':'data:application/json;base64,<base64-encoded-content>','steps':['//\x201.\x20Encode\x20your\x20local\x20WIP\x20file\x20as\x20a\x20base64\x20data\x20URL:','//\x20\x20\x20\x20On\x20Linux/macOS:','echo\x20\x22data:application/json;base64,$(base64\x20-w0\x20\x27'+b+'\x27)\x22','//\x20\x20\x20\x20On\x20Windows\x20(PowerShell):','$bytes\x20=\x20[System.IO.File]::ReadAllBytes(\x27'+a+'\x27);\x20$b64\x20=\x20[System.Convert]::ToBase64String($bytes);\x20Write-Output\x20\x22data:application/json;base64,$b64\x22','//\x202.\x20Use\x20the\x20resulting\x20data\x20URL\x20as\x20the\x20wip_url\x20field\x20when\x20updating\x20the\x20Service.','//\x203.\x20Note:\x20data\x20URLs\x20are\x20NOT\x20recommended\x20for\x20files\x20>\x2050\x20KB\x20due\x20to\x20on-chain\x20storage\x20cost.'],'notes':['Only\x20suitable\x20for\x20very\x20small\x20WIP\x20files\x20(typically\x20<\x2010\x20KB).','Data\x20URLs\x20cannot\x20be\x20updated\x20without\x20an\x20on-chain\x20transaction\x20—\x20content\x20is\x20literally\x20embedded.','Prefer\x20GitHub\x20Pages\x20or\x20IPFS\x20for\x20files\x20>\x2010\x20KB.']}];}export function analyzeWipDeployment(a){const b=classifyWipPath(a),c=b['is_local'];let d,e=[];if(c)b['type']==='local_http'?d='The\x20WIP\x20URL\x20\x27'+a+'\x27\x20is\x20a\x20'+b['description']+'.\x20'+'It\x20is\x20reachable\x20only\x20from\x20the\x20merchant\x27s\x20own\x20machine/LAN\x20—\x20customers\x20and\x20'+'on-chain\x20verifiers\x20on\x20other\x20machines\x20CANNOT\x20fetch\x20it.\x20Storing\x20it\x20on-chain\x20'+'makes\x20every\x20customer\x20order\x20fail.\x20'+'Deploy\x20the\x20.wip\x20file\x20to\x20a\x20public\x20host\x20(GitHub\x20Pages,\x20IPFS,\x20or\x20your\x20own\x20website)\x20'+'and\x20update\x20the\x20Service\x27s\x20wip_url\x20with\x20the\x20public\x20URL.':d='The\x20WIP\x20path\x20\x27'+a+'\x27\x20is\x20a\x20LOCAL\x20'+b['type']+'\x20path.\x20'+'Local\x20paths\x20stored\x20on-chain\x20are\x20unreachable\x20by\x20customers\x20and\x20verifiers.\x20'+'Deploy\x20the\x20.wip\x20file\x20to\x20a\x20public\x20host\x20(GitHub\x20Pages,\x20IPFS,\x20or\x20your\x20own\x20website)\x20'+'and\x20update\x20the\x20Service\x27s\x20wip_url\x20with\x20the\x20public\x20URL.',e=getDeployOptions(a);else{if(b['type']==='http_url')d='The\x20WIP\x20path\x20is\x20an\x20HTTP(S)\x20URL\x20—\x20verify\x20the\x20server\x20returns\x20200.\x20'+'If\x20the\x20URL\x20returns\x20404/403,\x20the\x20file\x20may\x20have\x20been\x20moved\x20or\x20deleted.',e=[];else{if(b['type']==='ipfs')d='The\x20WIP\x20path\x20is\x20an\x20IPFS\x20URL\x20—\x20verify\x20the\x20gateway\x20is\x20responsive.\x20'+'If\x20the\x20CID\x20is\x20unreachable,\x20the\x20file\x20may\x20have\x20been\x20unpinned.',e=[];else b['type']==='data_url'?(d='The\x20WIP\x20path\x20is\x20a\x20data\x20URL\x20—\x20content\x20is\x20embedded,\x20no\x20deployment\x20needed.',e=[]):(d='Unrecognized\x20WIP\x20path\x20format:\x20\x27'+a+'\x27',e=[]);}}return{'path':a,'classification':b,'needs_deployment':c,'reason':d,'options':e,'remind_update_hash':c};}export function formatDeployHints(a){if(!a['needs_deployment']&&a['options']['length']===0x0)return'';const b=[];b['push']('===\x20WIP\x20Deployment\x20Assistance\x20==='),b['push'](''),b['push']('Path:\x20'+a['path']),b['push']('Type:\x20'+a['classification']['description']),b['push']('Reason:\x20'+a['reason']),b['push']('');if(a['options']['length']>0x0){b['push']('Recommended\x20deployment\x20options:'),b['push']('');for(const c of a['options']){b['push']('▶\x20'+c['name']+'\x20(difficulty:\x20'+c['difficulty']+',\x20free:\x20'+c['free']+')'),b['push']('\x20\x20'+c['description']),b['push']('\x20\x20Resulting\x20URL\x20pattern:\x20'+c['result_url_pattern']),b['push']('\x20\x20Steps:');for(const d of c['steps']){b['push']('\x20\x20\x20\x20'+d);}if(c['notes']&&c['notes']['length']>0x0){b['push']('\x20\x20Notes:');for(const e of c['notes']){b['push']('\x20\x20\x20\x20-\x20'+e);}}b['push']('');}}return a['remind_update_hash']&&(b['push']('⚠️\x20After\x20deploying,\x20compute\x20the\x20new\x20WIP\x20hash\x20and\x20update\x20the\x20Service:'),b['push']('\x20\x201.\x20Re-run\x20wip_file\x20{\x20type:\x20\x27verify\x27,\x20wipFilePath:\x20\x27<new-public-url>\x27\x20}\x20to\x20confirm\x20the\x20file\x20is\x20reachable.'),b['push']('\x20\x202.\x20Extract\x20the\x20meta.hash\x20from\x20the\x20WIP\x20file\x20(or\x20use\x20wip_file\x20{\x20type:\x20\x27verify\x27\x20}\x20result).'),b['push']('\x20\x203.\x20Update\x20the\x20Service\x20on-chain:\x20onchain_operations\x20{\x20operation_type:\x20\x27service\x27,\x20data:\x20{\x20object:\x20\x27<service-id>\x27,\x20sales:\x20{\x20op:\x20\x27set\x27,\x20sales:\x20[{\x20...,\x20wip_url:\x20\x27<new-public-url>\x27,\x20wip_hash:\x20\x27<hash>\x27\x20}]\x20}\x20}\x20}'),b['push']('')),b['push']('==============================='),b['join']('\x0a');}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wowok/agent-mcp",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.7",
|
|
4
4
|
"description": "Making It Easy for AI Agents to Communicate, Collaborate, Trade, and Trust.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"license": "Apache-2.0",
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@modelcontextprotocol/server": "^2.0.0",
|
|
57
|
-
"@wowok/wowok": "3.1.
|
|
57
|
+
"@wowok/wowok": "3.1.7",
|
|
58
58
|
"lodash": "^4.18.1",
|
|
59
59
|
"zod": "^4.2.0"
|
|
60
60
|
},
|