@unityclaw/sdk 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.
@@ -4,7 +4,7 @@ import os from "os";
4
4
  import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
5
5
  var CONFIG_DIR = path.join(os.homedir(), ".unityclaw");
6
6
  var CONFIG_FILE = path.join(CONFIG_DIR, "config.json");
7
- var DEFAULT_TASKS_DIR = path.join(CONFIG_DIR, "tasks");
7
+ var DEFAULT_TASKS_DIR = path.join(os.homedir(), "Documents", "tasks");
8
8
  function getConfigPath() {
9
9
  return CONFIG_FILE;
10
10
  }
package/dist/cli.cjs CHANGED
@@ -29,7 +29,7 @@ var import_os = __toESM(require("os"), 1);
29
29
  var import_fs = require("fs");
30
30
  var CONFIG_DIR = import_path.default.join(import_os.default.homedir(), ".unityclaw");
31
31
  var CONFIG_FILE = import_path.default.join(CONFIG_DIR, "config.json");
32
- var DEFAULT_TASKS_DIR = import_path.default.join(CONFIG_DIR, "tasks");
32
+ var DEFAULT_TASKS_DIR = import_path.default.join(import_os.default.homedir(), "Documents", "tasks");
33
33
  function getConfigPath() {
34
34
  return CONFIG_FILE;
35
35
  }
package/dist/cli.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  getConfigValue,
5
5
  loadConfig,
6
6
  setConfigValue
7
- } from "./chunk-WG7OYNEX.js";
7
+ } from "./chunk-SZITFMFH.js";
8
8
 
9
9
  // src/cli.ts
10
10
  var args = process.argv.slice(2);
