dsh-lark-bot 0.19.2 → 0.19.3

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/plugin.d.ts CHANGED
@@ -1321,9 +1321,11 @@ interface GuardianUpdateState {
1321
1321
  route: GuardianUpdateRoute;
1322
1322
  startedAt: string;
1323
1323
  finishedAt?: string;
1324
+ errorCode?: GuardianUpdateErrorCode;
1324
1325
  error?: string;
1325
1326
  delivered?: boolean;
1326
1327
  }
1328
+ type GuardianUpdateErrorCode = 'filesystem-access' | 'registry-unavailable' | 'bootstrap-unavailable' | 'upgrade-failed';
1327
1329
  interface GuardianUpdateHandoffOptions {
1328
1330
  file: string;
1329
1331
  packageName: string;
package/dist/plugin.js CHANGED
@@ -864,9 +864,9 @@ async function writeFileAtomic(target, data, options = {}) {
864
864
  }
865
865
  }
866
866
  async function rmSilently(path) {
867
- const { rm: rm10 } = await import("fs/promises");
867
+ const { rm: rm11 } = await import("fs/promises");
868
868
  try {
869
- await rm10(path, { force: true });
869
+ await rm11(path, { force: true });
870
870
  } catch {
871
871
  }
872
872
  }
@@ -15008,14 +15008,14 @@ function matchProfileProcess(cmdline, dshProfile) {
15008
15008
  if (/(?:^|\s)plugin(?:\s|$)/.test(cmdline)) return false;
15009
15009
  return hasProfileFlag(cmdline, dshProfile) && looksLikeDshProcess(cmdline);
15010
15010
  }
