@zq-silk/yui 0.15.7 → 0.15.8

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 (281) hide show
  1. package/ARCHITECTURE.md +192 -399
  2. package/README.md +127 -1149
  3. package/dist/agent/adapterCatalog.js +15 -2
  4. package/dist/agent/agent.js +23 -3
  5. package/dist/agent/argumentPolicy.js +7 -1
  6. package/dist/agent/connectionPlan.js +62 -0
  7. package/dist/agent/executionComponents.js +158 -0
  8. package/dist/agent/launchEnvironment.js +31 -3
  9. package/dist/agent/managedRuntimeEnvironment.js +3 -5
  10. package/dist/{turn/turn.js → agentRun/agentRun.js} +166 -109
  11. package/dist/{turn/turnIdentity.js → agentRun/runIdentity.js} +4 -4
  12. package/dist/brief/taskBrief.js +12 -0
  13. package/dist/cli/agentConfigurationPicker.js +13 -0
  14. package/dist/cli/commandCatalog.js +157 -70
  15. package/dist/cli/interactionCandidates.js +5 -5
  16. package/dist/cli/interactionPolicy.js +38 -8
  17. package/dist/cli/invocationRouter.js +1 -1
  18. package/dist/cli/managedDiagnostics.js +28 -0
  19. package/dist/cli/operatorWizard.js +1 -7
  20. package/dist/cli/roleOptionOrder.js +27 -0
  21. package/dist/cli/roleWizard.js +50 -14
  22. package/dist/cli/updateOrchestrator.js +1 -1
  23. package/dist/cli/updatePorts.js +3 -4
  24. package/dist/cli.js +178 -95
  25. package/dist/commands/agentCommands.js +72 -14
  26. package/dist/commands/capabilityCommands.js +9 -6
  27. package/dist/commands/configCommands.js +20 -20
  28. package/dist/commands/deliveryGuardPreflight.js +2 -2
  29. package/dist/commands/executionAuditCommands.js +24 -24
  30. package/dist/commands/globalRoleCommands.js +1 -1
  31. package/dist/commands/grantCommands.js +4 -4
  32. package/dist/commands/operatorCommands.js +1 -7
  33. package/dist/commands/projectCommands.js +4 -4
  34. package/dist/commands/resourcesCommands.js +2 -2
  35. package/dist/commands/roleConfiguration.js +25 -5
  36. package/dist/commands/roleRuntimeGuard.js +4 -5
  37. package/dist/commands/sessionCommands.js +3 -7
  38. package/dist/commands/taskActivationCommands.js +259 -0
  39. package/dist/commands/taskActor.js +28 -49
  40. package/dist/commands/taskCommands.js +1188 -710
  41. package/dist/commands/taskContextCommand.js +39 -583
  42. package/dist/commands/taskExecutionCommands.js +32 -32
  43. package/dist/commands/taskInputCommands.js +40 -104
  44. package/dist/commands/taskIntegrationCommands.js +3 -2
  45. package/dist/commands/taskIntegrationQueueCommands.js +1 -1
  46. package/dist/commands/taskNextActionCommand.js +8 -8
  47. package/dist/commands/taskOverviewCommand.js +33 -45
  48. package/dist/commands/taskRemoteDeliveryCommand.js +2 -2
  49. package/dist/commands/taskRoleRuntimeStatus.js +133 -102
  50. package/dist/commands/telemetryCommands.js +36 -38
  51. package/dist/config/configCatalog.js +4 -4
  52. package/dist/config/yuiConfig.js +8 -8
  53. package/dist/context/contextSnapshot.js +10 -10
  54. package/dist/context/dispatchContext.js +11 -11
  55. package/dist/context/roleSessionContext.js +6 -3
  56. package/dist/context/{turnContextPack.js → runContextPack.js} +146 -81
  57. package/dist/context/{turnInputContract.js → runInputContract.js} +73 -60
  58. package/dist/context/sessionBootstrapManifest.js +21 -2
  59. package/dist/context/sourceRunContext.js +30 -0
  60. package/dist/context/taskContext.js +458 -0
  61. package/dist/context/wakeNotification.js +27 -27
  62. package/dist/controller/agentRuntimeObserver.js +21 -24
  63. package/dist/controller/capabilityBridge.js +17 -6
  64. package/dist/controller/clientRuntime.js +65 -92
  65. package/dist/controller/controller.js +114 -188
  66. package/dist/controller/fileSchedulerStoreAdapter.js +787 -887
  67. package/dist/controller/jobControl.js +54 -85
  68. package/dist/controller/resourceInventory.js +8 -27
  69. package/dist/controller/resourceInventoryLinux.js +12 -13
  70. package/dist/controller/runtime.js +529 -479
  71. package/dist/controller/runtimeEventInbox.js +55 -25
  72. package/dist/controller/runtimeEventProcessor.js +22 -31
  73. package/dist/controller/{runtimeHookTurnFence.js → runtimeHookRunFence.js} +91 -115
  74. package/dist/controller/runtimeLaunchCoordinator.js +80 -426
  75. package/dist/controller/runtimeObservationHook.js +14 -18
  76. package/dist/controller/sessionNotify.js +16 -24
  77. package/dist/controller/sessionOwnerReconciliation.js +168 -50
  78. package/dist/controller/structuredProviderObservation.js +138 -99
  79. package/dist/coordination/workMailbox.js +3 -3
  80. package/dist/coordination/workMailboxQueue.js +36 -33
  81. package/dist/core/boundedRpc.js +8 -1
  82. package/dist/core/controllerClient.js +20 -1
  83. package/dist/core/controllerServer.js +4 -4
  84. package/dist/doctor/doctor.js +13 -2
  85. package/dist/domain/agentResultTransport.js +9 -9
  86. package/dist/execution/codexThreadNaming.js +2 -8
  87. package/dist/execution/executionHealth.js +51 -63
  88. package/dist/execution/reviewMainRun.js +137 -0
  89. package/dist/execution/workItemExecution.js +28 -29
  90. package/dist/execution/workItemExecutionProjection.js +99 -107
  91. package/dist/execution/workItemMainRun.js +141 -0
  92. package/dist/executor/agentAdapter.js +227 -20
  93. package/dist/executor/agentConfigurationCatalog.js +126 -4
  94. package/dist/executor/agentConfigurationProbe.js +162 -4
  95. package/dist/executor/agentExecutor.js +79 -78
  96. package/dist/executor/effectiveLaunch.js +105 -18
  97. package/dist/executor/executorRegistry.js +29 -44
  98. package/dist/executor/fileRoleLaunchPlanner.js +229 -154
  99. package/dist/executor/workspacePreflightClassification.js +16 -16
  100. package/dist/grant/capabilityGrant.js +6 -3
  101. package/dist/input/inputRequest.js +12 -10
  102. package/dist/integration/gitIntegrationService.js +4 -11
  103. package/dist/integration/integrationQueueService.js +4 -4
  104. package/dist/interaction/operatorPresentation.js +1 -1
  105. package/dist/kernel/builtinCapabilities.js +247 -12
  106. package/dist/kernel/capabilityRegistry.js +64 -18
  107. package/dist/kernel/instanceHost.js +12 -1
  108. package/dist/kernel/kernelPorts.js +2 -2
  109. package/dist/lifecycle/canonicalLifecycleEvent.js +44 -49
  110. package/dist/lifecycle/exactRunTerminalization.js +449 -0
  111. package/dist/message/message.js +62 -6
  112. package/dist/message/messageContinuation.js +204 -0
  113. package/dist/observability/executionAudit.js +70 -72
  114. package/dist/observability/faultClassification.js +2 -2
  115. package/dist/observability/orchestrationMetrics.js +8 -8
  116. package/dist/operator/operatorSessionHistory.js +1 -7
  117. package/dist/output/agentConfigurationPresentation.js +8 -3
  118. package/dist/output/agentRunConfigurationPresentation.js +128 -0
  119. package/dist/output/rolePresentation.js +54 -3
  120. package/dist/plugins/pluginChild.js +104 -0
  121. package/dist/plugins/pluginIntent.js +26 -0
  122. package/dist/plugins/pluginInterpreter.js +43 -0
  123. package/dist/plugins/pluginPackage.js +101 -0
  124. package/dist/plugins/pluginProcess.js +112 -0
  125. package/dist/plugins/pluginService.js +380 -0
  126. package/dist/profile/agentProfile.js +1 -1
  127. package/dist/repository/gitWorkspace.js +26 -4
  128. package/dist/repository/project.js +19 -4
  129. package/dist/repository/taskBaseFreshness.js +13 -13
  130. package/dist/repository/taskWorkspaceCoordinator.js +20 -27
  131. package/dist/repository/taskWorkspacePreparer.js +344 -83
  132. package/dist/resources/autoResourceGc.js +3 -3
  133. package/dist/resources/liveReferences.js +3 -3
  134. package/dist/resources/projectResource.js +123 -0
  135. package/dist/resources/projectResourceService.js +421 -0
  136. package/dist/resources/resourceDiscovery.js +6 -6
  137. package/dist/resources/resourceGc.js +1 -1
  138. package/dist/resources/resourceRegistrar.js +1 -1
  139. package/dist/resources/resourceTypes.js +1 -1
  140. package/dist/review/deltaRecheck.js +3 -3
  141. package/dist/review/reviewAcceptance.js +16 -16
  142. package/dist/review/reviewDecision.js +7 -7
  143. package/dist/review/reviewRound.js +21 -20
  144. package/dist/review/reviewerAvailability.js +2 -2
  145. package/dist/role/role.js +51 -7
  146. package/dist/role/taskRoleUpdate.js +30 -0
  147. package/dist/runtime/acpProtocol.js +425 -0
  148. package/dist/runtime/acpSession.js +731 -0
  149. package/dist/runtime/acpSessionConfiguration.js +260 -0
  150. package/dist/runtime/agentDriver.js +30 -11
  151. package/dist/runtime/agentEndpoint.js +278 -0
  152. package/dist/runtime/agentEndpointIdentity.js +86 -0
  153. package/dist/runtime/agentEndpointOwnership.js +239 -0
  154. package/dist/runtime/agentError.js +2 -10
  155. package/dist/runtime/agentHost.js +565 -314
  156. package/dist/runtime/agentRunConfiguration.js +258 -0
  157. package/dist/runtime/builtinAgentDrivers.js +134 -18
  158. package/dist/runtime/builtinAgentErrorMappers.js +55 -3
  159. package/dist/runtime/builtinTranscriptUsage.js +1 -1
  160. package/dist/runtime/claude-process-owner +0 -0
  161. package/dist/runtime/codexAppServerRuntime.js +38 -30
  162. package/dist/runtime/codexInteractiveHost.js +41 -6
  163. package/dist/runtime/continuationManager.js +2 -6
  164. package/dist/runtime/executionEnvironment.js +30 -0
  165. package/dist/runtime/firstProgressAdvisory.js +11 -11
  166. package/dist/runtime/index.js +4 -3
  167. package/dist/runtime/jsonLineChannel.js +109 -0
  168. package/dist/runtime/launchBroker.js +91 -16
  169. package/dist/runtime/launchDiagnostics.js +2 -2
  170. package/dist/runtime/lifecycleReservation.js +10 -18
  171. package/dist/runtime/managedCaller.js +61 -17
  172. package/dist/runtime/nativeSessionControl.js +102 -0
  173. package/dist/runtime/ports.js +6 -21
  174. package/dist/runtime/processExitObservation.js +8 -7
  175. package/dist/runtime/promptEnvelope.js +17 -6
  176. package/dist/runtime/providerContinuation.js +3 -9
  177. package/dist/runtime/providerContinuationReconciliationService.js +4 -13
  178. package/dist/runtime/providerControl.js +2 -7
  179. package/dist/runtime/providerRuntimeIdentity.js +110 -222
  180. package/dist/runtime/providerRuntimeReconciler.js +5 -9
  181. package/dist/runtime/runtimeBinding.js +0 -1
  182. package/dist/runtime/runtimeContinuationProjection.js +4 -7
  183. package/dist/runtime/runtimeDeadlines.js +9 -0
  184. package/dist/runtime/runtimeHealthPolicy.js +1 -1
  185. package/dist/runtime/runtimeObservation.js +29 -65
  186. package/dist/runtime/runtimeProjection.js +43 -51
  187. package/dist/runtime/runtimeSessionCandidate.js +1 -3
  188. package/dist/runtime/sessionLaunchRequest.js +3 -7
  189. package/dist/runtime/sessionOwnerIdentity.js +7 -54
  190. package/dist/runtime/sessionOwnerRegistry.js +22 -17
  191. package/dist/runtime/sessionReconciliation.js +4 -8
  192. package/dist/runtime/sessionTerminationGuard.js +70 -259
  193. package/dist/runtime/sessionTokenMetrics.js +5 -16
  194. package/dist/runtime/structuredProviderHost.js +237 -117
  195. package/dist/runtime/taskRuntimeIsolation.js +39 -122
  196. package/dist/runtime/tmuxAdapters.js +39 -86
  197. package/dist/scheduler/activeRoleRunDelivery.js +354 -0
  198. package/dist/scheduler/leaderWakeupProcessor.js +75 -266
  199. package/dist/scheduler/operatorInputNotificationProcessor.js +1 -1
  200. package/dist/scheduler/ports.js +80 -9
  201. package/dist/scheduler/{roleTurnLiveness.js → roleRunLiveness.js} +26 -30
  202. package/dist/scheduler/{roleTurnStall.js → roleRunStall.js} +128 -139
  203. package/dist/scheduler/taskExecutionProjection.js +120 -124
  204. package/dist/scheduler/taskObservabilityProjection.js +29 -29
  205. package/dist/scheduler/taskWake.js +11 -4
  206. package/dist/scheduler/wakeReason.js +9 -1
  207. package/dist/setup/setupCommand.js +1 -0
  208. package/dist/storage/migrations/agentRunContract.js +159 -0
  209. package/dist/storage/migrations/removeRuntimeGeneration.js +207 -0
  210. package/dist/storage/sqliteSchema.js +431 -5
  211. package/dist/storage/sqliteStore.js +375 -220
  212. package/dist/storage/storageVersions.js +1 -1
  213. package/dist/storage/storeRpc.js +10 -5
  214. package/dist/storage/taskStore.js +13 -11
  215. package/dist/storage/upgrade/upgradeOrchestrator.js +5 -7
  216. package/dist/surface/surfaceContributions.js +102 -0
  217. package/dist/task/completionReadiness.js +32 -6
  218. package/dist/task/deliveryGuard.js +16 -16
  219. package/dist/task/draftPlan.js +72 -12
  220. package/dist/task/nextAction.js +144 -128
  221. package/dist/task/remoteDelivery.js +6 -6
  222. package/dist/task/task.js +184 -18
  223. package/dist/task/taskActivation.js +301 -0
  224. package/dist/task/taskActivationService.js +392 -0
  225. package/dist/task/taskRecordReference.js +5 -4
  226. package/dist/task/taskRecordRetirement.js +1 -1
  227. package/dist/telemetry/sqliteTelemetryStore.js +55 -68
  228. package/dist/telemetry/telemetryConfig.js +14 -14
  229. package/dist/telemetry/telemetryWiring.js +2 -2
  230. package/dist/web/assets/assetManifest.js +2 -0
  231. package/dist/web/assets/client/app.js +120 -20
  232. package/dist/web/assets/client/components.js +87 -54
  233. package/dist/web/assets/client/i18n.js +83 -41
  234. package/dist/web/assets/client/markdown.js +1 -1
  235. package/dist/web/assets/client/taskSurface.js +353 -0
  236. package/dist/web/assets/client/view.js +49 -44
  237. package/dist/web/assets/shell.js +1 -1
  238. package/dist/web/assets/styles/cards.js +22 -4
  239. package/dist/web/controllerWeb.js +60 -0
  240. package/dist/web/webMutation.js +28 -0
  241. package/dist/web/webServer.js +118 -8
  242. package/dist/web/webSnapshot.js +81 -74
  243. package/dist/web/webTaskSurface.js +64 -0
  244. package/dist/workItem/dependencyGate.js +1 -1
  245. package/dist/workItem/workItem.js +80 -48
  246. package/dist/workspace/workItemChangeSetManager.js +16 -9
  247. package/docs/agent-result-consumption.md +94 -0
  248. package/docs/agent-runtime-drivers.md +91 -0
  249. package/docs/architecture/README.md +38 -0
  250. package/docs/architecture/capabilities-and-resources.md +79 -0
  251. package/docs/managed-turn-and-session-runtime.md +222 -0
  252. package/docs/observability/README.md +81 -0
  253. package/docs/plugin-sdk.md +290 -0
  254. package/docs/provider-runtime.md +163 -0
  255. package/docs/release-workflow.md +303 -0
  256. package/docs/roles-and-configuration.md +113 -0
  257. package/docs/sqlite-control-plane-design.md +76 -0
  258. package/docs/task-dag-semantics.md +57 -0
  259. package/docs/task-delivery.md +103 -0
  260. package/docs/task-local-identity.md +6 -6
  261. package/docs/testing/verification-levels.md +86 -0
  262. package/i18n/README.zh-CN.md +98 -739
  263. package/package.json +2 -2
  264. package/skills/yui-leader/SKILL.md +130 -103
  265. package/skills/yui-leader/references/integration.md +39 -0
  266. package/skills/yui-leader/references/replicated-execution.md +42 -0
  267. package/skills/yui-leader/references/task-plugins.md +33 -0
  268. package/skills/yui-operator/SKILL.md +30 -59
  269. package/skills/yui-reviewer/SKILL.md +35 -36
  270. package/skills/yui-runtime/SKILL.md +88 -24
  271. package/skills/yui-runtime/references/publication.md +22 -0
  272. package/skills/yui-runtime/references/recovery.md +64 -0
  273. package/skills/yui-worker/SKILL.md +37 -39
  274. package/dist/cli/roleOptionCatalog.js +0 -68
  275. package/dist/context/sourceTurnContext.js +0 -30
  276. package/dist/execution/reviewMainTurn.js +0 -161
  277. package/dist/execution/workItemMainTurn.js +0 -164
  278. package/dist/lifecycle/exactTurnTerminalization.js +0 -407
  279. package/dist/runtime/preallocatedNativeSession.js +0 -13
  280. package/dist/runtime/runtimeStopReceipt.js +0 -42
  281. package/dist/scheduler/activeRoleTurnDelivery.js +0 -315
