@jingyi0605/codingns4dsh 0.1.2 → 0.1.7-rc.3

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 (171) hide show
  1. package/README.en.md +4 -4
  2. package/README.md +14 -5
  3. package/data/build/dist/client/account-bar.js +57 -3
  4. package/data/build/dist/client/bundle.js +36246 -268
  5. package/data/build/dist/client/cli-slots.js +60 -18
  6. package/data/build/dist/client/dsh-h5-bootstrap.d.ts +2 -0
  7. package/data/build/dist/client/dsh-h5-bootstrap.js +79 -13
  8. package/data/build/dist/client/features/file-management-panel.d.ts +5 -0
  9. package/data/build/dist/client/features/file-management-panel.js +48 -0
  10. package/data/build/dist/client/features/file-management.d.ts +4 -0
  11. package/data/build/dist/client/features/file-management.js +50 -0
  12. package/data/build/dist/client/features/index.d.ts +10 -1
  13. package/data/build/dist/client/features/index.js +12 -1
  14. package/data/build/dist/client/features/login-protection-panel.js +1 -1
  15. package/data/build/dist/client/features/login-protection-session.d.ts +2 -0
  16. package/data/build/dist/client/features/login-protection-session.js +18 -0
  17. package/data/build/dist/client/features/peer-host.d.ts +4 -0
  18. package/data/build/dist/client/features/peer-host.js +89 -0
  19. package/data/build/dist/client/features/reverse-proxy-panel.js +23 -7
  20. package/data/build/dist/client/features/reverse-proxy.d.ts +1 -2
  21. package/data/build/dist/client/features/reverse-proxy.js +75 -5
  22. package/data/build/dist/client/features/types.d.ts +9 -0
  23. package/data/build/dist/client/features/workspace-session-enhancement-panel.js +10 -0
  24. package/data/build/dist/client/features/workspace-session-enhancement.js +18 -1
  25. package/data/build/dist/client/file-management-dom.d.ts +12 -0
  26. package/data/build/dist/client/file-management-dom.js +527 -0
  27. package/data/build/dist/client/git-management.js +24 -5
  28. package/data/build/dist/client/host-navigation.d.ts +29 -0
  29. package/data/build/dist/client/host-navigation.js +29 -0
  30. package/data/build/dist/client/host-router.d.ts +3 -0
  31. package/data/build/dist/client/host-router.js +2 -0
  32. package/data/build/dist/client/index.d.ts +6 -1
  33. package/data/build/dist/client/index.js +30 -10
  34. package/data/build/dist/client/locale.js +36 -7
  35. package/data/build/dist/client/peer-host-connection-button.d.ts +13 -0
  36. package/data/build/dist/client/peer-host-connection-button.js +69 -0
  37. package/data/build/dist/client/peer-host-management-api.d.ts +40 -0
  38. package/data/build/dist/client/peer-host-management-api.js +33 -0
  39. package/data/build/dist/client/peer-host-management-panel.d.ts +13 -0
  40. package/data/build/dist/client/peer-host-management-panel.js +181 -0
  41. package/data/build/dist/client/peer-host-native-session-ui.d.ts +60 -0
  42. package/data/build/dist/client/peer-host-native-session-ui.js +372 -0
  43. package/data/build/dist/client/peer-host-scoped-client.d.ts +67 -0
  44. package/data/build/dist/client/peer-host-scoped-client.js +316 -0
  45. package/data/build/dist/client/peer-host-session-controller.d.ts +30 -0
  46. package/data/build/dist/client/peer-host-session-controller.js +95 -0
  47. package/data/build/dist/client/quick-phrase-slot.js +14 -0
  48. package/data/build/dist/client/remote-web-context.js +26 -4
  49. package/data/build/dist/client/session-changed-files-view.d.ts +15 -0
  50. package/data/build/dist/client/session-changed-files-view.js +337 -0
  51. package/data/build/dist/client/settings-bridge.d.ts +14 -4
  52. package/data/build/dist/client/settings-bridge.js +59 -12
  53. package/data/build/dist/client/settings-section.js +17 -4
  54. package/data/build/dist/client/subscription-slot.js +21 -8
  55. package/data/build/dist/client/workspace-session-rightbar-dom.d.ts +28 -0
  56. package/data/build/dist/client/workspace-session-rightbar-dom.js +291 -0
  57. package/data/build/dist/dsh-capabilities/client/config-forms-adapter.js +25 -33
  58. package/data/build/dist/dsh-capabilities/client/settings-scope-adapter.d.ts +7 -1
  59. package/data/build/dist/dsh-capabilities/client/settings-scope-adapter.js +34 -11
  60. package/data/build/dist/dsh-capabilities/matrix.js +9 -0
  61. package/data/build/dist/dsh-capabilities/routes.js +35 -0
  62. package/data/build/dist/dsh-capabilities/settings-store.d.ts +12 -0
  63. package/data/build/dist/dsh-capabilities/settings-store.js +34 -0
  64. package/data/build/dist/dsh-capabilities/types.d.ts +1 -1
  65. package/data/build/dist/features/host-router.d.ts +26 -0
  66. package/data/build/dist/features/host-router.js +110 -0
  67. package/data/build/dist/features/registry.js +3 -0
  68. package/data/build/dist/host/cli-adapters/codex-driver.d.ts +13 -1
  69. package/data/build/dist/host/cli-adapters/codex-driver.js +528 -72
  70. package/data/build/dist/host/cli-adapters/command-code-driver.d.ts +21 -2
  71. package/data/build/dist/host/cli-adapters/command-code-driver.js +408 -105
  72. package/data/build/dist/host/cli-adapters/driver.d.ts +2 -0
  73. package/data/build/dist/host/cli-adapters/dsh-message-projector.d.ts +2 -0
  74. package/data/build/dist/host/cli-adapters/dsh-message-projector.js +47 -28
  75. package/data/build/dist/host/cli-adapters/dsh-tool-history.js +37 -0
  76. package/data/build/dist/host/cli-adapters/feature.js +94 -10
  77. package/data/build/dist/host/cli-adapters/json-rpc-process.d.ts +6 -0
  78. package/data/build/dist/host/cli-adapters/json-rpc-process.js +14 -3
  79. package/data/build/dist/host/cli-adapters/kimi-driver.js +3 -3
  80. package/data/build/dist/host/cli-adapters/model-catalog.d.ts +6 -0
  81. package/data/build/dist/host/cli-adapters/model-catalog.js +8 -0
  82. package/data/build/dist/host/cli-adapters/opencode-driver.js +14 -2
  83. package/data/build/dist/host/cli-adapters/pi-driver.js +2 -2
  84. package/data/build/dist/host/cli-adapters/process-utils.d.ts +8 -0
  85. package/data/build/dist/host/cli-adapters/process-utils.js +48 -0
  86. package/data/build/dist/host/cli-adapters/registry.d.ts +6 -1
  87. package/data/build/dist/host/cli-adapters/registry.js +41 -7
  88. package/data/build/dist/host/cli-adapters/rpc-driver-utils.js +23 -4
  89. package/data/build/dist/host/cli-adapters/standard-stream-driver.d.ts +3 -0
  90. package/data/build/dist/host/cli-adapters/standard-stream-driver.js +36 -15
  91. package/data/build/dist/host/dsh-device-runtime.d.ts +2 -0
  92. package/data/build/dist/host/dsh-device-runtime.js +55 -29
  93. package/data/build/dist/host/dsh-runtime-version.d.ts +3 -2
  94. package/data/build/dist/host/dsh-runtime-version.js +71 -2
  95. package/data/build/dist/host/features/auth.js +10 -2
  96. package/data/build/dist/host/features/file-management.d.ts +5 -0
  97. package/data/build/dist/host/features/file-management.js +267 -0
  98. package/data/build/dist/host/features/git-management.js +24 -2
  99. package/data/build/dist/host/features/index.d.ts +2 -0
  100. package/data/build/dist/host/features/index.js +6 -0
  101. package/data/build/dist/host/features/peer-host.d.ts +22 -0
  102. package/data/build/dist/host/features/peer-host.js +322 -0
  103. package/data/build/dist/host/features/types.d.ts +4 -0
  104. package/data/build/dist/host/host-router.d.ts +3 -0
  105. package/data/build/dist/host/host-router.js +2 -0
  106. package/data/build/dist/host/index-injection.d.ts +17 -0
  107. package/data/build/dist/host/index-injection.js +24 -0
  108. package/data/build/dist/host/index.d.ts +4 -1
  109. package/data/build/dist/host/index.js +41 -7
  110. package/data/build/dist/host/lan-access-dsh.d.ts +34 -1
  111. package/data/build/dist/host/lan-access-dsh.js +145 -26
  112. package/data/build/dist/host/modules/peer-host/host-api-proxy-service.d.ts +52 -0
  113. package/data/build/dist/host/modules/peer-host/host-api-proxy-service.js +166 -0
  114. package/data/build/dist/host/modules/peer-host/host-ws-connector.d.ts +31 -0
  115. package/data/build/dist/host/modules/peer-host/host-ws-connector.js +108 -0
  116. package/data/build/dist/host/modules/peer-host/host-ws-proxy-service.d.ts +26 -0
  117. package/data/build/dist/host/modules/peer-host/host-ws-proxy-service.js +159 -0
  118. package/data/build/dist/host/modules/peer-host/peer-host-aggregate-service.d.ts +50 -0
  119. package/data/build/dist/host/modules/peer-host/peer-host-aggregate-service.js +97 -0
  120. package/data/build/dist/host/modules/peer-host/peer-host-diagnostics.d.ts +19 -0
  121. package/data/build/dist/host/modules/peer-host/peer-host-diagnostics.js +54 -0
  122. package/data/build/dist/host/modules/peer-host/peer-host-handshake.d.ts +44 -0
  123. package/data/build/dist/host/modules/peer-host/peer-host-handshake.js +133 -0
  124. package/data/build/dist/host/modules/peer-host/peer-host-relay.d.ts +65 -0
  125. package/data/build/dist/host/modules/peer-host/peer-host-relay.js +196 -0
  126. package/data/build/dist/host/modules/peer-host/peer-host-session.d.ts +42 -0
  127. package/data/build/dist/host/modules/peer-host/peer-host-session.js +152 -0
  128. package/data/build/dist/host/modules/peer-host/peer-host-store.d.ts +92 -0
  129. package/data/build/dist/host/modules/peer-host/peer-host-store.js +323 -0
  130. package/data/build/dist/host/modules/peer-host/peer-host-ws-gateway.d.ts +34 -0
  131. package/data/build/dist/host/modules/peer-host/peer-host-ws-gateway.js +156 -0
  132. package/data/build/dist/host/native-session-bridge.d.ts +18 -2
  133. package/data/build/dist/host/native-session-bridge.js +236 -8
  134. package/data/build/dist/host/remote-web-runtime.js +26 -1
  135. package/data/build/dist/host/rpc.js +8 -3
  136. package/data/build/dist/host/session-changes.d.ts +5 -0
  137. package/data/build/dist/host/session-changes.js +163 -0
  138. package/data/build/dist/host/settings.js +6 -0
  139. package/data/build/dist/index.d.ts +1 -1
  140. package/data/build/dist/index.js +1 -1
  141. package/data/build/dist/shared/contracts/cli-adapter.d.ts +23 -2
  142. package/data/build/dist/shared/contracts/config.d.ts +15 -0
  143. package/data/build/dist/shared/contracts/config.js +10 -0
  144. package/data/build/dist/shared/contracts/dsh-device.d.ts +2 -0
  145. package/data/build/dist/shared/contracts/errors.d.ts +14 -0
  146. package/data/build/dist/shared/contracts/errors.js +15 -0
  147. package/data/build/dist/shared/contracts/feature.d.ts +2 -0
  148. package/data/build/dist/shared/contracts/file-management.d.ts +6 -0
  149. package/data/build/dist/shared/contracts/file-management.js +3 -0
  150. package/data/build/dist/shared/contracts/peer-host.d.ts +116 -15
  151. package/data/build/dist/shared/contracts/peer-host.js +19 -0
  152. package/data/build/dist/shared/contracts/version.d.ts +1 -1
  153. package/data/build/dist/shared/contracts/version.js +1 -1
  154. package/data/build/dist/shared/index.d.ts +4 -3
  155. package/data/build/dist/shared/index.js +2 -2
  156. package/data/build/dist/transport/debug.d.ts +5 -0
  157. package/data/build/dist/transport/debug.js +23 -1
  158. package/data/build/dist/transport/dsh-transport.d.ts +2 -0
  159. package/data/build/dist/transport/dsh-transport.js +11 -0
  160. package/data/build/dist/transport/webrtc-client.d.ts +2 -0
  161. package/data/build/dist/transport/webrtc-client.js +2 -1
  162. package/data/build/dist/transport/webrtc-host.d.ts +2 -0
  163. package/data/build/dist/transport/webrtc-host.js +6 -3
  164. package/data/build/dist/typert.host.d.ts +1 -1
  165. package/data/build/dist/typert.host.js +2 -1
  166. package/dsh.bundle.patch +10 -0
  167. package/package.json +19 -11
  168. package/profile/README.md +2 -2
  169. package/profile/package.json +2 -2
  170. package/profile/version.json +1 -1
  171. package/version.json +1 -1
