@zq-silk/yui 0.15.8 → 0.15.11

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.
Files changed (151) hide show
  1. package/ARCHITECTURE.md +2 -0
  2. package/ARCHITECTURE.zh-CN.md +151 -0
  3. package/README.md +211 -14
  4. package/dist/agent/launchEnvironment.js +7 -0
  5. package/dist/artifacts/artifactCapability.js +74 -0
  6. package/dist/artifacts/artifactCommitLock.js +249 -0
  7. package/dist/artifacts/artifactPaths.js +151 -0
  8. package/dist/artifacts/gitArtifactRef.js +146 -0
  9. package/dist/artifacts/managedGit.js +332 -0
  10. package/dist/artifacts/taskArtifactRepository.js +277 -0
  11. package/dist/cli/commandCatalog.js +40 -16
  12. package/dist/cli/interactionPolicy.js +3 -3
  13. package/dist/cli/updateOrchestrator.js +24 -1
  14. package/dist/cli/updatePorts.js +7 -3
  15. package/dist/cli/upgradeCommand.js +42 -2
  16. package/dist/cli.js +403 -93
  17. package/dist/commands/globalRoleCommands.js +314 -4
  18. package/dist/commands/operatorCommands.js +33 -2
  19. package/dist/commands/projectCommands.js +6 -7
  20. package/dist/commands/releaseCommands.js +18 -0
  21. package/dist/commands/taskActivationCommands.js +22 -0
  22. package/dist/commands/taskActor.js +25 -0
  23. package/dist/commands/taskCommands.js +846 -155
  24. package/dist/commands/taskIntegrationCommands.js +16 -38
  25. package/dist/commands/taskIntegrationQueueCommands.js +1 -1
  26. package/dist/commands/taskRemoteDeliveryCommand.js +6 -6
  27. package/dist/commands/taskRoleRuntimeStatus.js +35 -0
  28. package/dist/context/runContextPack.js +28 -16
  29. package/dist/context/taskContext.js +64 -5
  30. package/dist/controller/agentHostObservation.js +155 -0
  31. package/dist/controller/clientRuntime.js +17 -2
  32. package/dist/controller/controller.js +11 -2
  33. package/dist/controller/fileSchedulerStoreAdapter.js +446 -13
  34. package/dist/controller/globalInputDelivery.js +119 -0
  35. package/dist/controller/jobControl.js +6 -2
  36. package/dist/controller/resourceInventory.js +14 -4
  37. package/dist/controller/resourceInventoryLinux.js +2 -6
  38. package/dist/controller/runtime.js +81 -6
  39. package/dist/controller/runtimeEventInbox.js +32 -3
  40. package/dist/controller/runtimeEventProcessor.js +26 -6
  41. package/dist/controller/runtimeHookRunFence.js +75 -19
  42. package/dist/controller/structuredProviderObservation.js +133 -70
  43. package/dist/coordination/workMailboxQueue.js +5 -0
  44. package/dist/execution/workItemExecutionProjection.js +1 -1
  45. package/dist/executor/agentExecutor.js +64 -4
  46. package/dist/executor/executorRegistry.js +3 -0
  47. package/dist/executor/fileRoleLaunchPlanner.js +78 -118
  48. package/dist/integration/deliveryObligation.js +2 -1
  49. package/dist/integration/gitIntegrationService.js +312 -382
  50. package/dist/integration/integrationAttempt.js +30 -4
  51. package/dist/integration/integrationQueueService.js +7 -7
  52. package/dist/integration/integrationSourceApplication.js +323 -0
  53. package/dist/kernel/builtinCapabilities.js +32 -24
  54. package/dist/message/globalInterrupt.js +33 -0
  55. package/dist/message/inputControlResolution.js +106 -0
  56. package/dist/message/message.js +423 -0
  57. package/dist/message/messageContinuation.js +126 -3
  58. package/dist/message/taskInterrupt.js +34 -0
  59. package/dist/observability/orchestrationMetrics.js +1 -1
  60. package/dist/plugins/pluginService.js +11 -3
  61. package/dist/release/releaseHandover.js +22 -0
  62. package/dist/release/releaseWorkflowPorts.js +15 -7
  63. package/dist/repository/gitWorkspace.js +72 -15
  64. package/dist/repository/taskWorkspaceCoordinator.js +134 -0
  65. package/dist/repository/taskWorkspacePreparer.js +120 -49
  66. package/dist/repository/workItemCandidateSnapshot.js +34 -0
  67. package/dist/resources/projectResource.js +0 -48
  68. package/dist/resources/projectResourceService.js +3 -81
  69. package/dist/resources/resourceDiscovery.js +3 -2
  70. package/dist/runtime/agentHost.js +152 -72
  71. package/dist/runtime/agentHostCompatibility.js +127 -0
  72. package/dist/runtime/agentHostProtocol.js +53 -0
  73. package/dist/runtime/executionEnvironment.js +0 -19
  74. package/dist/runtime/launchBroker.js +6 -0
  75. package/dist/runtime/sessionReconciliation.js +4 -4
  76. package/dist/runtime/taskRuntimeIsolation.js +30 -6
  77. package/dist/runtime/tmuxAdapters.js +5 -3
  78. package/dist/scheduler/operatorEvent.js +4 -0
  79. package/dist/scheduler/taskExecutionProjection.js +12 -1
  80. package/dist/scheduler/wakeReason.js +7 -1
  81. package/dist/scheduler/wakeupQueue.js +2 -0
  82. package/dist/setup/setupCommand.js +29 -16
  83. package/dist/storage/homeLayout.js +130 -0
  84. package/dist/storage/migrations/artifactsToGit.js +338 -0
  85. package/dist/storage/migrations/collapseWorktreeLayout.js +963 -0
  86. package/dist/storage/migrations/integrationContinuation.js +104 -0
  87. package/dist/storage/migrations/submitIntent.js +126 -0
  88. package/dist/storage/migrations/unifyHomeLayout.js +925 -0
  89. package/dist/storage/sqliteSchema.js +173 -7
  90. package/dist/storage/sqliteStore.js +41 -22
  91. package/dist/storage/storageVersions.js +1 -1
  92. package/dist/storage/storeRpc.js +2 -1
  93. package/dist/storage/upgrade/upgradeOrchestrator.js +95 -2
  94. package/dist/task/archiveDiagnostics.js +128 -0
  95. package/dist/task/nextAction.js +44 -11
  96. package/dist/task/taskActivation.js +26 -0
  97. package/dist/task/taskActivationService.js +85 -69
  98. package/dist/task/taskSubmission.js +236 -0
  99. package/dist/web/assets/client/app.js +58 -2
  100. package/dist/web/assets/client/components.js +1 -0
  101. package/dist/web/assets/client/i18n.js +6 -0
  102. package/dist/web/assets/client/taskSurface.js +202 -7
  103. package/dist/web/assets/client/view.js +7 -4
  104. package/dist/web/assets/shell.js +23 -0
  105. package/dist/web/assets/styles/layout.js +1 -1
  106. package/dist/web/assets/styles/widgets.js +12 -0
  107. package/dist/web/webServer.js +135 -4
  108. package/dist/web/webSnapshot.js +4 -3
  109. package/dist/web/webTaskSurface.js +225 -8
  110. package/dist/workItem/workItem.js +14 -10
  111. package/dist/workspace/workItemChangeSetManager.js +18 -2
  112. package/docs/agent-result-consumption.md +2 -0
  113. package/docs/agent-result-consumption.zh-CN.md +81 -0
  114. package/docs/agent-runtime-drivers.md +2 -0
  115. package/docs/agent-runtime-drivers.zh-CN.md +77 -0
  116. package/docs/architecture/README.md +44 -32
  117. package/docs/architecture/README.zh-CN.md +43 -0
  118. package/docs/architecture/capabilities-and-resources.md +118 -79
  119. package/docs/architecture/capabilities-and-resources.zh-CN.md +83 -0
  120. package/docs/managed-turn-and-session-runtime.md +2 -0
  121. package/docs/managed-turn-and-session-runtime.zh-CN.md +180 -0
  122. package/docs/observability/README.md +2 -0
  123. package/docs/observability/README.zh-CN.md +71 -0
  124. package/docs/plugin-sdk.md +320 -217
  125. package/docs/plugin-sdk.zh-CN.md +293 -0
  126. package/docs/provider-runtime.md +2 -0
  127. package/docs/provider-runtime.zh-CN.md +132 -0
  128. package/docs/release-workflow.md +41 -0
  129. package/docs/release-workflow.zh-CN.md +266 -0
  130. package/docs/roles-and-configuration.md +2 -0
  131. package/docs/roles-and-configuration.zh-CN.md +96 -0
  132. package/docs/sqlite-control-plane-design.md +225 -1
  133. package/docs/sqlite-control-plane-design.zh-CN.md +62 -0
  134. package/docs/task-dag-semantics.md +80 -57
  135. package/docs/task-dag-semantics.zh-CN.md +59 -0
  136. package/docs/task-delivery.md +2 -0
  137. package/docs/task-delivery.zh-CN.md +82 -0
  138. package/docs/task-local-identity.md +2 -0
  139. package/docs/task-local-identity.zh-CN.md +58 -0
  140. package/docs/testing/verification-levels.md +26 -0
  141. package/docs/testing/verification-levels.zh-CN.md +80 -0
  142. package/i18n/README.zh-CN.md +199 -10
  143. package/package.json +2 -1
  144. package/skills/yui-leader/SKILL.md +88 -331
  145. package/skills/yui-leader/references/execution.md +405 -0
  146. package/skills/yui-leader/references/integration.md +52 -2
  147. package/skills/yui-leader/references/planning.md +109 -0
  148. package/skills/yui-leader/references/task-plugins.md +8 -4
  149. package/skills/yui-operator/SKILL.md +22 -4
  150. package/skills/yui-runtime/SKILL.md +27 -0
  151. package/skills/yui-runtime/references/publication.md +20 -0
