@lazycatcloud/lzc-cli 1.3.15 → 1.3.17

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/changelog.md CHANGED
@@ -1,55 +1,69 @@
1
1
  # Changelog
2
2
 
3
- ## [1.3.15](https://gitee.com/linakesi/lzc-cli/compare/v1.3.14...v1.3.15) (2026-02-26)
3
+ ## [1.3.17](https://gitee.com/linakesi/lzc-cli/compare/v1.3.15...v1.3.17) (2026-03-03)
4
4
 
5
5
 
6
6
  ### Bug Fixes
7
7
 
8
- * disable i18next support notice output ([f433c88](https://gitee.com/linakesi/lzc-cli/commits/f433c88e9a2434c9cff303c088fa39d33bf59309))
8
+ * dealing with the error prompt of creating a new app ([6069b28](https://gitee.com/linakesi/lzc-cli/commits/6069b282027c7a6ddbcde45a0ff26156e6745030))
9
+ * playground site url ([5afd2ec](https://gitee.com/linakesi/lzc-cli/commits/5afd2ec5edd8aee51579add5daed3ccaabc4650f))
10
+ * submit the app file size ([7dffe90](https://gitee.com/linakesi/lzc-cli/commits/7dffe90b4a18f6f4b8afd8ace23c836d7fba17a7))
9
11
 
10
- ## [1.3.14](https://gitee.com/linakesi/lzc-cli/compare/v1.3.13...v1.3.14) (2025-12-17)
12
+ ## [1.3.16](https://gitee.com/linakesi/lzc-cli/compare/v1.3.13...v1.3.16) (2026-02-28)
13
+
14
+ ### Bug Fixes
15
+
16
+ - dealing with the i18n difference escape problem ([2b98cdf](https://gitee.com/linakesi/lzc-cli/commits/2b98cdf0573a1537bee409079d6160da1b7cd80b))
17
+ - disable i18next support notice output ([f433c88](https://gitee.com/linakesi/lzc-cli/commits/f433c88e9a2434c9cff303c088fa39d33bf59309))
18
+ - playground site url ([5afd2ec](https://gitee.com/linakesi/lzc-cli/commits/5afd2ec5edd8aee51579add5daed3ccaabc4650f))
11
19
 
20
+ ### Features
21
+
22
+ - cmd publish add `changelog-files` option ([17d95c6](https://gitee.com/linakesi/lzc-cli/commits/17d95c6fa761f25af234946dedd3d6a0503ba962))
23
+
24
+ ## [1.3.15](https://gitee.com/linakesi/lzc-cli/compare/v1.3.14...v1.3.15) (2026-02-26)
12
25
 
13
26
  ### Bug Fixes
14
27
 
15
- * dealing with the i18n difference escape problem ([2b98cdf](https://gitee.com/linakesi/lzc-cli/commits/2b98cdf0573a1537bee409079d6160da1b7cd80b))
28
+ - disable i18next support notice output ([f433c88](https://gitee.com/linakesi/lzc-cli/commits/f433c88e9a2434c9cff303c088fa39d33bf59309))
16
29
 
30
+ ## [1.3.14](https://gitee.com/linakesi/lzc-cli/compare/v1.3.13...v1.3.14) (2025-12-17)
31
+
32
+ ### Bug Fixes
33
+
34
+ - dealing with the i18n difference escape problem ([2b98cdf](https://gitee.com/linakesi/lzc-cli/commits/2b98cdf0573a1537bee409079d6160da1b7cd80b))
17
35
 
18
36
  ### Features
19
37
 
20
- * cmd publish add `changelog-files` option ([17d95c6](https://gitee.com/linakesi/lzc-cli/commits/17d95c6fa761f25af234946dedd3d6a0503ba962))
38
+ - cmd publish add `changelog-files` option ([17d95c6](https://gitee.com/linakesi/lzc-cli/commits/17d95c6fa761f25af234946dedd3d6a0503ba962))
21
39
 
22
40
  ## [1.3.13](https://gitee.com/linakesi/lzc-cli/compare/v1.3.12...v1.3.13) (2025-12-10)
23
41
 
24
-
25
42
  ### Features
26
43
 
27
- * add i18n ([f62c52a](https://gitee.com/linakesi/lzc-cli/commits/f62c52a9b443d2226ffa06d17593f1912b9dc4de))
28
- * add i18n config ([185418d](https://gitee.com/linakesi/lzc-cli/commits/185418d5e77858d55fca485ff115191c0c95834e))
29
- * some copywriters provide i18n calls ([54d92f1](https://gitee.com/linakesi/lzc-cli/commits/54d92f17520e6413d735c82d57d3aa3404410add))
44
+ - add i18n ([f62c52a](https://gitee.com/linakesi/lzc-cli/commits/f62c52a9b443d2226ffa06d17593f1912b9dc4de))
45
+ - add i18n config ([185418d](https://gitee.com/linakesi/lzc-cli/commits/185418d5e77858d55fca485ff115191c0c95834e))
46
+ - some copywriters provide i18n calls ([54d92f1](https://gitee.com/linakesi/lzc-cli/commits/54d92f17520e6413d735c82d57d3aa3404410add))
30
47
 
31
48
  ## [1.3.12](https://gitee.com/linakesi/lzc-cli/compare/v1.3.11...v1.3.12) (2025-10-29)
32
49
 
33
-
34
50
  ### Bug Fixes
35
51
 
36
- * ci friendly publish command ([1e7b477](https://gitee.com/linakesi/lzc-cli/commits/1e7b47740f1d9ae15d677a16a97d7cc461814c42))
37
- * pre publish print error ([55c8326](https://gitee.com/linakesi/lzc-cli/commits/55c832625aa532bab3e0fcf0d7ec09d8235db190))
38
-
52
+ - ci friendly publish command ([1e7b477](https://gitee.com/linakesi/lzc-cli/commits/1e7b47740f1d9ae15d677a16a97d7cc461814c42))
53
+ - pre publish print error ([55c8326](https://gitee.com/linakesi/lzc-cli/commits/55c832625aa532bab3e0fcf0d7ec09d8235db190))
39
54
 
40
55
  ### Features
41
56
 
42
- * add `LZC_CLI_CHECK_DNS_RESOLVE` set check dev tools to use built-in dns resolution ([78ba39e](https://gitee.com/linakesi/lzc-cli/commits/78ba39e6869cbed956141e7ff7812ce3718e41ce))
43
- * supports config the language key for publish app update logs through `--clang` ([e06eec8](https://gitee.com/linakesi/lzc-cli/commits/e06eec88f11827816ddd4e3a7ccd43b2883a1003))
44
- * uninstall app add `--delete-data` parameter ([b4378f7](https://gitee.com/linakesi/lzc-cli/commits/b4378f77b528fbb5b5a1c74771ddda9f60f4e49a))
57
+ - add `LZC_CLI_CHECK_DNS_RESOLVE` set check dev tools to use built-in dns resolution ([78ba39e](https://gitee.com/linakesi/lzc-cli/commits/78ba39e6869cbed956141e7ff7812ce3718e41ce))
58
+ - supports config the language key for publish app update logs through `--clang` ([e06eec8](https://gitee.com/linakesi/lzc-cli/commits/e06eec88f11827816ddd4e3a7ccd43b2883a1003))
59
+ - uninstall app add `--delete-data` parameter ([b4378f7](https://gitee.com/linakesi/lzc-cli/commits/b4378f77b528fbb5b5a1c74771ddda9f60f4e49a))
45
60
 
46
61
  ## [1.3.11](https://gitee.com/linakesi/lzc-cli/compare/v1.3.10...v1.3.11) (2025-10-10)
47
62
 
48
-
49
63
  ### Features
50
64
 
51
- * support setting token through environment variables ([4a25f84](https://gitee.com/linakesi/lzc-cli/commits/4a25f84fe4df938cb3d85f6391e27772dae5b071))
52
- * the copy-image command adds the `trace-level` parameter ([cd4d4c3](https://gitee.com/linakesi/lzc-cli/commits/cd4d4c351d4bd43bffcfe5f67087c6bffd65d3f4))
65
+ - support setting token through environment variables ([4a25f84](https://gitee.com/linakesi/lzc-cli/commits/4a25f84fe4df938cb3d85f6391e27772dae5b071))
66
+ - the copy-image command adds the `trace-level` parameter ([cd4d4c3](https://gitee.com/linakesi/lzc-cli/commits/cd4d4c351d4bd43bffcfe5f67087c6bffd65d3f4))
53
67
 
54
68
  ## [1.3.10](https://gitee.com/linakesi/lzc-cli/compare/v0.0.8...v1.3.10) (2025-08-15)
55
69
 
package/lib/app/index.js CHANGED
@@ -130,10 +130,16 @@ export function lpkAppCommand(program) {
130
130
  type: 'string',
131
131
  default: 'y',
132
132
  });
133
+ args.option('ssh-private-key', {
134
+ alias: 'ssh-key',
135
+ describe: t('lzc_cli.lib.app.index.lpk_cmd_install_args_ssh_private_key_desc', '指定安装时用于连接设备的 SSH 私钥路径(兼容别名: --ssh-key)'),
136
+ type: 'string',
137
+ });
133
138
  },
134
- handler: async ({ pkgPath, apk }) => {
139
+ handler: async ({ pkgPath, apk, sshPrivateKey }) => {
135
140
  await shellApi.init();
136
141
  installConfig.apk = apk == 'y';
142
+ installConfig.sshPrivateKey = sshPrivateKey ? path.resolve(sshPrivateKey) : '';
137
143
 
138
144
  pkgPath = pkgPath ?? process.cwd();
139
145
  const installer = new LpkInstaller();
@@ -7,7 +7,7 @@ import shellapi from '../shellapi.js';
7
7
  import { t } from '../i18n/index.js';
8
8
  import { triggerApk } from './apkshell.js';
9
9
 
10
- export const installConfig = { apk: true };
10
+ export const installConfig = { apk: true, sshPrivateKey: '' };
11
11
  // 从一个目录中找出修改时间最新的包
12
12
  function findOnceLpkByDir(dir = process.cwd()) {
13
13
  const pkg = fs
@@ -26,9 +26,9 @@ function findOnceLpkByDir(dir = process.cwd()) {
26
26
  }
27
27
 
28
28
  export class LpkInstaller {
29
- constructor() { }
29
+ constructor() {}
30
30
 
31
- async init() { }
31
+ async init() {}
32
32
 
33
33
  // deploy 构建和安装
34
34
  async deploy(builder) {
@@ -116,7 +116,7 @@ export class LpkInstaller {
116
116
 
117
117
  try {
118
118
  const bridge = new DebugBridge();
119
- await bridge.init();
119
+ await bridge.init(installConfig.sshPrivateKey);
120
120
  logger.info(t('lzc_cli.lib.app.lpk_installer.install_from_file_start_tips', '开始安装应用'));
121
121
  await bridge.install(pkgPath, manifest ? manifest['package'] : '');
122
122
  logger.info('\n');
@@ -126,7 +126,7 @@ export class LpkInstaller {
126
126
  t('lzc_cli.lib.app.lpk_installer.install_from_file_done_tips', `👉 请在浏览器中访问 https://{{ subdomain }}.{{ boxname }}.heiyu.space`, {
127
127
  subdomain: manifest['application']['subdomain'],
128
128
  boxname: shellapi.boxname,
129
- interpolation: { escapeValue: false }
129
+ interpolation: { escapeValue: false },
130
130
  }),
131
131
  );
132
132
  logger.info(t('lzc_cli.lib.app.lpk_installer.install_from_file_login_tips', `👉 并使用微服的用户名和密码登录`));
@@ -107,15 +107,33 @@ async function askPublishAppInfo(baseUrl, manifest, locale) {
107
107
  }
108
108
 
109
109
  async function askWhetherCreateLPK(baseUrl, manifest, locale) {
110
- const answers = await inquirer.prompt([
111
- {
112
- name: 'continue',
113
- type: 'input',
114
- message: t('lzc_cli.lib.publish.ask_whether_create_lpk_continue_prompt', '检测到您当前的应用,还没有在懒猫微服中创建,是否使用当前的安装包中的信息进行创建? [y/n]'),
115
- default: 'y',
116
- },
117
- ]);
118
- if (answers.continue.toLowerCase() === 'y') {
110
+ try {
111
+ // 是否允许创建应用预检请求
112
+ const _options = await request(`${baseUrl}/app/create`, {
113
+ method: 'OPTIONS',
114
+ });
115
+ logger.debug('create app preflight:', { url: _options.url, ok: _options.ok, status: _options.status });
116
+ if (!_options.ok || _options.status < 199 || _options.status > 299) {
117
+ throw undefined;
118
+ }
119
+
120
+ // 要求输入应用信息
121
+ const answers = await inquirer.prompt([
122
+ {
123
+ name: 'continue',
124
+ type: 'input',
125
+ message: t(
126
+ 'lzc_cli.lib.publish.ask_whether_create_lpk_continue_prompt',
127
+ '检测到您当前的应用,还没有在懒猫微服中创建,是否使用当前的安装包中的信息进行创建? [y/n]',
128
+ ),
129
+ default: 'y',
130
+ },
131
+ ]);
132
+ if (answers.continue.toLowerCase() != 'y') {
133
+ throw undefined;
134
+ }
135
+
136
+ // 发送创建应用请求
119
137
  const appInfo = await askPublishAppInfo(baseUrl, manifest, locale);
120
138
  const crateAppRes = await request(`${baseUrl}/app/create`, {
121
139
  method: 'POST',
@@ -127,9 +145,28 @@ async function askWhetherCreateLPK(baseUrl, manifest, locale) {
127
145
  source_author: appInfo.author,
128
146
  }),
129
147
  });
130
- logger.debug('create app res: ', await crateAppRes.text());
131
- logger.info(t('lzc_cli.lib.publish.ask_whether_create_lpk_success_tips', `创建 {{ package }} 应用成功!`, { package: manifest['package'], interpolation: { escapeValue: false } }));
132
- } else {
148
+ logger.debug('create app res:', await crateAppRes.text());
149
+ if (!crateAppRes.ok) {
150
+ const data = await crateAppRes.json();
151
+ throw new Error(data?.message || `status:${crateAppRes.status} statusText:${crateAppRes.statusText}`);
152
+ }
153
+ logger.info(
154
+ t('lzc_cli.lib.publish.ask_whether_create_lpk_success_tips', `创建 {{ package }} 应用成功!`, {
155
+ package: manifest['package'],
156
+ interpolation: { escapeValue: false },
157
+ }),
158
+ );
159
+ } catch (error) {
160
+ if (error) {
161
+ logger.debug('create app failed: ', error.message ?? 'unknown');
162
+ logger.error(
163
+ t('lzc_cli.lib.publish.ask_whether_create_lpk_failed_tips', `创建 {{ package }} 应用失败!`, {
164
+ package: manifest['package'],
165
+ interpolation: { escapeValue: false },
166
+ }),
167
+ error.message || '',
168
+ );
169
+ }
133
170
  logger.info(
134
171
  t(
135
172
  'lzc_cli.lib.publish.ask_whether_create_lpk_fail_tips',
@@ -212,7 +249,7 @@ export class Publish {
212
249
 
213
250
  const { manifest, appIdExisted } = await this.checkAppIdExist(pkgPath);
214
251
  if (!appIdExisted) {
215
- await askWhetherCreateLPK(this.baseUrl, manifest, locale);
252
+ await askWhetherCreateLPK(this.baseUrl, manifest, currentLocale);
216
253
  }
217
254
 
218
255
  await autoLogin();
@@ -239,7 +276,7 @@ export class Publish {
239
276
  logger.error(
240
277
  t('lzc_cli.lib.publish.publish_lpk_fail_tips', `LPK 文件上传失败,err: {{ message }}`, {
241
278
  message: lpkInfo?.message ?? lpkInfo,
242
- interpolation: { escapeValue: false }
279
+ interpolation: { escapeValue: false },
243
280
  }),
244
281
  );
245
282
  throw new Error(lpkInfo?.message ?? lpkInfo);
@@ -253,7 +290,7 @@ export class Publish {
253
290
 
254
291
  // changelogs 本地化
255
292
  const langKey = getLanguageForLocale(currentLocale);
256
- changelogs[langKey] = changelog
293
+ changelogs[langKey] = changelog;
257
294
  }
258
295
  logger.debug('publish changelogs is', changelogs);
259
296
 
@@ -270,6 +307,8 @@ export class Publish {
270
307
  pkg_path: lpkInfo.url,
271
308
  unsupported_platforms: lpkInfo.unsupportedPlatforms,
272
309
  min_os_version: lpkInfo.minOsVersion,
310
+ lpk_size: lpkInfo.lpkSize,
311
+ image_size: lpkInfo.imageSize,
273
312
  changelogs,
274
313
  },
275
314
  };
@@ -28,9 +28,11 @@ export class DebugBridge {
28
28
  this.boxname = shellApi.boxname;
29
29
  this.domain = `dev.${this.boxname}.heiyu.space`;
30
30
  this.checkUseResolve = !!process.env[`${_SYSTEM_ENV_PREFIX}_CHECK_DNS_RESOLVE`];
31
+ this.sshPrivateKeyPath = '';
31
32
  }
32
33
 
33
- async init() {
34
+ async init(sshPrivateKeyPath = '') {
35
+ this.setSshPrivateKey(sshPrivateKeyPath);
34
36
  await this.checkDevTools();
35
37
  if (!(await this.canPublicKey())) {
36
38
  // 如果不能 ssh public key 登录则提示授权申请,否则后面可能会出现 rsync 询问密码的问题
@@ -38,13 +40,45 @@ export class DebugBridge {
38
40
  }
39
41
  }
40
42
 
43
+ setSshPrivateKey(sshPrivateKeyPath = '') {
44
+ this.sshPrivateKeyPath = '';
45
+ if (!sshPrivateKeyPath) {
46
+ return;
47
+ }
48
+ if (!fs.existsSync(sshPrivateKeyPath)) {
49
+ throw t('lzc_cli.lib.debug_bridge.ssh_private_key_not_exist_fail', '指定的 ssh 私钥不存在: {{ sshPrivateKeyPath }}', {
50
+ sshPrivateKeyPath,
51
+ interpolation: { escapeValue: false },
52
+ });
53
+ }
54
+ const keyStat = fs.statSync(sshPrivateKeyPath);
55
+ if (!keyStat.isFile()) {
56
+ throw t('lzc_cli.lib.debug_bridge.ssh_private_key_not_file_fail', '指定的 ssh 私钥路径不是文件: {{ sshPrivateKeyPath }}', {
57
+ sshPrivateKeyPath,
58
+ interpolation: { escapeValue: false },
59
+ });
60
+ }
61
+ this.sshPrivateKeyPath = sshPrivateKeyPath;
62
+ logger.info(
63
+ t('lzc_cli.lib.debug_bridge.ssh_private_key_in_use_tips', '当前使用 --ssh-private-key: {{ sshPrivateKeyPath }}', {
64
+ sshPrivateKeyPath,
65
+ interpolation: { escapeValue: false },
66
+ }),
67
+ );
68
+ }
69
+
70
+ buildSshCmdArgs(...args) {
71
+ const identityArg = this.sshPrivateKeyPath ? [`-i "${this.sshPrivateKeyPath}"`] : [];
72
+ return sshCmdArgs(...identityArg, ...args);
73
+ }
74
+
41
75
  async checkDevTools() {
42
76
  let domain = this.domain;
43
77
  if (this.checkUseResolve) {
44
78
  try {
45
79
  const _ipv6 = await resolveDomain(this.domain, true);
46
80
  domain = `[${_ipv6}]`;
47
- } catch { }
81
+ } catch {}
48
82
  }
49
83
  const url = `https://${domain}/bannerfile`;
50
84
  return new Promise((resolve, reject) => {
@@ -87,21 +121,21 @@ export class DebugBridge {
87
121
  ssh.status == 0
88
122
  ? resolve(ssh.stdout)
89
123
  : reject(
90
- t('lzc_cli.lib.debug_bridge.common_exec_fail', `执行命令 {{ cmd }} {{ args }} 出错\n{{ stdout }}\n{{ stderr }}`, {
91
- cmd,
92
- args: args.join(' '),
93
- stdout: ssh.stdout ?? '',
94
- stdout: ssh.stderr ?? '',
95
- interpolation: { escapeValue: false }
96
- }),
97
- );
124
+ t('lzc_cli.lib.debug_bridge.common_exec_fail', `执行命令 {{ cmd }} {{ args }} 出错\n{{ stdout }}\n{{ stderr }}`, {
125
+ cmd,
126
+ args: args.join(' '),
127
+ stdout: ssh.stdout ?? '',
128
+ stdout: ssh.stderr ?? '',
129
+ interpolation: { escapeValue: false },
130
+ }),
131
+ );
98
132
  });
99
133
  }
100
134
 
101
135
  async install(lpkPath, pkgId) {
102
136
  const stream = fs.createReadStream(lpkPath);
103
137
  const resolvedIp = await resolveDomain(this.domain);
104
- const ssh = spawn(sshBinary(), [...sshCmdArgs(`box@${resolvedIp}`), `install --uid ${this.uid}`, pkgId ? `--pkgId ${pkgId}` : ''], {
138
+ const ssh = spawn(sshBinary(), [...this.buildSshCmdArgs(`box@${resolvedIp}`), `install --uid ${this.uid}`, pkgId ? `--pkgId ${pkgId}` : ''], {
105
139
  shell: true,
106
140
  stdio: ['pipe', 'inherit', 'inherit'],
107
141
  });
@@ -115,7 +149,7 @@ export class DebugBridge {
115
149
 
116
150
  async canPublicKey() {
117
151
  try {
118
- await this.common(sshBinary(), [...sshCmdArgs(`box@${this.domain}`)]);
152
+ await this.common(sshBinary(), [...this.buildSshCmdArgs(`box@${this.domain}`)]);
119
153
  return true;
120
154
  } catch (err) {
121
155
  logger.debug('canPublicKey error: ', err);
@@ -146,7 +180,7 @@ export class DebugBridge {
146
180
  boxname: this.boxname,
147
181
  domain: this.domain,
148
182
  pk,
149
- interpolation: { escapeValue: false }
183
+ interpolation: { escapeValue: false },
150
184
  },
151
185
  ),
152
186
  );
@@ -154,21 +188,21 @@ export class DebugBridge {
154
188
  }
155
189
 
156
190
  async status(appId) {
157
- return this.common(sshBinary(), [...sshCmdArgs(`box@${this.domain}`), `status --uid ${this.uid}`, appId]);
191
+ return this.common(sshBinary(), [...this.buildSshCmdArgs(`box@${this.domain}`), `status --uid ${this.uid}`, appId]);
158
192
  }
159
193
 
160
194
  async isDevshell(appId) {
161
195
  await this.backendVersion020();
162
- const stdout = await this.common(sshBinary(), [...sshCmdArgs(`box@${this.domain}`), `isDevshellV2 --uid ${this.uid}`, appId]);
196
+ const stdout = await this.common(sshBinary(), [...this.buildSshCmdArgs(`box@${this.domain}`), `isDevshellV2 --uid ${this.uid}`, appId]);
163
197
  return stdout == 'true';
164
198
  }
165
199
 
166
200
  async resume(appId) {
167
- return this.common(sshBinary(), [...sshCmdArgs(`box@${this.domain}`), `resume --uid ${this.uid}`, appId]);
201
+ return this.common(sshBinary(), [...this.buildSshCmdArgs(`box@${this.domain}`), `resume --uid ${this.uid}`, appId]);
168
202
  }
169
203
 
170
204
  async version() {
171
- const output = await this.common(sshBinary(), [...sshCmdArgs(`box@${this.domain}`), `version`]);
205
+ const output = await this.common(sshBinary(), [...this.buildSshCmdArgs(`box@${this.domain}`), `version`]);
172
206
  logger.debug(`backend version:\n${output}`);
173
207
  try {
174
208
  const data = JSON.parse(output);
@@ -179,7 +213,7 @@ export class DebugBridge {
179
213
  }
180
214
 
181
215
  async uninstall(appId, deleteAppData = false) {
182
- return this.common(sshBinary(), [...sshCmdArgs(`box@${this.domain}`), `uninstall --uid ${this.uid}`, deleteAppData ? '--delete-data' : '', appId]);
216
+ return this.common(sshBinary(), [...this.buildSshCmdArgs(`box@${this.domain}`), `uninstall --uid ${this.uid}`, deleteAppData ? '--delete-data' : '', appId]);
183
217
  }
184
218
 
185
219
  async devshell(appId, isUserApp, onconnect = null) {
@@ -199,7 +233,16 @@ export class DebugBridge {
199
233
 
200
234
  const stream = spawn(
201
235
  sshBinary(),
202
- [...sshCmdArgs(`box@${resolvedIp}`), '-t', 'devshell', `--uid ${this.uid}`, isUserApp ? '--userapp' : '', appId, '/bin/sh', '/lzcapp/pkg/content/devshell/exec.sh'],
236
+ [
237
+ ...this.buildSshCmdArgs(`box@${resolvedIp}`),
238
+ '-t',
239
+ 'devshell',
240
+ `--uid ${this.uid}`,
241
+ isUserApp ? '--userapp' : '',
242
+ appId,
243
+ '/bin/sh',
244
+ '/lzcapp/pkg/content/devshell/exec.sh',
245
+ ],
203
246
  {
204
247
  shell: true,
205
248
  stdio: 'inherit',
@@ -224,7 +267,7 @@ export class DebugBridge {
224
267
  const resolvedIp = await resolveDomain(this.domain);
225
268
  const stream = fs.createReadStream(contextTar);
226
269
 
227
- const buildStream = spawn(sshBinary(), [...sshCmdArgs(`box@${resolvedIp}`), `build --tag ${tag}`], {
270
+ const buildStream = spawn(sshBinary(), [...this.buildSshCmdArgs(`box@${resolvedIp}`), `build --tag ${tag}`], {
228
271
  shell: true,
229
272
  stdio: ['pipe', 'inherit', 'inherit'],
230
273
  });
@@ -244,7 +287,7 @@ export class DebugBridge {
244
287
  await this.backendVersion020();
245
288
 
246
289
  const resolvedIp = await resolveDomain(this.domain);
247
- const stream = spawn(sshBinary(), [...sshCmdArgs(`box@${resolvedIp}`), '-t', 'lzc-docker', ...argv], {
290
+ const stream = spawn(sshBinary(), [...this.buildSshCmdArgs(`box@${resolvedIp}`), '-t', 'lzc-docker', ...argv], {
248
291
  shell: true,
249
292
  stdio: 'inherit',
250
293
  });
@@ -259,7 +302,7 @@ export class DebugBridge {
259
302
  await this.backendVersion020();
260
303
 
261
304
  const resolvedIp = await resolveDomain(this.domain);
262
- const stream = spawn(sshBinary(), [...sshCmdArgs(`box@${resolvedIp}`), '-t', 'lzc-docker-compose', ...argv], {
305
+ const stream = spawn(sshBinary(), [...this.buildSshCmdArgs(`box@${resolvedIp}`), '-t', 'lzc-docker-compose', ...argv], {
263
306
  shell: true,
264
307
  stdio: 'inherit',
265
308
  });
@@ -22,6 +22,7 @@
22
22
  "lpk_cmd_devshell_args_force_desc": "force rebuild",
23
23
  "lpk_cmd_devshell_desc": "Enter the development environment of the box",
24
24
  "lpk_cmd_index_rags_apk_desc": "Whether to generate APK(y/n)",
25
+ "lpk_cmd_install_args_ssh_private_key_desc": "Specify the SSH private key path used to connect to the device (compatible alias: --ssh-key)",
25
26
  "lpk_cmd_init_desc": "Initialize Lazycat Cloud application (providing the most basic template)",
26
27
  "lpk_cmd_init_success": "Application initialization completed",
27
28
  "lpk_cmd_install_desc": "Deploy the application to the device. pkgPath can be a path, or https://, http:// request address. If not filled in, it will default to lpk in the current directory.",
@@ -158,7 +159,10 @@
158
159
  "common_start_log": "Execute command {{cmd}} {{args}}",
159
160
  "install_fail": "install failed",
160
161
  "ssh_apply_grant_not_credible_tips": "The public key of your current machine has not been added to the trust list of Microservice ({{boxname}}). Please use the Microservice administrator account to visit the following address in the browser to automatically add the public key you selected to the trust list. (All operations are only performed in your LCMD, and no data, including this development machine, will be leaked outside your LCMD)\n\n-> https://{{domain}}/auth?key={{pk}}",
161
- "ssh_apply_grant_not_exist_tips": "It is detected that your current environment has not added the ssh public key to the ‘Lazy Cat Developer Tools’. Please select the type of public key you need to add."
162
+ "ssh_apply_grant_not_exist_tips": "It is detected that your current environment has not added the ssh public key to the ‘Lazy Cat Developer Tools’. Please select the type of public key you need to add.",
163
+ "ssh_private_key_in_use_tips": "Using --ssh-private-key: {{sshPrivateKeyPath}}",
164
+ "ssh_private_key_not_exist_fail": "The specified SSH private key does not exist: {{sshPrivateKeyPath}}",
165
+ "ssh_private_key_not_file_fail": "The specified SSH private key path is not a file: {{sshPrivateKeyPath}}"
162
166
  },
163
167
  "docker": {
164
168
  "index": {
@@ -193,6 +197,7 @@
193
197
  "ask_publish_app_info_package_validate": "The application bundle identifier does not comply with the specification. It is recommended to use reverse domain name notation.",
194
198
  "ask_publish_app_info_source_prompt": "Please enter the application source (original applications are optional):",
195
199
  "ask_whether_create_lpk_continue_prompt": "It is detected that your current application has not been created in Lazycat LCMD. Do you want to use the information in the current installation package to create it? [y/n]",
200
+ "ask_whether_create_lpk_failed_tips": "Failed to create {{package}} application!",
196
201
  "ask_whether_create_lpk_fail_tips": "The application you currently want to publish has not been created in the 'Developer Center of Lazy Mao Microservice'. Please follow the steps below to create it:\n\n1. Open the browser https://developer.lazycat.cloud/manage\n2. Log in to your developer account\n3. After logging in successfully, you can view the applications in your account and manage your applications.\n4. Click 'Add' and fill in the information based on your application.\n5. After filling in, click Create\n6. After successful creation, you can publish the application through 'lzc-cli appstore publish'",
197
202
  "ask_whether_create_lpk_success_tips": "Created {{package}} application successfully!",
198
203
  "check_app_id_exist_fail_tips": "Check whether there is an error in the application. The error status code is:",
@@ -249,4 +254,4 @@
249
254
  }
250
255
  }
251
256
  }
252
- }
257
+ }
@@ -24,6 +24,7 @@
24
24
  "lpk_cmd_index_rags_apk_desc": "是否生成APK(y/n)",
25
25
  "lpk_cmd_init_desc": "初始化懒猫云应用(提供最基础的模板)",
26
26
  "lpk_cmd_init_success": "应用初始化完成",
27
+ "lpk_cmd_install_args_ssh_private_key_desc": "指定安装时用于连接设备的 SSH 私钥路径(兼容别名: --ssh-key)",
27
28
  "lpk_cmd_install_desc": "部署应用至设备, pkgPath 可以为路径,或者https://,http://请求地址, 如果不填写,将默认为当前目录下的lpk",
28
29
  "lpk_cmd_log_args_follow_desc": "持续输出",
29
30
  "lpk_cmd_log_desc": "查看某一个app的日志",
@@ -158,7 +159,10 @@
158
159
  "common_start_log": "执行命令 {{ cmd }} {{ args }}",
159
160
  "install_fail": "install 失败",
160
161
  "ssh_apply_grant_not_credible_tips": "您当前机器的公钥未添加到微服({{ boxname }})的信任列表中,请使用微服管理员账号在浏览器中访问以下地址,将您选择的公钥自动添加到信任列表中。(所有操作均只在您微服中进行,包括本开发机在内的任何数据不会泄漏到您的微服之外)\n\n-> https://{{ domain }}/auth?key={{ pk }}\n",
161
- "ssh_apply_grant_not_exist_tips": "检测到您当前的环境还没有添加 ssh 公钥到 ‘懒猫开发者工具’ 中,请选择您需要添加的公钥类型"
162
+ "ssh_apply_grant_not_exist_tips": "检测到您当前的环境还没有添加 ssh 公钥到 ‘懒猫开发者工具’ 中,请选择您需要添加的公钥类型",
163
+ "ssh_private_key_in_use_tips": "当前使用 --ssh-private-key: {{ sshPrivateKeyPath }}",
164
+ "ssh_private_key_not_exist_fail": "指定的 ssh 私钥不存在: {{ sshPrivateKeyPath }}",
165
+ "ssh_private_key_not_file_fail": "指定的 ssh 私钥路径不是文件: {{ sshPrivateKeyPath }}"
162
166
  },
163
167
  "docker": {
164
168
  "index": {
@@ -194,6 +198,7 @@
194
198
  "ask_publish_app_info_source_prompt": "请输入应用来源(原创应用可不填):",
195
199
  "ask_whether_create_lpk_continue_prompt": "检测到您当前的应用,还没有在懒猫微服中创建,是否使用当前的安装包中的信息进行创建? [y/n]",
196
200
  "ask_whether_create_lpk_fail_tips": "当前想发布的应用没有在 '懒猫微服的开发者中心' 创建,请按照以下步骤创建:\n\n1. 浏览器打开 https://developer.lazycat.cloud/manage\n2. 登录您的开发者帐号\n3. 登录成功后,您可以查看到您帐号中的应用,同时您也可以对您的应用进行管理\n4. 点击 '新增',根据您的应用信息进行填写\n5. 填写完成后,点击创建即可\n6. 创建成功后,您可以通过 'lzc-cli appstore publish' 来发布应用了\n",
201
+ "ask_whether_create_lpk_failed_tips": "创建 {{ package }} 应用失败!",
197
202
  "ask_whether_create_lpk_success_tips": "创建 {{ package }} 应用成功!",
198
203
  "check_app_id_exist_fail_tips": "检测应用是否存在出错, 错误状态码为: ",
199
204
  "pre_check_fail_tips": "不能发布一个devshell的版本,请重新使用 `lzc-cli project build` 构建",
package/package.json CHANGED
@@ -1,91 +1,91 @@
1
1
  {
2
- "name": "@lazycatcloud/lzc-cli",
3
- "version": "1.3.15",
4
- "description": "lazycat cloud developer kit",
5
- "scripts": {
6
- "release": "release-it patch",
7
- "prepublishOnly": "node check-changelog.js",
8
- "i18n:parser": "i18next-cli extract -c i18next.config.js --sync-all && prettier -w ./lib/i18n/locales"
9
- },
10
- "files": [
11
- "template",
12
- "scripts",
13
- "lib",
14
- "changelog.md"
15
- ],
16
- "engines": {
17
- "node": ">=18"
18
- },
19
- "bin": {
20
- "lzc-cli": "scripts/cli.js",
21
- "lzc-docker": "scripts/lzc-docker.js",
22
- "lzc-docker-compose": "scripts/lzc-docker-compose.js"
23
- },
24
- "type": "module",
25
- "keywords": [
26
- "lazycat cloud sdk"
27
- ],
28
- "author": "zac zeng",
29
- "license": "ISC",
30
- "dependencies": {
31
- "@balena/dockerignore": "^1.0.2",
32
- "@grpc/grpc-js": "^1.11.1",
33
- "@grpc/proto-loader": "^0.7.13",
34
- "@lazycatcloud/sdk": "^0.1.423",
35
- "adm-zip": "^0.5.16",
36
- "archiver": "^7.0.1",
37
- "axios": "^1.7.7",
38
- "chalk": "^5.3.0",
39
- "chokidar": "^3.6.0",
40
- "command-exists": "^1.2.9",
41
- "cross-spawn": "^7.0.3",
42
- "dockerfile-ast": "^0.6.1",
43
- "envsub": "^4.1.0",
44
- "fast-glob": "^3.3.2",
45
- "form-data": "^4.0.0",
46
- "i18next": "^25.7.1",
47
- "i18next-fs-backend": "^2.6.1",
48
- "ignore": "^5.3.2",
49
- "inquirer": "^10.1.8",
50
- "isbinaryfile": "^5.0.2",
51
- "js-yaml": "^4.1.0",
52
- "lodash": "^4.17.23",
53
- "lodash.debounce": "^4.0.8",
54
- "lodash.merge": "^4.6.2",
55
- "lodash.mergewith": "^4.6.2",
56
- "loglevel": "^1.9.1",
57
- "node-fetch": "^3.3.2",
58
- "semver": "^7.6.3",
59
- "tar": "^7.4.3",
60
- "yargs": "^17.7.2"
61
- },
62
- "devDependencies": {
63
- "@release-it/conventional-changelog": "^10.0.1",
64
- "@types/command-exists": "^1.2.3",
65
- "i18next-cli": "^1.32.0",
66
- "prettier": "^3.3.3",
67
- "release-it": "^19.0.4"
68
- },
69
- "release-it": {
70
- "git": {
71
- "requireCleanWorkingDir": false,
72
- "commitMessage": "chore: release v${version}",
73
- "commit": true,
74
- "tag": true,
75
- "push": false
76
- },
77
- "npm": {
78
- "publish": false
79
- },
80
- "plugins": {
81
- "@release-it/conventional-changelog": {
82
- "preset": "angular",
83
- "infile": "changelog.md"
84
- }
85
- }
86
- },
87
- "publishConfig": {
88
- "registry": "https://registry.npmjs.org",
89
- "access": "public"
90
- }
2
+ "name": "@lazycatcloud/lzc-cli",
3
+ "version": "1.3.17",
4
+ "description": "lazycat cloud developer kit",
5
+ "scripts": {
6
+ "release": "release-it patch",
7
+ "prepublishOnly": "node check-changelog.js",
8
+ "i18n:parser": "i18next-cli extract -c i18next.config.js --sync-all && prettier -w ./lib/i18n/locales"
9
+ },
10
+ "files": [
11
+ "template",
12
+ "scripts",
13
+ "lib",
14
+ "changelog.md"
15
+ ],
16
+ "engines": {
17
+ "node": ">=18"
18
+ },
19
+ "bin": {
20
+ "lzc-cli": "scripts/cli.js",
21
+ "lzc-docker": "scripts/lzc-docker.js",
22
+ "lzc-docker-compose": "scripts/lzc-docker-compose.js"
23
+ },
24
+ "type": "module",
25
+ "keywords": [
26
+ "lazycat cloud sdk"
27
+ ],
28
+ "author": "zac zeng",
29
+ "license": "ISC",
30
+ "dependencies": {
31
+ "@balena/dockerignore": "^1.0.2",
32
+ "@grpc/grpc-js": "^1.11.1",
33
+ "@grpc/proto-loader": "^0.7.13",
34
+ "@lazycatcloud/sdk": "^0.1.423",
35
+ "adm-zip": "^0.5.16",
36
+ "archiver": "^7.0.1",
37
+ "axios": "^1.7.7",
38
+ "chalk": "^5.3.0",
39
+ "chokidar": "^3.6.0",
40
+ "command-exists": "^1.2.9",
41
+ "cross-spawn": "^7.0.3",
42
+ "dockerfile-ast": "^0.6.1",
43
+ "envsub": "^4.1.0",
44
+ "fast-glob": "^3.3.2",
45
+ "form-data": "^4.0.0",
46
+ "i18next": "^25.7.1",
47
+ "i18next-fs-backend": "^2.6.1",
48
+ "ignore": "^5.3.2",
49
+ "inquirer": "^10.1.8",
50
+ "isbinaryfile": "^5.0.2",
51
+ "js-yaml": "^4.1.0",
52
+ "lodash": "^4.17.23",
53
+ "lodash.debounce": "^4.0.8",
54
+ "lodash.merge": "^4.6.2",
55
+ "lodash.mergewith": "^4.6.2",
56
+ "loglevel": "^1.9.1",
57
+ "node-fetch": "^3.3.2",
58
+ "semver": "^7.6.3",
59
+ "tar": "^7.4.3",
60
+ "yargs": "^17.7.2"
61
+ },
62
+ "devDependencies": {
63
+ "@release-it/conventional-changelog": "^10.0.1",
64
+ "@types/command-exists": "^1.2.3",
65
+ "i18next-cli": "^1.32.0",
66
+ "prettier": "^3.3.3",
67
+ "release-it": "^19.0.4"
68
+ },
69
+ "release-it": {
70
+ "git": {
71
+ "requireCleanWorkingDir": false,
72
+ "commitMessage": "chore: release v${version}",
73
+ "commit": true,
74
+ "tag": true,
75
+ "push": false
76
+ },
77
+ "npm": {
78
+ "publish": false
79
+ },
80
+ "plugins": {
81
+ "@release-it/conventional-changelog": {
82
+ "preset": "angular",
83
+ "infile": "changelog.md"
84
+ }
85
+ }
86
+ },
87
+ "publishConfig": {
88
+ "registry": "https://registry.npmjs.org",
89
+ "access": "public"
90
+ }
91
91
  }