@@ -18,6 +18,7 @@ export function createDshCapabilityRegistry(dshVersion, runtime, context) {
18
18
  add({ id: 'connection-rpc-peer-aware', capability: 'connection.rpc', supportedDsh: rangeModern, runtime, priority: 20, status: 'supported', introducedIn: '0.1.7-rc.2', detect: (ctx) => ctx.connection !== undefined, create: (ctx) => ctx.connection });
19
19
  add({ id: 'connection-peer', capability: 'connection.peer', supportedDsh: rangeModern, runtime, priority: 20, status: 'supported', introducedIn: '0.1.7-rc.2', detect: (ctx) => ctx.connection?.peer !== undefined, create: (ctx) => ctx.connection.peer });
20
20
  add({ id: 'remote-result', capability: 'typert.remote', supportedDsh: '>=0.1.5-rc.3 <=0.1.7-rc.2', runtime, priority: 10, status: 'supported', introducedIn: '0.1.5-rc.3', detect: (ctx) => ctx.remote !== undefined, create: (ctx) => ctx.remote });
21
+ addPeerHostHostRoutes(add);
21
22
  }
22
23
  else {
23
24
  add({ id: 'settings-scope', capability: 'settings.store', supportedDsh: rangeLegacy, runtime, priority: 10, status: 'supported', introducedIn: '0.1.5-rc.3', detect: (ctx) => typeof ctx.settingsScope?.bind === 'function', create: (ctx) => ctx.settingsScope });
@@ -28,7 +29,41 @@ export function createDshCapabilityRegistry(dshVersion, runtime, context) {
28
29
  add({ id: 'conversation-events', capability: 'conversation.tool-call', supportedDsh: '>=0.1.5-rc.3 <=0.1.7-rc.2', runtime, priority: 10, status: 'supported', introducedIn: '0.1.5-rc.3', detect: (ctx) => ctx.uiConversation !== undefined, create: (ctx) => ctx.uiConversation });
29
30
  add({ id: 'sidebar-right', capability: 'sidebar.right', supportedDsh: '>=0.1.5-rc.3 <=0.1.7-rc.2', runtime, priority: 10, status: 'supported', introducedIn: '0.1.5-rc.3', detect: (ctx) => ctx.sidebarRight !== undefined, create: (ctx) => ctx.sidebarRight });
30
31
  add({ id: 'remote-result', capability: 'typert.remote', supportedDsh: '>=0.1.5-rc.3 <=0.1.7-rc.2', runtime, priority: 10, status: 'supported', introducedIn: '0.1.5-rc.3', detect: (ctx) => ctx.remote !== undefined, create: (ctx) => ctx.remote });
32
+ addPeerHostClientRoutes(add);
31
33
  }
32
34
  return registry;
33
35
  }
