@kevisual/cli 0.0.93 → 0.0.95

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.
@@ -58805,6 +58805,8 @@ var initConfig = (configRootPath) => {
58805
58805
  const pageConfigPath = path.join(configDir2, "assistant-page-config.json");
58806
58806
  const pagesDir = createDir(path.join(configDir2, "pages"));
58807
58807
  const appsDir = createDir(path.join(configDir2, "apps"));
58808
+ const skillsDir = createDir(path.join(configDir2, "skills"), false);
58809
+ const pluginsDir = createDir(path.join(configDir2, "plugins"), false);
58808
58810
  const appsConfigPath = path.join(configDir2, "assistant-apps-config.json");
58809
58811
  const appPidPath = path.join(configDir2, "assistant-app.pid");
58810
58812
  const envConfigPath = path.join(configDir2, ".env");
@@ -58816,7 +58818,9 @@ var initConfig = (configRootPath) => {
58816
58818
  pagesDir,
58817
58819
  pageConfigPath,
58818
58820
  appPidPath,
58819
- envConfigPath
58821
+ envConfigPath,
58822
+ skillsDir,
58823
+ pluginsDir
58820
58824
  };
58821
58825
  };
58822
58826
  var assistantConfig;
@@ -68674,7 +68678,7 @@ import path6 from "node:path";
68674
68678
  import fs9 from "node:fs";
68675
68679
 
68676
68680
  // src/module/light-code/run.ts
68677
- import { fork as fork3 } from "child_process";
68681
+ import { fork as fork3 } from "node:child_process";
68678
68682
  import fs7 from "fs";
