@hunan36/dsh-git-flow 0.4.0 → 0.4.2

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
@@ -100,7 +100,7 @@ If you would rather not install pnpm at all, the plugin itself does not need it
100
100
  - **Use Node's npm**: `cd ~/.dsh/profiles/<profile> && npm install https://github.com/hunan36/dsh-git-flow`
101
101
  - **Copy the directory**: drop the whole `dsh-git-flow` folder (including `lib/`) into `<profile>/node_modules/`, for offline or fully manual setups
102
102
 
103
- Both need one extra step: add `dsh-git-flow` to that profile's `dsh.profile.bundles` in its `package.json`, then restart `dsh web`. The plugin page and `dsh plugin add` do that for you; a manual install does not, and the package stays unloaded even though it sits in `node_modules`.
103
+ Both need one extra step: add `@hunan36/dsh-git-flow` to that profile's `dsh.profile.bundles` in its `package.json`, then restart `dsh web`. The plugin page and `dsh plugin add` do that for you; a manual install does not, and the package stays unloaded even though it sits in `node_modules`.
104
104
 
105
105
  ### Point the plugin page at npm (a machine that only has npm)
106
106
 
@@ -234,11 +234,11 @@ After editing `src/`, run **`pnpm build` and commit `lib/` along with it**, or e
234
234
  Artifact contract:
235
235
 
236
236
  - `lib/index.js`: Node ESM, imported directly by the cordis loader.