36
+ /** PeerHost Host 能力只接受显式注入的适配器,避免把普通 DSH 服务误报为已实现。 */
37
+ function addPeerHostHostRoutes(add) {
38
+ addPeerHostRoute(add, 'peer-host.store', 'peer-host-store', 'peerHostStore');
39
+ addPeerHostRoute(add, 'peer-host.handshake', 'peer-host-handshake', 'peerHostHandshake');
40
+ addPeerHostRoute(add, 'peer-host.http-proxy', 'peer-host-http-proxy', 'peerHostHttpProxy');
41
+ addPeerHostRoute(add, 'peer-host.ws-proxy', 'peer-host-ws-proxy', 'peerHostWsProxy');
42
+ addPeerHostRoute(add, 'peer-host.aggregate', 'peer-host-aggregate', 'peerHostAggregate');
43
+ addPeerHostRoute(add, 'peer-host.relay-route', 'peer-host-relay-route', 'peerHostRelayRoute');
44
+ }
45
+ /** PeerHost Client 导航能力由独立 adapter 注入;未注入时由 Feature 诊断降级。 */
46
+ function addPeerHostClientRoutes(add) {
47
+ addPeerHostRoute(add, 'peer-host.native-navigation', 'peer-host-native-navigation-legacy', 'peerHostNativeNavigation', '>=0.1.5-rc.3 <=0.1.6', 'deprecated');
48
+ addPeerHostRoute(add, 'peer-host.native-navigation', 'peer-host-native-navigation-modern', 'peerHostNativeNavigation', '>=0.1.7-rc.2 <=0.1.7-rc.2', 'supported', 20);
49
+ addPeerHostRoute(add, 'peer-host.remote-web-context-fallback', 'peer-host-remote-web-context-fallback', 'peerHostRemoteWebContextFallback');
50
+ }
51
+ function addPeerHostRoute(add, capability, id, field, supportedDsh = '>=0.1.5-rc.3 <=0.1.7-rc.2', status = 'supported', priority = 10) {
52
+ add({
53
+ id,
54
+ capability,
55
+ supportedDsh,
56
+ runtime: capability === 'peer-host.native-navigation' || capability === 'peer-host.remote-web-context-fallback' ? 'client' : 'host',
57
+ priority,
58
+ status,
59
+ introducedIn: '0.1.5-rc.3',
60
+ detect: (context) => readPeerHostAdapter(context, field) !== undefined,
61
+ create: (context) => readPeerHostAdapter(context, field),
62
+ });
63
+ }
64
+ function readPeerHostAdapter(context, field) {
65
+ if (typeof context !== 'object' || context === null || Array.isArray(context))
66
+ return undefined;
67
+ return context[field];
68
+ }
34
69
  //# sourceMappingURL=routes.js.map
