dsh-codebuddy-llm 0.1.0 → 0.1.1

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/README.md CHANGED
@@ -35,7 +35,7 @@ This is an unofficial, third-party plugin. Its author is the only party behind i
35
35
  ## Tips
36
36
 
37
37
  - **Prove the CLI first, without the harness.** `codebuddy --print --output-format stream-json "hello"` should print one JSON line per event. A plugin that registers but answers nothing usually means the CLI is not signed in, not on the `PATH` of the process that launched the harness, or does not support the flags in `args`.
38
- - **Prefer an absolute `command`** when the harness runs from a GUI, a daemon, or a service manager: those often inherit a smaller `PATH` than your shell.
38
+ - **Prefer an absolute `command`** when the harness runs from a GUI, a daemon, or a service manager: those often inherit a smaller `PATH` than your shell. A missing CLI is reported rather than hidden — the Models page refuses with `CodeBuddy CLI is unavailable: codebuddy is not on this process's PATH (N directories searched)`, and the same text is logged at load.
39
39
  - **Narrow the default permission mode** for repositories you did not write. `default`, `acceptEdits`, or `plan` keeps the CLI's tools from acting on their own; `bypassPermissions` does not.
40
40
  - **Try `transport: acp`** when the CLI supports `--acp`: one child per route instead of one per call, the CLI's thinking arrives as its own block, and a conversation resumes its CLI-side session. Fall back to `print` for a CLI without ACP.
41
41
  - **Keep the entry id `llm-cli`.** That id is the settings namespace, so the documented `llm-cli:` section and any existing profile settings keep working after install.