package/ARCHITECTURE.md CHANGED
@@ -1,3 +1,5 @@
1
+ <p align="right"><strong>English</strong> | <a href="./ARCHITECTURE.zh-CN.md">简体中文</a></p>
2
+
1
3
  # Yui architecture
2
4
 
3
5
  Yui is a local control plane and context API for intelligent Agents. Agents own
@@ -0,0 +1,151 @@
1
+ <p align="right"><a href="./ARCHITECTURE.md">English</a> | <strong>简体中文</strong></p>
2
+
3
+ # Yui 架构
4
+
5
+ Yui 是面向智能 Agent 的本地控制面与上下文 API。Agent 拥有规划、执行拓扑、语义审查、
6
+ 验收和恢复。Core 拥有持久身份、授权、工作区隔离、数据完整性和有界效果。它暴露当前
7
+ 事实和原子操作,而不是替 Agent 选择工作流。
8
+
9
+ ## 职责
10
+
11
+ | 边界 | 拥有 | 不拥有 |
12
+ | --- | --- | --- |
13
+ | Operator / Leader | 用户协调;Task 结果、规划和判断 | 伪造的运行时回执或自行授予的外部权限 |
14
+ | Task Store | Task、Role、WorkItem、Run、消息、结果、事件和资源所有权 | 原生 transcript 或推断出的 Provider 活动 |
15
+ | Context | 获授权的有界读取、不可变事件增量、精确执行快照 | 第二份可写 Task 或投递确认 |
16
+ | Controller | 投递、观察、Job、能力 Host 和 Web 监听 | 对 Agent 散文的语义解读 |
17
+ | CapabilityRegistry / InstanceHost | 描述符解析、范围受限调用、实现引用和处置 | Task 规划、任意插件特权或自动恢复 |
18
+ | AgentHost / AgentEndpoint / Driver | 原生连接、输入处置、精确结果关联和观察 | Task 验收或对共享 Provider daemon 的所有权 |
19
+ | Project / Resource | Knowledge、受管 Git 工作区、采用的环境和持久 artifact | 从目录名推断出的权限 |
20
+ | CLI / Web | 共享的领域操作和投影 | 独立的业务状态或另一个插件 Host |
21
+
22
+ 一个 `YUI_HOME` 有一个权威的 SQLite 控制面 Store 和一个 Controller。Project Knowledge
23
+ 维护在该 Home 下;仓库材料可以作为证据,但不替代所维护的 Knowledge。
24
+
25
+ ## 意图、协作与执行
26
+
27
+ Task 表示一个有界结果,可能跨多个 Project。它的 type 描述意图,不规定分解方式。
28
+ Leader 可以直接负责有界工作;WorkItem 是有实质性、可独立验收、且有明确负责人的需求。
29
+
30
+ Task 生命周期是 `draft / active / completed / cancelled / archived`。WorkItem 生命周期
31
+ 是 `open / accepted / retired`。执行、等待和失败归 AgentRun 和运行时观察,不构成额外的
32
+ WorkItem 状态。只有被接受的直接依赖才满足 `dependsOn`;替换元数据不重定向依赖图。
33
+
34
+ 一个有效的 Leader Session 可以在没有活动 AgentRun 的情况下读取 Context 并修改范围
35
+ 受限的 Task 事实。Worker 与 Reviewer 动作保留其精确的 Assignment 和工作区边界。替换
36
+ 或撤销一个 Session 会改变权限;一次瞬时的投递失败既不授予也不撤销无关权限。已释放的
37
+ Leader 保留范围受限的诊断读取,而非写权限。
38
+
39
+ 持久 Task 上下文与工程控制数据有各自的用途。需求、决策、验收和原始结果必须在原生
40
+ 对话之外存续。AgentRun 的输入/结果历史仍是证据,而它的活动索引、原生投递状态、Host
41
+ 和 Session 选择只控制一次执行尝试。替换那次执行绝不完成或删除 Task。
42
+
43
+ AgentRun 记录一次明确请求的执行,带有冻结的 Context 和生效配置。原生对话、Goal 延续
44
+ 和普通 Leader 通知不会自动创建 Run。消息可以通过一个新的、精确关联的 Run 延续已派发
45
+ 的工作,而不改变需求、已捕获的权限或工作区。
46
+
47
+ 参见 [Session 与 AgentRun](docs/managed-turn-and-session-runtime.zh-CN.md)和
48
+ [Task 依赖](docs/task-dag-semantics.zh-CN.md)。
49
+
50
+ ## 投递与结果
51
+
52
+ 显式派发与普通通知共享原生输入传输,但保有不同的持久 owner。Controller 认领一个有界
53
+ mailbox 批次;AgentHost 通过 AgentEndpoint 串行化提交。Provider 绑定记录实际接受和原生
54
+ 关联。一条通知可以在接受时结算,而不要求最终执行报告。
55
+
56
+ 忙碌且已证明未接受会为后续尝试保留输入。仅有传输提交不证明接受。未知效果保持可见且被
57
+ 围栏隔离:不盲目重发,也不推断成功。显式替换先解决实际的原生执行,再丢弃其工程占用。
58
+ 在一个已认领批次期间到达的输入,留待下一个批次。读取 Context 不消费投递。
59
+
60
+ 一个精确的终态事务持久化一个原始 AgentRunResult 和一条引用 Message。Core 校验身份、
61
+ 传输和工作区事实;它不把散文解析为 findings、投票、修复拓扑或验收。Provider 成功与
62
+ 语义成功是两回事。
63
+
64
+ 直接执行使用一个 main Run。复制执行为彼此不同的 Producer Lane 冻结一个 Assignment。
65
+ Leader 显式选择终态原始结果并启动一个 main 综合 Run;被选中的失败结果也可以是有用的
66
+ 证据。Core 检查来源,而不是成功计数或共识。Lane 不是 Candidate,也不是 Integration
67
+ 来源。
68
+
69
+ ReviewRound 引用一个冻结的 Candidate 或 Task head,以及它确切的 Reviewer Run。原始
70
+ Reviewer 输出留在那个 Run 上。审查策略和显式的 Task-final 合同规定何时需要审查;报告的
71
+ 含义由 Leader 判断。参见[结果消费](docs/agent-result-consumption.zh-CN.md)。
72
+
73
+ ## 规划、工作区与资源
74
+
75
+ Draft 包含规划事实和 Project 绑定,而不是一个已采用的交付工作区。它私有的规划目录在
76
+ 控制 Home 和交付树之外。规划 Session 捕获 `planning` 权限。Leader 可以在一个 Run 或
77
+ 普通讨论中持久化一个激活请求并返回;原生静止会把该意图释放出来,进行当前权限和资源
78
+ 检查。
79
+
80
+ 激活先准备物理资源,然后原子地采用 Task 状态、工作区身份和所有权。失败会保留意图和一份
81
+ 诊断、通知 Leader,并停止对那次失败采用的自动重复。成功会通知 Leader 进入交付,而无需
82
+ 再一次用户提示。Task 激活不能把一个活动 Session 已捕获的权限变更为 `delivery`;一次
83
+ 兼容的交付启动必须确立那条边界。
84
+
85
+ 稳定的 Project checkout 是只读参考。受管工作区的 owner 是 Task、WorkItem、ReviewRound
86
+ 或 IntegrationAttempt,而不是 Role 名。多 Project 工作区包含按 Project 划分的 Git 根。
87
+ 写范围和精确的 Git 血缘在效果发生处检查;一个 Profile 的行为意图不是 grant。
88
+
89
+ 一个隔离结果被捕获为不可变的、按 Project 划分的 ChangeSet,并通过一个候选 worktree
90
+ 集成。检查先于对目标 head 的 compare-and-swap 推进。冲突或目标移动保留证据且不推进它。
91
+ Leader 单独验收交付。
92
+
93
+ Resource 支持不可变内容、外部版本和回执 artifact,以及被显式标记的参考资料。环境的
94
+ prepare、adopt、bind 和 release 是彼此独立的操作。选择影响未来的原生执行;活动 Session
95
+ 保留其已捕获的环境。trusted-local 采用不是 OS 沙箱,release 也绝不意味着删除用户目录。
96
+
97
+ ## 运行时身份与替换
98
+
99
+ Agent 执行组件、连接方案、原生 Session、Host attachment 和 AgentRun 标识不同的东西。
100
+ Codex CLI 使用 App Server,Claude Code CLI 使用 stream-json,ACP peer 使用 ACP 连接
101
+ 实现。未知的 ACP 产品身份保持未知。
102
+
103
+ 期望的 Role 配置、冻结的生效启动,以及 Agent 实际自报的配置是彼此独立的事实。被请求的
104
+ model 或权限不是它当前已生效的证据。ACP 配置通过协商的选项应用并检查;不受支持的轴
105
+ 显式失败,而不是被猜测。
106
+
107
+ Host 拥有一次性客户端,而不是共享的原生对话。Session 实现被固定到其实际的代码边界。
108
+ 新的调用或 Session 可以选择一个新实现,同时旧引用排空。一次超时或客户端退出不证明后代
109
+ 资源已停止;未解决的处置保持可观察,而不是被报告为干净。
110
+
111
+ Session 复用是可选的。`task role session new` 在既有运行时 mailbox 中记录替换意图,
112
+ 包括当一个 Run 处于活动、或先前的 Session 已经结束时。一旦其资源停止,Yui 取消旧 Role
113
+ 的工程尝试,保留历史和工作区,并选择一个新 Session。未处理的通知引用被带入后继的上下文,
114
+ 而不是丢在一个时间游标之后。是否重试既有工作由 Agent 决定。持久的原生连接位置和专用
115
+ 进程托管使恢复独立于旧 Host。一个确实存活/未知的写者仍是一条资源边界,而不是隐瞒诊断
116
+ 或抹除持久上下文的理由。
117
+
118
+ 参见 [Provider Runtime](docs/provider-runtime.zh-CN.md)和
119
+ [Agent Drivers](docs/agent-runtime-drivers.zh-CN.md)。
120
+
121
+ ## 能力、插件与 Surface
122
+
123
+ 能力使用经认证的 `search / describe / call`。描述符声明 schema、effect、权限、scope 和
124
+ Provider 身份。歧义要求显式选择。嵌套调用不能放大调用者的权限或效果;原始操作回执在
125
+ 父调用失败后仍存续。
126
+
127
+ Registry 暴露 context、消息、artifact、环境、插件以及部分 Task/Job 操作。其他 CLI/Web
128
+ 操作直接共享领域处理器。并不要求每个操作都经由一个插件路由。
129
+
130
+ 经验证的 Task-local 插件在 Store 中保留显式的 enabled 意图,在 InstanceHost 中保留活
131
+ 实例。读取或重启不运行作者代码。Leader 的管理仅限于其 Task;可执行代码仍需要确切的、
132
+ 由 Operator 签发的 grant。插件验证不是安全认证。
133
+
134
+ CLI 贡献和受控的 Web 面板是 Registry 的投影。Web 仅本地回环、由 Controller 拥有;浏览器
135
+ 凭据不会变成 Operator 权限。参见[插件 SDK](docs/plugin-sdk.zh-CN.md)和
136
+ [能力与资源](docs/architecture/capabilities-and-resources.zh-CN.md)。
137
+
138
+ ## 持久化、完成与运维
139
+
140
+ Home 有一条只追加的存储迁移链。普通运行时只接受当前记录。显式升级会备份并迁移受支持的
141
+ 有效 Home;畸形状态被诊断,而不是自动修复。
142
+
143
+ 完成会冻结交付结果,并检查适用的验收、集成和审查合同。它区别于发布、已验证的远程合并、
144
+ 物理静止和归档。归档要求工作已了结、受管资源干净可移除,保留 Task 历史,且不可重开。
145
+
146
+ 运行时健康度和成本是观察,而不是语义判定。Agent 读取精确的故障和当前意图,以选择重试、
147
+ 修复或放弃。Yui 不会自动创建救援 Worker 或选择另一个模型。
148
+
149
+ [文档导航](docs/architecture/README.zh-CN.md)链接当前的各项合同。
150
+ [验证策略](docs/testing/verification-levels.zh-CN.md)把核心冒烟与临时的、针对变更的
151
+ 以及经显式授权的真实资源证据区分开;文档不构成对完整生产验证的声明。
package/README.md CHANGED
@@ -2,20 +2,42 @@
2
2
 
