Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
15e421f
chore(Config): 新增 .gitignore,忽略本地 .mcp.json 配置;
ThreeFish-AI Jun 27, 2026
84c740e
docs(AGENTS): 新增协作协议文档 AGENTS.md 及 CLAUDE.md 软链;
ThreeFish-AI Jun 27, 2026
5ad6715
docs(Agents): 新增知识索引、Issue 记录、引用规范与浏览器验证协议文档;
ThreeFish-AI Jun 27, 2026
f56f848
feat(M0): 初始化工程脚手架、CI 流水线与源码分层骨架
ThreeFish-AI Jun 27, 2026
a935597
docs(Research): 持久化全链路调研报告与工程方案
ThreeFish-AI Jun 27, 2026
fcec204
feat(M1): Git Adapter + 多 changelist Changes 树视图
ThreeFish-AI Jun 27, 2026
7e2c552
feat(M2): Commit 提交窗口 + CommitPipeline + AI 接缝
ThreeFish-AI Jun 27, 2026
9cfc31f
fix(Review): M0/M1/M2 审查修复(正确性 + 测试补齐)
ThreeFish-AI Jun 27, 2026
2a68293
feat(M3): Log/Branches/Blame + Show History
ThreeFish-AI Jun 27, 2026
d2c17d6
feat(M4): Stash 视图与操作(stash-backed Shelf MVP)
ThreeFish-AI Jun 27, 2026
cac355a
docs+fix+release: M0-M5 文档沉淀 + M0-M4 审查补缺口 + v0.0.1-rc.1 发布准备
ThreeFish-AI Jun 27, 2026
142fb47
feat(Parity-Batch1): git CLI 通道补齐 cherry-pick/revert/reset/rename/sta…
ThreeFish-AI Jun 27, 2026
ffc0d47
feat(Parity-Batch2): Git 提交图 Webview + Console
ThreeFish-AI Jun 27, 2026
9ec8b9e
feat(Parity-Batch3): partial/hunk 级提交 + undo/drop/fixup + cleanup + 3…
ThreeFish-AI Jun 27, 2026
75d41da
feat(Inline-Commit): editor 行内提交 CodeLens(#13)
ThreeFish-AI Jun 27, 2026
d4bce6c
feat(Parity-Batch4): 忠实 Shelf + 交互式 Rebase UI + Move Hunk to Changelist
ThreeFish-AI Jun 27, 2026
cb5e501
chore(Release): v0.0.1-rc.2 发布
ThreeFish-AI Jun 28, 2026
018cb70
feat(Parity): 复刻 IDEA Git 工具窗口全量功能(Branches/Log/Graph/Merge/Rebase); …
ThreeFish-AI Jun 29, 2026
3cc2018
chore(Release): v0.0.1-rc.3 发布 + GitHub Release 附带可本地安装的 .vsix (#16)
ThreeFish-AI Jun 29, 2026
e131c15
fix(GitToolWindow): 修复活动栏未提交角标缺失与 Branches Push 失败 (#17)
ThreeFish-AI Jun 29, 2026
62ae4b6
chore(Release): v0.0.1-rc.4 发布;
ThreeFish-AI Jun 29, 2026
9554bb3
feat(Worktree): 新增 Worktree 视图与完整工作树操作功能; (#18)
ThreeFish-AI Jun 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
458 changes: 458 additions & 0 deletions .agents/browser-validation.md

Large diffs are not rendered by default.

65 changes: 65 additions & 0 deletions .agents/issue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Issues 摘要

> 用于跨上下文留存问题处理经验,避免重复踩坑。新条目追加在末尾,同 Issue 只维护一处。
>
> 每条摘要包含:**表因 / 根因 / 处理方式 / 后续防范 / 同类问题影响**。

---

## #1 JSDoc 块注释中的 `*/` 提前闭合注释

- **表因**:`pnpm run check-types` 在 `src/engine/model/index.ts` 报大量 `TS1127 Invalid character` / `TS1109 Expression expected`,指向一段纯中文注释行。
- **根因**:注释文本「`INDEX_*/工作区/冲突`」中的 `*/` 序列被 TypeScript 解析为块注释终止符,导致其后中文文本暴露为代码,触发语法错误。
- **处理方式**:改写注释,移除 `*/` 序列(`INDEX_*/工作区` → `INDEX 系列、工作区`)。
- **后续防范**:在任何 `/* ... */` 块注释内引用含 `*/` 的内容(如 `gitDecoration.*`、正则 `*/`、glob)时,必须转义或改写;可用 `grep -rn '\*/' src/ | grep -vE '\*/\s*$'` 扫描提前闭合。
- **同类问题影响**:所有含中文技术注释的 TS 文件,尤以注释内出现路径/枚举/正则片段时高发。

## #2 pnpm 11 构建脚本审批与配置迁移

- **表因**:`pnpm install` 输出 `[ERR_PNPM_IGNORED_BUILDS] Ignored build scripts: esbuild, @vscode/vsce-sign, keytar`,导致 esbuild 原生二进制未安装,后续构建可能失败;且 `package.json` 的 `pnpm.onlyBuiltDependencies` 字段被忽略并告警。
- **根因**:pnpm 10/11 出于供应链安全默认拦截依赖 postinstall;同时 pnpm 11.9 将 `onlyBuiltDependencies` 等设置**移出 package.json**,新位置为 `pnpm-workspace.yaml`(本版本使用 `allowBuilds:` 审批格式,由 pnpm 自动生成脚手架)。
- **处理方式**:删除 package.json 的 `pnpm` 字段;在 `pnpm-workspace.yaml` 写入 `allowBuilds: { esbuild: true, '@vscode/vsce-sign': true, keytar: true }` 后重新 `pnpm install`,三个 postinstall 正常执行。
- **后续防范**:pnpm 项目一律在 `pnpm-workspace.yaml` 管理构建脚本审批;新增含原生二进制的依赖时,需在此文件追加放行;CI 首次 `pnpm install` 后确认无 `ERR_PNPM_IGNORED_BUILDS`。
- **同类问题影响**:所有 pnpm 11 工程;凡依赖 esbuild / keytar / @vscode/vsce-sign / prebuild-install 类原生模块的扩展。

## #3 pnpm 11.9 要求 Node ≥ 22.13(CI 用 Node 20 崩溃)

- **表因**:CI `Lint & Build` job 10s 内失败,日志 `Error [ERR_UNKNOWN_BUILTIN_MODULE]: No such built-in module: node:sqlite`,并告警 `This version of pnpm requires at least Node.js v22.13`。本地不暴露(本地用 Node 24)。
- **根因**:pnpm 11.9 内部使用 Node 22.13+ 才有的 `node:sqlite` 内置模块;CI 工作流配置 `node-version: 20`,pnpm 启动即崩。
- **处理方式**:CI 所有 job 的 `setup-node` 由 `node-version: 20` 升至 `node-version: 22`。
- **后续防范**:pnpm ≥ 11 工程的 Node 基线须 ≥ 22.13;`engines.node`/CI/本地三者对齐(建议 22 LTS 或 24);升级 pnpm 前查其 Node 版本要求(https://r.pnpm.io/comp)。
- **同类问题影响**:所有 pnpm 11+ 的 CI/本地环境;node:sqlite 依赖的其他工具链。

## #4 CI 集成测试 job 缺失扩展构建步骤

- **表因**:CI `Test` job 集成测试报 `Activating extension 'threefish-ai.hyper-git' failed: Cannot find module '.../dist/extension.js'`;本地却通过。
- **根因**:`test` job 仅跑 `test:unit` + `test:integration`,未执行 `node esbuild.js` 构建 `dist/extension.js`;test-electron 启动真实 VS Code 加载扩展(`main: ./dist/extension.js`)时找不到入口。本地因先前 `pnpm run package` 残留 dist/ 而误判通过。
- **处理方式**:`test` job 在 `pnpm install` 后、测试前增加 `node esbuild.js`(或 `pnpm run compile`)构建 dist/。
- **后续防范**:凡含 `@vscode/test-electron` 集成测试的 CI job,必须在测试前显式构建扩展产物;本地验证集成测试后清理 dist/ 以暴露该依赖;`.gitignore` 排除 dist/ 时注意 CI 需重建。
- **同类问题影响**:所有 VS Code 扩展的 test-electron CI job;本地"能跑"但 CI 失败的构建产物缺失类问题。

## #5 ESLint flat config 遍历 .vscode-test 导致 OOM

- **表因**:本地 `pnpm run lint` 在 ~70s 后 `FATAL ERROR: ... JavaScript heap out of memory`(4GB 耗尽);M0 时却正常。
- **根因**:`@vscode/test-electron` 首次运行将完整 VS Code(约 260MB、海量 JS)下载到 `.vscode-test/`;ESLint 9 flat config 默认仅忽略 `node_modules`,**不忽略 `.vscode-test/`**,于是 eslint 遍历其下成千上万 JS 文件导致 OOM。M0 lint 通过是因为当时 `.vscode-test/` 尚未生成。
- **处理方式**:在 `eslint.config.mjs` 的 `ignores` 增加 `.vscode-test/**`。
- **后续防范**:含 test-electron 的扩展,eslint ignores 必须含 `.vscode-test/**`(及 `out/**`、`dist/**`、`*.vsix`);CI 因不缓存该目录可能不暴露,但本地必现——本地与 CI 环境差异需警惕。
- **同类问题影响**:所有跑过 test-electron 的本地环境的 eslint/其他静态分析工具。

## #6 vscode.git 公开 API add() 须传绝对路径

- **表因**:调用 `Repository.add(['README.md'])`(相对路径)无效或误加文件;CommitService 初期也曾困惑路径语义。
- **根因**:`extensions/git/src/api/api1.ts` 的 `add(paths)` 实现为 `paths.map(p => Uri.file(p))`——`Uri.file()` 要求**绝对路径**;相对路径会被包装成畸形 Uri,内部 `path.relative(root, ...)` 计算错误。`revert`/`clean`/`restore` 同理。
- **处理方式**:CommitService 始终传 `ChangeItem.uri.fsPath`(绝对)。
- **后续防范**:消费 vscode.git 公开 API 的路径类方法(add/revert/clean/restore)一律传绝对 fsPath;已加集成测试 `tests/suite/commit-flow.test.js` 守护。
- **同类问题影响**:所有消费 vscode.git API 做 stage/revert 的扩展;git CLI 本身接受相对路径,但**公开 API 层不接受**,二者语义差异易踩。

## #7 GitHub Release 缺少可本地安装的 `.vsix` 资产

- **表因**:README 指引「从 Releases 下载 `.vsix` → `Extensions: Install from VSIX`」,但 rc.1/rc.2 的 GitHub Release 页面无任何 `.vsix` 资产,用户无法手动安装。
- **根因**:`ci.yml` 的 `package` job 只把 `.vsix` 当作 **Actions artifact**(90 天即逝、非公开下载)上传,`publish` job 仅将其发往 VS Code Marketplace / OpenVSX;**全流程无任何 step 创建 GitHub Release 或向其上传资产**(rc.1/rc.2 的 Release 实为手工 `gh release create`,本就不含 `.vsix`)。
- **处理方式**:新增独立 `github-release` job(`softprops/action-gh-release@v2`),`needs: package` 复用 vsix artifact,对 `v*` tag 自动建 Release 并 `files: '*.vsix'` 上传;`*rc*` 自动 `prerelease`;`fail_on_unmatched_files: true` 防空资产。
- **后续防范**:该 job 与市场 `publish` **解耦**(不 `needs: publish`、不挂 `environment: production`),保证「Release 带 `.vsix`」不被市场审批门/密钥缺失阻塞;「仅出 Release、暂不发市场」时不审批 production 即可,无需改 publish job;最小权限仅本 job 提权 `contents: write`。
- **同类问题影响**:所有「CI 只上传 artifact + 发市场、却在 README 承诺 Release 手动下载」的 VS Code 扩展;artifact ≠ Release 资产,二者可见性/留存期差异易被忽视。


34 changes: 34 additions & 0 deletions .agents/knowledge-map.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Knowledge Map(知识索引)

> 项目内文档与关键能力索引;按主题正交分组,链接为相对路径以便跨上下文跳转。
> 新增/变更文档时应即时同步本表。

## 工程协议与基线
- [AGENTS.md](../AGENTS.md) — 协作协议与工程行为准则(熵减心法 / 架构原则 / 执行规范)。
- [README.md](../README.md) — Hyper Git 项目说明、架构(路径 B)与 M0-M5 路线图。
- [CHANGELOG.md](../CHANGELOG.md) — 版本变更记录(Keep a Changelog 格式)。
- [LICENSE](../LICENSE) — MIT。

## Agents 知识库(本目录)
- [Issue 记录](./issue.md) — 跨上下文问题处理经验(表因 / 根因 / 处理 / 防范)。
- [引用规范 IEEE](./reference-specifications.md) — 文献引用格式与上标锚定。
- [浏览器验证协议](./browser-validation.md) — OAuth/SSO 红线与 E2E 验证协议。

## 项目文档(docs/)
- [文档中心](../docs/README.md) — 文档与调研资产总索引。
- [实施状态总览](../docs/milestones/implementation-status.md) — M0-M5 交付记录 + API 限制 + M5 AI 设计 + 验证/发布(**实施看板**)。
- [工程实施方案](../docs/architecture/engineering-plan.md) — 路径 B 架构 + M0-M5 里程碑(**开发蓝图**)。
- [IDEA 功能复刻矩阵](../docs/requirements/idea-feature-matrix.md) — 56 功能点 / 8 组(**验收基线**)。
- [调研报告](../docs/research/README.md) — SCM 集成 / 工程蓝图 / 发布 CI / AI 接缝四路循证报告。

## 架构分层(src/)
> 依赖方向单向:`UI → Adapter → Engine`;`Agent` 以接口注入 `Engine`/`CommitPipeline`,不反向依赖 UI。

- `engine/` — 纯领域逻辑(零 vscode 依赖,Vitest 可测):`model/`、`scm-mapping/`、`commit/pipeline.ts`、`diff/`(M4)。
- `adapter/` — 唯一接触 vscode API:`GitRepositoryAdapter`、`ChangelistRegistry`、`tree/`、`webview/`、`diff/`、`storage/`(M1+)。
- `agent/` — AI 接缝(M5 实现):`ILlmProvider`、`IPreCommitInspector`、`IChangelistGrouper`、`IConflictResolver`、`IChatToolRegistrar`。
- `shared/protocol.ts` — Webview ↔ Host 消息契约【单一事实源】。
- `infra/` — 日志(OutputChannel)/ 错误处理 / 事件总线 / 配置。

## 里程碑
M0 脚手架 + CI ✅ → M1 Git Adapter + Changes(多 changelist)→ M2 Commit 窗口 → M3 Log/Branches/Diff → M4 Shelf/Partial/Stash → M5 AI Agent。
16 changes: 16 additions & 0 deletions .agents/reference-specifications.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Reference Specifications (IEEE)

> **模版准则**:[编号] 作者缩写. 姓, "文章标题," _刊名/会议名缩写 (斜体)_, 卷号, 期数, 页码, 年份.

```latex
[1] A. Author, B. Author, and C. Author, "Title of paper," *Abbrev. Title of Journal*, vol. X, no. Y, pp. XX–XX, Year.
```

**引用实践**

- **文内锚定**:采用标准上标链接形式:`描述内容<sup>[[1]](#ref1)</sup>`。
- **文献索引**:底层采用 HTML 锚点 `id` 实现跳转稳定性。

```latex
<a id="ref1"></a>[1] A. Vaswani et al., "Attention is all you need," Adv. Neural Inf. Process. Syst., vol. 30, pp. 5998–6008, 2017.
```
16 changes: 16 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
root = true

[*]
indent_style = tab
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false

[*.{yml,yaml,json}]
indent_style = tab
indent_size = 2
12 changes: 12 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
version: 2
updates:
- package-ecosystem: npm
directory: /
schedule:
interval: weekly
open-pull-requests-limit: 5
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
open-pull-requests-limit: 5
126 changes: 126 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
name: CI

on:
push:
branches: [master, feature/1.x.x]
tags:
- 'v*'
pull_request:

permissions:
contents: read

jobs:
# 闸门:类型检查 + lint + 生产构建(快门,ubuntu 单格)
lint-build:
name: Lint & Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm run check-types
- run: pnpm run lint
- run: pnpm run package

# 集成测试矩阵:main/tag 跑三平台,PR 仅 ubuntu 快门
test:
name: Test (${{ matrix.os }})
needs: lint-build
strategy:
fail-fast: false
matrix:
os: ${{ (github.event_name == 'pull_request') && fromJson('["ubuntu-latest"]') || fromJson('["ubuntu-latest", "macos-latest", "windows-latest"]') }}
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- name: 构建 dist/extension.js(集成测试需加载扩展)
run: node esbuild.js
- run: pnpm run test:unit
- name: 集成测试(Linux 需 xvfb 包装 Electron)
run: xvfb-run -a pnpm run test:integration
if: runner.os == 'Linux'
- name: 集成测试
run: pnpm run test:integration
if: runner.os != 'Linux'

# 打包 vsix(Linux 保 POSIX 文件属性)
package:
name: Package vsix
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm dlx @vscode/vsce package --no-yarn
- uses: actions/upload-artifact@v4
with:
name: vsix
path: '*.vsix'
if-no-files-found: error

# GitHub Release:仅 tag 触发,将 .vsix 作为可本地安装资产附带(与市场 publish 解耦)
github-release:
name: GitHub Release (.vsix)
needs: package
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/download-artifact@v4
with:
name: vsix
- name: 创建/更新 GitHub Release 并附带 .vsix
uses: softprops/action-gh-release@v2
with:
files: '*.vsix'
prerelease: ${{ contains(github.ref_name, 'rc') }}
generate_release_notes: true
fail_on_unmatched_files: true

# 发布:仅 tag 触发,双市场(Marketplace + OpenVSX),生产环境审批门
publish:
name: Publish
needs: package
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- uses: actions/download-artifact@v4
with:
name: vsix
- name: 发布到 VS Code Marketplace
run: |
PRE_FLAG=$([[ "${GITHUB_REF_NAME}" == *rc* ]] && echo "--pre-release" || echo "")
pnpm dlx @vscode/vsce publish --packagePath *.vsix $PRE_FLAG
env:
VSCE_PAT: ${{ secrets.VSCE_PAT }}
- name: 发布到 OpenVSX(覆盖 Cursor / Windsurf 等 AI IDE)
run: |
PRE_FLAG=$([[ "${GITHUB_REF_NAME}" == *rc* ]] && echo "--pre-release" || echo "")
pnpm dlx ovsx publish *.vsix $PRE_FLAG
env:
OVSX_PAT: ${{ secrets.OVSX_PAT }}
18 changes: 18 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# 本地 MCP 配置(不入仓)
.mcp.json

# 依赖与构建产物
node_modules/
dist/
out/
*.vsix

# VS Code Test 临时
.vscode-test/

# 临时产物(执行计划等,一律收敛至此并即时清理)
.temp/

# 系统/编辑器
.DS_Store
Thumbs.db
2 changes: 2 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# 规避 vsce 打包与 pnpm 符号链接 node_modules 的 hoisting 兼容问题(循证:Track3 §一/§4)
node-linker=hoisted
6 changes: 6 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
dist/**
out/**
node_modules/**
*.vsix
media/**
pnpm-lock.yaml
8 changes: 8 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"useTabs": true,
"tabWidth": 2,
"singleQuote": true,
"semi": true,
"printWidth": 120,
"trailingComma": "all"
}
6 changes: 6 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"recommendations": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode"
]
}
13 changes: 13 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "运行扩展(Extension Host)",
"type": "extensionHost",
"request": "launch",
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
"outFiles": ["${workspaceFolder}/dist/**/*.js"],
"preLaunchTask": "pnpm: watch"
}
]
}
26 changes: 26 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "watch",
"problemMatcher": "$esbuild-watch",
"isBackground": true,
"label": "pnpm: watch",
"group": { "kind": "build", "isDefault": true },
"presentation": { "reveal": "never" }
},
{
"type": "npm",
"script": "check-types",
"problemMatcher": ["$tsc"],
"label": "pnpm: check-types"
},
{
"type": "npm",
"script": "lint",
"problemMatcher": ["$eslint-stylish"],
"label": "pnpm: lint"
}
]
}
28 changes: 28 additions & 0 deletions .vscodeignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
.vscode/**
.vscode-test/**
src/**
tests/**
node_modules/**
.github/**
.agents/**
.context/**
docs/**
.temp/**
media-src/**
AGENTS.md
CLAUDE.md
pnpm-lock.yaml
pnpm-workspace.yaml
**/*.ts
**/*.map
tsconfig.json
esbuild.js
eslint.config.mjs
.prettierrc
.prettierignore
.editorconfig
.npmrc
.gitignore
.gitattributes
vitest.config.ts
**/.DS_Store
Loading
Loading