@@ -1,10 +1,23 @@
1
1
  export const AGENT_ADAPTER_CATALOG = Object.freeze([
2
2
  Object.freeze({ id: "codex", label: "Codex" }),
3
- Object.freeze({ id: "claude", label: "Claude" })
3
+ Object.freeze({ id: "claude", label: "Claude" }),
4
+ // One adapter for the Agent Client Protocol, not one per product. Which ACP
5
+ // Agent runs is a launch descriptor fact, so a further ACP product needs no
6
+ // new adapter and no new branch anywhere above this line.
7
+ Object.freeze({ id: "acp", label: "Agent Client Protocol" })
4
8
  ]);
5
9
  export function supportedAgentAdapterIds() {
6
10
  return AGENT_ADAPTER_CATALOG.map(({ id }) => id).sort();
7
11
  }
8
12
  export function isAgentAdapterId(value) {
9
- return value === "codex" || value === "claude";
13
+ return AGENT_ADAPTER_CATALOG.some(({ id }) => id === value);
14
+ }
15
+ /**
16
+ * The catalog's own display label, falling back to the raw id.
17
+ *
18
+ * The fallback is deliberate: a stored binding may name an adapter this build
19
+ * no longer ships, and showing that id is more useful than hiding it.
20
+ */
21
+ export function agentAdapterLabel(adapterId) {
22
+ return AGENT_ADAPTER_CATALOG.find(({ id }) => id === adapterId)?.label ?? adapterId;
10
23
  }
