Skip to content
Merged
19 changes: 11 additions & 8 deletions .agents/skills/gframework-pr-review/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ Shortcut: `$gframework-pr-review`
## Workflow

1. Read `AGENTS.md` before deciding how to validate or fix anything.
2. Resolve the current branch with Windows Git from WSL, following the repository worktree rule.
2. Resolve the current branch following the repository worktree rule:
- prefer Linux `git` with explicit `--git-dir` / `--work-tree` binding in WSL worktrees
- only fall back to `git.exe` when that executable is available and actually runnable in the current session
3. Run `scripts/fetch_current_pr_review.py` to:
- locate the PR for the current branch through the GitHub PR API
- fetch PR metadata, issue comments, reviews, and review comments through the GitHub API
Expand All @@ -31,20 +33,20 @@ Shortcut: `$gframework-pr-review`
## Commands

- Default:
- `python3 .codex/skills/gframework-pr-review/scripts/fetch_current_pr_review.py`
- `python3 .agents/skills/gframework-pr-review/scripts/fetch_current_pr_review.py`
- Recommended machine-readable workflow:
- `python3 .codex/skills/gframework-pr-review/scripts/fetch_current_pr_review.py --pr 265 --json-output /tmp/pr265-review.json`
- `python3 .agents/skills/gframework-pr-review/scripts/fetch_current_pr_review.py --pr 265 --json-output /tmp/pr265-review.json`
- `jq '.coderabbit_review.outside_diff_comments' /tmp/pr265-review.json`
- Force a PR number:
- `python3 .codex/skills/gframework-pr-review/scripts/fetch_current_pr_review.py --pr 253`
- `python3 .agents/skills/gframework-pr-review/scripts/fetch_current_pr_review.py --pr 253`
- Machine-readable output:
- `python3 .codex/skills/gframework-pr-review/scripts/fetch_current_pr_review.py --format json`
- `python3 .agents/skills/gframework-pr-review/scripts/fetch_current_pr_review.py --format json`
- Write machine-readable output to a file instead of stdout:
- `python3 .codex/skills/gframework-pr-review/scripts/fetch_current_pr_review.py --pr 253 --format json --json-output /tmp/pr253-review.json`
- `python3 .agents/skills/gframework-pr-review/scripts/fetch_current_pr_review.py --pr 253 --format json --json-output /tmp/pr253-review.json`
- Inspect only a high-signal section:
- `python3 .codex/skills/gframework-pr-review/scripts/fetch_current_pr_review.py --pr 253 --section outside-diff`
- `python3 .agents/skills/gframework-pr-review/scripts/fetch_current_pr_review.py --pr 253 --section outside-diff`
- Narrow text output to one path fragment:
- `python3 .codex/skills/gframework-pr-review/scripts/fetch_current_pr_review.py --pr 253 --section outside-diff --path GFramework.Core/Events/Event.cs`
- `python3 .agents/skills/gframework-pr-review/scripts/fetch_current_pr_review.py --pr 253 --section outside-diff --path GFramework.Core/Events/Event.cs`

## Output Expectations

Expand All @@ -67,6 +69,7 @@ The script should produce:

- If the current branch has no matching public PR, report that clearly instead of guessing.
- If GitHub access fails because of proxy configuration, rerun the fetch with proxy variables removed.
- If the current WSL session resolves `git.exe` but cannot execute it cleanly, keep using the explicit Linux worktree binding instead of retrying Windows Git.
- Prefer GitHub API results over PR HTML. The PR HTML page is now a fallback/debugging source, not the primary source of truth.
- If the summary block and the latest head review threads disagree, trust the latest unresolved head-review threads and treat older summary findings as stale until re-verified locally.
- Do not assume every AI reviewer behaves like CodeRabbit. `greptile-apps[bot]` findings may exist only as latest-head review threads, without CodeRabbit-style issue comments or folded review-body sections.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@