237
- - `lib/client.js`: a CJS factory wrapped as `window.__ModuleLoader__.load({ id: "dsh-git-flow", factory: (require) => … })`; `react`, `react/jsx-runtime`, and `@deepseek-ai/dsh-client-ui-primitives` stay external and come from the page's static module table.
237
+ - `lib/client.js`: a CJS factory wrapped as `window.__ModuleLoader__.load({ id: "@hunan36/dsh-git-flow", factory: (require) => … })` (the id is `package.json`'s `name`); `react`, `react/jsx-runtime`, and `@deepseek-ai/dsh-client-ui-primitives` stay external and come from the page's static module table.
238
238
 
239
239
  ## Compatibility
240
240
 
241
- Developed and verified against `@deepseek-ai/dsh@0.1.6-alpha.2`, with peer and dev dependencies pinned to it. dsh is still alpha, so contracts such as `conversation.input.left`, `ctx.webServer.register`, and `ctx.slots.inject` may drift between minor versions. After upgrading dsh, rebuild and confirm the first line of `lib/client.js` is still `window.__ModuleLoader__.load({ id: "dsh-git-flow"`.
241
+ Developed and verified against `@deepseek-ai/dsh@0.1.6-alpha.2`, with peer and dev dependencies pinned to it. dsh is still alpha, so contracts such as `conversation.input.left`, `ctx.webServer.register`, and `ctx.slots.inject` may drift between minor versions. After upgrading dsh, rebuild and confirm the first line of `lib/client.js` is still `window.__ModuleLoader__.load({ id: "@hunan36/dsh-git-flow"`.
242
242
 
243
243
  ## Known limits
244
244
 
@@ -251,4 +251,4 @@ Developed and verified against `@deepseek-ai/dsh@0.1.6-alpha.2`, with peer and d
251
251
 
252
252
  ## Verification (0.1.6-alpha.2)
253
253
 
254
- Measured on an isolated `DSH_HOME` with profile `gitflow-web` (`dsh-git-flow` appended to `dsh.profile.bundles`): the chip text equals `git branch --show-current`; the menu lists every local branch plus each remote-only one; search filters rows; switching moves both the chip and the worktree files; a dirty switch is refused and only confirms `--force` after a second dialog; an invalid branch name errors while a valid one is created and switched to; with a single file checked, the model returned a `feat: …` message and `git log -1 --name-only` showed only that file; commit-and-push made the branch appear in `git ls-remote` with its upstream set; a session whose workspace is not a repository renders no chip; the `headless` profile boots with no warning and no routes.
254
+ Measured on an isolated `DSH_HOME` with profile `gitflow-web` (`@hunan36/dsh-git-flow` appended to `dsh.profile.bundles`): the chip text equals `git branch --show-current`; the menu lists every local branch plus each remote-only one; search filters rows; switching moves both the chip and the worktree files; a dirty switch is refused and only confirms `--force` after a second dialog; an invalid branch name errors while a valid one is created and switched to; with a single file checked, the model returned a `feat: …` message and `git log -1 --name-only` showed only that file; commit-and-push made the branch appear in `git ls-remote` with its upstream set; a session whose workspace is not a repository renders no chip; the `headless` profile boots with no warning and no routes.
package/README.zh.md CHANGED
@@ -99,7 +99,7 @@ npm install -g pnpm # 装最新的 10.x
99
99
  - **用 Node 自带的 npm**:`cd ~/.dsh/profiles/<profile> && npm install https://github.com/hunan36/dsh-git-flow`
100
100
  - **直接拷贝**:把整个 `dsh-git-flow` 目录(含 `lib/`)拷进 `<profile>/node_modules/`,适用于离线或纯手工环境
101
101
 
102
- 这两种方式都必须**再补一步**:把 `dsh-git-flow` 加进该 profile `package.json` 的 `dsh.profile.bundles`,然后重启 `dsh web` —— 插件页和 `dsh plugin add` 会自动做这一步,手工装则要自己写,否则包在 `node_modules` 里也不会被加载。
102
+ 这两种方式都必须**再补一步**:把 `@hunan36/dsh-git-flow` 加进该 profile `package.json` 的 `dsh.profile.bundles`,然后重启 `dsh web` —— 插件页和 `dsh plugin add` 会自动做这一步,手工装则要自己写,否则包在 `node_modules` 里也不会被加载。
103
103
 
104
104
  ### 让插件页改用 npm(机器上只有 npm)
105
105
 
@@ -236,14 +236,14 @@ pnpm build # tsc -> lib/types/**,tsdown -> lib/index.js + lib/client.js
236
236
  产物契约:
237
237
 
238
238
  - `lib/index.js`:Node ESM,被 cordis loader 直接 import。
239
- - `lib/client.js`:CJS 工厂包成 `window.__ModuleLoader__.load({ id: "dsh-git-flow", factory: (require) => … })`;
239
+ - `lib/client.js`:CJS 工厂包成 `window.__ModuleLoader__.load({ id: "@hunan36/dsh-git-flow", factory: (require) => … })`(id 取 `package.json` 的 `name`);
240
240
  `react`、`react/jsx-runtime`、`@deepseek-ai/dsh-client-ui-primitives` 保持 external,由页面静态模块表提供。
241
241
 
242
242
  ## 兼容性
243
243
 
244
244
  针对 `@deepseek-ai/dsh@0.1.6-alpha.2` 实测开发,peer/devDependencies 锁在该版本。dsh 尚在 alpha,
245
245
  `conversation.input.left`、`ctx.webServer.register`、`ctx.slots.inject` 等契约可能在小版本间漂移;
246
- 升级 dsh 后请重跑构建并确认 `lib/client.js` 首行仍是 `window.__ModuleLoader__.load({ id: "dsh-git-flow"`。
246
+ 升级 dsh 后请重跑构建并确认 `lib/client.js` 首行仍是 `window.__ModuleLoader__.load({ id: "@hunan36/dsh-git-flow"`。
247
247
 
248
248
  ## 已知边界
249
249
 
@@ -256,7 +256,7 @@ pnpm build # tsc -> lib/types/**,tsdown -> lib/index.js + lib/client.js
256
256
 
257
257
  ## 验证记录(0.1.6-alpha.2)
258
258
 
259
- 独立 `DSH_HOME` + profile `gitflow-web`(bundles 追加 `dsh-git-flow`)实测:胶囊文本 == `git branch --show-current`;
259
+ 独立 `DSH_HOME` + profile `gitflow-web`(bundles 追加 `@hunan36/dsh-git-flow`)实测:胶囊文本 == `git branch --show-current`;
260
260
  弹层行数 == 本地分支 + 仅在远端;搜索过滤;切分支后胶囊与工作区文件同步;脏工作区切换被拦下并弹二次确认(`--force` 才丢弃改动);
261
261
  非法分支名报错、合法名创建并切换;勾选单个文件生成 AI 信息(`feat: …`)并只提交该文件(`git log -1 --name-only` 验证);
262
262
  提交并推送后 `git ls-remote` 出现该分支且建立 upstream;非 git 工作区会话里胶囊不渲染;`headless` profile 启动无警告、无路由。
package/cordis.patch.yml CHANGED
@@ -1,3 +1,3 @@
1
1
  - insert:
2
2
  - id: git-flow
3
- name: 'dsh-git-flow'
3
+ name: '@hunan36/dsh-git-flow'
package/lib/index.js CHANGED
@@ -663,14 +663,16 @@ var GitFlow = class extends Service {
663
663
  async checkout(sessionId, name, force = false) {
664
664
  const repo = await this.resolveRepo(sessionId);
665
665
  assertBranchName(name);
666
+ const target = await this.unqualifiedName(repo, name);
666
667
  const args = ["switch"];
667
668
  if (force) args.push("--force");
668
- if (await this.hasLocalBranch(repo, name)) args.push(name);
669
+ if (await this.hasLocalBranch(repo, target)) args.push(target);
669
670
  else {
670
- const remotes = await this.remoteBranches(repo, name);
671
- if (remotes.length > 1) throw new GitError("git/invalid-input", `branch ${name} exists on multiple remotes: ${remotes.join(", ")}`);
672
- if (remotes.length === 1) args.push("-c", name, "--track", remotes[0]);
673
- else args.push(name);
671
+ const remotes = await this.remoteBranches(repo, target);
672
+ const tracking = remotes.includes(name) ? name : remotes.length === 1 ? remotes[0] : void 0;
673
+ if (tracking !== void 0) args.push("-c", target, "--track", tracking);
674
+ else if (remotes.length > 1) throw new GitError("git/invalid-input", `branch ${target} exists on multiple remotes: ${remotes.join(", ")}`);
675
+ else args.push(target);
674
676
  }
675
677
  await this.runSwitch(repo, args);
676
678
  return this.status(sessionId);
@@ -1202,6 +1204,20 @@ var GitFlow = class extends Service {
1202
1204
  `refs/heads/${name}`
1203
1205
  ])).exitCode === 0;
1204
1206
  }