@@ -1,6 +1,7 @@
1
1
  import { isAgentAdapterId } from "./adapterCatalog.js";
2
+ import { adapterIdForExecutionComponent, resolveAgentExecutionComponent } from "./executionComponents.js";
2
3
  import { validateAgentBaseArguments } from "./argumentPolicy.js";
3
- export function createConfiguredAgent(id, adapterId, command, baseArgs, environment, now) {
4
+ export function createConfiguredAgent(id, adapterId, command, baseArgs, environment, now, component) {
4
5
  const normalizedId = requireSafeIdentity(id, "Agent id");
5
6
  if (!isAgentAdapterId(adapterId))
6
7
  throw new Error(`Agent adapter is unsupported: ${adapterId}.`);
@@ -8,8 +9,11 @@ export function createConfiguredAgent(id, adapterId, command, baseArgs, environm
8
9
  validateAgentBaseArguments(adapterId, baseArgs);
9
10
  const timestamp = now.toISOString();
10
11
  return {
11
- schemaVersion: 2,
12
+ schemaVersion: 3,
12
13
  id: normalizedId,
14
+ // An unnamed component resolves from the plan, which for ACP means the
15
+ // unidentified entry rather than a guess at which product is installed.
16
+ component: resolveAgentExecutionComponent(adapterId, component),
13
17
  adapterId,
14
18
  command: normalizedCommand,
15
19
  baseArgs: [...baseArgs],
@@ -41,11 +45,27 @@ export function resolveAgentEnvironment(agent, processEnvironment = process.env)
41
45
  }));
42
46
  }