OWNER = "GeWuYou"
REPO = "GFramework"
WORKTREE_ROOT_DIRECTORY_NAME = "GFramework-WorkTree"
DEFAULT_WINDOWS_GIT = "/mnt/d/Tool/Development Tools/Git/cmd/git.exe"
GIT_ENVIRONMENT_KEY = "GFRAMEWORK_WINDOWS_GIT"
GIT_DIR_ENVIRONMENT_KEY = "GFRAMEWORK_GIT_DIR"
WORK_TREE_ENVIRONMENT_KEY = "GFRAMEWORK_WORK_TREE"
USER_AGENT = "codex-gframework-pr-review"
CODERABBIT_LOGIN = "coderabbitai[bot]"
GREPTILE_LOGIN = "greptile-apps[bot]"
Expand Down Expand Up @@ -83,6 +86,43 @@ def resolve_git_command() -> str:
raise RuntimeError(f"No usable git executable found. Set {GIT_ENVIRONMENT_KEY} to override it.")


def find_repository_root(start_path: Path) -> Path | None:
"""Locate the repository root by walking parent directories for repo markers."""
for candidate in (start_path, *start_path.parents):
if (candidate / "AGENTS.md").exists() and (candidate / ".ai/environment/tools.ai.yaml").exists():
return candidate

return None


def resolve_worktree_git_dir(repository_root: Path) -> Path | None:
"""Resolve the main-repository worktree gitdir for this WSL worktree layout."""
if repository_root.parent.name != WORKTREE_ROOT_DIRECTORY_NAME:
return None

primary_repository_root = repository_root.parent.parent / REPO
candidate_git_dir = primary_repository_root / ".git" / "worktrees" / repository_root.name
return candidate_git_dir if candidate_git_dir.exists() else None


def resolve_git_invocation() -> list[str]:
"""Resolve the git command arguments, preferring explicit WSL worktree binding."""
configured_git_dir = os.environ.get(GIT_DIR_ENVIRONMENT_KEY)
configured_work_tree = os.environ.get(WORK_TREE_ENVIRONMENT_KEY)
linux_git = shutil.which("git")

if configured_git_dir and configured_work_tree and linux_git:
return [linux_git, f"--git-dir={configured_git_dir}", f"--work-tree={configured_work_tree}"]

repository_root = find_repository_root(Path.cwd())
if repository_root is not None and linux_git:
worktree_git_dir = resolve_worktree_git_dir(repository_root)
if worktree_git_dir is not None:
return [linux_git, f"--git-dir={worktree_git_dir}", f"--work-tree={repository_root}"]

return [resolve_git_command()]


def resolve_request_timeout_seconds() -> int:
"""Return the GitHub request timeout in seconds."""
configured_timeout = os.environ.get(REQUEST_TIMEOUT_ENVIRONMENT_KEY)
Expand Down Expand Up @@ -113,7 +153,7 @@ def run_command(args: list[str]) -> str:

def get_current_branch() -> str:
"""Return the current git branch name."""
return run_command([resolve_git_command(), "rev-parse", "--abbrev-ref", "HEAD"])
return run_command([*resolve_git_invocation(), "rev-parse", "--abbrev-ref", "HEAD"])


def open_url(url: str, accept: str) -> tuple[str, Any]:
Expand Down
23 changes: 15 additions & 8 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,21 @@ All AI agents and contributors must follow these rules when writing, reviewing,
- Use `@.ai/environment/tools.raw.yaml` only when you need the full collected facts behind the AI-facing hints.
- Prefer the project-relevant tools listed there instead of assuming every installed system tool is fair game.
- If the real environment differs from the inventory, use the project-relevant installed tool and report the mismatch.
- When working in WSL against this repository's Windows-backed worktree, prefer Windows Git from WSL (for example
`git.exe`) instead of the Linux `git` binary.
- If a Git command in WSL fails with a worktree-style “not a git repository” path translation error, rerun it with the
Windows Git executable and treat that as the repository-default Git path for the rest of the task.
- If the shell does not currently resolve `git.exe` to the host Windows Git installation, prepend that installation's
command directory to `PATH` and reset shell command hashing for the current session before continuing.
- After resolving the host Windows Git path, prefer an explicit session-local binding for subsequent commands so the
shell does not fall back to Linux `/usr/bin/git` later in the same WSL session.
- When working in WSL against this repository's Windows-backed worktree, first prefer Linux `git` with an explicit
`--git-dir=<repo>/.git/worktrees/<worktree-name>` and `--work-tree=<worktree-root>` binding for every repository
command. Treat that explicit binding as higher priority than `git.exe`, because it avoids WSL worktree path
translation mistakes and still works in sessions where Windows `.exe` execution is unavailable.
- If a plain Linux `git` command in WSL fails with a worktree-style “not a git repository” path translation error,
rerun it with the explicit `--git-dir` / `--work-tree` binding before trying `git.exe`.
- Only prefer Windows Git from WSL (for example `git.exe`) when that executable is both resolvable and executable in the
current session, and when the explicit Linux `git` binding is unavailable or has already failed.
- If the shell resolves `git.exe` but the current WSL session cannot execute it cleanly (for example `Exec format
error`), keep using the explicit Linux `git` binding for the rest of the task instead of retrying Windows Git.
- If the shell does not currently resolve `git.exe` to the host Windows Git installation and you still need Windows Git
as a fallback, prepend that installation's command directory to `PATH` and reset shell command hashing for the
current session before continuing.
- After resolving either strategy, prefer a session-local binding or command wrapper for subsequent Git commands so the
shell does not silently fall back to the wrong repository context later in the same WSL session.

