@unityclaw/skills 1.0.3 → 1.0.5

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.
@@ -1,9 +1,11 @@
1
1
  // src/index.ts
2
- import { spawn } from "child_process";
2
+ import { spawn, execSync } from "child_process";
3
3
  import { cp, mkdir, readdir, readFile } from "fs/promises";
4
- import { existsSync, readdirSync } from "fs";
4
+ import { existsSync, readdirSync, readFileSync, writeFileSync, mkdirSync } from "fs";
5
5
  import path from "path";
6
6
  import { fileURLToPath } from "url";
7
+ import * as os from "os";
8
+ import * as readline from "readline";
7
9
  function getSkillsDir() {
8
10
  const hasSkillDirs = (dir) => {
9
11
  try {
@@ -108,6 +110,57 @@ function getOpenClawSkillsDir() {
108
110
  const homeDir = process.env.HOME || process.env.USERPROFILE || "";
109
111
  return process.env.OPENCLAW_SKILLS_DIR || path.join(homeDir, ".openclaw", "skills");
110
112
  }
113
+ async function promptForApiKey() {
114
+ const rl = readline.createInterface({
115
+ input: process.stdin,
116
+ output: process.stdout
117
+ });
118
+ return new Promise((resolve) => {
119
+ rl.question("\nEnter your UnityClaw API key (or press Enter to skip): ", (answer) => {
120
+ rl.close();
121
+ resolve(answer.trim() || void 0);
122
+ });
123
+ });
124
+ }
125
+ function updateOpenClawEnvConfig(apiKey) {
126
+ const openclawDir = path.join(os.homedir(), ".openclaw");
127
+ const openclawPath = path.join(openclawDir, "openclaw.json");
128
+ let config = {};
129
+ if (existsSync(openclawPath)) {
130
+ try {
131
+ config = JSON.parse(readFileSync(openclawPath, "utf-8"));
132
+ } catch {
133
+ config = {};
134
+ }
135
+ }
136
+ if (!config.env) config.env = {};
137
+ const env = config.env;
138
+ if (!env.vars) env.vars = {};
139
+ env.vars.UNITYCLAW_API_KEY = apiKey;
140
+ if (!existsSync(openclawDir)) {
141
+ mkdirSync(openclawDir, { recursive: true });
142
+ }
143
+ writeFileSync(openclawPath, JSON.stringify(config, null, 2), "utf-8");
144
+ }
145
+ function hasExistingApiKey() {
146
+ const sdkConfigPath = path.join(os.homedir(), ".unityclaw", "config.json");
147
+ if (existsSync(sdkConfigPath)) {
148
+ try {
149
+ const config = JSON.parse(readFileSync(sdkConfigPath, "utf-8"));
150
+ if (config?.apiKey) return true;
151
+ } catch {
152
+ }
153
+ }
154
+ const openclawPath = path.join(os.homedir(), ".openclaw", "openclaw.json");
155
+ if (existsSync(openclawPath)) {
156
+ try {
157
+ const config = JSON.parse(readFileSync(openclawPath, "utf-8"));
158
+ if (config?.env?.vars?.UNITYCLAW_API_KEY) return true;
159
+ } catch {
160
+ }
161
+ }
162
+ return false;
163
+ }
111
164
  async function installSkills(target, skills) {
112
165
  const targetDir = target === "claude" ? getClaudeSkillsDir() : getOpenClawSkillsDir();
113
166
  const skillsDir = getSkillsDir();
@@ -137,6 +190,41 @@ Installing ${skillsToInstall.length} skill(s):
137
190
  }
138
191
  console.log(`
139
192
  \u2728 Done! Skills installed to: ${targetDir}`);
193
+ console.log("target", target);
194
+ console.log("hasExistingApiKey", hasExistingApiKey());
195
+ if (target === "openclaw" && !hasExistingApiKey()) {
196
+ console.log("\n\u{1F527} Configuration:");
197
+ console.log(" UnityClaw API key not found.\n");
198
+ const apiKey = await promptForApiKey();
199
+ if (apiKey) {
200
+ try {
201
+ execSync(`npx @unityclaw/sdk config set apiKey ${apiKey}`, { stdio: "pipe" });
202
+ } catch {
203
+ const configDir = path.join(os.homedir(), ".unityclaw");
204
+ const configPath = path.join(configDir, "config.json");
205
+ let config = {};
206
+ if (existsSync(configPath)) {
207
+ try {
208
+ config = JSON.parse(readFileSync(configPath, "utf-8"));
209
+ } catch {
210
+ config = {};
211
+ }
212
+ }
213
+ config.apiKey = apiKey;
214
+ if (!existsSync(configDir)) {
215
+ mkdirSync(configDir, { recursive: true });
216
+ }
217
+ writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
218
+ }
219
+ updateOpenClawEnvConfig(apiKey);
220
+ console.log("\n \u2705 API key saved to:");
221
+ console.log(" - ~/.openclaw/openclaw.json");
222
+ console.log("\n Get your API key at: https://unityclaw.com");
223
+ } else {
224
+ console.log("\n \u26A0\uFE0F Skipped. Configure later with:");
225
+ console.log(" npx @unityclaw/sdk config set apiKey <your-key>");
226
+ }
227
+ }
140
228
  }
141
229
  async function executeSkill(skillCommand) {
142
230
  const args = [
package/dist/cli.cjs CHANGED
@@ -33,6 +33,8 @@ var import_promises = require("fs/promises");
33
33
  var import_fs = require("fs");
34
34
  var import_path = __toESM(require("path"), 1);
35
35
  var import_url = require("url");
36
+ var os = __toESM(require("os"), 1);
37
+ var readline = __toESM(require("readline"), 1);
36
38
  var import_meta = {};
37
39
  function getSkillsDir() {
38
40
  const hasSkillDirs = (dir) => {
@@ -138,6 +140,57 @@ function getOpenClawSkillsDir() {
138
140
  const homeDir = process.env.HOME || process.env.USERPROFILE || "";
139
141
  return process.env.OPENCLAW_SKILLS_DIR || import_path.default.join(homeDir, ".openclaw", "skills");
140
142
  }
143
+ async function promptForApiKey() {
144
+ const rl = readline.createInterface({
145
+ input: process.stdin,
146
+ output: process.stdout
147
+ });
148
+ return new Promise((resolve) => {
149
+ rl.question("\nEnter your UnityClaw API key (or press Enter to skip): ", (answer) => {
150
+ rl.close();
151
+ resolve(answer.trim() || void 0);
152
+ });
153
+ });
154
+ }
155
+ function updateOpenClawEnvConfig(apiKey) {
156
+ const openclawDir = import_path.default.join(os.homedir(), ".openclaw");
157
+ const openclawPath = import_path.default.join(openclawDir, "openclaw.json");
158
+ let config = {};
159
+ if ((0, import_fs.existsSync)(openclawPath)) {
160
+ try {
161
+ config = JSON.parse((0, import_fs.readFileSync)(openclawPath, "utf-8"));
162
+ } catch {
163
+ config = {};
164
+ }
165
+ }
166
+ if (!config.env) config.env = {};
167
+ const env = config.env;
168
+ if (!env.vars) env.vars = {};
169
+ env.vars.UNITYCLAW_API_KEY = apiKey;
170
+ if (!(0, import_fs.existsSync)(openclawDir)) {
171
+ (0, import_fs.mkdirSync)(openclawDir, { recursive: true });
172
+ }
173
+ (0, import_fs.writeFileSync)(openclawPath, JSON.stringify(config, null, 2), "utf-8");
174
+ }
175
+ function hasExistingApiKey() {
176
+ const sdkConfigPath = import_path.default.join(os.homedir(), ".unityclaw", "config.json");
177
+ if ((0, import_fs.existsSync)(sdkConfigPath)) {
178
+ try {
179
+ const config = JSON.parse((0, import_fs.readFileSync)(sdkConfigPath, "utf-8"));
180
+ if (config?.apiKey) return true;
181
+ } catch {
182
+ }
183
+ }
184
+ const openclawPath = import_path.default.join(os.homedir(), ".openclaw", "openclaw.json");
185
+ if ((0, import_fs.existsSync)(openclawPath)) {
186
+ try {
187
+ const config = JSON.parse((0, import_fs.readFileSync)(openclawPath, "utf-8"));
188
+ if (config?.env?.vars?.UNITYCLAW_API_KEY) return true;
189
+ } catch {
190
+ }
191
+ }
192
+ return false;
193
+ }
141
194
  async function installSkills(target, skills) {
142
195
  const targetDir = target === "claude" ? getClaudeSkillsDir() : getOpenClawSkillsDir();
143
196
  const skillsDir = getSkillsDir();
@@ -167,6 +220,41 @@ Installing ${skillsToInstall.length} skill(s):
167
220
  }
168
221
  console.log(`
169
222
  \u2728 Done! Skills installed to: ${targetDir}`);
223
+ console.log("target", target);
224
+ console.log("hasExistingApiKey", hasExistingApiKey());
225
+ if (target === "openclaw" && !hasExistingApiKey()) {
226
+ console.log("\n\u{1F527} Configuration:");
227
+ console.log(" UnityClaw API key not found.\n");
228
+ const apiKey = await promptForApiKey();
229
+ if (apiKey) {
230
+ try {
231
+ (0, import_child_process.execSync)(`npx @unityclaw/sdk config set apiKey ${apiKey}`, { stdio: "pipe" });
232
+ } catch {
233
+ const configDir = import_path.default.join(os.homedir(), ".unityclaw");
234
+ const configPath = import_path.default.join(configDir, "config.json");
235
+ let config = {};
236
+ if ((0, import_fs.existsSync)(configPath)) {
237
+ try {
238
+ config = JSON.parse((0, import_fs.readFileSync)(configPath, "utf-8"));
239
+ } catch {
240
+ config = {};
241
+ }
242
+ }
243
+ config.apiKey = apiKey;
244
+ if (!(0, import_fs.existsSync)(configDir)) {
245
+ (0, import_fs.mkdirSync)(configDir, { recursive: true });
246
+ }
247
+ (0, import_fs.writeFileSync)(configPath, JSON.stringify(config, null, 2), "utf-8");
248
+ }
249
+ updateOpenClawEnvConfig(apiKey);
250
+ console.log("\n \u2705 API key saved to:");
251
+ console.log(" - ~/.openclaw/openclaw.json");
252
+ console.log("\n Get your API key at: https://unityclaw.com");
253
+ } else {
254
+ console.log("\n \u26A0\uFE0F Skipped. Configure later with:");
255
+ console.log(" npx @unityclaw/sdk config set apiKey <your-key>");
256
+ }
257
+ }
170
258
  }
171
259
  async function executeSkill(skillCommand) {
172
260
  const args2 = [
package/dist/cli.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  executeSkill,
4
4
  installSkills,
5
5
  listSkills
6
- } from "./chunk-FAGVVFFQ.js";
6
+ } from "./chunk-VTGLNHDK.js";
7
7
 
8
8
  // src/cli.ts
9
9
  import { program } from "commander";
package/dist/index.cjs CHANGED
@@ -44,6 +44,8 @@ var import_promises = require("fs/promises");
44
44
  var import_fs = require("fs");
45
45
  var import_path = __toESM(require("path"), 1);
46
46
  var import_url = require("url");
47
+ var os = __toESM(require("os"), 1);
48
+ var readline = __toESM(require("readline"), 1);
47
49
  var import_meta = {};
48
50
  function getSkillsDir() {
49
51
  const hasSkillDirs = (dir) => {
@@ -149,6 +151,57 @@ function getOpenClawSkillsDir() {
149
151
  const homeDir = process.env.HOME || process.env.USERPROFILE || "";
150
152
  return process.env.OPENCLAW_SKILLS_DIR || import_path.default.join(homeDir, ".openclaw", "skills");
151
153
  }
154
+ async function promptForApiKey() {
155
+ const rl = readline.createInterface({
156
+ input: process.stdin,
157
+ output: process.stdout
158
+ });
159
+ return new Promise((resolve) => {
160
+ rl.question("\nEnter your UnityClaw API key (or press Enter to skip): ", (answer) => {
161
+ rl.close();
162
+ resolve(answer.trim() || void 0);
163
+ });
164
+ });
165
+ }
166
+ function updateOpenClawEnvConfig(apiKey) {
167
+ const openclawDir = import_path.default.join(os.homedir(), ".openclaw");
168
+ const openclawPath = import_path.default.join(openclawDir, "openclaw.json");
169
+ let config = {};
170
+ if ((0, import_fs.existsSync)(openclawPath)) {
171
+ try {
172
+ config = JSON.parse((0, import_fs.readFileSync)(openclawPath, "utf-8"));
173
+ } catch {
174
+ config = {};
175
+ }
176
+ }
177
+ if (!config.env) config.env = {};
178
+ const env = config.env;
179
+ if (!env.vars) env.vars = {};
180
+ env.vars.UNITYCLAW_API_KEY = apiKey;
181
+ if (!(0, import_fs.existsSync)(openclawDir)) {
182
+ (0, import_fs.mkdirSync)(openclawDir, { recursive: true });
183
+ }
184
+ (0, import_fs.writeFileSync)(openclawPath, JSON.stringify(config, null, 2), "utf-8");
185
+ }
186
+ function hasExistingApiKey() {
187
+ const sdkConfigPath = import_path.default.join(os.homedir(), ".unityclaw", "config.json");
188
+ if ((0, import_fs.existsSync)(sdkConfigPath)) {
189
+ try {
190
+ const config = JSON.parse((0, import_fs.readFileSync)(sdkConfigPath, "utf-8"));
191
+ if (config?.apiKey) return true;
192
+ } catch {
193
+ }
194
+ }
195
+ const openclawPath = import_path.default.join(os.homedir(), ".openclaw", "openclaw.json");
196
+ if ((0, import_fs.existsSync)(openclawPath)) {
197
+ try {
198
+ const config = JSON.parse((0, import_fs.readFileSync)(openclawPath, "utf-8"));
199
+ if (config?.env?.vars?.UNITYCLAW_API_KEY) return true;
200
+ } catch {
201
+ }
202
+ }
203
+ return false;
204
+ }
152
205
  async function installSkills(target, skills) {
153
206
  const targetDir = target === "claude" ? getClaudeSkillsDir() : getOpenClawSkillsDir();
154
207
  const skillsDir = getSkillsDir();
@@ -178,6 +231,41 @@ Installing ${skillsToInstall.length} skill(s):
178
231
  }
179
232
  console.log(`
180
233
  \u2728 Done! Skills installed to: ${targetDir}`);
234
+ console.log("target", target);
235
+ console.log("hasExistingApiKey", hasExistingApiKey());
236
+ if (target === "openclaw" && !hasExistingApiKey()) {
237
+ console.log("\n\u{1F527} Configuration:");
238
+ console.log(" UnityClaw API key not found.\n");
239
+ const apiKey = await promptForApiKey();
240
+ if (apiKey) {
241
+ try {
242
+ (0, import_child_process.execSync)(`npx @unityclaw/sdk config set apiKey ${apiKey}`, { stdio: "pipe" });
243
+ } catch {
244
+ const configDir = import_path.default.join(os.homedir(), ".unityclaw");
245
+ const configPath = import_path.default.join(configDir, "config.json");
246
+ let config = {};
247
+ if ((0, import_fs.existsSync)(configPath)) {
248
+ try {
249
+ config = JSON.parse((0, import_fs.readFileSync)(configPath, "utf-8"));
250
+ } catch {
251
+ config = {};
252
+ }
253
+ }
254
+ config.apiKey = apiKey;
255
+ if (!(0, import_fs.existsSync)(configDir)) {
256
+ (0, import_fs.mkdirSync)(configDir, { recursive: true });
257
+ }
258
+ (0, import_fs.writeFileSync)(configPath, JSON.stringify(config, null, 2), "utf-8");
259
+ }
260
+ updateOpenClawEnvConfig(apiKey);
261
+ console.log("\n \u2705 API key saved to:");
262
+ console.log(" - ~/.openclaw/openclaw.json");
263
+ console.log("\n Get your API key at: https://unityclaw.com");
264
+ } else {
265
+ console.log("\n \u26A0\uFE0F Skipped. Configure later with:");
266
+ console.log(" npx @unityclaw/sdk config set apiKey <your-key>");
267
+ }
268
+ }
181
269
  }
182
270
  async function executeSkill(skillCommand) {
183
271
  const args = [
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  installSkills,
7
7
  listSkills,
8
8
  parseSkill
9
- } from "./chunk-FAGVVFFQ.js";
9
+ } from "./chunk-VTGLNHDK.js";
10
10
  export {
11
11
  executeSkill,
12
12
  getClaudeSkillsDir,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unityclaw/skills",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "UnityClaw Skills - Claude Code and OpenClaw skill definitions for AI-powered image/video generation, media analysis, and more",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: unityclaw-document-convert
3
3
  description: Convert documents between formats (PDF, Word, PPT, Excel, Image)
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  metadata:
6
6
  openclaw:
7
7
  requires:
@@ -41,6 +41,29 @@ npx @unityclaw/sdk config set apiKey your-api-key
41
41
  export UNITYCLAW_API_KEY=your-api-key
42
42
  ```
43
43
 
44
+ ## Response Structure
45
+
46
+ > **IMPORTANT:** The result has a nested structure. Use `result.success` to check overall success, and access data via `result.response.data`.
47
+
48
+ ```typescript
49
+ interface UnityClawResult {
50
+ success: boolean; // ✅ Use this to check if SDK call succeeded
51
+ taskId: string; // Task identifier
52
+ taskFolder: string; // Path to task folder with logs
53
+ duration: number; // Request duration in ms
54
+ response: { // API response object
55
+ code: number; // 0 = success
56
+ data: Array<{ // ✅ Result data here
57
+ name: string;
58
+ contentType: string;
59
+ content: string; // URL to converted document
60
+ }> | null;
61
+ };
62
+ logs: Array<{ timestamp; level; message }>;
63
+ attachments: any[];
64
+ }
65
+ ```
66
+
44
67
  ## Quick Start
45
68
 
46
69
  ```typescript
@@ -55,8 +78,9 @@ const result = await client.document.pdf2Word({
55
78
  ]
56
79
  });
57
80
 
58
- if (result.code === 0) {
59
- console.log('Converted document:', result.data);
81
+ // ✅ Correct: Check result.success, access data via result.response.data
82
+ if (result.success && result.response?.data) {
83
+ console.log('Converted document:', result.response.data);
60
84
  }
61
85
  ```
62
86
 
@@ -175,8 +199,8 @@ const result = await client.document.pdf2Word({
175
199
  ]
176
200
  });
177
201
 
178
- if (result.code === 0 && result.data) {
179
- console.log('Word document:', result.data[0].content);
202
+ if (result.success && result.response?.data) {
203
+ console.log('Word document:', result.response.data[0].content);
180
204
  }
181
205
  ```
182
206
 
@@ -210,8 +234,8 @@ const result = await client.document.pdf2Image({
210
234
  });
211
235
 
212
236
  // Returns array of images (one per page)
213
- if (result.code === 0 && result.data) {
214
- result.data.forEach((img, i) => {
237
+ if (result.success && result.response?.data) {
238
+ result.response.data.forEach((img, i) => {
215
239
  console.log(`Page ${i + 1}: ${img.content}`);
216
240
  });
217
241
  }
@@ -290,8 +314,8 @@ const results = await Promise.all(
290
314
  );
291
315
 
292
316
  results.forEach((result, i) => {
293
- if (result.code === 0) {
294
- console.log(`File ${i + 1} converted: ${result.data?.[0]?.content}`);
317
+ if (result.success && result.response?.data) {
318
+ console.log(`File ${i + 1} converted: ${result.response.data?.[0]?.content}`);
295
319
  }
296
320
  });
297
321
  ```
@@ -304,14 +328,14 @@ const converted = await client.document.image2Word({
304
328
  attachment: [{ tmp_url: 'https://...', name: 'image.jpg' }]
305
329
  });
306
330
 
307
- if (converted.code === 0 && converted.data) {
331
+ if (converted.success && converted.response?.data) {
308
332
  const translated = await client.document.translate({
309
- attachment: converted.data,
333
+ attachment: converted.response.data,
310
334
  source_language: 'en',
311
335
  target_language: 'zh'
312
336
  });
313
337
 
314
- console.log('Translated document:', translated.data);
338
+ console.log('Translated document:', translated.response?.data);
315
339
  }
316
340
  ```
317
341
 
@@ -332,11 +356,19 @@ const result = await client.document.pdf2Word({
332
356
  attachment: [{ tmp_url: 'https://...', name: 'doc.pdf' }]
333
357
  });
334
358
 
335
- if (result.code !== 0) {
336
- console.error('Conversion failed:', result.msg);
337
- } else {
338
- console.log('Success:', result.data);
359
+ if (!result.success) {
360
+ console.error('Request failed');
361
+ console.log('Check logs:', result.logs);
362
+ return;
363
+ }
364
+
365
+ if (result.response?.code !== 0) {
366
+ console.error('API error:', result.response);
367
+ return;
339
368
  }
369
+
370
+ // Success
371
+ console.log('Success:', result.response.data);
340
372
  ```
341
373
 
342
374
  ## Task Folders
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: unityclaw-document-translation
3
3
  description: Translate documents between multiple languages while preserving formatting
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  metadata:
6
6
  openclaw:
7
7
  requires:
@@ -41,6 +41,29 @@ npx @unityclaw/sdk config set apiKey your-api-key
41
41
  export UNITYCLAW_API_KEY=your-api-key
42
42
  ```
43
43
 
44
+ ## Response Structure
45
+
46
+ > **IMPORTANT:** The result has a nested structure. Use `result.success` to check overall success, and access data via `result.response.data`.
47
+
48
+ ```typescript
49
+ interface UnityClawResult {
50
+ success: boolean; // ✅ Use this to check if SDK call succeeded
51
+ taskId: string; // Task identifier
52
+ taskFolder: string; // Path to task folder with logs
53
+ duration: number; // Request duration in ms
54
+ response: { // API response object
55
+ code: number; // 0 = success
56
+ data: Array<{ // ✅ Result data here
57
+ name: string;
58
+ contentType: string;
59
+ content: string; // URL to translated document
60
+ }> | null;
61
+ };
62
+ logs: Array<{ timestamp; level; message }>;
63
+ attachments: any[];
64
+ }
65
+ ```
66
+
44
67
  ## Quick Start
45
68
 
46
69
  ```typescript
@@ -56,8 +79,9 @@ const result = await client.document.translate({
56
79
  target_language: { value: 'zh', label: 'Chinese' }
57
80
  });
58
81
 
59
- if (result.code === 0) {
60
- console.log('Translated document:', result.data);
82
+ // ✅ Correct: Check result.success, access data via result.response.data
83
+ if (result.success && result.response?.data) {
84
+ console.log('Translated document:', result.response.data);
61
85
  }
62
86
  ```
63
87
 
@@ -130,8 +154,8 @@ const result = await client.document.translate({
130
154
  target_language: { value: 'zh', label: 'Chinese' }
131
155
  });
132
156
 
133
- if (result.code === 0 && result.data) {
134
- console.log('Translated PDF:', result.data[0].content);
157
+ if (result.success && result.response?.data) {
158
+ console.log('Translated PDF:', result.response.data[0].content);
135
159
  }
136
160
  ```
137
161
 
@@ -175,8 +199,8 @@ const result = await client.document.translate({
175
199
  target_language: { value: 'zh', label: 'Chinese' }
176
200
  });
177
201
 
178
- if (result.code === 0 && result.data) {
179
- result.data.forEach((doc, i) => {
202
+ if (result.success && result.response?.data) {
203
+ result.response.data.forEach((doc, i) => {
180
204
  console.log(`Document ${i + 1}: ${doc.content}`);
181
205
  });
182
206
  }
@@ -241,11 +265,19 @@ const result = await client.document.translate({
241
265
  target_language: 'zh'
242
266
  });
243
267
 
244
- if (result.code !== 0) {
245
- console.error('Translation failed:', result.msg);
246
- } else {
247
- console.log('Success:', result.data);
268
+ if (!result.success) {
269
+ console.error('Request failed');
270
+ console.log('Check logs:', result.logs);
271
+ return;
272
+ }
273
+
274
+ if (result.response?.code !== 0) {
275
+ console.error('API error:', result.response);
276
+ return;
248
277
  }
278
+
279
+ // Success
280
+ console.log('Success:', result.response.data);
249
281
  ```
250
282
 
251
283
  ## Task Folders
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: unityclaw-image-compress
3
3
  description: Compress images with quality control to reduce file size
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  metadata:
6
6
  openclaw:
7
7
  requires:
@@ -41,6 +41,29 @@ npx @unityclaw/sdk config set apiKey your-api-key
41
41
  export UNITYCLAW_API_KEY=your-api-key
42
42
  ```
43
43
 
44
+ ## Response Structure
45
+
46
+ > **IMPORTANT:** The result has a nested structure. Use `result.success` to check overall success, and access data via `result.response.data`.
47
+
48
+ ```typescript
49
+ interface UnityClawResult {
50
+ success: boolean; // ✅ Use this to check if SDK call succeeded
51
+ taskId: string; // Task identifier
52
+ taskFolder: string; // Path to task folder with logs
53
+ duration: number; // Request duration in ms
54
+ response: { // API response object
55
+ code: number; // 0 = success
56
+ data: Array<{ // ✅ Result data here
57
+ name: string;
58
+ contentType: string;
59
+ content: string; // URL to compressed image
60
+ }> | null;
61
+ };
62
+ logs: Array<{ timestamp; level; message }>;
63
+ attachments: any[];
64
+ }
65
+ ```
66
+
44
67
  ## Quick Start
45
68
 
46
69
  ```typescript
@@ -55,8 +78,9 @@ const result = await client.image.compress({
55
78
  quality: 80
56
79
  });
57
80
 
58
- if (result.code === 0) {
59
- console.log('Compressed images:', result.data);
81
+ // ✅ Correct: Check result.success, access data via result.response.data
82
+ if (result.success && result.response?.data) {
83
+ console.log('Compressed images:', result.response.data);
60
84
  }
61
85
  ```
62
86
 
@@ -104,8 +128,8 @@ const result = await client.image.compress({
104
128
  quality: 75
105
129
  });
106
130
 
107
- if (result.code === 0 && result.data) {
108
- const compressedImage = result.data[0];
131
+ if (result.success && result.response?.data) {
132
+ const compressedImage = result.response.data[0];
109
133
  console.log('Compressed URL:', compressedImage.content);
110
134
  }
111
135
  ```
@@ -124,8 +148,8 @@ const result = await client.image.compress({
124
148
  quality: 80
125
149
  });
126
150
 
127
- if (result.code === 0 && result.data) {
128
- result.data.forEach((img, i) => {
151
+ if (result.success && result.response?.data) {
152
+ result.response.data.forEach((img, i) => {
129
153
  console.log(`Image ${i + 1}: ${img.content}`);
130
154
  });
131
155
  }
@@ -159,16 +183,16 @@ const generated = await client.image.gemini({
159
183
  prompt: 'A beautiful landscape'
160
184
  });
161
185
 
162
- if (generated.code === 0 && generated.data) {
186
+ if (generated.success && generated.response?.data) {
163
187
  const compressed = await client.image.compress({
164
- attachment: generated.data.map(img => ({
188
+ attachment: generated.response.data.map(img => ({
165
189
  tmp_url: img.content,
166
190
  name: img.name
167
191
  })),
168
192
  quality: 75
169
193
  });
170
194
 
171
- console.log('Compressed generated images:', compressed.data);
195
+ console.log('Compressed generated images:', compressed.response?.data);
172
196
  }
173
197
  ```
174
198
 
@@ -190,11 +214,19 @@ const result = await client.image.compress({
190
214
  quality: 80
191
215
  });
192
216
 
193
- if (result.code !== 0) {
194
- console.error('Compression failed:', result.msg);
195
- } else {
196
- console.log('Success:', result.data);
217
+ if (!result.success) {
218
+ console.error('Request failed');
219
+ console.log('Check logs:', result.logs);
220
+ return;
221
+ }
222
+
223
+ if (result.response?.code !== 0) {
224
+ console.error('API error:', result.response);
225
+ return;
197
226
  }
227
+
228
+ // Success
229
+ console.log('Success:', result.response.data);
198
230
  ```
199
231
 
200
232
  ## Quality Guidelines
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: unityclaw-image-generation
3
3
  description: Generate high-quality images using Gemini or JiMeng (Doubao) models
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  metadata:
6
6
  openclaw:
7
7
  requires:
@@ -41,6 +41,33 @@ npx @unityclaw/sdk config set apiKey your-api-key
41
41
  export UNITYCLAW_API_KEY=your-api-key
42
42
  ```
43
43
 
44
+ ## Response Structure
45
+
46
+ > **IMPORTANT:** The result has a nested structure. Use `result.success` to check overall success, and access image data via `result.response.data`.
47
+
48
+ ```typescript
49
+ interface ImageGenerationResult {
50
+ success: boolean; // ✅ Use this to check if SDK call succeeded
51
+ taskId: string; // Task identifier (e.g., "b7b613d1")
52
+ taskFolder: string; // Path to task folder with logs
53
+ duration: number; // Request duration in ms
54
+ response: { // API response object
55
+ code: number; // 0 = success
56
+ data: Array<{ // ✅ Generated images here
57
+ name: string; // File name
58
+ contentType: string; // "attachment/url"
59
+ content: string; // Image URL
60
+ }> | null;
61
+ };
62
+ logs: Array<{ // Execution logs
63
+ timestamp: string;
64
+ level: string;
65
+ message: string;
66
+ }>;
67
+ attachments: any[]; // Downloaded attachments
68
+ }
69
+ ```
70
+
44
71
  ## Quick Start
45
72
 
46
73
  ```typescript
@@ -54,8 +81,11 @@ const result = await client.image.gemini({
54
81
  aspect_ratio: { value: '16:9', label: '16:9' }
55
82
  });
56
83
 
57
- if (result.code === 0) {
58
- console.log('Generated images:', result.data);
84
+ // ✅ Correct: Check result.success, access data via result.response.data
85
+ if (result.success && result.response?.data) {
86
+ console.log('Generated images:', result.response.data);
87
+ } else {
88
+ console.error('Error:', result.response);
59
89
  }
60
90
  ```
61
91
 
@@ -147,8 +177,8 @@ const result = await client.image.gemini({
147
177
  size: { value: '2K', label: '2K' }
148
178
  });
149
179
 
150
- if (result.code === 0 && result.data) {
151
- result.data.forEach((img, i) => {
180
+ if (result.success && result.response?.data) {
181
+ result.response.data.forEach((img, i) => {
152
182
  console.log(`Image ${i + 1}: ${img.content}`);
153
183
  });
154
184
  }
@@ -164,6 +194,10 @@ const result = await client.image.gemini({
164
194
  ],
165
195
  aspect_ratio: { value: '1:1', label: '1:1' }
166
196
  });
197
+
198
+ if (result.success) {
199
+ console.log('Style transfer complete:', result.response.data);
200
+ }
167
201
  ```
168
202
 
169
203
  ### Batch Generation
@@ -180,7 +214,7 @@ const results = await Promise.all(
180
214
  );
181
215
 
182
216
  results.forEach((result, i) => {
183
- if (result.code === 0) {
217
+ if (result.success) {
184
218
  console.log(`Prompt ${i + 1}: Success`);
185
219
  }
186
220
  });
@@ -188,27 +222,46 @@ results.forEach((result, i) => {
188
222
 
189
223
  ## Error Handling
190
224
 
225
+ > **IMPORTANT:** Always check `result.success` first, then access data via `result.response.data`.
226
+
191
227
  ```typescript
192
228
  const result = await client.image.gemini({ prompt: 'test' });
193
229
 
194
- if (result.code !== 0) {
195
- console.error('Error:', result.msg);
196
- // Handle error
197
- } else {
198
- console.log('Success:', result.data);
230
+ if (!result.success) {
231
+ console.error('Request failed');
232
+ console.log('Check logs:', result.logs);
233
+ return;
234
+ }
235
+
236
+ // Check API response code
237
+ if (result.response?.code !== 0) {
238
+ console.error('API error:', result.response);
239
+ return;
199
240
  }
241
+
242
+ // Success - access result.response.data
243
+ console.log('Success:', result.response.data);
244
+ console.log('Task ID:', result.taskId);
200
245
  ```
201
246
 
202
247
  ## Task Folders
203
248
 
204
- Each execution creates a task folder:
249
+ Each execution creates a task folder with detailed logs:
205
250
 
206
251
  ```typescript
207
252
  const result = await client.image.gemini({ prompt: 'test' });
208
253
 
209
- console.log('Task ID:', result.taskId);
210
- console.log('Task Folder:', result.taskFolder);
211
- console.log('Attachments:', result.attachments);
254
+ console.log('Task ID:', result.taskId); // e.g., "609600db"
255
+ console.log('Task Folder:', result.taskFolder); // e.g., "~/Documents/tasks/20260312_202723_609600db/"
256
+
257
+ // Task folder structure:
258
+ // ├── attachments/ - Generated images
259
+ // │ └── xxx.png
260
+ // └── logs/
261
+ // ├── execution.log
262
+ // ├── request.json - API request payload
263
+ // ├── response.json - Raw API response
264
+ // └── summary.json - Task summary with success status
212
265
  ```
213
266
 
214
267
  ## Related Skills
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: unityclaw-media-analysis
3
3
  description: Analyze video and audio content to extract subtitles, summaries, and insights
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  metadata:
6
6
  openclaw:
7
7
  requires:
@@ -41,6 +41,28 @@ npx @unityclaw/sdk config set apiKey your-api-key
41
41
  export UNITYCLAW_API_KEY=your-api-key
42
42
  ```
43
43
 
44
+ ## Response Structure
45
+
46
+ > **IMPORTANT:** The result has a nested structure. Use `result.success` to check overall success, and access data via `result.response.data`.
47
+
48
+ ```typescript
49
+ interface UnityClawResult {
50
+ success: boolean; // ✅ Use this to check if SDK call succeeded
51
+ taskId: string; // Task identifier
52
+ taskFolder: string; // Path to task folder with logs
53
+ duration: number; // Request duration in ms
54
+ response: { // API response object
55
+ code: number; // 0 = success
56
+ data: { // ✅ Result data here
57
+ summary: string; // Content summary
58
+ subtitle: string; // Extracted subtitles/transcript
59
+ } | null;
60
+ };
61
+ logs: Array<{ timestamp; level; message }>;
62
+ attachments: any[];
63
+ }
64
+ ```
65
+
44
66
  ## Quick Start
45
67
 
46
68
  ```typescript
@@ -53,9 +75,10 @@ const result = await client.media.analyze({
53
75
  url: [{ link: 'https://youtube.com/watch?v=...' }]
54
76
  });
55
77
 
56
- if (result.code === 0) {
57
- console.log('Summary:', result.data?.summary);
58
- console.log('Subtitle:', result.data?.subtitle);
78
+ // ✅ Correct: Check result.success, access data via result.response.data
79
+ if (result.success && result.response?.data) {
80
+ console.log('Summary:', result.response.data.summary);
81
+ console.log('Subtitle:', result.response.data.subtitle);
59
82
  }
60
83
  ```
61
84
 
@@ -136,9 +159,9 @@ const result = await client.media.analyze({
136
159
  url: [{ link: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' }]
137
160
  });
138
161
 
139
- if (result.code === 0 && result.data) {
140
- console.log('Summary:', result.data.summary);
141
- console.log('Transcript:', result.data.subtitle);
162
+ if (result.success && result.response?.data) {
163
+ console.log('Summary:', result.response.data.summary);
164
+ console.log('Transcript:', result.response.data.subtitle);
142
165
  }
143
166
  ```
144
167
 
@@ -200,8 +223,8 @@ const results = await Promise.all(
200
223
  );
201
224
 
202
225
  results.forEach((result, i) => {
203
- if (result.code === 0) {
204
- console.log(`Video ${i + 1}:`, result.data?.summary);
226
+ if (result.success) {
227
+ console.log(`Video ${i + 1}:`, result.response?.data?.summary);
205
228
  }
206
229
  });
207
230
  ```
@@ -277,11 +300,19 @@ const result = await client.media.analyze({
277
300
  url: [{ link: 'https://youtube.com/watch?v=invalid' }]
278
301
  });
279
302
 
280
- if (result.code !== 0) {
281
- console.error('Analysis failed:', result.msg);
282
- } else {
283
- console.log('Success:', result.data);
303
+ if (!result.success) {
304
+ console.error('Request failed');
305
+ console.log('Check logs:', result.logs);
306
+ return;
284
307
  }
308
+
309
+ if (result.response?.code !== 0) {
310
+ console.error('API error:', result.response);
311
+ return;
312
+ }
313
+
314
+ // Success
315
+ console.log('Success:', result.response.data);
285
316
  ```
286
317
 
287
318
  ## Task Folders
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: unityclaw-video-generation-kling
3
3
  description: Generate AI videos using Kling model with multi-version support
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  metadata:
6
6
  openclaw:
7
7
  requires:
@@ -41,6 +41,29 @@ npx @unityclaw/sdk config set apiKey your-api-key
41
41
  export UNITYCLAW_API_KEY=your-api-key
42
42
  ```
43
43
 
44
+ ## Response Structure
45
+
46
+ > **IMPORTANT:** The result has a nested structure. Use `result.success` to check overall success, and access data via `result.response.data`.
47
+
48
+ ```typescript
49
+ interface UnityClawResult {
50
+ success: boolean; // ✅ Use this to check if SDK call succeeded
51
+ taskId: string; // Task identifier
52
+ taskFolder: string; // Path to task folder with logs
53
+ duration: number; // Request duration in ms
54
+ response: { // API response object
55
+ code: number; // 0 = success
56
+ data: Array<{ // ✅ Result data here
57
+ name: string;
58
+ contentType: string;
59
+ content: string; // URL to generated video
60
+ }> | null;
61
+ };
62
+ logs: Array<{ timestamp; level; message }>;
63
+ attachments: any[];
64
+ }
65
+ ```
66
+
44
67
  ## Quick Start
45
68
 
46
69
  ```typescript
@@ -54,8 +77,9 @@ const result = await client.video.kling({
54
77
  duration: { value: '5', label: '5s' }
55
78
  });
56
79
 
57
- if (result.code === 0) {
58
- console.log('Generated video:', result.data);
80
+ // ✅ Correct: Check result.success, access data via result.response.data
81
+ if (result.success && result.response?.data) {
82
+ console.log('Generated video:', result.response.data);
59
83
  }
60
84
  ```
61
85
 
@@ -201,11 +225,19 @@ const result = await client.video.kling({
201
225
  aspect_ratio: '16:9'
202
226
  });
203
227
 
204
- if (result.code !== 0) {
205
- console.error('Video generation failed:', result.msg);
206
- } else {
207
- console.log('Success:', result.data);
228
+ if (!result.success) {
229
+ console.error('Request failed');
230
+ console.log('Check logs:', result.logs);
231
+ return;
232
+ }
233
+
234
+ if (result.response?.code !== 0) {
235
+ console.error('API error:', result.response);
236
+ return;
208
237
  }
238
+
239
+ // Success
240
+ console.log('Success:', result.response.data);
209
241
  ```
210
242
 
211
243
  ## Task Folders
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: unityclaw-video-generation-other
3
3
  description: Generate videos using Doubao, Wan (Alibaba), MiniMax, and JiMeng models
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  metadata:
6
6
  openclaw:
7
7
  requires:
@@ -41,6 +41,29 @@ npx @unityclaw/sdk config set apiKey your-api-key
41
41
  export UNITYCLAW_API_KEY=your-api-key
42
42
  ```
43
43
 
44
+ ## Response Structure
45
+
46
+ > **IMPORTANT:** The result has a nested structure. Use `result.success` to check overall success, and access data via `result.response.data`.
47
+
48
+ ```typescript
49
+ interface UnityClawResult {
50
+ success: boolean; // ✅ Use this to check if SDK call succeeded
51
+ taskId: string; // Task identifier
52
+ taskFolder: string; // Path to task folder with logs
53
+ duration: number; // Request duration in ms
54
+ response: { // API response object
55
+ code: number; // 0 = success
56
+ data: Array<{ // ✅ Result data here
57
+ name: string;
58
+ contentType: string;
59
+ content: string; // URL to generated video
60
+ }> | null;
61
+ };
62
+ logs: Array<{ timestamp; level; message }>;
63
+ attachments: any[];
64
+ }
65
+ ```
66
+
44
67
  ## Quick Start
45
68
 
46
69
  ```typescript
@@ -54,6 +77,11 @@ const result = await client.video.doubao({
54
77
  resolution: { value: '1080p', label: '1080p' },
55
78
  ratio: { value: '16:9', label: '16:9' }
56
79
  });
80
+
81
+ // ✅ Correct: Check result.success, access data via result.response.data
82
+ if (result.success && result.response?.data) {
83
+ console.log('Generated video:', result.response.data);
84
+ }
57
85
  ```
58
86
 
59
87
  ## Available APIs
@@ -225,8 +253,8 @@ const results = await Promise.all([
225
253
 
226
254
  results.forEach((result, i) => {
227
255
  const model = ['Doubao', 'Wan', 'MiniMax'][i];
228
- if (result.code === 0) {
229
- console.log(`${model}: ${result.data?.[0]?.content}`);
256
+ if (result.success && result.response?.data) {
257
+ console.log(`${model}: ${result.response.data?.[0]?.content}`);
230
258
  }
231
259
  });
232
260
  ```
@@ -259,11 +287,19 @@ const result = await client.video.doubao({
259
287
  ratio: '16:9'
260
288
  });
261
289
 
262
- if (result.code !== 0) {
263
- console.error('Failed:', result.msg);
264
- } else {
265
- console.log('Success:', result.data);
290
+ if (!result.success) {
291
+ console.error('Request failed');
292
+ console.log('Check logs:', result.logs);
293
+ return;
266
294
  }
295
+
296
+ if (result.response?.code !== 0) {
297
+ console.error('API error:', result.response);
298
+ return;
299
+ }
300
+
301
+ // Success
302
+ console.log('Success:', result.response.data);
267
303
  ```
268
304
 
269
305
  ## Task Folders
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: unityclaw-video-generation-sora
3
3
  description: Generate cinematic videos using OpenAI Sora AI model
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  metadata:
6
6
  openclaw:
7
7
  requires:
@@ -41,6 +41,29 @@ npx @unityclaw/sdk config set apiKey your-api-key
41
41
  export UNITYCLAW_API_KEY=your-api-key
42
42
  ```
43
43
 
44
+ ## Response Structure
45
+
46
+ > **IMPORTANT:** The result has a nested structure. Use `result.success` to check overall success, and access data via `result.response.data`.
47
+
48
+ ```typescript
49
+ interface UnityClawResult {
50
+ success: boolean; // ✅ Use this to check if SDK call succeeded
51
+ taskId: string; // Task identifier
52
+ taskFolder: string; // Path to task folder with logs
53
+ duration: number; // Request duration in ms
54
+ response: { // API response object
55
+ code: number; // 0 = success
56
+ data: Array<{ // ✅ Result data here
57
+ name: string;
58
+ contentType: string;
59
+ content: string; // URL to generated video
60
+ }> | null;
61
+ };
62
+ logs: Array<{ timestamp; level; message }>;
63
+ attachments: any[];
64
+ }
65
+ ```
66
+
44
67
  ## Quick Start
45
68
 
46
69
  ```typescript
@@ -53,8 +76,9 @@ const result = await client.video.sora({
53
76
  orientation: { value: 'landscape', label: 'Landscape' }
54
77
  });
55
78
 
56
- if (result.code === 0) {
57
- console.log('Generated video:', result.data);
79
+ // ✅ Correct: Check result.success, access data via result.response.data
80
+ if (result.success && result.response?.data) {
81
+ console.log('Generated video:', result.response.data);
58
82
  }
59
83
  ```
60
84
 
@@ -127,8 +151,8 @@ const result = await client.video.sora({
127
151
  orientation: { value: 'landscape', label: 'Landscape' }
128
152
  });
129
153
 
130
- if (result.code === 0 && result.data) {
131
- console.log('Video URL:', result.data[0].content);
154
+ if (result.success && result.response?.data) {
155
+ console.log('Video URL:', result.response.data[0].content);
132
156
  }
133
157
  ```
134
158
 
@@ -180,8 +204,8 @@ const results = await Promise.all(
180
204
  );
181
205
 
182
206
  results.forEach((result, i) => {
183
- if (result.code === 0) {
184
- console.log(`Video ${i + 1}: ${result.data?.[0]?.content}`);
207
+ if (result.success && result.response?.data) {
208
+ console.log(`Video ${i + 1}: ${result.response.data?.[0]?.content}`);
185
209
  }
186
210
  });
187
211
  ```
@@ -218,11 +242,19 @@ const result = await client.video.sora({
218
242
  orientation: { value: 'landscape', label: 'Landscape' }
219
243
  });
220
244
 
221
- if (result.code !== 0) {
222
- console.error('Video generation failed:', result.msg);
223
- } else {
224
- console.log('Success:', result.data);
245
+ if (!result.success) {
246
+ console.error('Request failed');
247
+ console.log('Check logs:', result.logs);
248
+ return;
249
+ }
250
+
251
+ if (result.response?.code !== 0) {
252
+ console.error('API error:', result.response);
253
+ return;
225
254
  }
255
+
256
+ // Success
257
+ console.log('Success:', result.response.data);
226
258
  ```
227
259
 
228
260
  ## Task Folders
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: unityclaw-video-generation-veo
3
3
  description: Generate high-quality videos using Google Veo AI model
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  metadata:
6
6
  openclaw:
7
7
  requires:
@@ -41,6 +41,29 @@ npx @unityclaw/sdk config set apiKey your-api-key
41
41
  export UNITYCLAW_API_KEY=your-api-key
42
42
  ```
43
43
 
44
+ ## Response Structure
45
+
46
+ > **IMPORTANT:** The result has a nested structure. Use `result.success` to check overall success, and access data via `result.response.data`.
47
+
48
+ ```typescript
49
+ interface UnityClawResult {
50
+ success: boolean; // ✅ Use this to check if SDK call succeeded
51
+ taskId: string; // Task identifier
52
+ taskFolder: string; // Path to task folder with logs
53
+ duration: number; // Request duration in ms
54
+ response: { // API response object
55
+ code: number; // 0 = success
56
+ data: Array<{ // ✅ Result data here
57
+ name: string;
58
+ contentType: string;
59
+ content: string; // URL to generated video
60
+ }> | null;
61
+ };
62
+ logs: Array<{ timestamp; level; message }>;
63
+ attachments: any[];
64
+ }
65
+ ```
66
+
44
67
  ## Quick Start
45
68
 
46
69
  ```typescript
@@ -54,8 +77,9 @@ const result = await client.video.veo({
54
77
  duration: { value: '8', label: '8s' }
55
78
  });
56
79
 
57
- if (result.code === 0) {
58
- console.log('Generated video:', result.data);
80
+ // ✅ Correct: Check result.success, access data via result.response.data
81
+ if (result.success && result.response?.data) {
82
+ console.log('Generated video:', result.response.data);
59
83
  }
60
84
  ```
61
85
 
@@ -207,11 +231,19 @@ const result = await client.video.veo({
207
231
  aspect_ratio: '16:9'
208
232
  });
209
233
 
210
- if (result.code !== 0) {
211
- console.error('Video generation failed:', result.msg);
212
- } else {
213
- console.log('Success:', result.data);
234
+ if (!result.success) {
235
+ console.error('Request failed');
236
+ console.log('Check logs:', result.logs);
237
+ return;
238
+ }
239
+
240
+ if (result.response?.code !== 0) {
241
+ console.error('API error:', result.response);
242
+ return;
214
243
  }
244
+
245
+ // Success
246
+ console.log('Success:', result.response.data);
215
247
  ```
216
248
 
217
249
  ## Task Folders