@@ -26,4 +26,16 @@ export interface CodingNsSettingsStore<T> {
26
26
  }
27
27
  /** 将 DSH 两代写入结果统一成内部成功布尔值。 */
28
28
  export declare function accepted(write: Promise<void | boolean>): Promise<boolean>;
29
+ /**
30
+ * 判断两份设置快照在内容上是否等价。
31
+ *
32
+ * DSH 的 ConfigForm、SettingsScope 和插件自己的 Host RPC 都会在每次读取时
33
+ * 构造新对象。`useSyncExternalStore` 要求 `getSnapshot()` 在内容未变化时返回
34
+ * 同一个引用,否则 React 会在每次渲染后重新比对快照并强制再次渲染,直到抛出
35
+ * “Maximum update depth exceeded”(React #185)。所有适配器都必须先比较内容、
36
+ * 再决定是否替换快照并唤醒订阅者。
37
+ */
38
+ export declare function sameSettingsSnapshot<T>(left: CodingNsSettingsSnapshot<T>, right: CodingNsSettingsSnapshot<T>): boolean;
39
+ /** 设置内容的结构比较:数组按顺序、对象按键,标量按 Object.is。 */
40
+ export declare function sameSettingsValue(left: unknown, right: unknown): boolean;
29
41
  //# sourceMappingURL=settings-store.d.ts.map