## Git Workflow Rules

Expand Down
55 changes: 39 additions & 16 deletions GFramework.Core.Abstractions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

`GFramework.Core.Abstractions` 承载 `Core` 运行时对应的接口、枚举和值对象,用来定义跨模块协作边界。

它只描述契约,不提供默认的架构、事件、状态、资源或 IoC 实现;这些实现都在 `GFramework.Core` 中。

## 什么时候单独依赖它

- 你在做插件、适配层或扩展包,只想依赖契约,不想把完整运行时拉进来
Expand All @@ -20,32 +22,53 @@

## 契约地图

| 目录 | 作用 |
| 目录族 | 作用 |
| --- | --- |
| `Architectures/` | `IArchitecture`、模块、阶段监听与服务管理契约 |
| `Command/` / `Query/` | 旧版命令与查询执行器接口 |
| `Controller/` | `IController` |
| `Events/` | 事件契约、解绑接口与传播上下文 |
| `Model/` / `Systems/` / `Utility/` | 核心组件接口 |
| `State/` / `StateManagement/` | 状态机、Store、reducer、selector 契约 |
| `Property/` | `IBindableProperty` 与只读属性接口 |
| `Resource/` | 资源管理与释放策略契约 |
| `Localization/` | 本地化表、格式化与异常类型 |
| `Logging/` | logger、log entry、factory 相关契约 |
| `Ioc/` | `IIocContainer` |
| `Lifecycle/` | 初始化 / 销毁生命周期契约 |
| `Coroutine/` | 时间源、yield 指令与协程状态枚举 |
| `Pause/` | 暂停栈、token 与状态事件 |
| `Storage/` / `Serializer/` / `Versioning/` | 通用存储、序列化与版本化契约 |
| `Architectures/` `Lifecycle/` `Registries/` | `IArchitecture`、上下文、模块、服务模块、阶段监听、注册表基类与生命周期契约 |
| `Bases/` `Controller/` `Model/` `Systems/` `Utility/` `Rule/` | 组件角色接口、优先级 / key 值对象、上下文感知约束与扩展边界 |
| `Command/` `Query/` `Cqrs/` | 旧版命令 / 查询执行器接口,以及 `ICqrsRuntime` 这类新请求模型接线契约 |
| `Events/` `Property/` `State/` `StateManagement/` | 事件总线、解绑对象、可绑定属性、状态机、Store / reducer / middleware 契约 |
| `Coroutine/` `Time/` `Pause/` `Concurrency/` | 协程状态、时间源、暂停栈、键控异步锁和统计对象 |
| `Resource/` `Pool/` `Logging/` `Localization/` | 资源句柄、对象池、日志、日志工厂、本地化表与格式化契约 |
| `Configuration/` `Environment/` | 配置管理器、环境对象与运行时环境访问契约 |
| `Data/` `Serializer/` `Storage/` `Versioning/` | 数据装载、序列化、存储与版本化契约 |
| `Enums/` `Properties/` | 架构阶段枚举,以及架构 / logger 相关属性键 |

## XML 覆盖基线

截至 `2026-04-22`,已按顶层目录对 `GFramework.Core.Abstractions` 的公开 / 内部类型声明做过一轮轻量盘点;当前契约目录族的类型声明都已带
XML 注释。这里记录的是类型族级基线,成员级契约细节仍需要在后续波次继续审计。