68679
68683
  var fileExists = (path6) => {
68680
68684
  try {
@@ -68872,11 +68876,18 @@ var initLightCode = async (opts) => {
68872
68876
  if (routerItem.path?.includes("auth") || routerItem.path?.includes("router") || routerItem.path?.includes("call")) {
68873
68877
  continue;
68874
68878
  }
68879
+ const metadata = routerItem.metadata || {};
68880
+ if (metadata.tags && Array.isArray(metadata.tags)) {
68881
+ metadata.tags.push("light-code");
68882
+ } else {
68883
+ metadata.tags = ["light-code"];
68884
+ }
68875
68885
  app.route({
68876
68886
  id: routerItem.id,
68877
- path: routerItem.id,
68887
+ path: `${routerItem.id}__${routerItem.path}`,
68888
+ key: routerItem.key,
68878
68889
  description: routerItem.description || "",
68879
- metadata: routerItem.metadata || {},
68890
+ metadata,
68880
68891
  middleware: ["auth"]
68881
68892
  }).define(async (ctx) => {
68882
68893
  const tokenUser = ctx.state?.tokenUser || {};
@@ -68991,7 +69002,8 @@ class AssistantApp extends Manager2 {
68991
69002
  if (isConnect) {
68992
69003
  remoteApp.listenProxy();
68993
69004
  this.remoteIsConnected = true;
68994
- remoteApp.emitter.once("close", () => {
69005
+ remoteApp.emitter.removeAllListeners("close");
69006
+ remoteApp.emitter.on("close", () => {
68995
69007
  setTimeout(() => {
68996
69008
  if (remoteApp.isError) {
68997
69009
  console.error("远程应用发生错误,不重连");
@@ -69091,8 +69103,8 @@ class AssistantApp extends Manager2 {
69091
69103
  remoteApp.listenProxy();
69092
69104
  this.attemptedConnectTimes = 0;
69093
69105
  console.log("重新连接到了远程应用服务器");
69094
- this.reconnectRemoteApp();
69095
69106
  } else {
69107
+ this.reconnectRemoteApp();
69096
69108
  setTimeout(() => {
69097
69109
  this.initRouterApp();
69098
69110
  }, 30 * 1000 + this.attemptedConnectTimes * 10 * 1000);
@@ -109694,13 +109706,13 @@ async function getPorts(options) {
109694
109706
  // src/routes/opencode/module/open.ts
109695
109707
  import os5 from "node:os";
109696
109708
  import { execSync } from "node:child_process";
109709
+ var DEFAULT_PORT = 5000;
109697
109710
 
109698
109711
  class OpencodeManager {
109699
109712
  static instance = null;
109700
109713
  client = null;
109701
109714
  server = null;
109702
109715
  isInitializing = false;
109703
- currentPort = null;
109704
109716
  url = "";
109705
109717
  constructor() {}
109706
109718
  static getInstance() {
@@ -109709,17 +109721,17 @@ class OpencodeManager {
109709
109721
  }
109710
109722
  return OpencodeManager.instance;
109711
109723
  }
109712
- async getClient() {
109724
+ async getClient(opts) {
109725
+ const port = opts?.port ?? DEFAULT_PORT;
109713
109726
  if (this.client) {
109714
109727
  return this.client;
109715
109728
  }
109716
109729
  if (this.isInitializing) {
109717
109730
  await new Promise((resolve) => setTimeout(resolve, 100));
109718
- return this.getClient();
109731
+ return this.getClient(opts);
109719
109732
  }
109720
109733
  this.isInitializing = true;
109721
109734
  try {
109722
- const port = 5000;
109723
109735
  const currentPort = await getPorts({ port });
109724
109736
  if (port === currentPort) {
109725
109737
  const result = await createOpencode({
@@ -109775,13 +109787,13 @@ class OpencodeManager {
109775
109787
  console.error("Failed to close OpenCode server:", error4);
109776
109788
  }
109777
109789
  }
109778
- async close() {
109790
+ async close(opts) {
109779
109791
  if (this.server) {
109780
109792
  this.server.close();
109781
109793
  this.server = null;
109782
109794
  return;
109783
109795
  }
109784
- const port = 5000;
109796
+ const port = opts?.port ?? DEFAULT_PORT;
109785
109797
  const currentPort = await getPorts({ port });
109786
109798
  if (port === currentPort) {
109787
109799
  this.client = null;
@@ -109791,14 +109803,20 @@ class OpencodeManager {
109791
109803
  }
109792
109804
  this.client = null;
109793
109805
  }
109794
- async getUrl() {
109806
+ async getUrl(opts) {
109807
+ const port = opts?.port ?? DEFAULT_PORT;
109795
109808
  if (this.url) {
109796
109809
  return this.url;
109797
109810
  }
109798
109811
  if (!this.url) {
109799
- await this.getClient();
109812
+ await this.getClient(opts);
109800
109813
  }
109801
- return "http://localhost:5000";
109814
+ return `http://localhost:${port}`;
109815
+ }
109816
+ async restart(opts) {
109817
+ const port = opts?.port ?? DEFAULT_PORT;
109818
+ await this.close({ port });
109819
+ return await this.getClient({ port });
109802
109820
  }
109803
109821
  }
109804
109822
  var opencodeManager = OpencodeManager.getInstance();
@@ -109815,11 +109833,13 @@ app.route({
109815
109833
  skill: "create-opencode-client",
109816
109834
  title: "创建 OpenCode 客户端",
109817
109835
  summary: "创建 OpenCode 客户端,如果存在则复用",
109818
- args: {}
109836
+ args: {
109837
+ port: tool.schema.number().optional().describe("OpenCode 服务端口,默认为 5000")
109838
+ }
109819
109839
  })
109820
109840
  }
109821
109841
  }).define(async (ctx) => {
109822
- const client3 = await opencodeManager.getClient();
109842
+ const client3 = await opencodeManager.getClient({ port: ctx.query.port });
109823
109843
  ctx.body = { content: `${opencodeManager.url} OpenCode 客户端已就绪` };
109824
109844
  }).addTo(app);
109825
109845
  app.route({
@@ -109832,14 +109852,38 @@ app.route({
109832
109852
  ...createSkill({
109833
109853
  skill: "close-opencode-client",
109834
109854
  title: "关闭 OpenCode 客户端",
109835
- summary: "关闭 OpenCode 客户端",
109836
- args: {}
109855
+ summary: "关闭 OpenCode 客户端, 未提供端口则关闭默认端口",
109856
+ args: {
109857
+ port: tool.schema.number().optional().describe("OpenCode 服务端口,默认为 5000")
109858
+ }
109837
109859
  })
109838
109860
  }
109839
109861
  }).define(async (ctx) => {
109840
- await opencodeManager.close();
109862
+ const port = ctx.query.port;
109863
+ await opencodeManager.close({ port });
109841
109864
  ctx.body = { content: "OpenCode 客户端已关闭" };
109842
109865
  }).addTo(app);
109866
+ app.route({
109867
+ path: "opencode",
109868
+ key: "restart",
109869
+ middleware: ["auth"],
109870
+ description: "重启 OpenCode 客户端",
109871
+ metadata: {
109872
+ tags: ["opencode"],
109873
+ ...createSkill({
109874
+ skill: "restart-opencode-client",
109875
+ title: "重启 OpenCode 客户端",
109876
+ summary: "重启 OpenCode 客户端",
109877
+ args: {
109878
+ port: tool.schema.number().optional().describe("OpenCode 服务端口,默认为 5000")
109879
+ }
109880
+ })
109881
+ }
109882
+ }).define(async (ctx) => {
109883
+ const port = ctx.query.port;
109884
+ const res = await opencodeManager.restart({ port });
109885
+ ctx.body = { content: `${opencodeManager.url} OpenCode 客户端已经重启` };
109886
+ }).addTo(app);
109843
109887
  app.route({
109844
109888
  path: "opencode",
109845
109889
  key: "getUrl",
@@ -109851,11 +109895,13 @@ app.route({
109851
109895
  skill: "get-opencode-url",
109852
109896
  title: "获取 OpenCode 服务 URL",
109853
109897
  summary: "获取当前 OpenCode 服务的 URL 地址",
109854
- args: {}
109898
+ args: {
109899
+ port: tool.schema.number().optional().describe("OpenCode 服务端口,默认为 5000")
109900
+ }
109855
109901
  })
109856
109902
  }
109857
109903
  }).define(async (ctx) => {
109858
- const url4 = await opencodeManager.getUrl();
109904
+ const url4 = await opencodeManager.getUrl({ port: ctx.query.port });
109859
109905
  const cnbURL = useKey("CNB_VSCODE_PROXY_URI");
109860
109906
  let content = `本地访问地址: ${url4}`;
109861
109907
  if (cnbURL) {
@@ -110508,6 +110554,126 @@ app.route({
110508
110554
  });
110509
110555
  }).addTo(app);
110510
110556
 
110557
+ // src/module/cmd/run.ts
110558
+ import { spawn as spawn5 } from "node:child_process";
110559
+ var runCmd = (opts) => {
110560
+ const { cmd, cwd } = opts || {};
110561
+ return new Promise((resolve) => {
110562
+ const parts = cmd.split(" ");
110563
+ const command = parts[0];
110564
+ const args = parts.slice(1);
110565
+ const proc = spawn5(command, args, {
110566
+ cwd: cwd || process.cwd(),
110567
+ shell: true,
110568
+ env: { ...process.env, ...opts?.env }
110569
+ });
110570
+ let stdout = "";
110571
+ let stderr = "";
110572
+ let result = "";
110573
+ proc.stdout.on("data", (data) => {
110574
+ stdout += data.toString();
110575
+ });
110576
+ proc.stderr.on("data", (data) => {
110577
+ stderr += data.toString();
110578
+ });
110579
+ proc.on("close", (code2) => {
110580
+ result = stdout;
110581
+ if (stderr) {
110582
+ result += `
110583
+ ` + stderr;
110584
+ }
110585
+ resolve({ code: code2 === 0 ? 200 : code2, data: result });
110586
+ });
110587
+ proc.on("error", (err) => {
110588
+ resolve({ code: 500, data: err.message });
110589
+ });
110590
+ });
110591
+ };
110592
+
110593
+ // src/routes/kevisual/auth.ts
110594
+ app.route({
110595
+ path: "kevisual",
110596
+ key: " me",
110597
+ description: "查看 ev cli 是否登录",
110598
+ middleware: ["admin-auth"],
110599
+ metadata: {
110600
+ tags: ["opencode"],
110601
+ ...createSkill({
110602
+ skill: "kevisual-me",
110603
+ title: "查看 ev cli 是否登录",
110604
+ summary: "查看 ev cli 是否登录",
110605
+ args: {}
110606
+ })
110607
+ }
110608
+ }).define(async (ctx) => {
110609
+ const cmd = "ev me";
110610
+ const res = await runCmd({ cmd });
110611
+ if (res.code === 200) {
110612
+ ctx.body = { content: res.data };
110613
+ } else {
110614
+ ctx.throw(500, res.data);
110615
+ }
110616
+ }).addTo(app);
110617
+ app.route({
110618
+ path: "kevisual",
110619
+ key: "loginByAdmin",
110620
+ description: "通过当前登录用户 ev cli",
110621
+ middleware: ["admin-auth"],
110622
+ metadata: {
110623
+ tags: ["opencode"],
110624
+ ...createSkill({
110625
+ skill: "kevisual-login-by-admin",
110626
+ title: "通过当前登录用户 ev cli",
110627
+ summary: "通过当前登录用户登录 ev cli, 直接用当前的用户的 token 直接设置 token 给 ev cli, 登录失败直接停止任务",
110628
+ args: {}
110629
+ })
110630
+ }
110631
+ }).define(async (ctx) => {
110632
+ const token = ctx.query?.token || useKey("KEVISUAL_TOKEN");
110633
+ if (!token) {
110634
+ ctx.throw(400, "登录的 token 不能为空,请传入 token 参数");
110635
+ return;
110636
+ }
110637
+ const cmd = `ev login -e `;
110638
+ const res = await runCmd({
110639
+ cmd,
110640
+ env: {
110641
+ KEVISUAL_TOKEN: token
110642
+ }
110643
+ });
110644
+ if (res.code === 200) {
110645
+ ctx.body = { content: res.data };
110646
+ } else {
110647
+ ctx.throw(500, res.data);
110648
+ }
110649
+ }).addTo(app);
110650
+
110651
+ // src/routes/kevisual/deploy.ts
110652
+ app.route({
110653
+ path: "kevisual",
110654
+ key: "deploy",
110655
+ description: "部署一个网页",
110656
+ middleware: ["admin-auth"],
110657
+ metadata: {
110658
+ tags: ["kevisual"],
110659
+ ...createSkill({
110660
+ skill: "kevisual-deploy",
110661
+ title: "部署一个网页",
110662
+ summary: "部署一个网页到 kevisual 平台",
110663
+ args: {
110664
+ filepath: tool.schema.string().describe("要部署的网页文件路径"),
110665
+ appKey: tool.schema.string().optional().describe("应用的 appKey,如果不传则创建一个新的应用"),
110666
+ version: tool.schema.string().optional().describe("应用的版本号,默认为 1.0.0"),
110667
+ update: tool.schema.boolean().optional().describe("是否同时更新部署,默认为 false")
110668
+ }
110669
+ })
110670
+ }
110671
+ }).define(async (ctx) => {
110672
+ const { filepath, appKey, update } = ctx.query;
110673
+ console.log("部署网页,filepath:", filepath, "appKey:", appKey);
110674
+ ctx.body = { content: "部署功能正在开发中,敬请期待!" };
110675
+ }).addTo(app);
110676
+
110511
110677
  // src/routes/index.ts
110512
110678
  import os6 from "node:os";
110513
110679
 
@@ -111709,17 +111875,15 @@ var checkAuth = async (ctx, isAdmin = false) => {
111709
111875
  }
111710
111876
  authCache.set(token, tokenUser);
111711
111877
  }
111712
- if (ctx.state) {
111713
- ctx.state = {
111714
- ...ctx.state,
111715
- token,
111716
- tokenUser
111717
- };
111718
- }
111878
+ ctx.state = {
111879
+ ...ctx.state,
111880
+ token,
111881
+ tokenUser
111882
+ };
111719
111883
  const { username } = tokenUser;
111720
111884
  if (!auth.username) {
111721
111885
  auth.username = username;
111722
- assistantConfig2.setConfig({ auth });
111886
+ assistantConfig2.setConfig({ auth, token });
111723
111887
  }
111724
111888
  if (isAdmin && auth.username) {
111725
111889
  const admins = config4.auth?.admin || [];
@@ -111727,6 +111891,12 @@ var checkAuth = async (ctx, isAdmin = false) => {
111727
111891
  const admin = auth.username;
111728
111892
  if (admin === username) {
111729
111893
  isCheckAdmin = true;
111894
+ const _token = config4.token;
111895
+ if (!_token) {
111896
+ assistantConfig2.setConfig({ token });
111897
+ } else if (_token && _token.startsWith("st-") && _token !== token) {
111898
+ assistantConfig2.setConfig({ token });
111899
+ }
111730
111900
  }
111731
111901
  if (!isCheckAdmin && admins.length > 0 && admins.includes(username)) {
111732
111902
  isCheckAdmin = true;
@@ -111761,7 +111931,6 @@ app.route({
111761
111931
  id: "admin-auth",
111762
111932
  description: "管理员鉴权, 获取用户信息,并验证是否为管理员。"
111763
111933
  }).define(async (ctx) => {
111764
- logger.debug("query", ctx.query);
111765
111934
  if (!ctx.query?.token && ctx.appId === app.appId) {
111766
111935
  return;
111767
111936
  }
@@ -100480,6 +100480,8 @@ var initConfig = (configRootPath) => {
100480
100480
  const pageConfigPath = path.join(configDir2, "assistant-page-config.json");
100481
100481
  const pagesDir = createDir(path.join(configDir2, "pages"));
100482
100482
  const appsDir = createDir(path.join(configDir2, "apps"));
100483
+ const skillsDir = createDir(path.join(configDir2, "skills"), false);
100484
+ const pluginsDir = createDir(path.join(configDir2, "plugins"), false);
100483
100485
  const appsConfigPath = path.join(configDir2, "assistant-apps-config.json");
100484
100486
  const appPidPath = path.join(configDir2, "assistant-app.pid");
100485
100487
  const envConfigPath = path.join(configDir2, ".env");
@@ -100491,7 +100493,9 @@ var initConfig = (configRootPath) => {
100491
100493
  pagesDir,
100492
100494
  pageConfigPath,
100493
100495
  appPidPath,
100494
- envConfigPath
100496
+ envConfigPath,
100497
+ skillsDir,
100498
+ pluginsDir
100495
100499
  };
100496
100500
  };
100497
100501
  var assistantConfig;
@@ -111075,7 +111079,7 @@ import path9 from "node:path";
111075
111079
  import fs11 from "node:fs";
111076
111080
 
111077
111081
  // src/module/light-code/run.ts
111078
- import { fork as fork3 } from "child_process";
111082
+ import { fork as fork3 } from "node:child_process";
111079
111083
  import fs9 from "fs";
111080
111084
  var fileExists = (path9) => {
111081
111085
  try {
@@ -111273,11 +111277,18 @@ var initLightCode = async (opts) => {
111273
111277
  if (routerItem.path?.includes("auth") || routerItem.path?.includes("router") || routerItem.path?.includes("call")) {
111274
111278
  continue;
111275
111279
  }
111280
+ const metadata = routerItem.metadata || {};
111281
+ if (metadata.tags && Array.isArray(metadata.tags)) {
111282
+ metadata.tags.push("light-code");
111283
+ } else {
111284
+ metadata.tags = ["light-code"];
111285
+ }
111276
111286
  app.route({
111277
111287
  id: routerItem.id,
111278
- path: routerItem.id,
111288
+ path: `${routerItem.id}__${routerItem.path}`,
111289
+ key: routerItem.key,
111279
111290
  description: routerItem.description || "",
111280
- metadata: routerItem.metadata || {},
111291
+ metadata,
111281
111292
  middleware: ["auth"]
111282
111293
  }).define(async (ctx) => {
111283
111294
  const tokenUser = ctx.state?.tokenUser || {};
@@ -111392,7 +111403,8 @@ class AssistantApp extends Manager2 {
111392
111403
  if (isConnect) {
111393
111404
  remoteApp.listenProxy();
111394
111405
  this.remoteIsConnected = true;
111395
- remoteApp.emitter.once("close", () => {
111406
+ remoteApp.emitter.removeAllListeners("close");
111407
+ remoteApp.emitter.on("close", () => {
111396
111408
  setTimeout(() => {
111397
111409
  if (remoteApp.isError) {
111398
111410
  console.error("远程应用发生错误,不重连");
@@ -111492,8 +111504,8 @@ class AssistantApp extends Manager2 {
111492
111504
  remoteApp.listenProxy();
111493
111505
  this.attemptedConnectTimes = 0;
111494
111506
  console.log("重新连接到了远程应用服务器");
111495
- this.reconnectRemoteApp();
111496
111507
  } else {
111508
+ this.reconnectRemoteApp();
111497
111509
  setTimeout(() => {
111498
111510
  this.initRouterApp();
111499
111511
  }, 30 * 1000 + this.attemptedConnectTimes * 10 * 1000);
@@ -137625,13 +137637,13 @@ function portNumbers(from3, to) {
137625
137637
  // src/routes/opencode/module/open.ts
137626
137638
  import os5 from "node:os";
137627
137639
  import { execSync } from "node:child_process";
137640
+ var DEFAULT_PORT = 5000;
137628
137641
 
137629
137642
  class OpencodeManager {
137630
137643
  static instance = null;
137631
137644
  client = null;
137632
137645
  server = null;
137633
137646
  isInitializing = false;
137634
- currentPort = null;
137635
137647
  url = "";
137636
137648
  constructor() {}
137637
137649
  static getInstance() {
@@ -137640,17 +137652,17 @@ class OpencodeManager {
137640
137652
  }
137641
137653
  return OpencodeManager.instance;
137642
137654
  }
137643
- async getClient() {
137655
+ async getClient(opts) {
137656
+ const port = opts?.port ?? DEFAULT_PORT;
137644
137657
  if (this.client) {
137645
137658
  return this.client;
137646
137659
  }
137647
137660
  if (this.isInitializing) {
137648
137661
  await new Promise((resolve) => setTimeout(resolve, 100));
137649
- return this.getClient();
137662
+ return this.getClient(opts);
137650
137663
  }
137651
137664
  this.isInitializing = true;
137652
137665
  try {
137653
- const port = 5000;
137654
137666
  const currentPort = await getPorts({ port });
137655
137667
  if (port === currentPort) {
137656
137668
  const result = await createOpencode({
@@ -137706,13 +137718,13 @@ class OpencodeManager {
137706
137718
  console.error("Failed to close OpenCode server:", error3);
137707
137719
  }
137708
137720
  }
137709
- async close() {
137721
+ async close(opts) {
137710
137722
  if (this.server) {
137711
137723
  this.server.close();
137712
137724
  this.server = null;
137713
137725
  return;
137714
137726
  }
137715
- const port = 5000;
137727
+ const port = opts?.port ?? DEFAULT_PORT;
137716
137728
  const currentPort = await getPorts({ port });
137717
137729
  if (port === currentPort) {
137718
137730
  this.client = null;
@@ -137722,14 +137734,20 @@ class OpencodeManager {
137722
137734
  }
137723
137735
  this.client = null;
137724
137736
  }
137725
- async getUrl() {
137737
+ async getUrl(opts) {
137738
+ const port = opts?.port ?? DEFAULT_PORT;
137726
137739
  if (this.url) {
137727
137740
  return this.url;
137728
137741
  }
137729
137742
  if (!this.url) {
137730
- await this.getClient();
137743
+ await this.getClient(opts);
137731
137744
  }
137732
- return "http://localhost:5000";
137745
+ return `http://localhost:${port}`;
137746
+ }
137747
+ async restart(opts) {
137748
+ const port = opts?.port ?? DEFAULT_PORT;
137749
+ await this.close({ port });
137750
+ return await this.getClient({ port });
137733
137751
  }
137734
137752
  }
137735
137753
  var opencodeManager = OpencodeManager.getInstance();
@@ -137746,11 +137764,13 @@ app.route({
137746
137764
  skill: "create-opencode-client",
137747
137765
  title: "创建 OpenCode 客户端",
137748
137766
  summary: "创建 OpenCode 客户端,如果存在则复用",
137749
- args: {}
137767
+ args: {
137768
+ port: tool.schema.number().optional().describe("OpenCode 服务端口,默认为 5000")
137769
+ }
137750
137770
  })
137751
137771
  }
137752
137772
  }).define(async (ctx) => {
137753
- const client3 = await opencodeManager.getClient();
137773
+ const client3 = await opencodeManager.getClient({ port: ctx.query.port });
137754
137774
  ctx.body = { content: `${opencodeManager.url} OpenCode 客户端已就绪` };
137755
137775
  }).addTo(app);
137756
137776
  app.route({
@@ -137763,14 +137783,38 @@ app.route({
137763
137783
  ...createSkill({
137764
137784
  skill: "close-opencode-client",
137765
137785
  title: "关闭 OpenCode 客户端",
137766
- summary: "关闭 OpenCode 客户端",
137767
- args: {}
137786
+ summary: "关闭 OpenCode 客户端, 未提供端口则关闭默认端口",
137787
+ args: {
137788
+ port: tool.schema.number().optional().describe("OpenCode 服务端口,默认为 5000")
137789
+ }
137768
137790
  })
137769
137791
  }
137770
137792
  }).define(async (ctx) => {
137771
- await opencodeManager.close();
137793
+ const port = ctx.query.port;
137794
+ await opencodeManager.close({ port });
137772
137795
  ctx.body = { content: "OpenCode 客户端已关闭" };
137773
137796
  }).addTo(app);
137797
+ app.route({
137798
+ path: "opencode",
137799
+ key: "restart",
137800
+ middleware: ["auth"],
137801
+ description: "重启 OpenCode 客户端",
137802
+ metadata: {
137803
+ tags: ["opencode"],
137804
+ ...createSkill({
137805
+ skill: "restart-opencode-client",
137806
+ title: "重启 OpenCode 客户端",
137807
+ summary: "重启 OpenCode 客户端",
137808
+ args: {
137809
+ port: tool.schema.number().optional().describe("OpenCode 服务端口,默认为 5000")
137810
+ }
137811
+ })
137812
+ }
137813
+ }).define(async (ctx) => {
137814
+ const port = ctx.query.port;
137815
+ const res = await opencodeManager.restart({ port });
137816
+ ctx.body = { content: `${opencodeManager.url} OpenCode 客户端已经重启` };
137817
+ }).addTo(app);
137774
137818
  app.route({
137775
137819
  path: "opencode",
137776
137820
  key: "getUrl",
@@ -137782,11 +137826,13 @@ app.route({
137782
137826
  skill: "get-opencode-url",
137783
137827
  title: "获取 OpenCode 服务 URL",
137784
137828
  summary: "获取当前 OpenCode 服务的 URL 地址",
137785
- args: {}
137829
+ args: {
137830
+ port: tool.schema.number().optional().describe("OpenCode 服务端口,默认为 5000")
137831
+ }
137786
137832
  })
137787
137833
  }
137788
137834
  }).define(async (ctx) => {
137789
- const url3 = await opencodeManager.getUrl();
137835
+ const url3 = await opencodeManager.getUrl({ port: ctx.query.port });
137790
137836
  const cnbURL = useKey("CNB_VSCODE_PROXY_URI");
137791
137837
  let content = `本地访问地址: ${url3}`;
137792
137838
  if (cnbURL) {
@@ -137888,6 +137934,126 @@ app.route({
137888
137934
  });
137889
137935
  }).addTo(app);
137890
137936
 
137937
+ // src/module/cmd/run.ts
137938
+ import { spawn as spawn5 } from "node:child_process";
137939
+ var runCmd = (opts) => {
137940
+ const { cmd, cwd } = opts || {};
137941
+ return new Promise((resolve) => {
137942
+ const parts = cmd.split(" ");
137943
+ const command = parts[0];
137944
+ const args = parts.slice(1);
137945
+ const proc = spawn5(command, args, {
137946
+ cwd: cwd || process.cwd(),
137947
+ shell: true,
137948
+ env: { ...process.env, ...opts?.env }
137949
+ });
137950
+ let stdout = "";
137951
+ let stderr = "";
137952
+ let result = "";
137953
+ proc.stdout.on("data", (data) => {
137954
+ stdout += data.toString();
137955
+ });
137956
+ proc.stderr.on("data", (data) => {
137957
+ stderr += data.toString();
137958
+ });
137959
+ proc.on("close", (code2) => {
137960
+ result = stdout;
137961
+ if (stderr) {
137962
+ result += `
137963
+ ` + stderr;
137964
+ }
137965
+ resolve({ code: code2 === 0 ? 200 : code2, data: result });
137966
+ });
137967
+ proc.on("error", (err) => {
137968
+ resolve({ code: 500, data: err.message });
137969
+ });
137970
+ });
137971
+ };
137972
+
137973
+ // src/routes/kevisual/auth.ts
137974
+ app.route({
137975
+ path: "kevisual",
137976
+ key: " me",
137977
+ description: "查看 ev cli 是否登录",
137978
+ middleware: ["admin-auth"],
137979
+ metadata: {
137980
+ tags: ["opencode"],
137981
+ ...createSkill({
137982
+ skill: "kevisual-me",
137983
+ title: "查看 ev cli 是否登录",
137984
+ summary: "查看 ev cli 是否登录",
137985
+ args: {}
137986
+ })
137987
+ }
137988
+ }).define(async (ctx) => {
137989
+ const cmd = "ev me";
137990
+ const res = await runCmd({ cmd });
137991
+ if (res.code === 200) {
137992
+ ctx.body = { content: res.data };
137993
+ } else {
137994
+ ctx.throw(500, res.data);
137995
+ }
137996
+ }).addTo(app);
137997
+ app.route({
137998
+ path: "kevisual",
137999
+ key: "loginByAdmin",
138000
+ description: "通过当前登录用户 ev cli",
138001
+ middleware: ["admin-auth"],
138002
+ metadata: {
138003
+ tags: ["opencode"],
138004
+ ...createSkill({
138005
+ skill: "kevisual-login-by-admin",
138006
+ title: "通过当前登录用户 ev cli",
138007
+ summary: "通过当前登录用户登录 ev cli, 直接用当前的用户的 token 直接设置 token 给 ev cli, 登录失败直接停止任务",
138008
+ args: {}
138009
+ })
138010
+ }
138011
+ }).define(async (ctx) => {
138012
+ const token = ctx.query?.token || useKey("KEVISUAL_TOKEN");
138013
+ if (!token) {
138014
+ ctx.throw(400, "登录的 token 不能为空,请传入 token 参数");
138015
+ return;
138016
+ }
138017
+ const cmd = `ev login -e `;
138018
+ const res = await runCmd({
138019
+ cmd,
138020
+ env: {
138021
+ KEVISUAL_TOKEN: token
138022
+ }
138023
+ });
138024
+ if (res.code === 200) {
138025
+ ctx.body = { content: res.data };
138026
+ } else {
138027
+ ctx.throw(500, res.data);
138028
+ }
138029
+ }).addTo(app);
138030
+
138031
+ // src/routes/kevisual/deploy.ts
138032
+ app.route({
138033
+ path: "kevisual",
138034
+ key: "deploy",
138035
+ description: "部署一个网页",
138036
+ middleware: ["admin-auth"],
138037
+ metadata: {
138038
+ tags: ["kevisual"],
138039
+ ...createSkill({
138040
+ skill: "kevisual-deploy",
138041
+ title: "部署一个网页",
138042
+ summary: "部署一个网页到 kevisual 平台",
138043
+ args: {
138044
+ filepath: tool.schema.string().describe("要部署的网页文件路径"),
138045
+ appKey: tool.schema.string().optional().describe("应用的 appKey,如果不传则创建一个新的应用"),
138046
+ version: tool.schema.string().optional().describe("应用的版本号,默认为 1.0.0"),
138047
+ update: tool.schema.boolean().optional().describe("是否同时更新部署,默认为 false")
138048
+ }
138049
+ })
138050
+ }
138051
+ }).define(async (ctx) => {
138052
+ const { filepath, appKey, update } = ctx.query;
138053
+ console.log("部署网页,filepath:", filepath, "appKey:", appKey);
138054
+ ctx.body = { content: "部署功能正在开发中,敬请期待!" };
138055
+ }).addTo(app);
138056
+
137891
138057
  // src/routes/index.ts
137892
138058
  import os6 from "node:os";
137893
138059
 
@@ -139103,17 +139269,15 @@ var checkAuth = async (ctx, isAdmin = false) => {
139103
139269
  }
139104
139270
  authCache.set(token, tokenUser);
139105
139271
  }
139106
- if (ctx.state) {
139107
- ctx.state = {
139108
- ...ctx.state,
139109
- token,
139110
- tokenUser
139111
- };
139112
- }
139272
+ ctx.state = {
139273
+ ...ctx.state,
139274
+ token,
139275
+ tokenUser
139276
+ };
139113
139277
  const { username } = tokenUser;
139114
139278
  if (!auth.username) {
139115
139279
  auth.username = username;
139116
- assistantConfig2.setConfig({ auth });
139280
+ assistantConfig2.setConfig({ auth, token });
139117
139281
  }
139118
139282
  if (isAdmin && auth.username) {
139119
139283
  const admins = config3.auth?.admin || [];
@@ -139121,6 +139285,12 @@ var checkAuth = async (ctx, isAdmin = false) => {
139121
139285
  const admin = auth.username;
139122
139286
  if (admin === username) {
139123
139287
  isCheckAdmin = true;
139288
+ const _token = config3.token;
139289
+ if (!_token) {
139290
+ assistantConfig2.setConfig({ token });
139291
+ } else if (_token && _token.startsWith("st-") && _token !== token) {
139292
+ assistantConfig2.setConfig({ token });
139293
+ }
139124
139294
  }
139125
139295
  if (!isCheckAdmin && admins.length > 0 && admins.includes(username)) {
139126
139296
  isCheckAdmin = true;
@@ -139155,7 +139325,6 @@ app.route({
139155
139325
  id: "admin-auth",
139156
139326
  description: "管理员鉴权, 获取用户信息,并验证是否为管理员。"
139157
139327
  }).define(async (ctx) => {
139158
- logger.debug("query", ctx.query);
139159
139328
  if (!ctx.query?.token && ctx.appId === app.appId) {
139160
139329
  return;
139161
139330
  }
package/dist/assistant.js CHANGED
@@ -44057,6 +44057,8 @@ var initConfig = (configRootPath) => {
44057
44057
  const pageConfigPath = path.join(configDir2, "assistant-page-config.json");
44058
44058
  const pagesDir = createDir(path.join(configDir2, "pages"));
44059
44059
  const appsDir = createDir(path.join(configDir2, "apps"));
44060
+ const skillsDir = createDir(path.join(configDir2, "skills"), false);
44061
+ const pluginsDir = createDir(path.join(configDir2, "plugins"), false);
44060
44062
  const appsConfigPath = path.join(configDir2, "assistant-apps-config.json");
44061
44063
  const appPidPath = path.join(configDir2, "assistant-app.pid");
44062
44064
  const envConfigPath = path.join(configDir2, ".env");
@@ -44068,7 +44070,9 @@ var initConfig = (configRootPath) => {
44068
44070
  pagesDir,
44069
44071
  pageConfigPath,
44070
44072
  appPidPath,
44071
- envConfigPath
44073
+ envConfigPath,
44074
+ skillsDir,
44075
+ pluginsDir
44072
44076
  };
44073
44077
  };
44074
44078
  var assistantConfig;
@@ -63926,7 +63930,7 @@ import path6 from "node:path";
63926
63930
  import fs9 from "node:fs";
63927
63931
 
63928
63932
  // src/module/light-code/run.ts
63929
- import { fork as fork3 } from "child_process";
63933
+ import { fork as fork3 } from "node:child_process";
63930
63934
  import fs7 from "fs";
63931
63935
  var fileExists = (path6) => {
63932
63936
  try {
@@ -64124,11 +64128,18 @@ var initLightCode = async (opts) => {
64124
64128
  if (routerItem.path?.includes("auth") || routerItem.path?.includes("router") || routerItem.path?.includes("call")) {
64125
64129
  continue;
64126
64130
  }
64131
+ const metadata = routerItem.metadata || {};
64132
+ if (metadata.tags && Array.isArray(metadata.tags)) {
64133
+ metadata.tags.push("light-code");
64134
+ } else {
64135
+ metadata.tags = ["light-code"];
64136
+ }
64127
64137
  app.route({
64128
64138
  id: routerItem.id,
64129
- path: routerItem.id,
64139
+ path: `${routerItem.id}__${routerItem.path}`,
64140
+ key: routerItem.key,
64130
64141
  description: routerItem.description || "",
64131
- metadata: routerItem.metadata || {},
64142
+ metadata,
64132
64143
  middleware: ["auth"]
64133
64144
  }).define(async (ctx) => {
64134
64145
  const tokenUser = ctx.state?.tokenUser || {};
@@ -64243,7 +64254,8 @@ class AssistantApp extends Manager2 {
64243
64254
  if (isConnect) {
64244
64255
  remoteApp.listenProxy();
64245
64256
  this.remoteIsConnected = true;
64246
- remoteApp.emitter.once("close", () => {
64257
+ remoteApp.emitter.removeAllListeners("close");
64258
+ remoteApp.emitter.on("close", () => {
64247
64259
  setTimeout(() => {
64248
64260
  if (remoteApp.isError) {
64249
64261
  console.error("远程应用发生错误,不重连");
@@ -64343,8 +64355,8 @@ class AssistantApp extends Manager2 {
64343
64355
  remoteApp.listenProxy();
64344
64356
  this.attemptedConnectTimes = 0;
64345
64357
  console.log("重新连接到了远程应用服务器");
64346
- this.reconnectRemoteApp();
64347
64358
  } else {
64359
+ this.reconnectRemoteApp();
64348
64360
  setTimeout(() => {
64349
64361
  this.initRouterApp();
64350
64362
  }, 30 * 1000 + this.attemptedConnectTimes * 10 * 1000);
@@ -64616,8 +64628,8 @@ var assistantConfig2 = new AssistantConfig({
64616
64628
  import fs11 from "fs";
64617
64629
  var version2 = "0.0.1";
64618
64630
  try {
64619
- if ("0.0.7")
64620
- version2 = "0.0.7";
64631
+ if ("0.0.8")
64632
+ version2 = "0.0.8";
64621
64633
  } catch (e) {}
64622
64634
  program.name("asst").description("A CLI tool with envison").version(version2, "-v, --version", "output the current version");
64623
64635
  var ls = new Command("ls").description("List files in the current directory").action(() => {
package/dist/envision.js CHANGED
@@ -22327,8 +22327,8 @@ InitEnv.init();
22327
22327
  var version = useContextKey("version", () => {
22328
22328
  let version2 = "0.0.64";
22329
22329
  try {
22330
- if ("0.0.93")
22331
- version2 = "0.0.93";
22330
+ if ("0.0.95")
22331
+ version2 = "0.0.95";
22332
22332
  } catch (e) {}
22333
22333
  return version2;
22334
22334
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kevisual/cli",
3
- "version": "0.0.93",
3
+ "version": "0.0.95",
4
4
  "description": "envision 命令行工具",
5
5
  "type": "module",
6
6
  "basename": "/root/cli",