dsh-agentone 0.5.3 → 0.5.5

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/lib/index.js CHANGED
@@ -153,8 +153,25 @@ async function ensureFreshToken(config, log) {
153
153
  return tokenRefreshInFlight;
154
154
  }
155
155
 
156
- /** web profile 固定名(dsh 控制台只跑 web profile)。 */
157
- const PLUGIN_PROFILE = 'web';
156
+ /**
157
+ * 插件管理目标 profile:普通 dsh 固定 web(控制台只跑 web profile);
158
+ * DSH Desktop 用 desktopProfiles.current(apply 时探测填充)。
159
+ */
160
+ let PLUGIN_PROFILE = 'web';
161
+ /** desktop 受管插件操作通道(desktopPnpm.runPlugin),非 desktop 为 null。 */
162
+ let desktopPluginCli = null;
163
+
164
+ function pluginProfileDir(config) {
165
+ return join(resolveDshHome(config), 'profiles', PLUGIN_PROFILE);
166
+ }
167
+
168
+ /** 转发 dsh plugin 子命令:desktop 走受管 pnpm,普通 dsh 走官方 CLI。 */
169
+ async function runPluginCli(args) {
170
+ if (desktopPluginCli) {
171
+ return desktopPluginCli(args);
172
+ }
173
+ return dshPluginCli(args, PLUGIN_PROFILE);
174
+ }
158
175
 
159
176
  /**
160
177
  * npm 包名白名单(scoped 与非 scoped)。用户输入会进入 CLI 参数,必须先
@@ -164,10 +181,6 @@ const NPM_NAME_RE = /^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/;
164
181
  /** 版本白名单:语义化版本、^ ~ 前缀与 latest 标签。 */
165
182
  const VERSION_RE = /^(?:\^|~)?\d+(?:\.\d+){0,3}(?:[-+][a-z0-9._-]+)?$|^latest$/;
166
183
 
167
- function pluginProfileDir(config) {
168
- return join(resolveDshHome(config), 'profiles', PLUGIN_PROFILE);
169
- }
170
-
171
184
  /** 校验用户输入的包名/版本;非法值直接拒绝(中文报错)。 */