| 类型族 | 基线状态 | 代表类型 |
| --- | --- | --- |
| `Architectures/` `Lifecycle/` `Registries/` | `20/20` 个类型声明已带 XML 注释 | `IArchitecture`、`IArchitectureContext`、`IServiceModule`、`KeyValueRegistryBase<TKey, TValue>` |
| `Command/` `Query/` `Cqrs/` | `10/10` 个类型声明已带 XML 注释 | `ICommandExecutor`、`IAsyncQueryExecutor`、`ICqrsRuntime` |
| `Events/` `Property/` `State/` `StateManagement/` | `25/25` 个类型声明已带 XML 注释 | `IEventBus`、`IBindableProperty<T>`、`IStateMachine`、`IStore<TState>` |
| `Coroutine/` `Time/` `Pause/` `Concurrency/` | `17/17` 个类型声明已带 XML 注释 | `IYieldInstruction`、`ITimeProvider`、`IPauseStackManager`、`IAsyncKeyLockManager` |
| `Resource/` `Pool/` `Logging/` `Localization/` | `27/27` 个类型声明已带 XML 注释 | `IResourceManager`、`IObjectPoolSystem`、`ILogger`、`ILocalizationManager` |
| `Configuration/` `Environment/` `Data/` `Serializer/` `Storage/` `Versioning/` | `7/7` 个类型声明已带 XML 注释 | `IConfigurationManager`、`IEnvironment`、`ILoadableFrom<T>`、`ISerializer`、`IStorage` |
| `Bases/` `Controller/` `Model/` `Systems/` `Utility/` `Rule/` `Enums/` `Properties/` | `19/19` 个类型声明已带 XML 注释 | `IPrioritized`、`IController`、`IModel`、`ISystem`、`IContextUtility`、`ArchitecturePhase` |

完整 inventory 与阅读顺序见 `docs/zh-CN/abstractions/core-abstractions.md`。

## 采用建议

- 框架消费者通常同时安装 `GFramework.Core` 与 `GFramework.Core.Abstractions`
- 若你只需要对接口编程,可以仅引用本包,再在应用层自行提供实现
- 若你在写上层模块,优先把公共契约放在 `*.Abstractions`,实现放在对应 runtime 包

## 重点 XML 关注点

如果你在做契约审计、模块拆分或测试替身,优先看这些类型族的 XML 文档:

- 架构与模块入口:`IArchitecture`、`IArchitectureContext`、`IServiceModule`
- 运行时基础设施:`IIocContainer`、`ILogger`、`IResourceManager`、`IConfigurationManager`
- 状态与并发能力:`IStateMachine`、`IStore`、`IAsyncKeyLockManager`、`ITimeProvider`
- 迁移与组合边界:`ICommandExecutor`、`IQueryExecutor`、`ICqrsRuntime`

## 对应文档

- 抽象接口栏目:[`../docs/zh-CN/abstractions/index.md`](../docs/zh-CN/abstractions/index.md)
- Core 抽象页:[`../docs/zh-CN/abstractions/core-abstractions.md`](../docs/zh-CN/abstractions/core-abstractions.md)
- Core 运行时入口:[`../GFramework.Core/README.md`](../GFramework.Core/README.md)
- API 参考入口:[`../docs/zh-CN/api-reference/index.md`](../docs/zh-CN/api-reference/index.md)
32 changes: 29 additions & 3 deletions GFramework.Core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@

- `Architecture` 与 `ArchitectureContext`
- `Model` / `System` / `Utility` 运行时
- 旧版 `Command` / `Query` 执行器
- 事件、属性、状态机、状态管理
- 资源、日志、协程、并发、环境与本地化
- 旧版 `Command` / `Query` 执行器,以及与新版 `CQRS` runtime 的接线入口
- 事件、属性、状态机、状态管理、规则与上下文扩展
- 资源、对象池、日志、协程、并发、环境、配置与本地化
- 服务模块管理、时间提供器与默认的 IoC 容器适配

它不负责:

