@zq-silk/yui 0.2.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/ARCHITECTURE.md +603 -133
- package/README.md +806 -31
- package/dist/agent/agent.js +2 -1
- package/dist/agent/argumentPolicy.js +3 -1
- package/dist/agent/launchEnvironment.js +106 -0
- package/dist/agent/managedRuntimeEnvironment.js +34 -0
- package/dist/brief/taskBrief.js +11 -1
- package/dist/cli/agentConfigurationPicker.js +287 -0
- package/dist/cli/commandCatalog.js +488 -60
- package/dist/cli/completion.js +146 -22
- package/dist/cli/helpRenderer.js +3 -1
- package/dist/cli/interactionCandidates.js +53 -15
- package/dist/cli/interactionPolicy.js +267 -30
- package/dist/cli/interactiveSelection.js +6 -2
- package/dist/cli/invocationRouter.js +5 -1
- package/dist/cli/operatorWizard.js +87 -0
- package/dist/cli/roleOptionCatalog.js +1 -0
- package/dist/cli/roleWizard.js +185 -21
- package/dist/cli/updateCommand.js +62 -19
- package/dist/cli/updateOrchestrator.js +539 -0
- package/dist/cli/updatePorts.js +1119 -0
- package/dist/cli/upgradeCommand.js +112 -0
- package/dist/cli.js +1420 -86
- package/dist/commands/agentCommands.js +146 -3
- package/dist/commands/configCommands.js +126 -0
- package/dist/commands/controllerCommands.js +365 -0
- package/dist/commands/globalRoleCommands.js +168 -126
- package/dist/commands/jobCommands.js +18 -8
- package/dist/commands/operatorCommands.js +159 -9
- package/dist/commands/profileCommands.js +203 -0
- package/dist/commands/projectCommands.js +650 -0
- package/dist/commands/roleConfiguration.js +85 -24
- package/dist/commands/roleRuntimeGuard.js +12 -0
- package/dist/commands/roleSkillValidation.js +47 -0
- package/dist/commands/taskActor.js +127 -0
- package/dist/commands/taskCommands.js +4201 -313
- package/dist/commands/taskCompletionGate.js +131 -0
- package/dist/commands/taskContextCommand.js +244 -30
- package/dist/commands/taskInputCommands.js +177 -59
- package/dist/commands/taskIntegrationCommands.js +303 -0
- package/dist/commands/taskOverviewCommand.js +363 -0
- package/dist/commands/taskRoleRuntimeStatus.js +125 -19
- package/dist/commands/textInput.js +15 -0
- package/dist/completion/completionInstaller.js +26 -22
- package/dist/config/yuiConfig.js +4 -3
- package/dist/context/dispatchContext.js +90 -38
- package/dist/context/roleSessionContext.js +119 -0
- package/dist/controller/claudeLifecycleHook.js +203 -0
- package/dist/controller/clientRuntime.js +408 -56
- package/dist/controller/codexLifecycleHook.js +108 -0
- package/dist/controller/controller.js +1089 -32
- package/dist/controller/domainIdentity.js +505 -0
- package/dist/controller/ephemeralResourceReaper.js +131 -0
- package/dist/controller/fileSchedulerStoreAdapter.js +2153 -103
- package/dist/controller/providerHookRunFence.js +127 -0
- package/dist/controller/resourceCleanupLinux.js +286 -0
- package/dist/controller/resourceInventory.js +531 -0
- package/dist/controller/resourceInventoryLinux.js +610 -0
- package/dist/controller/runtime.js +629 -10
- package/dist/controller/runtimeEventInbox.js +564 -0
- package/dist/controller/runtimeEventProcessor.js +248 -0
- package/dist/controller/runtimeLaunchCoordinator.js +477 -0
- package/dist/controller/sessionNotify.js +121 -78
- package/dist/coordination/deadlineScheduler.js +15 -0
- package/dist/coordination/mailboxScheduler.js +108 -0
- package/dist/coordination/workMailbox.js +329 -0
- package/dist/coordination/workMailboxQueue.js +86 -0
- package/dist/core/controllerClient.js +19 -5
- package/dist/core/controllerEndpoint.js +37 -0
- package/dist/core/controllerServer.js +218 -10
- package/dist/core/protocol.js +6 -2
- package/dist/decision/decision.js +2 -1
- package/dist/doctor/doctor.js +681 -32
- package/dist/domain/validation.js +53 -0
- package/dist/errors/cliError.js +5 -3
- package/dist/event/taskEvent.js +7 -3
- package/dist/execution/codexThreadNaming.js +160 -0
- package/dist/execution/executionGroup.js +579 -0
- package/dist/executor/agentAdapter.js +255 -40
- package/dist/executor/agentConfigurationCatalog.js +326 -0
- package/dist/executor/agentConfigurationProbe.js +506 -0
- package/dist/executor/agentExecutor.js +625 -10
- package/dist/executor/codexConfigConflict.js +290 -0
- package/dist/executor/effectiveLaunch.js +340 -0
- package/dist/executor/executorRegistry.js +238 -36
- package/dist/executor/fileRoleLaunchPlanner.js +550 -40
- package/dist/executor/turnCompletion.js +126 -0
- package/dist/input/inputRequest.js +30 -9
- package/dist/integration/changeSet.js +36 -0
- package/dist/integration/checkResult.js +24 -0
- package/dist/integration/gitIntegrationService.js +695 -0
- package/dist/integration/integrationAttempt.js +142 -0
- package/dist/interaction/operatorPresentation.js +96 -0
- package/dist/lifecycle/canonicalLifecycleEvent.js +342 -0
- package/dist/lifecycle/exactRunTerminalization.js +572 -0
- package/dist/lifecycle/providerLifecycleMapping.js +190 -0
- package/dist/lifecycle/taskRoleSessionReset.js +124 -0
- package/dist/message/message.js +23 -7
- package/dist/milestone/milestone.js +2 -1
- package/dist/operator/operatorSessionHistory.js +124 -0
- package/dist/output/agentConfigurationPresentation.js +43 -0
- package/dist/output/rolePresentation.js +34 -10
- package/dist/output/terminal.js +8 -0
- package/dist/output/timePresentation.js +55 -0
- package/dist/profile/agentProfile.js +128 -0
- package/dist/repository/gitWorkspace.js +578 -24
- package/dist/repository/project.js +213 -0
- package/dist/repository/taskWorkspaceCoordinator.js +392 -0
- package/dist/repository/taskWorkspacePreparer.js +1688 -191
- package/dist/review/reviewConfig.js +11 -0
- package/dist/review/reviewRound.js +399 -0
- package/dist/review/taskFinalReviewContract.js +90 -0
- package/dist/role/role.js +124 -23
- package/dist/run/agentRun.js +155 -12
- package/dist/run/runIdentity.js +82 -0
- package/dist/runtime/exactControlPlane.js +472 -0
- package/dist/runtime/index.js +8 -0
- package/dist/runtime/lifecycleReservation.js +38 -0
- package/dist/runtime/ports.js +11 -0
- package/dist/runtime/preallocatedNativeSession.js +13 -0
- package/dist/runtime/promptEnvelope.js +30 -0
- package/dist/runtime/runtimeBinding.js +31 -0
- package/dist/runtime/runtimeOwner.js +14 -0
- package/dist/runtime/sessionLaunchRequest.js +62 -0
- package/dist/runtime/sessionTitle.js +54 -0
- package/dist/runtime/taskRuntimeIsolation.js +643 -0
- package/dist/runtime/tmuxAdapters.js +315 -0
- package/dist/runtime/turnCompletion.js +3 -0
- package/dist/runtime/validation.js +23 -0
- package/dist/scheduler/activeRoleRunDelivery.js +342 -32
- package/dist/scheduler/activeTaskProgress.js +63 -0
- package/dist/scheduler/leaderFailure.js +2 -1
- package/dist/scheduler/leaderWakeupProcessor.js +307 -66
- package/dist/scheduler/operatorInputNotificationProcessor.js +109 -46
- package/dist/scheduler/operatorNotification.js +44 -2
- package/dist/scheduler/ports.js +28 -1
- package/dist/scheduler/roleRunLiveness.js +131 -25
- package/dist/scheduler/roleRunStall.js +951 -0
- package/dist/scheduler/taskExecutionProjection.js +544 -0
- package/dist/scheduler/wakeupQueue.js +3 -0
- package/dist/setup/setupCommand.js +302 -52
- package/dist/storage/compatibleTaskStore.js +102 -0
- package/dist/storage/migration/baseline.js +78 -0
- package/dist/storage/migration/classifier.js +51 -0
- package/dist/storage/migration/compatibleCodec.js +53 -0
- package/dist/storage/migration/engine.js +147 -0
- package/dist/storage/migration/index.js +33 -0
- package/dist/storage/migration/planner.js +154 -0
- package/dist/storage/migration/productionRegistry.js +486 -0
- package/dist/storage/migration/registry.js +169 -0
- package/dist/storage/migration/report.js +54 -0
- package/dist/storage/migration/types.js +31 -0
- package/dist/storage/storageSchema.js +147 -123
- package/dist/storage/storageVersions.js +11 -0
- package/dist/storage/taskStore.js +1793 -197
- package/dist/storage/upgrade/homeClassification.js +156 -0
- package/dist/storage/upgrade/homeMigrationTarget.js +595 -0
- package/dist/storage/upgrade/offlineUpgradeInventory.js +315 -0
- package/dist/storage/upgrade/productionMigrationRegistry.js +6 -0
- package/dist/storage/upgrade/recordVersionScan.js +176 -0
- package/dist/storage/upgrade/recordVersions.js +159 -0
- package/dist/storage/upgrade/switchProgress.js +80 -0
- package/dist/storage/upgrade/upgradeOrchestrator.js +948 -0
- package/dist/storage/upgrade/upgradeReceipt.js +161 -0
- package/dist/storage/upgradeCoordination.js +186 -0
- package/dist/storage/upgradeFence.js +366 -0
- package/dist/task/task.js +132 -26
- package/dist/task/taskRecordReference.js +66 -0
- package/dist/tmux/commandExecutor.js +75 -2
- package/dist/tmux/tmuxManager.js +747 -49
- package/dist/version.js +23 -0
- package/dist/web/assets/assetManifest.js +62 -0
- package/dist/web/assets/client/app.js +631 -0
- package/dist/web/assets/client/components.js +605 -0
- package/dist/web/assets/client/dom.js +14 -0
- package/dist/web/assets/client/format.js +28 -0
- package/dist/web/assets/client/i18n.js +494 -0
- package/dist/web/assets/client/markdown.js +114 -0
- package/dist/web/assets/client/theme.js +32 -0
- package/dist/web/assets/client/view.js +458 -0
- package/dist/web/assets/fontData.js +12 -0
- package/dist/web/assets/fonts.js +12 -0
- package/dist/web/assets/shell.js +114 -0
- package/dist/web/assets/styles/cards.js +135 -0
- package/dist/web/assets/styles/layout.js +47 -0
- package/dist/web/assets/styles/markdown.js +29 -0
- package/dist/web/assets/styles/responsive.js +39 -0
- package/dist/web/assets/styles/tokens.js +101 -0
- package/dist/web/assets/styles/widgets.js +147 -0
- package/dist/web/tmuxWebTerminal.js +158 -0
- package/dist/web/webServer.js +463 -0
- package/dist/web/webSnapshot.js +148 -0
- package/dist/workItem/workItem.js +642 -23
- package/dist/workspace/gitChangeSetCapture.js +86 -0
- package/dist/workspace/workItemChangeSetManager.js +445 -0
- package/dist/worktree/managedWorkspace.js +202 -0
- package/docs/task-local-identity.md +62 -0
- package/i18n/README.zh-CN.md +406 -31
- package/package.json +10 -2
- package/skills/yui-leader/SKILL.md +601 -39
- package/skills/yui-operator/SKILL.md +255 -34
- package/skills/yui-reviewer/SKILL.md +57 -0
- package/skills/yui-worker/SKILL.md +214 -17
- package/dist/commands/repositoryCommands.js +0 -86
- package/dist/operator/operatorContext.js +0 -66
- package/dist/repository/repository.js +0 -55
- package/dist/scheduler/archivedTaskRuntime.js +0 -12
- package/dist/worktree/roleWorkspace.js +0 -62
package/i18n/README.zh-CN.md
CHANGED
|
@@ -2,9 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
# Yui
|
|
4
4
|
|
|
5
|
-
Yui
|
|
5
|
+
Yui 是面向持久 Codex/Claude 工作的本地控制平面。用户只需和 Operator
|
|
6
|
+
对话;Operator 将不同 Project 的需求、Bug、审查和问题咨询路由到对应
|
|
7
|
+
Task,Leader 再负责拆解、执行选择、验收和安全集成。
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
当前实现保留实用的 Role/Agent/session 与 CLI 框架,不恢复后期膨胀的数据维护、租约、定时调度和恢复账本体系。
|
|
10
|
+
|
|
11
|
+
## 核心模型
|
|
12
|
+
|
|
13
|
+
- `WorkItem`:唯一的有界工作单元,保存目标、验收条件、依赖、状态和精简结果。
|
|
14
|
+
- `WorkerProfile`:可复用且与 provider 无关的行为模板,保存指令、Skill、访问要求及可选 model/effort hint。
|
|
15
|
+
- `TaskRole`:Task 内可修改的 Worker 实例,可绑定多个 Agent,并分别保存运行配置。
|
|
16
|
+
- `AgentRun`:Task Role 的一次受管派发与结果交付。
|
|
17
|
+
- `ChangeSet`:隔离 WorkItem 当前 HEAD 的不可变 Git 结果。
|
|
18
|
+
- Integration:候选集成、检查、冲突报告和 Leader 决策。
|
|
19
|
+
|
|
20
|
+
每个 WorkItem 只选择三条路径之一:Leader 直接执行、Leader 在当前
|
|
21
|
+
Agent 对话内创建 native subagent,或交给 Task Role AgentRun。Yui
|
|
22
|
+
不提供 subagent 启动命令,也不创建 child Session 记录。
|
|
23
|
+
|
|
24
|
+
内置 Profile:
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
worker explorer implementer reviewer
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Profile 不绑定 Agent,也不持有 Session 或 workspace。Operator、Leader
|
|
31
|
+
与 Task Role 是运行时 Role。
|
|
8
32
|
|
|
9
33
|
## 环境要求
|
|
10
34
|
|
|
@@ -21,7 +45,24 @@ yui setup
|
|
|
21
45
|
yui doctor
|
|
22
46
|
```
|
|
23
47
|
|
|
24
|
-
`setup` 是交互式的:检测已安装的 Agent CLI
|
|
48
|
+
`setup` 是交互式的:检测已安装的 Agent CLI,选择要配置的 Agent、默认
|
|
49
|
+
Agent 和 Operator Agent,并实时探测所选 CLI 当前支持的模型。它先配置
|
|
50
|
+
Leader 和 Operator,再说明全局 Worker 配置会复制到新建的 Task Role,
|
|
51
|
+
让用户选择 Worker 复用 Leader 配置还是单独配置。模型选择后只展示该模型
|
|
52
|
+
支持的思考强度。随后 setup 会确认位于 Yui home 外部的 Project workspace,
|
|
53
|
+
并询问 shell completion。选择器同时提供原生 CLI 默认值和自定义值入口。
|
|
54
|
+
再次运行不会删除已有 Task/Role,也不会改变当前安装的 Project workspace,
|
|
55
|
+
可用于安全地调整配置。
|
|
56
|
+
|
|
57
|
+
模型与思考强度属于 Agent binding 设置,因此 Operator、Leader 和全局
|
|
58
|
+
Worker 即使使用同一个 Agent CLI,也可以采用不同配置。Profile 中的
|
|
59
|
+
model/effort 只是 native child 的可移植 hint。
|
|
60
|
+
|
|
61
|
+
Setup 会为每个受管 Agent binding 显式设置 `bypass` permission strategy。
|
|
62
|
+
后续 Role 更新可选择 `default`、`bypass` 或 `configured`;`configured` 会
|
|
63
|
+
保留对应 adapter 的原生权限枚举与工具规则。
|
|
64
|
+
|
|
65
|
+
运行时能力目录会在每次命令中刷新,并缓存在 Yui home。实时探测超时或失败时,Yui 会展示同一 Agent 启动上下文最近一次成功的缓存并明确提示数据可能过期;没有匹配缓存时,则提供 CLI 默认值和自定义入口。`yui agent capabilities <id>` 可一次性读取同一份目录,包括模型、逐模型思考强度,以及权限、搜索可用性、profile、settings source、service tier 等其他运行时选项。
|
|
25
66
|
|
|
26
67
|
`completion` 无论是否指定 shell,都会进入确认流程:
|
|
27
68
|
|
|
@@ -39,15 +80,29 @@ export YUI_HOME=/absolute/path/to/yui-home
|
|
|
39
80
|
yui setup
|
|
40
81
|
```
|
|
41
82
|
|
|
42
|
-
home 中包含 `schema.json`、权威 `state.json`、Controller
|
|
83
|
+
home 中包含 `schema.json`、权威 `state.json`、Project Catalog、项目知识和 Controller 发现文件。稳定 Project checkout 与受管理 worktree 位于 home 外部的 workspace。运行时存储严格匹配且 fresh-only:不会双读旧 schema,也不会猜测旧 ID。
|
|
84
|
+
|
|
85
|
+
所有 Task-owned 记录族都在各自 Task 内分配单调递增的本地 ID。因此,不同
|
|
86
|
+
Task 可以同时拥有 `work-item-1`、`agent-run-1` 或 `input-1`。受管 Task
|
|
87
|
+
session 可由 `YUI_TASK_ID` 提供作用域并使用本地短 ID;Task session 外必须
|
|
88
|
+
使用 `<task-id>/<local-id>`。Yui 不会拿裸 ID 扫描所有 Task。已经显式接收
|
|
89
|
+
Task 的命令(例如 `task work create`、`task integration start`)仍使用该
|
|
90
|
+
Task 内的本地子记录 ID。Candidate 只在所属 WorkItem 内递增,并同时保存
|
|
91
|
+
Task 与 WorkItem provenance。
|
|
92
|
+
|
|
93
|
+
Yui 只支持当前 aggregate-v14 / StoredTask-v13 schema。旧 home 不提供转换、
|
|
94
|
+
双读或历史记录推断;需要使用新版本时初始化全新的 `YUI_HOME`。当前引用契约见
|
|
95
|
+
[Task 本地 ID](../docs/task-local-identity.md)。
|
|
43
96
|
|
|
44
97
|
## 快速开始
|
|
45
98
|
|
|
46
99
|
```sh
|
|
47
|
-
yui
|
|
48
|
-
|
|
100
|
+
yui project add app /absolute/workspace/app \
|
|
101
|
+
--remote git@example.com:team/app.git --stable main --development develop
|
|
102
|
+
yui project update app --alias app-cli --development develop
|
|
103
|
+
yui project list
|
|
49
104
|
|
|
50
|
-
yui task create "交付 CSV 导出" --
|
|
105
|
+
yui task create "交付 CSV 导出" --project app
|
|
51
106
|
yui task update <task-id> --priority high --tags release,csv --due-at 2026-08-01T00:00:00Z
|
|
52
107
|
yui task update <task-id> --clear-priority --clear-tags --clear-due-at
|
|
53
108
|
yui task show <task-id>
|
|
@@ -55,37 +110,286 @@ yui task context <task-id>
|
|
|
55
110
|
yui task activate <task-id>
|
|
56
111
|
```
|
|
57
112
|
|
|
113
|
+
面向用户的时间默认按北京时间(`Asia/Shanghai`)显示;持久化记录和
|
|
114
|
+
`--json` 数据仍使用 UTC/RFC 3339。可通过以下命令查看或修改 IANA 时区:
|
|
115
|
+
|
|
116
|
+
```sh
|
|
117
|
+
yui config show
|
|
118
|
+
yui config set --time-zone Europe/London
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
WorkItem 审查只有一条可选的全局规则,并直接复用已有 Global Role 的
|
|
122
|
+
Agent、model、权限、prompt 和 Skills:
|
|
123
|
+
|
|
124
|
+
```sh
|
|
125
|
+
yui config review set --role reviewer --trigger always
|
|
126
|
+
yui config review show
|
|
127
|
+
yui config review clear
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
对带 Project 的软件交付,可使用 `--trigger final`:WorkItem 验收与
|
|
131
|
+
Integration 保持独立,在 Task 完成前只对所有已集成 Project 的冻结候选做
|
|
132
|
+
一次 Task 级 ReviewRound:
|
|
133
|
+
|
|
134
|
+
```sh
|
|
135
|
+
yui config review set --role reviewer --trigger final
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
每个进入 Leader 验收阶段的结果,都会成为原 WorkItem 上一个明确的候选。
|
|
139
|
+
当前全局规则对所有新旧 Task 的下一个候选生效,并在候选提交时形成快照;
|
|
140
|
+
后续 `set`/`clear` 不会改变已经在途的判断。
|
|
141
|
+
`always` 会为每个候选启动 ReviewRound,包括 Role yield 的结果和 Leader 直接管理的
|
|
142
|
+
结果;`leader` 则让候选保持等待验收,由 Leader 直接 accept 或执行
|
|
143
|
+
`yui task work review <task-id>/<work-item-id>`。因此只要配置了审查规则,Leader
|
|
144
|
+
管理的候选也不会直接标记为完成。ReviewRound 引用不可变候选,审查
|
|
145
|
+
AgentRun 不创建新 WorkItem,也不会递归触发审查。审查以自然语言结果
|
|
146
|
+
唤醒 Leader;Leader 决定验收、reject 后在原 Role 与原 Session 中修复、
|
|
147
|
+
再次审查,或通过 InputRequest 询问用户。审查失败会保留为可见证据并
|
|
148
|
+
唤醒 Leader,但不会取代 Leader 的最终判断。
|
|
149
|
+
`final` 不为每个 WorkItem 创建完整 ReviewRound;`task complete` 会在每个绑定
|
|
150
|
+
Project 都有 committed Integration 后排队一次 Task 级 Review。冻结的集成头
|
|
151
|
+
发生变化时才会重新排队,旧报告仍保留为证据。Reviewer 按 Project Policy/Knowledge
|
|
152
|
+
检查整个 Task,并只报告有直接证据的可达、重要、可行动问题或有限验证缺口。
|
|
153
|
+
所有候选、ReviewRound 和 Leader 决策都集中在原 WorkItem 下;reject
|
|
154
|
+
后的下一轮会复用原执行 Role、Session 与 workspace,并追加新候选。
|
|
155
|
+
|
|
58
156
|
查看已有 Task 的详细状态时,优先使用 `task context`。它一次聚合 Task、Brief、Active Decision、最近的 Milestone、Role、当前及最近的 WorkItem 与关联 Run、最近的 Message、Open/Resolved InputRequest 和 Event。终端输出会精简历史和长文本;`yui --json task context <task-id>` 会在顶层 `data` 中返回完整记录。
|
|
59
157
|
|
|
60
|
-
|
|
158
|
+
Task identity 由一个有界交付目标决定,而不是由涉及几个仓库决定。带仓库的
|
|
159
|
+
Task 可以绑定多个 Project,并为每个 Project 记录独立 base ref:
|
|
160
|
+
|
|
161
|
+
```text
|
|
162
|
+
<workspace>/tasks/<task-id>/main/
|
|
163
|
+
├── backend/
|
|
164
|
+
├── frontend/
|
|
165
|
+
└── shared-sdk/
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
`<workspace>/tasks/<task-id>/main` 是逻辑上的多 Project 容器,不是 Git 仓库。
|
|
169
|
+
每个 Project 子目录才是受支持的 Git cwd(例如
|
|
170
|
+
`<workspace>/tasks/<task-id>/main/yui`),并指向该 Project 的受管 worktree:
|
|
171
|
+
`<workspace>/worktree/<project>/<task-id>/main`。Git 命令必须在对应的
|
|
172
|
+
Project 子目录中运行。只绑定一个 Project 时,原生 Agent 直接从该 Project
|
|
173
|
+
的受管 worktree 启动,因此会按 Agent 自身机制发现项目配置和 Skills。
|
|
174
|
+
绑定多个 Project 时,Agent
|
|
175
|
+
从逻辑根目录启动,Yui 通过 Provider 原生的 additional-directory 机制声明
|
|
176
|
+
每个 Project worktree。创建时应一次绑定已知 Project;如果同一目标在执行中
|
|
177
|
+
确认还需要另一个仓库,只能由 active Task 的 Leader 追加:
|
|
178
|
+
|
|
179
|
+
```sh
|
|
180
|
+
yui task create "升级认证协议" \
|
|
181
|
+
--project backend --project frontend \
|
|
182
|
+
--base backend=develop --base frontend=main
|
|
183
|
+
yui task project add <task-id> shared-sdk --base main
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
实现型 WorkItem 必须声明允许修改的 Project。它保留与 Task main 一致的
|
|
187
|
+
相对目录布局,只为写入范围创建隔离 worktree,其他 Task Project 作为上下文
|
|
188
|
+
从 Task main 暴露。Yui 会在受管派发和 `yui-worker` Skill 中明确列出可写与
|
|
189
|
+
仅上下文 Project,由 Agent 严格遵守该边界。原生 Agent 权限作用于整个会话,
|
|
190
|
+
而 Profile `access` 只是行为意图,不是 provider sandbox 或写入授权。所有受管 Role binding(包括
|
|
191
|
+
`explorer`)默认使用 `permission.strategy=bypass`,避免 provider 权限提示阻塞
|
|
192
|
+
正常工作;Profile 与 Skill 负责约束行为,只有精确 WorkItem/ReviewRound 范围
|
|
193
|
+
和匹配的 managed workspace 才能授权修改 Project。Role 也可以显式选择
|
|
194
|
+
`default`,或用 `configured` 保留显式设置的任意 provider 原生权限选项子集。
|
|
195
|
+
|
|
196
|
+
写入范围只能扩大,不能缩小。Worker yield 并报告还需要另一个仓库后,
|
|
197
|
+
Leader 使用完整的“旧范围 + 新范围”更新并重新派发:
|
|
198
|
+
|
|
199
|
+
```sh
|
|
200
|
+
yui task work create <task-id> "升级协议与客户端" \
|
|
201
|
+
--project backend --project frontend --role implementer
|
|
202
|
+
yui task work scope <task-id>/<work-item-id> \
|
|
203
|
+
--project backend --project frontend --project shared-sdk
|
|
204
|
+
yui task work isolate <task-id>/<work-item-id>
|
|
205
|
+
yui task work reject <task-id>/<work-item-id> \
|
|
206
|
+
--summary "已扩大写入范围,请在刷新后的 workspace 继续。"
|
|
207
|
+
yui task work dispatch <task-id>/<work-item-id>
|
|
208
|
+
yui task work capture <task-id>/<work-item-id>
|
|
209
|
+
yui task integration start <task-id> --project backend \
|
|
210
|
+
--change-set <backend-change-set-id> --check "<validation command>"
|
|
211
|
+
yui task integration cleanup <task-id>/<integration-id>
|
|
212
|
+
yui task work cleanup <task-id>/<work-item-id> --integrated
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
`capture` 为每个实际修改的 Project 记录一个不可变 ChangeSet;同一 HEAD
|
|
216
|
+
重复 capture 会复用记录,修复后的新 HEAD 会产生新候选。Integration 保持
|
|
217
|
+
单 Project Git 事务,所以 Leader 分别集成每个 Project。只有所有已修改
|
|
218
|
+
Project 的最新候选都完成集成,WorkItem 才能验收;仍有未集成结果时不能执行
|
|
219
|
+
`--integrated` 清理。`--abandon` 只用于明确放弃,dirty worktree 会原地保留。
|
|
220
|
+
原生 Agent Session 可能绑定启动目录,因此 Role 在 Task main 与隔离
|
|
221
|
+
WorkItem workspace 之间移动时,Yui 会退役已停止的旧 Session;下一次派发
|
|
222
|
+
在新目录创建 Session,持久 Yui 记录继续提供上下文。
|
|
61
223
|
|
|
62
224
|
通过 Operator 提交消息:
|
|
63
225
|
|
|
64
226
|
```sh
|
|
65
227
|
yui operator submit "比较 CSV 与 JSON 的兼容性" --task <task-id>
|
|
66
228
|
yui operator submit "研究更小的缓存设计"
|
|
229
|
+
yui operator list
|
|
230
|
+
yui operator resume
|
|
231
|
+
yui operator resume --last
|
|
232
|
+
yui operator new
|
|
67
233
|
yui operator enter
|
|
68
234
|
```
|
|
69
235
|
|
|
236
|
+
当 Task Role 当前的原生 Session 无法继续时,只需按意图重置:
|
|
237
|
+
|
|
238
|
+
```sh
|
|
239
|
+
yui task role reset <task-id> <role> --reason "<该 generation 无法继续的原因>"
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Yui 从自己的记录中推导当前 Run、Agent、launch、receipt 和 native Session。
|
|
243
|
+
它只失败化该精确 active Run(以及对应 execution WorkItem),把当前 Session
|
|
244
|
+
保存为 broken history,并要求 Controller 只停止该 Role 拥有的 runtime。该命令
|
|
245
|
+
不会创建 Candidate、验收工作或完成 Task。cleanup pending 期间,`task role status`
|
|
246
|
+
和 `task context` 会阻止 fresh launch;已有 message、review 和交付历史都会保留。
|
|
247
|
+
|
|
70
248
|
不带 `--task` 时会创建新 Draft。Draft 可以继续规划,但激活前不会执行 Agent 工作。
|
|
249
|
+
Operator 会结合 Project Catalog 和现有 Task context 路由请求。同一有界
|
|
250
|
+
目标的追加需求、修复、审查和咨询继续进入原 Task,即使它涉及多个 Project。
|
|
251
|
+
目标、所有权边界或生命周期独立时才创建新 Task。需求、Bug 和咨询共用同一
|
|
252
|
+
Task/WorkItem 模型,不增加额外任务类型。
|
|
253
|
+
`operator list` 按固定的最近更新时间倒序展示历史对话,并显示 Agent
|
|
254
|
+
及可读的标题或摘要;底层 provider session ID 始终保持内部实现细节。
|
|
255
|
+
若 adapter 尚未提供这些元数据,Yui 会显示 provider 和稳定的 Yui
|
|
256
|
+
短引用,确保无标题会话仍可区分。`operator resume` 使用同一个轻量编号列表,
|
|
257
|
+
`--last` 可直接恢复最近一条;
|
|
258
|
+
`operator new` 创建空白对话,并把原对话保留在历史中。
|
|
259
|
+
|
|
260
|
+
从已配置的全局 Worker 创建 Task Role,应用 Profile 并派发 WorkItem:
|
|
261
|
+
|
|
262
|
+
```sh
|
|
263
|
+
yui role show worker
|
|
264
|
+
yui task role add <task-id> implementer --profile implementer
|
|
265
|
+
yui task role show <task-id> implementer
|
|
266
|
+
|
|
267
|
+
yui task work create <task-id> "实现导出器" \
|
|
268
|
+
--project app --role implementer
|
|
269
|
+
yui task work isolate <task-id>/<work-item-id>
|
|
270
|
+
yui task work dispatch <task-id>/<work-item-id> --input "完成实现并运行聚焦测试"
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
每个 Agent binding 只有一套 adapter-specific 权限枚举配置:`default` 遵循
|
|
274
|
+
provider 默认行为;`bypass` 编译 provider 支持的 bypass flag;`configured`
|
|
275
|
+
保留其中显式设置的原生选项。Codex 选项是 `sandbox` 和 `approval`;Claude 选项是
|
|
276
|
+
`mode`、`allowedTools` 与 `disallowedTools`。provider 权限与 Profile 行为意图、
|
|
277
|
+
Project 写入授权彼此独立:普通写入只由精确 WorkItem 范围和匹配的 managed
|
|
278
|
+
workspace 授权。任意非 Leader
|
|
279
|
+
Task Role 在创建时不传 `--agent`,都会复制全局 Worker Role 的完整 Agent
|
|
280
|
+
bindings,Leader 无需重新拼接 model、effort 和权限。创建回执与
|
|
281
|
+
`task context` 分别记录 Profile intent、精确可写 Project 与实际 permission strategy。显式
|
|
282
|
+
`--agent` 属于 Task 专用覆盖,必须在派发前补全并回读配置。
|
|
283
|
+
|
|
284
|
+
ReviewRound 从冻结 Candidate SHA 创建独立的可写 worktree。只有 exact
|
|
285
|
+
ReviewRound owner、reviewRoundId、冻结 base 与 workspace 全部匹配时,才获得
|
|
286
|
+
该 workspace 的写入授权;Skill 仍禁止 push、Integration、Task state、其他
|
|
287
|
+
workspace 与真实 YUI_HOME 变更。两种 provider 都必须直接执行当前 Run 的 exact
|
|
288
|
+
stdin yield;最终回复本身不是持久交付。review yield 的 stdin 保存 Reviewer
|
|
289
|
+
完整的自由格式 Markdown 或 JSON 报告。如果 JSON 含已知的 `checks` 或
|
|
290
|
+
`evidenceCommit` 字段,Yui 会把它们记录为结构化证据,并核验 commit 是否等于
|
|
291
|
+
managed Review branch HEAD;未知字段仍保留在完整报告中:
|
|
292
|
+
|
|
293
|
+
```sh
|
|
294
|
+
yui task run yield <task-id>/<review-run-id> --summary-file - <<'YUI_SUMMARY'
|
|
295
|
+
{"summary":"复现并验证完成","checks":[{"name":"npm test","outcome":"passed","details":"全部通过"}],"evidenceCommit":"<exact-sha>"}
|
|
296
|
+
YUI_SUMMARY
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Reviewer 可以修改文件并在不提交的情况下 yield;脏字节不会被推断为 evidence。
|
|
300
|
+
该 Round 仍会精确终结且不产生 Candidate/ChangeSet,workspace 会为 Leader 判断而
|
|
301
|
+
保留,cleanup 会在其重新变干净前拒绝删除。
|
|
302
|
+
|
|
303
|
+
Worker 显式交付当前 Run:
|
|
304
|
+
|
|
305
|
+
```sh
|
|
306
|
+
yui task run yield <task-id>/<run-id> --summary-file - <<'YUI_SUMMARY'
|
|
307
|
+
导出器已完成,聚焦测试通过
|
|
308
|
+
YUI_SUMMARY
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
yield 会结束 AgentRun,将 WorkItem 提交给 Leader 审查,并追加结果消息和
|
|
312
|
+
唤醒 Leader;它不会验收或完成 WorkItem。Leader 不会自唤醒,pending wake
|
|
313
|
+
会保留到 Leader 空闲。
|
|
314
|
+
|
|
315
|
+
如果无法最终判断结果,交接必须明确标为 `uncertain`、`incomplete`、
|
|
316
|
+
`blocked` 或 `requiring Leader judgment`,并提交最完整且真实的身份、已执行
|
|
317
|
+
动作、仓库状态、检查与错误、最后生命周期边界、未完成工作、待决事项、风险、
|
|
318
|
+
置信度及有界下一选项。yield 只记录不可变的 Run/Candidate 或 Review 证据;
|
|
319
|
+
它不表示验收、WorkItem 完成、ChangeSet capture、Integration 或 Task 完成。
|
|
320
|
+
|
|
321
|
+
对于有界工作,Leader 可以直接执行 roleless WorkItem,也可以在当前
|
|
322
|
+
Agent 对话中创建 native subagent:
|
|
323
|
+
|
|
324
|
+
```sh
|
|
325
|
+
yui task work create <task-id> "审查实现" \
|
|
326
|
+
--objective "返回有源码依据的问题" \
|
|
327
|
+
--accept "每个问题都标明受影响路径"
|
|
328
|
+
yui task work update <task-id>/<work-item-id> running
|
|
329
|
+
yui profile show reviewer
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
subagent 的创建与结果返回完全由 Leader 当前 Agent 的 native child 能力
|
|
333
|
+
完成,没有 `yui ... subagent` 命令。Leader 必须选择并读取一个显式
|
|
334
|
+
Worker Profile;没有合适的专用 Profile 时使用 `worker`。child brief
|
|
335
|
+
需要包含 Profile revision、instructions、Skills、访问边界、验证要求及
|
|
336
|
+
当前 runtime 支持的 model/effort hint。
|
|
337
|
+
|
|
338
|
+
native subagent 继承 Leader Agent、凭据和对话上下文,忽略 Task Role 的
|
|
339
|
+
Agent bindings。Leader 审查返回结果后,在 WorkItem summary 中登记真实
|
|
340
|
+
执行信息:
|
|
341
|
+
|
|
342
|
+
```sh
|
|
343
|
+
yui task work update <task-id>/<work-item-id> done \
|
|
344
|
+
--summary "executor=subagent; profile=reviewer@3; model=inherited; round=1; result=reviewed; checks=npm test passed"
|
|
345
|
+
```
|
|
71
346
|
|
|
72
|
-
|
|
347
|
+
无法确认实际 model/effort 时使用 `inherited` 或 `unknown`,不能猜测。
|
|
348
|
+
需要独立 provider、凭据、交互 Session 或持久生命周期时,使用 Task Role
|
|
349
|
+
AgentRun。
|
|
350
|
+
|
|
351
|
+
隔离 Task Role 的结果按“Worker yield → Leader 语义审查 → capture 当前
|
|
352
|
+
HEAD → candidate 集成和检查 → Leader accept”的顺序处理。审查不通过时,
|
|
353
|
+
Leader reject 并在同一 workspace 重新派发。相同 HEAD 重复 capture 复用
|
|
354
|
+
原 ChangeSet;修复后的新 HEAD 形成新候选:
|
|
73
355
|
|
|
74
356
|
```sh
|
|
75
|
-
yui task
|
|
76
|
-
yui task
|
|
357
|
+
yui task work reject <task-id>/<work-item-id> --summary "需要修复的具体问题"
|
|
358
|
+
yui task work dispatch <task-id>/<work-item-id> --input "结合上一轮结果修复"
|
|
359
|
+
yui task work capture <task-id>/<work-item-id>
|
|
360
|
+
yui task integration start <task-id> \
|
|
361
|
+
--change-set <latest-change-set-id> --check "npm test"
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
Integration 只保存紧凑检查结果和失败诊断。完整 stdout/stderr 流式写入
|
|
365
|
+
`YUI_HOME/artifacts/integration-checks/...`;`task integration show`
|
|
366
|
+
展示相对日志路径,cleanup 同时清理候选 worktree 和日志。
|
|
367
|
+
|
|
368
|
+
代码或语义冲突会保持 blocked,直到该 Task 的 Leader 记录决策:
|
|
77
369
|
|
|
78
|
-
|
|
79
|
-
yui task
|
|
370
|
+
```sh
|
|
371
|
+
yui task integration resolve <task-id>/<integration-id> \
|
|
372
|
+
--option manual-resolution \
|
|
373
|
+
--rationale "保留公开契约并组合两边实现"
|
|
374
|
+
yui task integration continue <task-id>/<integration-id>
|
|
80
375
|
```
|
|
81
376
|
|
|
82
|
-
Worker
|
|
377
|
+
Worker yield 不等于 WorkItem 完成。Leader 审查结果、验证和最新
|
|
378
|
+
ChangeSet 集成后再显式验收:
|
|
83
379
|
|
|
84
380
|
```sh
|
|
85
|
-
yui task
|
|
381
|
+
yui task work accept <task-id>/<work-item-id> --summary "验收标准满足。"
|
|
86
382
|
```
|
|
87
383
|
|
|
88
|
-
|
|
384
|
+
使用 `task work reject` 退回待验收结果以便修复和重新派发,使用
|
|
385
|
+
`task work retire <task>/<work> --summary "..."` 退役过时工作,并可选指定
|
|
386
|
+
replacement。WorkItem、Integration
|
|
387
|
+
worktree 与检查日志会作为证据保留,直到显式清理。
|
|
388
|
+
|
|
389
|
+
长期 Task 不依赖 native transcript 恢复。Leader 每次 yield 前更新 Brief
|
|
390
|
+
的 focus 和 leader summary;材料性技术选择写入 Decision;可独立汇报的
|
|
391
|
+
阶段成果写入 Milestone;只有跨 Task 稳定有效的信息才进入 Project
|
|
392
|
+
Knowledge。
|
|
89
393
|
|
|
90
394
|
当活动 Leader Run 必须获得用户决定才能继续时,可以创建持久 InputRequest,并 yield 当前 Run:
|
|
91
395
|
|
|
@@ -93,8 +397,8 @@ yield 会原子完成 Run 和 WorkItem、追加结果消息并唤醒 Leader。Le
|
|
|
93
397
|
yui task input request <task-id> --question "默认使用哪种格式?" \
|
|
94
398
|
--choice csv="CSV" --choice json="JSON" --blocks work-item:<work-item-id>
|
|
95
399
|
yui task input list
|
|
96
|
-
yui task input show <input-id>
|
|
97
|
-
yui task input answer <input-id> --choice csv
|
|
400
|
+
yui task input show <task-id>/<input-id>
|
|
401
|
+
yui task input answer <task-id>/<input-id> --choice csv
|
|
98
402
|
```
|
|
99
403
|
|
|
100
404
|
请求默认必须由用户回答,并保持开放直到回答或取消。当 Agent 存在安全的推荐方案时,可以为选项设置明确的超时回退:
|
|
@@ -105,9 +409,9 @@ yui task input request <task-id> --question "默认使用哪种格式?" \
|
|
|
105
409
|
--recommend csv --timeout-seconds 300
|
|
106
410
|
```
|
|
107
411
|
|
|
108
|
-
|
|
412
|
+
推荐项会明确展示给用户;如果截止时间前没有回答,独立的最近 deadline timer 会唤醒 Controller,原子采用这个确定选项,并排队恢复固定的 Leader session。自由文本和必须由用户回答的请求永远不会自动解决。
|
|
109
413
|
|
|
110
|
-
`task input list` 是权威的全局开放输入 Inbox;可附加 Task ID 限定范围,或使用 `--all` 查看已回答和已取消的请求。Controller
|
|
414
|
+
`task input list` 是权威的全局开放输入 Inbox;可附加 Task ID 限定范围,或使用 `--all` 查看已回答和已取消的请求。Controller 还会尝试向已有且结构化状态为 ready 的 Operator process 投递一次带回执的提示;它不会为了通知而启动或打断 Operator。process 不可用或 pane fence 已变化时,请求仍保留在 Inbox,并在后续 Controller 定向处理中重新尝试。该路径不会读取或分类 Agent 终端文本。用户和 Operator 都可回答。存在开放请求时,无关的 pending wake 不会绕过等待,Task 也不能 complete 或 archive。原 Leader 也可执行 `yui task input cancel <task-id> <input-id> --reason "..."`,取消会排队恢复该固定 Leader session。
|
|
111
415
|
|
|
112
416
|
```sh
|
|
113
417
|
yui task context <task-id>
|
|
@@ -115,19 +419,23 @@ yui task context <task-id>
|
|
|
115
419
|
|
|
116
420
|
需要查看单个集合或记录时,再使用 `task work`、`task message`、`task run` 和 Task Knowledge 下的细分命令。
|
|
117
421
|
|
|
118
|
-
完成目标后,可将 Task 标记为 completed,从而停止自动唤醒,同时保留 session
|
|
422
|
+
完成目标后,可将 Task 标记为 completed,从而停止自动唤醒,同时保留 session 和 Task main worktree:
|
|
119
423
|
|
|
120
424
|
```sh
|
|
121
425
|
yui task complete <task-id> --summary "CSV 导出已交付并验证"
|
|
122
426
|
yui task reopen <task-id>
|
|
123
427
|
```
|
|
124
428
|
|
|
125
|
-
completed Task 在显式 reopen 前会拒绝消息、派发、进入 session、重试和迟到的 yield
|
|
429
|
+
completed Task 在显式 reopen 前会拒绝消息、派发、进入 session、重试和迟到的 yield。每个隔离 WorkItem worktree 必须先显式清理,清理时也会删除其受管分支;archive 还必须通过 `--integrated` 或 `--abandon` 明确 Task main 的处理结果,之后才会停止 session 并清理干净的 Task main。Task 与 WorkItem 记录都会保留,Task main 分支作为恢复信息保留,不会被静默删除。
|
|
126
430
|
Task 生命周期的交互选择只展示有效来源状态:activate 只展示 Draft,complete 只展示 active,reopen 只展示 completed。
|
|
127
431
|
|
|
128
432
|
## Session 与 tmux
|
|
129
433
|
|
|
130
|
-
|
|
434
|
+
所有长时间运行的交互式 Agent 进程都由 tmux 承载。执行 `operator enter`、`role enter` 或 `task enter` 前,Yui 会关闭 readline、退出 raw mode、暂停自身 stdin,再同步把终端交给 tmux。attach 会继承外层终端的真实能力并进入干净的 alternate screen;鼠标滚动只查看 Agent pane 的 100,000 行 tmux 历史,不再混入 attach 之前的 shell 或 IDE Terminal 历史。因此 Agent 原生的 `/model`、斜杠命令提示、全屏渲染和按键处理都可正常工作。
|
|
435
|
+
|
|
436
|
+
tmux 会在 pane 创建时固定其历史容量。配置该限制之前创建的 Role 会保留原容量;Yui 会在 Terminal attach 和 Web 中提示用户退出并重新进入一次,从而在保留 Agent 原生对话的同时创建具有 100,000 行历史的新 pane。
|
|
437
|
+
|
|
438
|
+
同一个 Operator 或 Task tmux session 中,第一个 Terminal/Web 客户端可写,后续查看者自动只读,避免多个入口同时向同一个 Agent 输入。
|
|
131
439
|
|
|
132
440
|
```sh
|
|
133
441
|
yui role enter <global-role>
|
|
@@ -135,10 +443,26 @@ yui task enter <task-id> [role]
|
|
|
135
443
|
yui task role enter <task-id> <role>
|
|
136
444
|
```
|
|
137
445
|
|
|
138
|
-
每个 Role 可绑定多个 Agent
|
|
446
|
+
每个 Role 可绑定多个 Agent,但任一时刻只有一个 active Agent,并为每个
|
|
447
|
+
Agent binding 独立保存 native session。Operator 进一步限制为同一种
|
|
448
|
+
adapter 最多绑定一个,例如可同时绑定一个 Codex 和一个 Claude;这些
|
|
449
|
+
binding 是预先保存、可随时切换的配置,而不是并行身份。Operator 可为
|
|
450
|
+
每个 binding 保留多条历史对话。`operator new` 与 `operator resume`
|
|
451
|
+
复用唯一的 Operator tmux pane;存在运行中进程时,Yui 会先确认再停止
|
|
452
|
+
并切换。跨 Agent 切换默认复用已保存的 model/effort,只有用户明确选择
|
|
453
|
+
更新时才进入现有配置选择流程。
|
|
454
|
+
|
|
455
|
+
使用 `yui role unbind <global-role> <agent-id>` 或 `yui task role unbind <task-id> <role> <agent-id>` 可移除休眠 binding。active binding 或任何未 stopped 的 native session 都会被拒绝;stopped session 记录会和 binding 在同一事务中删除。
|
|
139
456
|
|
|
140
457
|
Claude 的 session ID 在启动前分配。受管理的 Codex 启动使用 Codex 结构化 `notify` 回调,在 turn 完成后记录 thread ID,不再向模型对话注入 session-bind prompt。
|
|
141
458
|
|
|
459
|
+
自动生命周期与投递判断只使用结构化 Hook payload、持久身份、tmux process
|
|
460
|
+
state、receipt 与 pane fence。Yui 不会解析 prompt glyph、进度文本、trust dialog
|
|
461
|
+
或其他 Agent 终端输出来推断 ready 或 success。`captureRole()` 只用于显式的人类
|
|
462
|
+
transcript 查看,不具备生命周期权威。
|
|
463
|
+
|
|
464
|
+
稳定的 Role 上下文也属于启动元数据,而不是 bootstrap turn。Yui 通过 Agent 原生的 system/developer instruction 通道传入 Role 策略和 `systemPrompt`。Task execution Run 按角色接收通用 Leader 或 Worker Skill,review Run 则按持久 Run purpose 接收通用 Reviewer Skill;这些都只是 Yui 自己拥有的可移植编排规则。Project Skills 始终是 Project 中正常版本化的文件,由 Agent 通过自身项目机制发现、选择并按需加载;Yui 不扫描、不解析、不复制,也不注入 Project Skills。Codex developer instructions 只携带 Yui 自有 Role Skill 的精简绝对路径。由于 `developer_instructions` 是单一标量配置,Yui 会检查当前支持的全部 Linux Codex 配置层:`/etc/codex/config.toml`、用户配置、选中的 `$CODEX_HOME/<name>.config.toml`、项目配置以及 `/etc/codex/managed_config.toml`;任意一层已经设置该值时都会明确拒绝覆盖。受管理的 Codex 会话还必须独占用于记录原生 Turn 完成状态的结构化 `notify` 回调;任意受检配置层已经定义 `notify` 时,Yui 都会拒绝启动,避免两个回调互相静默覆盖。`skills.config` 只负责启停已发现 Skill,Yui 不会误用它。Claude 从 Yui 管理的私有 `0600` context 文件读取同一份 Yui Role Skill 内容,不再把大段或敏感文本放进 argv;重试和 resume 会复用按 purpose 区分的稳定路径。非 Operator 的 global Role 保持中性,不会注入 Task 编排 Skill。因此 Operator 会停在空白的原生 composer,用户输入仍是第一条 user message;Leader wake、Worker 和 Reviewer Run assignment 仍是邮箱投递的真实工作消息。不具备原生指令通道的 adapter 必须拒绝这类上下文,不能静默降级为首轮 user prompt。
|
|
465
|
+
|
|
142
466
|
## Controller 与失败处理
|
|
143
467
|
|
|
144
468
|
每个 `YUI_HOME` 有一个后台 Controller:
|
|
@@ -151,15 +475,15 @@ yui controller restart
|
|
|
151
475
|
|
|
152
476
|
`controller restart` 会用当前安装的 Yui 版本替换 Controller 进程及其调度循环、socket 服务,不会停止或重启已受管的 tmux/Agent 会话。
|
|
153
477
|
|
|
154
|
-
|
|
478
|
+
恢复 reconciliation 默认每 120 秒执行一次。普通持久状态变化只会将 Task、Role 或 Operator key 放入队列并立即返回;固定 100ms 窗口内到达的 key 会合并触发一次不重叠的定向处理。Operator 呈现使用独立 lane,不会被 Task 的 Git/worktree 操作阻塞;周期 Git/worktree 处理只覆盖仍有持久 Task mailbox 工作的 Task,活动 Role 的存活检查合并为一次 tmux inventory。Codex turn-complete Hook 直接写入存储,不启动或等待 Controller,并给合法的 yield、输入请求或完成动作保留 2 秒竞争窗口;到期后才关闭被 Agent 遗忘的活动 Role Run。持久 WorkMailbox 会冻结当前 processing 批次,期间的新事件合并到下一 pending 批次;失败会释放当前批次供恢复。推荐输入与 pending Turn 共用最近 deadline 选择器,不依赖恢复扫描间隔;显式 `task reconcile` 仍会立即请求恢复扫描。保留的闭环为:
|
|
155
479
|
|
|
156
|
-
1. 准备 active Task
|
|
480
|
+
1. 准备 active Project Task 的主 worktree;
|
|
157
481
|
2. 停止 archived Task 的 tmux,并只清理干净 worktree;
|
|
158
482
|
3. 投递排队的 Worker Run;
|
|
159
483
|
4. 检测活动 Role 进程退出;
|
|
160
484
|
5. Leader 空闲时投递 pending wake。
|
|
161
485
|
|
|
162
|
-
自动输入只通过 tmux
|
|
486
|
+
自动输入只通过 tmux 投递。每次处理只做一次非阻塞的 process-state readiness 检查;启动阶段忙碌时通过小型有界 mailbox timer 重试,后续忙碌会话通常由 Codex turn-complete 事件再次唤醒。pane 内 receipt 可避免 Controller 重试时重复输入同一 Run。
|
|
163
487
|
|
|
164
488
|
Role 在 yield 前退出时,Controller 会失败对应 Run 和 running WorkItem,并唤醒 Leader。恢复状态通过精简的 Jobs 兼容视图呈现:
|
|
165
489
|
|
|
@@ -172,34 +496,85 @@ yui task run retry <failed-run-id>
|
|
|
172
496
|
|
|
173
497
|
`jobs` 不是旧版通用队列,只展示持久 Leader wake 和 Leader recovery failure。
|
|
174
498
|
|
|
175
|
-
completion
|
|
499
|
+
completion 是可逆的执行屏障。只有活动工作已处理且所有 worktree 干净时才能归档;归档停止 Task 的 tmux session 并移除托管 worktree,但保留 Task 记录。脏 worktree 会让 Task 保持 completed,供后续处理。
|
|
500
|
+
|
|
501
|
+
## 本地 Web 控制室
|
|
502
|
+
|
|
503
|
+
默认在 loopback 地址启动本地控制室:
|
|
504
|
+
|
|
505
|
+
```sh
|
|
506
|
+
yui web
|
|
507
|
+
# Yui web control room: http://127.0.0.1:4173
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
可用 `--port <port>` 或 `--host 127.0.0.1|::1|localhost` 修改监听参数。Yui 会拒绝非 loopback host,因为控制室会展示 Task、Role、WorkItem、Run、Message、Decision、Milestone 和 InputRequest 等信息。服务启动时生成的随机 token 会嵌入页面,并保护写操作和终端连接。
|
|
511
|
+
|
|
512
|
+
Web 端可以通过与 Terminal 相同的持久化 CLI 路径回答 open InputRequest,也可以通过原生 xterm 客户端 attach 到已有 Operator、Leader 或 Worker tmux pane。关闭浏览器终端只会 detach 当前 tmux client,Agent 进程与对话继续保留;Web 不复制 transcript,也不维护第二套会话状态。
|
|
513
|
+
|
|
514
|
+
控制台默认打开概览驾驶舱:四个运营指标(进行中任务、等待你处理的输入、已完成任务、总数)、跨任务的关注收件箱(把所有 open InputRequest 连同问题和紧急程度集中展示,无需进入任务即可回答),以及当前进行中的任务列表。选中任务后进入带锚点的详情视图(摘要、焦点、工作项、运行、角色、历史、消息),顶部标签栏会跟随滚动高亮当前所在分区。
|
|
515
|
+
|
|
516
|
+
控制室支持 English 与简体中文,首次打开时跟随浏览器语言,也可以手动切换并记住选择。主题选择器可在深色「控制室」、浅色「纸本台账」和深蓝「Atlas 深空」之间切换。语言与主题偏好只保存在浏览器 `localStorage`,不会修改 `YUI_HOME`。
|
|
176
517
|
|
|
177
518
|
## 管理命令
|
|
178
519
|
|
|
179
520
|
```sh
|
|
180
521
|
yui update
|
|
181
|
-
yui agent add|list|show|update|remove
|
|
522
|
+
yui agent add|list|show|capabilities|update|remove
|
|
182
523
|
yui role add|list|show|update|remove|bind|enter
|
|
183
524
|
yui role session record|replace
|
|
184
|
-
yui
|
|
525
|
+
yui project add|clone|update|discover|list|show|knowledge
|
|
185
526
|
```
|
|
186
527
|
|
|
187
528
|
Agent 环境变量绑定只保存进程环境变量名,不保存 secret 值;raw args 不能覆盖 adapter 管理的生命周期参数。
|
|
188
529
|
|
|
189
530
|
## 范围
|
|
190
531
|
|
|
191
|
-
Yui
|
|
532
|
+
Yui 面向一台机器上的一个受信任本地用户。它的 Web/API 仅支持 loopback,不包含远程或多用户 Web、分布式协调、backup/import/export、trash/restore、derived index、recovery journal、runtime lease、inactivity TTL、cooldown 或 recurring schedule。
|
|
192
533
|
|
|
193
534
|
持久化和调度细节见 [ARCHITECTURE.md](../ARCHITECTURE.md)。
|
|
535
|
+
可复用的用户视角验收方案见
|
|
536
|
+
[Operator 路由与长期任务端到端测试方案](../docs/testing/operator-routing-e2e-plan.md)。
|
|
194
537
|
|
|
195
538
|
## 本地开发
|
|
196
539
|
|
|
197
540
|
```sh
|
|
541
|
+
npm ci
|
|
198
542
|
npm run build
|
|
199
543
|
npm test
|
|
200
544
|
npm run lint
|
|
201
545
|
```
|
|
202
546
|
|
|
547
|
+
如需让用户终端使用当前 checkout,可逆地接管用户级 `yui` 命令:
|
|
548
|
+
|
|
549
|
+
```sh
|
|
550
|
+
make link
|
|
551
|
+
command -v yui
|
|
552
|
+
yui doctor
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
第一次执行 `make link` 会把最初的 `yui` 入口保存在同一个用户级 bin 目录,再用指向当前 checkout 的受管符号链接接管命令。之后在其他 checkout 执行 `make link` 只会移动这个受管链接:最后执行者生效,开发环境之间不会形成备份链。请串行执行 `make link` 和 `make unlink`,不要从多个环境或 checkout 并发调用。launcher 默认使用当前生效 checkout 的 `output/dev/home` 作为 `YUI_HOME`;显式设置的 `YUI_HOME` 仍然优先。受管 Agent 不依赖这个全局链接:Controller 会把指向自身 Yui CLI 和 `YUI_HOME` 的私有 launcher 放到 PATH 最前面。若已有 Controller 也需要加载新代码,请执行 `yui controller restart`。任意采用本实现的 checkout 都可以执行 `make unlink`;它会校验共享受管状态并恢复唯一一份最初 `yui` 入口。
|
|
556
|
+
|
|
557
|
+
```sh
|
|
558
|
+
make unlink
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
若只想隔离运行当前 checkout、而不改动全局 `yui`,构建它的本地 launcher,而不是执行 `link`:
|
|
562
|
+
|
|
563
|
+
```sh
|
|
564
|
+
make install-local
|
|
565
|
+
./output/dev/bin/yui doctor
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
`make install-local` 会在 `output/dev/bin/yui` 写入一个自包含 launcher,并且完全不碰用户级 `yui` 命令。该 launcher 会自行解析所在 checkout,并把 `YUI_HOME` 默认指向本 checkout 的 `output/dev/home`;因此 Yui 从 `YUI_HOME` 派生的所有实例标识(Controller socket、tmux server、state)都会与其他 checkout 或全局安装保持隔离。该命令是幂等的,拉取新代码后可重复执行(若已有 Controller 在运行,再执行 `./output/dev/bin/yui controller restart`)。请以绝对路径调用该 launcher,作为每个 checkout 稳定的入口;把 `output/dev/bin` 加入 `PATH` 只是单个 shell 会话的便捷做法。
|
|
569
|
+
|
|
570
|
+
`make install-local` 会先 build 出 `dist/`,然后只写入一个文件——launcher 本身。它不会修改 `PATH`,也不会创建数据 home,因此在需要状态的命令之前先执行一次 `./output/dev/bin/yui setup`。注意:裸敲 `yui` 是按 `PATH` 解析的,**与当前所在目录无关**;即使人在本 checkout 目录里,裸 `yui` 也不会用到本地 launcher,仍然会执行 `PATH` 找到的那个(通常是全局 `yui`)。要选中本实例,请使用 launcher 的绝对路径;或仅针对某一个交互式 shell,把它前置到 `PATH`:
|
|
571
|
+
|
|
572
|
+
```sh
|
|
573
|
+
export PATH="$PWD/output/dev/bin:$PATH" # 仅当前 shell 生效;不适用于自动化
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
这也是推荐给 agent 和脚本的入口:执行一次 `make install-local`,之后在任意工作目录下以绝对路径调用 `<checkout>/output/dev/bin/yui ...`。不要依赖 `export` 跨命令留存,因为每条命令都在全新进程中运行。
|
|
577
|
+
|
|
203
578
|
## 许可证
|
|
204
579
|
|
|
205
580
|
[MIT](../LICENSE)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zq-silk/yui",
|
|
3
|
-
"version": "0.2
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Local control plane for long-running native agent CLI sessions backed by tmux.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": false,
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"files": [
|
|
12
12
|
"dist",
|
|
13
13
|
"skills",
|
|
14
|
+
"docs",
|
|
14
15
|
"README.md",
|
|
15
16
|
"ARCHITECTURE.md",
|
|
16
17
|
"i18n/README.zh-CN.md",
|
|
@@ -43,5 +44,12 @@
|
|
|
43
44
|
"bugs": {
|
|
44
45
|
"url": "https://github.com/zhangqian-silk/Yui/issues"
|
|
45
46
|
},
|
|
46
|
-
"homepage": "https://github.com/zhangqian-silk/Yui#readme"
|
|
47
|
+
"homepage": "https://github.com/zhangqian-silk/Yui#readme",
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@xterm/addon-fit": "^0.11.0",
|
|
50
|
+
"@xterm/xterm": "^6.0.0",
|
|
51
|
+
"node-pty": "^1.1.0",
|
|
52
|
+
"smol-toml": "1.7.0",
|
|
53
|
+
"ws": "^8.21.1"
|
|
54
|
+
}
|
|
47
55
|
}
|