openclawmp 0.1.4 → 0.1.6
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/lib/commands/comment.js +101 -83
- package/lib/commands/issue.js +121 -89
- package/lib/commands/publish.js +472 -306
- package/lib/config.js +104 -97
- package/package.json +2 -2
package/lib/config.js
CHANGED
|
@@ -5,115 +5,119 @@
|
|
|
5
5
|
// Stores: auth tokens, preferences
|
|
6
6
|
// ============================================================================
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
"use strict";
|
|
9
9
|
|
|
10
|
-
const fs = require(
|
|
11
|
-
const path = require(
|
|
12
|
-
const os = require(
|
|
10
|
+
const fs = require("fs");
|
|
11
|
+
const path = require("path");
|
|
12
|
+
const os = require("os");
|
|
13
13
|
|
|
14
|
-
const CONFIG_DIR = path.join(os.homedir(),
|
|
15
|
-
const AUTH_FILE = path.join(CONFIG_DIR,
|
|
16
|
-
const CREDENTIALS_FILE = path.join(CONFIG_DIR,
|
|
14
|
+
const CONFIG_DIR = path.join(os.homedir(), ".openclawmp");
|
|
15
|
+
const AUTH_FILE = path.join(CONFIG_DIR, "auth.json");
|
|
16
|
+
const CREDENTIALS_FILE = path.join(CONFIG_DIR, "credentials.json");
|
|
17
17
|
|
|
18
18
|
// Default API base — can be overridden by --api flag or OPENCLAWMP_API env
|
|
19
|
-
let API_BASE =
|
|
19
|
+
let API_BASE = "https://openclawmp.cc";
|
|
20
|
+
// let API_BASE = "http://localhost:3001";
|
|
20
21
|
|
|
21
22
|
// OpenClaw state directory (for lockfile, install dirs, device identity)
|
|
22
|
-
const OPENCLAW_STATE_DIR =
|
|
23
|
-
|
|
24
|
-
const
|
|
23
|
+
const OPENCLAW_STATE_DIR =
|
|
24
|
+
process.env.OPENCLAW_STATE_DIR || path.join(os.homedir(), ".openclaw");
|
|
25
|
+
const LOCKFILE = path.join(OPENCLAW_STATE_DIR, "seafood-lock.json");
|
|
26
|
+
const DEVICE_JSON = path.join(OPENCLAW_STATE_DIR, "identity", "device.json");
|
|
25
27
|
|
|
26
28
|
// Valid asset types and their install subdirectories
|
|
27
29
|
const ASSET_TYPES = {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
skill: "skills",
|
|
31
|
+
plugin: "extensions",
|
|
32
|
+
trigger: "triggers",
|
|
33
|
+
channel: "extensions",
|
|
34
|
+
experience: "experiences",
|
|
33
35
|
};
|
|
34
36
|
|
|
35
37
|
/**
|
|
36
38
|
* Ensure config directory exists
|
|
37
39
|
*/
|
|
38
40
|
function ensureConfigDir() {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
if (!fs.existsSync(CONFIG_DIR)) {
|
|
42
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
43
|
+
}
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
/**
|
|
45
47
|
* Get the install directory for a given asset type
|
|
46
48
|
*/
|
|
47
49
|
function installDirForType(type) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
const subdir = ASSET_TYPES[type];
|
|
51
|
+
if (!subdir) {
|
|
52
|
+
throw new Error(
|
|
53
|
+
`Unknown asset type: ${type}. Valid types: ${Object.keys(ASSET_TYPES).join(", ")}`,
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
return path.join(OPENCLAW_STATE_DIR, subdir);
|
|
53
57
|
}
|
|
54
58
|
|
|
55
59
|
/**
|
|
56
60
|
* Get/set API base URL
|
|
57
61
|
*/
|
|
58
62
|
function getApiBase() {
|
|
59
|
-
|
|
63
|
+
return API_BASE;
|
|
60
64
|
}
|
|
61
65
|
|
|
62
66
|
function setApiBase(url) {
|
|
63
|
-
|
|
64
|
-
|
|
67
|
+
// Strip trailing slash
|
|
68
|
+
API_BASE = url.replace(/\/+$/, "");
|
|
65
69
|
}
|
|
66
70
|
|
|
67
71
|
/**
|
|
68
72
|
* Read auth token (priority: env var > auth.json > credentials.json)
|
|
69
73
|
*/
|
|
70
74
|
function getAuthToken() {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
+
// 1. Environment variable (highest priority)
|
|
76
|
+
if (process.env.OPENCLAWMP_TOKEN) {
|
|
77
|
+
return process.env.OPENCLAWMP_TOKEN;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
ensureConfigDir();
|
|
81
|
+
|
|
82
|
+
// 2. auth.json (format: { token: "sk-xxx" })
|
|
83
|
+
if (fs.existsSync(AUTH_FILE)) {
|
|
84
|
+
try {
|
|
85
|
+
const data = JSON.parse(fs.readFileSync(AUTH_FILE, "utf-8"));
|
|
86
|
+
if (data.token) return data.token;
|
|
87
|
+
} catch {}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// 3. credentials.json (format: { api_key: "sk-xxx" })
|
|
91
|
+
if (fs.existsSync(CREDENTIALS_FILE)) {
|
|
92
|
+
try {
|
|
93
|
+
const data = JSON.parse(fs.readFileSync(CREDENTIALS_FILE, "utf-8"));
|
|
94
|
+
if (data.api_key) return data.api_key;
|
|
95
|
+
} catch {}
|
|
96
|
+
}
|
|
75
97
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
// 2. auth.json (format: { token: "sk-xxx" })
|
|
79
|
-
if (fs.existsSync(AUTH_FILE)) {
|
|
80
|
-
try {
|
|
81
|
-
const data = JSON.parse(fs.readFileSync(AUTH_FILE, 'utf-8'));
|
|
82
|
-
if (data.token) return data.token;
|
|
83
|
-
} catch {}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// 3. credentials.json (format: { api_key: "sk-xxx" })
|
|
87
|
-
if (fs.existsSync(CREDENTIALS_FILE)) {
|
|
88
|
-
try {
|
|
89
|
-
const data = JSON.parse(fs.readFileSync(CREDENTIALS_FILE, 'utf-8'));
|
|
90
|
-
if (data.api_key) return data.api_key;
|
|
91
|
-
} catch {}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return null;
|
|
98
|
+
return null;
|
|
95
99
|
}
|
|
96
100
|
|
|
97
101
|
/**
|
|
98
102
|
* Save auth token
|
|
99
103
|
*/
|
|
100
104
|
function saveAuthToken(token, extra = {}) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
105
|
+
ensureConfigDir();
|
|
106
|
+
const data = { token, savedAt: new Date().toISOString(), ...extra };
|
|
107
|
+
fs.writeFileSync(AUTH_FILE, JSON.stringify(data, null, 2) + "\n");
|
|
104
108
|
}
|
|
105
109
|
|
|
106
110
|
/**
|
|
107
111
|
* Read the OpenClaw device ID
|
|
108
112
|
*/
|
|
109
113
|
function getDeviceId() {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
if (!fs.existsSync(DEVICE_JSON)) return null;
|
|
115
|
+
try {
|
|
116
|
+
const data = JSON.parse(fs.readFileSync(DEVICE_JSON, "utf-8"));
|
|
117
|
+
return data.deviceId || null;
|
|
118
|
+
} catch {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
117
121
|
}
|
|
118
122
|
|
|
119
123
|
// === Lockfile operations ===
|
|
@@ -122,62 +126,65 @@ function getDeviceId() {
|
|
|
122
126
|
* Initialize lockfile if it doesn't exist
|
|
123
127
|
*/
|
|
124
128
|
function initLockfile() {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
129
|
+
if (!fs.existsSync(LOCKFILE)) {
|
|
130
|
+
const dir = path.dirname(LOCKFILE);
|
|
131
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
132
|
+
fs.writeFileSync(
|
|
133
|
+
LOCKFILE,
|
|
134
|
+
JSON.stringify({ version: 1, installed: {} }, null, 2) + "\n",
|
|
135
|
+
);
|
|
136
|
+
}
|
|
130
137
|
}
|
|
131
138
|
|
|
132
139
|
/**
|
|
133
140
|
* Read the lockfile
|
|
134
141
|
*/
|
|
135
142
|
function readLockfile() {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
143
|
+
initLockfile();
|
|
144
|
+
try {
|
|
145
|
+
return JSON.parse(fs.readFileSync(LOCKFILE, "utf-8"));
|
|
146
|
+
} catch {
|
|
147
|
+
return { version: 1, installed: {} };
|
|
148
|
+
}
|
|
142
149
|
}
|
|
143
150
|
|
|
144
151
|
/**
|
|
145
152
|
* Update a lockfile entry
|
|
146
153
|
*/
|
|
147
154
|
function updateLockfile(key, version, location) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
+
const lock = readLockfile();
|
|
156
|
+
lock.installed[key] = {
|
|
157
|
+
version,
|
|
158
|
+
installedAt: new Date().toISOString(),
|
|
159
|
+
location,
|
|
160
|
+
};
|
|
161
|
+
fs.writeFileSync(LOCKFILE, JSON.stringify(lock, null, 2) + "\n");
|
|
155
162
|
}
|
|
156
163
|
|
|
157
164
|
/**
|
|
158
165
|
* Remove a lockfile entry
|
|
159
166
|
*/
|
|
160
167
|
function removeLockfile(key) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
168
|
+
const lock = readLockfile();
|
|
169
|
+
delete lock.installed[key];
|
|
170
|
+
fs.writeFileSync(LOCKFILE, JSON.stringify(lock, null, 2) + "\n");
|
|
164
171
|
}
|
|
165
172
|
|
|
166
173
|
module.exports = {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
174
|
+
CONFIG_DIR,
|
|
175
|
+
OPENCLAW_STATE_DIR,
|
|
176
|
+
LOCKFILE,
|
|
177
|
+
DEVICE_JSON,
|
|
178
|
+
ASSET_TYPES,
|
|
179
|
+
ensureConfigDir,
|
|
180
|
+
installDirForType,
|
|
181
|
+
getApiBase,
|
|
182
|
+
setApiBase,
|
|
183
|
+
getAuthToken,
|
|
184
|
+
saveAuthToken,
|
|
185
|
+
getDeviceId,
|
|
186
|
+
initLockfile,
|
|
187
|
+
readLockfile,
|
|
188
|
+
updateLockfile,
|
|
189
|
+
removeLockfile,
|
|
183
190
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openclawmp",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.6",
|
|
4
|
+
"description": "🐟 OpenClaw Marketplace CLI — 水产市场命令行工具",
|
|
5
5
|
"bin": {
|
|
6
6
|
"openclawmp": "./bin/openclawmp.js"
|
|
7
7
|
},
|