Expand All @@ -37,22 +38,45 @@
| 目录 | 作用 |
| --- | --- |
| `Architectures/` | 架构入口、上下文、生命周期、模块安装与组件注册 |
| `Services/` | 服务模块注册、生命周期协调与模块管理 |
| `Command/` | 旧版命令执行器与同步 / 异步命令基类 |
| `Query/` | 旧版查询执行器与同步 / 异步查询基类 |
| `Events/` | 事件总线、事件作用域、统计与过滤 |
| `Property/` | `BindableProperty<T>` 与相关解绑对象 |
| `State/` | 状态机与状态切换事件 |
| `StateManagement/` | Store、selector、middleware 与状态诊断 |
| `Coroutine/` | 协程调度、快照、统计与优先级 |
| `Time/` | 默认时间提供器与协程时间源 |
| `Resource/` | 资源缓存、句柄和释放策略 |
| `Pool/` | 对象池系统与常用池化辅助实现 |
| `Logging/` | logger、factory、配置与组合日志器 |
| `Ioc/` | 基于 `Microsoft.Extensions.DependencyInjection` 的容器适配 |
| `Concurrency/` | 键控异步锁与统计 |
| `Configuration/` | 配置管理器与配置监听解绑对象 |
| `Environment/` | 运行环境对象与上下文环境扩展 |
| `Pause/` | 暂停栈和暂停范围 |
| `Localization/` | 本地化表与格式化入口 |
| `Rule/` | `ContextAwareBase` 等上下文感知基类 |
| `Functional/` | `Option`、`Result` 等轻量函数式工具 |
| `Extensions/` | 上下文与集合等扩展方法 |

## XML 覆盖基线

截至 `2026-04-22`,已按顶层目录对 `GFramework.Core` 的公开 / 内部类型声明做过一轮轻量盘点;当前主目录族的类型声明都已带
XML 注释。这里先保留阅读基线,成员级 ``<param>`` / ``<returns>`` / 生命周期语义审计仍属于后续治理项。

| 类型族 | 基线状态 | 代表类型 |
| --- | --- | --- |
| `Architectures/` `Services/` | `22/22` 个类型声明已带 XML 注释 | `Architecture`、`ArchitectureContext`、`ArchitectureLifecycle`、`ServiceModuleManager` |
| `Command/` `Query/` | `15/15` 个类型声明已带 XML 注释 | `CommandExecutor`、`AsyncQueryExecutor`、`AbstractCommand<TInput>`、`AbstractQuery<TResult>` |
| `Events/` `Property/` `State/` `StateManagement/` | `29/29` 个类型声明已带 XML 注释 | `EventBus`、`BindableProperty<T>`、`StateMachine`、`Store<TState>` |
| `Coroutine/` `Time/` `Pause/` `Concurrency/` | `43/43` 个类型声明已带 XML 注释 | `CoroutineScheduler`、`CoroutineHandle`、`PauseStackManager`、`AsyncKeyLockManager` |
| `Resource/` `Pool/` | `8/8` 个类型声明已带 XML 注释 | `ResourceManager`、`AutoReleaseStrategy`、`AbstractObjectPoolSystem<TKey, TObject>` |
| `Logging/` `Localization/` `Configuration/` `Environment/` `Ioc/` | `31/31` 个类型声明已带 XML 注释 | `ConsoleLogger`、`LocalizationManager`、`ConfigurationManager`、`DefaultEnvironment`、`MicrosoftDiContainer` |
| `Model/` `Systems/` `Utility/` `Rule/` `Extensions/` `Functional/` | `34/34` 个类型声明已带 XML 注释 | `AbstractModel`、`AbstractSystem`、`NumericDisplayFormatter`、`ContextAwareBase`、`Result<T>` |

完整的模块化阅读顺序和 inventory 说明见 `docs/zh-CN/core/index.md`。

## 最小接入路径

```bash
Expand Down Expand Up @@ -80,5 +104,7 @@ dotnet add package GeWuYou.GFramework.Core.Abstractions
## 对应文档

- Core 栏目:[`../docs/zh-CN/core/index.md`](../docs/zh-CN/core/index.md)
- Core 抽象层:[`../docs/zh-CN/abstractions/core-abstractions.md`](../docs/zh-CN/abstractions/core-abstractions.md)
- API 参考入口:[`../docs/zh-CN/api-reference/index.md`](../docs/zh-CN/api-reference/index.md)
- CQRS:[`../docs/zh-CN/core/cqrs.md`](../docs/zh-CN/core/cqrs.md)
- 入门指南:[`../docs/zh-CN/getting-started/index.md`](../docs/zh-CN/getting-started/index.md)
Loading
Loading