43
47
  export function validateConfiguredAgent(agent) {
44
- if (agent.schemaVersion !== 2)
48
+ if (agent.schemaVersion !== 3)
45
49
  throw new Error("Agent schema version is invalid.");
46
50
  requireSafeIdentity(agent.id, "Agent id");
47
51
  if (!isAgentAdapterId(agent.adapterId))
48
52
  throw new Error(`Agent adapter is unsupported: ${agent.adapterId}.`);
53
+ // A schema 3 record always carries a component: storage 10 backfilled every
54
+ // stored Agent, and the constructor resolves one for every new Agent. So an
55
+ // absent value here is a corrupt record, not an old one, and resolving it to
56
+ // the plan default would invent a product identity for data that never lost
57
+ // one. That default belongs to the constructor, where an operator naming
58
+ // only a plan is a real and supported request — this validator reads records
59
+ // that were already written, where the same silence means something else.
60
+ if (agent.component === undefined) {
61
+ throw new Error(`Agent is missing its execution component: ${agent.id}.`);
62
+ }
63
+ // The component determines its plan, so a stored pair that disagrees is
64
+ // corruption rather than a configuration the operator can act on.
65
+ const expected = adapterIdForExecutionComponent(resolveAgentExecutionComponent(agent.adapterId, agent.component));
66
+ if (expected !== agent.adapterId) {
67
+ throw new Error(`Agent execution component ${agent.component} does not match adapter ${agent.adapterId}.`);
68
+ }
49
69
  requireText(agent.command, "Agent command");
50
70
  validateAgentBaseArguments(agent.adapterId, agent.baseArgs);
51
71
  if (!Array.isArray(agent.environment))
@@ -18,7 +18,13 @@ const OWNED_ARGUMENTS_BY_ADAPTER = {
18
18
  "--fallback-model", "--tools", "--system-prompt", "--system-prompt-file",
19
19
  "--append-system-prompt", "--append-system-prompt-file", "--plugin-dir",
20
20
  "--name", "-n", "--output-format", "--input-format"
21
- ]
21
+ ],
22
+ // The ACP adapter compiles no arguments of its own: the protocol is spoken
23
+ // over stdio once the product is running, and how a given product enters ACP
24
+ // mode (`acp`, `--experimental-acp`, …) is a descriptor fact. Reserving any
25
+ // name here would both encode one product's spelling and reject the very
26
+ // baseArgs that select ACP mode.
27
+ acp: []
22
28
  };
