【从0到1构建一个ClaudeAgent】协作-Worktree+任务隔离 _
任务板管 做什么 但不管 在哪做。解法: 给每个任务一个独立的 git worktree 目录, 用任务 ID 把两边关联起来。各干各的目录, 互不干扰任务管目标,worktree 管目录按 ID 绑定。Java实现代码javapublic class WorktreeTaskIsolationSystem { // --- 新增配置 --- private static final Path REPO_ROOT detectRepoRoot(WORKDIR); // Git仓库根目录 private static final Path TASKS_DIR REPO_ROOT.resolve(.tasks); private static final Path WORKTREES_DIR REPO_ROOT.resolve(.worktrees); private static final Path EVENTS_LOG_PATH WORKTREES_DIR.resolve(events.jsonl); // --- 新增Git 仓库检测 --- private static Path detectRepoRoot(Path cwd) { try { ProcessBuilder pb new ProcessBuilder(git, rev-parse, --show-toplevel); pb.directory(cwd.toFile()); Process process pb.start(); boolean finished process.waitFor(10, TimeUnit.SECONDS); if (!finished) { return cwd; } String output new String(process.getInputStream().readAllBytes()).trim(); Path root Paths.get(output); return Files.exists(root) ? root : cwd; // 自动检测自动发现Git仓库根目录 // 向后兼容如果不是Git仓库使用当前目录 } catch (Exception e) { return cwd; } } // --- 新增事件总线EventBus--- static class EventBus { private final Path eventLogPath; public EventBus(Path eventLogPath) { this.eventLogPath eventLogPath; try { Files.createDirectories(eventLogPath.getParent()); if (!Files.exists(eventLogPath)) { Files.writeString(eventLogPath, ); } } catch (IOException e) { throw new RuntimeException(Failed to create event bus, e); } } /** * 发出事件 */ public void emit(String event, MapString, Object task, MapString, Object worktree, String error) { MapString, Object payload new LinkedHashMap(); payload.put(event, event); payload.put(ts, System.currentTimeMillis() / 1000.0); payload.put(task, task ! null ? task : Map.of()); payload.put(worktree, worktree ! null ? worktree : Map.of()); if (error ! null) { payload.put(error, error); } // 结构化事件事件类型、时间戳、关联数据 // 错误跟踪支持记录操作失败信息 try { String jsonLine gson.toJson(payload) \n; Files.writeString(eventLogPath, jsonLine, StandardOpenOption.CREATE, StandardOpenOption.APPEND); // JSONL格式每行一个事件便于流式处理 // 追加写入支持长时间运行的事件记录 } catch (IOException e) { System.err.println(Failed to emit event: e.getMessage()); } } /** * 列出最近事件 */ public String listRecent(int limit) { int n Math.max(1, Math.min(limit, 200)); try { ListString lines Files.readAllLines(eventLogPath); ListMapString, Object events new ArrayList(); int start Math.max(0, lines.size() - n); for (int i start; i lines.size(); i) { try { Type type new TypeTokenMapString, Object(){}.getType(); MapString, Object event gson.fromJson(lines.get(i), type); events.add(event); } catch (Exception e) { MapString, Object errorEvent new HashMap(); errorEvent.put(event, parse_error); errorEvent.put(raw, lines.get(i)); events.add(errorEvent); // 容错处理即使解析失败也记录原始数据 } } return gson.toJson(events); } catch (IOException e) { return []; } } } // 初始化事件总线 private static final EventBus EVENTS new EventBus(EVENTS_LOG_PATH); // --- 新增任务管理器支持工作树绑定--- static class TaskManager { private final Path tasksDir; private int nextId 1; public TaskManager(Path tasksDir) { this.tasksDir tasksDir; try { Files.createDirectories(tasksDir); this.nextId getMaxId() 1; } catch (IOException e) { throw new RuntimeException(Failed to initialize task manager, e); } } /** * 绑定任务到工作树 */ public String bindWorktree(int taskId, String worktree, String owner) throws IOException { MapString, Object task loadTask(taskId); task.put(worktree, worktree); // 任务-工作树关联建立任务和工作树的双向链接 if (owner ! null !owner.isEmpty()) { task.put(owner, owner); } if (pending.equals(task.get(status))) { task.put(status, in_progress); // 状态自动转换绑定工作树时自动开始任务 } task.put(updated_at, System.currentTimeMillis() / 1000.0); saveTask(task); return gson.toJson(task); } /** * 解绑工作树 */ public String unbindWorktree(int taskId) throws IOException { MapString, Object task loadTask(taskId); task.put(worktree, ); task.put(updated_at, System.currentTimeMillis() / 1000.0); saveTask(task); return gson.toJson(task); // 解绑机制支持任务和工作树的解耦 } /** * 列出所有任务 */ public String listAllTasks() throws IOException { // ... 列出任务逻辑包含工作树绑定信息 sb.append(String.format(%s #%d: %s%s%s\n, marker, id, subject, ownerStr, worktreeStr)); // 可视化展示显示任务状态、所有者、工作树绑定 } } // 初始化任务管理器 private static final TaskManager TASKS new TaskManager(TASKS_DIR); // --- 新增工作树管理器WorktreeManager--- static class WorktreeManager { private final Path repoRoot; private final TaskManager taskManager; private final EventBus eventBus; private final Path worktreesDir; private final Path indexPath; private final boolean gitAvailable; public WorktreeManager(Path repoRoot, TaskManager taskManager, EventBus eventBus) { this.repoRoot repoRoot; this.taskManager taskManager; this.eventBus eventBus; this.worktreesDir repoRoot.resolve(.worktrees); this.indexPath worktreesDir.resolve(index.json); // 集成架构工作树管理器与任务管理器、事件总线集成 try { Files.createDirectories(worktreesDir); if (!Files.exists(indexPath)) { MapString, Object index new HashMap(); index.put(worktrees, new ArrayListMapString, Object()); Files.writeString(indexPath, gson.toJson(index)); } } catch (IOException e) { throw new RuntimeException(Failed to initialize worktree manager, e); } this.gitAvailable isGitRepo(); } /** * 检查是否是Git仓库 */ private boolean isGitRepo() { try { ProcessBuilder pb new ProcessBuilder(git, rev-parse, --is-inside-work-tree); pb.directory(repoRoot.toFile()); Process process pb.start(); return process.exitValue() 0; } catch (Exception e) { return false; } } /** * 执行Git命令 */ private String runGit(ListString args) throws Exception { if (!gitAvailable) { throw new RuntimeException(Not in a git repository. worktree tools require git.); } ProcessBuilder pb new ProcessBuilder(git); pb.command().addAll(args); pb.directory(repoRoot.toFile()); Process process pb.start(); boolean finished process.waitFor(120, TimeUnit.SECONDS); if (!finished) { process.destroy(); throw new RuntimeException(git command timeout); } int exitCode process.exitValue(); if (exitCode ! 0) { String error new String(process.getErrorStream().readAllBytes()).trim(); String output new String(process.getInputStream().readAllBytes()).trim(); String message error.isEmpty() ? output : error; if (message.isEmpty()) { message git String.join( , args) failed; } throw new RuntimeException(message); } String output new String(process.getInputStream().readAllBytes()).trim(); String error new String(process.getErrorStream().readAllBytes()).trim(); String result output (error.isEmpty() ? : \n error); return result.isEmpty() ? (no output) : result; } /** * 加载索引文件 */ SuppressWarnings(unchecked) private MapString, Object loadIndex() throws IOException { String content Files.readString(indexPath); Type type new TypeTokenMapString, Object(){}.getType(); return gson.fromJson(content, type); } /** * 保存索引文件 */ private void saveIndex(MapString, Object index) throws IOException { Files.writeString(indexPath, gson.toJson(index)); } /** * 验证工作树名称 */ private void validateName(String name) { if (name null || name.isEmpty() || name.length() 40) { throw new IllegalArgumentException(Worktree name must be 1-40 characters); } if (!name.matches([A-Za-z0-9._-])) { throw new IllegalArgumentException( Invalid worktree name. Use letters, numbers, ., _, - only ); } // 名称规范确保工作树名称安全且规范 } /** * 创建工作树 */ public String createWorktree(String name, Integer taskId, String baseRef) throws Exception { validateName(name); MapString, Object existing findWorktree(name); if (existing ! null) { throw new IllegalArgumentException(Worktree name already exists); } if (taskId ! null !taskManager.taskExists(taskId)) { throw new IllegalArgumentException(Task taskId not found); } // 发出创建前事件 MapString, Object taskInfo taskId ! null ? Map.of(id, taskId) : Map.of(); MapString, Object worktreeInfo Map.of(name, name, base_ref, baseRef); eventBus.emit(worktree.create.before, taskInfo, worktreeInfo, null); try { Path worktreePath worktreesDir.resolve(name); String branch wt/ name; // 自动生成分支名 // Git工作树创建 runGit(Arrays.asList(worktree, add, -b, branch, worktreePath.toString(), baseRef)); // Git工作树独立的代码工作目录 // 自动分支为每个工作树创建独立分支 // 创建索引条目 MapString, Object entry new LinkedHashMap(); entry.put(name, name); entry.put(path, worktreePath.toString()); entry.put(branch, branch); entry.put(task_id, taskId); entry.put(status, active); entry.put(created_at, System.currentTimeMillis() / 1000.0); // 保存到索引 MapString, Object index loadIndex(); SuppressWarnings(unchecked) ListMapString, Object worktrees (ListMapString, Object) index.get(worktrees); worktrees.add(entry); saveIndex(index); // 绑定任务 if (taskId ! null) { taskManager.bindWorktree(taskId, name, ); } // 发出创建后事件 MapString, Object worktreeAfter new LinkedHashMap(); worktreeAfter.put(name, name); worktreeAfter.put(path, worktreePath.toString()); worktreeAfter.put(branch, branch); worktreeAfter.put(status, active); eventBus.emit(worktree.create.after, taskInfo, worktreeAfter, null); return gson.toJson(entry); } catch (Exception e) { eventBus.emit(worktree.create.failed, taskInfo, Map.of(name, name, base_ref, baseRef), e.getMessage()); throw e; } } /** * 获取工作树状态 */ public String getWorktreeStatus(String name) throws IOException { MapString, Object worktree findWorktree(name); if (worktree null) { return Error: Unknown worktree name ; } Path worktreePath Paths.get((String) worktree.get(path)); if (!Files.exists(worktreePath)) { return Error: Worktree path missing: worktreePath; } try { ProcessBuilder pb new ProcessBuilder(git, status, --short, --branch); pb.directory(worktreePath.toFile()); Process process pb.start(); boolean finished process.waitFor(60, TimeUnit.SECONDS); if (!finished) { process.destroy(); return Error: Git status timeout; } String output new String(process.getInputStream().readAllBytes()).trim(); String error new String(process.getErrorStream().readAllBytes()).trim(); String result output (error.isEmpty() ? : \n error); return result.isEmpty() ? Clean worktree : result; // Git状态检查提供详细的工作树状态信息 } catch (Exception e) { return Error: e.getMessage(); } } /** * 在工作树中运行命令 */ public String runInWorktree(String name, String command) throws Exception { // 安全检查 String[] dangerous {rm -rf /, sudo, shutdown, reboot, /dev/}; for (String d : dangerous) { if (command.contains(d)) { return Error: Dangerous command blocked; } } MapString, Object worktree findWorktree(name); if (worktree null) { return Error: Unknown worktree name ; } Path worktreePath Paths.get((String) worktree.get(path)); if (!Files.exists(worktreePath)) { return Error: Worktree path missing: worktreePath; } try { ProcessBuilder pb new ProcessBuilder(bash, -c, command); pb.directory(worktreePath.toFile()); // 目录隔离命令在工作树的独立目录中执行 Process process pb.start(); boolean finished process.waitFor(300, TimeUnit.SECONDS); if (!finished) { process.destroy(); return Error: Timeout (300s); } String output new String(process.getInputStream().readAllBytes()).trim(); String error new String(process.getErrorStream().readAllBytes()).trim(); String result output (error.isEmpty() ? : \n error); return result.isEmpty() ? (no output) : result.substring(0, Math.min(result.length(), 50000)); } catch (Exception e) { return Error: e.getMessage(); } } /** * 删除工作树 */ public String removeWorktree(String name, boolean force, boolean completeTask) throws Exception { MapString, Object worktree findWorktree(name); if (worktree null) { return Error: Unknown worktree name ; } // 发出删除前事件 Integer taskId (Integer) worktree.get(task_id); MapString, Object taskInfo taskId ! null ? Map.of(id, taskId) : Map.of(); MapString, Object worktreeInfo Map.of( name, name, path, worktree.get(path) ); eventBus.emit(worktree.remove.before, taskInfo, worktreeInfo, null); try { ListString args new ArrayList(); args.addAll(Arrays.asList(worktree, remove)); if (force) { args.add(--force); } args.add((String) worktree.get(path)); runGit(args); // Git工作树删除清理Git工作树 // 完成任务 if (completeTask taskId ! null) { MapString, Object task gson.fromJson(taskManager.getTask(taskId), new TypeTokenMapString, Object(){}.getType()); taskManager.updateTask(taskId, completed, null); taskManager.unbindWorktree(taskId); // 任务-工作树生命周期协同删除工作树时自动完成任务 MapString, Object taskEvent new HashMap(); taskEvent.put(id, taskId); taskEvent.put(subject, task.get(subject)); taskEvent.put(status, completed); eventBus.emit(task.completed, taskEvent, Map.of(name, name), null); } // 更新索引 MapString, Object index loadIndex(); SuppressWarnings(unchecked) ListMapString, Object worktrees (ListMapString, Object) index.get(worktrees); for (MapString, Object wt : worktrees) { if (name.equals(wt.get(name))) { wt.put(status, removed); wt.put(removed_at, System.currentTimeMillis() / 1000.0); break; } } saveIndex(index); // 索引更新标记工作树为已删除状态 // 发出删除后事件 MapString, Object worktreeAfter new HashMap(); worktreeAfter.put(name, name); worktreeAfter.put(path, worktree.get(path)); worktreeAfter.put(status, removed); eventBus.emit(worktree.remove.after, taskInfo, worktreeAfter, null); return Removed worktree name ; } catch (Exception e) { eventBus.emit(worktree.remove.failed, taskInfo, worktreeInfo, e.getMessage()); throw e; } } /** * 保留工作树标记为保留状态 */ public String keepWorktree(String name) throws IOException { MapString, Object worktree findWorktree(name); if (worktree null) { return Error: Unknown worktree name ; } MapString, Object index loadIndex(); SuppressWarnings(unchecked) ListMapString, Object worktrees (ListMapString, Object) index.get(worktrees); MapString, Object keptWorktree null; for (MapString, Object wt : worktrees) { if (name.equals(wt.get(name))) { wt.put(status, kept); wt.put(kept_at, System.currentTimeMillis() / 1000.0); keptWorktree wt; break; } } saveIndex(index); // 保留状态标记工作树为需要保留不自动清理 // 发出保留事件 Integer taskId (Integer) worktree.get(task_id); MapString, Object taskInfo taskId ! null ? Map.of(id, taskId) : Map.of(); MapString, Object worktreeInfo new HashMap(); worktreeInfo.put(name, name); worktreeInfo.put(path, worktree.get(path)); worktreeInfo.put(status, kept); eventBus.emit(worktree.keep, taskInfo, worktreeInfo, null); return keptWorktree ! null ? gson.toJson(keptWorktree) : Error: Unknown worktree name ; } } // 初始化工作树管理器 private static final WorktreeManager WORKTREES new WorktreeManager(REPO_ROOT, TASKS, EVENTS); // --- 新增工具处理器 --- static { // 新增任务工具 TOOL_HANDLERS.put(task_create, args - { String subject (String) args.get(subject); String description (String) args.get(description); return TASKS.createTask(subject, description); }); TOOL_HANDLERS.put(task_list, args - TASKS.listAllTasks()); TOOL_HANDLERS.put(task_get, args - { int taskId ((Number) args.get(task_id)).intValue(); return TASKS.getTask(taskId); }); TOOL_HANDLERS.put(task_update, args - { int taskId ((Number) args.get(task_id)).intValue(); String status (String) args.get(status); String owner (String) args.get(owner); return TASKS.updateTask(taskId, status, owner); }); TOOL_HANDLERS.put(task_bind_worktree, args - { int taskId ((Number) args.get(task_id)).intValue(); String worktree (String) args.get(worktree); String owner (String) args.get(owner); return TASKS.bindWorktree(taskId, worktree, owner); }); // 新增工作树工具 TOOL_HANDLERS.put(worktree_create, args - { String name (String) args.get(name); Integer taskId args.get(task_id) ! null ? ((Number) args.get(task_id)).intValue() : null; String baseRef (String) args.get(base_ref); if (baseRef null) baseRef HEAD; return WORKTREES.createWorktree(name, taskId, baseRef); }); TOOL_HANDLERS.put(worktree_list, args - WORKTREES.listWorktrees()); TOOL_HANDLERS.put(worktree_status, args - { String name (String) args.get(name); return WORKTREES.getWorktreeStatus(name); }); TOOL_HANDLERS.put(worktree_run, args - { String name (String) args.get(name); String command (String) args.get(command); return WORKTREES.runInWorktree(name, command); }); TOOL_HANDLERS.put(worktree_keep, args - { String name (String) args.get(name); return WORKTREES.keepWorktree(name); }); TOOL_HANDLERS.put(worktree_remove, args - { String name (String) args.get(name); boolean force args.get(force) ! null (Boolean) args.get(force); boolean completeTask args.get(complete_task) ! null (Boolean) args.get(complete_task); return WORKTREES.removeWorktree(name, force, completeTask); }); TOOL_HANDLERS.put(worktree_events, args - { int limit args.get(limit) ! null ? ((Number) args.get(limit)).intValue() : 20; return EVENTS.listRecent(limit); }); } // --- 新增工具定义 --- private static ListMapString, Object getToolSpecs() { ListMapString, Object tools new ArrayList(); // 任务工具定义... // 工作树工具定义... return tools; } }这段代码引入了工作树任务隔离系统实现了目录级隔离每个任务在自己的工作树中执行控制平面与执行平面分离控制平面任务管理.tasks/执行平面工作树管理.worktrees/事件总线记录完整生命周期事件Git 工作树集成利用 git worktree 实现隔离关键洞察通过目录隔离并行任务通过任务ID进行协调。Git工作树隔离架构核心思想从文件系统隔离升级为Git仓库级别的代码隔离通过Git工作树实现完全隔离的并行开发环境为每个任务提供独立的代码工作空间避免冲突支持真正的并行开发。java// 核心路径配置 private static final Path REPO_ROOT detectRepoRoot(WORKDIR); // Git仓库根目录 private static final Path WORKTREES_DIR REPO_ROOT.resolve(.worktrees); // 工作树目录 // Git仓库感知自动检测Git仓库根目录 // 工作树管理专门的工作树存储目录 // 版本控制集成与Git深度集成java// Git仓库检测 private static Path detectRepoRoot(Path cwd) { try { ProcessBuilder pb new ProcessBuilder(git, rev-parse, --show-toplevel); pb.directory(cwd.toFile()); Process process pb.start(); String output new String(process.getInputStream().readAllBytes()).trim(); Path root Paths.get(output); return Files.exists(root) ? root : cwd; // 自动发现自动定位Git仓库根目录 // 兼容处理非Git仓库时回退到当前目录 } catch (Exception e) { return cwd; } }Git原生集成深度集成Git版本控制系统仓库感知自动识别和适应Git仓库结构向后兼容非Git环境也能工作专业级隔离为专业软件开发设计工作树管理系统java// 工作树管理器核心 static class WorktreeManager { private final Path repoRoot; private final TaskManager taskManager; private final EventBus eventBus; private final Path worktreesDir; private final Path indexPath; private final boolean gitAvailable; // 三组件集成仓库、任务、事件总线 // 索引管理工作树元数据索引 // 可用性检查检测Git环境 }集成架构与任务管理和事件系统深度集成元数据管理工作树元数据集中管理环境感知自动检测和适应Git环境专业级管理企业级的工作树生命周期管理Git工作树创建机制java// 创建工作树 public String createWorktree(String name, Integer taskId, String baseRef) throws Exception { validateName(name); Path worktreePath worktreesDir.resolve(name); String branch wt/ name; // 自动生成分支名 // Git工作树创建 runGit(Arrays.asList(worktree, add, -b, branch, worktreePath.toString(), baseRef)); // Git工作树独立的工作目录 // 自动分支为每个工作树创建独立分支 // 创建索引条目 MapString, Object entry new LinkedHashMap(); entry.put(name, name); entry.put(path, worktreePath.toString()); entry.put(branch, branch); entry.put(task_id, taskId); entry.put(status, active); entry.put(created_at, System.currentTimeMillis() / 1000.0); // 完整元数据名称、路径、分支、关联任务 // 状态管理明确的工作树生命周期状态 // 保存到索引 MapString, Object index loadIndex(); SuppressWarnings(unchecked) ListMapString, Object worktrees (ListMapString, Object) index.get(worktrees); worktrees.add(entry); saveIndex(index); // 索引管理集中式工作树元数据管理 // 持久化工作树信息持久化存储 }Git原生使用Git工作树实现真正的代码隔离自动分支为每个工作树自动创建分支元数据完整完整的工作树元数据记录持久化索引工作树信息持久化存储状态管理明确的工作树生命周期状态任务-工作树双向绑定java// 任务管理器中的工作树绑定 public String bindWorktree(int taskId, String worktree, String owner) throws IOException { MapString, Object task loadTask(taskId); task.put(worktree, worktree); // 双向绑定任务记录工作树工作树记录任务 // 关联管理建立任务和工作树的一对一关系 if (owner ! null !owner.isEmpty()) { task.put(owner, owner); } if (pending.equals(task.get(status))) { task.put(status, in_progress); // 状态自动转换绑定工作树时自动开始任务 // 工作流优化简化任务启动流程 } task.put(updated_at, System.currentTimeMillis() / 1000.0); saveTask(task); return gson.toJson(task); }java// 工作树管理器中的任务绑定 if (taskId ! null) { taskManager.bindWorktree(taskId, name, ); // 协同绑定创建工作树时自动绑定任务 // 双向同步确保任务和工作树状态一致 }双向关联任务和工作树相互引用状态协同任务和工作树状态自动同步工作流简化自动的状态转换和绑定数据一致性确保关联数据的一致性工作树操作隔离java// 在工作树中运行命令 public String runInWorktree(String name, String command) throws Exception { MapString, Object worktree findWorktree(name); Path worktreePath Paths.get((String) worktree.get(path)); try { ProcessBuilder pb new ProcessBuilder(bash, -c, command); pb.directory(worktreePath.toFile()); // 目录隔离命令在工作树的独立目录中执行 // 环境隔离每个工作树有自己的Git环境 Process process pb.start(); boolean finished process.waitFor(300, TimeUnit.SECONDS); String output new String(process.getInputStream().readAllBytes()).trim(); String error new String(process.getErrorStream().readAllBytes()).trim(); String result output (error.isEmpty() ? : \n error); return result.isEmpty() ? (no output) : result.substring(0, Math.min(result.length(), 50000)); } catch (Exception e) { return Error: e.getMessage(); } }完全隔离每个工作树是独立的文件系统目录Git环境隔离每个工作树有自己的Git配置和历史安全执行命令在隔离环境中执行结果返回返回完整的命令执行结果Git状态检查java// 获取工作树状态 public String getWorktreeStatus(String name) throws IOException { Path worktreePath Paths.get((String) worktree.get(path)); try { ProcessBuilder pb new ProcessBuilder(git, status, --short, --branch); pb.directory(worktreePath.toFile()); // Git状态获取详细的工作树Git状态 // 信息丰富包括分支信息、变更状态等 Process process pb.start(); boolean finished process.waitFor(60, TimeUnit.SECONDS); String output new String(process.getInputStream().readAllBytes()).trim(); String error new String(process.getErrorStream().readAllBytes()).trim(); String result output (error.isEmpty() ? : \n error); return result.isEmpty() ? Clean worktree : result; } catch (Exception e) { return Error: e.getMessage(); } }Git专业提供专业的Git状态信息实时状态实时检查工作树的Git状态变更追踪跟踪代码变更情况问题诊断便于诊断Git相关问题工作树生命周期管理java// 删除工作树 public String removeWorktree(String name, boolean force, boolean completeTask) throws Exception { // Git工作树删除 ListString args new ArrayList(); args.addAll(Arrays.asList(worktree, remove)); if (force) { args.add(--force); } args.add((String) worktree.get(path)); runGit(args); // Git清理使用Git命令清理工作树 // 选项支持支持强制删除等选项 // 完成任务 if (completeTask taskId ! null) { taskManager.updateTask(taskId, completed, null); taskManager.unbindWorktree(taskId); // 生命周期协同删除工作树时自动完成任务 // 状态清理清理任务和工作树的关联 MapString, Object taskEvent new HashMap(); taskEvent.put(id, taskId); taskEvent.put(subject, task.get(subject)); taskEvent.put(status, completed); eventBus.emit(task.completed, taskEvent, Map.of(name, name), null); } // 更新索引 for (MapString, Object wt : worktrees) { if (name.equals(wt.get(name))) { wt.put(status, removed); wt.put(removed_at, System.currentTimeMillis() / 1000.0); break; } } saveIndex(index); // 状态更新标记工作树为已删除状态 // 历史保留保留工作树的删除记录 }完整生命周期创建、使用、保留、删除的完整生命周期Git原生使用Git命令管理工作树任务协同工作树删除时自动处理关联任务状态管理明确的工作树状态管理历史追踪保留工作树的历史记录工作树保留机制java// 保留工作树 public String keepWorktree(String name) throws IOException { for (MapString, Object wt : worktrees) { if (name.equals(wt.get(name))) { wt.put(status, kept); wt.put(kept_at, System.currentTimeMillis() / 1000.0); keptWorktree wt; break; } } saveIndex(index); // 保留状态标记工作树为需要保留 // 不自动清理保留的工作树不会被自动清理 // 时间戳记录记录保留时间 }选择性保留可以保留有价值的工作树长期存储保留的工作树可以长期存在状态明确明确的保留状态标记时间追踪记录保留时间事件总线集成java// 事件总线 static class EventBus { public void emit(String event, MapString, Object task, MapString, Object worktree, String error) { MapString, Object payload new LinkedHashMap(); payload.put(event, event); payload.put(ts, System.currentTimeMillis() / 1000.0); payload.put(task, task ! null ? task : Map.of()); payload.put(worktree, worktree ! null ? worktree : Map.of()); if (error ! null) { payload.put(error, error); } // 结构化事件标准的事件格式 // 时间戳精确的事件时间 // 关联数据关联的任务和工作树信息 // 错误信息支持错误事件记录 String jsonLine gson.toJson(payload) \n; Files.writeString(eventLogPath, jsonLine, StandardOpenOption.CREATE, StandardOpenOption.APPEND); // JSONL格式便于流式处理和分析 // 追加写入支持长时间运行的事件记录 } }全面审计所有工作树操作都有完整的事件记录结构化日志标准化的JSON事件格式时间序列精确的时间戳序列错误追踪完整的错误事件追踪可分析性便于后续的数据分析架构演进与价值从 AutonomousAgentsSystem 到 WorktreeTaskIsolationSystem 的升级维度AutonomousAgentsSystemWorktreeTaskIsolationSystem代码隔离文件系统级Git仓库级并行开发有限并行完全并行版本控制外部集成原生集成冲突避免手动管理自动隔离专业程度通用系统专业开发系统总结完结撒花。。。总体来说这个开源网站系统性地拆解了一个高级AI编程智能体的构建过程展现了一条清晰的能力演进路径从具备基础感知和执行能力的单一智能体工具与执行发展到能够进行内部规划、分解任务、调用外部知识的协调者规划与协调再升级为可以管理资源、并行处理、支撑长时对话的高效执行者内存管理与并发最终演化为一个角色分明、通信