gin-skills 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DEVELOPMENT.md +510 -0
- package/README.md +103 -0
- package/agents/developer.md +56 -0
- package/agents/frontend-design.md +69 -0
- package/agents/mobile-reviewer.md +36 -0
- package/agents/review-code.md +49 -0
- package/agents/security-scanner.md +50 -0
- package/agents/tester.md +72 -0
- package/bin/cli.js +460 -0
- package/landing/ai-build-ai.png +0 -0
- package/landing/index.html +1524 -0
- package/landing/logo.png +0 -0
- package/package.json +37 -0
- package/skills/active-life-dev/SKILL.md +157 -0
- package/skills/active-life-dev/docs/auth.md +187 -0
- package/skills/active-life-dev/docs/customers.md +216 -0
- package/skills/active-life-dev/docs/integrations.md +209 -0
- package/skills/active-life-dev/docs/inventory.md +192 -0
- package/skills/active-life-dev/docs/modules.md +181 -0
- package/skills/active-life-dev/docs/orders.md +180 -0
- package/skills/active-life-dev/docs/patterns.md +319 -0
- package/skills/active-life-dev/docs/products.md +216 -0
- package/skills/active-life-dev/docs/schema.md +502 -0
- package/skills/active-life-dev/docs/setup.md +169 -0
- package/skills/active-life-dev/docs/vouchers.md +144 -0
- package/skills/ai-asset-generator/SKILL.md +247 -0
- package/skills/ai-asset-generator/docs/gen-image.md +274 -0
- package/skills/ai-asset-generator/docs/genvideo.md +341 -0
- package/skills/ai-asset-generator/docs/remove-background.md +19 -0
- package/skills/ai-asset-generator/lib/bg-remove.mjs +54 -0
- package/skills/ai-asset-generator/lib/env.mjs +48 -0
- package/skills/ai-asset-generator/lib/kie-client.mjs +111 -0
- package/skills/ai-asset-generator/output/logo/logo.png +0 -0
- package/skills/ai-build-ai/SKILL.md +127 -0
- package/skills/ai-build-ai/docs/agent-teams.md +293 -0
- package/skills/ai-build-ai/docs/checkpointing.md +161 -0
- package/skills/ai-build-ai/docs/create-agent.md +399 -0
- package/skills/ai-build-ai/docs/create-mcp.md +395 -0
- package/skills/ai-build-ai/docs/create-skill.md +299 -0
- package/skills/ai-build-ai/docs/headless-mode.md +614 -0
- package/skills/ai-build-ai/docs/hooks.md +578 -0
- package/skills/ai-build-ai/docs/memory-claude-md.md +375 -0
- package/skills/ai-build-ai/docs/output-styles.md +208 -0
- package/skills/ai-build-ai/docs/overview.md +162 -0
- package/skills/ai-build-ai/docs/permissions.md +391 -0
- package/skills/ai-build-ai/docs/plugins.md +396 -0
- package/skills/ai-build-ai/docs/sandbox.md +262 -0
- package/skills/ai-build-ai/docs/team-lead-workflow.md +648 -0
- package/skills/ant-design/SKILL.md +323 -0
- package/skills/ant-design/docs/components.md +160 -0
- package/skills/ant-design/docs/data-entry.md +406 -0
- package/skills/ant-design/docs/display.md +594 -0
- package/skills/ant-design/docs/feedback.md +451 -0
- package/skills/ant-design/docs/key-components.md +414 -0
- package/skills/ant-design/docs/navigation.md +310 -0
- package/skills/ant-design/docs/pro-components.md +543 -0
- package/skills/ant-design/docs/setup.md +213 -0
- package/skills/ant-design/docs/theme.md +265 -0
- package/skills/flutter-performance/SKILL.md +803 -0
- package/skills/flutter-performance/references/flutter-patterns.md +595 -0
- package/skills/icon-generator/SKILL.md +270 -0
- package/skills/mobile-app-review/SKILL.md +321 -0
- package/skills/mobile-app-review/references/apple-review.md +132 -0
- package/skills/mobile-app-review/references/google-play-review.md +203 -0
- package/skills/mongodb/SKILL.md +667 -0
- package/skills/mongodb/references/mongoose-patterns.md +368 -0
- package/skills/nestjs-architecture/SKILL.md +1086 -0
- package/skills/nestjs-architecture/references/advanced-patterns.md +590 -0
- package/skills/performance/SKILL.md +509 -0
- package/skills/react-fsd-architecture/SKILL.md +693 -0
- package/skills/react-fsd-architecture/references/fsd-patterns.md +747 -0
- package/skills/react-native-expo/SKILL.md +128 -0
- package/skills/react-native-expo/references/data-layer.md +252 -0
- package/skills/react-native-expo/references/design-system.md +252 -0
- package/skills/react-native-expo/references/navigation.md +199 -0
- package/skills/react-native-expo/references/performance.md +229 -0
- package/skills/react-native-expo/references/platform-services.md +179 -0
- package/skills/react-native-expo/references/state-management.md +209 -0
- package/skills/react-native-expo/references/ui-patterns.md +301 -0
- package/skills/react-query/SKILL.md +685 -0
- package/skills/react-query/references/query-patterns.md +365 -0
- package/skills/review-code/SKILL.md +374 -0
- package/skills/review-code/references/clean-code-principles.md +395 -0
- package/skills/review-code/references/frontend-patterns.md +136 -0
- package/skills/review-code/references/nestjs-patterns.md +184 -0
- package/skills/security-scanner/SKILL.md +366 -0
- package/skills/security-scanner/references/nestjs-security.md +260 -0
- package/skills/security-scanner/references/nextjs-security.md +201 -0
- package/skills/security-scanner/references/react-native-security.md +199 -0
- package/skills/ui-ux-pro-max/SKILL.md +377 -0
- package/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/skills/ui-ux-pro-max/data/colors.csv +97 -0
- package/skills/ui-ux-pro-max/data/icons.csv +101 -0
- package/skills/ui-ux-pro-max/data/landing.csv +31 -0
- package/skills/ui-ux-pro-max/data/products.csv +97 -0
- package/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
- package/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/skills/ui-ux-pro-max/data/styles.csv +68 -0
- package/skills/ui-ux-pro-max/data/typography.csv +58 -0
- package/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
POST
|
|
2
|
+
/api/v1/jobs/createTask
|
|
3
|
+
Create Task
|
|
4
|
+
Create a new generation task
|
|
5
|
+
|
|
6
|
+
Request Parameters
|
|
7
|
+
The API accepts a JSON payload with the following structure:
|
|
8
|
+
|
|
9
|
+
Request Body Structure
|
|
10
|
+
{
|
|
11
|
+
"model": "string",
|
|
12
|
+
"callBackUrl": "string (optional)",
|
|
13
|
+
"input": {
|
|
14
|
+
// Input parameters based on form configuration
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
Root Level Parameters
|
|
18
|
+
model
|
|
19
|
+
Required
|
|
20
|
+
string
|
|
21
|
+
The model name to use for generation
|
|
22
|
+
|
|
23
|
+
Example:
|
|
24
|
+
|
|
25
|
+
"bytedance/v1-pro-image-to-video"
|
|
26
|
+
callBackUrl
|
|
27
|
+
Optional
|
|
28
|
+
string
|
|
29
|
+
Callback URL for task completion notifications. Optional parameter. If provided, the system will send POST requests to this URL when the task completes (success or failure). If not provided, no callback notifications will be sent.
|
|
30
|
+
|
|
31
|
+
Example:
|
|
32
|
+
|
|
33
|
+
"https://your-domain.com/api/callback"
|
|
34
|
+
Input Object Parameters
|
|
35
|
+
The input object contains the following parameters based on the form configuration:
|
|
36
|
+
|
|
37
|
+
input.prompt
|
|
38
|
+
Required
|
|
39
|
+
string
|
|
40
|
+
The text prompt used to generate the video
|
|
41
|
+
|
|
42
|
+
Max length: 10000 characters
|
|
43
|
+
Example:
|
|
44
|
+
|
|
45
|
+
"A golden retriever dashing through shallow surf at the beach, back angle camera low near waterline, splashes frozen in time, blur trails in waves and paws, afternoon sun glinting off wet fur, overcast day, dramatic clouds"
|
|
46
|
+
input.image_url
|
|
47
|
+
Required
|
|
48
|
+
string(URL)
|
|
49
|
+
The URL of the image used to generate video
|
|
50
|
+
|
|
51
|
+
Please provide the URL of the uploaded file; Accepted types: image/jpeg, image/png, image/webp; Max size: 10.0MB
|
|
52
|
+
Example:
|
|
53
|
+
|
|
54
|
+
"https://file.aiquickdraw.com/custom-page/akr/section-images/1755179021328w1nhip18.webp"
|
|
55
|
+
input.resolution
|
|
56
|
+
Optional
|
|
57
|
+
string
|
|
58
|
+
Video resolution - 480p for faster generation, 720p for balance, 1080p for higher quality
|
|
59
|
+
|
|
60
|
+
Available options:
|
|
61
|
+
|
|
62
|
+
480p
|
|
63
|
+
-
|
|
64
|
+
480p
|
|
65
|
+
720p
|
|
66
|
+
-
|
|
67
|
+
720p
|
|
68
|
+
1080p
|
|
69
|
+
-
|
|
70
|
+
1080p
|
|
71
|
+
Example:
|
|
72
|
+
|
|
73
|
+
"720p"
|
|
74
|
+
input.duration
|
|
75
|
+
Optional
|
|
76
|
+
string
|
|
77
|
+
Duration of the video in seconds
|
|
78
|
+
|
|
79
|
+
Available options:
|
|
80
|
+
|
|
81
|
+
5
|
|
82
|
+
-
|
|
83
|
+
5s
|
|
84
|
+
10
|
|
85
|
+
-
|
|
86
|
+
10s
|
|
87
|
+
Example:
|
|
88
|
+
|
|
89
|
+
"5"
|
|
90
|
+
input.camera_fixed
|
|
91
|
+
Optional
|
|
92
|
+
boolean
|
|
93
|
+
Whether to fix the camera position
|
|
94
|
+
|
|
95
|
+
Boolean value (true/false)
|
|
96
|
+
Example:
|
|
97
|
+
|
|
98
|
+
false
|
|
99
|
+
input.seed
|
|
100
|
+
Optional
|
|
101
|
+
number
|
|
102
|
+
Random seed to control video generation. Use -1 for random.
|
|
103
|
+
|
|
104
|
+
Min: -1, Max: 2147483647, Step: 1
|
|
105
|
+
Example:
|
|
106
|
+
|
|
107
|
+
-1
|
|
108
|
+
input.enable_safety_checker
|
|
109
|
+
Optional
|
|
110
|
+
boolean
|
|
111
|
+
The safety checker is always enabled in Playground. It can only be disabled by setting false through the API.
|
|
112
|
+
|
|
113
|
+
Boolean value (true/false)
|
|
114
|
+
Example:
|
|
115
|
+
|
|
116
|
+
true
|
|
117
|
+
Request Example
|
|
118
|
+
|
|
119
|
+
cURL
|
|
120
|
+
|
|
121
|
+
JavaScript
|
|
122
|
+
|
|
123
|
+
Python
|
|
124
|
+
curl -X POST "https://api.kie.ai/api/v1/jobs/createTask" \
|
|
125
|
+
-H "Content-Type: application/json" \
|
|
126
|
+
-H "Authorization: Bearer YOUR_API_KEY" \
|
|
127
|
+
-d '{
|
|
128
|
+
"model": "bytedance/v1-pro-image-to-video",
|
|
129
|
+
"callBackUrl": "https://your-domain.com/api/callback",
|
|
130
|
+
"input": {
|
|
131
|
+
"prompt": "A golden retriever dashing through shallow surf at the beach, back angle camera low near waterline, splashes frozen in time, blur trails in waves and paws, afternoon sun glinting off wet fur, overcast day, dramatic clouds",
|
|
132
|
+
"image_url": "https://file.aiquickdraw.com/custom-page/akr/section-images/1755179021328w1nhip18.webp",
|
|
133
|
+
"resolution": "720p",
|
|
134
|
+
"duration": "5",
|
|
135
|
+
"camera_fixed": false,
|
|
136
|
+
"seed": -1,
|
|
137
|
+
"enable_safety_checker": true
|
|
138
|
+
}
|
|
139
|
+
}'
|
|
140
|
+
Response Example
|
|
141
|
+
{
|
|
142
|
+
"code": 200,
|
|
143
|
+
"message": "success",
|
|
144
|
+
"data": {
|
|
145
|
+
"taskId": "task_12345678"
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
Response Fields
|
|
149
|
+
code
|
|
150
|
+
Status code, 200 for success, others for failure
|
|
151
|
+
message
|
|
152
|
+
Response message, error description when failed
|
|
153
|
+
data.taskId
|
|
154
|
+
Task ID for querying task status
|
|
155
|
+
Callback Notifications
|
|
156
|
+
When you provide the callBackUrl parameter when creating a task, the system will send POST requests to the specified URL upon task completion (success or failure).
|
|
157
|
+
|
|
158
|
+
Success Callback Example
|
|
159
|
+
{
|
|
160
|
+
"code": 200,
|
|
161
|
+
"data": {
|
|
162
|
+
"completeTime": 1755599644000,
|
|
163
|
+
"costTime": 8,
|
|
164
|
+
"createTime": 1755599634000,
|
|
165
|
+
"model": "bytedance/v1-pro-image-to-video",
|
|
166
|
+
"param": "{\"callBackUrl\":\"https://your-domain.com/api/callback\",\"model\":\"bytedance/v1-pro-image-to-video\",\"input\":{\"prompt\":\"A golden retriever dashing through shallow surf at the beach, back angle camera low near waterline, splashes frozen in time, blur trails in waves and paws, afternoon sun glinting off wet fur, overcast day, dramatic clouds\",\"image_url\":\"https://file.aiquickdraw.com/custom-page/akr/section-images/1755179021328w1nhip18.webp\",\"resolution\":\"720p\",\"duration\":\"5\",\"camera_fixed\":false,\"seed\":-1,\"enable_safety_checker\":true}}",
|
|
167
|
+
"resultJson": "{\"resultUrls\":[\"https://example.com/generated-image.jpg\"]}",
|
|
168
|
+
"state": "success",
|
|
169
|
+
"taskId": "e989621f54392584b05867f87b160672",
|
|
170
|
+
"failCode": null,
|
|
171
|
+
"failMsg": null,
|
|
172
|
+
},
|
|
173
|
+
"msg": "Playground task completed successfully."
|
|
174
|
+
}
|
|
175
|
+
Failure Callback Example
|
|
176
|
+
{
|
|
177
|
+
"code": 501,
|
|
178
|
+
"data": {
|
|
179
|
+
"completeTime": 1755597081000,
|
|
180
|
+
"costTime": 0,
|
|
181
|
+
"createTime": 1755596341000,
|
|
182
|
+
"failCode": "500",
|
|
183
|
+
"failMsg": "Internal server error",
|
|
184
|
+
"model": "bytedance/v1-pro-image-to-video",
|
|
185
|
+
"param": "{\"callBackUrl\":\"https://your-domain.com/api/callback\",\"model\":\"bytedance/v1-pro-image-to-video\",\"input\":{\"prompt\":\"A golden retriever dashing through shallow surf at the beach, back angle camera low near waterline, splashes frozen in time, blur trails in waves and paws, afternoon sun glinting off wet fur, overcast day, dramatic clouds\",\"image_url\":\"https://file.aiquickdraw.com/custom-page/akr/section-images/1755179021328w1nhip18.webp\",\"resolution\":\"720p\",\"duration\":\"5\",\"camera_fixed\":false,\"seed\":-1,\"enable_safety_checker\":true}}",
|
|
186
|
+
"state": "fail",
|
|
187
|
+
"taskId": "bd3a37c523149e4adf45a3ddb5faf1a8",
|
|
188
|
+
"resultJson": null,
|
|
189
|
+
},
|
|
190
|
+
"msg": "Playground task failed."
|
|
191
|
+
}
|
|
192
|
+
Important Notes
|
|
193
|
+
The callback content structure is identical to the Query Task API response
|
|
194
|
+
The param field contains the complete Create Task request parameters, not just the input section
|
|
195
|
+
If callBackUrl is not provided, no callback notifications will be sent
|
|
196
|
+
|
|
197
|
+
GET
|
|
198
|
+
/api/v1/jobs/recordInfo
|
|
199
|
+
Query Task
|
|
200
|
+
Query task status and results by task ID
|
|
201
|
+
|
|
202
|
+
Request Example
|
|
203
|
+
|
|
204
|
+
cURL
|
|
205
|
+
|
|
206
|
+
JavaScript
|
|
207
|
+
|
|
208
|
+
Python
|
|
209
|
+
curl -X GET "https://api.kie.ai/api/v1/jobs/recordInfo?taskId=task_12345678" \
|
|
210
|
+
-H "Authorization: Bearer YOUR_API_KEY"
|
|
211
|
+
Response Example
|
|
212
|
+
{
|
|
213
|
+
"code": 200,
|
|
214
|
+
"message": "success",
|
|
215
|
+
"data": {
|
|
216
|
+
"taskId": "task_12345678",
|
|
217
|
+
"model": "bytedance/v1-pro-image-to-video",
|
|
218
|
+
"state": "success",
|
|
219
|
+
"param": "{\"model\":\"bytedance/v1-pro-image-to-video\",\"callBackUrl\":\"https://your-domain.com/api/callback\",\"input\":{\"prompt\":\"A golden retriever dashing through shallow surf at the beach, back angle camera low near waterline, splashes frozen in time, blur trails in waves and paws, afternoon sun glinting off wet fur, overcast day, dramatic clouds\",\"image_url\":\"https://file.aiquickdraw.com/custom-page/akr/section-images/1755179021328w1nhip18.webp\",\"resolution\":\"720p\",\"duration\":\"5\",\"camera_fixed\":false,\"seed\":-1,\"enable_safety_checker\":true}}",
|
|
220
|
+
"resultJson": "{\"resultUrls\":[\"https://example.com/generated-image.jpg\"]}",
|
|
221
|
+
"failCode": "",
|
|
222
|
+
"failMsg": "",
|
|
223
|
+
"costTime": 0,
|
|
224
|
+
"completeTime": 1698765432000,
|
|
225
|
+
"createTime": 1698765400000
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
Response Fields
|
|
229
|
+
code
|
|
230
|
+
Status code, 200 for success, others for failure
|
|
231
|
+
message
|
|
232
|
+
Response message, error description when failed
|
|
233
|
+
data.taskId
|
|
234
|
+
Task ID
|
|
235
|
+
data.model
|
|
236
|
+
Model used for generation
|
|
237
|
+
data.state
|
|
238
|
+
Generation state
|
|
239
|
+
data.param
|
|
240
|
+
Complete Create Task request parameters as JSON string (includes model, callBackUrl, input and all other parameters)
|
|
241
|
+
data.resultJson
|
|
242
|
+
Result JSON string containing generated media URLs
|
|
243
|
+
data.failCode
|
|
244
|
+
Error code (when generation failed)
|
|
245
|
+
data.failMsg
|
|
246
|
+
Error message (when generation failed)
|
|
247
|
+
data.completeTime
|
|
248
|
+
Completion timestamp
|
|
249
|
+
data.createTime
|
|
250
|
+
Creation timestamp
|
|
251
|
+
data.costTime
|
|
252
|
+
Cost time in milliseconds
|
|
253
|
+
State Values
|
|
254
|
+
waiting
|
|
255
|
+
Waiting for generation
|
|
256
|
+
queuing
|
|
257
|
+
In queue
|
|
258
|
+
generating
|
|
259
|
+
Generating
|
|
260
|
+
success
|
|
261
|
+
Generation successful
|
|
262
|
+
fail
|
|
263
|
+
Generation failed
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
example input
|
|
267
|
+
GET
|
|
268
|
+
/api/v1/jobs/recordInfo
|
|
269
|
+
Query Task
|
|
270
|
+
Query task status and results by task ID
|
|
271
|
+
|
|
272
|
+
Request Example
|
|
273
|
+
|
|
274
|
+
cURL
|
|
275
|
+
|
|
276
|
+
JavaScript
|
|
277
|
+
|
|
278
|
+
Python
|
|
279
|
+
curl -X GET "https://api.kie.ai/api/v1/jobs/recordInfo?taskId=task_12345678" \
|
|
280
|
+
-H "Authorization: Bearer YOUR_API_KEY"
|
|
281
|
+
Response Example
|
|
282
|
+
{
|
|
283
|
+
"code": 200,
|
|
284
|
+
"message": "success",
|
|
285
|
+
"data": {
|
|
286
|
+
"taskId": "task_12345678",
|
|
287
|
+
"model": "bytedance/v1-pro-image-to-video",
|
|
288
|
+
"state": "success",
|
|
289
|
+
"param": "{\"model\":\"bytedance/v1-pro-image-to-video\",\"callBackUrl\":\"https://your-domain.com/api/callback\",\"input\":{\"prompt\":\"A golden retriever dashing through shallow surf at the beach, back angle camera low near waterline, splashes frozen in time, blur trails in waves and paws, afternoon sun glinting off wet fur, overcast day, dramatic clouds\",\"image_url\":\"https://file.aiquickdraw.com/custom-page/akr/section-images/1755179021328w1nhip18.webp\",\"resolution\":\"720p\",\"duration\":\"5\",\"camera_fixed\":false,\"seed\":-1,\"enable_safety_checker\":true}}",
|
|
290
|
+
"resultJson": "{\"resultUrls\":[\"https://example.com/generated-image.jpg\"]}",
|
|
291
|
+
"failCode": "",
|
|
292
|
+
"failMsg": "",
|
|
293
|
+
"costTime": 0,
|
|
294
|
+
"completeTime": 1698765432000,
|
|
295
|
+
"createTime": 1698765400000
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
Response Fields
|
|
299
|
+
code
|
|
300
|
+
Status code, 200 for success, others for failure
|
|
301
|
+
message
|
|
302
|
+
Response message, error description when failed
|
|
303
|
+
data.taskId
|
|
304
|
+
Task ID
|
|
305
|
+
data.model
|
|
306
|
+
Model used for generation
|
|
307
|
+
data.state
|
|
308
|
+
Generation state
|
|
309
|
+
data.param
|
|
310
|
+
Complete Create Task request parameters as JSON string (includes model, callBackUrl, input and all other parameters)
|
|
311
|
+
data.resultJson
|
|
312
|
+
Result JSON string containing generated media URLs
|
|
313
|
+
data.failCode
|
|
314
|
+
Error code (when generation failed)
|
|
315
|
+
data.failMsg
|
|
316
|
+
Error message (when generation failed)
|
|
317
|
+
data.completeTime
|
|
318
|
+
Completion timestamp
|
|
319
|
+
data.createTime
|
|
320
|
+
Creation timestamp
|
|
321
|
+
data.costTime
|
|
322
|
+
Cost time in milliseconds
|
|
323
|
+
State Values
|
|
324
|
+
waiting
|
|
325
|
+
Waiting for generation
|
|
326
|
+
queuing
|
|
327
|
+
In queue
|
|
328
|
+
generating
|
|
329
|
+
Generating
|
|
330
|
+
success
|
|
331
|
+
Generation successful
|
|
332
|
+
fail
|
|
333
|
+
Generation failed
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
ouput
|
|
337
|
+
{
|
|
338
|
+
"resultUrls": [
|
|
339
|
+
"https://file.aiquickdraw.com/custom-page/akr/section-images/17551796948046brblmi1.mp4"
|
|
340
|
+
]
|
|
341
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
curl -X 'POST' \
|
|
2
|
+
'https://api.styai.app/api/v1/media/remove-background' \
|
|
3
|
+
-H 'accept: application/json' \
|
|
4
|
+
-H 'X-API-Key: YOUR_STY_AI_API_KEY' \
|
|
5
|
+
-H 'Content-Type: multipart/form-data' \
|
|
6
|
+
-F 'file=@intro-step1.png;type=image/png' \
|
|
7
|
+
-F 'cropToForeground=false' \
|
|
8
|
+
-F 'targetSize=1024 768' \
|
|
9
|
+
-F 'outputFormat=png'
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
output
|
|
13
|
+
{
|
|
14
|
+
buffer: "base64",
|
|
15
|
+
contentType: "image/png",
|
|
16
|
+
size: 300000,
|
|
17
|
+
processingTime: 1000,
|
|
18
|
+
sucess: true
|
|
19
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared background removal via Sty AI API.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { writeFile, readFile } from "fs/promises";
|
|
6
|
+
import { resolve, dirname, join } from "path";
|
|
7
|
+
import { fileURLToPath } from "url";
|
|
8
|
+
import { log } from "./kie-client.mjs";
|
|
9
|
+
|
|
10
|
+
const __lib = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
const OUTPUT_BASE = resolve(join(__lib, "..", "output"));
|
|
12
|
+
|
|
13
|
+
function assertSafePath(p, base) {
|
|
14
|
+
const resolved = resolve(p);
|
|
15
|
+
if (!resolved.startsWith(base)) {
|
|
16
|
+
throw new Error(`Path traversal blocked: ${p} escapes ${base}`);
|
|
17
|
+
}
|
|
18
|
+
return resolved;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export async function removeBackground(inputPath, outputPath) {
|
|
22
|
+
const safeOutput = assertSafePath(outputPath, OUTPUT_BASE);
|
|
23
|
+
|
|
24
|
+
const apiKey = process.env.STY_AI_API_KEY;
|
|
25
|
+
if (!apiKey) {
|
|
26
|
+
throw new Error("STY_AI_API_KEY environment variable is not set");
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const fileBuffer = await readFile(inputPath);
|
|
30
|
+
const blob = new Blob([fileBuffer], { type: "image/png" });
|
|
31
|
+
|
|
32
|
+
const formData = new FormData();
|
|
33
|
+
formData.append("file", blob, "image.png");
|
|
34
|
+
formData.append("cropToForeground", "true");
|
|
35
|
+
formData.append("outputFormat", "png");
|
|
36
|
+
|
|
37
|
+
const res = await fetch("https://api.styai.app/api/v1/media/remove-background", {
|
|
38
|
+
method: "POST",
|
|
39
|
+
headers: {
|
|
40
|
+
accept: "application/json",
|
|
41
|
+
"X-API-Key": apiKey,
|
|
42
|
+
},
|
|
43
|
+
body: formData,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const json = await res.json();
|
|
47
|
+
if (!json.sucess && !json.success) {
|
|
48
|
+
throw new Error("Background removal failed");
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const buffer = Buffer.from(json.buffer, "base64");
|
|
52
|
+
await writeFile(safeOutput, buffer);
|
|
53
|
+
log(` [bg-removed] ${safeOutput}`);
|
|
54
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared .env loader for ai-asset-generator scripts.
|
|
3
|
+
*
|
|
4
|
+
* Search order:
|
|
5
|
+
* 1. Project root (skills/) — the single source of truth for all env vars
|
|
6
|
+
* 2. ai-asset-generator/ dir — legacy fallback
|
|
7
|
+
* 3. Monorepo root (skills/../../) — fallback for monorepo setups
|
|
8
|
+
*
|
|
9
|
+
* Files checked: .env, .env.local (values from earlier files win).
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { readFile } from "fs/promises";
|
|
13
|
+
import { join, dirname } from "path";
|
|
14
|
+
import { fileURLToPath } from "url";
|
|
15
|
+
|
|
16
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
17
|
+
const GENERATOR_DIR = join(__dirname, "..");
|
|
18
|
+
const PROJECT_ROOT = join(__dirname, "..", "..", ".."); // skills/
|
|
19
|
+
const MONOREPO_ROOT = join(__dirname, "..", "..", "..", ".."); // one above skills/
|
|
20
|
+
|
|
21
|
+
export async function loadEnv() {
|
|
22
|
+
const searchPaths = [PROJECT_ROOT, GENERATOR_DIR, MONOREPO_ROOT];
|
|
23
|
+
const envFiles = [".env", ".env.local"];
|
|
24
|
+
|
|
25
|
+
for (const dir of searchPaths) {
|
|
26
|
+
for (const envFile of envFiles) {
|
|
27
|
+
try {
|
|
28
|
+
const raw = await readFile(join(dir, envFile), "utf8");
|
|
29
|
+
let loaded = 0;
|
|
30
|
+
for (const line of raw.split("\n")) {
|
|
31
|
+
const trimmed = line.trim();
|
|
32
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
33
|
+
const eq = trimmed.indexOf("=");
|
|
34
|
+
if (eq === -1) continue;
|
|
35
|
+
const key = trimmed.slice(0, eq).trim();
|
|
36
|
+
const val = trimmed.slice(eq + 1).trim();
|
|
37
|
+
if (!process.env[key]) {
|
|
38
|
+
process.env[key] = val;
|
|
39
|
+
loaded++;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (loaded > 0) console.log(` [env] Loaded ${loaded} vars from ${dir}/${envFile}`);
|
|
43
|
+
} catch {
|
|
44
|
+
// File doesn't exist, continue
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared KIE AI API client.
|
|
3
|
+
*
|
|
4
|
+
* Provides: createTask, queryTask, pollUntilDone, downloadFile
|
|
5
|
+
* All scripts use the same API base and auth pattern.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { writeFile, mkdir } from "fs/promises";
|
|
9
|
+
import { existsSync } from "fs";
|
|
10
|
+
import { dirname, join, resolve } from "path";
|
|
11
|
+
import { fileURLToPath } from "url";
|
|
12
|
+
|
|
13
|
+
const __lib = dirname(fileURLToPath(import.meta.url));
|
|
14
|
+
const SKILL_DIR = join(__lib, "..");
|
|
15
|
+
|
|
16
|
+
// ─── Helpers ────────────────────────────────────────────────
|
|
17
|
+
export const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
18
|
+
export const log = (msg) => console.log(msg);
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Default output directory: ai-asset-generator/output/<name>/
|
|
22
|
+
* Each generator gets its own subfolder under the skill's output/ dir.
|
|
23
|
+
*/
|
|
24
|
+
export function outputDir(name) {
|
|
25
|
+
return join(SKILL_DIR, "output", name);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// ─── API Client ─────────────────────────────────────────────
|
|
29
|
+
const API = "https://api.kie.ai/api/v1/jobs";
|
|
30
|
+
|
|
31
|
+
function headers() {
|
|
32
|
+
return {
|
|
33
|
+
"Content-Type": "application/json",
|
|
34
|
+
Authorization: `Bearer ${process.env.KIE_AI_API_KEY}`,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export async function createTask(payload) {
|
|
39
|
+
const res = await fetch(`${API}/createTask`, {
|
|
40
|
+
method: "POST",
|
|
41
|
+
headers: headers(),
|
|
42
|
+
body: JSON.stringify(payload),
|
|
43
|
+
});
|
|
44
|
+
const json = await res.json();
|
|
45
|
+
if (json.code !== 200) {
|
|
46
|
+
throw new Error(`createTask failed (${json.code}): ${json.message}`);
|
|
47
|
+
}
|
|
48
|
+
return json.data.taskId;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export async function queryTask(taskId) {
|
|
52
|
+
const res = await fetch(`${API}/recordInfo?taskId=${taskId}`, {
|
|
53
|
+
headers: { Authorization: `Bearer ${process.env.KIE_AI_API_KEY}` },
|
|
54
|
+
});
|
|
55
|
+
const json = await res.json();
|
|
56
|
+
if (json.code !== 200) {
|
|
57
|
+
throw new Error(`queryTask failed (${json.code}): ${json.message}`);
|
|
58
|
+
}
|
|
59
|
+
return json.data;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Poll a task until it reaches success/fail.
|
|
64
|
+
* Uses increasing delay: 5s → 8s → 12s → … capped at 30s.
|
|
65
|
+
*/
|
|
66
|
+
export async function pollUntilDone(taskId, label, timeoutMs = 300_000) {
|
|
67
|
+
const t0 = Date.now();
|
|
68
|
+
let delay = 5_000;
|
|
69
|
+
|
|
70
|
+
while (Date.now() - t0 < timeoutMs) {
|
|
71
|
+
const task = await queryTask(taskId);
|
|
72
|
+
|
|
73
|
+
if (task.state === "success") {
|
|
74
|
+
const urls = JSON.parse(task.resultJson).resultUrls;
|
|
75
|
+
log(` [done] ${label}`);
|
|
76
|
+
return urls[0];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (task.state === "fail") {
|
|
80
|
+
throw new Error(`${label} failed: ${task.failMsg || "unknown"}`);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const elapsed = Math.round((Date.now() - t0) / 1000);
|
|
84
|
+
log(` [${task.state}] ${label} (${elapsed}s, next poll in ${Math.round(delay / 1000)}s)`);
|
|
85
|
+
await sleep(delay);
|
|
86
|
+
delay = Math.min(Math.round(delay * 1.5), 30_000);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
throw new Error(`${label} timed out after ${timeoutMs / 1000}s`);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export async function downloadFile(url, dest) {
|
|
93
|
+
const parsed = new URL(url);
|
|
94
|
+
if (!['https:'].includes(parsed.protocol)) {
|
|
95
|
+
throw new Error(`Disallowed URL scheme: ${parsed.protocol}`);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const safeDest = resolve(dest);
|
|
99
|
+
const safeBase = resolve(join(SKILL_DIR, "output"));
|
|
100
|
+
if (!safeDest.startsWith(safeBase)) {
|
|
101
|
+
throw new Error(`Path traversal blocked: ${dest} escapes output directory`);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const dir = dirname(safeDest);
|
|
105
|
+
if (!existsSync(dir)) await mkdir(dir, { recursive: true });
|
|
106
|
+
const res = await fetch(url);
|
|
107
|
+
if (!res.ok) throw new Error(`Download failed: ${res.status} ${url}`);
|
|
108
|
+
const buf = Buffer.from(await res.arrayBuffer());
|
|
109
|
+
await writeFile(safeDest, buf);
|
|
110
|
+
log(` [saved] ${safeDest}`);
|
|
111
|
+
}
|
|
Binary file
|