15011
- async function listProcesses() {
15012
- if (process.platform === "win32") {
15013
- return listProcessesWindows();
15011
+ async function listProcesses(platform = process.platform, run = captureOutput) {
15012
+ if (platform === "win32") {
15013
+ return listProcessesWindows(run);
15014
15014
  }
15015
- return listProcessesPosix();
15015
+ return listProcessesPosix(run);
15016
15016
  }
15017
- async function listProcessesPosix() {
15018
- const { stdout } = await captureOutput("ps", ["-axo", "pid=,args="], 1e4);
15017
+ async function listProcessesPosix(run) {
15018
+ const { stdout } = await run("ps", ["-axo", "pid=,args="], 1e4);
15019
15019
  const result = [];
15020
15020
  for (const line of stdout.split("\n")) {
15021
15021
  const match = /^\s*(\d+)\s+(.+)$/.exec(line);
@@ -15025,33 +15025,46 @@ async function listProcessesPosix() {
15025
15025
  }
15026
15026
  return result;
15027
15027
  }
15028
- async function listProcessesWindows() {
15029
- const { stdout } = await captureOutput(
15028
+ async function listProcessesWindows(run) {
15029
+ const { stdout } = await run(
15030
15030
  "powershell.exe",
15031
15031
  [
15032
15032
  "-NoProfile",
15033
15033
  "-NonInteractive",
15034
15034
  "-Command",
15035
- "Get-CimInstance Win32_Process | Select-Object ProcessId, CommandLine | ConvertTo-Csv -NoTypeInformation"
15035
+ "Get-CimInstance Win32_Process | Select-Object ProcessId, CommandLine | ConvertTo-Json -Compress"
15036
15036
  ],
15037
15037
  1e4
15038
15038
  );
15039
- const result = [];
15040
- for (const line of stdout.split("\n").slice(1)) {
15041
- const [pid, ...rest] = line.trim().split(",");
15042
- const numeric = Number(pid?.replace(/"/g, ""));
15043
- if (Number.isInteger(numeric) && rest.length > 0) {
15044
- result.push({ pid: numeric, cmdline: rest.join(",").replace(/^"|"$/g, "") });
15045
- }
15039
+ try {
15040
+ const parsed = JSON.parse(stdout);
15041
+ const rows = Array.isArray(parsed) ? parsed : [parsed];
15042
+ return rows.flatMap((row) => {
15043
+ if (typeof row !== "object" || row === null) return [];
15044
+ const record = row;
15045
+ const pid = Number(record.ProcessId);
15046
+ const cmdline = record.CommandLine;
15047
+ return Number.isInteger(pid) && pid > 0 && typeof cmdline === "string" ? [{ pid, cmdline }] : [];
15048
+ });
15049
+ } catch {
15050
+ return [];
15046
15051
  }
15047
- return result;
15048
15052
  }
15049
- async function captureOutput(command, args, timeoutMs = 3e4) {
15053
+ async function captureOutput(command, args, timeoutMs = 3e4, options = {}) {
15050
15054
  return new Promise((resolve6) => {
15051
- const child = spawn5(command, [...args], {
15052
- stdio: ["ignore", "pipe", "pipe"],
15053
- windowsHide: true
15054
- });
15055
+ const previousUmask = options.umask !== void 0 && process.platform !== "win32" ? process.umask(options.umask) : void 0;
15056
+ const child = (() => {
15057
+ try {
15058
+ return spawn5(command, [...args], {
15059
+ stdio: ["ignore", "pipe", "pipe"],
15060
+ windowsHide: true,
15061
+ ...options.cwd ? { cwd: options.cwd } : {},
15062
+ ...options.env ? { env: options.env } : {}
15063
+ });
15064
+ } finally {
15065
+ if (previousUmask !== void 0) process.umask(previousUmask);
15066
+ }
15067
+ })();
15055
15068
  let stdout = "";
15056
15069
  let stderr = "";
15057
15070
  child.stdout?.on("data", (chunk) => {
@@ -16374,11 +16387,35 @@ function buildSecretHandler(deps) {
16374
16387
  init_own_package();
16375
16388
 
16376
16389
  // src/guardian/update-handoff.ts
16377
- import { randomUUID as randomUUID13 } from "crypto";
16390
+ import { createHash as createHash3, randomUUID as randomUUID13 } from "crypto";
16378
16391
  import { spawn as spawn7 } from "child_process";
16379
- import { mkdir as mkdir20, readFile as readFile28 } from "fs/promises";
16392
+ import { chmod, mkdir as mkdir20, readFile as readFile28, rm as rm10 } from "fs/promises";
16380
16393
  import { dirname as dirname15, join as join23 } from "path";
16381
16394
  init_own_package();
16395
+ function guardianUpdateFailureHint(code) {
16396
+ switch (code) {
16397
+ case "filesystem-access":
16398
+ return {
16399
+ zh: "\u66F4\u65B0\u5DE5\u4F5C\u76EE\u5F55\u4E0D\u53EF\u8BBF\u95EE\uFF1B\u8BF7\u53D1\u9001 `/doctor` \u68C0\u67E5\u6587\u4EF6\u6743\u9650\u540E\u91CD\u8BD5\u3002",
16400
+ en: "The private update workspace is inaccessible. Send `/doctor` to check file permissions, then retry."
16401
+ };
16402
+ case "registry-unavailable":
16403
+ return {
16404
+ zh: "\u65E0\u6CD5\u8FDE\u63A5 npm \u6B63\u5F0F\u6E90\uFF1B\u8BF7\u68C0\u67E5\u7F51\u7EDC\u540E\u91CD\u8BD5\u3002",
16405
+ en: "The npm registry is unreachable. Check the network, then retry."
16406
+ };
16407
+ case "bootstrap-unavailable":
16408
+ return {
16409
+ zh: "\u65E0\u6CD5\u542F\u52A8 npm/npx\uFF1B\u8BF7\u53D1\u9001 `/doctor` \u68C0\u67E5 Node.js \u4E0E npm\u3002",
16410
+ en: "npm/npx could not start. Send `/doctor` to check Node.js and npm."
16411
+ };
16412
+ default:
16413
+ return {
16414
+ zh: "\u5347\u7EA7\u547D\u4EE4\u672A\u5B8C\u6210\uFF1B\u8BF7\u53D1\u9001 `/doctor` \u68C0\u67E5\u540E\u91CD\u8BD5\u3002",
16415
+ en: "The upgrade command did not complete. Send `/doctor`, then retry."
16416
+ };
16417
+ }
16418
+ }
16382
16419
  async function loadState(file) {
16383
16420
  try {
16384
16421
  const parsed = JSON.parse(await readFile28(file, "utf8"));
@@ -17171,12 +17208,13 @@ async function startBridgeEngine(options) {
17171
17208
  const deliverUpdateResult = async () => {
17172
17209
  await updateHandoff.deliverResult(async (state) => {
17173
17210
  if (!streaming) throw new Error("channel is not ready");
17211
+ const failureHint = guardianUpdateFailureHint(state.errorCode);
17174
17212
  const markdown2 = state.status === "succeeded" ? bilingualMarkdown(
17175
17213
  `\u2705 dsh-lark-bot \u5DF2\u66F4\u65B0\u5230 \`${state.targetVersion}\`\uFF0C\u673A\u5668\u4EBA\u5DF2\u5B8C\u6210\u91CD\u8F7D\u3002`,
17176
17214
  `\u2705 dsh-lark-bot was updated to \`${state.targetVersion}\` and reloaded.`
17177
17215
  ) : bilingualMarkdown(
17178
- `\u26A0\uFE0F dsh-lark-bot \u66F4\u65B0\u5230 \`${state.targetVersion}\` \u5931\u8D25\u3002\u8BF7\u91CD\u65B0\u53D1\u9001 \`/upgrade\`\uFF1B\u5982\u4ECD\u5931\u8D25\uFF0C\u53D1\u9001 \`/doctor\` \u68C0\u67E5\u3002`,
17179
- `\u26A0\uFE0F Failed to update dsh-lark-bot to \`${state.targetVersion}\`. Send \`/upgrade\` to retry, or \`/doctor\` if it still fails.`
17216
+ `\u26A0\uFE0F dsh-lark-bot \u66F4\u65B0\u5230 \`${state.targetVersion}\` \u5931\u8D25\u3002${failureHint.zh}`,
17217
+ `\u26A0\uFE0F Failed to update dsh-lark-bot to \`${state.targetVersion}\`. ${failureHint.en}`
17180
17218
  );
17181
17219
  await streaming.sendMarkdown(state.route.chatId, markdown2, {
17182
17220
  ...state.route.threadId ? { threadId: state.route.threadId } : {}