@unityclaw/sdk 1.0.2 → 1.0.4
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/README.md +173 -0
- package/dist/chunk-SZITFMFH.js +71 -0
- package/dist/cli.cjs +160 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +82 -0
- package/dist/index.cjs +98 -14
- package/dist/index.d.cts +28 -1
- package/dist/index.d.ts +28 -1
- package/dist/index.js +39 -13
- package/package.json +8 -4
- package/src/cli.ts +95 -0
package/README.md
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# @unityclaw/sdk
|
|
2
|
+
|
|
3
|
+
Node.js SDK for UnityClaw API - AI-powered image/video generation, media analysis, and more.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @unityclaw/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { UnityClawClient } from '@unityclaw/sdk';
|
|
15
|
+
|
|
16
|
+
// Reads UNITYCLAW_API_KEY from environment variable
|
|
17
|
+
const client = new UnityClawClient();
|
|
18
|
+
|
|
19
|
+
// Or with explicit config
|
|
20
|
+
const client = new UnityClawClient({
|
|
21
|
+
apiKey: 'your-api-key',
|
|
22
|
+
baseUrl: 'https://unityclaw.com',
|
|
23
|
+
taskDir: './tasks'
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// Generate image
|
|
27
|
+
const imageResult = await client.image.gemini({
|
|
28
|
+
prompt: 'A beautiful sunset over mountains'
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// Generate video
|
|
32
|
+
const videoResult = await client.video.sora({
|
|
33
|
+
prompt: 'A cat playing piano',
|
|
34
|
+
orientation: { value: 'landscape', label: 'Landscape' }
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// Translate document
|
|
38
|
+
const docResult = await client.document.translate({
|
|
39
|
+
attachment: [{ tmp_url: 'https://...', name: 'doc.pdf' }],
|
|
40
|
+
source_language: { value: 'en', label: 'English' },
|
|
41
|
+
target_language: { value: 'zh', label: 'Chinese' }
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Analyze media
|
|
45
|
+
const mediaResult = await client.media.analyze({
|
|
46
|
+
url: [{ link: 'https://youtube.com/watch?v=...' }]
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Configuration
|
|
51
|
+
|
|
52
|
+
### Environment Variables
|
|
53
|
+
|
|
54
|
+
- `UNITYCLAW_API_KEY` - Your UnityClaw API key
|
|
55
|
+
- `UNITYCLAW_BASE_URL` - API base URL (optional, defaults to https://unityclaw.com)
|
|
56
|
+
|
|
57
|
+
### CLI Configuration
|
|
58
|
+
|
|
59
|
+
Use the CLI to persist configuration:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# Install globally
|
|
63
|
+
npm install -g @unityclaw/sdk
|
|
64
|
+
|
|
65
|
+
# Set API key (stored in ~/.unityclaw/config.json)
|
|
66
|
+
unityclaw-sdk config set apiKey your-api-key
|
|
67
|
+
|
|
68
|
+
# Set custom base URL
|
|
69
|
+
unityclaw-sdk config set baseUrl https://custom.example.com
|
|
70
|
+
|
|
71
|
+
# View current configuration
|
|
72
|
+
unityclaw-sdk config
|
|
73
|
+
|
|
74
|
+
# Get a specific value
|
|
75
|
+
unityclaw-sdk config get apiKey
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Configuration Priority
|
|
79
|
+
|
|
80
|
+
1. Constructor parameters (highest priority)
|
|
81
|
+
2. Environment variables
|
|
82
|
+
3. Config file (~/.unityclaw/config.json)
|
|
83
|
+
4. Default values (lowest priority)
|
|
84
|
+
|
|
85
|
+
## Task Folders
|
|
86
|
+
|
|
87
|
+
Each SDK execution creates a task folder with:
|
|
88
|
+
|
|
89
|
+
- `logs/request.json` - Request details
|
|
90
|
+
- `logs/response.json` - API response
|
|
91
|
+
- `logs/execution.log` - Execution log
|
|
92
|
+
- `attachments/` - Downloaded attachments (to avoid link expiration)
|
|
93
|
+
|
|
94
|
+
### Default Task Directory
|
|
95
|
+
|
|
96
|
+
Tasks are stored in `~/.unityclaw/tasks/` by default. You can override this:
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
const client = new UnityClawClient({
|
|
100
|
+
taskDir: '/path/to/custom/tasks'
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## API Reference
|
|
105
|
+
|
|
106
|
+
### Image Generation
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
// Gemini
|
|
110
|
+
await client.image.gemini({
|
|
111
|
+
prompt: 'A sunset over mountains',
|
|
112
|
+
aspect_ratio: '16:9'
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// JiMeng (Doubao)
|
|
116
|
+
await client.image.jimeng({
|
|
117
|
+
prompt: 'A futuristic city',
|
|
118
|
+
model: 'v6.0'
|
|
119
|
+
});
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Video Generation
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
// Sora
|
|
126
|
+
await client.video.sora({
|
|
127
|
+
prompt: 'A cat playing piano',
|
|
128
|
+
orientation: 'landscape'
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// Veo
|
|
132
|
+
await client.video.veo({
|
|
133
|
+
prompt: 'Ocean waves at sunset'
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// Kling
|
|
137
|
+
await client.video.kling({
|
|
138
|
+
prompt: 'A dancing robot',
|
|
139
|
+
version: 'v1.5'
|
|
140
|
+
});
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Document Processing
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
// Translate document
|
|
147
|
+
await client.document.translate({
|
|
148
|
+
attachment: [{ tmp_url: 'https://...', name: 'doc.pdf' }],
|
|
149
|
+
source_language: { value: 'en', label: 'English' },
|
|
150
|
+
target_language: { value: 'zh', label: 'Chinese' }
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
// Convert document
|
|
154
|
+
await client.document.convert({
|
|
155
|
+
attachment: [{ tmp_url: 'https://...', name: 'doc.pdf' }],
|
|
156
|
+
target_format: { value: 'word', label: 'Word' }
|
|
157
|
+
});
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Media Analysis
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
const result = await client.media.analyze({
|
|
164
|
+
url: [{ link: 'https://youtube.com/watch?v=...' }]
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
console.log(result.data.summary);
|
|
168
|
+
console.log(result.data.subtitle);
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## License
|
|
172
|
+
|
|
173
|
+
MIT
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// src/config.ts
|
|
2
|
+
import path from "path";
|
|
3
|
+
import os from "os";
|
|
4
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
5
|
+
var CONFIG_DIR = path.join(os.homedir(), ".unityclaw");
|
|
6
|
+
var CONFIG_FILE = path.join(CONFIG_DIR, "config.json");
|
|
7
|
+
var DEFAULT_TASKS_DIR = path.join(os.homedir(), "Documents", "tasks");
|
|
8
|
+
function getConfigPath() {
|
|
9
|
+
return CONFIG_FILE;
|
|
10
|
+
}
|
|
11
|
+
function loadConfig() {
|
|
12
|
+
try {
|
|
13
|
+
if (existsSync(CONFIG_FILE)) {
|
|
14
|
+
const content = readFileSync(CONFIG_FILE, "utf-8");
|
|
15
|
+
return JSON.parse(content);
|
|
16
|
+
}
|
|
17
|
+
} catch {
|
|
18
|
+
}
|
|
19
|
+
return {};
|
|
20
|
+
}
|
|
21
|
+
function saveConfig(config) {
|
|
22
|
+
if (!existsSync(CONFIG_DIR)) {
|
|
23
|
+
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), "utf-8");
|
|
26
|
+
}
|
|
27
|
+
function setConfigValue(key, value) {
|
|
28
|
+
const config = loadConfig();
|
|
29
|
+
const keyMap = {
|
|
30
|
+
"apiKey": "apiKey",
|
|
31
|
+
"api_key": "apiKey",
|
|
32
|
+
"key": "apiKey",
|
|
33
|
+
"baseUrl": "baseUrl",
|
|
34
|
+
"base_url": "baseUrl",
|
|
35
|
+
"url": "baseUrl",
|
|
36
|
+
"taskDir": "taskDir",
|
|
37
|
+
"task_dir": "taskDir",
|
|
38
|
+
"tasks": "taskDir"
|
|
39
|
+
};
|
|
40
|
+
const configKey = keyMap[key] || key;
|
|
41
|
+
config[configKey] = value;
|
|
42
|
+
saveConfig(config);
|
|
43
|
+
}
|
|
44
|
+
function getConfigValue(key) {
|
|
45
|
+
const config = loadConfig();
|
|
46
|
+
const keyMap = {
|
|
47
|
+
"apiKey": "apiKey",
|
|
48
|
+
"api_key": "apiKey",
|
|
49
|
+
"key": "apiKey",
|
|
50
|
+
"baseUrl": "baseUrl",
|
|
51
|
+
"base_url": "baseUrl",
|
|
52
|
+
"url": "baseUrl",
|
|
53
|
+
"taskDir": "taskDir",
|
|
54
|
+
"task_dir": "taskDir",
|
|
55
|
+
"tasks": "taskDir"
|
|
56
|
+
};
|
|
57
|
+
const configKey = keyMap[key] || key;
|
|
58
|
+
const value = config[configKey];
|
|
59
|
+
return value ? String(value) : void 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export {
|
|
63
|
+
CONFIG_DIR,
|
|
64
|
+
CONFIG_FILE,
|
|
65
|
+
DEFAULT_TASKS_DIR,
|
|
66
|
+
getConfigPath,
|
|
67
|
+
loadConfig,
|
|
68
|
+
saveConfig,
|
|
69
|
+
setConfigValue,
|
|
70
|
+
getConfigValue
|
|
71
|
+
};
|
package/dist/cli.cjs
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
18
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
19
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
20
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
21
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
22
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
23
|
+
mod
|
|
24
|
+
));
|
|
25
|
+
|
|
26
|
+
// src/config.ts
|
|
27
|
+
var import_path = __toESM(require("path"), 1);
|
|
28
|
+
var import_os = __toESM(require("os"), 1);
|
|
29
|
+
var import_fs = require("fs");
|
|
30
|
+
var CONFIG_DIR = import_path.default.join(import_os.default.homedir(), ".unityclaw");
|
|
31
|
+
var CONFIG_FILE = import_path.default.join(CONFIG_DIR, "config.json");
|
|
32
|
+
var DEFAULT_TASKS_DIR = import_path.default.join(import_os.default.homedir(), "Documents", "tasks");
|
|
33
|
+
function getConfigPath() {
|
|
34
|
+
return CONFIG_FILE;
|
|
35
|
+
}
|
|
36
|
+
function loadConfig() {
|
|
37
|
+
try {
|
|
38
|
+
if ((0, import_fs.existsSync)(CONFIG_FILE)) {
|
|
39
|
+
const content = (0, import_fs.readFileSync)(CONFIG_FILE, "utf-8");
|
|
40
|
+
return JSON.parse(content);
|
|
41
|
+
}
|
|
42
|
+
} catch {
|
|
43
|
+
}
|
|
44
|
+
return {};
|
|
45
|
+
}
|
|
46
|
+
function saveConfig(config) {
|
|
47
|
+
if (!(0, import_fs.existsSync)(CONFIG_DIR)) {
|
|
48
|
+
(0, import_fs.mkdirSync)(CONFIG_DIR, { recursive: true });
|
|
49
|
+
}
|
|
50
|
+
(0, import_fs.writeFileSync)(CONFIG_FILE, JSON.stringify(config, null, 2), "utf-8");
|
|
51
|
+
}
|
|
52
|
+
function setConfigValue(key, value) {
|
|
53
|
+
const config = loadConfig();
|
|
54
|
+
const keyMap = {
|
|
55
|
+
"apiKey": "apiKey",
|
|
56
|
+
"api_key": "apiKey",
|
|
57
|
+
"key": "apiKey",
|
|
58
|
+
"baseUrl": "baseUrl",
|
|
59
|
+
"base_url": "baseUrl",
|
|
60
|
+
"url": "baseUrl",
|
|
61
|
+
"taskDir": "taskDir",
|
|
62
|
+
"task_dir": "taskDir",
|
|
63
|
+
"tasks": "taskDir"
|
|
64
|
+
};
|
|
65
|
+
const configKey = keyMap[key] || key;
|
|
66
|
+
config[configKey] = value;
|
|
67
|
+
saveConfig(config);
|
|
68
|
+
}
|
|
69
|
+
function getConfigValue(key) {
|
|
70
|
+
const config = loadConfig();
|
|
71
|
+
const keyMap = {
|
|
72
|
+
"apiKey": "apiKey",
|
|
73
|
+
"api_key": "apiKey",
|
|
74
|
+
"key": "apiKey",
|
|
75
|
+
"baseUrl": "baseUrl",
|
|
76
|
+
"base_url": "baseUrl",
|
|
77
|
+
"url": "baseUrl",
|
|
78
|
+
"taskDir": "taskDir",
|
|
79
|
+
"task_dir": "taskDir",
|
|
80
|
+
"tasks": "taskDir"
|
|
81
|
+
};
|
|
82
|
+
const configKey = keyMap[key] || key;
|
|
83
|
+
const value = config[configKey];
|
|
84
|
+
return value ? String(value) : void 0;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// src/cli.ts
|
|
88
|
+
var args = process.argv.slice(2);
|
|
89
|
+
var command = args[0];
|
|
90
|
+
function showHelp() {
|
|
91
|
+
console.log(`
|
|
92
|
+
@unityclaw/sdk CLI - Configuration Management
|
|
93
|
+
|
|
94
|
+
Usage:
|
|
95
|
+
unityclaw-sdk config Show current configuration
|
|
96
|
+
unityclaw-sdk config set <key> <value> Set a configuration value
|
|
97
|
+
unityclaw-sdk config get <key> Get a configuration value
|
|
98
|
+
unityclaw-sdk config list List all configuration
|
|
99
|
+
|
|
100
|
+
Configuration keys:
|
|
101
|
+
apiKey API key for UnityClaw
|
|
102
|
+
baseUrl Base URL for API (default: https://unityclaw.com)
|
|
103
|
+
taskDir Directory for task folders (default: ~/.unityclaw/tasks)
|
|
104
|
+
|
|
105
|
+
Examples:
|
|
106
|
+
unityclaw-sdk config set apiKey your-api-key
|
|
107
|
+
unityclaw-sdk config set baseUrl https://custom.example.com
|
|
108
|
+
unityclaw-sdk config get apiKey
|
|
109
|
+
unityclaw-sdk config list
|
|
110
|
+
`);
|
|
111
|
+
}
|
|
112
|
+
if (!command || command === "help" || command === "--help" || command === "-h") {
|
|
113
|
+
showHelp();
|
|
114
|
+
process.exit(0);
|
|
115
|
+
}
|
|
116
|
+
if (command === "config") {
|
|
117
|
+
const action = args[1];
|
|
118
|
+
const key = args[2];
|
|
119
|
+
const value = args[3];
|
|
120
|
+
if (!action) {
|
|
121
|
+
const config = loadConfig();
|
|
122
|
+
console.log("\nCurrent configuration:\n");
|
|
123
|
+
console.log(` Config file: ${getConfigPath()}
|
|
124
|
+
`);
|
|
125
|
+
if (Object.keys(config).length === 0) {
|
|
126
|
+
console.log(" (empty - no configuration set)\n");
|
|
127
|
+
} else {
|
|
128
|
+
for (const [k, v] of Object.entries(config)) {
|
|
129
|
+
const displayValue = k === "apiKey" && v ? `${String(v).slice(0, 8)}...${String(v).slice(-4)}` : v;
|
|
130
|
+
console.log(` ${k}: ${displayValue}`);
|
|
131
|
+
}
|
|
132
|
+
console.log();
|
|
133
|
+
}
|
|
134
|
+
} else if (action === "set" && key && value) {
|
|
135
|
+
setConfigValue(key, value);
|
|
136
|
+
console.log(`\u2705 Config saved to ${getConfigPath()}`);
|
|
137
|
+
} else if (action === "get" && key) {
|
|
138
|
+
const val = getConfigValue(key);
|
|
139
|
+
if (val) {
|
|
140
|
+
console.log(val);
|
|
141
|
+
} else {
|
|
142
|
+
console.log(`(not set)`);
|
|
143
|
+
}
|
|
144
|
+
} else if (action === "list") {
|
|
145
|
+
const config = loadConfig();
|
|
146
|
+
console.log("\nConfiguration:\n");
|
|
147
|
+
for (const [k, v] of Object.entries(config)) {
|
|
148
|
+
const displayValue = k === "apiKey" && v ? `${String(v).slice(0, 8)}...${String(v).slice(-4)}` : v;
|
|
149
|
+
console.log(` ${k}: ${displayValue}`);
|
|
150
|
+
}
|
|
151
|
+
console.log();
|
|
152
|
+
} else {
|
|
153
|
+
console.error("Invalid usage. Run `unityclaw-sdk config --help` for help.");
|
|
154
|
+
process.exit(1);
|
|
155
|
+
}
|
|
156
|
+
} else {
|
|
157
|
+
console.error(`Unknown command: ${command}`);
|
|
158
|
+
showHelp();
|
|
159
|
+
process.exit(1);
|
|
160
|
+
}
|
package/dist/cli.d.cts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
getConfigPath,
|
|
4
|
+
getConfigValue,
|
|
5
|
+
loadConfig,
|
|
6
|
+
setConfigValue
|
|
7
|
+
} from "./chunk-SZITFMFH.js";
|
|
8
|
+
|
|
9
|
+
// src/cli.ts
|
|
10
|
+
var args = process.argv.slice(2);
|
|
11
|
+
var command = args[0];
|
|
12
|
+
function showHelp() {
|
|
13
|
+
console.log(`
|
|
14
|
+
@unityclaw/sdk CLI - Configuration Management
|
|
15
|
+
|
|
16
|
+
Usage:
|
|
17
|
+
unityclaw-sdk config Show current configuration
|
|
18
|
+
unityclaw-sdk config set <key> <value> Set a configuration value
|
|
19
|
+
unityclaw-sdk config get <key> Get a configuration value
|
|
20
|
+
unityclaw-sdk config list List all configuration
|
|
21
|
+
|
|
22
|
+
Configuration keys:
|
|
23
|
+
apiKey API key for UnityClaw
|
|
24
|
+
baseUrl Base URL for API (default: https://unityclaw.com)
|
|
25
|
+
taskDir Directory for task folders (default: ~/.unityclaw/tasks)
|
|
26
|
+
|
|
27
|
+
Examples:
|
|
28
|
+
unityclaw-sdk config set apiKey your-api-key
|
|
29
|
+
unityclaw-sdk config set baseUrl https://custom.example.com
|
|
30
|
+
unityclaw-sdk config get apiKey
|
|
31
|
+
unityclaw-sdk config list
|
|
32
|
+
`);
|
|
33
|
+
}
|
|
34
|
+
if (!command || command === "help" || command === "--help" || command === "-h") {
|
|
35
|
+
showHelp();
|
|
36
|
+
process.exit(0);
|
|
37
|
+
}
|
|
38
|
+
if (command === "config") {
|
|
39
|
+
const action = args[1];
|
|
40
|
+
const key = args[2];
|
|
41
|
+
const value = args[3];
|
|
42
|
+
if (!action) {
|
|
43
|
+
const config = loadConfig();
|
|
44
|
+
console.log("\nCurrent configuration:\n");
|
|
45
|
+
console.log(` Config file: ${getConfigPath()}
|
|
46
|
+
`);
|
|
47
|
+
if (Object.keys(config).length === 0) {
|
|
48
|
+
console.log(" (empty - no configuration set)\n");
|
|
49
|
+
} else {
|
|
50
|
+
for (const [k, v] of Object.entries(config)) {
|
|
51
|
+
const displayValue = k === "apiKey" && v ? `${String(v).slice(0, 8)}...${String(v).slice(-4)}` : v;
|
|
52
|
+
console.log(` ${k}: ${displayValue}`);
|
|
53
|
+
}
|
|
54
|
+
console.log();
|
|
55
|
+
}
|
|
56
|
+
} else if (action === "set" && key && value) {
|
|
57
|
+
setConfigValue(key, value);
|
|
58
|
+
console.log(`\u2705 Config saved to ${getConfigPath()}`);
|
|
59
|
+
} else if (action === "get" && key) {
|
|
60
|
+
const val = getConfigValue(key);
|
|
61
|
+
if (val) {
|
|
62
|
+
console.log(val);
|
|
63
|
+
} else {
|
|
64
|
+
console.log(`(not set)`);
|
|
65
|
+
}
|
|
66
|
+
} else if (action === "list") {
|
|
67
|
+
const config = loadConfig();
|
|
68
|
+
console.log("\nConfiguration:\n");
|
|
69
|
+
for (const [k, v] of Object.entries(config)) {
|
|
70
|
+
const displayValue = k === "apiKey" && v ? `${String(v).slice(0, 8)}...${String(v).slice(-4)}` : v;
|
|
71
|
+
console.log(` ${k}: ${displayValue}`);
|
|
72
|
+
}
|
|
73
|
+
console.log();
|
|
74
|
+
} else {
|
|
75
|
+
console.error("Invalid usage. Run `unityclaw-sdk config --help` for help.");
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
} else {
|
|
79
|
+
console.error(`Unknown command: ${command}`);
|
|
80
|
+
showHelp();
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
package/dist/index.cjs
CHANGED
|
@@ -30,18 +30,24 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
CONFIG_DIR: () => CONFIG_DIR,
|
|
34
|
+
CONFIG_FILE: () => CONFIG_FILE,
|
|
35
|
+
DEFAULT_TASKS_DIR: () => DEFAULT_TASKS_DIR,
|
|
33
36
|
DocumentAPI: () => DocumentAPI,
|
|
34
37
|
ImageAPI: () => ImageAPI,
|
|
35
38
|
MediaAPI: () => MediaAPI,
|
|
36
39
|
TaskFolderManager: () => TaskFolderManager,
|
|
37
40
|
UnityClawClient: () => UnityClawClient,
|
|
38
|
-
VideoAPI: () => VideoAPI
|
|
41
|
+
VideoAPI: () => VideoAPI,
|
|
42
|
+
getConfigPath: () => getConfigPath,
|
|
43
|
+
getConfigValue: () => getConfigValue,
|
|
44
|
+
loadConfig: () => loadConfig,
|
|
45
|
+
saveConfig: () => saveConfig,
|
|
46
|
+
setConfigValue: () => setConfigValue
|
|
39
47
|
});
|
|
40
48
|
module.exports = __toCommonJS(index_exports);
|
|
41
49
|
|
|
42
50
|
// src/client.ts
|
|
43
|
-
var import_path2 = __toESM(require("path"), 1);
|
|
44
|
-
var import_os = __toESM(require("os"), 1);
|
|
45
51
|
var import_axios2 = __toESM(require("axios"), 1);
|
|
46
52
|
|
|
47
53
|
// src/task-folder.ts
|
|
@@ -227,6 +233,67 @@ var TaskFolderManager = class {
|
|
|
227
233
|
}
|
|
228
234
|
};
|
|
229
235
|
|
|
236
|
+
// src/config.ts
|
|
237
|
+
var import_path2 = __toESM(require("path"), 1);
|
|
238
|
+
var import_os = __toESM(require("os"), 1);
|
|
239
|
+
var import_fs2 = require("fs");
|
|
240
|
+
var CONFIG_DIR = import_path2.default.join(import_os.default.homedir(), ".unityclaw");
|
|
241
|
+
var CONFIG_FILE = import_path2.default.join(CONFIG_DIR, "config.json");
|
|
242
|
+
var DEFAULT_TASKS_DIR = import_path2.default.join(import_os.default.homedir(), "Documents", "tasks");
|
|
243
|
+
function getConfigPath() {
|
|
244
|
+
return CONFIG_FILE;
|
|
245
|
+
}
|
|
246
|
+
function loadConfig() {
|
|
247
|
+
try {
|
|
248
|
+
if ((0, import_fs2.existsSync)(CONFIG_FILE)) {
|
|
249
|
+
const content = (0, import_fs2.readFileSync)(CONFIG_FILE, "utf-8");
|
|
250
|
+
return JSON.parse(content);
|
|
251
|
+
}
|
|
252
|
+
} catch {
|
|
253
|
+
}
|
|
254
|
+
return {};
|
|
255
|
+
}
|
|
256
|
+
function saveConfig(config) {
|
|
257
|
+
if (!(0, import_fs2.existsSync)(CONFIG_DIR)) {
|
|
258
|
+
(0, import_fs2.mkdirSync)(CONFIG_DIR, { recursive: true });
|
|
259
|
+
}
|
|
260
|
+
(0, import_fs2.writeFileSync)(CONFIG_FILE, JSON.stringify(config, null, 2), "utf-8");
|
|
261
|
+
}
|
|
262
|
+
function setConfigValue(key, value) {
|
|
263
|
+
const config = loadConfig();
|
|
264
|
+
const keyMap = {
|
|
265
|
+
"apiKey": "apiKey",
|
|
266
|
+
"api_key": "apiKey",
|
|
267
|
+
"key": "apiKey",
|
|
268
|
+
"baseUrl": "baseUrl",
|
|
269
|
+
"base_url": "baseUrl",
|
|
270
|
+
"url": "baseUrl",
|
|
271
|
+
"taskDir": "taskDir",
|
|
272
|
+
"task_dir": "taskDir",
|
|
273
|
+
"tasks": "taskDir"
|
|
274
|
+
};
|
|
275
|
+
const configKey = keyMap[key] || key;
|
|
276
|
+
config[configKey] = value;
|
|
277
|
+
saveConfig(config);
|
|
278
|
+
}
|
|
279
|
+
function getConfigValue(key) {
|
|
280
|
+
const config = loadConfig();
|
|
281
|
+
const keyMap = {
|
|
282
|
+
"apiKey": "apiKey",
|
|
283
|
+
"api_key": "apiKey",
|
|
284
|
+
"key": "apiKey",
|
|
285
|
+
"baseUrl": "baseUrl",
|
|
286
|
+
"base_url": "baseUrl",
|
|
287
|
+
"url": "baseUrl",
|
|
288
|
+
"taskDir": "taskDir",
|
|
289
|
+
"task_dir": "taskDir",
|
|
290
|
+
"tasks": "taskDir"
|
|
291
|
+
};
|
|
292
|
+
const configKey = keyMap[key] || key;
|
|
293
|
+
const value = config[configKey];
|
|
294
|
+
return value ? String(value) : void 0;
|
|
295
|
+
}
|
|
296
|
+
|
|
230
297
|
// src/apis/image.ts
|
|
231
298
|
var ImageAPI = class {
|
|
232
299
|
constructor(client) {
|
|
@@ -708,6 +775,16 @@ var MediaAPI = class {
|
|
|
708
775
|
// src/client.ts
|
|
709
776
|
var DEFAULT_BASE_URL = "https://unityclaw.com";
|
|
710
777
|
var DEFAULT_TIMEOUT = 3e5;
|
|
778
|
+
var OLD_DOMAINS = ["fieldshortcut.cn", "fieldshortcut.com"];
|
|
779
|
+
var NEW_DOMAIN = "unityclaw.com";
|
|
780
|
+
function replaceOldDomains(text) {
|
|
781
|
+
if (!text || typeof text !== "string") return text;
|
|
782
|
+
let result = text;
|
|
783
|
+
for (const oldDomain of OLD_DOMAINS) {
|
|
784
|
+
result = result.replace(new RegExp(oldDomain.replace(/\./g, "\\."), "g"), NEW_DOMAIN);
|
|
785
|
+
}
|
|
786
|
+
return result;
|
|
787
|
+
}
|
|
711
788
|
var UnityClawClient = class {
|
|
712
789
|
config;
|
|
713
790
|
httpClient;
|
|
@@ -718,21 +795,16 @@ var UnityClawClient = class {
|
|
|
718
795
|
document;
|
|
719
796
|
media;
|
|
720
797
|
constructor(config = {}) {
|
|
721
|
-
const
|
|
722
|
-
const
|
|
798
|
+
const fileConfig = loadConfig();
|
|
799
|
+
const apiKey = config.apiKey ?? process.env.UNITYCLAW_API_KEY ?? fileConfig.apiKey ?? "";
|
|
800
|
+
const baseUrl = config.baseUrl ?? process.env.UNITYCLAW_BASE_URL ?? fileConfig.baseUrl ?? DEFAULT_BASE_URL;
|
|
723
801
|
if (!apiKey) {
|
|
724
802
|
throw new Error("API key is required. Set UNITYCLAW_API_KEY environment variable or pass apiKey in config.");
|
|
725
803
|
}
|
|
726
804
|
this.config = {
|
|
727
805
|
apiKey,
|
|
728
806
|
baseUrl,
|
|
729
|
-
taskDir: config.taskDir ??
|
|
730
|
-
try {
|
|
731
|
-
return import_path2.default.join(process.cwd(), "tasks");
|
|
732
|
-
} catch {
|
|
733
|
-
return import_path2.default.join(import_os.default.homedir(), "tasks");
|
|
734
|
-
}
|
|
735
|
-
})(),
|
|
807
|
+
taskDir: config.taskDir ?? fileConfig.taskDir ?? DEFAULT_TASKS_DIR,
|
|
736
808
|
timeout: config.timeout ?? DEFAULT_TIMEOUT,
|
|
737
809
|
downloadAttachments: config.downloadAttachments ?? true,
|
|
738
810
|
context: config.context ?? {}
|
|
@@ -819,6 +891,9 @@ var UnityClawClient = class {
|
|
|
819
891
|
await this.taskFolderManager.writeRequest(taskCtx, endpoint, params, context);
|
|
820
892
|
await this.taskFolderManager.log(taskCtx, "info", "Request prepared", { endpoint, params });
|
|
821
893
|
const response = await this.httpClient.post(endpoint, requestBody);
|
|
894
|
+
if (response.data.msg) {
|
|
895
|
+
response.data.msg = replaceOldDomains(response.data.msg);
|
|
896
|
+
}
|
|
822
897
|
await this.taskFolderManager.writeResponse(taskCtx, response.data);
|
|
823
898
|
await this.taskFolderManager.log(taskCtx, "info", "Response received", {
|
|
824
899
|
code: response.data.code,
|
|
@@ -846,7 +921,8 @@ var UnityClawClient = class {
|
|
|
846
921
|
response.data.code === 0
|
|
847
922
|
);
|
|
848
923
|
} catch (error) {
|
|
849
|
-
const
|
|
924
|
+
const rawErrorMessage = error instanceof import_axios2.AxiosError ? error.response?.data?.msg || error.message : error instanceof Error ? error.message : String(error);
|
|
925
|
+
const errorMessage = replaceOldDomains(rawErrorMessage);
|
|
850
926
|
await this.taskFolderManager.log(taskCtx, "error", `Request failed: ${errorMessage}`, {
|
|
851
927
|
error: error instanceof import_axios2.AxiosError ? { status: error.response?.status, data: error.response?.data } : error
|
|
852
928
|
});
|
|
@@ -910,10 +986,18 @@ var UnityClawClient = class {
|
|
|
910
986
|
};
|
|
911
987
|
// Annotate the CommonJS export names for ESM import in node:
|
|
912
988
|
0 && (module.exports = {
|
|
989
|
+
CONFIG_DIR,
|
|
990
|
+
CONFIG_FILE,
|
|
991
|
+
DEFAULT_TASKS_DIR,
|
|
913
992
|
DocumentAPI,
|
|
914
993
|
ImageAPI,
|
|
915
994
|
MediaAPI,
|
|
916
995
|
TaskFolderManager,
|
|
917
996
|
UnityClawClient,
|
|
918
|
-
VideoAPI
|
|
997
|
+
VideoAPI,
|
|
998
|
+
getConfigPath,
|
|
999
|
+
getConfigValue,
|
|
1000
|
+
loadConfig,
|
|
1001
|
+
saveConfig,
|
|
1002
|
+
setConfigValue
|
|
919
1003
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -804,4 +804,31 @@ declare class UnityClawClient {
|
|
|
804
804
|
analyzeMedia(params: MediaAnalysisParams): Promise<TaskResult<APIResponse<MediaAnalysisResult>>>;
|
|
805
805
|
}
|
|
806
806
|
|
|
807
|
-
|
|
807
|
+
/**
|
|
808
|
+
* UnityClaw SDK Config Management
|
|
809
|
+
* Shared configuration for SDK and CLI tools
|
|
810
|
+
*/
|
|
811
|
+
/** Config directory */
|
|
812
|
+
declare const CONFIG_DIR: string;
|
|
813
|
+
/** Config file path */
|
|
814
|
+
declare const CONFIG_FILE: string;
|
|
815
|
+
/** Default tasks directory - in Documents so users can easily find results */
|
|
816
|
+
declare const DEFAULT_TASKS_DIR: string;
|
|
817
|
+
/** UnityClaw configuration */
|
|
818
|
+
interface UnityClawConfig {
|
|
819
|
+
apiKey?: string;
|
|
820
|
+
baseUrl?: string;
|
|
821
|
+
taskDir?: string;
|
|
822
|
+
}
|
|
823
|
+
/** Get config file path */
|
|
824
|
+
declare function getConfigPath(): string;
|
|
825
|
+
/** Load config from ~/.unityclaw/config.json */
|
|
826
|
+
declare function loadConfig(): UnityClawConfig;
|
|
827
|
+
/** Save config to file */
|
|
828
|
+
declare function saveConfig(config: UnityClawConfig): void;
|
|
829
|
+
/** Set a config value */
|
|
830
|
+
declare function setConfigValue(key: string, value: string): void;
|
|
831
|
+
/** Get a config value */
|
|
832
|
+
declare function getConfigValue(key: string): string | undefined;
|
|
833
|
+
|
|
834
|
+
export { type APIResponse, type AttachmentFieldItem, type AttachmentResult, type BitableContext, CONFIG_DIR, CONFIG_FILE, type Context, DEFAULT_TASKS_DIR, type DeepPartial, type DocConvertParams, type DocTranslateParams, DocumentAPI, type DoubaoVideoParams, type GeminiImageParams, ImageAPI, type ImageGenParams, type JiMengImageParams, type JiMengVideoParams, type KlingVideoParams, type LabelFieldItem, type LabelValue, MediaAPI, type MediaAnalysisParams, type MediaAnalysisResult, type MiniMaxVideoParams, type OpenClawShortcutParams, type SDKContext, type SoraVideoParams, type TaskFolderContext, TaskFolderManager, type TaskFolderOptions, type TaskLog, type TaskResult, type TextFieldItem, type TextInput, UnityClawClient, type UnityClawClientConfig, type UnityClawConfig, type UrlFieldItem, type VeoVideoParams, VideoAPI, type WanVideoParams, getConfigPath, getConfigValue, loadConfig, saveConfig, setConfigValue };
|
package/dist/index.d.ts
CHANGED
|
@@ -804,4 +804,31 @@ declare class UnityClawClient {
|
|
|
804
804
|
analyzeMedia(params: MediaAnalysisParams): Promise<TaskResult<APIResponse<MediaAnalysisResult>>>;
|
|
805
805
|
}
|
|
806
806
|
|
|
807
|
-
|
|
807
|
+
/**
|
|
808
|
+
* UnityClaw SDK Config Management
|
|
809
|
+
* Shared configuration for SDK and CLI tools
|
|
810
|
+
*/
|
|
811
|
+
/** Config directory */
|
|
812
|
+
declare const CONFIG_DIR: string;
|
|
813
|
+
/** Config file path */
|
|
814
|
+
declare const CONFIG_FILE: string;
|
|
815
|
+
/** Default tasks directory - in Documents so users can easily find results */
|
|
816
|
+
declare const DEFAULT_TASKS_DIR: string;
|
|
817
|
+
/** UnityClaw configuration */
|
|
818
|
+
interface UnityClawConfig {
|
|
819
|
+
apiKey?: string;
|
|
820
|
+
baseUrl?: string;
|
|
821
|
+
taskDir?: string;
|
|
822
|
+
}
|
|
823
|
+
/** Get config file path */
|
|
824
|
+
declare function getConfigPath(): string;
|
|
825
|
+
/** Load config from ~/.unityclaw/config.json */
|
|
826
|
+
declare function loadConfig(): UnityClawConfig;
|
|
827
|
+
/** Save config to file */
|
|
828
|
+
declare function saveConfig(config: UnityClawConfig): void;
|
|
829
|
+
/** Set a config value */
|
|
830
|
+
declare function setConfigValue(key: string, value: string): void;
|
|
831
|
+
/** Get a config value */
|
|
832
|
+
declare function getConfigValue(key: string): string | undefined;
|
|
833
|
+
|
|
834
|
+
export { type APIResponse, type AttachmentFieldItem, type AttachmentResult, type BitableContext, CONFIG_DIR, CONFIG_FILE, type Context, DEFAULT_TASKS_DIR, type DeepPartial, type DocConvertParams, type DocTranslateParams, DocumentAPI, type DoubaoVideoParams, type GeminiImageParams, ImageAPI, type ImageGenParams, type JiMengImageParams, type JiMengVideoParams, type KlingVideoParams, type LabelFieldItem, type LabelValue, MediaAPI, type MediaAnalysisParams, type MediaAnalysisResult, type MiniMaxVideoParams, type OpenClawShortcutParams, type SDKContext, type SoraVideoParams, type TaskFolderContext, TaskFolderManager, type TaskFolderOptions, type TaskLog, type TaskResult, type TextFieldItem, type TextInput, UnityClawClient, type UnityClawClientConfig, type UnityClawConfig, type UrlFieldItem, type VeoVideoParams, VideoAPI, type WanVideoParams, getConfigPath, getConfigValue, loadConfig, saveConfig, setConfigValue };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CONFIG_DIR,
|
|
3
|
+
CONFIG_FILE,
|
|
4
|
+
DEFAULT_TASKS_DIR,
|
|
5
|
+
getConfigPath,
|
|
6
|
+
getConfigValue,
|
|
7
|
+
loadConfig,
|
|
8
|
+
saveConfig,
|
|
9
|
+
setConfigValue
|
|
10
|
+
} from "./chunk-SZITFMFH.js";
|
|
11
|
+
|
|
1
12
|
// src/client.ts
|
|
2
|
-
import path from "path";
|
|
3
|
-
import os from "os";
|
|
4
13
|
import axios2, { AxiosError } from "axios";
|
|
5
14
|
|
|
6
15
|
// src/task-folder.ts
|
|
@@ -667,6 +676,16 @@ var MediaAPI = class {
|
|
|
667
676
|
// src/client.ts
|
|
668
677
|
var DEFAULT_BASE_URL = "https://unityclaw.com";
|
|
669
678
|
var DEFAULT_TIMEOUT = 3e5;
|
|
679
|
+
var OLD_DOMAINS = ["fieldshortcut.cn", "fieldshortcut.com"];
|
|
680
|
+
var NEW_DOMAIN = "unityclaw.com";
|
|
681
|
+
function replaceOldDomains(text) {
|
|
682
|
+
if (!text || typeof text !== "string") return text;
|
|
683
|
+
let result = text;
|
|
684
|
+
for (const oldDomain of OLD_DOMAINS) {
|
|
685
|
+
result = result.replace(new RegExp(oldDomain.replace(/\./g, "\\."), "g"), NEW_DOMAIN);
|
|
686
|
+
}
|
|
687
|
+
return result;
|
|
688
|
+
}
|
|
670
689
|
var UnityClawClient = class {
|
|
671
690
|
config;
|
|
672
691
|
httpClient;
|
|
@@ -677,21 +696,16 @@ var UnityClawClient = class {
|
|
|
677
696
|
document;
|
|
678
697
|
media;
|
|
679
698
|
constructor(config = {}) {
|
|
680
|
-
const
|
|
681
|
-
const
|
|
699
|
+
const fileConfig = loadConfig();
|
|
700
|
+
const apiKey = config.apiKey ?? process.env.UNITYCLAW_API_KEY ?? fileConfig.apiKey ?? "";
|
|
701
|
+
const baseUrl = config.baseUrl ?? process.env.UNITYCLAW_BASE_URL ?? fileConfig.baseUrl ?? DEFAULT_BASE_URL;
|
|
682
702
|
if (!apiKey) {
|
|
683
703
|
throw new Error("API key is required. Set UNITYCLAW_API_KEY environment variable or pass apiKey in config.");
|
|
684
704
|
}
|
|
685
705
|
this.config = {
|
|
686
706
|
apiKey,
|
|
687
707
|
baseUrl,
|
|
688
|
-
taskDir: config.taskDir ??
|
|
689
|
-
try {
|
|
690
|
-
return path.join(process.cwd(), "tasks");
|
|
691
|
-
} catch {
|
|
692
|
-
return path.join(os.homedir(), "tasks");
|
|
693
|
-
}
|
|
694
|
-
})(),
|
|
708
|
+
taskDir: config.taskDir ?? fileConfig.taskDir ?? DEFAULT_TASKS_DIR,
|
|
695
709
|
timeout: config.timeout ?? DEFAULT_TIMEOUT,
|
|
696
710
|
downloadAttachments: config.downloadAttachments ?? true,
|
|
697
711
|
context: config.context ?? {}
|
|
@@ -778,6 +792,9 @@ var UnityClawClient = class {
|
|
|
778
792
|
await this.taskFolderManager.writeRequest(taskCtx, endpoint, params, context);
|
|
779
793
|
await this.taskFolderManager.log(taskCtx, "info", "Request prepared", { endpoint, params });
|
|
780
794
|
const response = await this.httpClient.post(endpoint, requestBody);
|
|
795
|
+
if (response.data.msg) {
|
|
796
|
+
response.data.msg = replaceOldDomains(response.data.msg);
|
|
797
|
+
}
|
|
781
798
|
await this.taskFolderManager.writeResponse(taskCtx, response.data);
|
|
782
799
|
await this.taskFolderManager.log(taskCtx, "info", "Response received", {
|
|
783
800
|
code: response.data.code,
|
|
@@ -805,7 +822,8 @@ var UnityClawClient = class {
|
|
|
805
822
|
response.data.code === 0
|
|
806
823
|
);
|
|
807
824
|
} catch (error) {
|
|
808
|
-
const
|
|
825
|
+
const rawErrorMessage = error instanceof AxiosError ? error.response?.data?.msg || error.message : error instanceof Error ? error.message : String(error);
|
|
826
|
+
const errorMessage = replaceOldDomains(rawErrorMessage);
|
|
809
827
|
await this.taskFolderManager.log(taskCtx, "error", `Request failed: ${errorMessage}`, {
|
|
810
828
|
error: error instanceof AxiosError ? { status: error.response?.status, data: error.response?.data } : error
|
|
811
829
|
});
|
|
@@ -868,10 +886,18 @@ var UnityClawClient = class {
|
|
|
868
886
|
}
|
|
869
887
|
};
|
|
870
888
|
export {
|
|
889
|
+
CONFIG_DIR,
|
|
890
|
+
CONFIG_FILE,
|
|
891
|
+
DEFAULT_TASKS_DIR,
|
|
871
892
|
DocumentAPI,
|
|
872
893
|
ImageAPI,
|
|
873
894
|
MediaAPI,
|
|
874
895
|
TaskFolderManager,
|
|
875
896
|
UnityClawClient,
|
|
876
|
-
VideoAPI
|
|
897
|
+
VideoAPI,
|
|
898
|
+
getConfigPath,
|
|
899
|
+
getConfigValue,
|
|
900
|
+
loadConfig,
|
|
901
|
+
saveConfig,
|
|
902
|
+
setConfigValue
|
|
877
903
|
};
|
package/package.json
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unityclaw/sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "Node.js SDK for UnityClaw API - AI-powered image/video generation, media analysis, and more",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"unityclaw-sdk": "./dist/cli.js"
|
|
8
|
+
},
|
|
6
9
|
"main": "./dist/index.cjs",
|
|
7
10
|
"module": "./dist/index.js",
|
|
8
11
|
"types": "./dist/index.d.ts",
|
|
@@ -15,11 +18,12 @@
|
|
|
15
18
|
},
|
|
16
19
|
"files": [
|
|
17
20
|
"dist",
|
|
18
|
-
"README.md"
|
|
21
|
+
"README.md",
|
|
22
|
+
"src/cli.ts"
|
|
19
23
|
],
|
|
20
24
|
"scripts": {
|
|
21
|
-
"build": "tsup src/index.ts --format cjs,esm --dts --clean",
|
|
22
|
-
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
25
|
+
"build": "tsup src/index.ts src/cli.ts --format cjs,esm --dts --clean",
|
|
26
|
+
"dev": "tsup src/index.ts src/cli.ts --format cjs,esm --dts --watch",
|
|
23
27
|
"typecheck": "tsc --noEmit",
|
|
24
28
|
"prepublishOnly": "npm run build"
|
|
25
29
|
},
|
package/src/cli.ts
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @unityclaw/sdk CLI
|
|
4
|
+
* Configuration management for UnityClaw SDK
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
loadConfig,
|
|
9
|
+
setConfigValue,
|
|
10
|
+
getConfigValue,
|
|
11
|
+
getConfigPath,
|
|
12
|
+
} from './config.js';
|
|
13
|
+
|
|
14
|
+
const args = process.argv.slice(2);
|
|
15
|
+
const command = args[0];
|
|
16
|
+
|
|
17
|
+
function showHelp() {
|
|
18
|
+
console.log(`
|
|
19
|
+
@unityclaw/sdk CLI - Configuration Management
|
|
20
|
+
|
|
21
|
+
Usage:
|
|
22
|
+
unityclaw-sdk config Show current configuration
|
|
23
|
+
unityclaw-sdk config set <key> <value> Set a configuration value
|
|
24
|
+
unityclaw-sdk config get <key> Get a configuration value
|
|
25
|
+
unityclaw-sdk config list List all configuration
|
|
26
|
+
|
|
27
|
+
Configuration keys:
|
|
28
|
+
apiKey API key for UnityClaw
|
|
29
|
+
baseUrl Base URL for API (default: https://unityclaw.com)
|
|
30
|
+
taskDir Directory for task folders (default: ~/.unityclaw/tasks)
|
|
31
|
+
|
|
32
|
+
Examples:
|
|
33
|
+
unityclaw-sdk config set apiKey your-api-key
|
|
34
|
+
unityclaw-sdk config set baseUrl https://custom.example.com
|
|
35
|
+
unityclaw-sdk config get apiKey
|
|
36
|
+
unityclaw-sdk config list
|
|
37
|
+
`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (!command || command === 'help' || command === '--help' || command === '-h') {
|
|
41
|
+
showHelp();
|
|
42
|
+
process.exit(0);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (command === 'config') {
|
|
46
|
+
const action = args[1];
|
|
47
|
+
const key = args[2];
|
|
48
|
+
const value = args[3];
|
|
49
|
+
|
|
50
|
+
if (!action) {
|
|
51
|
+
// Show current config
|
|
52
|
+
const config = loadConfig();
|
|
53
|
+
console.log('\nCurrent configuration:\n');
|
|
54
|
+
console.log(` Config file: ${getConfigPath()}\n`);
|
|
55
|
+
if (Object.keys(config).length === 0) {
|
|
56
|
+
console.log(' (empty - no configuration set)\n');
|
|
57
|
+
} else {
|
|
58
|
+
for (const [k, v] of Object.entries(config)) {
|
|
59
|
+
// Mask API key for security
|
|
60
|
+
const displayValue = k === 'apiKey' && v
|
|
61
|
+
? `${String(v).slice(0, 8)}...${String(v).slice(-4)}`
|
|
62
|
+
: v;
|
|
63
|
+
console.log(` ${k}: ${displayValue}`);
|
|
64
|
+
}
|
|
65
|
+
console.log();
|
|
66
|
+
}
|
|
67
|
+
} else if (action === 'set' && key && value) {
|
|
68
|
+
setConfigValue(key, value);
|
|
69
|
+
console.log(`✅ Config saved to ${getConfigPath()}`);
|
|
70
|
+
} else if (action === 'get' && key) {
|
|
71
|
+
const val = getConfigValue(key);
|
|
72
|
+
if (val) {
|
|
73
|
+
console.log(val);
|
|
74
|
+
} else {
|
|
75
|
+
console.log(`(not set)`);
|
|
76
|
+
}
|
|
77
|
+
} else if (action === 'list') {
|
|
78
|
+
const config = loadConfig();
|
|
79
|
+
console.log('\nConfiguration:\n');
|
|
80
|
+
for (const [k, v] of Object.entries(config)) {
|
|
81
|
+
const displayValue = k === 'apiKey' && v
|
|
82
|
+
? `${String(v).slice(0, 8)}...${String(v).slice(-4)}`
|
|
83
|
+
: v;
|
|
84
|
+
console.log(` ${k}: ${displayValue}`);
|
|
85
|
+
}
|
|
86
|
+
console.log();
|
|
87
|
+
} else {
|
|
88
|
+
console.error('Invalid usage. Run `unityclaw-sdk config --help` for help.');
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
} else {
|
|
92
|
+
console.error(`Unknown command: ${command}`);
|
|
93
|
+
showHelp();
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|