@@ -118,7 +118,7 @@ Model ids come from the CLI itself: an `acp` route asks the handshake (which als
118
118
  - Only the final answer crosses the boundary: the CLI's internal tool steps stay invisible to the harness session log.
119
119
  - `permissionMode` governs the CLI's tools, and harness permission presets, the filesystem sandbox, and the shell sandbox do not mediate them. The default `bypassPermissions` therefore grants the child the desktop process's OS access — narrow it when that is not intended.
120
120
  - Only CodeBuddy-shaped output is understood: both the `stream-json` vocabulary and the positional-prompt invocation are CodeBuddy's.
121
- - A missing executable yields no discovered models; the route still mounts and serves its configured catalog.
121
+ - A missing or unreachable executable is reported as a refusal naming the configured command, instead of an empty catalog; the route still mounts, and still serves a `models` list you configured yourself. Model calls then fail the same way, so fix the `command` before relying on the route.
122
122
  - Compaction and a model switch need a context capacity: the CLI must report one, or the catalog entry must declare `contextWindow`.
123
123
 
124
124
  ## Provenance
package/README.zh.md CHANGED
@@ -35,7 +35,7 @@ description: "委托式 CLI LLM 适配器:每次模型调用都交给 CodeBudd
35
35
  ## 使用提示
36
36
 
37
37
  - **先用 CLI 自证,再装插件。** 直接跑 `codebuddy --print --output-format stream-json "hello"`,应能看到一行一个事件的 JSON。若插件挂上了却答不出内容,通常意味着 CLI 未登录、不在启动 harness 那个进程的 `PATH` 上,或不支持 `args` 里的参数。
38
- - **`command` 尽量写绝对路径。** 从 GUI、守护进程或服务管理器启动 harness 时,继承到的 `PATH` 往往比你的 shell 小。
38
+ - **`command` 尽量写绝对路径。** 从 GUI、守护进程或服务管理器启动 harness 时,继承到的 `PATH` 往往比你的 shell 小。CLI 缺失不会被静默吞掉:Models 页会以 `CodeBuddy CLI is unavailable: codebuddy is not on this process's PATH (N directories searched)` 拒绝,装载时也会打印同样的内容。
39
39
  - **对不是自己写的仓库,先调窄权限。** `default`、`acceptEdits` 或 `plan` 会阻止 CLI 的工具自行行动;`bypassPermissions` 不会。
40
40
  - **CLI 支持 `--acp` 时优先试 `transport: acp`。** 每条路由只起一个子进程而非每次调用一个,CLI 的思考过程会作为独立块返回,对话也能续用 CLI 侧会话;不支持 ACP 的 CLI 仍用 `print`。
41
41
  - **保留 entry id `llm-cli`。** 这个 id 就是设置命名空间,改掉它会让文档里的 `llm-cli:` 配置段和已有 profile 设置失效。
@@ -118,7 +118,7 @@ dsh plugin --profile work add dsh-codebuddy-llm
118
118
  - 只有最终答案越过边界:CLI 内部的工具步骤对 harness 会话日志不可见。
119
119
  - `permissionMode` 管的是 CLI 的工具;harness 的权限预设、文件系统沙箱和 shell 沙箱都不介入。因此默认的 `bypassPermissions` 等于把桌面进程的 OS 权限交给子进程——不希望如此时请调窄。
120
120
  - 只理解 CodeBuddy 形状的输出:`stream-json` 词汇和位置参数式调用都是 CodeBuddy 的约定。
121
- - 可执行文件缺失时发现不到模型;路由仍会挂载并提供已配置的目录。
121
+ - 可执行文件缺失或不可执行时,会以拒绝的形式报出所配置的命令,而不是返回空目录;路由仍会挂载,你自己在 `models` 里配置的列表也照常可用。此时模型调用同样会失败,请先修好 `command` 再依赖该路由。
122
122
  - 压缩与模型切换需要上下文容量:要么 CLI 报出该值,要么目录条目声明 `contextWindow`。
123
123
 
124
124
  ## 来源
package/index.js CHANGED
@@ -1,7 +1,37 @@
1
1
  import { LlmAdapter } from "@deepseek-ai/dsh-llm";
2
2
  import z from "@deepseek-ai/schemastery";
3
+ import { accessSync, constants } from "node:fs";
4
+ import { delimiter, join } from "node:path";
3
5
  /** Largest delay a Node timer accepts; inlined so this file needs no dsh-timeout package. */
4
6
  const MAX_TIMER_DELAY_MS = 2_147_483_647;
7
+ /**
8
+ * Report why the configured executable cannot be run, or undefined when it can.
9
+ *
10
+ * A host launched from a desktop shell inherits launchd's PATH rather than the
11
+ * one a login shell assembles, so an installed CLI is routinely unreachable
12
+ * under the bare name `codebuddy`. Discovery would otherwise report an empty
13
+ * catalog, which reads as "this route serves no models" instead of "the CLI is
14
+ * not installed or not on this process's PATH".
15
+ * @param command - configured executable, either a bare name or a path.
16
+ * @param env - extra environment entries the child receives over the seam's base.
17
+ * @returns an actionable diagnostic, or undefined when the executable resolves.
18
+ */
19
+ function executableProblem(command, env) {
20
+ const runs = (candidate) => {
21
+ try {
22
+ accessSync(candidate, constants.X_OK);
23
+ return true;
24
+ } catch {
25
+ return false;
26
+ }
27
+ };
28
+ if (command.length === 0) return "the configured command is empty";
29
+ if (command.includes("/")) return runs(command) ? undefined : `${command} is missing or not executable`;
30
+ const path = env.PATH ?? process.env.PATH ?? "";
31
+ const searched = path.split(delimiter).filter((dir) => dir.length > 0);
32
+ for (const dir of searched) if (runs(join(dir, command))) return undefined;
33
+ return `${command} is not on this process's PATH (${searched.length === 0 ? "PATH is empty" : `${searched.length} directories searched`})`;
34
+ }
5
35
  //#region lib/types/acp.js
6
36
  /**
7
37
  * ACP transport: one long-lived CLI child that carries every delegated run of a
@@ -1624,6 +1654,11 @@ function apply(ctx, config) {
1624
1654
  const probeCatalog = async (signal) => {
1625
1655
  const current = plainOptions(config);
1626
1656
  const facts = resolveAdapterOptions(current, process.cwd());
1657
+ // A missing CLI is a deployment fault, not an empty catalog: throwing here
1658
+ // reaches the Models page as a refusal carrying this text, while the load
1659
+ // probe logs it, so neither surface shows a silent zero-model route.
1660
+ const problem = executableProblem(facts.argv[0], facts.env);
1661
+ if (problem !== void 0) throw new Error(`CodeBuddy CLI is unavailable: ${problem}. Install the CodeBuddy CLI, or point \`command\` in this plugin's \`llm-cli\` config at its absolute path.`);
1627
1662
  const models = await discoverCliModels({
1628
1663
  argv: facts.discoveryArgv,
1629
1664
  cwd: facts.cwd,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-codebuddy-llm",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Delegating CLI LLM adapter for the DeepSeek Harness: answers each model call by running the CodeBuddy CLI child that carries its own sign-in and agent loop, so a deployment runs without an API key",
5
5
  "author": "saisaiwang <287442583@qq.com>",
6
6
  "repository": {