@dimcool/mcp 0.1.27 → 0.1.29
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/dist/index.js +529 -72
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -41,7 +41,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
41
41
|
var require_XMLHttpRequest = __commonJS({
|
|
42
42
|
"../../node_modules/xmlhttprequest-ssl/lib/XMLHttpRequest.js"(exports, module) {
|
|
43
43
|
"use strict";
|
|
44
|
-
var
|
|
44
|
+
var fs2 = __require("fs");
|
|
45
45
|
var Url = __require("url");
|
|
46
46
|
var spawn = __require("child_process").spawn;
|
|
47
47
|
module.exports = XMLHttpRequest3;
|
|
@@ -199,7 +199,7 @@ var require_XMLHttpRequest = __commonJS({
|
|
|
199
199
|
throw new Error("XMLHttpRequest: Only GET method is supported");
|
|
200
200
|
}
|
|
201
201
|
if (settings.async) {
|
|
202
|
-
|
|
202
|
+
fs2.readFile(unescape(url2.pathname), function(error, data2) {
|
|
203
203
|
if (error) {
|
|
204
204
|
self2.handleError(error, error.errno || -1);
|
|
205
205
|
} else {
|
|
@@ -211,7 +211,7 @@ var require_XMLHttpRequest = __commonJS({
|
|
|
211
211
|
});
|
|
212
212
|
} else {
|
|
213
213
|
try {
|
|
214
|
-
this.response =
|
|
214
|
+
this.response = fs2.readFileSync(unescape(url2.pathname));
|
|
215
215
|
this.responseText = this.response.toString("utf8");
|
|
216
216
|
this.status = 200;
|
|
217
217
|
setState(self2.DONE);
|
|
@@ -337,15 +337,15 @@ var require_XMLHttpRequest = __commonJS({
|
|
|
337
337
|
} else {
|
|
338
338
|
var contentFile = ".node-xmlhttprequest-content-" + process.pid;
|
|
339
339
|
var syncFile = ".node-xmlhttprequest-sync-" + process.pid;
|
|
340
|
-
|
|
340
|
+
fs2.writeFileSync(syncFile, "", "utf8");
|
|
341
341
|
var execString = "var http = require('http'), https = require('https'), fs = require('fs');var doRequest = http" + (ssl ? "s" : "") + ".request;var options = " + JSON.stringify(options) + ";var responseText = '';var responseData = Buffer.alloc(0);var req = doRequest(options, function(response) {response.on('data', function(chunk) { var data = Buffer.from(chunk); responseText += data.toString('utf8'); responseData = Buffer.concat([responseData, data]);});response.on('end', function() {fs.writeFileSync('" + contentFile + "', JSON.stringify({err: null, data: {statusCode: response.statusCode, headers: response.headers, text: responseText, data: responseData.toString('base64')}}), 'utf8');fs.unlinkSync('" + syncFile + "');});response.on('error', function(error) {fs.writeFileSync('" + contentFile + "', 'NODE-XMLHTTPREQUEST-ERROR:' + JSON.stringify(error), 'utf8');fs.unlinkSync('" + syncFile + "');});}).on('error', function(error) {fs.writeFileSync('" + contentFile + "', 'NODE-XMLHTTPREQUEST-ERROR:' + JSON.stringify(error), 'utf8');fs.unlinkSync('" + syncFile + "');});" + (data ? "req.write('" + JSON.stringify(data).slice(1, -1).replace(/'/g, "\\'") + "');" : "") + "req.end();";
|
|
342
342
|
var syncProc = spawn(process.argv[0], ["-e", execString]);
|
|
343
343
|
var statusText;
|
|
344
|
-
while (
|
|
344
|
+
while (fs2.existsSync(syncFile)) {
|
|
345
345
|
}
|
|
346
|
-
self2.responseText =
|
|
346
|
+
self2.responseText = fs2.readFileSync(contentFile, "utf8");
|
|
347
347
|
syncProc.stdin.end();
|
|
348
|
-
|
|
348
|
+
fs2.unlinkSync(contentFile);
|
|
349
349
|
if (self2.responseText.match(/^NODE-XMLHTTPREQUEST-ERROR:/)) {
|
|
350
350
|
var errorObj = JSON.parse(self2.responseText.replace(/^NODE-XMLHTTPREQUEST-ERROR:/, ""));
|
|
351
351
|
self2.handleError(errorObj, 503);
|
|
@@ -1235,8 +1235,8 @@ var require_constants = __commonJS({
|
|
|
1235
1235
|
var require_node_gyp_build = __commonJS({
|
|
1236
1236
|
"../../node_modules/node-gyp-build/node-gyp-build.js"(exports, module) {
|
|
1237
1237
|
"use strict";
|
|
1238
|
-
var
|
|
1239
|
-
var
|
|
1238
|
+
var fs2 = __require("fs");
|
|
1239
|
+
var path3 = __require("path");
|
|
1240
1240
|
var os2 = __require("os");
|
|
1241
1241
|
var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
|
|
1242
1242
|
var vars = process.config && process.config.variables || {};
|
|
@@ -1253,21 +1253,21 @@ var require_node_gyp_build = __commonJS({
|
|
|
1253
1253
|
return runtimeRequire(load.resolve(dir));
|
|
1254
1254
|
}
|
|
1255
1255
|
load.resolve = load.path = function(dir) {
|
|
1256
|
-
dir =
|
|
1256
|
+
dir = path3.resolve(dir || ".");
|
|
1257
1257
|
try {
|
|
1258
|
-
var name = runtimeRequire(
|
|
1258
|
+
var name = runtimeRequire(path3.join(dir, "package.json")).name.toUpperCase().replace(/-/g, "_");
|
|
1259
1259
|
if (process.env[name + "_PREBUILD"]) dir = process.env[name + "_PREBUILD"];
|
|
1260
1260
|
} catch (err) {
|
|
1261
1261
|
}
|
|
1262
1262
|
if (!prebuildsOnly) {
|
|
1263
|
-
var release = getFirst(
|
|
1263
|
+
var release = getFirst(path3.join(dir, "build/Release"), matchBuild);
|
|
1264
1264
|
if (release) return release;
|
|
1265
|
-
var debug12 = getFirst(
|
|
1265
|
+
var debug12 = getFirst(path3.join(dir, "build/Debug"), matchBuild);
|
|
1266
1266
|
if (debug12) return debug12;
|
|
1267
1267
|
}
|
|
1268
|
-
var prebuild =
|
|
1268
|
+
var prebuild = resolve2(dir);
|
|
1269
1269
|
if (prebuild) return prebuild;
|
|
1270
|
-
var nearby =
|
|
1270
|
+
var nearby = resolve2(path3.dirname(process.execPath));
|
|
1271
1271
|
if (nearby) return nearby;
|
|
1272
1272
|
var target = [
|
|
1273
1273
|
"platform=" + platform,
|
|
@@ -1283,27 +1283,27 @@ var require_node_gyp_build = __commonJS({
|
|
|
1283
1283
|
// eslint-disable-line
|
|
1284
1284
|
].filter(Boolean).join(" ");
|
|
1285
1285
|
throw new Error("No native build was found for " + target + "\n loaded from: " + dir + "\n");
|
|
1286
|
-
function
|
|
1287
|
-
var tuples = readdirSync(
|
|
1286
|
+
function resolve2(dir2) {
|
|
1287
|
+
var tuples = readdirSync(path3.join(dir2, "prebuilds")).map(parseTuple);
|
|
1288
1288
|
var tuple = tuples.filter(matchTuple(platform, arch)).sort(compareTuples)[0];
|
|
1289
1289
|
if (!tuple) return;
|
|
1290
|
-
var prebuilds =
|
|
1290
|
+
var prebuilds = path3.join(dir2, "prebuilds", tuple.name);
|
|
1291
1291
|
var parsed = readdirSync(prebuilds).map(parseTags);
|
|
1292
1292
|
var candidates = parsed.filter(matchTags(runtime, abi));
|
|
1293
1293
|
var winner = candidates.sort(compareTags(runtime))[0];
|
|
1294
|
-
if (winner) return
|
|
1294
|
+
if (winner) return path3.join(prebuilds, winner.file);
|
|
1295
1295
|
}
|
|
1296
1296
|
};
|
|
1297
1297
|
function readdirSync(dir) {
|
|
1298
1298
|
try {
|
|
1299
|
-
return
|
|
1299
|
+
return fs2.readdirSync(dir);
|
|
1300
1300
|
} catch (err) {
|
|
1301
1301
|
return [];
|
|
1302
1302
|
}
|
|
1303
1303
|
}
|
|
1304
1304
|
function getFirst(dir, filter) {
|
|
1305
1305
|
var files = readdirSync(dir).filter(filter);
|
|
1306
|
-
return files[0] &&
|
|
1306
|
+
return files[0] && path3.join(dir, files[0]);
|
|
1307
1307
|
}
|
|
1308
1308
|
function matchBuild(name) {
|
|
1309
1309
|
return /\.node$/.test(name);
|
|
@@ -1390,7 +1390,7 @@ var require_node_gyp_build = __commonJS({
|
|
|
1390
1390
|
return typeof window !== "undefined" && window.process && window.process.type === "renderer";
|
|
1391
1391
|
}
|
|
1392
1392
|
function isAlpine(platform2) {
|
|
1393
|
-
return platform2 === "linux" &&
|
|
1393
|
+
return platform2 === "linux" && fs2.existsSync("/etc/alpine-release");
|
|
1394
1394
|
}
|
|
1395
1395
|
load.parseTags = parseTags;
|
|
1396
1396
|
load.matchTags = matchTags;
|
|
@@ -3676,7 +3676,7 @@ var require_websocket = __commonJS({
|
|
|
3676
3676
|
var tls = __require("tls");
|
|
3677
3677
|
var { randomBytes, createHash } = __require("crypto");
|
|
3678
3678
|
var { Duplex, Readable } = __require("stream");
|
|
3679
|
-
var { URL } = __require("url");
|
|
3679
|
+
var { URL: URL2 } = __require("url");
|
|
3680
3680
|
var PerMessageDeflate = require_permessage_deflate();
|
|
3681
3681
|
var Receiver2 = require_receiver();
|
|
3682
3682
|
var Sender2 = require_sender();
|
|
@@ -4166,11 +4166,11 @@ var require_websocket = __commonJS({
|
|
|
4166
4166
|
);
|
|
4167
4167
|
}
|
|
4168
4168
|
let parsedUrl;
|
|
4169
|
-
if (address instanceof
|
|
4169
|
+
if (address instanceof URL2) {
|
|
4170
4170
|
parsedUrl = address;
|
|
4171
4171
|
} else {
|
|
4172
4172
|
try {
|
|
4173
|
-
parsedUrl = new
|
|
4173
|
+
parsedUrl = new URL2(address);
|
|
4174
4174
|
} catch (e) {
|
|
4175
4175
|
throw new SyntaxError(`Invalid URL: ${address}`);
|
|
4176
4176
|
}
|
|
@@ -4307,7 +4307,7 @@ var require_websocket = __commonJS({
|
|
|
4307
4307
|
req.abort();
|
|
4308
4308
|
let addr;
|
|
4309
4309
|
try {
|
|
4310
|
-
addr = new
|
|
4310
|
+
addr = new URL2(location2, address);
|
|
4311
4311
|
} catch (e) {
|
|
4312
4312
|
const err = new SyntaxError(`Invalid URL: ${location2}`);
|
|
4313
4313
|
emitErrorAndClose(websocket, err);
|
|
@@ -7309,13 +7309,13 @@ var require_nacl_fast = __commonJS({
|
|
|
7309
7309
|
import {
|
|
7310
7310
|
chmod,
|
|
7311
7311
|
mkdir,
|
|
7312
|
-
readFile,
|
|
7312
|
+
readFile as readFile2,
|
|
7313
7313
|
rename,
|
|
7314
|
-
stat,
|
|
7314
|
+
stat as stat2,
|
|
7315
7315
|
writeFile
|
|
7316
7316
|
} from "fs/promises";
|
|
7317
7317
|
import os from "os";
|
|
7318
|
-
import
|
|
7318
|
+
import path2 from "path";
|
|
7319
7319
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
7320
7320
|
import { Keypair as Keypair2 } from "@solana/web3.js";
|
|
7321
7321
|
import bs582 from "bs58";
|
|
@@ -8572,12 +8572,12 @@ function parse2(str) {
|
|
|
8572
8572
|
uri.queryKey = queryKey(uri, uri["query"]);
|
|
8573
8573
|
return uri;
|
|
8574
8574
|
}
|
|
8575
|
-
function pathNames(obj,
|
|
8576
|
-
const regx = /\/{2,9}/g, names =
|
|
8577
|
-
if (
|
|
8575
|
+
function pathNames(obj, path3) {
|
|
8576
|
+
const regx = /\/{2,9}/g, names = path3.replace(regx, "/").split("/");
|
|
8577
|
+
if (path3.slice(0, 1) == "/" || path3.length === 0) {
|
|
8578
8578
|
names.splice(0, 1);
|
|
8579
8579
|
}
|
|
8580
|
-
if (
|
|
8580
|
+
if (path3.slice(-1) == "/") {
|
|
8581
8581
|
names.splice(names.length - 1, 1);
|
|
8582
8582
|
}
|
|
8583
8583
|
return names;
|
|
@@ -9194,7 +9194,7 @@ var protocol2 = Socket.protocol;
|
|
|
9194
9194
|
// ../../node_modules/socket.io-client/build/esm-debug/url.js
|
|
9195
9195
|
var import_debug7 = __toESM(require_src(), 1);
|
|
9196
9196
|
var debug7 = (0, import_debug7.default)("socket.io-client:url");
|
|
9197
|
-
function url(uri,
|
|
9197
|
+
function url(uri, path3 = "", loc) {
|
|
9198
9198
|
let obj = uri;
|
|
9199
9199
|
loc = loc || typeof location !== "undefined" && location;
|
|
9200
9200
|
if (null == uri)
|
|
@@ -9228,7 +9228,7 @@ function url(uri, path2 = "", loc) {
|
|
|
9228
9228
|
obj.path = obj.path || "/";
|
|
9229
9229
|
const ipv6 = obj.host.indexOf(":") !== -1;
|
|
9230
9230
|
const host = ipv6 ? "[" + obj.host + "]" : obj.host;
|
|
9231
|
-
obj.id = obj.protocol + "://" + host + ":" + obj.port +
|
|
9231
|
+
obj.id = obj.protocol + "://" + host + ":" + obj.port + path3;
|
|
9232
9232
|
obj.href = obj.protocol + "://" + host + (loc && loc.port === obj.port ? "" : ":" + obj.port);
|
|
9233
9233
|
return obj;
|
|
9234
9234
|
}
|
|
@@ -9878,9 +9878,9 @@ var Socket2 = class extends Emitter {
|
|
|
9878
9878
|
* @return a Promise that will be fulfilled when the server acknowledges the event
|
|
9879
9879
|
*/
|
|
9880
9880
|
emitWithAck(ev, ...args) {
|
|
9881
|
-
return new Promise((
|
|
9881
|
+
return new Promise((resolve2, reject) => {
|
|
9882
9882
|
const fn = (arg1, arg2) => {
|
|
9883
|
-
return arg1 ? reject(arg1) :
|
|
9883
|
+
return arg1 ? reject(arg1) : resolve2(arg2);
|
|
9884
9884
|
};
|
|
9885
9885
|
fn.withError = true;
|
|
9886
9886
|
args.push(fn);
|
|
@@ -10852,8 +10852,8 @@ function lookup(uri, opts) {
|
|
|
10852
10852
|
const parsed = url(uri, opts.path || "/socket.io");
|
|
10853
10853
|
const source = parsed.source;
|
|
10854
10854
|
const id = parsed.id;
|
|
10855
|
-
const
|
|
10856
|
-
const sameNamespace = cache[id] &&
|
|
10855
|
+
const path3 = parsed.path;
|
|
10856
|
+
const sameNamespace = cache[id] && path3 in cache[id]["nsps"];
|
|
10857
10857
|
const newConnection = opts.forceNew || opts["force new connection"] || false === opts.multiplex || sameNamespace;
|
|
10858
10858
|
let io;
|
|
10859
10859
|
if (newConnection) {
|
|
@@ -11751,6 +11751,16 @@ var Admin = class {
|
|
|
11751
11751
|
);
|
|
11752
11752
|
}
|
|
11753
11753
|
};
|
|
11754
|
+
function isFile(input) {
|
|
11755
|
+
return typeof input.arrayBuffer === "function";
|
|
11756
|
+
}
|
|
11757
|
+
function buildFormDataFromPayload(payload) {
|
|
11758
|
+
const formData = new FormData();
|
|
11759
|
+
const part = payload.data instanceof Uint8Array ? payload.data : new Uint8Array(payload.data);
|
|
11760
|
+
const blob = new Blob([part], { type: payload.mimeType });
|
|
11761
|
+
formData.append("file", blob, payload.filename);
|
|
11762
|
+
return formData;
|
|
11763
|
+
}
|
|
11754
11764
|
var Users = class {
|
|
11755
11765
|
constructor(http, logger2) {
|
|
11756
11766
|
this.http = http;
|
|
@@ -11837,14 +11847,22 @@ var Users = class {
|
|
|
11837
11847
|
async updateProfile(data) {
|
|
11838
11848
|
return this.http.patch("/users/me/profile", data);
|
|
11839
11849
|
}
|
|
11840
|
-
async uploadAvatar(
|
|
11841
|
-
const
|
|
11842
|
-
|
|
11850
|
+
async uploadAvatar(input) {
|
|
11851
|
+
const payload = isFile(input) ? {
|
|
11852
|
+
data: new Uint8Array(await input.arrayBuffer()),
|
|
11853
|
+
mimeType: input.type,
|
|
11854
|
+
filename: input.name
|
|
11855
|
+
} : input;
|
|
11856
|
+
const formData = buildFormDataFromPayload(payload);
|
|
11843
11857
|
return this.http.upload("/users/me/profile/avatar", formData);
|
|
11844
11858
|
}
|
|
11845
|
-
async uploadCoverImage(
|
|
11846
|
-
const
|
|
11847
|
-
|
|
11859
|
+
async uploadCoverImage(input) {
|
|
11860
|
+
const payload = isFile(input) ? {
|
|
11861
|
+
data: new Uint8Array(await input.arrayBuffer()),
|
|
11862
|
+
mimeType: input.type,
|
|
11863
|
+
filename: input.name
|
|
11864
|
+
} : input;
|
|
11865
|
+
const formData = buildFormDataFromPayload(payload);
|
|
11848
11866
|
return this.http.upload("/users/me/profile/cover", formData);
|
|
11849
11867
|
}
|
|
11850
11868
|
async removeAvatar() {
|
|
@@ -12178,7 +12196,7 @@ async function withRetry(fn, options = {}) {
|
|
|
12178
12196
|
throw lastError;
|
|
12179
12197
|
}
|
|
12180
12198
|
function sleep(ms) {
|
|
12181
|
-
return new Promise((
|
|
12199
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
12182
12200
|
}
|
|
12183
12201
|
var DEFAULT_RETRY_OPTIONS = {
|
|
12184
12202
|
maxAttempts: 3,
|
|
@@ -13446,12 +13464,12 @@ var BaseWsTransport = class {
|
|
|
13446
13464
|
if (this.connectionState.connected) {
|
|
13447
13465
|
return Promise.resolve();
|
|
13448
13466
|
}
|
|
13449
|
-
return new Promise((
|
|
13467
|
+
return new Promise((resolve2, reject) => {
|
|
13450
13468
|
const timeoutId = setTimeout(() => {
|
|
13451
13469
|
this.waiters.delete(waiter);
|
|
13452
13470
|
reject(new Error("WebSocket connection timed out"));
|
|
13453
13471
|
}, timeoutMs);
|
|
13454
|
-
const waiter = { resolve, reject, timeoutId };
|
|
13472
|
+
const waiter = { resolve: resolve2, reject, timeoutId };
|
|
13455
13473
|
this.waiters.add(waiter);
|
|
13456
13474
|
});
|
|
13457
13475
|
}
|
|
@@ -14225,6 +14243,22 @@ function createGameActionsStore(transport2) {
|
|
|
14225
14243
|
updateState(gameId, updated);
|
|
14226
14244
|
break;
|
|
14227
14245
|
}
|
|
14246
|
+
case "game:move": {
|
|
14247
|
+
const { gameId, fen, turn, currentPlayerId, status, winnerId } = event.payload;
|
|
14248
|
+
if (!gameId) return;
|
|
14249
|
+
const current = store.getState().statesByGameId[gameId];
|
|
14250
|
+
if (!isNonRpsState(current)) return;
|
|
14251
|
+
const updated = {
|
|
14252
|
+
...current,
|
|
14253
|
+
fen,
|
|
14254
|
+
turn,
|
|
14255
|
+
currentPlayerId,
|
|
14256
|
+
status,
|
|
14257
|
+
...winnerId != null && { winnerId }
|
|
14258
|
+
};
|
|
14259
|
+
updateState(gameId, updated);
|
|
14260
|
+
break;
|
|
14261
|
+
}
|
|
14228
14262
|
case "game:state": {
|
|
14229
14263
|
const gameId = event.payload.gameId ?? event.payload.state.gameId;
|
|
14230
14264
|
if (!gameId) return;
|
|
@@ -15957,16 +15991,56 @@ async function joinQueue(client, args) {
|
|
|
15957
15991
|
try {
|
|
15958
15992
|
await client.ensureConnected();
|
|
15959
15993
|
const lobby = await client.sdk.lobbies.joinQueue(args.lobbyId);
|
|
15960
|
-
|
|
15994
|
+
let matched = !!(lobby.status === "active" && lobby.gameId);
|
|
15995
|
+
let gameId = lobby.gameId || null;
|
|
15996
|
+
if (!matched) {
|
|
15997
|
+
const lobbyStore = client.sdk.lobbyStore;
|
|
15998
|
+
lobbyStore.joinLobby(args.lobbyId);
|
|
15999
|
+
const timeout = 3e5;
|
|
16000
|
+
const start = Date.now();
|
|
16001
|
+
let lastRefresh = Date.now();
|
|
16002
|
+
while (Date.now() - start < timeout) {
|
|
16003
|
+
const matchedEvent = lobbyStore.store.getState().matchedEvent;
|
|
16004
|
+
if (matchedEvent?.gameId) {
|
|
16005
|
+
gameId = matchedEvent.gameId;
|
|
16006
|
+
matched = true;
|
|
16007
|
+
break;
|
|
16008
|
+
}
|
|
16009
|
+
if (Date.now() - lastRefresh > 2e3) {
|
|
16010
|
+
try {
|
|
16011
|
+
const fresh = await client.sdk.lobbies.getLobby(args.lobbyId);
|
|
16012
|
+
if (fresh.status === "active" && fresh.gameId) {
|
|
16013
|
+
gameId = fresh.gameId;
|
|
16014
|
+
matched = true;
|
|
16015
|
+
break;
|
|
16016
|
+
}
|
|
16017
|
+
} catch {
|
|
16018
|
+
}
|
|
16019
|
+
lastRefresh = Date.now();
|
|
16020
|
+
}
|
|
16021
|
+
await raceTimeout(
|
|
16022
|
+
new Promise((resolve2) => {
|
|
16023
|
+
const unsub = lobbyStore.store.subscribeSelector(
|
|
16024
|
+
(s) => s.matchedEvent,
|
|
16025
|
+
() => {
|
|
16026
|
+
unsub();
|
|
16027
|
+
resolve2();
|
|
16028
|
+
}
|
|
16029
|
+
);
|
|
16030
|
+
}),
|
|
16031
|
+
1e3
|
|
16032
|
+
);
|
|
16033
|
+
}
|
|
16034
|
+
}
|
|
15961
16035
|
const spectateUrl = matched ? await getSpectateUrl(client) : null;
|
|
15962
16036
|
return {
|
|
15963
16037
|
data: {
|
|
15964
16038
|
lobbyId: lobby.id,
|
|
15965
|
-
status: lobby.status,
|
|
15966
|
-
gameId
|
|
16039
|
+
status: matched ? "active" : lobby.status,
|
|
16040
|
+
gameId,
|
|
15967
16041
|
matched: !!matched,
|
|
15968
16042
|
...spectateUrl && { spectateUrl },
|
|
15969
|
-
hint: matched ? `Game started! Call dim_game_loop with gameId "${
|
|
16043
|
+
hint: matched ? `Game started! Call dim_game_loop with gameId "${gameId}" to play.${spectateUrl ? ` Tell the user they can spectate at ${spectateUrl}` : ""}` : "No match found within timeout. Call dim_join_queue again to resume waiting."
|
|
15970
16044
|
}
|
|
15971
16045
|
};
|
|
15972
16046
|
} catch (error) {
|
|
@@ -16081,13 +16155,12 @@ async function gameLoop(client, args) {
|
|
|
16081
16155
|
const store = client.sdk.gameActionsStore;
|
|
16082
16156
|
const timeout = 3e5;
|
|
16083
16157
|
const start = Date.now();
|
|
16084
|
-
|
|
16085
|
-
|
|
16086
|
-
|
|
16087
|
-
|
|
16088
|
-
|
|
16089
|
-
|
|
16090
|
-
}
|
|
16158
|
+
await client.ensureConnected();
|
|
16159
|
+
store.joinGame(gameId);
|
|
16160
|
+
const fetched = await client.sdk.games.getGameState(gameId);
|
|
16161
|
+
store.setBaseState(gameId, fetched);
|
|
16162
|
+
let state = fetched;
|
|
16163
|
+
let lastRefresh = Date.now();
|
|
16091
16164
|
while (Date.now() - start < timeout) {
|
|
16092
16165
|
state = store.store.getState().statesByGameId[gameId];
|
|
16093
16166
|
if (state?.status === "completed") {
|
|
@@ -16097,17 +16170,22 @@ async function gameLoop(client, args) {
|
|
|
16097
16170
|
return buildGameLoopReturn(client, gameId, state, "your-turn");
|
|
16098
16171
|
}
|
|
16099
16172
|
await raceTimeout(
|
|
16100
|
-
new Promise((
|
|
16173
|
+
new Promise((resolve2) => {
|
|
16101
16174
|
const unsub = store.store.subscribeSelector(
|
|
16102
16175
|
(s) => s.statesByGameId[gameId],
|
|
16103
16176
|
() => {
|
|
16104
16177
|
unsub();
|
|
16105
|
-
|
|
16178
|
+
resolve2();
|
|
16106
16179
|
}
|
|
16107
16180
|
);
|
|
16108
16181
|
}),
|
|
16109
16182
|
1e3
|
|
16110
16183
|
);
|
|
16184
|
+
if (Date.now() - lastRefresh > 2e3) {
|
|
16185
|
+
const fresh = await client.sdk.games.getGameState(gameId);
|
|
16186
|
+
store.setBaseState(gameId, fresh);
|
|
16187
|
+
lastRefresh = Date.now();
|
|
16188
|
+
}
|
|
16111
16189
|
}
|
|
16112
16190
|
state = store.store.getState().statesByGameId[gameId];
|
|
16113
16191
|
return buildGameLoopReturn(client, gameId, state ?? {}, "timeout");
|
|
@@ -16181,11 +16259,11 @@ async function acceptRematch(client, args) {
|
|
|
16181
16259
|
}
|
|
16182
16260
|
}
|
|
16183
16261
|
function raceTimeout(promise, ms) {
|
|
16184
|
-
return new Promise((
|
|
16185
|
-
const timer = setTimeout(
|
|
16262
|
+
return new Promise((resolve2) => {
|
|
16263
|
+
const timer = setTimeout(resolve2, ms);
|
|
16186
16264
|
promise.then(() => {
|
|
16187
16265
|
clearTimeout(timer);
|
|
16188
|
-
|
|
16266
|
+
resolve2();
|
|
16189
16267
|
});
|
|
16190
16268
|
});
|
|
16191
16269
|
}
|
|
@@ -16767,6 +16845,321 @@ async function getAgentConfig(client) {
|
|
|
16767
16845
|
}
|
|
16768
16846
|
}
|
|
16769
16847
|
|
|
16848
|
+
// ../dim-agent-core/src/tools/profile.ts
|
|
16849
|
+
import * as fs from "fs/promises";
|
|
16850
|
+
import * as path from "path";
|
|
16851
|
+
import * as dns from "dns";
|
|
16852
|
+
import { promisify } from "util";
|
|
16853
|
+
var dnsLookup = promisify(dns.lookup);
|
|
16854
|
+
var MAX_FILE_SIZE_BYTES = 5 * 1024 * 1024;
|
|
16855
|
+
var FETCH_TIMEOUT_MS = 15e3;
|
|
16856
|
+
var ALLOWED_MIME_TYPES = [
|
|
16857
|
+
"image/jpeg",
|
|
16858
|
+
"image/jpg",
|
|
16859
|
+
"image/png",
|
|
16860
|
+
"image/webp",
|
|
16861
|
+
"image/gif"
|
|
16862
|
+
];
|
|
16863
|
+
var EXT_TO_MIME = {
|
|
16864
|
+
".png": "image/png",
|
|
16865
|
+
".jpg": "image/jpeg",
|
|
16866
|
+
".jpeg": "image/jpeg",
|
|
16867
|
+
".gif": "image/gif",
|
|
16868
|
+
".webp": "image/webp"
|
|
16869
|
+
};
|
|
16870
|
+
function getDefaultAllowedBaseDir() {
|
|
16871
|
+
const env = process.env.DIM_AGENT_WORKSPACE_DIR;
|
|
16872
|
+
if (env) return path.resolve(env);
|
|
16873
|
+
const home = process.env.HOME || process.env.USERPROFILE || ".";
|
|
16874
|
+
return path.join(home, ".openclaw", "workspace");
|
|
16875
|
+
}
|
|
16876
|
+
function isPathUnderBase(filePath, baseDir) {
|
|
16877
|
+
const resolved = path.resolve(filePath);
|
|
16878
|
+
const base = path.resolve(baseDir);
|
|
16879
|
+
const relative2 = path.relative(base, resolved);
|
|
16880
|
+
return relative2 !== "" && !relative2.startsWith("..") && !path.isAbsolute(relative2);
|
|
16881
|
+
}
|
|
16882
|
+
function mimeFromExtension(filePathOrUrl) {
|
|
16883
|
+
const ext = path.extname(filePathOrUrl).toLowerCase();
|
|
16884
|
+
return EXT_TO_MIME[ext] ?? null;
|
|
16885
|
+
}
|
|
16886
|
+
function normalizeContentType(header) {
|
|
16887
|
+
if (!header) return null;
|
|
16888
|
+
const main = header.split(";")[0].trim().toLowerCase();
|
|
16889
|
+
return main || null;
|
|
16890
|
+
}
|
|
16891
|
+
function isAllowedMime(mime) {
|
|
16892
|
+
return ALLOWED_MIME_TYPES.includes(
|
|
16893
|
+
mime
|
|
16894
|
+
);
|
|
16895
|
+
}
|
|
16896
|
+
function isPrivateOrLocalHost(hostname) {
|
|
16897
|
+
if (hostname === "localhost" || hostname === "::1") return true;
|
|
16898
|
+
const ipv4 = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(hostname);
|
|
16899
|
+
if (ipv4) {
|
|
16900
|
+
const [, a, b, c, d] = ipv4.map(Number);
|
|
16901
|
+
if (a === 127) return true;
|
|
16902
|
+
if (a === 10) return true;
|
|
16903
|
+
if (a === 172 && b >= 16 && b <= 31) return true;
|
|
16904
|
+
if (a === 192 && b === 168) return true;
|
|
16905
|
+
if (a === 169 && b === 254) return true;
|
|
16906
|
+
return false;
|
|
16907
|
+
}
|
|
16908
|
+
if (hostname.startsWith("::1") || hostname.startsWith("fe80:")) return true;
|
|
16909
|
+
return false;
|
|
16910
|
+
}
|
|
16911
|
+
async function assertUrlSafeForFetch(imageUrl) {
|
|
16912
|
+
let parsed;
|
|
16913
|
+
try {
|
|
16914
|
+
parsed = new URL(imageUrl);
|
|
16915
|
+
} catch {
|
|
16916
|
+
throw new Error("Invalid imageUrl: not a valid URL.");
|
|
16917
|
+
}
|
|
16918
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
16919
|
+
throw new Error("Invalid imageUrl: only http and https are allowed.");
|
|
16920
|
+
}
|
|
16921
|
+
const hostname = parsed.hostname;
|
|
16922
|
+
if (isPrivateOrLocalHost(hostname)) {
|
|
16923
|
+
throw new Error(
|
|
16924
|
+
"Invalid imageUrl: URLs to localhost or private IPs are not allowed."
|
|
16925
|
+
);
|
|
16926
|
+
}
|
|
16927
|
+
try {
|
|
16928
|
+
const { address } = await dnsLookup(hostname, { family: 4 });
|
|
16929
|
+
if (isPrivateOrLocalHost(address)) {
|
|
16930
|
+
throw new Error(
|
|
16931
|
+
"Invalid imageUrl: hostname resolves to a private or local IP."
|
|
16932
|
+
);
|
|
16933
|
+
}
|
|
16934
|
+
if (address === "169.254.169.254") {
|
|
16935
|
+
throw new Error("Invalid imageUrl: cloud metadata URLs are not allowed.");
|
|
16936
|
+
}
|
|
16937
|
+
} catch (err) {
|
|
16938
|
+
if (err instanceof Error && err.message.startsWith("Invalid imageUrl:"))
|
|
16939
|
+
throw err;
|
|
16940
|
+
throw new Error(
|
|
16941
|
+
`Invalid imageUrl: could not resolve hostname (${err instanceof Error ? err.message : String(err)}).`
|
|
16942
|
+
);
|
|
16943
|
+
}
|
|
16944
|
+
}
|
|
16945
|
+
async function resolveImageFromFilePath(filePath, allowedBaseDir) {
|
|
16946
|
+
if (!path.isAbsolute(filePath)) {
|
|
16947
|
+
filePath = path.resolve(allowedBaseDir, filePath);
|
|
16948
|
+
}
|
|
16949
|
+
const realPath = await fs.realpath(filePath).catch(() => null);
|
|
16950
|
+
const resolved = realPath ?? filePath;
|
|
16951
|
+
if (!isPathUnderBase(resolved, allowedBaseDir)) {
|
|
16952
|
+
throw new Error("filePath is outside the allowed workspace directory.");
|
|
16953
|
+
}
|
|
16954
|
+
const stat3 = await fs.stat(resolved, { bigint: false }).catch(() => null);
|
|
16955
|
+
if (!stat3) throw new Error("File not found or not readable.");
|
|
16956
|
+
if (stat3.size > MAX_FILE_SIZE_BYTES) {
|
|
16957
|
+
throw new Error(
|
|
16958
|
+
`File size exceeds ${MAX_FILE_SIZE_BYTES / 1024 / 1024}MB limit.`
|
|
16959
|
+
);
|
|
16960
|
+
}
|
|
16961
|
+
const buffer = await fs.readFile(resolved);
|
|
16962
|
+
const mime = mimeFromExtension(resolved) ?? "image/png";
|
|
16963
|
+
if (!isAllowedMime(mime)) {
|
|
16964
|
+
throw new Error(
|
|
16965
|
+
`File type not allowed. Allowed: ${ALLOWED_MIME_TYPES.join(", ")}.`
|
|
16966
|
+
);
|
|
16967
|
+
}
|
|
16968
|
+
const filename = path.basename(resolved) || "image";
|
|
16969
|
+
return {
|
|
16970
|
+
data: new Uint8Array(buffer),
|
|
16971
|
+
mimeType: mime,
|
|
16972
|
+
filename
|
|
16973
|
+
};
|
|
16974
|
+
}
|
|
16975
|
+
async function resolveImageFromUrl(imageUrl) {
|
|
16976
|
+
await assertUrlSafeForFetch(imageUrl);
|
|
16977
|
+
const controller = new AbortController();
|
|
16978
|
+
const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
16979
|
+
try {
|
|
16980
|
+
const res = await fetch(imageUrl, {
|
|
16981
|
+
redirect: "manual",
|
|
16982
|
+
signal: controller.signal
|
|
16983
|
+
});
|
|
16984
|
+
clearTimeout(timeout);
|
|
16985
|
+
if (res.status >= 300 && res.status < 400) {
|
|
16986
|
+
throw new Error("Redirects are not allowed. Use the final image URL.");
|
|
16987
|
+
}
|
|
16988
|
+
if (!res.ok) {
|
|
16989
|
+
throw new Error(`Fetch failed: ${res.status} ${res.statusText}`);
|
|
16990
|
+
}
|
|
16991
|
+
const contentType = normalizeContentType(res.headers.get("Content-Type"));
|
|
16992
|
+
const mimeFromHeader = contentType && isAllowedMime(contentType) ? contentType : null;
|
|
16993
|
+
const contentLength = res.headers.get("Content-Length");
|
|
16994
|
+
if (contentLength) {
|
|
16995
|
+
const len = parseInt(contentLength, 10);
|
|
16996
|
+
if (!Number.isNaN(len) && len > MAX_FILE_SIZE_BYTES) {
|
|
16997
|
+
throw new Error(
|
|
16998
|
+
`Content-Length (${len}) exceeds ${MAX_FILE_SIZE_BYTES / 1024 / 1024}MB limit.`
|
|
16999
|
+
);
|
|
17000
|
+
}
|
|
17001
|
+
}
|
|
17002
|
+
const buf = await res.arrayBuffer();
|
|
17003
|
+
if (buf.byteLength > MAX_FILE_SIZE_BYTES) {
|
|
17004
|
+
throw new Error(
|
|
17005
|
+
`Response size exceeds ${MAX_FILE_SIZE_BYTES / 1024 / 1024}MB limit.`
|
|
17006
|
+
);
|
|
17007
|
+
}
|
|
17008
|
+
const mime = mimeFromHeader ?? mimeFromExtension(imageUrl) ?? "image/png";
|
|
17009
|
+
if (!isAllowedMime(mime)) {
|
|
17010
|
+
throw new Error(
|
|
17011
|
+
`Content-Type not allowed. Allowed: ${ALLOWED_MIME_TYPES.join(", ")}.`
|
|
17012
|
+
);
|
|
17013
|
+
}
|
|
17014
|
+
const ext = mime === "image/jpeg" || mime === "image/jpg" ? ".jpg" : mime.replace("image/", ".");
|
|
17015
|
+
return {
|
|
17016
|
+
data: new Uint8Array(buf),
|
|
17017
|
+
mimeType: mime,
|
|
17018
|
+
filename: `image${ext}`
|
|
17019
|
+
};
|
|
17020
|
+
} finally {
|
|
17021
|
+
clearTimeout(timeout);
|
|
17022
|
+
}
|
|
17023
|
+
}
|
|
17024
|
+
async function uploadAvatar(client, args) {
|
|
17025
|
+
try {
|
|
17026
|
+
if (!client.currentUserId) {
|
|
17027
|
+
return {
|
|
17028
|
+
error: "Not authenticated. Call dim_login first.",
|
|
17029
|
+
isError: true
|
|
17030
|
+
};
|
|
17031
|
+
}
|
|
17032
|
+
const { filePath, imageUrl } = args;
|
|
17033
|
+
if (filePath && imageUrl) {
|
|
17034
|
+
return {
|
|
17035
|
+
error: "Provide either filePath or imageUrl, not both.",
|
|
17036
|
+
isError: true
|
|
17037
|
+
};
|
|
17038
|
+
}
|
|
17039
|
+
if (!filePath && !imageUrl) {
|
|
17040
|
+
return { error: "Provide filePath or imageUrl.", isError: true };
|
|
17041
|
+
}
|
|
17042
|
+
const baseDir = getDefaultAllowedBaseDir();
|
|
17043
|
+
const payload = filePath ? await resolveImageFromFilePath(filePath, baseDir) : await resolveImageFromUrl(imageUrl);
|
|
17044
|
+
const user = await client.sdk.users.uploadAvatar(payload);
|
|
17045
|
+
return { data: { success: true, user } };
|
|
17046
|
+
} catch (error) {
|
|
17047
|
+
return {
|
|
17048
|
+
error: error instanceof Error ? error.message : String(error),
|
|
17049
|
+
isError: true
|
|
17050
|
+
};
|
|
17051
|
+
}
|
|
17052
|
+
}
|
|
17053
|
+
async function uploadCoverImage(client, args) {
|
|
17054
|
+
try {
|
|
17055
|
+
if (!client.currentUserId) {
|
|
17056
|
+
return {
|
|
17057
|
+
error: "Not authenticated. Call dim_login first.",
|
|
17058
|
+
isError: true
|
|
17059
|
+
};
|
|
17060
|
+
}
|
|
17061
|
+
const { filePath, imageUrl } = args;
|
|
17062
|
+
if (filePath && imageUrl) {
|
|
17063
|
+
return {
|
|
17064
|
+
error: "Provide either filePath or imageUrl, not both.",
|
|
17065
|
+
isError: true
|
|
17066
|
+
};
|
|
17067
|
+
}
|
|
17068
|
+
if (!filePath && !imageUrl) {
|
|
17069
|
+
return { error: "Provide filePath or imageUrl.", isError: true };
|
|
17070
|
+
}
|
|
17071
|
+
const baseDir = getDefaultAllowedBaseDir();
|
|
17072
|
+
const payload = filePath ? await resolveImageFromFilePath(filePath, baseDir) : await resolveImageFromUrl(imageUrl);
|
|
17073
|
+
const user = await client.sdk.users.uploadCoverImage(payload);
|
|
17074
|
+
return { data: { success: true, user } };
|
|
17075
|
+
} catch (error) {
|
|
17076
|
+
return {
|
|
17077
|
+
error: error instanceof Error ? error.message : String(error),
|
|
17078
|
+
isError: true
|
|
17079
|
+
};
|
|
17080
|
+
}
|
|
17081
|
+
}
|
|
17082
|
+
async function removeAvatar(client) {
|
|
17083
|
+
try {
|
|
17084
|
+
if (!client.currentUserId) {
|
|
17085
|
+
return {
|
|
17086
|
+
error: "Not authenticated. Call dim_login first.",
|
|
17087
|
+
isError: true
|
|
17088
|
+
};
|
|
17089
|
+
}
|
|
17090
|
+
const user = await client.sdk.users.removeAvatar();
|
|
17091
|
+
return { data: { success: true, user } };
|
|
17092
|
+
} catch (error) {
|
|
17093
|
+
return {
|
|
17094
|
+
error: error instanceof Error ? error.message : String(error),
|
|
17095
|
+
isError: true
|
|
17096
|
+
};
|
|
17097
|
+
}
|
|
17098
|
+
}
|
|
17099
|
+
async function removeCoverImage(client) {
|
|
17100
|
+
try {
|
|
17101
|
+
if (!client.currentUserId) {
|
|
17102
|
+
return {
|
|
17103
|
+
error: "Not authenticated. Call dim_login first.",
|
|
17104
|
+
isError: true
|
|
17105
|
+
};
|
|
17106
|
+
}
|
|
17107
|
+
const user = await client.sdk.users.removeCoverImage();
|
|
17108
|
+
return { data: { success: true, user } };
|
|
17109
|
+
} catch (error) {
|
|
17110
|
+
return {
|
|
17111
|
+
error: error instanceof Error ? error.message : String(error),
|
|
17112
|
+
isError: true
|
|
17113
|
+
};
|
|
17114
|
+
}
|
|
17115
|
+
}
|
|
17116
|
+
function getProfileImageRequirements() {
|
|
17117
|
+
return {
|
|
17118
|
+
data: {
|
|
17119
|
+
avatar: {
|
|
17120
|
+
maxFileSizeBytes: MAX_FILE_SIZE_BYTES,
|
|
17121
|
+
maxDimensions: { width: 200, height: 200 },
|
|
17122
|
+
aspectRatio: "1:1",
|
|
17123
|
+
allowedMimeTypes: [...ALLOWED_MIME_TYPES]
|
|
17124
|
+
},
|
|
17125
|
+
cover: {
|
|
17126
|
+
maxFileSizeBytes: MAX_FILE_SIZE_BYTES,
|
|
17127
|
+
maxDimensions: { width: 1200, height: 400 },
|
|
17128
|
+
aspectRatio: "3:1",
|
|
17129
|
+
allowedMimeTypes: [...ALLOWED_MIME_TYPES]
|
|
17130
|
+
}
|
|
17131
|
+
}
|
|
17132
|
+
};
|
|
17133
|
+
}
|
|
17134
|
+
var BIO_MAX_LENGTH = 500;
|
|
17135
|
+
async function setBio(client, args) {
|
|
17136
|
+
try {
|
|
17137
|
+
if (!client.currentUserId) {
|
|
17138
|
+
return {
|
|
17139
|
+
error: "Not authenticated. Call dim_login first.",
|
|
17140
|
+
isError: true
|
|
17141
|
+
};
|
|
17142
|
+
}
|
|
17143
|
+
const { bio } = args;
|
|
17144
|
+
if (typeof bio !== "string") {
|
|
17145
|
+
return { error: "bio must be a string.", isError: true };
|
|
17146
|
+
}
|
|
17147
|
+
if (bio.length > BIO_MAX_LENGTH) {
|
|
17148
|
+
return {
|
|
17149
|
+
error: `Bio must be at most ${BIO_MAX_LENGTH} characters.`,
|
|
17150
|
+
isError: true
|
|
17151
|
+
};
|
|
17152
|
+
}
|
|
17153
|
+
await client.sdk.users.updateProfile({ bio });
|
|
17154
|
+
return { data: { success: true } };
|
|
17155
|
+
} catch (error) {
|
|
17156
|
+
return {
|
|
17157
|
+
error: error instanceof Error ? error.message : String(error),
|
|
17158
|
+
isError: true
|
|
17159
|
+
};
|
|
17160
|
+
}
|
|
17161
|
+
}
|
|
17162
|
+
|
|
16770
17163
|
// ../dim-agent-core/src/tools/users.ts
|
|
16771
17164
|
function formatMinor(m) {
|
|
16772
17165
|
if (m == null) return "\u2014";
|
|
@@ -16859,6 +17252,70 @@ var TOOL_DEFINITIONS = [
|
|
|
16859
17252
|
},
|
|
16860
17253
|
execute: (c, a) => setUsername(c, a)
|
|
16861
17254
|
},
|
|
17255
|
+
{
|
|
17256
|
+
name: "dim_upload_avatar",
|
|
17257
|
+
description: "Upload a profile avatar image. Provide filePath (path to image file in workspace) or imageUrl (URL to fetch image from). Max 5MB; allowed types: JPEG, PNG, WebP, GIF. Use dim_get_profile_image_requirements for dimensions.",
|
|
17258
|
+
params: {
|
|
17259
|
+
filePath: {
|
|
17260
|
+
type: "string",
|
|
17261
|
+
description: "Path to image file (under allowed workspace)"
|
|
17262
|
+
},
|
|
17263
|
+
imageUrl: {
|
|
17264
|
+
type: "string",
|
|
17265
|
+
description: "URL of image to fetch and upload"
|
|
17266
|
+
}
|
|
17267
|
+
},
|
|
17268
|
+
execute: (c, a) => uploadAvatar(c, a)
|
|
17269
|
+
},
|
|
17270
|
+
{
|
|
17271
|
+
name: "dim_upload_cover_image",
|
|
17272
|
+
description: "Upload a profile cover/header image. Provide filePath or imageUrl. Max 5MB; allowed types: JPEG, PNG, WebP, GIF. Use dim_get_profile_image_requirements for dimensions.",
|
|
17273
|
+
params: {
|
|
17274
|
+
filePath: {
|
|
17275
|
+
type: "string",
|
|
17276
|
+
description: "Path to image file (under allowed workspace)"
|
|
17277
|
+
},
|
|
17278
|
+
imageUrl: {
|
|
17279
|
+
type: "string",
|
|
17280
|
+
description: "URL of image to fetch and upload"
|
|
17281
|
+
}
|
|
17282
|
+
},
|
|
17283
|
+
execute: (c, a) => uploadCoverImage(
|
|
17284
|
+
c,
|
|
17285
|
+
a
|
|
17286
|
+
)
|
|
17287
|
+
},
|
|
17288
|
+
{
|
|
17289
|
+
name: "dim_remove_avatar",
|
|
17290
|
+
description: "Remove the current profile avatar (reset to default).",
|
|
17291
|
+
params: {},
|
|
17292
|
+
execute: (c) => removeAvatar(c)
|
|
17293
|
+
},
|
|
17294
|
+
{
|
|
17295
|
+
name: "dim_remove_cover_image",
|
|
17296
|
+
description: "Remove the current profile cover/header image (reset to default).",
|
|
17297
|
+
params: {},
|
|
17298
|
+
execute: (c) => removeCoverImage(c)
|
|
17299
|
+
},
|
|
17300
|
+
{
|
|
17301
|
+
name: "dim_get_profile_image_requirements",
|
|
17302
|
+
description: "Get max dimensions, max file size, aspect ratio, and allowed MIME types for avatar and cover images. Use before uploading to validate or choose images.",
|
|
17303
|
+
params: {},
|
|
17304
|
+
execute: async () => getProfileImageRequirements()
|
|
17305
|
+
},
|
|
17306
|
+
{
|
|
17307
|
+
name: "dim_set_bio",
|
|
17308
|
+
description: "Set or update your profile bio. Max 500 characters. No truncation; shorten if over limit.",
|
|
17309
|
+
params: {
|
|
17310
|
+
bio: {
|
|
17311
|
+
type: "string",
|
|
17312
|
+
description: "The new profile bio (max 500 characters)",
|
|
17313
|
+
required: true,
|
|
17314
|
+
max: 500
|
|
17315
|
+
}
|
|
17316
|
+
},
|
|
17317
|
+
execute: (c, a) => setBio(c, a)
|
|
17318
|
+
},
|
|
16862
17319
|
{
|
|
16863
17320
|
name: "dim_check_maintenance",
|
|
16864
17321
|
description: "Check if DIM is in maintenance mode. Call this before other operations to avoid failing with 503; when maintenance is true, inform the user to come back later.",
|
|
@@ -17932,7 +18389,7 @@ function createDimMcpServer(config) {
|
|
|
17932
18389
|
}
|
|
17933
18390
|
|
|
17934
18391
|
// src/index.ts
|
|
17935
|
-
var DEFAULT_WALLET_STORE_PATH =
|
|
18392
|
+
var DEFAULT_WALLET_STORE_PATH = path2.join(
|
|
17936
18393
|
os.homedir(),
|
|
17937
18394
|
".dim",
|
|
17938
18395
|
"mcp-wallet.json"
|
|
@@ -17951,21 +18408,21 @@ function resolveWalletStorePath(cliArgs2) {
|
|
|
17951
18408
|
);
|
|
17952
18409
|
}
|
|
17953
18410
|
if (value2.startsWith("~/")) {
|
|
17954
|
-
return
|
|
18411
|
+
return path2.join(os.homedir(), value2.slice(2));
|
|
17955
18412
|
}
|
|
17956
|
-
return
|
|
18413
|
+
return path2.resolve(value2);
|
|
17957
18414
|
}
|
|
17958
18415
|
const envPath = process.env.DIM_WALLET_STORE_PATH?.trim();
|
|
17959
18416
|
if (envPath) {
|
|
17960
18417
|
if (envPath.startsWith("~/")) {
|
|
17961
|
-
return
|
|
18418
|
+
return path2.join(os.homedir(), envPath.slice(2));
|
|
17962
18419
|
}
|
|
17963
|
-
return
|
|
18420
|
+
return path2.resolve(envPath);
|
|
17964
18421
|
}
|
|
17965
18422
|
return DEFAULT_WALLET_STORE_PATH;
|
|
17966
18423
|
}
|
|
17967
18424
|
async function writeWalletStoreFile(storePath, record) {
|
|
17968
|
-
await mkdir(
|
|
18425
|
+
await mkdir(path2.dirname(storePath), { recursive: true });
|
|
17969
18426
|
const tmpPath = `${storePath}.tmp`;
|
|
17970
18427
|
await writeFile(tmpPath, `${JSON.stringify(record, null, 2)}
|
|
17971
18428
|
`, {
|
|
@@ -17977,7 +18434,7 @@ async function writeWalletStoreFile(storePath, record) {
|
|
|
17977
18434
|
}
|
|
17978
18435
|
async function readWalletStoreFile(storePath) {
|
|
17979
18436
|
try {
|
|
17980
|
-
const raw = await
|
|
18437
|
+
const raw = await readFile2(storePath, "utf8");
|
|
17981
18438
|
const parsed = JSON.parse(raw);
|
|
17982
18439
|
if (parsed.walletPrivateKey && parsed.walletAddress) {
|
|
17983
18440
|
return {
|
|
@@ -18003,7 +18460,7 @@ async function createWalletRecord() {
|
|
|
18003
18460
|
}
|
|
18004
18461
|
async function walletStoreExists(storePath) {
|
|
18005
18462
|
try {
|
|
18006
|
-
await
|
|
18463
|
+
await stat2(storePath);
|
|
18007
18464
|
return true;
|
|
18008
18465
|
} catch {
|
|
18009
18466
|
return false;
|