package/dist/index.cjs CHANGED
@@ -103,30 +103,45 @@ var TaskFolderManager = class {
103
103
  /**
104
104
  * Download an attachment from URL to local folder
105
105
  * Important: Downloads attachments to avoid tmp_url expiration
106
+ * Includes retry logic for transient failures
106
107
  */
107
- async downloadAttachment(ctx, attachment) {
108
+ async downloadAttachment(ctx, attachment, maxRetries = 3, retryDelayMs = 1e3) {
108
109
  if (!this.options.downloadAttachments || !attachment.tmp_url) {
109
110
  return attachment.tmp_url;
110
111
  }
111
- try {
112
- const url = attachment.tmp_url;
113
- const urlPath = url.split("?")[0];
114
- const baseName = urlPath ? (0, import_path.basename)(urlPath) : "";
115
- const filename = attachment.name || baseName || `file_${Date.now()}`;
116
- const localPath = (0, import_path.join)(ctx.attachmentsPath, filename);
117
- const response = await import_axios.default.get(url, {
118
- responseType: "arraybuffer",
119
- timeout: 6e4
120
- });
121
- await (0, import_promises.writeFile)(localPath, Buffer.from(response.data));
122
- ctx.downloadedFiles.push(localPath);
123
- return localPath;
124
- } catch (error) {
125
- await this.log(ctx, "warn", `Failed to download attachment: ${attachment.name}`, {
126
- error: error instanceof Error ? error.message : error
127
- });
128
- return attachment.tmp_url;
112
+ const url = attachment.tmp_url;
113
+ const urlPath = url.split("?")[0];
114
+ const baseName = urlPath ? (0, import_path.basename)(urlPath) : "";
115
+ const filename = attachment.name || baseName || `file_${Date.now()}`;
116
+ const localPath = (0, import_path.join)(ctx.attachmentsPath, filename);
117
+ let lastError;
118
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
119
+ try {
120
+ const response = await import_axios.default.get(url, {
121
+ responseType: "arraybuffer",
122
+ timeout: 6e4
123
+ });
124
+ await (0, import_promises.writeFile)(localPath, Buffer.from(response.data));
125
+ ctx.downloadedFiles.push(localPath);
126
+ if (attempt > 1) {
127
+ await this.log(ctx, "info", `Download succeeded on attempt ${attempt}: ${filename}`);
128
+ }
129
+ return localPath;
130
+ } catch (error) {
131
+ lastError = error instanceof Error ? error : new Error(String(error));
132
+ if (attempt < maxRetries) {
133
+ await this.log(ctx, "warn", `Download attempt ${attempt}/${maxRetries} failed for ${filename}, retrying...`, {
134
+ error: lastError.message
135
+ });
136
+ await new Promise((resolve) => setTimeout(resolve, retryDelayMs * attempt));
137
+ }
138
+ }
129
139
  }
140
+ await this.log(ctx, "warn", `Failed to download attachment after ${maxRetries} attempts: ${filename}`, {
141
+ error: lastError?.message,
142
+ url: url.substring(0, 100) + "..."
143
+ });
144
+ return attachment.tmp_url;
130
145
  }
131
146
  /**
132
147
  * Download multiple attachments
@@ -239,7 +254,7 @@ var import_os = __toESM(require("os"), 1);
239
254
  var import_fs2 = require("fs");
240
255
  var CONFIG_DIR = import_path2.default.join(import_os.default.homedir(), ".unityclaw");
241
256
  var CONFIG_FILE = import_path2.default.join(CONFIG_DIR, "config.json");
242
- var DEFAULT_TASKS_DIR = import_path2.default.join(CONFIG_DIR, "tasks");
257
+ var DEFAULT_TASKS_DIR = import_path2.default.join(import_os.default.homedir(), "Documents", "tasks");
243
258
  function getConfigPath() {
244
259
  return CONFIG_FILE;
245
260
  }
@@ -775,6 +790,16 @@ var MediaAPI = class {
775
790
  // src/client.ts
776
791
  var DEFAULT_BASE_URL = "https://unityclaw.com";
777
792
  var DEFAULT_TIMEOUT = 3e5;
793
+ var OLD_DOMAINS = ["fieldshortcut.cn", "fieldshortcut.com"];
794
+ var NEW_DOMAIN = "unityclaw.com";
795
+ function replaceOldDomains(text) {
796
+ if (!text || typeof text !== "string") return text;
797
+ let result = text;
798
+ for (const oldDomain of OLD_DOMAINS) {
799
+ result = result.replace(new RegExp(oldDomain.replace(/\./g, "\\."), "g"), NEW_DOMAIN);
800
+ }
801
+ return result;
802
+ }
778
803
  var UnityClawClient = class {
779
804
  config;
780
805
  httpClient;
@@ -881,6 +906,9 @@ var UnityClawClient = class {
881
906
  await this.taskFolderManager.writeRequest(taskCtx, endpoint, params, context);
882
907
  await this.taskFolderManager.log(taskCtx, "info", "Request prepared", { endpoint, params });
883
908
  const response = await this.httpClient.post(endpoint, requestBody);
909
+ if (response.data.msg) {
910
+ response.data.msg = replaceOldDomains(response.data.msg);
911
+ }
884
912
  await this.taskFolderManager.writeResponse(taskCtx, response.data);
885
913
  await this.taskFolderManager.log(taskCtx, "info", "Response received", {
886
914
  code: response.data.code,
@@ -908,7 +936,8 @@ var UnityClawClient = class {
908
936
  response.data.code === 0
909
937
  );
910
938
  } catch (error) {
911
- const errorMessage = error instanceof import_axios2.AxiosError ? error.response?.data?.msg || error.message : error instanceof Error ? error.message : String(error);
939
+ const rawErrorMessage = error instanceof import_axios2.AxiosError ? error.response?.data?.msg || error.message : error instanceof Error ? error.message : String(error);
940
+ const errorMessage = replaceOldDomains(rawErrorMessage);
912
941
  await this.taskFolderManager.log(taskCtx, "error", `Request failed: ${errorMessage}`, {
913
942
  error: error instanceof import_axios2.AxiosError ? { status: error.response?.status, data: error.response?.data } : error
914
943
  });
package/dist/index.d.cts CHANGED
@@ -272,8 +272,9 @@ declare class TaskFolderManager {
272
272
  /**
273
273
  * Download an attachment from URL to local folder
274
274
  * Important: Downloads attachments to avoid tmp_url expiration
275
+ * Includes retry logic for transient failures
275
276
  */
276
- downloadAttachment(ctx: TaskFolderContext, attachment: AttachmentFieldItem): Promise<string | undefined>;
277
+ downloadAttachment(ctx: TaskFolderContext, attachment: AttachmentFieldItem, maxRetries?: number, retryDelayMs?: number): Promise<string | undefined>;
277
278
  /**
278
279
  * Download multiple attachments
279
280
  */
@@ -812,7 +813,7 @@ declare class UnityClawClient {
812
813
  declare const CONFIG_DIR: string;
813
814
  /** Config file path */
814
815
  declare const CONFIG_FILE: string;
815
- /** Default tasks directory */
816
+ /** Default tasks directory - in Documents so users can easily find results */
816
817
  declare const DEFAULT_TASKS_DIR: string;
817
818
  /** UnityClaw configuration */
818
819
  interface UnityClawConfig {
package/dist/index.d.ts CHANGED
@@ -272,8 +272,9 @@ declare class TaskFolderManager {
272
272
  /**
273
273
  * Download an attachment from URL to local folder
274
274
  * Important: Downloads attachments to avoid tmp_url expiration
275
+ * Includes retry logic for transient failures
275
276
  */
276
- downloadAttachment(ctx: TaskFolderContext, attachment: AttachmentFieldItem): Promise<string | undefined>;
277
+ downloadAttachment(ctx: TaskFolderContext, attachment: AttachmentFieldItem, maxRetries?: number, retryDelayMs?: number): Promise<string | undefined>;
277
278
  /**
278
279
  * Download multiple attachments
279
280
  */
@@ -812,7 +813,7 @@ declare class UnityClawClient {
812
813
  declare const CONFIG_DIR: string;
813
814
  /** Config file path */
814
815
  declare const CONFIG_FILE: string;
815
- /** Default tasks directory */
816
+ /** Default tasks directory - in Documents so users can easily find results */
816
817
  declare const DEFAULT_TASKS_DIR: string;
817
818
  /** UnityClaw configuration */
818
819
  interface UnityClawConfig {
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  loadConfig,
8
8
  saveConfig,
9
9
  setConfigValue
10
- } from "./chunk-WG7OYNEX.js";
10
+ } from "./chunk-SZITFMFH.js";
11
11
 
12
12
  // src/client.ts
13
13
  import axios2, { AxiosError } from "axios";
@@ -65,30 +65,45 @@ var TaskFolderManager = class {
65
65
  /**
66
66
  * Download an attachment from URL to local folder
67
67
  * Important: Downloads attachments to avoid tmp_url expiration
68
+ * Includes retry logic for transient failures
68
69
  */
69
- async downloadAttachment(ctx, attachment) {
70
+ async downloadAttachment(ctx, attachment, maxRetries = 3, retryDelayMs = 1e3) {
70
71
  if (!this.options.downloadAttachments || !attachment.tmp_url) {
71
72
  return attachment.tmp_url;
72
73
  }
73
- try {
74
- const url = attachment.tmp_url;
75
- const urlPath = url.split("?")[0];
76
- const baseName = urlPath ? basename(urlPath) : "";
77
- const filename = attachment.name || baseName || `file_${Date.now()}`;
78
- const localPath = join(ctx.attachmentsPath, filename);
79
- const response = await axios.get(url, {
80
- responseType: "arraybuffer",
81
- timeout: 6e4
82
- });
83
- await writeFile(localPath, Buffer.from(response.data));
84
- ctx.downloadedFiles.push(localPath);
85
- return localPath;
86
- } catch (error) {
87
- await this.log(ctx, "warn", `Failed to download attachment: ${attachment.name}`, {
88
- error: error instanceof Error ? error.message : error
89
- });
90
- return attachment.tmp_url;
74
+ const url = attachment.tmp_url;
75
+ const urlPath = url.split("?")[0];
76
+ const baseName = urlPath ? basename(urlPath) : "";
77
+ const filename = attachment.name || baseName || `file_${Date.now()}`;
78
+ const localPath = join(ctx.attachmentsPath, filename);
79
+ let lastError;
80
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
81
+ try {
82
+ const response = await axios.get(url, {
83
+ responseType: "arraybuffer",
84
+ timeout: 6e4
85
+ });
86
+ await writeFile(localPath, Buffer.from(response.data));
87
+ ctx.downloadedFiles.push(localPath);
88
+ if (attempt > 1) {
89
+ await this.log(ctx, "info", `Download succeeded on attempt ${attempt}: ${filename}`);
90
+ }
91
+ return localPath;
92
+ } catch (error) {
93
+ lastError = error instanceof Error ? error : new Error(String(error));
94
+ if (attempt < maxRetries) {
95
+ await this.log(ctx, "warn", `Download attempt ${attempt}/${maxRetries} failed for ${filename}, retrying...`, {
96
+ error: lastError.message
97
+ });
98
+ await new Promise((resolve) => setTimeout(resolve, retryDelayMs * attempt));
99
+ }
100
+ }
91
101
  }
102
+ await this.log(ctx, "warn", `Failed to download attachment after ${maxRetries} attempts: ${filename}`, {
103
+ error: lastError?.message,
104
+ url: url.substring(0, 100) + "..."
105
+ });
106
+ return attachment.tmp_url;
92
107
  }
93
108
  /**
94
109
  * Download multiple attachments
@@ -676,6 +691,16 @@ var MediaAPI = class {
676
691
  // src/client.ts
677
692
  var DEFAULT_BASE_URL = "https://unityclaw.com";
678
693
  var DEFAULT_TIMEOUT = 3e5;
694
+ var OLD_DOMAINS = ["fieldshortcut.cn", "fieldshortcut.com"];
695
+ var NEW_DOMAIN = "unityclaw.com";
696
+ function replaceOldDomains(text) {
697
+ if (!text || typeof text !== "string") return text;
698
+ let result = text;
699
+ for (const oldDomain of OLD_DOMAINS) {
700
+ result = result.replace(new RegExp(oldDomain.replace(/\./g, "\\."), "g"), NEW_DOMAIN);
701
+ }
702
+ return result;
703
+ }
679
704
  var UnityClawClient = class {
680
705
  config;
681
706
  httpClient;
@@ -782,6 +807,9 @@ var UnityClawClient = class {
782
807
  await this.taskFolderManager.writeRequest(taskCtx, endpoint, params, context);
783
808
  await this.taskFolderManager.log(taskCtx, "info", "Request prepared", { endpoint, params });
784
809
  const response = await this.httpClient.post(endpoint, requestBody);
810
+ if (response.data.msg) {
811
+ response.data.msg = replaceOldDomains(response.data.msg);
812
+ }
785
813
  await this.taskFolderManager.writeResponse(taskCtx, response.data);
786
814
  await this.taskFolderManager.log(taskCtx, "info", "Response received", {
787
815
  code: response.data.code,
@@ -809,7 +837,8 @@ var UnityClawClient = class {
809
837
  response.data.code === 0
810
838
  );
811
839
  } catch (error) {
812
- const errorMessage = error instanceof AxiosError ? error.response?.data?.msg || error.message : error instanceof Error ? error.message : String(error);
840
+ const rawErrorMessage = error instanceof AxiosError ? error.response?.data?.msg || error.message : error instanceof Error ? error.message : String(error);
841
+ const errorMessage = replaceOldDomains(rawErrorMessage);
813
842
  await this.taskFolderManager.log(taskCtx, "error", `Request failed: ${errorMessage}`, {
814
843
  error: error instanceof AxiosError ? { status: error.response?.status, data: error.response?.data } : error
815
844
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unityclaw/sdk",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Node.js SDK for UnityClaw API - AI-powered image/video generation, media analysis, and more",
5
5
  "type": "module",
6
6
  "bin": {