@@ -2,4 +2,38 @@
2
2
  export function accepted(write) {
3
3
  return write.then((result) => result !== false);
4
4
  }
5
+ /**
6
+ * 判断两份设置快照在内容上是否等价。
7
+ *
8
+ * DSH 的 ConfigForm、SettingsScope 和插件自己的 Host RPC 都会在每次读取时
9
+ * 构造新对象。`useSyncExternalStore` 要求 `getSnapshot()` 在内容未变化时返回
10
+ * 同一个引用,否则 React 会在每次渲染后重新比对快照并强制再次渲染,直到抛出
11
+ * “Maximum update depth exceeded”(React #185)。所有适配器都必须先比较内容、
12
+ * 再决定是否替换快照并唤醒订阅者。
13
+ */
14
+ export function sameSettingsSnapshot(left, right) {
15
+ return sameSettingsValue(left.value, right.value)
16
+ && left.revision === right.revision
17
+ && left.writable === right.writable
18
+ && left.status === right.status;
19
+ }
20
+ /** 设置内容的结构比较:数组按顺序、对象按键,标量按 Object.is。 */
21
+ export function sameSettingsValue(left, right) {
22
+ if (Object.is(left, right))
23
+ return true;
24
+ if (left === null || right === null || typeof left !== 'object' || typeof right !== 'object')
25
+ return false;
26
+ if (Array.isArray(left) || Array.isArray(right)) {
27
+ if (!Array.isArray(left) || !Array.isArray(right) || left.length !== right.length)
28
+ return false;
29
+ return left.every((value, index) => sameSettingsValue(value, right[index]));
30
+ }
31
+ const leftRecord = left;
32
+ const rightRecord = right;
33
+ const leftKeys = Object.keys(leftRecord);
34
+ const rightKeys = Object.keys(rightRecord);
35
+ if (leftKeys.length !== rightKeys.length)
36
+ return false;
37
+ return leftKeys.every((key) => Object.prototype.hasOwnProperty.call(rightRecord, key) && sameSettingsValue(leftRecord[key], rightRecord[key]));
38
+ }
5
39
  //# sourceMappingURL=settings-store.js.map