1207
+ /**
1208
+ * Turn a branch row's name into something `git switch` accepts. Remote-only
1209
+ * rows are labelled `<remote>/<branch>` because that is their short refname,
1210
+ * but git refuses to switch to a remote ref directly; stripping the prefix
1211
+ * lets {@link checkout} create the local tracking branch instead. Only a
1212
+ * known remote is peeled off, and only when no real local branch has that
1213
+ * exact name.
1214
+ */
1215
+ async unqualifiedName(repo, name) {
1216
+ if (await this.hasLocalBranch(repo, name)) return name;
1217
+ const slash = name.indexOf("/");
1218
+ if (slash <= 0) return name;
1219
+ return (await this.git.runOk(repo, ["remote"])).stdout.split("\n").map((line) => line.trim()).filter(Boolean).includes(name.slice(0, slash)) ? name.slice(slash + 1) : name;
1220
+ }
1205
1221
  async remoteBranches(repo, name) {
1206
1222
  return (await this.git.runOk(repo, [
1207
1223
  "for-each-ref",
@@ -173,6 +173,15 @@ export declare class GitFlow extends Service {
173
173
  */
174
174
  private changedInIndex;
175
175
  private hasLocalBranch;
176
+ /**
177
+ * Turn a branch row's name into something `git switch` accepts. Remote-only
178
+ * rows are labelled `<remote>/<branch>` because that is their short refname,
179
+ * but git refuses to switch to a remote ref directly; stripping the prefix
180
+ * lets {@link checkout} create the local tracking branch instead. Only a
181
+ * known remote is peeled off, and only when no real local branch has that
182
+ * exact name.
183
+ */
184
+ private unqualifiedName;
176
185
  private remoteBranches;
177
186
  private runSwitch;
178
187
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hunan36/dsh-git-flow",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "Workspace git branch switcher, commit composer with AI-written messages, and push for DeepSeek Harness",
5
5
  "keywords": [
6
6
  "dsh",