@kevisual/cli 0.1.14 → 0.1.16
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/assistant-opencode.js +61 -10
- package/dist/assistant-server.js +62 -10
- package/dist/assistant.js +53 -6
- package/dist/envision.js +31 -20
- package/package.json +1 -1
|
@@ -44010,13 +44010,22 @@ class AssistantConfig {
|
|
|
44010
44010
|
getDefaultInitAssistantConfig() {
|
|
44011
44011
|
const id = randomId2();
|
|
44012
44012
|
const isCNB = !!useKey("CNB");
|
|
44013
|
+
let kevisualUrl = "https://kevisual.cn";
|
|
44014
|
+
if (isCNB) {
|
|
44015
|
+
const uri = getCNBUrl();
|
|
44016
|
+
if (uri) {
|
|
44017
|
+
kevisualUrl = uri;
|
|
44018
|
+
} else {
|
|
44019
|
+
kevisualUrl = "http://kevisual.cn";
|
|
44020
|
+
}
|
|
44021
|
+
}
|
|
44013
44022
|
return {
|
|
44014
44023
|
app: {
|
|
44015
|
-
url:
|
|
44024
|
+
url: kevisualUrl,
|
|
44016
44025
|
id
|
|
44017
44026
|
},
|
|
44018
44027
|
description: "助手配置文件",
|
|
44019
|
-
docs:
|
|
44028
|
+
docs: `${kevisualUrl}/root/cli/docs/`,
|
|
44020
44029
|
home: isCNB ? "/root/cli-center" : "/root/home",
|
|
44021
44030
|
proxy: [],
|
|
44022
44031
|
share: {
|
|
@@ -44035,6 +44044,16 @@ var parseIfJson2 = (content) => {
|
|
|
44035
44044
|
}
|
|
44036
44045
|
};
|
|
44037
44046
|
var randomId2 = () => Math.random().toString(36).substring(2, 8);
|
|
44047
|
+
var getCNBUrl = () => {
|
|
44048
|
+
const isCNB = !!useKey("CNB");
|
|
44049
|
+
const uri = useKey("CNB_VSCODE_PROXY_URI");
|
|
44050
|
+
if (!isCNB)
|
|
44051
|
+
return null;
|
|
44052
|
+
if (uri) {
|
|
44053
|
+
return uri.replace("{{port}}", "51515");
|
|
44054
|
+
}
|
|
44055
|
+
return null;
|
|
44056
|
+
};
|
|
44038
44057
|
// src/module/assistant/proxy/utils.ts
|
|
44039
44058
|
var isBun3 = typeof Bun !== "undefined" && Bun?.version != null;
|
|
44040
44059
|
var isNode3 = typeof process !== "undefined" && process?.versions != null && process.versions?.node != null;
|
|
@@ -51799,8 +51818,10 @@ class RemoteApp {
|
|
|
51799
51818
|
mainApp;
|
|
51800
51819
|
url;
|
|
51801
51820
|
id;
|
|
51821
|
+
username;
|
|
51802
51822
|
emitter;
|
|
51803
51823
|
isConnected;
|
|
51824
|
+
isVerified;
|
|
51804
51825
|
ws;
|
|
51805
51826
|
remoteIsConnected;
|
|
51806
51827
|
isError = false;
|
|
@@ -51817,12 +51838,17 @@ class RemoteApp {
|
|
|
51817
51838
|
const token = opts.token;
|
|
51818
51839
|
const url4 = opts.url;
|
|
51819
51840
|
const id = opts.id;
|
|
51841
|
+
const username = opts.username;
|
|
51842
|
+
this.username = username;
|
|
51820
51843
|
this.emitter = opts?.emitter || new import__2.default;
|
|
51821
51844
|
const _url2 = new URL(url4);
|
|
51822
51845
|
if (token) {
|
|
51823
51846
|
_url2.searchParams.set("token", token);
|
|
51824
51847
|
}
|
|
51825
51848
|
_url2.searchParams.set("id", id);
|
|
51849
|
+
if (!token && !username) {
|
|
51850
|
+
console.error(`[remote-app] 不存在用户名和token ${id}. 权限认证会失败。`);
|
|
51851
|
+
}
|
|
51826
51852
|
this.url = _url2.toString();
|
|
51827
51853
|
this.id = id;
|
|
51828
51854
|
this.autoReconnect = opts?.autoReconnect ?? true;
|
|
@@ -51854,6 +51880,18 @@ class RemoteApp {
|
|
|
51854
51880
|
that.emitter.once("open", listenOnce);
|
|
51855
51881
|
});
|
|
51856
51882
|
}
|
|
51883
|
+
async waitVerify() {
|
|
51884
|
+
if (this.isVerified) {
|
|
51885
|
+
return true;
|
|
51886
|
+
}
|
|
51887
|
+
return new Promise((resolve) => {
|
|
51888
|
+
const listenOnce = () => {
|
|
51889
|
+
this.isVerified = true;
|
|
51890
|
+
resolve(true);
|
|
51891
|
+
};
|
|
51892
|
+
this.emitter.once("verified", listenOnce);
|
|
51893
|
+
});
|
|
51894
|
+
}
|
|
51857
51895
|
getWsURL(url4) {
|
|
51858
51896
|
const { protocol } = new URL(url4);
|
|
51859
51897
|
if (protocol.startsWith("ws")) {
|
|
@@ -51980,6 +52018,7 @@ class RemoteApp {
|
|
|
51980
52018
|
listenProxy() {
|
|
51981
52019
|
const remoteApp = this;
|
|
51982
52020
|
const app = this.mainApp;
|
|
52021
|
+
const username = this.username;
|
|
51983
52022
|
const listenFn = async (event) => {
|
|
51984
52023
|
try {
|
|
51985
52024
|
const data = event.toString();
|
|
@@ -51987,11 +52026,16 @@ class RemoteApp {
|
|
|
51987
52026
|
const bodyData = body?.data;
|
|
51988
52027
|
const message = bodyData?.message || {};
|
|
51989
52028
|
const context = bodyData?.context || {};
|
|
52029
|
+
console.log("[remote-app] 远程应用收到消息:", body);
|
|
51990
52030
|
if (body?.code === 401) {
|
|
51991
|
-
console.error("远程应用认证失败,请检查 token 是否正确");
|
|
52031
|
+
console.error("[remote-app] 远程应用认证失败,请检查 token 是否正确");
|
|
51992
52032
|
this.isError = true;
|
|
51993
52033
|
return;
|
|
51994
52034
|
}
|
|
52035
|
+
if (body?.type === "verified") {
|
|
52036
|
+
remoteApp.emitter.emit("verified");
|
|
52037
|
+
return;
|
|
52038
|
+
}
|
|
51995
52039
|
if (body?.type !== "proxy")
|
|
51996
52040
|
return;
|
|
51997
52041
|
if (!body.id) {
|
|
@@ -52014,13 +52058,15 @@ class RemoteApp {
|
|
|
52014
52058
|
}
|
|
52015
52059
|
});
|
|
52016
52060
|
} catch (error49) {
|
|
52017
|
-
console.error("处理远程代理请求出错:", error49);
|
|
52061
|
+
console.error("[remote-app] 处理远程代理请求出错:", error49);
|
|
52018
52062
|
}
|
|
52019
52063
|
};
|
|
52020
52064
|
remoteApp.json({
|
|
52021
52065
|
id: this.id,
|
|
52022
|
-
type: "registryClient"
|
|
52066
|
+
type: "registryClient",
|
|
52067
|
+
username
|
|
52023
52068
|
});
|
|
52069
|
+
console.log(`[remote-app] 远程应用 ${this.id} (${username}) 已注册到主应用,等待消息...`);
|
|
52024
52070
|
remoteApp.emitter.on("message", listenFn);
|
|
52025
52071
|
const closeMessage = () => {
|
|
52026
52072
|
remoteApp.emitter.off("message", listenFn);
|
|
@@ -80962,10 +81008,11 @@ class AssistantApp extends Manager2 {
|
|
|
80962
81008
|
}
|
|
80963
81009
|
const url4 = new URL(shareUrl);
|
|
80964
81010
|
const id = config4?.app?.id;
|
|
80965
|
-
if (
|
|
81011
|
+
if (url4 && id) {
|
|
80966
81012
|
const remoteApp = new RemoteApp({
|
|
80967
81013
|
url: url4.toString(),
|
|
80968
81014
|
token,
|
|
81015
|
+
username: config4?.auth?.username || "",
|
|
80969
81016
|
id,
|
|
80970
81017
|
app: this.mainApp,
|
|
80971
81018
|
autoReconnect: true,
|
|
@@ -98500,7 +98547,6 @@ async function reload3() {
|
|
|
98500
98547
|
});
|
|
98501
98548
|
});
|
|
98502
98549
|
}
|
|
98503
|
-
|
|
98504
98550
|
// src/routes/config/index.ts
|
|
98505
98551
|
app.route({
|
|
98506
98552
|
path: "config",
|
|
@@ -98522,12 +98568,14 @@ app.route({
|
|
|
98522
98568
|
app.route({
|
|
98523
98569
|
path: "config",
|
|
98524
98570
|
key: "getId",
|
|
98525
|
-
description: "获取appId"
|
|
98571
|
+
description: "获取appId和访问地址"
|
|
98526
98572
|
}).define(async (ctx) => {
|
|
98527
98573
|
const config7 = assistantConfig2.getCacheAssistantConfig();
|
|
98528
98574
|
const appId = config7?.app?.id || null;
|
|
98575
|
+
let kevisualUrl = getCNBUrl() || "https://kevisual.cn";
|
|
98529
98576
|
ctx.body = {
|
|
98530
|
-
id: appId
|
|
98577
|
+
id: appId,
|
|
98578
|
+
url: kevisualUrl
|
|
98531
98579
|
};
|
|
98532
98580
|
}).addTo(app);
|
|
98533
98581
|
|
|
@@ -102203,9 +102251,9 @@ var getLiveMdContent = (opts) => {
|
|
|
102203
102251
|
|
|
102204
102252
|
### 其他说明
|
|
102205
102253
|
|
|
102254
|
+
1. 保活说明
|
|
102206
102255
|
使用插件访问vscode web获取wss进行保活,避免长时间不操作导致的自动断开连接。
|
|
102207
102256
|
|
|
102208
|
-
保活说明
|
|
102209
102257
|
方法1: 使用插件访问vscode web获取wss进行保活,避免长时间不操作导致的自动断开连接。
|
|
102210
102258
|
|
|
102211
102259
|
1. 安装插件[CNB LIVE](https://chromewebstore.google.com/detail/cnb-live/iajpiophkcdghonpijkcgpjafbcjhkko?pli=1)
|
|
@@ -102217,6 +102265,9 @@ var getLiveMdContent = (opts) => {
|
|
|
102217
102265
|
4. 运行cli命令,ev cnb live -c /workspace/live/keep.json.(直接对话opencode或者openclaw调用cnb-live技能即可)
|
|
102218
102266
|
|
|
102219
102267
|
方法2:环境变量设置CNB_COOKIE,直接opencode或者openclaw的ui界面对话说,cnb-keep-live保活,他会自动调用保活,同时不需要点cnb-lie插件获取配置。
|
|
102268
|
+
|
|
102269
|
+
2. Opencode web访问说明
|
|
102270
|
+
Opencode打开web地址,需要在浏览器输入用户名和密码,用户名固定为root,密码为CNB_TOKEN的值. 纯连接打开包含账号密码,第一次点击后,需要把账号密码清理掉才能访问,opencode的bug导致的。
|
|
102220
102271
|
`;
|
|
102221
102272
|
const labels = [
|
|
102222
102273
|
{
|
package/dist/assistant-server.js
CHANGED
|
@@ -82880,13 +82880,22 @@ class AssistantConfig {
|
|
|
82880
82880
|
getDefaultInitAssistantConfig() {
|
|
82881
82881
|
const id = randomId2();
|
|
82882
82882
|
const isCNB = !!useKey2("CNB");
|
|
82883
|
+
let kevisualUrl = "https://kevisual.cn";
|
|
82884
|
+
if (isCNB) {
|
|
82885
|
+
const uri = getCNBUrl();
|
|
82886
|
+
if (uri) {
|
|
82887
|
+
kevisualUrl = uri;
|
|
82888
|
+
} else {
|
|
82889
|
+
kevisualUrl = "http://kevisual.cn";
|
|
82890
|
+
}
|
|
82891
|
+
}
|
|
82883
82892
|
return {
|
|
82884
82893
|
app: {
|
|
82885
|
-
url:
|
|
82894
|
+
url: kevisualUrl,
|
|
82886
82895
|
id
|
|
82887
82896
|
},
|
|
82888
82897
|
description: "助手配置文件",
|
|
82889
|
-
docs:
|
|
82898
|
+
docs: `${kevisualUrl}/root/cli/docs/`,
|
|
82890
82899
|
home: isCNB ? "/root/cli-center" : "/root/home",
|
|
82891
82900
|
proxy: [],
|
|
82892
82901
|
share: {
|
|
@@ -82905,6 +82914,16 @@ var parseIfJson2 = (content) => {
|
|
|
82905
82914
|
}
|
|
82906
82915
|
};
|
|
82907
82916
|
var randomId2 = () => Math.random().toString(36).substring(2, 8);
|
|
82917
|
+
var getCNBUrl = () => {
|
|
82918
|
+
const isCNB = !!useKey2("CNB");
|
|
82919
|
+
const uri = useKey2("CNB_VSCODE_PROXY_URI");
|
|
82920
|
+
if (!isCNB)
|
|
82921
|
+
return null;
|
|
82922
|
+
if (uri) {
|
|
82923
|
+
return uri.replace("{{port}}", "51515");
|
|
82924
|
+
}
|
|
82925
|
+
return null;
|
|
82926
|
+
};
|
|
82908
82927
|
// src/module/assistant/proxy/http-proxy.ts
|
|
82909
82928
|
import http3 from "node:http";
|
|
82910
82929
|
import https2 from "node:https";
|
|
@@ -91414,8 +91433,10 @@ class RemoteApp {
|
|
|
91414
91433
|
mainApp;
|
|
91415
91434
|
url;
|
|
91416
91435
|
id;
|
|
91436
|
+
username;
|
|
91417
91437
|
emitter;
|
|
91418
91438
|
isConnected;
|
|
91439
|
+
isVerified;
|
|
91419
91440
|
ws;
|
|
91420
91441
|
remoteIsConnected;
|
|
91421
91442
|
isError = false;
|
|
@@ -91432,12 +91453,17 @@ class RemoteApp {
|
|
|
91432
91453
|
const token = opts.token;
|
|
91433
91454
|
const url4 = opts.url;
|
|
91434
91455
|
const id = opts.id;
|
|
91456
|
+
const username = opts.username;
|
|
91457
|
+
this.username = username;
|
|
91435
91458
|
this.emitter = opts?.emitter || new import__2.default;
|
|
91436
91459
|
const _url2 = new URL(url4);
|
|
91437
91460
|
if (token) {
|
|
91438
91461
|
_url2.searchParams.set("token", token);
|
|
91439
91462
|
}
|
|
91440
91463
|
_url2.searchParams.set("id", id);
|
|
91464
|
+
if (!token && !username) {
|
|
91465
|
+
console.error(`[remote-app] 不存在用户名和token ${id}. 权限认证会失败。`);
|
|
91466
|
+
}
|
|
91441
91467
|
this.url = _url2.toString();
|
|
91442
91468
|
this.id = id;
|
|
91443
91469
|
this.autoReconnect = opts?.autoReconnect ?? true;
|
|
@@ -91469,6 +91495,18 @@ class RemoteApp {
|
|
|
91469
91495
|
that.emitter.once("open", listenOnce);
|
|
91470
91496
|
});
|
|
91471
91497
|
}
|
|
91498
|
+
async waitVerify() {
|
|
91499
|
+
if (this.isVerified) {
|
|
91500
|
+
return true;
|
|
91501
|
+
}
|
|
91502
|
+
return new Promise((resolve) => {
|
|
91503
|
+
const listenOnce = () => {
|
|
91504
|
+
this.isVerified = true;
|
|
91505
|
+
resolve(true);
|
|
91506
|
+
};
|
|
91507
|
+
this.emitter.once("verified", listenOnce);
|
|
91508
|
+
});
|
|
91509
|
+
}
|
|
91472
91510
|
getWsURL(url4) {
|
|
91473
91511
|
const { protocol } = new URL(url4);
|
|
91474
91512
|
if (protocol.startsWith("ws")) {
|
|
@@ -91595,6 +91633,7 @@ class RemoteApp {
|
|
|
91595
91633
|
listenProxy() {
|
|
91596
91634
|
const remoteApp = this;
|
|
91597
91635
|
const app = this.mainApp;
|
|
91636
|
+
const username = this.username;
|
|
91598
91637
|
const listenFn = async (event) => {
|
|
91599
91638
|
try {
|
|
91600
91639
|
const data = event.toString();
|
|
@@ -91602,11 +91641,16 @@ class RemoteApp {
|
|
|
91602
91641
|
const bodyData = body?.data;
|
|
91603
91642
|
const message = bodyData?.message || {};
|
|
91604
91643
|
const context = bodyData?.context || {};
|
|
91644
|
+
console.log("[remote-app] 远程应用收到消息:", body);
|
|
91605
91645
|
if (body?.code === 401) {
|
|
91606
|
-
console.error("远程应用认证失败,请检查 token 是否正确");
|
|
91646
|
+
console.error("[remote-app] 远程应用认证失败,请检查 token 是否正确");
|
|
91607
91647
|
this.isError = true;
|
|
91608
91648
|
return;
|
|
91609
91649
|
}
|
|
91650
|
+
if (body?.type === "verified") {
|
|
91651
|
+
remoteApp.emitter.emit("verified");
|
|
91652
|
+
return;
|
|
91653
|
+
}
|
|
91610
91654
|
if (body?.type !== "proxy")
|
|
91611
91655
|
return;
|
|
91612
91656
|
if (!body.id) {
|
|
@@ -91629,13 +91673,15 @@ class RemoteApp {
|
|
|
91629
91673
|
}
|
|
91630
91674
|
});
|
|
91631
91675
|
} catch (error49) {
|
|
91632
|
-
console.error("处理远程代理请求出错:", error49);
|
|
91676
|
+
console.error("[remote-app] 处理远程代理请求出错:", error49);
|
|
91633
91677
|
}
|
|
91634
91678
|
};
|
|
91635
91679
|
remoteApp.json({
|
|
91636
91680
|
id: this.id,
|
|
91637
|
-
type: "registryClient"
|
|
91681
|
+
type: "registryClient",
|
|
91682
|
+
username
|
|
91638
91683
|
});
|
|
91684
|
+
console.log(`[remote-app] 远程应用 ${this.id} (${username}) 已注册到主应用,等待消息...`);
|
|
91639
91685
|
remoteApp.emitter.on("message", listenFn);
|
|
91640
91686
|
const closeMessage = () => {
|
|
91641
91687
|
remoteApp.emitter.off("message", listenFn);
|
|
@@ -119995,10 +120041,11 @@ class AssistantApp extends Manager2 {
|
|
|
119995
120041
|
}
|
|
119996
120042
|
const url4 = new URL(shareUrl);
|
|
119997
120043
|
const id = config4?.app?.id;
|
|
119998
|
-
if (
|
|
120044
|
+
if (url4 && id) {
|
|
119999
120045
|
const remoteApp = new RemoteApp({
|
|
120000
120046
|
url: url4.toString(),
|
|
120001
120047
|
token,
|
|
120048
|
+
username: config4?.auth?.username || "",
|
|
120002
120049
|
id,
|
|
120003
120050
|
app: this.mainApp,
|
|
120004
120051
|
autoReconnect: true,
|
|
@@ -122986,7 +123033,6 @@ async function reload3() {
|
|
|
122986
123033
|
});
|
|
122987
123034
|
});
|
|
122988
123035
|
}
|
|
122989
|
-
|
|
122990
123036
|
// src/routes/config/index.ts
|
|
122991
123037
|
app.route({
|
|
122992
123038
|
path: "config",
|
|
@@ -123008,12 +123054,14 @@ app.route({
|
|
|
123008
123054
|
app.route({
|
|
123009
123055
|
path: "config",
|
|
123010
123056
|
key: "getId",
|
|
123011
|
-
description: "获取appId"
|
|
123057
|
+
description: "获取appId和访问地址"
|
|
123012
123058
|
}).define(async (ctx) => {
|
|
123013
123059
|
const config6 = assistantConfig2.getCacheAssistantConfig();
|
|
123014
123060
|
const appId = config6?.app?.id || null;
|
|
123061
|
+
let kevisualUrl = getCNBUrl() || "https://kevisual.cn";
|
|
123015
123062
|
ctx.body = {
|
|
123016
|
-
id: appId
|
|
123063
|
+
id: appId,
|
|
123064
|
+
url: kevisualUrl
|
|
123017
123065
|
};
|
|
123018
123066
|
}).addTo(app);
|
|
123019
123067
|
|
|
@@ -126711,9 +126759,9 @@ var getLiveMdContent = (opts) => {
|
|
|
126711
126759
|
|
|
126712
126760
|
### 其他说明
|
|
126713
126761
|
|
|
126762
|
+
1. 保活说明
|
|
126714
126763
|
使用插件访问vscode web获取wss进行保活,避免长时间不操作导致的自动断开连接。
|
|
126715
126764
|
|
|
126716
|
-
保活说明
|
|
126717
126765
|
方法1: 使用插件访问vscode web获取wss进行保活,避免长时间不操作导致的自动断开连接。
|
|
126718
126766
|
|
|
126719
126767
|
1. 安装插件[CNB LIVE](https://chromewebstore.google.com/detail/cnb-live/iajpiophkcdghonpijkcgpjafbcjhkko?pli=1)
|
|
@@ -126725,6 +126773,9 @@ var getLiveMdContent = (opts) => {
|
|
|
126725
126773
|
4. 运行cli命令,ev cnb live -c /workspace/live/keep.json.(直接对话opencode或者openclaw调用cnb-live技能即可)
|
|
126726
126774
|
|
|
126727
126775
|
方法2:环境变量设置CNB_COOKIE,直接opencode或者openclaw的ui界面对话说,cnb-keep-live保活,他会自动调用保活,同时不需要点cnb-lie插件获取配置。
|
|
126776
|
+
|
|
126777
|
+
2. Opencode web访问说明
|
|
126778
|
+
Opencode打开web地址,需要在浏览器输入用户名和密码,用户名固定为root,密码为CNB_TOKEN的值. 纯连接打开包含账号密码,第一次点击后,需要把账号密码清理掉才能访问,opencode的bug导致的。
|
|
126728
126779
|
`;
|
|
126729
126780
|
const labels = [
|
|
126730
126781
|
{
|
|
@@ -129138,6 +129189,7 @@ var {
|
|
|
129138
129189
|
// src/server.ts
|
|
129139
129190
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
129140
129191
|
import path22 from "node:path";
|
|
129192
|
+
|
|
129141
129193
|
// src/module/get-bun-path.ts
|
|
129142
129194
|
import fs24 from "node:fs";
|
|
129143
129195
|
import path21 from "node:path";
|
package/dist/assistant.js
CHANGED
|
@@ -28807,13 +28807,22 @@ class AssistantConfig {
|
|
|
28807
28807
|
getDefaultInitAssistantConfig() {
|
|
28808
28808
|
const id = randomId();
|
|
28809
28809
|
const isCNB = !!useKey("CNB");
|
|
28810
|
+
let kevisualUrl = "https://kevisual.cn";
|
|
28811
|
+
if (isCNB) {
|
|
28812
|
+
const uri = getCNBUrl();
|
|
28813
|
+
if (uri) {
|
|
28814
|
+
kevisualUrl = uri;
|
|
28815
|
+
} else {
|
|
28816
|
+
kevisualUrl = "http://kevisual.cn";
|
|
28817
|
+
}
|
|
28818
|
+
}
|
|
28810
28819
|
return {
|
|
28811
28820
|
app: {
|
|
28812
|
-
url:
|
|
28821
|
+
url: kevisualUrl,
|
|
28813
28822
|
id
|
|
28814
28823
|
},
|
|
28815
28824
|
description: "助手配置文件",
|
|
28816
|
-
docs:
|
|
28825
|
+
docs: `${kevisualUrl}/root/cli/docs/`,
|
|
28817
28826
|
home: isCNB ? "/root/cli-center" : "/root/home",
|
|
28818
28827
|
proxy: [],
|
|
28819
28828
|
share: {
|
|
@@ -28832,6 +28841,16 @@ var parseIfJson = (content) => {
|
|
|
28832
28841
|
}
|
|
28833
28842
|
};
|
|
28834
28843
|
var randomId = () => Math.random().toString(36).substring(2, 8);
|
|
28844
|
+
var getCNBUrl = () => {
|
|
28845
|
+
const isCNB = !!useKey("CNB");
|
|
28846
|
+
const uri = useKey("CNB_VSCODE_PROXY_URI");
|
|
28847
|
+
if (!isCNB)
|
|
28848
|
+
return null;
|
|
28849
|
+
if (uri) {
|
|
28850
|
+
return uri.replace("{{port}}", "51515");
|
|
28851
|
+
}
|
|
28852
|
+
return null;
|
|
28853
|
+
};
|
|
28835
28854
|
// src/module/assistant/proxy/utils.ts
|
|
28836
28855
|
var isBun = typeof Bun !== "undefined" && Bun?.version != null;
|
|
28837
28856
|
var isNode = typeof process !== "undefined" && process?.versions != null && process.versions?.node != null;
|
|
@@ -36584,8 +36603,10 @@ class RemoteApp {
|
|
|
36584
36603
|
mainApp;
|
|
36585
36604
|
url;
|
|
36586
36605
|
id;
|
|
36606
|
+
username;
|
|
36587
36607
|
emitter;
|
|
36588
36608
|
isConnected;
|
|
36609
|
+
isVerified;
|
|
36589
36610
|
ws;
|
|
36590
36611
|
remoteIsConnected;
|
|
36591
36612
|
isError = false;
|
|
@@ -36602,12 +36623,17 @@ class RemoteApp {
|
|
|
36602
36623
|
const token = opts.token;
|
|
36603
36624
|
const url = opts.url;
|
|
36604
36625
|
const id = opts.id;
|
|
36626
|
+
const username = opts.username;
|
|
36627
|
+
this.username = username;
|
|
36605
36628
|
this.emitter = opts?.emitter || new import__2.default;
|
|
36606
36629
|
const _url = new URL(url);
|
|
36607
36630
|
if (token) {
|
|
36608
36631
|
_url.searchParams.set("token", token);
|
|
36609
36632
|
}
|
|
36610
36633
|
_url.searchParams.set("id", id);
|
|
36634
|
+
if (!token && !username) {
|
|
36635
|
+
console.error(`[remote-app] 不存在用户名和token ${id}. 权限认证会失败。`);
|
|
36636
|
+
}
|
|
36611
36637
|
this.url = _url.toString();
|
|
36612
36638
|
this.id = id;
|
|
36613
36639
|
this.autoReconnect = opts?.autoReconnect ?? true;
|
|
@@ -36639,6 +36665,18 @@ class RemoteApp {
|
|
|
36639
36665
|
that.emitter.once("open", listenOnce);
|
|
36640
36666
|
});
|
|
36641
36667
|
}
|
|
36668
|
+
async waitVerify() {
|
|
36669
|
+
if (this.isVerified) {
|
|
36670
|
+
return true;
|
|
36671
|
+
}
|
|
36672
|
+
return new Promise((resolve) => {
|
|
36673
|
+
const listenOnce = () => {
|
|
36674
|
+
this.isVerified = true;
|
|
36675
|
+
resolve(true);
|
|
36676
|
+
};
|
|
36677
|
+
this.emitter.once("verified", listenOnce);
|
|
36678
|
+
});
|
|
36679
|
+
}
|
|
36642
36680
|
getWsURL(url) {
|
|
36643
36681
|
const { protocol } = new URL(url);
|
|
36644
36682
|
if (protocol.startsWith("ws")) {
|
|
@@ -36765,6 +36803,7 @@ class RemoteApp {
|
|
|
36765
36803
|
listenProxy() {
|
|
36766
36804
|
const remoteApp = this;
|
|
36767
36805
|
const app = this.mainApp;
|
|
36806
|
+
const username = this.username;
|
|
36768
36807
|
const listenFn = async (event) => {
|
|
36769
36808
|
try {
|
|
36770
36809
|
const data = event.toString();
|
|
@@ -36772,11 +36811,16 @@ class RemoteApp {
|
|
|
36772
36811
|
const bodyData = body?.data;
|
|
36773
36812
|
const message = bodyData?.message || {};
|
|
36774
36813
|
const context = bodyData?.context || {};
|
|
36814
|
+
console.log("[remote-app] 远程应用收到消息:", body);
|
|
36775
36815
|
if (body?.code === 401) {
|
|
36776
|
-
console.error("远程应用认证失败,请检查 token 是否正确");
|
|
36816
|
+
console.error("[remote-app] 远程应用认证失败,请检查 token 是否正确");
|
|
36777
36817
|
this.isError = true;
|
|
36778
36818
|
return;
|
|
36779
36819
|
}
|
|
36820
|
+
if (body?.type === "verified") {
|
|
36821
|
+
remoteApp.emitter.emit("verified");
|
|
36822
|
+
return;
|
|
36823
|
+
}
|
|
36780
36824
|
if (body?.type !== "proxy")
|
|
36781
36825
|
return;
|
|
36782
36826
|
if (!body.id) {
|
|
@@ -36799,13 +36843,15 @@ class RemoteApp {
|
|
|
36799
36843
|
}
|
|
36800
36844
|
});
|
|
36801
36845
|
} catch (error2) {
|
|
36802
|
-
console.error("处理远程代理请求出错:", error2);
|
|
36846
|
+
console.error("[remote-app] 处理远程代理请求出错:", error2);
|
|
36803
36847
|
}
|
|
36804
36848
|
};
|
|
36805
36849
|
remoteApp.json({
|
|
36806
36850
|
id: this.id,
|
|
36807
|
-
type: "registryClient"
|
|
36851
|
+
type: "registryClient",
|
|
36852
|
+
username
|
|
36808
36853
|
});
|
|
36854
|
+
console.log(`[remote-app] 远程应用 ${this.id} (${username}) 已注册到主应用,等待消息...`);
|
|
36809
36855
|
remoteApp.emitter.on("message", listenFn);
|
|
36810
36856
|
const closeMessage = () => {
|
|
36811
36857
|
remoteApp.emitter.off("message", listenFn);
|
|
@@ -87221,10 +87267,11 @@ class AssistantApp extends Manager2 {
|
|
|
87221
87267
|
}
|
|
87222
87268
|
const url4 = new URL(shareUrl);
|
|
87223
87269
|
const id = config5?.app?.id;
|
|
87224
|
-
if (
|
|
87270
|
+
if (url4 && id) {
|
|
87225
87271
|
const remoteApp = new RemoteApp({
|
|
87226
87272
|
url: url4.toString(),
|
|
87227
87273
|
token,
|
|
87274
|
+
username: config5?.auth?.username || "",
|
|
87228
87275
|
id,
|
|
87229
87276
|
app: this.mainApp,
|
|
87230
87277
|
autoReconnect: true,
|
package/dist/envision.js
CHANGED
|
@@ -22312,8 +22312,8 @@ InitEnv.init();
|
|
|
22312
22312
|
var version = useContextKey("version", () => {
|
|
22313
22313
|
let version2 = "0.0.64";
|
|
22314
22314
|
try {
|
|
22315
|
-
if ("0.1.
|
|
22316
|
-
version2 = "0.1.
|
|
22315
|
+
if ("0.1.16")
|
|
22316
|
+
version2 = "0.1.16";
|
|
22317
22317
|
} catch (e) {}
|
|
22318
22318
|
return version2;
|
|
22319
22319
|
});
|
|
@@ -28538,7 +28538,7 @@ var getPackageJson = (opts) => {
|
|
|
28538
28538
|
return null;
|
|
28539
28539
|
}
|
|
28540
28540
|
};
|
|
28541
|
-
var command2 = new Command("deploy").description("把前端文件传到服务器").argument("<filePath>", "Path to the file to be uploaded, filepath or directory").option("-v, --version <version>", "verbose").option("-k, --key <key>", "key").option("-y, --yes <yes>", "yes").option("-o, --org <org>", "org").option("-u, --update", "load current app. set current version in product。 redis 缓存更新").option("-s, --showBackend", "show backend url, 部署的后端应用,显示执行的cli命令").option("-d, --dot", "是否上传隐藏文件").option("--dir, --directory <directory>", "
|
|
28541
|
+
var command2 = new Command("deploy").description("把前端文件传到服务器").argument("<filePath>", "Path to the file to be uploaded, filepath or directory").option("-v, --version <version>", "verbose").option("-k, --key <key>", "key").option("-y, --yes <yes>", "yes").option("-o, --org <org>", "org").option("-u, --update", "load current app. set current version in product。 redis 缓存更新").option("-s, --showBackend", "show backend url, 部署的后端应用,显示执行的cli命令").option("-d, --dot", "是否上传隐藏文件").option("--dir, --directory <directory>", "上传的prefix路径,默认为空,例如设置为static,则会上传到/${username}/resources/${key}/${version}/static/路径下").action(async (filePath, options) => {
|
|
28542
28542
|
try {
|
|
28543
28543
|
let { version: version2, key, yes, update, org, showBackend } = options;
|
|
28544
28544
|
const dot = !!options.dot;
|
|
@@ -28646,7 +28646,7 @@ var command2 = new Command("deploy").description("把前端文件传到服务器
|
|
|
28646
28646
|
}
|
|
28647
28647
|
});
|
|
28648
28648
|
var uploadFilesV2 = async (files, directory, opts) => {
|
|
28649
|
-
const { key, version: version2, username } = opts || {};
|
|
28649
|
+
const { key, version: version2, username, directory: prefix } = opts || {};
|
|
28650
28650
|
for (let i = 0;i < files.length; i++) {
|
|
28651
28651
|
const file = files[i];
|
|
28652
28652
|
const filePath = path3.join(directory, file);
|
|
@@ -28659,7 +28659,7 @@ var uploadFilesV2 = async (files, directory, opts) => {
|
|
|
28659
28659
|
filepath: file
|
|
28660
28660
|
});
|
|
28661
28661
|
const _baseURL = getBaseURL();
|
|
28662
|
-
const url = new URL(`/${username}/resources/${key}/${version2}/${file}`, _baseURL);
|
|
28662
|
+
const url = new URL(`/${username}/resources/${key}/${version2}/${prefix ? prefix + "/" : ""}${file}`, _baseURL);
|
|
28663
28663
|
const token2 = await storage.getItem("token");
|
|
28664
28664
|
const check = () => {
|
|
28665
28665
|
const checkUrl = new URL(url.toString());
|
|
@@ -29997,14 +29997,20 @@ class SyncBase {
|
|
|
29997
29997
|
async getSyncList(opts) {
|
|
29998
29998
|
const config2 = this.config;
|
|
29999
29999
|
let sync = config2?.sync || {};
|
|
30000
|
+
const local2 = opts?.getLocalFile ?? true;
|
|
30000
30001
|
const syncDirectory = await this.getSyncDirectoryList();
|
|
30001
|
-
|
|
30002
|
+
if (local2) {
|
|
30003
|
+
sync = this.getMergeSync(sync, syncDirectory.sync);
|
|
30004
|
+
}
|
|
30002
30005
|
const syncKeys = Object.keys(sync);
|
|
30003
30006
|
const baseURL3 = this.baseURL;
|
|
30004
30007
|
const syncList = syncKeys.map((key) => {
|
|
30005
30008
|
const value = sync[key];
|
|
30006
30009
|
const filepath = path9.join(this.#dir, key);
|
|
30007
|
-
|
|
30010
|
+
const dirs = path9.dirname(filepath).split(path9.sep);
|
|
30011
|
+
const hasGit = dirs.includes(".git");
|
|
30012
|
+
const hasNodeModules = dirs.includes("node_modules");
|
|
30013
|
+
if (hasGit || hasNodeModules) {
|
|
30008
30014
|
return null;
|
|
30009
30015
|
}
|
|
30010
30016
|
if (typeof value === "string") {
|
|
@@ -30299,10 +30305,14 @@ var syncCreateList = new Command("create").option("-d --dir <dir>", "配置目
|
|
|
30299
30305
|
logger.info(newJson);
|
|
30300
30306
|
}
|
|
30301
30307
|
});
|
|
30302
|
-
var clone = new Command("clone").option("-d --dir <dir>", "配置目录").option("-c --config <config>", "配置文件的名字", "kevisual.json").option("-i --link <link>", "克隆链接, 比 kevisual.json 优先级更高").description("检查目录").action(async (opts) => {
|
|
30303
|
-
|
|
30308
|
+
var clone = new Command("clone").option("-d --dir <dir>", "配置目录").option("-c --config <config>", "配置文件的名字", "kevisual.json").option("-i --link <link>", "克隆链接, 比 kevisual.json 优先级更高").option("-l --local", "值对sync的列表进行clone处理,只对sync列表处理").description("检查目录").action(async (opts) => {
|
|
30309
|
+
let link = opts.link || "";
|
|
30310
|
+
const local2 = opts.local || false;
|
|
30304
30311
|
const sync = new SyncBase({ dir: opts.dir, baseURL, configFilename: opts.config });
|
|
30305
30312
|
if (link) {
|
|
30313
|
+
if (!link.endsWith(".json")) {
|
|
30314
|
+
link = link + (link.endsWith("/") ? "" : "/") + "kevisual.json";
|
|
30315
|
+
}
|
|
30306
30316
|
const res = await query.fetchText(link);
|
|
30307
30317
|
if (res.code === 200) {
|
|
30308
30318
|
fs14.writeFileSync(sync.configPath, JSON.stringify(res.data, null, 2));
|
|
@@ -30312,7 +30322,7 @@ var clone = new Command("clone").option("-d --dir <dir>", "配置目录").option
|
|
|
30312
30322
|
}
|
|
30313
30323
|
await sync.init();
|
|
30314
30324
|
}
|
|
30315
|
-
const syncList2 = await sync.getSyncList();
|
|
30325
|
+
const syncList2 = await sync.getSyncList({ getLocalFile: !local2 });
|
|
30316
30326
|
logger.debug(syncList2);
|
|
30317
30327
|
logger.info(`检查目录
|
|
30318
30328
|
`);
|
|
@@ -30338,21 +30348,22 @@ var clone = new Command("clone").option("-d --dir <dir>", "配置目录").option
|
|
|
30338
30348
|
const rp = sync.getRelativePath(item2.pathname);
|
|
30339
30349
|
if (!rp)
|
|
30340
30350
|
return false;
|
|
30341
|
-
if (rp.absolute.endsWith("gitignore.txt")) {
|
|
30342
|
-
const newPath = rp.absolute.replace("gitignore.txt", ".gitignore");
|
|
30343
|
-
rp.absolute = newPath;
|
|
30344
|
-
rp.relative = path10.relative(sync.dir, newPath);
|
|
30345
|
-
} else if (rp.absolute.endsWith(".dot")) {
|
|
30346
|
-
const filename = path10.basename(rp.absolute, ".dot");
|
|
30347
|
-
const newPath = path10.join(path10.dirname(rp.absolute), `.${filename}`);
|
|
30348
|
-
rp.absolute = newPath;
|
|
30349
|
-
rp.relative = path10.relative(sync.dir, newPath);
|
|
30350
|
-
}
|
|
30351
30351
|
return { ...item2, relative: rp.relative, absolute: rp.absolute };
|
|
30352
30352
|
}).filter((i) => i);
|
|
30353
30353
|
for (const matchItem of matchList) {
|
|
30354
30354
|
if (!matchItem)
|
|
30355
30355
|
continue;
|
|
30356
|
+
if (local2) {
|
|
30357
|
+
const some = syncList2.some((syncItem) => {
|
|
30358
|
+
if (syncItem.url === matchItem.url) {
|
|
30359
|
+
return true;
|
|
30360
|
+
}
|
|
30361
|
+
return false;
|
|
30362
|
+
});
|
|
30363
|
+
if (!some) {
|
|
30364
|
+
continue;
|
|
30365
|
+
}
|
|
30366
|
+
}
|
|
30356
30367
|
let needDownload = true;
|
|
30357
30368
|
let hash = "";
|
|
30358
30369
|
await sync.getDir(matchItem.absolute, true);
|