23
29
  export function ownedArgumentsForAdapter(adapterId) {
24
30
  return OWNED_ARGUMENTS_BY_ADAPTER[adapterId];
@@ -0,0 +1,62 @@
1
+ /**
2
+ * The connection plan: how Yui reaches an execution component.
3
+ *
4
+ * Yui's adapter id has always carried this meaning, but two of its values are
5
+ * product names and one is a protocol name, which reads as a single mixed axis.
6
+ * Nothing about the plans changes here; they are stated explicitly instead of
7
+ * being implied by an adapter id and a lookup table elsewhere.
8
+ *
9
+ * A plan names its protocol and its transport together, as one authoritative
10
+ * binding. Protocol and transport are not independently selectable: there is no
11
+ * combination graph to assemble, because a wire protocol and the carrier it
12
+ * runs over are decided as a pair by the implementation that speaks them.
13
+ *
14
+ * Static protocol support is what this table records: what Yui's own client
15
+ * implements. It is not what a given Agent agreed to. Live handshake facts are
16
+ * negotiated per connection and reported separately; where a plan negotiates
17
+ * nothing, its handshake is explicitly `none` rather than silently absent.
18
+ */
19
+ import { AGENT_ADAPTER_CATALOG } from "./adapterCatalog.js";
20
+ export const AGENT_CONNECTION_PLANS = Object.freeze([
21
+ Object.freeze({
22
+ id: "codex",
23
+ label: "Codex app-server",
24
+ protocol: "codex-app-server",
25
+ // Codex versions its app-server interface with the CLI, not separately.
26
+ protocolVersion: "unknown",
27
+ transport: "codex-app-server-proxy",
28
+ handshake: "none"
29
+ }),
30
+ Object.freeze({
31
+ id: "claude",
32
+ label: "Claude Code stream-json",
33
+ protocol: "claude-stream-json",
34
+ protocolVersion: "unknown",
35
+ transport: "claude-stream-json",
36
+ handshake: "none"
37
+ }),
38
+ Object.freeze({
39
+ id: "acp",
40
+ label: "Agent Client Protocol (stdio)",
41
+ protocol: "agent-client-protocol",
42
+ protocolVersion: "1",
43
+ transport: "acp-stdio",
44
+ handshake: "negotiated",
45
+ handshakeMethod: "initialize"
46
+ })
47
+ ]);
48
+ export function agentConnectionPlan(adapterId) {
49
+ const plan = AGENT_CONNECTION_PLANS.find(({ id }) => id === adapterId);
50
+ if (plan === undefined) {
51
+ throw new Error(`No connection plan for adapter: ${adapterId}.`);
52
+ }
53
+ return plan;
54
+ }
55
+ export function agentTransportForAdapter(adapterId) {
56
+ return agentConnectionPlan(adapterId).transport;
57
+ }
58
+ // Every catalogued adapter must have exactly one plan. Checking at module load
59
+ // turns a missing entry into an immediate, obvious failure rather than a
60
+ // transport mismatch surfacing at launch.
61
+ for (const { id } of AGENT_ADAPTER_CATALOG)
62
+ agentConnectionPlan(id);
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Which execution component runs an Agent, stated independently from how Yui
3
+ * reaches it.
4
+ *
5
+ * Yui's adapter id answers one question: the connection plan — the protocol
6
+ * Yui speaks and the transport it speaks over. It deliberately does not answer
7
+ * "which product is running", because several distinct products are reachable
8
+ * through the same plan. The Agent Client Protocol is the clear case: Claude
9
+ * Code's CLI, the Claude Agent SDK bridge and any other ACP Agent all arrive
10
+ * over `acp`, and treating that protocol name as a product identity makes them
11
+ * indistinguishable in registration, display, Role bindings and Session
12
+ * snapshots.
13
+ *
14
+ * So the component is its own axis. Every component names exactly one
15
+ * connection plan it is reachable through, and that mapping is one-way and
16
+ * total: the component determines the plan, never the reverse. There is still
17
+ * exactly one authoritative binding to write, so the two facts cannot drift
18
+ * into disagreement, and no arbitrary component/protocol combination graph
19
+ * exists to be assembled.
20
+ *
21
+ * Naming follows the component that actually executes — a CLI or an SDK — and
22
+ * never "native", which names no product.
23
+ */
24
+ import { isAgentAdapterId } from "./adapterCatalog.js";
25
+ export const AGENT_EXECUTION_COMPONENT_CATALOG = Object.freeze([
26
+ Object.freeze({
27
+ id: "codex-cli",
28
+ label: "Codex CLI",
29
+ adapterId: "codex",
30
+ kind: "cli",
31
+ identified: true
32
+ }),
33
+ // Claude Code's own CLI, driven over its stream-json interface. This is a
34
+ // different access implementation from the SDK bridge below: different
35
+ // executable, different startup, different authentication surface and a
36
+ // different set of settings Yui can express. Neither one's configuration
37
+ // may be assumed to work for the other.
38
+ Object.freeze({
39
+ id: "claude-code-cli",
40
+ label: "Claude Code CLI",
41
+ adapterId: "claude",
42
+ kind: "cli",
43
+ identified: true
44
+ }),
45
+ // The Claude Agent SDK reached through an ACP bridge process. It speaks the
46
+ // protocol Yui already implements, so it needs no product branch in the
47
+ // codec — only its own identity here, so an operator can see and select it.
48
+ Object.freeze({
49
+ id: "claude-agent-sdk",
50
+ label: "Claude Agent SDK (ACP)",
51
+ adapterId: "acp",
52
+ kind: "sdk",
53
+ identified: true,
54
+ // The bridge exposes Claude Code's own permission modes, where
55
+ // `bypassPermissions` is the documented mode that skips approval
56
+ // prompts. The bridge offers it only when its own preconditions hold, so
57
+ // its presence in a Session's option list is still checked rather than
58
+ // assumed.
59
+ bypassPermissionMode: "bypassPermissions"
60
+ }),
61
+ // Every other ACP Agent, and every binding made before components were
62
+ // recorded. Yui does not know which product answers, and a command string
63
+ // is not evidence: an executable named `claude-agent-acp` may be a wrapper,
64
+ // a shim or something else entirely. Guessing a product here would attach a
65
+ // confident label to an unverified fact, so the honest value is this one.
66
+ // It states no bypass mode for the same reason: not knowing the product
67
+ // means not knowing which of its modes, if any, grants that authority.
68
+ Object.freeze({
69
+ id: "unknown-acp-agent",
70
+ label: "ACP Agent (unidentified)",
71
+ adapterId: "acp",
72
+ kind: "unknown",
73
+ identified: false
74
+ })
75
+ ]);
76
+ /**
77
+ * The component recorded when a connection plan is selected without naming one.
78
+ *
79
+ * A plan with a single possible component resolves to it. The ACP plan carries
80
+ * many products, so it resolves to the unidentified entry rather than to
81
+ * whichever product happens to be most common.
82
+ */
83
+ const DEFAULT_COMPONENT_BY_ADAPTER = Object.freeze({
84
+ codex: "codex-cli",
85
+ claude: "claude-code-cli",
86
+ acp: "unknown-acp-agent"
87
+ });
88
+ export function supportedAgentExecutionComponentIds() {
89
+ return AGENT_EXECUTION_COMPONENT_CATALOG.map(({ id }) => id).sort();
90
+ }
91
+ export function isAgentExecutionComponentId(value) {
92
+ return AGENT_EXECUTION_COMPONENT_CATALOG.some(({ id }) => id === value);
93
+ }
94
+ export function agentExecutionComponent(componentId) {
95
+ const entry = AGENT_EXECUTION_COMPONENT_CATALOG.find(({ id }) => id === componentId);
96
+ if (entry === undefined) {
97
+ throw new Error(`Agent execution component is unsupported: ${componentId}.`);
98
+ }
99
+ return entry;
100
+ }
101
+ /**
102
+ * The component's display label, falling back to the raw id.
103
+ *
104
+ * As with adapters, a stored binding may name a component this build no longer
105
+ * ships; showing that id is more useful than hiding it.
106
+ */
107
+ export function agentExecutionComponentLabel(componentId) {
108
+ return AGENT_EXECUTION_COMPONENT_CATALOG.find(({ id }) => id === componentId)?.label
109
+ ?? componentId;
110
+ }
111
+ /** The connection plan a component is reached through. */
112
+ export function adapterIdForExecutionComponent(componentId) {
113
+ return agentExecutionComponent(componentId).adapterId;
114
+ }
115
+ /** Components reachable through one connection plan, in catalog order. */
116
+ export function executionComponentsForAdapter(adapterId) {
117
+ return AGENT_EXECUTION_COMPONENT_CATALOG.filter((entry) => entry.adapterId === adapterId);
118
+ }
119
+ export function defaultExecutionComponentForAdapter(adapterId) {
120
+ return DEFAULT_COMPONENT_BY_ADAPTER[adapterId];
121
+ }
122
+ /**
123
+ * The component to show for a record that was parsed rather than constructed.
124
+ *
125
+ * Display surfaces read values back over the wire, where neither field is
126
+ * guaranteed to be a value this build knows. Refusing to render is the wrong
127
+ * answer there, so this never throws: a recognised component wins, an absent
128
+ * one falls back to its plan's default, and anything unrecognised is shown
129
+ * verbatim rather than replaced with a guess.
130
+ */
131
+ export function displayExecutionComponent(adapterId, componentId) {
132
+ if (componentId !== undefined)
133
+ return componentId;
134
+ return isAgentAdapterId(adapterId)
135
+ ? defaultExecutionComponentForAdapter(adapterId)
136
+ : adapterId;
137
+ }
138
+ /**
139
+ * Resolve the component for a connection plan, given what the caller stated.
140
+ *
141
+ * An absent component is not an error: it means the caller named only the plan,
142
+ * which is how every binding made before this axis existed reads. It resolves
143
+ * to the plan's default, which for ACP is the unidentified entry — the value is
144
+ * never inferred from a command, an argument or an environment variable.
145
+ */
146
+ export function resolveAgentExecutionComponent(adapterId, componentId) {
147
+ if (componentId === undefined)
148
+ return defaultExecutionComponentForAdapter(adapterId);
149
+ if (!isAgentExecutionComponentId(componentId)) {
150
+ throw new Error(`Agent execution component is unsupported: ${componentId}.`);
151
+ }
152
+ const expected = adapterIdForExecutionComponent(componentId);
153
+ if (expected !== adapterId) {
154
+ throw new Error(`Agent execution component ${componentId} is reached over the ${expected} `
155
+ + `connection plan, not ${adapterId}.`);
156
+ }
157
+ return componentId;
158
+ }
@@ -56,14 +56,42 @@ export const AGENT_OPERATIONAL_ENVIRONMENT_NAMES = [
56
56
  "REQUESTS_CA_BUNDLE",
57
57
  "SSH_AUTH_SOCK"
58
58
  ];
59
+ /** Native account context. Credential values remain volatile and belong only
60
+ * to this adapter; they are never copied into Roles, Tasks or launch arguments.
61
+ * Do not inherit numeric credential FDs across unrelated processes. */
62
+ const CLAUDE_NATIVE_ENVIRONMENT_NAMES = [
63
+ "CLAUDE_CONFIG_DIR",
64
+ "ANTHROPIC_API_KEY",
65
+ "ANTHROPIC_BASE_URL",
66
+ "ANTHROPIC_AUTH_TOKEN",
67
+ "ANTHROPIC_CUSTOM_HEADERS",
68
+ "ANTHROPIC_PROFILE",
69
+ "CLAUDE_CODE_OAUTH_TOKEN",
70
+ "ANTHROPIC_DEFAULT_OPUS_MODEL",
71
+ "ANTHROPIC_DEFAULT_SONNET_MODEL",
72
+ "ANTHROPIC_DEFAULT_HAIKU_MODEL",
73
+ "CLAUDE_CODE_SUBAGENT_MODEL",
74
+ "CLAUDE_CODE_USE_BEDROCK",
75
+ "CLAUDE_CODE_USE_VERTEX",
76
+ "CLAUDE_CODE_USE_FOUNDRY",
77
+ "CLAUDE_CODE_USE_GATEWAY",
78
+ "CLAUDE_CODE_PROVIDER_MANAGED_BY_HOST",
79
+ "CLAUDE_CODE_HOST_CREDS_FILE",
80
+ "CLAUDE_CODE_API_KEY_HELPER_TTL_MS",
81
+ "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC",
82
+ "DISABLE_AUTOUPDATER"
83
+ ];
59
84
  export const NATIVE_AGENT_ENVIRONMENT_NAMES = [
60
- "CODEX_HOME",
61
- "CLAUDE_CONFIG_DIR"
85
+ "CODEX_HOME", ...CLAUDE_NATIVE_ENVIRONMENT_NAMES
62
86
  ];
63
87
  export function nativeAgentEnvironmentNames(adapterId) {
64
88
  switch (adapterId) {
65
89
  case "codex": return ["CODEX_HOME"];
66
- case "claude": return ["CLAUDE_CONFIG_DIR"];
90
+ case "claude": return CLAUDE_NATIVE_ENVIRONMENT_NAMES;
91
+ // ACP standardizes the protocol, not where a product keeps its
92
+ // configuration. Naming a variable here would be a product branch, so an
93
+ // ACP Agent that needs one declares it as an ordinary environment binding.
94
+ case "acp": return [];
67
95
  }
68
96
  }
69
97
  export function selectEnvironment(source, names) {
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Environment values owned by Yui's managed runtime.
3
3
  *
4
- * These values carry control-plane, Task, workspace, or runtime generation identity. They
4
+ * These values carry control-plane, Task, workspace, or runtime identity. They
5
5
  * are never user Agent environment bindings, and an ordinary repository test
6
6
  * must not inherit them from the managed Session that launched the test
7
7
  * command.
@@ -16,8 +16,7 @@ export const YUI_MANAGED_RUNTIME_ENVIRONMENT_NAMES = Object.freeze([
16
16
  "YUI_ADAPTER_ID",
17
17
  "YUI_DRIVER_ID",
18
18
  "YUI_WORKSPACE",
19
- "YUI_TURN_ID",
20
- "YUI_RUNTIME_GENERATION_ID",
19
+ "YUI_RUN_ID",
21
20
  "YUI_NATIVE_SESSION_ROOT",
22
21
  "YUI_NATIVE_SESSION_ID",
23
22
  // Retired: Yui no longer publishes a frozen control-plane descriptor into a
@@ -31,6 +30,5 @@ export const YUI_MANAGED_RUNTIME_ENVIRONMENT_NAMES = Object.freeze([
31
30
  "YUI_AGENT_BASE_ARGS",
32
31
  "YUI_WRITABLE_PROJECT_IDS",
33
32
  "YUI_CONTEXT_PROJECT_IDS",
34
- "YUI_WORKSPACE_PROJECTS",
35
- "YUI_JOB_CALLER_KEY"
33
+ "YUI_WORKSPACE_PROJECTS"
36
34
  ]);