172
185
  function assertValidPackage(name, version) {
173
186
  if (!NPM_NAME_RE.test(name)) {
@@ -319,11 +332,11 @@ const BUILTIN_PLUGIN_ALLOW_BUILD = {
319
332
  'dsh-im': [],
320
333
  };
321
334
 
322
- /** 安装:白名单校验后转发官方 CLI(参数数组,无 shell)。 */
335
+ /** 安装:白名单校验后转发(desktop 受管 pnpm / 官方 CLI;参数数组,无 shell)。 */
323
336
  async function installProfilePlugin(config, name, version) {
324
337
  assertValidPackage(name, version);
325
338
  const target = version ? `${name}@${version}` : name;
326
- await dshPluginCli(['add', target, ...(BUILTIN_PLUGIN_ALLOW_BUILD[name] || [])]);
339
+ await runPluginCli(['add', target, ...(BUILTIN_PLUGIN_ALLOW_BUILD[name] || [])]);
327
340
  return listProfilePlugins(config);
328
341
  }
329
342
 
@@ -339,7 +352,7 @@ async function removeProfilePlugin(config, name) {
339
352
  if (name === PLUGIN_PACKAGE_NAME) {
340
353
  throw new Error('AgentOne 插件是登录与模型配置的载体,不能卸载自己');
341
354
  }
342
- await dshPluginCli(['remove', name]);
355
+ await runPluginCli(['remove', name]);
343
356
  return listProfilePlugins(config);
344
357
  }
345
358
 
@@ -352,7 +365,7 @@ async function upgradeProfilePlugin(config, name) {
352
365
  if (name === PLUGIN_PACKAGE_NAME) {
353
366
  throw new Error('AgentOne 插件随平台镜像一同升级,无需手动操作');
354
367
  }
355
- await dshPluginCli(['update', name]);
368
+ await runPluginCli(['update', name]);
356
369
  return listProfilePlugins(config);
357
370
  }
358
371
 
@@ -528,15 +541,27 @@ button{font:inherit;padding:9px 22px;border-radius:10px;border:none;cursor:point
528
541
 
529
542
  /**
530
543
  * 是否运行在 DSH Desktop 内:宿主进程是 Electron(execPath 指向 DSH Desktop
531
- * 可执行文件)。Desktop webserver 只信 Electron 内部请求,外部浏览器回调
532
- * 必须走一次性本地服务,与页面侧的自检(page.js/client.js)互为兜底。
544
+ * 可执行文件)。与页面侧标记(page.js desktop:true)互为兜底——iframe
545
+ * location.search 不含宿主 query,页面自检在设置 iframe 场景会漏。
533
546
  */
534
547
  function isDesktopHost() {
535
- return /DSH Desktop\.app/i.test(process.execPath);
548
+ return /DSH Desktop\.(?:app|exe)/i.test(process.execPath);
536
549
  }
537
550
 
538
551
  export function apply(ctx, config) {
539
552
  const log = ctx.logger || console;
553
+ // Desktop 环境探测(官方契约,见 harness-one DESKTOP.md):desktopProfiles
554
+ // 只在 DSH Desktop 存在。据此把插件管理切到当前 profile,并用受管
555
+ // desktopPnpm 做装/卸/升级(desktop 里 dsh CLI 拒绝操作 desktop profile)。
556
+ const desktopProfiles = ctx.get?.('desktopProfiles');
557
+ const isDesktopRuntime = Boolean(desktopProfiles?.current?.name) || isDesktopHost();
558
+ if (desktopProfiles?.current?.name) {
559
+ PLUGIN_PROFILE = desktopProfiles.current.name;
560
+ ctx.inject(['desktopPnpm'], (desktopCtx) => {
561
+ desktopPluginCli = (args) => desktopCtx.desktopPnpm.runPlugin(args);
562
+ log.info(`[dsh-agentone] desktop profile: ${PLUGIN_PROFILE}`);
563
+ });
564
+ }
540
565
  ctx.effect(() => {
541
566
  const register = (path, handler) => ctx.webServer.register({ kind: 'exact', path, handler });
542
567
 
@@ -619,7 +644,7 @@ export function apply(ctx, config) {
619
644
  // DSH Desktop:宿主 webserver 只信 Electron 内部请求,外部浏览器访问
620
645
  // /agentone/callback 会 403。desktop 环境(服务端自检 execPath 或页面
621
646
  // 传 desktop 标记)改由插件在本进程起一次性本地服务收回调。
622
- const callbackUrl = body.desktop || isDesktopHost()
647
+ const callbackUrl = body.desktop || isDesktopRuntime
623
648
  ? await openCallbackServer(config, log)
624
649
  : String(body.callback_url || '');
625
650
  if (!/^https?:\/\/|^\/portal\//.test(callbackUrl)) {
@@ -802,7 +827,7 @@ export function apply(ctx, config) {
802
827
  try {
803
828
  const [state, outdatedStdout] = await Promise.all([
804
829
  listProfilePlugins(config),
805
- pnpmCli(['outdated', '--format', 'list'], 60000)
830
+ pnpmCli(['outdated', '--format', 'list'], 60000, pluginProfileDir(config))
806
831
  .then((r) => r.stdout)
807
832
  .catch(() => ''),
808
833
  ]);
package/lib/proc.js CHANGED
@@ -25,12 +25,13 @@ function firstErrorLines(raw) {
25
25
  * async 函数;execFile 不经过 shell,参数数组中的每个元素都是独立参数,
26
26
  * 不存在拼接解释执行。
27
27
  */
28
- export async function runCliTool(tool, args, { timeoutMs = 300000 } = {}) {
28
+ export async function runCliTool(tool, args, { timeoutMs = 300000, cwd } = {}) {
29
29
  try {
30
30
  const { stdout, stderr } = await execFileAsync(tool, args, {
31
31
  timeout: timeoutMs,
32
32
  killSignal: 'SIGKILL',
33
33
  env: process.env,
34
+ cwd,
34
35
  });
35
36
  return { stdout, stderr };
36
37
  } catch (error) {
@@ -45,14 +46,14 @@ export async function runCliTool(tool, args, { timeoutMs = 300000 } = {}) {
45
46
  }
46
47
  }
47
48
 
48
- /** dsh plugin 子命令:转发给官方 CLI */
49
- export function dshPluginCli(args) {
50
- return runCliTool('dsh', ['plugin', '--profile', 'web', ...args]);
49
+ /** dsh plugin 子命令:转发给官方 CLI(profile 由调用方给出)。 */
50
+ export function dshPluginCli(args, profile = 'web') {
51
+ return runCliTool('dsh', ['plugin', '--profile', profile, ...args]);
51
52
  }
52
53
 
53
- /** pnpm 子命令(当前仅 outdated 查询)。 */
54
- export function pnpmCli(args, timeoutMs) {
55
- return runCliTool('pnpm', args, { timeoutMs });
54
+ /** pnpm 子命令(当前仅 outdated 查询);cwd 指向目标 profile 目录。 */
55
+ export function pnpmCli(args, timeoutMs, cwd) {
56
+ return runCliTool('pnpm', args, { timeoutMs, cwd });
56
57
  }
57
58
 
58
59
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-agentone",
3
- "version": "0.5.3",
3
+ "version": "0.5.5",
4
4
  "description": "AgentOne 平台集成插件:飞书登录、平台模型、SkillHub 技能、套餐申请、插件管理、lark-cli / ccpg-cli 探测(请求超时与错误码透传、令牌轮换 single-flight、凭据损坏容错、状态页 UX 增强)",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",