3
3
  # Yui
4
4
 
5
- Give your Agents work to carry forward, not just another chat to answer.
6
-
7
- Yui helps you turn requests into organized tasks and coordinate Agents to solve
8
- them. Describe what you want in conversation: an Agent identifies the relevant
9
- Project, distinguishes new work from a follow-up, and keeps related requirements
10
- together. Each Task has a Leader that plans the work, uses other configured
11
- Agents when useful, and brings results and decisions back to you.
5
+ [![Core CI](https://github.com/zhangqian-silk/yui/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/zhangqian-silk/yui/actions/workflows/ci.yml)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
7
+ ![Node](https://img.shields.io/badge/node-20%20%7C%2022%20%7C%2024-brightgreen.svg)
8
+ ![Platform](https://img.shields.io/badge/platform-Linux%20x64%20%28glibc%29-blue.svg)
9
+ [![PRs welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](#contributing)
12
10
 
13
- You do not need to manually create a ticket for every step, carry context between
14
- terminal windows, or remember which Agent was working on which requirement.
15
- Yui keeps the intent, progress and results outside any one conversation, so
16
- continuing work starts from the Task rather than from your memory.
11
+ Give your Agents work to carry forward, not just another chat to answer.
17
12
 
18
- [Quick start](#quick-start) · [Working through conversation](#working-through-conversation) · [Core design](#core-design)
13
+ Yui is a local control plane for coding Agents. Describe what you want to an
14
+ Operator in plain language: it identifies the relevant Project, tells new work
15
+ from a follow-up, and turns each request into a Task owned by a Leader that
16
+ plans, delegates and brings results and decisions back. Intent, progress and
17
+ results live outside any single conversation, so work continues from the Task —
18
+ not from terminal windows you juggle or details you have to remember.
19
+
20
+ **Highlights**
21
+
22
+ - **Durable by design** — Tasks, decisions and results live in one local SQLite
23
+ store, so work survives crashes and restarts and continues from the Task, not
24
+ a chat log.
25
+ - **One conversation, many Tasks** — the Operator turns plain-language requests
26
+ into new Tasks or follow-ups; no ticket IDs or terminal-window juggling.
27
+ - **A Leader owns each outcome** — it plans, splits work into WorkItems,
28
+ delegates to Workers and Reviewers, and closes the loop; you can talk to it
29
+ directly anytime.
30
+ - **Bring your own Agent** — Codex CLI, Claude Code CLI and ACP peers run behind
31
+ one boundary and stay replaceable without losing the Task.
32
+ - **Local-first and private** — everything runs on your machine for one trusted
33
+ user; the Web view is loopback and read-only.
34
+ - **Isolated by default** — repository work happens in managed Git worktrees;
35
+ the stable checkout stays read-only.
36
+
37
+ > **Status:** pre-1.0 (0.15.x). CLI surfaces and configuration may still change
38
+ > between releases; each upgrade migrates valid existing Homes.
39
+
40
+ [Quick start](#quick-start) · [Working through conversation](#working-through-conversation) · [Architecture](#architecture) · [Design principles](#design-principles)
19
41
 
20
42
  ## Quick start
21
43
 
@@ -117,7 +139,161 @@ submission is not silently repeated.
117
139
  For a visual overview, run `yui web` in another terminal. The local Web view
118
140
  shows the same tasks and pending questions; it is not a separate task system.
119
141
 
120
- ## Core design
142
+ ## Architecture
143
+
144
+ Under the hood, Yui keeps every durable fact in one local SQLite store and lets
145
+ Agents act on it through small, explicit operations. Here is the same system
146
+ from a few different angles:
147
+
148
+ - [Product structure](#product-structure) — the durable objects you work with
149
+ - [How work flows](#how-work-flows) — the closed loop around a Task
150
+ - [User message flow](#user-message-flow) — what happens when you send a message
151
+ - [Core modules](#core-modules) — the long-lived runtime pieces
152
+ - [Layered design](#layered-design) — responsibilities, top to bottom
153
+ - [Lifecycle](#lifecycle) — states a Task and WorkItem move through
154
+
155
+ ### Product structure
156
+
157
+ What Yui organizes for you — durable objects, not processes:
158
+
159
+ ```text
160
+ Global
161
+ ├─ Operator ── the Agent you converse with; spans all Projects & Tasks
162
+ └─ Projects
163
+ └─ Project ── a managed codebase + its Project Knowledge
164
+ └─ Task ── one bounded outcome you asked for
165
+ ├─ Brief ......... objective · boundaries · approach
166
+ ├─ Roles ......... Leader (owns it) · Workers · Reviewers
167
+ ├─ WorkItems ..... independently acceptable requirements
168
+ │ └─ AgentRun .. one requested execution ─▶ Result
169
+ ├─ Messages ...... durable conversation + Decisions
170
+ └─ Review / Integration ─▶ accepted delivery
171
+ ```
172
+
173
+ ### How work flows
174
+
175
+ ```text
176
+ You
177
+ │ describe work · answer questions · refine scope
178
+
179
+ Operator ── reads your intent, then either:
180
+ │ • opens a NEW Task, or
181
+ │ • APPENDS to an existing Task (a follow-up)
182
+
183
+ Task ── owned by one Leader, who runs the closed loop:
184
+
185
+ │ plan ─▶ split into WorkItems ─▶ deliver ─▶ review ─▶ close
186
+
187
+ │ each WorkItem is advanced by the Leader itself, or delegated:
188
+ │ ├──▶ Worker another Agent implements it
189
+ │ └──▶ Reviewer checks the result before it is accepted
190
+
191
+
192
+ Results and decisions come back to you — and you can talk to the Leader
193
+ directly about a task's details anytime.
194
+ ```
195
+
196
+ ### User message flow
197
+
198
+ What happens when you send one message — the Controller only wakes Agents; the
199
+ durable record always lives in the store:
200
+
201
+ ```text
202
+ ── Inbound ────────────────────────────────────────────────────────────────
203
+ You ─▶ Operator ─▶ records a Task (new, or a follow-up) + a Message ─▶ yui.db
204
+
205
+ Controller wakes the Leader
206
+
207
+ ── Work ───────────────────────────────────────────────────────────────────
208
+ Leader reads Context ─▶ acts itself, or delegates to Workers / Reviewers
209
+ ─▶ writes results · decisions · messages ─▶ yui.db
210
+
211
+ Controller wakes the Operator
212
+
213
+ ── Outbound ───────────────────────────────────────────────────────────────
214
+ yui.db ─▶ Operator reads the updates ─▶ replies to You
215
+ ```
216
+
217
+ ### Core modules
218
+
219
+ The long-lived runtime pieces. You only ever talk to the Operator; Agents and
220
+ the Controller are what touch the store:
221
+
222
+ ```text
223
+ You
224
+ │ natural-language conversation with the Operator
225
+ │ (you never drive the Controller or the store yourself)
226
+
227
+ Agent sessions · in tmux
228
+ │ Operator ── the Agent you talk to; routes requests into Tasks
229
+ │ Leader · Workers · Reviewers ── plan, deliver and review the work
230
+ │ each drives a native Agent via AgentHost / AgentEndpoint / Driver:
231
+ │ Codex CLI (App Server) · Claude Code CLI (stream-json) · ACP peers
232
+
233
+ │ Agents read Context and make atomic changes (yui operations)
234
+
235
+ ┌─ yui.db — SQLite (WAL) · single source of truth · one txn per change
236
+ │ Tasks · WorkItems · AgentRuns · Messages · Decisions · Results
237
+ └─ Project Knowledge · configuration
238
+
239
+ │ reads & records runtime facts; wakes and delivers work to the sessions
240
+
241
+ Controller · one per Home
242
+ delivery · Scheduler · jobs · capability host · Web listener
243
+ it moves work and records facts — it never judges an answer
244
+
245
+ Agents work in Projects: read-only checkout + isolated worktrees.
246
+ Web view (yui web): a loopback, read-only projection of the store.
247
+ ```
248
+
249
+ ### Layered design
250
+
251
+ Each layer owns one responsibility and exposes small, explicit capabilities —
252
+ never a fixed workflow:
253
+
254
+ ```text
255
+ Experience — how you interact
256
+ CLI (Operator) · Web (loopback, read-only) · native Agent sessions
257
+ collect input · show facts · confirm actions · invoke capabilities
258
+
259
+ Intelligence — who decides
260
+ Operator: recognize requests, split Tasks
261
+ Leader: plan · delegate · judge · complete one Task
262
+ Workers · Reviewers (behavior comes from Roles & Skills)
263
+
264
+ Capability — the atomic operations Yui exposes
265
+ deliver: Task · WorkItem · Decision · Candidate · Review
266
+ context: Context · Message · InputRequest · Project Knowledge
267
+ config: Roles · Agent config · Project · Plugin
268
+ execute: dispatch · inspect · stop · resources · Artifact
269
+
270
+ Execution — how work actually runs
271
+ AgentHost / AgentEndpoint / Driver, each in a tmux session
272
+ Codex CLI (App Server) · Claude Code CLI (stream-json) · ACP peers
273
+ managed Git worktrees · adopted environments
274
+
275
+ Kernel — durable authority: yui.db (SQLite, WAL)
276
+ storage · identity · permissions · operation facts · instance host
277
+
278
+ ▲ plugins extend the Capability layer through the Capability Registry
279
+ ```
280
+
281
+ ### Lifecycle
282
+
283
+ Status is one authority per object; execution and waiting are runtime facts, not
284
+ extra states:
285
+
286
+ ```text
287
+ Task draft ─▶ active ─▶ completed ─▶ archived
288
+ └────▶ cancelled ─▶ archived
289
+
290
+ WorkItem open ─▶ accepted ─▶ retired
291
+
292
+ Draft holds planning only; activation adopts a delivery workspace.
293
+ Archive needs settled work and clean worktrees; it cannot reopen.
294
+ ```
295
+
296
+ ## Design principles
121
297
 
122
298
  ### Agents make decisions; Yui makes work durable
123
299
 
@@ -161,6 +337,17 @@ Yui is designed for one trusted local user. It is not an OS sandbox or a remote
161
337
  multi-user service. Publishing, granting new access and other external effects
162
338
  still require the corresponding authority.
163
339
 
340
+ ## How Yui compares
341
+
342
+ | | Chat-only agent | Agent CLI + tmux, by hand | Yui |
343
+ | --- | --- | --- | --- |
344
+ | Work survives the session | no | your own notes | durable Tasks in one store |
345
+ | New request vs. follow-up | you decide | you decide | the Operator routes it |
346
+ | Multi-step delegation | manual | manual | Leader → WorkItems → Workers/Reviewers |
347
+ | Swap model/agent mid-task | context lost | manual re-setup | replaceable behind one boundary |
348
+ | Parallel work isolation | — | you manage branches | managed Git worktrees |
349
+ | Where the truth lives | the chat log | scattered | one SQLite source of truth |
350
+
164
351
  ## Learn more
165
352
 
166
353
  The [architecture overview](ARCHITECTURE.md) explains the end-to-end design.
@@ -174,7 +361,9 @@ before moving between builds or updating an existing Home.
174
361
 
175
362
  ## Contributing
176
363
 
177
- In a source checkout, start with `npm ci` and `npm test`. Read
364
+ Start with [CONTRIBUTING.md](CONTRIBUTING.md) for the full workflow, and please
365
+ follow our [Code of Conduct](CODE_OF_CONDUCT.md). In short: in a source
366
+ checkout, run `npm ci` and `npm test`. Read
178
367
  `.agents/skills/develop-yui/SKILL.md` and the
179
368
  [verification policy](docs/testing/verification-levels.md).
180
369
  Source builds also need a Linux C compiler and static libc development libraries
@@ -187,6 +376,14 @@ that checkout; run its `setup` before stateful use. Do not use the global `yui`
187
376
  or `make link` to validate local changes. Live-model, paid or shared-resource
188
377
  tests require an explicit request for those resources.
189
378
 
379
+ ## Community and support
380
+
381
+ - Questions, bugs and feature requests: open a
382
+ [GitHub issue](https://github.com/zhangqian-silk/yui/issues).
383
+ - Security: see the [security policy](SECURITY.md). Yui targets one trusted
384
+ local user and is not an OS sandbox or a remote service; please report
385
+ sensitive issues privately instead of opening a public issue.
386
+
190
387
  ## License
191
388
 
192
389
  [MIT](LICENSE)
@@ -122,6 +122,13 @@ export function operationalAgentEnvironment(adapterId, source) {
122
122
  || `${dirname(process.execPath)}:/usr/local/bin:/usr/bin:/bin`,
123
123
  HOME: source.HOME || homedir(),
124
124
  TERM: usableInteractiveTerminal(source.TERM),
125
+ // Base fallback only. Every managed Task launch has its isolation
126
+ // environment (TMPDIR = the Home-side runtime `roots.temporary`) assigned
127
+ // OVER this by the launch planner, so this branch is reached only by
128
+ // non-isolated global/ad-hoc launches with no managed runtime. Those run in
129
+ // the operator's own context, where their inherited TMPDIR (or the system
130
+ // temp) is the correct scratch — forcing it under control Home would
131
+ // misroute user scratch into Yui-managed storage.
125
132
  TMPDIR: source.TMPDIR || tmpdir()
126
133
  };
127
134
  }
@@ -0,0 +1,74 @@
1
+ import { openTaskArtifactRepository } from "./taskArtifactRepository.js";
2
+ import { saveArtifactFile } from "./gitArtifactRef.js";
3
+ import { requireCommitId } from "./managedGit.js";
4
+ import { safeRelativeArtifactPath } from "./artifactPaths.js";
5
+ /**
6
+ * Capability-shaped adapter over the per-Task local Git artifact repository.
7
+ *
8
+ * This is the file/directory artifact surface behind the `artifact.save`,
9
+ * `artifact.read` and `artifact.list` capabilities and the `yui task artifact`
10
+ * CLI. It deliberately does NOT reintroduce the immutable-record `artifact.save`
11
+ * shape: an artifact is now a file at a `relativePath`, saved by editing and
12
+ * committing it in the Task's local repository. The save returns a
13
+ * self-certifying commit-pinned reference (`taskId + commit + relativePath`),
14
+ * which is the identity used for frozen Candidate/Review/completion evidence.
15
+ *
16
+ * Content is handled as UTF-8 text with the same 8 MiB cap as the former
17
+ * immutable text artifact. Binary artifacts, high-frequency runtime data and
18
+ * very large files are out of scope for this first version by contract (§3.5)
19
+ * and are rejected or referenced through their existing resource boundary, not
20
+ * carried here.
21
+ */
22
+ /** Text cap for a single artifact file, mirroring the former immutable-artifact limit. */
23
+ const MAX_ARTIFACT_TEXT_BYTES = 8 * 1024 * 1024;
24
+ function requireTextContent(content) {
25
+ if (typeof content !== "string")
26
+ throw new Error("Artifact content must be UTF-8 text.");
27
+ const bytes = Buffer.from(content, "utf8");
28
+ if (bytes.byteLength > MAX_ARTIFACT_TEXT_BYTES) {
29
+ throw new Error(`Artifact content must be UTF-8 text of at most ${MAX_ARTIFACT_TEXT_BYTES} bytes.`);
30
+ }
31
+ return bytes;
32
+ }
33
+ /**
34
+ * `artifact.save`: write `content` to `relativePath` in the Task's local repo,
35
+ * commit exactly that path, and return the resulting commit-pinned reference.
36
+ */
37
+ export async function saveArtifactCapability(home, taskId, input) {
38
+ const bytes = requireTextContent(input.content);
39
+ return saveArtifactFile(home, taskId, {
40
+ relativePath: input.relativePath,
41
+ bytes,
42
+ ...(input.message === undefined ? {} : { message: input.message }),
43
+ ...(input.expectedHead === undefined ? {} : { expectedHead: input.expectedHead })
44
+ });
45
+ }
46
+ /**
47
+ * `artifact.read`: read `relativePath` at HEAD, or at a pinned `commit` for
48
+ * frozen evidence. Returns the bytes as UTF-8 text plus the resolved commit and
49
+ * digest, so a caller can record or verify the exact reference.
50
+ */
51
+ export async function readArtifactCapability(home, taskId, input) {
52
+ const repo = openTaskArtifactRepository(home, taskId);
53
+ if (!repo.exists())
54
+ throw new Error(`Artifact repository is unavailable for ${taskId}.`);
55
+ const safeRelative = safeRelativeArtifactPath(input.relativePath);
56
+ const content = await repo.read(safeRelative, input.commit === undefined ? undefined : requireCommitId(input.commit));
57
+ return {
58
+ taskId,
59
+ relativePath: content.relativePath,
60
+ commit: content.commit,
61
+ content: content.bytes.toString("utf8"),
62
+ digest: content.digest
63
+ };
64
+ }
65
+ /**
66
+ * `artifact.list`: tracked artifacts at HEAD (empty when the Task has no repo
67
+ * yet). This is an ordinary current read; it does not freeze anything.
68
+ */
69
+ export async function listArtifactsCapability(home, taskId) {
70
+ const repo = openTaskArtifactRepository(home, taskId);
71
+ if (!repo.exists())
72
+ return [];
73
+ return repo.list();
74
+ }