@@ -1,5 +1,5 @@
1
1
  /** DSH 宿主能力的稳定标识。业务模块只依赖这些标识,不直接依赖 DSH 版本。 */
2
- export type DshCapabilityId = 'settings.store' | 'connection.rpc' | 'connection.peer' | 'ui.icon.plus' | 'ui.icon.chevron' | 'locale.runtime' | 'theme.runtime' | 'conversation.tool-call' | 'sidebar.right' | 'typert.remote';
2
+ export type DshCapabilityId = 'settings.store' | 'connection.rpc' | 'connection.peer' | 'ui.icon.plus' | 'ui.icon.chevron' | 'locale.runtime' | 'theme.runtime' | 'conversation.tool-call' | 'sidebar.right' | 'typert.remote' | 'peer-host.store' | 'peer-host.handshake' | 'peer-host.http-proxy' | 'peer-host.ws-proxy' | 'peer-host.aggregate' | 'peer-host.relay-route' | 'peer-host.native-navigation' | 'peer-host.remote-web-context-fallback';
3
3
  export type DshCapabilityRuntime = 'host' | 'client';
4
4
  export type DshCapabilityRouteStatus = 'supported' | 'deprecated';
5
5
  export type DshCapabilityResolutionStatus = 'ready' | 'degraded' | 'unavailable';
