dsh-open-in-ide 0.0.0-stage → 0.3.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 harrithy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,252 @@
1
- # Temporary Holding Version
1
+ # dsh-open-in-ide
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ **English** | [中文](README.zh.md)
4
+
5
+ Open file references from the [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)
6
+ chat in your IDE — **Visual Studio Code by default**, or any detected VS Code
7
+ family / JetBrains IDE — positioned at the referenced line, instead of the in-app
8
+ document preview.
9
+
10
+ A DeepSeek Harness plugin (bundle + browser half). Tested with DeepSeek Harness
11
+ `0.2.1-rc.2` (Desktop / Web profile).
12
+
13
+ Supported editors, detected on the machine hosting the Harness:
14
+
15
+ * **VS Code family** (`--goto <path>:<line>:<column>`): Visual Studio Code,
16
+ VS Code Insiders, Cursor, Windsurf.
17
+ * **JetBrains family** (`--line <line> <path>`): IntelliJ IDEA, PyCharm, WebStorm,
18
+ GoLand, CLion, PhpStorm, Rider, RubyMine, DataGrip, RustRover.
19
+
20
+ ## Where to find it
21
+
22
+ After installing the bundle, reload the Harness page once.
23
+
24
+ ### 1. Enable it — Settings → Plugins → Installed plugins (已安装插件)
25
+
26
+ ![The plugin listed on the Plugins page](docs/plugins-installed.png)
27
+
28
+ The bundle appears as **“Open File Links in Your IDE”** (Chinese UI:
29
+ “在 IDE 中打开文件链接”) with its on/off switch.
30
+
31
+ ### 2. Choose your IDE — Settings → General → “IDE for file links” (打开文件的 IDE)
32
+
33
+ ![The IDE selector in General settings](docs/settings-general.png)
34
+
35
+ The row lists only the IDEs detected on the machine hosting the Harness;
36
+ **Visual Studio Code is the default**, and the first detected IDE is used when
37
+ VS Code is not installed.
38
+
39
+ ## Features
40
+
41
+ * **Plain click** on a file-reference chip in an assistant message opens that
42
+ file in the selected IDE at the referenced line.
43
+ * **The file's project opens with it.** For the VS Code family the host finds the
44
+ nearest project root (`.git`/`.hg`, else `package.json`, `Cargo.toml`,
45
+ `pom.xml`, …) and passes it as a folder argument, so VS Code opens or reuses
46
+ the **project window** instead of dropping a loose file into the most recently
47
+ used window. A file without any project marker opens as before.
48
+ * After opening, the editor window is **brought to the foreground** (and restored
49
+ if it was minimized). Windows uses a small Win32 helper to defeat the
50
+ background-process foreground lock; macOS activates via `osascript`; Linux
51
+ tries `wmctrl`/`xdotool`.
52
+ * **Two editor families**: VS Code / VS Code Insiders / Cursor / Windsurf are
53
+ launched with `--goto`; JetBrains IDEs (IntelliJ IDEA, PyCharm, WebStorm,
54
+ GoLand, CLion, PhpStorm, Rider, RubyMine, DataGrip, RustRover) with
55
+ `--line <line> <path>`. The browser only names an editor id from a fixed set.
56
+ * **Settings → General → “IDE for file links”** lists only the IDEs the host can
57
+ actually launch, detected by scanning known install locations and `PATH` on
58
+ every request. The default is Visual Studio Code; when it is not installed the
59
+ first detected IDE is used, and a saved choice that is no longer installed is
60
+ reconciled the same way.
61
+ * Clicking a **directory** reference opens it as a workspace folder.
62
+ * **Alt / Shift / Ctrl + click** keeps the shipped in-app preview.
63
+ * A toast names the target and the IDE, including failures (missing file,
64
+ uninstalled editor, launch error).
65
+ * No build step, no dependencies, no telemetry. The browser half ships as the
66
+ package's `./client` export; the host half only uses Node built-ins.
67
+
68
+ ## Requirements
69
+
70
+ * A DeepSeek Harness Web GUI (Desktop or a `web` profile). The host composition
71
+ must provide `webServer`, `connection`, `subprocess`, `fs`, and `sessions`;
72
+ the desktop and web profiles do.
73
+ * At least one supported IDE:
74
+ * **VS Code family**: Visual Studio Code, VS Code Insiders, Cursor, Windsurf.
75
+ * **JetBrains family**: IntelliJ IDEA, PyCharm, WebStorm, GoLand, CLion,
76
+ PhpStorm, Rider, RubyMine, DataGrip, RustRover.
77
+ * Compatibility note: the browser half keys off the shipped chat's
78
+ file-reference chip markup (`_fileMention_*` buttons with the authored path in
79
+ `title`). A future Harness UI change may need an update here; pin or report
80
+ the Harness version when filing an issue.
81
+
82
+ ## Install
83
+
84
+ The plugin is a standard DSH bundle, installed through the Plugin Manager
85
+ (Settings → Plugins) or the `plugin_manager` tool. A local directory install
86
+ links the checkout, so later edits apply live.
87
+
88
+ 1. Clone the repository:
89
+
90
+ ```bash
91
+ git clone https://github.com/harrithy/dsh-open-in-ide.git
92
+ ```
93
+
94
+ 2. Install the bundle from that directory. In the Harness, either use
95
+ **Settings → Plugins → install**, or ask the agent to run the
96
+ `plugin_manager` tool with `action: install_bundle` and this absolute
97
+ directory as `target`. A `link:` install from the profile's package manager
98
+ works too:
99
+
100
+ ```bash
101
+ dsh plugin --profile <profile> add link:/path/to/dsh-open-in-ide
102
+ ```
103
+
104
+ 3. **Reload the Harness page** (`F5`). The bundle `dsh-open-in-ide` and row
105
+ `open-in-ide` appear in Plugin Manager, and a new row appears in
106
+ Settings → General (see [Where to find it](#where-to-find-it)).
107
+
108
+ ## Auto update
109
+
110
+ When the plugin is installed from a **git checkout** (a `link:` install, as
111
+ described above), it can update itself while Harness keeps running:
112
+
113
+ * The page checks the configured repository once per load (`updateCheck`,
114
+ default on), and the **Settings → General → “Plugin updates”** row has a
115
+ check button at any time.
116
+ * When the remote has new commits the row shows the new version and an
117
+ **Update** button. Updating runs `git pull --ff-only` in the checkout and then
118
+ asks HMR to reload the plugin in place — no Harness restart.
119
+ * The updater only trusts the configured `updateRepository` origin. It refuses
120
+ a dirty working tree, a foreign origin, and non-fast-forward histories.
121
+ * Installs that are not git checkouts (tarball, registry copy) are reported as
122
+ such; update those through the Plugin Manager.
123
+
124
+ This needs `git` on `PATH` and network access to the repository.
125
+
126
+ ## Usage
127
+
128
+ * Click a file reference such as `src/app.ts:42` in an answer. The file opens in
129
+ the selected IDE at line 42.
130
+ * Choose the IDE in **Settings → General → “IDE for file links”**. The row lists
131
+ the IDEs detected on the machine hosting the Harness.
132
+ * The choice is stored in the browser (`localStorage`, key
133
+ `dsh.open-in-ide.editor`); the legacy key of the plugin's former name is read
134
+ once for migration.
135
+ * Line/column come from a `:42` / `:42:7` suffix in the chip label. The harness
136
+ exposes only the path as a DOM attribute, so the label is the line channel.
137
+ Absolute and workspace-relative paths are both accepted; relative paths
138
+ resolve against the Session's workspace directory on the host.
139
+ * The column (when present) is only forwarded to VS Code-family launchers;
140
+ JetBrains launchers receive the line only.
141
+ * Directories open as workspace folders.
142
+
143
+ ## Configuration
144
+
145
+ The row config lives in `cordis.patch.yml`; override it in the profile's own
146
+ `cordis.patch.yml` to tune behavior (the user patch layer survives plugin
147
+ updates):
148
+
149
+ ```yaml
150
+ - id: open-in-ide
151
+ config:
152
+ command: 'C:\Users\me\AppData\Local\Programs\Microsoft VS Code\bin\code.cmd'
153
+ reuseWindow: true
154
+ ```
155
+
156
+ | Field | Default | Meaning |
157
+ |---|---|---|
158
+ | `command` | `''` | Explicit editor CLI: a bare PATH name (`code`) or an absolute path (`...\bin\code.cmd`). When set it wins over the Settings selector; empty keeps the selector authoritative. |
159
+ | `commandKind` | `vscode` | Launcher contract used for a configured `command`: `vscode` (`--goto`) or `jetbrains` (`--line`). Ignored while `command` is empty. |
160
+ | `editor` | `vscode` | Fallback IDE when a request carries no selection: any supported id, e.g. `vscode`, `cursor`, `idea`, `pycharm`, `webstorm`. |
161
+ | `reuseWindow` | `false` | Add `--reuse-window` so the file opens in the most recent window (VS Code family only). VS Code already routes files into a window that has the containing folder open. |
162
+ | `openProjectFolder` | `true` | Pass the file's project root as a folder argument so VS Code opens or reuses the project window (VS Code family only). Set `false` to let VS Code decide. |
163
+ | `projectMarkers` | built-in list | Override the project-root markers: file or directory names without separators, e.g. `['.git', 'package.json', 'Cargo.toml']`. |
164
+ | `focusWindow` | `true` | Bring the editor window to the foreground after opening it (restore if minimized). Disable to let the OS decide. |
165
+ | `focusDelayMs` | `350` | Delay before the first foreground attempt; when a cold-started editor has no window yet the plugin retries a few times. |
166
+ | `updateCheck` | `true` | Check the repository for a newer version once per page load. The settings row's check button works regardless. |
167
+ | `updateRepository` | this GitHub URL | Repository the updater is allowed to pull from; a different origin is refused. |
168
+ | `updateDirectory` | plugin directory | Checkout directory to update (defaults to the directory this plugin was loaded from). |
169
+ | `extraArgs` | `[]` | Extra arguments placed before the target arguments, e.g. `["-n"]`. |
170
+ | `launchWatchMs` | `2000` | Early-failure watch window for the detached launcher; a launcher still running when it closes counts as launched. |
171
+
172
+ ## Detection and launch resolution
173
+
174
+ The host serves two routes, both fenced by the composition's connection trust
175
+ checks (Host/Origin fence plus browser authentication):
176
+
177
+ * `GET /open-in-ide/editors` — probes each supported editor id on every request
178
+ (cheap existence checks plus in-process `PATH` lookups) and answers which ones
179
+ this host can launch.
180
+ * `POST /open-in-ide/open` — validates `{ sessionId, path, line, column,
181
+ editor }`, resolves the path in the Session's workspace, then launches the
182
+ selected editor detached with the family's contract and a credential-scrubbed
183
+ environment.
184
+
185
+ Detection order:
186
+
187
+ * **Windows**:
188
+ * VS Code family: known install roots under `%LOCALAPPDATA%` / `%ProgramFiles%`,
189
+ then the IDE's CLI name on `PATH`. A machine where Cursor registered itself
190
+ as `code` still resolves the `vscode` id to the real VS Code install,
191
+ because known roots are tried before `PATH`.
192
+ * JetBrains: Toolbox launcher scripts
193
+ (`%LOCALAPPDATA%\JetBrains\Toolbox\scripts\<cli>.cmd`), Toolbox apps
194
+ (`…\Toolbox\apps\<app>\ch-<n>\<version>\bin\<exe>`), standalone installs
195
+ (`%ProgramFiles%\JetBrains\<Product 2024.x>\bin\<exe>`), then the CLI name
196
+ on `PATH`.
197
+ * **macOS**: VS Code family uses the `.app` bundle's
198
+ `Contents/Resources/app/bin/<cli>`; JetBrains uses
199
+ `<App>.app/Contents/MacOS/<cli>`. Both fall back to `PATH`.
200
+ * **Linux**: known install paths (`/opt/...`, `/usr/bin/...`, snap paths) and the
201
+ JetBrains Toolbox scripts directory under `~/.local/share/JetBrains`, then
202
+ `PATH`.
203
+
204
+ The browser never sends a command line: it names an editor id from a fixed set,
205
+ and the host resolves it to an executable it verified.
206
+
207
+ ## Limits
208
+
209
+ * Only the shipped Markdown file-reference chips are redirected. Tool-call card
210
+ file names, delivered-file cards, and the document preview keep their own
211
+ openers.
212
+ * Supported editors and their launcher contracts: VS Code family
213
+ (`--goto <path>:<line>:<col>`) and the JetBrains family
214
+ (`--line <line> <path>`). A custom `command` must accept the contract named by
215
+ `commandKind`.
216
+ * Detection covers the editor ids listed above. A portable build not on `PATH`,
217
+ or an editor outside those families, needs `command`.
218
+ * The column (when present) is only forwarded to the VS Code family; JetBrains
219
+ launchers receive the line only.
220
+ * Window raising is best-effort: Windows uses a Win32 helper (an unusual
221
+ foreground policy or security tool can still refuse the change), while macOS
222
+ and Linux depend on `osascript` / `wmctrl` / `xdotool` being available.
223
+ * Project-folder injection is heuristic and VS Code-family only: it walks up to
224
+ the nearest `.git`/`.hg` or manifest marker. JetBrains IDEs keep their own
225
+ project management and receive only the file/line; no folder is passed.
226
+ * Self-update only works for git checkouts whose origin matches
227
+ `updateRepository`, and requires `git` plus network access. Local uncommitted
228
+ changes block it on purpose; commit or stash them first.
229
+ * Line/column come from the visible chip label; when a link's label does not
230
+ repeat the line, the file opens without a line target.
231
+ * The editor choice is per browser (`localStorage`); another browser or origin
232
+ keeps its own choice.
233
+
234
+ ## Development
235
+
236
+ ```text
237
+ index.js Host half: detection + open routes, launch logic
238
+ client.js Browser half: settings row, click bridge, toasts
239
+ cordis.patch.yml Bundle row declaration + defaults
240
+ locale/{en,zh}.json Plugin Manager title/description
241
+ icon.svg Plugin artwork
242
+ docs/ Screenshots used by this README
243
+ ```
244
+
245
+ There is no build step: `index.js` is loaded by the Loader, `client.js` is served
246
+ to the browser as the package's `./client` export. A local directory install is
247
+ linked into the profile, so editing either file takes effect through HMR (client
248
+ immediately; host after the plugin row reloads).
249
+
250
+ ## License
251
+
252
+ MIT — see [LICENSE](LICENSE).
package/README.zh.md ADDED
@@ -0,0 +1,219 @@
1
+ # dsh-open-in-ide
2
+
3
+ [English](README.md) | **中文**
4
+
5
+ 点击 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 对话中
6
+ 回答里的文件引用,用你选择的 IDE(**默认 Visual Studio Code**,也支持 VS Code
7
+ 家族与 JetBrains 系列)打开对应文件并定位到引用的行,替代内置的文档预览。
8
+
9
+ 一个 DeepSeek Harness 插件(bundle + 浏览器半)。已在 DeepSeek Harness
10
+ `0.2.1-rc.2`(桌面版 / Web profile)上测试。
11
+
12
+ 支持的编辑器(在宿主机器上自动检测):
13
+
14
+ * **VS Code 家族**(`--goto <path>:<line>:<column>`):Visual Studio Code、
15
+ VS Code Insiders、Cursor、Windsurf。
16
+ * **JetBrains 家族**(`--line <line> <path>`):IntelliJ IDEA、PyCharm、
17
+ WebStorm、GoLand、CLion、PhpStorm、Rider、RubyMine、DataGrip、RustRover。
18
+
19
+ ## 在界面中的位置
20
+
21
+ 安装 bundle 后,刷新一次 Harness 页面。
22
+
23
+ ### 1. 启用插件 —— 设置 → 插件 → 已安装插件
24
+
25
+ ![插件管理页中的插件](docs/plugins-installed.png)
26
+
27
+ 插件在已安装列表中显示为 **「在 IDE 中打开文件链接」**,右侧开关用于启用/停用。
28
+
29
+ ### 2. 选择 IDE —— 设置 → 通用设置 →「打开文件的 IDE」
30
+
31
+ ![通用设置中的 IDE 选择器](docs/settings-general.png)
32
+
33
+ 下拉只列出本机检测到的 IDE;**默认 Visual Studio Code**,未安装 VS Code 时使用
34
+ 扫描到的第一个。已保存的选择如果后来被卸载,也会自动回退到 VS Code 或第一个
35
+ 检测到的 IDE。
36
+
37
+ ## 功能
38
+
39
+ * **单击**回答中的文件引用 chip,用所选 IDE 打开对应文件并定位到引用的行。
40
+ * **连同项目一起打开**:VS Code 家族会沿路径向上找项目根(`.git`/`.hg`,否则
41
+ `package.json`、`Cargo.toml`、`pom.xml` 等标记),把项目目录作为文件夹参数传
42
+ 给 CLI,于是 VS Code 会**打开或复用项目窗口**,而不是把文件变成散落标签塞进最近
43
+ 使用的窗口。没有任何项目标记的文件仍按原方式打开。
44
+ * 打开后会把 IDE 窗口**提到最前**(窗口最小化时先恢复)。Windows 通过一个小型
45
+ Win32 助手绕过“后台进程无前台权限”的限制;macOS 用 `osascript` 激活应用;
46
+ Linux 尝试 `wmctrl` / `xdotool`。
47
+ * **两个编辑器家族**:VS Code / Insiders / Cursor / Windsurf 用 `--goto` 启动;
48
+ JetBrains(IntelliJ IDEA、PyCharm、WebStorm、GoLand、CLion、PhpStorm、Rider、
49
+ RubyMine、DataGrip、RustRover)用 `--line <行> <路径>` 启动。浏览器只发送固定
50
+ 集合里的编辑器 id。
51
+ * **设置 → 通用设置 →「打开文件的 IDE」**只列出宿主真正能启动的 IDE(每次请求
52
+ 都会扫描已知安装位置和 `PATH`)。默认 VS Code;没有 VS Code 则用扫描到的第一
53
+ 个;已保存的选择失效时同样自动回退。
54
+ * 点击**目录**引用会在 IDE 中打开该文件夹。
55
+ * **Alt / Shift / Ctrl + 单击**保留内置预览(侧栏文档预览)。
56
+ * 顶部 toast 提示目标与 IDE,失败时给出原因(文件不存在、IDE 未安装、启动失败)。
57
+ * 无构建步骤、无依赖、无遥测。浏览器半以包的 `./client` 导出提供,宿主半只使用
58
+ Node 内置模块。
59
+
60
+ ## 环境要求
61
+
62
+ * 一个 DeepSeek Harness Web GUI(桌面版或 `web` profile)。宿主组合需要提供
63
+ `webServer`、`connection`、`subprocess`、`fs`、`sessions` 服务;桌面版与 web
64
+ profile 都满足。
65
+ * 至少安装一款受支持的 IDE:
66
+ * **VS Code 家族**:Visual Studio Code、VS Code Insiders、Cursor、Windsurf。
67
+ * **JetBrains 家族**:IntelliJ IDEA、PyCharm、WebStorm、GoLand、CLion、
68
+ PhpStorm、Rider、RubyMine、DataGrip、RustRover。
69
+ * 兼容性说明:浏览器半依赖当前聊天 UI 的文件引用 chip 结构(`_fileMention_*`
70
+ 按钮,作者路径在 `title` 属性里)。Harness 未来的 UI 改动可能需要适配;提
71
+ issue 时请附上 Harness 版本。
72
+
73
+ ## 安装
74
+
75
+ 本插件是标准 DSH bundle,通过 Plugin Manager(设置 → 插件)或 `plugin_manager`
76
+ 工具安装。本地目录安装会把源码目录链接进 profile,改代码即时生效。
77
+
78
+ 1. 克隆仓库:
79
+
80
+ ```bash
81
+ git clone https://github.com/harrithy/dsh-open-in-ide.git
82
+ ```
83
+
84
+ 2. 从这个目录安装 bundle。可在 Harness 中打开 **设置 → 插件 → 安装**,或让
85
+ agent 用 `plugin_manager` 工具执行 `action: install_bundle`,`target` 填这个
86
+ 目录的绝对路径。也可以用 profile 的包管理器做 `link:` 安装:
87
+
88
+ ```bash
89
+ dsh plugin --profile <profile> add link:/path/to/dsh-open-in-ide
90
+ ```
91
+
92
+ 3. **刷新 Harness 页面**(F5)。Plugin Manager 中会出现 bundle `dsh-open-in-ide`
93
+ 和行 `open-in-ide`,通用设置里会出现新的一行(见[在界面中的位置](#在界面中的位置))。
94
+
95
+ ## 自动更新
96
+
97
+ 当插件是从 **git checkout**(`link:` 安装,见上面的安装步骤)安装时,可以在 Harness
98
+ 运行期间自行更新:
99
+
100
+ * 页面每次加载会检查一次配置的仓库(`updateCheck`,默认开启);**设置 → 通用设置
101
+ →「插件更新」** 一行也可以随时手动检查。
102
+ * 远端有新提交时,该行会显示新版本和「更新」按钮。更新会在 checkout 里执行
103
+ `git pull --ff-only`,然后通过 HMR 就地重载插件,**不需要重启 Harness**。
104
+ * 更新器只信任配置的 `updateRepository` origin;本地有未提交改动、origin 不匹配、
105
+ 或无法快进的历史都会被拒绝。
106
+ * 非 git checkout(tarball、包管理器安装)会如实提示,请通过插件管理器更新。
107
+
108
+ 需要 `PATH` 上有 `git`,并且能访问该仓库。
109
+
110
+ ## 使用
111
+
112
+ * 点击回答里的文件引用(如 `src/app.ts:42`),文件会在所选 IDE 中打开并定位到
113
+ 第 42 行。
114
+ * 在 **设置 → 通用设置 →「打开文件的 IDE」** 中选择 IDE;下拉只列出宿主检测到
115
+ 的 IDE。
116
+ * 选择保存在浏览器(`localStorage`,键 `dsh.open-in-ide.editor`);插件改名前的
117
+ 旧键会被读取一次以完成迁移。
118
+ * 行号/列号取自 chip 文字末尾的 `:42` / `:42:7`。Harness 只把路径暴露在 DOM 的
119
+ `title` 属性中,所以链接文字是行号的通道。绝对路径和相对工作区的路径都支持,
120
+ 相对路径由宿主按 Session 的工作目录解析。
121
+ * 列号只会传给 VS Code 家族启动器;JetBrains 启动器只接收行号。
122
+ * 目录引用会作为工作区文件夹打开。
123
+
124
+ ## 配置
125
+
126
+ 行配置在 `cordis.patch.yml` 中;在 profile 自己的 `cordis.patch.yml` 里覆盖即可
127
+ (用户 patch 层在插件升级后仍保留):
128
+
129
+ ```yaml
130
+ - id: open-in-ide
131
+ config:
132
+ command: 'C:\Users\me\AppData\Local\Programs\Microsoft VS Code\bin\code.cmd'
133
+ reuseWindow: true
134
+ ```
135
+
136
+ | 字段 | 默认 | 含义 |
137
+ |---|---|---|
138
+ | `command` | `''` | 显式指定编辑器 CLI:PATH 名(`code`)或绝对路径(`...\bin\code.cmd`)。设置后优先于设置页选择;留空则设置页选择生效。 |
139
+ | `commandKind` | `vscode` | 配置了 `command` 时使用的启动约定:`vscode`(`--goto`)或 `jetbrains`(`--line`)。`command` 为空时忽略。 |
140
+ | `editor` | `vscode` | 请求未携带选择时的回退 IDE:任意受支持的 id,如 `vscode`、`cursor`、`idea`、`pycharm`、`webstorm`。 |
141
+ | `reuseWindow` | `false` | 追加 `--reuse-window`,在最近窗口打开(仅 VS Code 家族)。VS Code 本身会把文件路由到已打开该目录的窗口。 |
142
+ | `openProjectFolder` | `true` | 把文件所属项目根作为文件夹参数传入,让 VS Code 打开/复用项目窗口(仅 VS Code 家族)。设为 false 交给 VS Code 决定。 |
143
+ | `projectMarkers` | 内置列表 | 覆盖项目根标记:不带路径分隔符的文件/目录名,例如 `['.git', 'package.json', 'Cargo.toml']`。 |
144
+ | `focusWindow` | `true` | 打开后把 IDE 窗口提到最前(最小化时先恢复)。设为 false 则交给系统决定。 |
145
+ | `focusDelayMs` | `350` | 首次置前尝试的延迟;冷启动的编辑器窗口还没出现时会自动重试几次。 |
146
+ | `updateCheck` | `true` | 每次页面加载检查一次仓库新版本;设置行里的检查按钮不受此开关影响。 |
147
+ | `updateRepository` | 本仓库 GitHub 地址 | 更新器允许 pull 的仓库;origin 不同会被拒绝。 |
148
+ | `updateDirectory` | 插件所在目录 | 要更新的 checkout 目录(默认就是加载本插件的目录)。 |
149
+ | `extraArgs` | `[]` | 放在目标参数之前的额外参数,例如 `["-n"]`。 |
150
+ | `launchWatchMs` | `2000` | 分离启动器的早期失败观察窗口;窗口结束时仍在运行的启动器视为启动成功。 |
151
+
152
+ ## 检测与启动解析
153
+
154
+ 宿主提供两个路由,均先经过组合的 connection 信任检查(Host/Origin 防跨站 + 浏览器
155
+ 认证):
156
+
157
+ * `GET /open-in-ide/editors` —— 每次请求都探测支持的编辑器 id(路径存在性检查 +
158
+ 进程内 `PATH` 解析),返回本机能启动哪些。
159
+ * `POST /open-in-ide/open` —— 校验 `{ sessionId, path, line, column, editor }`,
160
+ 按 Session 工作目录解析路径,然后按家族约定分离启动所选编辑器,子进程使用凭据
161
+ 清理后的环境。
162
+
163
+ 检测顺序:
164
+
165
+ * **Windows**:
166
+ * VS Code 家族:`%LOCALAPPDATA%` / `%ProgramFiles%` 下的已知安装目录,然后是
167
+ `PATH` 上的 CLI 名。即使 Cursor 把 `code` 注册成自己的命令,`vscode` id 仍会
168
+ 解析到真正的 VS Code 安装,因为已知目录先于 `PATH` 尝试。
169
+ * JetBrains:Toolbox 启动脚本
170
+ (`%LOCALAPPDATA%\JetBrains\Toolbox\scripts\<cli>.cmd`)、Toolbox 应用目录
171
+ (`…\Toolbox\apps\<app>\ch-<n>\<version>\bin\<exe>`)、独立安装
172
+ (`%ProgramFiles%\JetBrains\<Product 2024.x>\bin\<exe>`),最后是 `PATH`
173
+ 上的 CLI 名。
174
+ * **macOS**:VS Code 家族用 `.app` 内的
175
+ `Contents/Resources/app/bin/<cli>`;JetBrains 用 `<App>.app/Contents/MacOS/<cli>`;
176
+ 两者都回退到 `PATH`。
177
+ * **Linux**:常见安装路径(`/opt/...`、`/usr/bin/...`、snap 路径)和
178
+ `~/.local/share/JetBrains` 下的 Toolbox 脚本目录,最后是 `PATH`。
179
+
180
+ 浏览器从不发送命令行:它只发送固定集合里的编辑器 id,宿主把它解析为自己验证过的
181
+ 可执行文件。
182
+
183
+ ## 限制
184
+
185
+ * 只重定向内置 Markdown 文件引用 chip。工具调用卡片里的文件名、交付文件卡片和
186
+ 文档预览保持各自的打开方式。
187
+ * 支持的编辑器与启动约定:VS Code 家族(`--goto <path>:<line>:<col>`)与
188
+ JetBrains 家族(`--line <行> <路径>`)。自定义 `command` 必须接受
189
+ `commandKind` 指定的约定。
190
+ * 检测覆盖上面列出的编辑器 id;不在 `PATH` 上的便携版或列表之外的编辑器需要
191
+ `command`。
192
+ * 列号只会传给 VS Code 家族;JetBrains 启动器只接收行号。
193
+ * 置前是尽力而为:Windows 通过 Win32 助手实现(极特殊的前台策略或安全软件仍可能
194
+ 拒绝),macOS/Linux 依赖 `osascript` / `wmctrl` / `xdotool` 是否可用。
195
+ * 项目文件夹注入是启发式且仅用于 VS Code 家族:向上找最近的 `.git`/`.hg` 或
196
+ manifest 标记。JetBrains 保持自己的项目管理,只接收文件/行号,不传文件夹。
197
+ * 自动更新仅适用于 origin 与 `updateRepository` 一致的 git checkout,且需要
198
+ `git` 和网络;本地有未提交改动时会故意拒绝,先提交或暂存。
199
+ * 行号/列号来自可见的 chip 文字;链接文字没有行号时只打开文件、不定位。
200
+ * 编辑器选择按浏览器保存(`localStorage`);不同浏览器或 origin 各自独立。
201
+
202
+ ## 开发
203
+
204
+ ```text
205
+ index.js 宿主半:检测 + 打开路由、启动逻辑
206
+ client.js 浏览器半:设置行、点击桥、toast
207
+ cordis.patch.yml bundle 行声明 + 默认配置
208
+ locale/{en,zh}.json Plugin Manager 标题/描述
209
+ icon.svg 插件图标
210
+ docs/ 本 README 使用的截图
211
+ ```
212
+
213
+ 没有构建步骤:`index.js` 由 Loader 加载,`client.js` 作为包的 `./client` 导出
214
+ 提供给浏览器。本地目录安装会链接进 profile,因此修改文件可通过 HMR 生效(浏览器
215
+ 半立即生效;宿主半在插件行重载后生效)。
216
+
217
+ ## 许可证
218
+
219
+ MIT,见 [LICENSE](LICENSE)。