93d1b21的任务收尾

This commit is contained in:
2025-12-19 02:30:45 +08:00
parent 93d1b21bb8
commit 5a29146c32
40 changed files with 3596 additions and 93 deletions

View File

@@ -101,10 +101,10 @@ DEFAULT_CONFIG = """############################################################
[general]
# 是否在 .gitignore 中忽略 .aide 目录
# - true(默认):自动添加 .aide/ 到 .gitignore不跟踪 aide 状态
# - false不修改 .gitignore允许 git 跟踪 .aide 目录
# 适用于需要在多设备同步 aide 状态的场景
gitignore_aide = true
# - true自动添加 .aide/ 到 .gitignore不跟踪 aide 状态
# - false(默认):不修改 .gitignore允许 git 跟踪 .aide 目录
# 推荐使用此设置,便于多设备同步 aide 状态和任务历史
gitignore_aide = false
################################################################################
# [runtime] - Aide 运行时要求
@@ -240,6 +240,30 @@ path = ".aide/project-docs"
# 默认:.aide/project-docs/block-plan.md
block_plan_path = ".aide/project-docs/block-plan.md"
################################################################################
# [user_docs] - 面向用户的文档配置
################################################################################
# 配置面向用户的文档系统。
# 包括 README、用户文档和流程图等。
[user_docs]
# README 文件路径(相对于项目根目录)
readme_path = "README.md"
# README 编写规范文件路径
# 存放项目的 README 编写规范和模板选择
rules_path = "make-readme-rules.md"
# 用户文档目录路径
docs_path = "docs"
# 用户流程图目录路径
graph_path = "docs/graph-guide"
# 流程图计划文件路径
# 存放流程图编写计划和进度,用于分步执行和接续执行
graph_plan_path = "docs/graph-guide/plan.md"
################################################################################
# [flow] - 流程追踪配置
################################################################################
@@ -327,11 +351,11 @@ class ConfigManager:
def ensure_gitignore(self) -> None:
"""根据配置决定是否在 .gitignore 中添加 .aide/ 忽略项。"""
# 读取配置,默认为 True忽略 .aide 目录)
# 读取配置,默认为 False忽略 .aide 目录)
config = self.load_config()
gitignore_aide = self._walk_get(config, "general.gitignore_aide")
if gitignore_aide is None:
gitignore_aide = True # 默认值
gitignore_aide = False # 默认值
if not gitignore_aide:
# 配置为 False不添加忽略项

View File

@@ -4,13 +4,14 @@ from __future__ import annotations
import json
import os
import secrets
import time
from contextlib import contextmanager
from pathlib import Path
from aide.flow.errors import FlowError
from aide.flow.types import FlowStatus
from aide.flow.utils import now_task_id
from aide.flow.utils import now_iso, now_task_id
class FlowStorage:
@@ -21,6 +22,7 @@ class FlowStorage:
self.lock_path = self.aide_dir / "flow-status.lock"
self.tmp_path = self.aide_dir / "flow-status.json.tmp"
self.logs_dir = self.aide_dir / "logs"
self.back_confirm_path = self.aide_dir / "back-confirm-state.json"
def ensure_ready(self) -> None:
if not self.aide_dir.exists():
@@ -144,3 +146,45 @@ class FlowStorage:
return None
# === Back-confirm 状态管理 ===
def has_pending_back_confirm(self) -> bool:
"""检查是否存在待确认的 back 请求。"""
return self.back_confirm_path.exists()
def load_back_confirm_state(self) -> dict | None:
"""加载 back-confirm 状态。"""
if not self.back_confirm_path.exists():
return None
try:
raw = self.back_confirm_path.read_text(encoding="utf-8")
data = json.loads(raw)
if not isinstance(data, dict):
raise ValueError("back-confirm 状态文件格式错误")
return data
except Exception as exc:
raise FlowError(f"读取 back-confirm 状态失败: {exc}")
def save_back_confirm_state(self, target_part: str, reason: str) -> str:
"""保存 back-confirm 状态,返回生成的 key。"""
key = secrets.token_hex(6) # 12 字符的随机 key
data = {
"pending_key": key,
"target_part": target_part,
"reason": reason,
"created_at": now_iso(),
}
try:
payload = json.dumps(data, ensure_ascii=False, indent=2) + "\n"
self.back_confirm_path.write_text(payload, encoding="utf-8")
except Exception as exc:
raise FlowError(f"保存 back-confirm 状态失败: {exc}")
return key
def clear_back_confirm_state(self) -> None:
"""清除 back-confirm 状态文件。"""
try:
self.back_confirm_path.unlink(missing_ok=True)
except Exception as exc:
raise FlowError(f"清除 back-confirm 状态失败: {exc}")

View File

@@ -39,7 +39,64 @@ class FlowTracker:
return self._run(action="next-part", to_phase=phase, text=summary)
def back_part(self, phase: str, reason: str) -> bool:
return self._run(action="back-part", to_phase=phase, text=reason)
"""返工请求:检测是否已确认,未确认则生成 key。"""
try:
self.storage.ensure_ready()
# 检查是否存在待确认的 back 请求
if self.storage.has_pending_back_confirm():
state = self.storage.load_back_confirm_state()
if state:
output.warn("已存在待确认的返工请求")
output.info(f"目标环节: {state['target_part']}")
output.info(f"原因: {state['reason']}")
output.info(f"请执行: aide flow back-confirm --key {state['pending_key']}")
return False
# 生成新的确认 key
key = self.storage.save_back_confirm_state(phase, reason)
output.warn("返工需要确认。请先完成准备工作,然后执行:")
output.info(f"aide flow back-confirm --key {key}")
return True
except FlowError as exc:
output.err(str(exc))
return False
def back_confirm(self, key: str) -> bool:
"""确认返工请求并执行。"""
try:
self.storage.ensure_ready()
# 检查是否存在待确认的请求
state = self.storage.load_back_confirm_state()
if state is None:
output.err("无待确认的返工请求")
return False
# 验证 key
if state.get("pending_key") != key:
output.err("确认 key 不匹配")
return False
# 获取目标阶段和原因
target_part = state["target_part"]
reason = state["reason"]
# 清除确认状态文件
self.storage.clear_back_confirm_state()
# 执行实际的 back-part 操作
result = self._run(action="back-part", to_phase=target_part, text=reason)
if result:
output.warn("建议执行 /exit 重新开始对话")
return result
except FlowError as exc:
output.err(str(exc))
return False
def issue(self, description: str) -> bool:
return self._run(action="issue", to_phase=None, text=description)

View File

@@ -119,6 +119,10 @@ def build_parser() -> argparse.ArgumentParser:
flow_back_part.add_argument("reason", help="回退原因")
flow_back_part.set_defaults(func=handle_flow_back_part)
flow_back_confirm = flow_sub.add_parser("back-confirm", help="确认返工请求")
flow_back_confirm.add_argument("--key", required=True, help="确认 key")
flow_back_confirm.set_defaults(func=handle_flow_back_confirm)
flow_issue = flow_sub.add_parser("issue", help="记录一般问题(不阻塞继续)")
flow_issue.add_argument("description", help="问题描述")
flow_issue.set_defaults(func=handle_flow_issue)
@@ -166,7 +170,8 @@ def build_parser() -> argparse.ArgumentParser:
def handle_init(args: argparse.Namespace) -> bool:
root = find_project_root()
# 使用当前工作目录(原地初始化,类似 git init
root = Path.cwd()
cfg = ConfigManager(root)
cfg.ensure_config()
cfg.ensure_gitignore()
@@ -300,6 +305,13 @@ def handle_flow_back_part(args: argparse.Namespace) -> bool:
return tracker.back_part(args.phase, args.reason)
def handle_flow_back_confirm(args: argparse.Namespace) -> bool:
root = find_project_root()
cfg = ConfigManager(root)
tracker = FlowTracker(root, cfg)
return tracker.back_confirm(args.key)
def handle_flow_issue(args: argparse.Namespace) -> bool:
root = find_project_root()
cfg = ConfigManager(root)

View File

@@ -199,9 +199,9 @@ aide-program/
### 5.2 .gitignore 处理
- `aide init`自动检查 `.gitignore`
- 默认添加 `.aide/` 为忽略项
- 可通过配置 `general.gitignore_aide = false` 禁用此行为
- `aide init`根据配置决定是否修改 `.gitignore`
- 默认不修改(`gitignore_aide = false`),推荐将 .aide/ 纳入版本控制
- 可通过配置 `general.gitignore_aide = true` 自动添加 `.aide/` 为忽略项
---

View File

@@ -25,7 +25,7 @@ aide 使用 TOML 格式的配置文件,位于 `.aide/config.toml`。
# general: 通用设置
[general]
gitignore_aide = true # 是否自动将 .aide/ 添加到 .gitignore
gitignore_aide = false # 是否自动将 .aide/ 添加到 .gitignore
# runtime: aide 自身运行要求
[runtime]
@@ -81,11 +81,12 @@ timeout = 0
| 字段 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `gitignore_aide` | bool | `true` | 是否自动将 .aide/ 添加到 .gitignore |
| `gitignore_aide` | bool | `false` | 是否自动将 .aide/ 添加到 .gitignore |
**使用场景**
- `aide init` 时检查此配置,决定是否修改 .gitignore
- 设为 `false`将 .aide/ 纳入版本控制
- 默认 `false`,推荐将 .aide/ 纳入版本控制,便于多设备同步
- 设为 `true` 可自动将 .aide/ 添加到 .gitignore
### 4.2 [runtime] 运行时配置