@@ -0,0 +1,26 @@
1
+ import { type ResourceScopeDisposer } from '../shared/contracts/peer-host.js';
2
+ import type { HostScope } from '../shared/contracts/peer-host.js';
3
+ export type HostRouterInput = Omit<HostScope, 'scopeGeneration'>;
4
+ /** 统一管理当前 Host/PeerHost 的完整作用域和 generation。 */
5
+ export declare class HostRouter {
6
+ private current;
7
+ private generation;
8
+ private disposers;
9
+ private transition;
10
+ getCurrent(): HostScope | null;
11
+ switchTo(input: HostRouterInput, disposer?: ResourceScopeDisposer): Promise<HostScope>;
12
+ /**
13
+ * 重连成功后强制创建新的 generation,即使逻辑 HostScope 没有变化。
14
+ * 旧作用域的所有 disposer 会先执行,调用方必须用返回值重建订阅。
15
+ */
16
+ rebuild(input: HostRouterInput, disposer?: ResourceScopeDisposer): Promise<HostScope>;
17
+ private transitionTo;
18
+ addDisposer(disposer: ResourceScopeDisposer): () => void;
19
+ registerAbortController(scope: HostScope, controller: AbortController): () => void;
20
+ isCurrent(scope: HostScope | null | undefined): boolean;
21
+ assertCurrent(scope: HostScope): void;
22
+ commitIfCurrent<T>(scope: HostScope, write: () => T): T;
23
+ key(scope: HostScope, resource: string, resourceId?: string): string;
24
+ clear(): Promise<void>;
25
+ }
26
+ //# sourceMappingURL=host-router.d.ts.map
@@ -0,0 +1,110 @@
1
+ import { ResourceScopeStaleError } from '../shared/contracts/peer-host.js';
2
+ /** 统一管理当前 Host/PeerHost 的完整作用域和 generation。 */
3
+ export class HostRouter {
4
+ current = null;
5
+ generation = 0;
6
+ disposers = [];
7
+ transition = Promise.resolve();
8
+ getCurrent() { return this.current; }
9
+ async switchTo(input, disposer) {
10
+ return this.transitionTo(input, disposer, false);
11
+ }
12
+ /**
13
+ * 重连成功后强制创建新的 generation,即使逻辑 HostScope 没有变化。
14
+ * 旧作用域的所有 disposer 会先执行,调用方必须用返回值重建订阅。
15
+ */
16
+ async rebuild(input, disposer) {
17
+ return this.transitionTo(input, disposer, true);
18
+ }
19
+ async transitionTo(input, disposer, force) {
20
+ validateInput(input);
21
+ let result;
22
+ const operation = this.transition.then(async () => {
23
+ if (!force && this.current !== null && sameInput(this.current, input)) {
24
+ if (disposer)
25
+ this.addDisposer(disposer);
26
+ result = this.current;
27
+ return;
28
+ }
29
+ const previous = this.current;
30
+ this.current = null;
31
+ const errors = await disposeAll(this.disposers);
32
+ this.disposers = [];
33
+ const next = Object.freeze({ ...input, scopeGeneration: ++this.generation });
34
+ this.current = next;
35
+ if (disposer)
36
+ this.addDisposer(disposer);
37
+ result = next;
38
+ if (errors.length > 0)
39
+ throw new AggregateError(errors, 'HostScope 清理失败');
40
+ void previous;
41
+ });
42
+ this.transition = operation.then(() => undefined, () => undefined);
43
+ return operation.then(() => result);
44
+ }
45
+ addDisposer(disposer) {
46
+ if (this.current === null)
47
+ throw new ResourceScopeStaleError('No active HostScope');
48
+ const entry = { dispose: disposer, active: true };
49
+ this.disposers.push(entry);
50
+ return () => { entry.active = false; };
51
+ }
52
+ registerAbortController(scope, controller) {
53
+ this.assertCurrent(scope);
54
+ return this.addDisposer(() => { if (!controller.signal.aborted)
55
+ controller.abort(new ResourceScopeStaleError()); });
56
+ }
57
+ isCurrent(scope) {
58
+ return scope !== null && scope !== undefined && this.current !== null && sameScope(this.current, scope);
59
+ }
60
+ assertCurrent(scope) {
61
+ if (!this.isCurrent(scope))
62
+ throw new ResourceScopeStaleError('HostScope 已失效');
63
+ }
64
+ commitIfCurrent(scope, write) {
65
+ this.assertCurrent(scope);
66
+ return write();
67
+ }
68
+ key(scope, resource, resourceId = '') {
69
+ this.assertCurrent(scope);
70
+ return [scope.hostId, scope.targetHostId ?? 'current', scope.workspaceId, scope.sessionId ?? 'none', resource, resourceId].map(encodeURIComponent).join(':');
71
+ }
72
+ async clear() {
73
+ const operation = this.transition.then(async () => {
74
+ this.current = null;
75
+ const errors = await disposeAll(this.disposers);
76
+ this.disposers = [];
77
+ if (errors.length > 0)
78
+ throw new AggregateError(errors, 'HostScope 清理失败');
79
+ });
80
+ this.transition = operation.then(() => undefined, () => undefined);
81
+ await operation;
82
+ }
83
+ }
84
+ function validateInput(input) {
85
+ if (!input || !text(input.hostId) || !text(input.workspaceId) || (input.targetHostId !== null && !text(input.targetHostId)) || (input.sessionId !== null && !text(input.sessionId)))
86
+ throw new TypeError('HostScope 输入无效');
87
+ }
88
+ function text(value) { return typeof value === 'string' && value.trim() !== ''; }
89
+ function sameInput(scope, input) {
90
+ return scope.hostId === input.hostId && scope.targetHostId === input.targetHostId && scope.workspaceId === input.workspaceId && scope.sessionId === input.sessionId;
91
+ }
92
+ function sameScope(left, right) {
93
+ return sameInput(left, right) && left.scopeGeneration === right.scopeGeneration;
94
+ }
95
+ async function disposeAll(entries) {
96
+ const errors = [];
97
+ for (const entry of [...entries].reverse()) {
98
+ if (!entry.active)
99
+ continue;
100
+ entry.active = false;
101
+ try {
102
+ await entry.dispose();
103
+ }
104
+ catch (error) {
105
+ errors.push(error);
106
+ }
107
+ }
108
+ return errors;
109
+ }
110
+ //# sourceMappingURL=host-router.js.map
@@ -404,6 +404,9 @@ function validateDescriptor(descriptor) {
404
404
  if (typeof descriptor.enabledByDefault !== 'boolean') {
405
405
  throw new FeatureRegistryError('FEATURE_INVALID_DESCRIPTOR', `Feature ${descriptor.name} has invalid enabledByDefault`, descriptor.name);
406
406
  }
407
+ if (descriptor.disabled !== undefined && typeof descriptor.disabled !== 'boolean') {
408
+ throw new FeatureRegistryError('FEATURE_INVALID_DESCRIPTOR', `Feature ${descriptor.name} has invalid disabled`, descriptor.name);
409
+ }
407
410
  if (descriptor.runtime !== 'host' && descriptor.runtime !== 'client' && descriptor.runtime !== 'both') {
408
411
  throw new FeatureRegistryError('FEATURE_INVALID_DESCRIPTOR', `Feature ${descriptor.name} has invalid runtime`, descriptor.name);
409
412
  }
@@ -33,7 +33,7 @@ export declare class CodexAppServerDriver implements CodingNsCliDriver {
33
33
  probeSession(input: CodingNsCliSessionProbeInput): Promise<CodingNsCliSessionProbeResult>;
34
34
  executeTurn(input: CodingNsCliTurnInput): AsyncIterable<CodingNsAgentEvent>;
35
35
  /**
36
- * 将一个 Codex turn 按工具完成点切成多个 DSH step。
36
+ * 将一个 Codex turn 按 assistant item 切成多个 DSH step。
37
37
  *
38
38
  * DSH 的 step 边界只能由 Agent Loop 提交;这里仅提前结束本次 llm/stream,
39
39
  * 保留同一个 Codex turn 的通知队列,下一次 llm/stream 再继续消费它。
@@ -42,10 +42,22 @@ export declare class CodexAppServerDriver implements CodingNsCliDriver {
42
42
  private startSegmentedTurn;
43
43
  private consumeSegment;
44
44
  private closeSegmentedTurn;
45
+ /** 在下一轮开始前主动压缩,避免把已满的线程直接交给 turn/start。 */
46
+ private ensureContextCapacity;
47
+ /** turn/start 遇到上下文超限时压缩一次并重试,兼容关闭自动压缩的 Codex 配置。 */
48
+ private startTurn;
49
+ /** thread/compact/start 立即返回,真正完成由 contextCompaction turn 的终态通知表示。 */
50
+ private compactThread;
51
+ private waitForCompaction;
45
52
  /** 将新输入 steer 到当前 Codex turn。 */
46
53
  steer(sessionId: string, prompt: string): Promise<void>;
47
54
  /** 中断当前 Codex turn,但保留 app-server 线程。 */
48
55
  interrupt(sessionId: string): Promise<void>;
56
+ /**
57
+ * 丢弃等待下一个 DSH step 的分段运行(取消、注入失败或切换适配器时)。
58
+ * 队列关闭后旧回合的通知不会再被投影进下一轮,续段标记同时解除。
59
+ */
60
+ discardSegmentedTurn(sessionId: string): void;
49
61
  /** 回传原生权限请求;审批值只在 Host 进程中流转。 */
50
62
  respondPermission(sessionId: string, response: CodingNsAgentPermissionResponse): void;
51
63
  /** 回传 requestUserInput 的结构化回答。 */