@agimon-ai/po 0.0.0-alpha.2 → 0.0.0-alpha.21

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 (255) hide show
  1. package/README.md +14 -11
  2. package/dist/antigravity.mjs +1 -2
  3. package/dist/baseCommand.mjs +1 -2
  4. package/dist/bin/cli.cjs +37 -14
  5. package/dist/bin/cli.cjs.map +1 -1
  6. package/dist/bin/cli.mjs +34 -14
  7. package/dist/bin/cli.mjs.map +1 -1
  8. package/dist/bin/{doomRunner.cjs → poRunner.cjs} +5 -5
  9. package/dist/bin/poRunner.cjs.map +1 -0
  10. package/dist/bin/{doomRunner.d.mts → poRunner.d.mts} +2 -2
  11. package/dist/bin/poRunner.d.mts.map +1 -0
  12. package/dist/bin/{doomRunner.mjs → poRunner.mjs} +5 -5
  13. package/dist/bin/poRunner.mjs.map +1 -0
  14. package/dist/builders/cli/extensionAssembler/index.cjs +14 -12
  15. package/dist/builders/cli/extensionAssembler/index.cjs.map +1 -1
  16. package/dist/builders/cli/extensionAssembler/index.d.mts +2 -1
  17. package/dist/builders/cli/extensionAssembler/index.d.mts.map +1 -1
  18. package/dist/builders/cli/extensionAssembler/index.mjs +14 -12
  19. package/dist/builders/cli/extensionAssembler/index.mjs.map +1 -1
  20. package/dist/catalog/index.json +68 -51
  21. package/dist/cliApp.mjs +1 -2
  22. package/dist/codex.mjs +1 -2
  23. package/dist/compatibilityCommand.mjs +1 -2
  24. package/dist/compatibilityContext.mjs +1 -2
  25. package/dist/compatibilityOptions.mjs +1 -2
  26. package/dist/config.cjs +57 -12
  27. package/dist/config.d.mts +3 -3
  28. package/dist/config.mjs +3 -3
  29. package/dist/doctorCommand.mjs +1 -2
  30. package/dist/emitMcpCommand.mjs +1 -2
  31. package/dist/explainCommand.mjs +1 -2
  32. package/dist/extensions/server.cjs +11 -7
  33. package/dist/extensions/server.cjs.map +1 -1
  34. package/dist/extensions/server.d.mts +2 -2
  35. package/dist/extensions/server.d.mts.map +1 -1
  36. package/dist/extensions/server.mjs +12 -8
  37. package/dist/extensions/server.mjs.map +1 -1
  38. package/dist/harnessContext.mjs +1 -2
  39. package/dist/harnessState.cjs +66 -11
  40. package/dist/harnessState.d.mts +2 -2
  41. package/dist/harnessState.mjs +1 -2
  42. package/dist/index.cjs +60 -15
  43. package/dist/index.d.mts +3 -3
  44. package/dist/index.mjs +3 -3
  45. package/dist/initCommand.mjs +1 -2
  46. package/dist/matrixOptions.mjs +1 -2
  47. package/dist/options.mjs +1 -2
  48. package/dist/process.mjs +1 -2
  49. package/dist/projectTrust.cjs +2 -2
  50. package/dist/projectTrust.d.mts +2 -2
  51. package/dist/projectTrust.mjs +1 -2
  52. package/dist/repository.cjs +1 -1
  53. package/dist/repository.d.mts +2 -2
  54. package/dist/repository.mjs +1 -2
  55. package/dist/router.mjs +1 -2
  56. package/dist/shared.mjs +1 -2
  57. package/dist/src/bin/agentDirectory.cjs +18 -12
  58. package/dist/src/bin/agentDirectory.cjs.map +1 -1
  59. package/dist/src/bin/agentDirectory.mjs +15 -12
  60. package/dist/src/bin/agentDirectory.mjs.map +1 -1
  61. package/dist/src/builders/apiContractExport/index.cjs +6 -6
  62. package/dist/src/builders/apiContractExport/index.cjs.map +1 -1
  63. package/dist/src/builders/apiContractExport/index.mjs +9 -9
  64. package/dist/src/builders/apiContractExport/index.mjs.map +1 -1
  65. package/dist/src/builders/cli/entryResolution.cjs +3 -3
  66. package/dist/src/builders/cli/entryResolution.cjs.map +1 -1
  67. package/dist/src/builders/cli/entryResolution.mjs +3 -3
  68. package/dist/src/builders/cli/entryResolution.mjs.map +1 -1
  69. package/dist/src/builders/cli/harnessContext.cjs +5 -5
  70. package/dist/src/builders/cli/harnessContext.cjs.map +1 -1
  71. package/dist/src/builders/cli/harnessContext.mjs +7 -7
  72. package/dist/src/builders/cli/harnessContext.mjs.map +1 -1
  73. package/dist/src/builders/hooks/index.cjs +1 -1
  74. package/dist/src/builders/hooks/index.cjs.map +1 -1
  75. package/dist/src/builders/hooks/index.mjs +2 -2
  76. package/dist/src/builders/hooks/index.mjs.map +1 -1
  77. package/dist/src/builders/server/backgroundSync.cjs +13 -1
  78. package/dist/src/builders/server/backgroundSync.cjs.map +1 -1
  79. package/dist/src/builders/server/backgroundSync.mjs +13 -1
  80. package/dist/src/builders/server/backgroundSync.mjs.map +1 -1
  81. package/dist/src/builders/server/bundlerService.cjs +151 -0
  82. package/dist/src/builders/server/bundlerService.cjs.map +1 -0
  83. package/dist/src/builders/server/bundlerService.mjs +151 -0
  84. package/dist/src/builders/server/bundlerService.mjs.map +1 -0
  85. package/dist/src/builders/server/computerUseBinding.cjs +2 -2
  86. package/dist/src/builders/server/computerUseBinding.cjs.map +1 -1
  87. package/dist/src/builders/server/computerUseBinding.mjs +3 -3
  88. package/dist/src/builders/server/computerUseBinding.mjs.map +1 -1
  89. package/dist/src/builders/server/defaultWorkspace.cjs +1 -1
  90. package/dist/src/builders/server/defaultWorkspace.cjs.map +1 -1
  91. package/dist/src/builders/server/defaultWorkspace.mjs +2 -2
  92. package/dist/src/builders/server/defaultWorkspace.mjs.map +1 -1
  93. package/dist/src/builders/server/idleRestart.cjs +3 -3
  94. package/dist/src/builders/server/idleRestart.cjs.map +1 -1
  95. package/dist/src/builders/server/idleRestart.mjs +3 -3
  96. package/dist/src/builders/server/idleRestart.mjs.map +1 -1
  97. package/dist/src/builders/server/index.cjs +6 -6
  98. package/dist/src/builders/server/index.cjs.map +1 -1
  99. package/dist/src/builders/server/index.mjs +6 -6
  100. package/dist/src/builders/server/index.mjs.map +1 -1
  101. package/dist/src/builders/server/logSink.cjs +3 -3
  102. package/dist/src/builders/server/logSink.cjs.map +1 -1
  103. package/dist/src/builders/server/logSink.mjs +2 -2
  104. package/dist/src/builders/server/logSink.mjs.map +1 -1
  105. package/dist/src/builders/server/mcpBundle.cjs.map +1 -1
  106. package/dist/src/builders/server/mcpBundle.d.mts +2 -2
  107. package/dist/src/builders/server/mcpBundle.mjs.map +1 -1
  108. package/dist/src/builders/server/packageUrl.cjs +25 -18
  109. package/dist/src/builders/server/packageUrl.cjs.map +1 -1
  110. package/dist/src/builders/server/packageUrl.mjs +25 -18
  111. package/dist/src/builders/server/packageUrl.mjs.map +1 -1
  112. package/dist/src/builders/server/runtime.cjs +157 -168
  113. package/dist/src/builders/server/runtime.cjs.map +1 -1
  114. package/dist/src/builders/server/runtime.mjs +161 -171
  115. package/dist/src/builders/server/runtime.mjs.map +1 -1
  116. package/dist/src/builders/server/selectionStatus.cjs +3 -3
  117. package/dist/src/builders/server/selectionStatus.cjs.map +1 -1
  118. package/dist/src/builders/server/selectionStatus.mjs +3 -3
  119. package/dist/src/builders/server/selectionStatus.mjs.map +1 -1
  120. package/dist/src/builders/server/sessionArguments.cjs.map +1 -1
  121. package/dist/src/builders/server/sessionArguments.mjs.map +1 -1
  122. package/dist/src/builders/server/watcherService.cjs +65 -0
  123. package/dist/src/builders/server/watcherService.cjs.map +1 -0
  124. package/dist/src/builders/server/watcherService.mjs +61 -0
  125. package/dist/src/builders/server/watcherService.mjs.map +1 -0
  126. package/dist/src/builders/server/webTemplateDecision.cjs +1 -1
  127. package/dist/src/builders/server/webTemplateDecision.cjs.map +1 -1
  128. package/dist/src/builders/server/webTemplateDecision.mjs +2 -2
  129. package/dist/src/builders/server/webTemplateDecision.mjs.map +1 -1
  130. package/dist/src/builders/web/bundle.cjs.map +1 -1
  131. package/dist/src/builders/web/bundle.d.mts +4 -3
  132. package/dist/src/builders/web/bundle.mjs.map +1 -1
  133. package/dist/src/builders/web/bundleAssetPolicy.d.mts +1 -0
  134. package/dist/src/builders/web/index.cjs +1 -1
  135. package/dist/src/builders/web/index.cjs.map +1 -1
  136. package/dist/src/builders/web/index.d.mts +1 -0
  137. package/dist/src/builders/web/index.mjs +1 -1
  138. package/dist/src/builders/web/index.mjs.map +1 -1
  139. package/dist/src/builders/web/webPluginGenerate.cjs +4 -15
  140. package/dist/src/builders/web/webPluginGenerate.cjs.map +1 -1
  141. package/dist/src/builders/web/webPluginGenerate.d.mts +5 -9
  142. package/dist/src/builders/web/webPluginGenerate.d.mts.map +1 -1
  143. package/dist/src/builders/web/webPluginGenerate.mjs +4 -15
  144. package/dist/src/builders/web/webPluginGenerate.mjs.map +1 -1
  145. package/dist/src/builders/web/webPluginVite.d.mts +1 -0
  146. package/dist/src/cli/cliApp.cjs +1 -1
  147. package/dist/src/cli/cliApp.cjs.map +1 -1
  148. package/dist/src/cli/cliApp.mjs +1 -1
  149. package/dist/src/cli/cliApp.mjs.map +1 -1
  150. package/dist/src/cli/commands/compat/index.cjs +1 -1
  151. package/dist/src/cli/commands/compat/index.cjs.map +1 -1
  152. package/dist/src/cli/commands/compat/index.mjs +1 -1
  153. package/dist/src/cli/commands/compat/index.mjs.map +1 -1
  154. package/dist/src/cli/commands/doctor/index.cjs +2 -2
  155. package/dist/src/cli/commands/doctor/index.cjs.map +1 -1
  156. package/dist/src/cli/commands/doctor/index.d.mts +1 -0
  157. package/dist/src/cli/commands/doctor/index.d.mts.map +1 -1
  158. package/dist/src/cli/commands/doctor/index.mjs +4 -4
  159. package/dist/src/cli/commands/doctor/index.mjs.map +1 -1
  160. package/dist/src/cli/commands/explain/index.cjs +3 -1
  161. package/dist/src/cli/commands/explain/index.cjs.map +1 -1
  162. package/dist/src/cli/commands/explain/index.d.mts.map +1 -1
  163. package/dist/src/cli/commands/explain/index.mjs +4 -2
  164. package/dist/src/cli/commands/explain/index.mjs.map +1 -1
  165. package/dist/src/cli/commands/init/index.cjs +2 -2
  166. package/dist/src/cli/commands/init/index.cjs.map +1 -1
  167. package/dist/src/cli/commands/init/index.mjs +3 -3
  168. package/dist/src/cli/commands/init/index.mjs.map +1 -1
  169. package/dist/src/cli/commands/init/presenter.cjs +1 -1
  170. package/dist/src/cli/commands/init/presenter.cjs.map +1 -1
  171. package/dist/src/cli/commands/init/presenter.mjs +2 -2
  172. package/dist/src/cli/commands/init/presenter.mjs.map +1 -1
  173. package/dist/src/cli/commands/sync/index.cjs +4 -4
  174. package/dist/src/cli/commands/sync/index.cjs.map +1 -1
  175. package/dist/src/cli/commands/sync/index.d.mts +1 -0
  176. package/dist/src/cli/commands/sync/index.mjs +7 -7
  177. package/dist/src/cli/commands/sync/index.mjs.map +1 -1
  178. package/dist/src/cli/commands/sync/presenter.cjs +1 -1
  179. package/dist/src/cli/commands/sync/presenter.cjs.map +1 -1
  180. package/dist/src/cli/commands/sync/presenter.d.mts +1 -1
  181. package/dist/src/cli/commands/sync/presenter.mjs +1 -1
  182. package/dist/src/cli/commands/sync/presenter.mjs.map +1 -1
  183. package/dist/src/cli/commands/web/index.cjs +2 -1
  184. package/dist/src/cli/commands/web/index.cjs.map +1 -1
  185. package/dist/src/cli/commands/web/index.mjs +2 -1
  186. package/dist/src/cli/commands/web/index.mjs.map +1 -1
  187. package/dist/src/cli/harnessOptions.cjs +1 -1
  188. package/dist/src/cli/harnessOptions.cjs.map +1 -1
  189. package/dist/src/cli/harnessOptions.mjs +2 -2
  190. package/dist/src/cli/harnessOptions.mjs.map +1 -1
  191. package/dist/src/cli/help.cjs +2 -0
  192. package/dist/src/cli/help.cjs.map +1 -1
  193. package/dist/src/cli/help.mjs +2 -0
  194. package/dist/src/cli/help.mjs.map +1 -1
  195. package/dist/src/cli/matrixOptions.cjs +1 -1
  196. package/dist/src/cli/matrixOptions.cjs.map +1 -1
  197. package/dist/src/cli/matrixOptions.d.mts +1 -1
  198. package/dist/src/cli/matrixOptions.mjs +1 -1
  199. package/dist/src/cli/matrixOptions.mjs.map +1 -1
  200. package/dist/src/cli/server/run.cjs +1 -1
  201. package/dist/src/cli/server/run.cjs.map +1 -1
  202. package/dist/src/cli/server/run.mjs +2 -2
  203. package/dist/src/cli/server/run.mjs.map +1 -1
  204. package/dist/src/composition/harnessState/index.cjs +66 -11
  205. package/dist/src/composition/harnessState/index.cjs.map +1 -1
  206. package/dist/src/composition/harnessState/index.d.mts +3 -3
  207. package/dist/src/composition/harnessState/index.mjs +2 -2
  208. package/dist/src/composition/harnessState/index.mjs.map +1 -1
  209. package/dist/src/composition/layerPackageInstaller/index.cjs +5 -4
  210. package/dist/src/composition/layerPackageInstaller/index.cjs.map +1 -1
  211. package/dist/src/composition/layerPackageInstaller/index.mjs +6 -5
  212. package/dist/src/composition/layerPackageInstaller/index.mjs.map +1 -1
  213. package/dist/src/composition/poHomeMigration/index.cjs +1 -1
  214. package/dist/src/composition/poHomeMigration/index.cjs.map +1 -1
  215. package/dist/src/composition/poHomeMigration/index.mjs +1 -1
  216. package/dist/src/composition/poHomeMigration/index.mjs.map +1 -1
  217. package/dist/src/composition/projectTrust/index.cjs +6 -6
  218. package/dist/src/composition/projectTrust/index.cjs.map +1 -1
  219. package/dist/src/composition/projectTrust/index.d.mts +7 -7
  220. package/dist/src/composition/projectTrust/index.d.mts.map +1 -1
  221. package/dist/src/composition/projectTrust/index.mjs +6 -6
  222. package/dist/src/composition/projectTrust/index.mjs.map +1 -1
  223. package/dist/src/composition/repository/index.cjs +8 -8
  224. package/dist/src/composition/repository/index.cjs.map +1 -1
  225. package/dist/src/composition/repository/index.d.mts +5 -5
  226. package/dist/src/composition/repository/index.d.mts.map +1 -1
  227. package/dist/src/composition/repository/index.mjs +10 -10
  228. package/dist/src/composition/repository/index.mjs.map +1 -1
  229. package/dist/src/composition/syncService/index.cjs +29 -9
  230. package/dist/src/composition/syncService/index.cjs.map +1 -1
  231. package/dist/src/composition/syncService/index.d.mts.map +1 -1
  232. package/dist/src/composition/syncService/index.mjs +31 -11
  233. package/dist/src/composition/syncService/index.mjs.map +1 -1
  234. package/dist/src/composition/syncService/localBuilds.cjs +7 -2
  235. package/dist/src/composition/syncService/localBuilds.cjs.map +1 -1
  236. package/dist/src/composition/syncService/localBuilds.mjs +7 -2
  237. package/dist/src/composition/syncService/localBuilds.mjs.map +1 -1
  238. package/dist/src/extensions/setupDiagnostics.cjs +3 -3
  239. package/dist/src/extensions/setupDiagnostics.cjs.map +1 -1
  240. package/dist/src/extensions/setupDiagnostics.mjs +3 -3
  241. package/dist/src/extensions/setupDiagnostics.mjs.map +1 -1
  242. package/dist/utils.mjs +1 -2
  243. package/docs/server/api-export.md +3 -3
  244. package/docs/server/api.md +23 -22
  245. package/docs/server/getting-started.md +7 -7
  246. package/docs/server/index.md +4 -4
  247. package/docs/server/ipc.md +7 -11
  248. package/docs/server/lifecycle.md +17 -17
  249. package/docs/server/security.md +8 -8
  250. package/package.json +42 -45
  251. package/src/prompts/po-author-extension/SKILL.md +1 -1
  252. package/src/prompts/po-author-extension/references/extension-contract.md +4 -4
  253. package/dist/bin/doomRunner.cjs.map +0 -1
  254. package/dist/bin/doomRunner.d.mts.map +0 -1
  255. package/dist/bin/doomRunner.mjs.map +0 -1
@@ -1,52 +1,49 @@
1
1
  import { HARNESS_STATE_KEYS, HARNESS_STATE_POINTER, loadHarnessState, updateHarnessState } from "../../composition/harnessState/index.mjs";
2
2
  import { findRepositoryRoot } from "../../composition/repository/index.mjs";
3
3
  import { createLayerResolvers, resolveExtensionComposition, unsyncedSelectors } from "../../../builders/cli/extensionAssembler/index.mjs";
4
- import { createPackageUrls } from "./packageUrl.mjs";
5
4
  import { compositionPackageRoots, mountWebPluginSlots, newestGlobalWebBuildKey, readGlobalWebBuildRecord, readGlobalWebBuildStatus, unslottedWebPackages } from "../web/index.mjs";
6
5
  import { mountNativePluginIds, readGlobalNativeBuildRecord, readGlobalNativeBuildStatus } from "../native/index.mjs";
7
6
  import { missingLayerPackageSpecifiers } from "../../composition/layerPackageInstaller/index.mjs";
8
- import { rootCompositions } from "../cli/sessionComposition.mjs";
9
7
  import { readMcpAppBuild } from "./mcpAppBuild.mjs";
10
- import { mcpPluginCandidates } from "./mcpBundle.mjs";
11
- import { globalWebPluginRoots, readSyncPointer } from "../../composition/syncService/index.mjs";
8
+ import { globalWebPluginRoots, readSyncPointer, syncPointerPath } from "../../composition/syncService/index.mjs";
12
9
  import { createBackgroundSync, createKeyedPickup, createSyncCheckpoints, syncedBuildKeys } from "./backgroundSync.mjs";
13
10
  import { buildHarnessContext } from "../cli/harnessContext.mjs";
14
11
  import { checkoutHookDescriptor, validateHookModules, writeLiveHookModules } from "../hooks/index.mjs";
12
+ import { createBundlerService } from "./bundlerService.mjs";
15
13
  import { createComputerUseBinding } from "./computerUseBinding.mjs";
16
14
  import { createDefaultWorkspaceFolder } from "./defaultWorkspace.mjs";
17
15
  import { createIdleRestart, holdsRestart, reopenRecycledSessions, testIdleRestartOverrides, writeRecycleFile } from "./idleRestart.mjs";
18
- import { serverFacetCandidates } from "./index.mjs";
19
16
  import { ensureGlobalLogSink } from "./logSink.mjs";
20
- import { createLiveModuleCache, createPackageReloadCheck } from "./packageReloadCheck.mjs";
21
17
  import { monitorRuntimeResources } from "./runtimeResources.mjs";
22
18
  import { publishHeadlessSelectionStatus } from "./selectionStatus.mjs";
23
19
  import { resolveSessionIdentity, sessionSelectionArgs } from "./sessionArguments.mjs";
24
20
  import { withShutdownDeadline } from "./shutdown.mjs";
21
+ import { createWatcherService, outsideNodeModules } from "./watcherService.mjs";
25
22
  import { resolveWebTemplateDecision } from "./webTemplateDecision.mjs";
26
23
  import { checkoutWorkspaceId } from "./workspaceCheckout.mjs";
27
24
  import fs from "node:fs";
28
25
  import path from "node:path";
29
26
  import os from "node:os";
30
- import { globalDoomConfigDirectory } from "@agimon-ai/po-config/config";
27
+ import { globalPoConfigDirectory } from "@agimon-ai/po-config/config";
31
28
  import { filterHookDisabledLayers, loadMajorModesConfig, resolveLayers } from "@agimon-ai/po-config/majorModes";
32
29
  import { resolveProfile } from "@agimon-ai/po-config/profiles";
33
30
  import { createHarnessTelemetry } from "@agimon-ai/po-core/runtimeLogSinkTelemetry";
34
31
  import { piAgentDirectory } from "@agimon-ai/po-core/piSettings";
35
- import { loadServerFacets, selectedServerProviderOverrides } from "@agimon-ai/po-core/serverFacet";
32
+ import { loadServerPackages, selectedServerProviderOverrides } from "@agimon-ai/po-core/serverPlugin";
36
33
  import crypto from "node:crypto";
37
34
  import { createOpenSessionRegistry, createRequestReceipts, createWorkspaceRegistry, identifyWorkspace, listSavedSessionRecords, listSavedSessions, readSqliteTranscript, readWorkspaceMarker, writeWorkspaceMarker } from "@agimon-ai/po-core/history";
38
- import { readDoomBackgroundWorkService } from "@agimon-ai/po-core/backgroundWork";
35
+ import { createNodePlatform } from "@agimon-ai/po-core/nodePlatform";
36
+ import { readPoBackgroundWorkService } from "@agimon-ai/po-core/backgroundWork";
39
37
  import { createHeadlessHub } from "@agimon-ai/po-core/headlessHub";
40
38
  import { serveHeadlessServer } from "@agimon-ai/po-core/headlessServer";
41
39
  import { createHeadlessSessionManager } from "@agimon-ai/po-core/headlessSessionManager";
42
40
  import { loadMcpPlugins, mcpUiResource } from "@agimon-ai/po-core/mcpFacet";
43
- import { DOOM_SHARE_FILE_REMOTE_OFF_MESSAGE, createServerExecutionBudget } from "@agimon-ai/po-core/packageApi";
41
+ import { PO_SHARE_FILE_REMOTE_OFF_MESSAGE, createServerExecutionBudget } from "@agimon-ai/po-core/packageApi";
44
42
  import { serveSessionApis } from "@agimon-ai/po-core/packageApiServer";
45
43
  import { createRemoteRuntime } from "@agimon-ai/po-core/remoteRuntime";
46
44
  import { createServerTelemetry } from "@agimon-ai/po-core/serverTelemetry";
47
45
  import { createWebCompositions } from "@agimon-ai/po-core/webCompositions";
48
46
  import { readMinorModeCatalog } from "@agimon-ai/po-minor-mode";
49
- import WebSocket from "ws";
50
47
  //#region src/builders/server/runtime.ts
51
48
  async function bounded(operation, label, notice) {
52
49
  try {
@@ -56,7 +53,7 @@ async function bounded(operation, label, notice) {
56
53
  }
57
54
  }
58
55
  async function runServerRuntime(options, runtime) {
59
- const { cwd: baseCwd, environment: incomingEnvironment, notice, resolveHarnessOptions, signal, onExtensionCheck } = runtime;
56
+ const { cwd: baseCwd, environment: incomingEnvironment, notice: rawNotice, resolveHarnessOptions, signal, onExtensionCheck } = runtime;
60
57
  const baseEnvironment = {
61
58
  ...incomingEnvironment,
62
59
  LOG_SINK_INSTANCE: "global"
@@ -65,31 +62,58 @@ async function runServerRuntime(options, runtime) {
65
62
  await ensureGlobalLogSink({
66
63
  cwd: baseCwd,
67
64
  env: baseEnvironment,
68
- notice
69
- }).catch((error) => notice(`Global log sink unavailable: ${error instanceof Error ? error.message : String(error)}`));
65
+ notice: rawNotice
66
+ }).catch((error) => rawNotice(`Global log sink unavailable: ${error instanceof Error ? error.message : String(error)}`));
70
67
  const telemetry = createServerTelemetry({
71
68
  cwd: baseCwd,
72
69
  env: baseEnvironment,
73
- warn: notice
70
+ warn: rawNotice
74
71
  });
72
+ const notice = (message) => {
73
+ rawNotice(message);
74
+ telemetry.recordEvent("po_server.notice", { message }).catch((error) => rawNotice(`notice telemetry failed: ${String(error)}`));
75
+ };
75
76
  const homeDirectory = baseEnvironment.HOME ?? os.homedir();
76
- /** Content-addressed import URLs for every Po package entry this server loads. */
77
- const packageUrls = createPackageUrls();
78
- /** URLs whose live import timed out or threw; skipped by every loader until the content changes. */
79
- const poisonedUrls = /* @__PURE__ */ new Set();
80
- /** Imports each content-addressed URL once, so a reload imports only what changed. */
81
- const importLive = createLiveModuleCache();
82
- /** The package identities each mounted global and workspace scope last loaded. */
83
- const reloadCheck = createPackageReloadCheck();
77
+ const serverDirectory = path.join(piAgentDirectory(baseEnvironment), "server");
78
+ const platform = createNodePlatform({
79
+ homeDirectory,
80
+ sessionsRoot: path.join(serverDirectory, "sessions")
81
+ });
82
+ /** Called on a watched change; assigned once every scope can be checked. */
83
+ let pickUpChange = () => void 0;
84
+ const watcher = createWatcherService({
85
+ onChange: () => pickUpChange(),
86
+ onNotice: notice
87
+ });
88
+ const isConfig = (file) => /\.ya?ml$/u.test(file);
89
+ watcher.add({
90
+ path: globalPoConfigDirectory(homeDirectory),
91
+ include: isConfig
92
+ });
93
+ /** Compiles and loads packages once per content; every scope and session selects from it. */
94
+ const bundler = createBundlerService({
95
+ homeDirectory,
96
+ environment: baseEnvironment,
97
+ onCompositions: (root, compositions) => {
98
+ watcher.add({
99
+ path: path.join(root, ".po"),
100
+ include: isConfig
101
+ });
102
+ for (const packageRoot of compositionPackageRoots(compositions)) if (!packageRoot.includes(`${path.sep}node_modules${path.sep}`)) watcher.add({
103
+ path: packageRoot,
104
+ recursive: true,
105
+ include: outsideNodeModules
106
+ });
107
+ }
108
+ });
84
109
  /** The hook module descriptor from the root's live registry; sources load in place or from snapshots. */
85
110
  const liveHookModules = (repoRoot) => writeLiveHookModules({
86
111
  repoRoot,
87
112
  homeDirectory,
88
- directory: path.join(globalDoomConfigDirectory(homeDirectory), "server", "hook-modules"),
89
- artifactFor: (source) => packageUrls.pathFor(source),
113
+ directory: path.join(globalPoConfigDirectory(homeDirectory), "server", "hook-modules"),
114
+ artifactFor: (source) => bundler.packageUrls.pathFor(source),
90
115
  onNotice: notice
91
116
  });
92
- const serverDirectory = path.join(piAgentDirectory(baseEnvironment), "server");
93
117
  const requestReceipts = createRequestReceipts({ directory: path.join(serverDirectory, "request-receipts-v1") });
94
118
  const activeMedia = /* @__PURE__ */ new Set();
95
119
  const mediaArbitration = {
@@ -173,7 +197,7 @@ async function runServerRuntime(options, runtime) {
173
197
  /** The last harness context built to report each repository's MCP projection, kept while it is current. */
174
198
  const repositoryContexts = /* @__PURE__ */ new Map();
175
199
  const sessionArtifacts = /* @__PURE__ */ new Map();
176
- /** Each host's facet root, where its session services (background work included) live. */
200
+ /** Each host's session package root, where its session services (background work included) live. */
177
201
  const sessionServiceRoots = /* @__PURE__ */ new WeakMap();
178
202
  let mountSessionApis;
179
203
  /**
@@ -260,8 +284,11 @@ async function runServerRuntime(options, runtime) {
260
284
  stepUpRequired: () => remoteRuntime?.remote.stepUpRequired("computer-use.activate") === true
261
285
  });
262
286
  let hub;
287
+ /** Assigned once the global builds can be read; no session opens before then. */
288
+ let publishSessionCompositions = () => ({});
263
289
  hub = createHeadlessHub({
264
290
  manager: sessionManager,
291
+ platform,
265
292
  resolveProfileIdentity: (root, profile) => {
266
293
  const identity = resolveProfile(root, profile, homeDirectory).identity;
267
294
  return identity === void 0 ? void 0 : {
@@ -269,10 +296,11 @@ async function runServerRuntime(options, runtime) {
269
296
  icon: identity.icon
270
297
  };
271
298
  },
299
+ publishSessionCompositions: (sessionId, root, majorMode) => publishSessionCompositions(sessionId, root, majorMode),
272
300
  admitWorkspace: async ({ root, name }) => admitWorkspace(root === void 0 || root.trim() === "" ? await createDefaultWorkspaceFolder(name ?? "", homeDirectory) : root, name),
273
301
  onWorkspaceRemoved: (workspaceId) => {
274
302
  workspaces.remove(workspaceId);
275
- reloadCheck.forget(`workspace:${workspaceId}`);
303
+ bundler.forgetScope(`workspace:${workspaceId}`);
276
304
  webCompositions?.remove({
277
305
  scope: "workspace",
278
306
  workspaceId
@@ -314,7 +342,7 @@ async function runServerRuntime(options, runtime) {
314
342
  const hosts = sessionManager.sessions();
315
343
  if (hosts.some((host) => {
316
344
  const root = sessionServiceRoots.get(host);
317
- const service = root === void 0 ? void 0 : readDoomBackgroundWorkService(root);
345
+ const service = root === void 0 ? void 0 : readPoBackgroundWorkService(root);
318
346
  return service !== void 0 && holdsRestart(service.snapshot());
319
347
  })) return true;
320
348
  return (await Promise.all(hosts.map((host) => host.runtime.readState()))).some((state) => state.isStreaming || state.isCompacting);
@@ -326,10 +354,13 @@ async function runServerRuntime(options, runtime) {
326
354
  const stopPersistSessionNames = hub.onEvent((event) => {
327
355
  if (event.kind !== "upsert") return;
328
356
  const record = openSessions.list().find((entry) => entry.sessionId === event.session.id);
329
- if (record === void 0 || record.name === event.session.name) return;
357
+ const groups = event.session.groups ?? [];
358
+ const sameGroups = groups.length === (record?.groups ?? []).length && groups.every((group, index) => record?.groups?.[index] === group);
359
+ if (record === void 0 || record.name === event.session.name && sameGroups) return;
330
360
  openSessions.add({
331
361
  ...record,
332
- name: event.session.name
362
+ name: event.session.name,
363
+ groups
333
364
  });
334
365
  });
335
366
  let harnessContext;
@@ -359,7 +390,7 @@ async function runServerRuntime(options, runtime) {
359
390
  sessionId: options.sessionId ?? crypto.randomUUID(),
360
391
  sessionName: options.sessionName
361
392
  });
362
- const globalRoot = globalDoomConfigDirectory(homeDirectory);
393
+ const globalRoot = globalPoConfigDirectory(homeDirectory);
363
394
  webCompositions = createWebCompositions(path.join(globalRoot, "server"), notice);
364
395
  /** Assigned once every scope can be checked; a sync that exits sooner is picked up then. */
365
396
  let pickUpSync = async () => void 0;
@@ -375,37 +406,14 @@ async function runServerRuntime(options, runtime) {
375
406
  background: backgroundSync,
376
407
  onNotice: notice
377
408
  });
378
- /**
379
- * Every composition the root's config can select, one per major mode, resolved live
380
- * from the root. A package sync has not prepared yet is left out with a diagnostic, so
381
- * the root opens without it; the server never installs or builds.
382
- */
383
- const liveCompositions = (root) => rootCompositions({
384
- root,
385
- homeDirectory,
386
- environment: baseEnvironment,
387
- tolerateUnsynced: true
409
+ watcher.add({
410
+ path: path.dirname(syncPointerPath(globalRoot)),
411
+ include: (file) => file === path.basename(syncPointerPath(globalRoot))
388
412
  });
389
- /** The root's server facet entries, each with the URL its current package content imports from. */
390
- const facetEntries = async (root) => {
391
- const entries = [];
392
- for (const { declaration, module, owners } of serverFacetCandidates(liveCompositions(root))) entries.push({
393
- packageName: declaration.packageName,
394
- entry: declaration.entry,
395
- module,
396
- url: await packageUrls.urlFor(module),
397
- scopes: declaration.scopes,
398
- owners,
399
- required: declaration.required === true
400
- });
401
- return entries;
402
- };
403
- /** Every package root the root's config can select, over all its major modes. */
404
- const scopePackageRoots = (root) => compositionPackageRoots(liveCompositions(root));
405
413
  /** What the root opened without: packages that do not resolve yet and web plugins with no slot. */
406
414
  const unsyncedOf = (root) => {
407
415
  try {
408
- const compositions = liveCompositions(root);
416
+ const compositions = bundler.compositions(root);
409
417
  const unslotted = webBuild === void 0 ? [] : unslottedWebPackages(webBuild, compositionPackageRoots(compositions));
410
418
  return [.../* @__PURE__ */ new Set([...unsyncedSelectors(compositions), ...unslotted])];
411
419
  } catch (error) {
@@ -421,11 +429,24 @@ async function runServerRuntime(options, runtime) {
421
429
  unsynced: unsyncedOf(root)
422
430
  }, request);
423
431
  let webBuild;
424
- /** Publishes one mount out of the current global build, naming only the plugin slots its root resolves. */
425
- const publishWebMount = (mount, root) => webBuild === void 0 ? void 0 : webCompositions?.publish(mount, webBuild, hub.channelTypes(), mountWebPluginSlots(webBuild, scopePackageRoots(root)));
432
+ /**
433
+ * Publishes one mount out of the current global build, naming only the plugin slots its root
434
+ * resolves. A session mount passes its major mode, so it names only that mode's slots.
435
+ */
436
+ const publishWebMount = (mount, root, majorMode) => webBuild === void 0 ? void 0 : webCompositions?.publish(mount, webBuild, hub.channelTypes(), mountWebPluginSlots(webBuild, bundler.packageRoots(root, majorMode)));
426
437
  let nativeBuild;
427
438
  /** Publishes one mount's native composition out of the current global native build. */
428
- const publishNativeMount = (mount, root) => nativeBuild === void 0 ? void 0 : webCompositions?.publishNative(mount, nativeBuild, hub.channelTypes(), mountNativePluginIds(nativeBuild, scopePackageRoots(root)));
439
+ const publishNativeMount = (mount, root, majorMode) => nativeBuild === void 0 ? void 0 : webCompositions?.publishNative(mount, nativeBuild, hub.channelTypes(), mountNativePluginIds(nativeBuild, bundler.packageRoots(root, majorMode)));
440
+ publishSessionCompositions = (sessionId, root, majorMode) => ({
441
+ webComposition: publishWebMount({
442
+ scope: "session",
443
+ sessionId
444
+ }, root, majorMode),
445
+ nativeComposition: publishNativeMount({
446
+ scope: "session",
447
+ sessionId
448
+ }, root, majorMode)
449
+ });
429
450
  const pickUpWebBuild = createKeyedPickup((key) => readGlobalWebBuildRecord(globalRoot, key), (build, key) => {
430
451
  notice(`Publishing global web build ${key}.`);
431
452
  webBuild = build;
@@ -487,58 +508,28 @@ async function runServerRuntime(options, runtime) {
487
508
  for (const { root, mount } of mounts) publish(mount, root);
488
509
  }
489
510
  };
490
- const defaultSelection = (root) => {
491
- const config = loadMajorModesConfig(root, homeDirectory, baseEnvironment);
492
- const majorMode = config.defaultMajorMode;
493
- return {
494
- root,
495
- majorMode,
496
- activeLayers: resolveLayers(config, majorMode)
497
- };
498
- };
499
511
  const loadComposition = async (root, scope, selection) => {
500
- const selected = selection ?? defaultSelection(root);
501
- return telemetry.runInSpan("po_server.composition_load", { scope }, async () => loadServerFacets(scope, {
502
- entries: await facetEntries(root),
512
+ const selected = selection ?? bundler.defaultSelection(root);
513
+ return telemetry.runInSpan("po_server.composition_load", { scope }, async () => loadServerPackages(scope, {
514
+ entries: await bundler.packageEntries(root),
503
515
  majorMode: selected.majorMode,
504
516
  activeLayers: selected.activeLayers,
505
517
  retainCandidates: scope === "session",
506
518
  onNotice: notice,
507
- poisoned: poisonedUrls,
508
- importer: importLive
519
+ poisoned: bundler.poisoned,
520
+ importer: bundler.importer
509
521
  }));
510
522
  };
511
523
  const scopeKey = (mount) => mount.scope === "global" ? "global" : `workspace:${mount.workspaceId}`;
512
- /**
513
- * What a global or workspace scope loads: one identity per facet entry in that scope.
514
- * The URL changes with package content; `selection` carries ownership and the root's
515
- * default mode, so a modes.yaml change that moves a facet in or out remounts too.
516
- */
517
- const scopeIdentities = (root, scope, entries) => {
518
- const { majorMode, activeLayers } = defaultSelection(root);
519
- return entries.filter((entry) => entry.scopes.includes(scope)).map((entry) => ({
520
- module: entry.module,
521
- url: entry.url,
522
- selection: JSON.stringify([
523
- entry.owners,
524
- entry.required === true,
525
- majorMode,
526
- activeLayers
527
- ])
528
- }));
529
- };
530
524
  const scopeChecks = /* @__PURE__ */ new Map();
531
525
  /**
532
- * The reload check for one mounted global or workspace scope: recompute its package
533
- * URLs and, only when they changed, load the new set and swap it in with
534
- * `replaceFacets`. Unchanged URLs come from the module cache, so only changed packages
535
- * import. A scope this server has not mounted yet is left to its admission. Checks of
536
- * one scope run one at a time; a failure restores the previous facets (the hub reports a
537
- * failed restore) and retries next time.
538
- *
539
- * ponytail: no fs.watch. A rebuilt local package takes effect at the next session or
540
- * admission. Watch the declared entries (see packageUrl's declaredTargets) and call this
541
- * when workspace routes must update without opening a session.
526
+ * The reload check for one served global or workspace scope: recompute its package URLs
527
+ * and, only when they changed, load the new set and install it. Unchanged URLs come from
528
+ * the module cache and the scope skips them, so only changed packages import and restart;
529
+ * a package no longer selected stays installed. A scope this server has not served yet is
530
+ * left to its admission. Checks of one scope run one at a time; a changed package whose
531
+ * new build fails gets its previous build back, and the check retries next time. Runs on a
532
+ * watched change, a finished sync and an upm change, never on the session path.
542
533
  */
543
534
  const checkScope = (root, mount) => {
544
535
  const key = scopeKey(mount);
@@ -548,15 +539,15 @@ async function runServerRuntime(options, runtime) {
548
539
  } catch (error) {
549
540
  notice(`Web build check failed: ${error instanceof Error ? error.message : String(error)}`);
550
541
  }
551
- const change = reloadCheck.diff(key, scopeIdentities(root, mount.scope, await facetEntries(root)));
542
+ const change = await bundler.diffScope(key, root, mount.scope);
552
543
  if (change.first || change.changed.length === 0 && change.reselected.length === 0 && change.removed.length === 0) return;
553
544
  const bundle = await loadComposition(root, mount.scope);
554
- await hub.replaceFacets(mount, bundle.facets);
555
- reloadCheck.commit(key, scopeIdentities(root, mount.scope, bundle.entries));
545
+ await hub.installPackages(mount, bundle.packages);
546
+ bundler.commitScope(key, root, mount.scope, bundle.entries);
556
547
  idleRestart.supersede(change.superseded);
557
548
  publishWebMount(mount, root);
558
549
  publishNativeMount(mount, root);
559
- notice(`Reloaded ${mount.scope === "global" ? "global" : `workspace '${mount.workspaceId}'`} facets (${String(change.changed.length)} changed, ${String(change.removed.length)} removed).`);
550
+ notice(`Reloaded ${mount.scope === "global" ? "global" : `workspace '${mount.workspaceId}'`} packages (${String(change.changed.length)} changed, ${String(change.removed.length)} no longer selected).`);
560
551
  }).catch((error) => notice(`Extension check of ${key} failed and retries at the next check: ${error instanceof Error ? error.message : String(error)}`));
561
552
  scopeChecks.set(key, settled);
562
553
  settled.then(() => {
@@ -566,16 +557,7 @@ async function runServerRuntime(options, runtime) {
566
557
  };
567
558
  const loadSessionMcp = async (root, selection) => {
568
559
  return telemetry.runInSpan("po_server.mcp_bundle_load", {}, async () => {
569
- const entries = [];
570
- const candidates = mcpPluginCandidates(liveCompositions(root));
571
- for (const { declaration, module, owners } of candidates) entries.push({
572
- packageName: declaration.packageName,
573
- ...declaration.ui === void 0 ? {} : { widgets: declaration.ui.widgets },
574
- entry: declaration.entry,
575
- module,
576
- url: await packageUrls.urlFor(module),
577
- owners
578
- });
560
+ const { candidates, entries } = await bundler.mcpEntries(root);
579
561
  let app;
580
562
  try {
581
563
  app = readMcpAppBuild({
@@ -597,8 +579,8 @@ async function runServerRuntime(options, runtime) {
597
579
  activeLayers: selection.activeLayers,
598
580
  retainCandidates: true,
599
581
  onNotice: notice,
600
- poisoned: poisonedUrls,
601
- importer: importLive
582
+ poisoned: bundler.poisoned,
583
+ importer: bundler.importer
602
584
  });
603
585
  });
604
586
  };
@@ -670,27 +652,22 @@ async function runServerRuntime(options, runtime) {
670
652
  redirect: "manual"
671
653
  }));
672
654
  },
673
- connectProtocol: (pathname, deviceId) => {
674
- if (!cockpit || !attachToken) throw new Error("The headless protocol listener is not ready.");
675
- const url = new URL(pathname, cockpit.url);
676
- url.protocol = "ws:";
677
- return new WebSocket(url, { headers: {
678
- "x-po-token": attachToken,
679
- ...deviceId === void 0 ? {} : {
680
- "x-po-api-caller-locality": "remote",
681
- "x-po-api-caller-device-id": deviceId,
682
- "x-po-api-caller-step-up": "not-required"
683
- }
684
- } });
655
+ acceptProtocol: (pathname, link, deviceId) => {
656
+ if (!cockpit) throw new Error("The headless protocol listener is not ready.");
657
+ return cockpit.acceptProtocol(pathname, link, {
658
+ "x-po-api-caller-locality": "remote",
659
+ "x-po-api-caller-device-id": deviceId,
660
+ "x-po-api-caller-step-up": "not-required"
661
+ });
685
662
  }
686
663
  });
687
- await hub.mountFacets(globalBundle.facets, {
664
+ await hub.serveScope({
688
665
  ...sharedApiContext,
689
666
  scope: "global",
690
667
  requestReceipts: requestReceipts.receipts,
691
668
  remoteControl: { fetch: (request) => remoteRuntime.fetchLocal(request) }
692
- });
693
- reloadCheck.commit("global", scopeIdentities(globalRoot, "global", globalBundle.entries));
669
+ }, globalBundle.packages);
670
+ bundler.commitScope("global", globalRoot, "global", globalBundle.entries);
694
671
  refreshWebBuild();
695
672
  syncCheckpoint(globalRoot, "The global scope");
696
673
  if (!backgroundSync.syncing) backgroundSync.request("server start");
@@ -709,10 +686,6 @@ async function runServerRuntime(options, runtime) {
709
686
  const renamed = record !== void 0 && name !== record.name;
710
687
  const existing = hub.workspaces().find((workspace) => workspace.id === id);
711
688
  if (existing !== void 0 && existing.available !== false && existing.root === root) {
712
- await checkScope(root, {
713
- scope: "workspace",
714
- workspaceId: id
715
- });
716
689
  syncCheckpoint(root, workspaceLabel(root, name));
717
690
  if (renamed) {
718
691
  workspaces.add({
@@ -749,15 +722,15 @@ async function runServerRuntime(options, runtime) {
749
722
  });
750
723
  const admission = (async () => {
751
724
  const bundle = await loadComposition(root, "workspace");
752
- await hub.mountFacets(bundle.facets, {
725
+ await hub.serveScope({
753
726
  ...sharedApiContext,
754
727
  scope: "workspace",
755
728
  workspaceId: id,
756
729
  workspaceRoot: root,
757
730
  cwd: root,
758
731
  resolveRepository: (requestedId) => requestedId === id ? root : void 0
759
- });
760
- reloadCheck.commit(`workspace:${id}`, scopeIdentities(root, "workspace", bundle.entries));
732
+ }, bundle.packages);
733
+ bundler.commitScope(`workspace:${id}`, root, "workspace", bundle.entries);
761
734
  try {
762
735
  refreshWebBuild();
763
736
  publishWebMount({
@@ -856,20 +829,14 @@ async function runServerRuntime(options, runtime) {
856
829
  return {
857
830
  cwd: policyOptions.cwd,
858
831
  repoRoot: policyOptions.repoRoot,
832
+ platform,
859
833
  sessionId: identity.sessionId,
860
834
  workspaceId: workspace.id,
861
835
  groupingRoot: workspace.root,
862
836
  sessionName: identity.sessionName,
863
837
  ...explicit.initialFastMode === void 0 ? {} : { initialFastMode: explicit.initialFastMode },
864
838
  ...explicit.initialAgentLocked === void 0 ? {} : { initialAgentLocked: explicit.initialAgentLocked },
865
- webComposition: publishWebMount({
866
- scope: "session",
867
- sessionId: identity.sessionId
868
- }, workspace.root),
869
- nativeComposition: publishNativeMount({
870
- scope: "session",
871
- sessionId: identity.sessionId
872
- }, workspace.root),
839
+ ...explicit.resume ? { resume: true } : {},
873
840
  ...identity.parentSessionId === void 0 ? {} : { parentSessionId: identity.parentSessionId },
874
841
  ...identity.sessionProvenance === void 0 ? {} : { sessionProvenance: identity.sessionProvenance },
875
842
  agentArgs: policyOptions.piArgs,
@@ -901,7 +868,7 @@ async function runServerRuntime(options, runtime) {
901
868
  };
902
869
  },
903
870
  candidates: bundle.entries,
904
- providerOverrides: () => selectedServerProviderOverrides(bundle.facets, sessionEnvironment),
871
+ providerOverrides: () => selectedServerProviderOverrides(bundle.packages, sessionEnvironment),
905
872
  requiredServerPackages: async () => {
906
873
  const harness = loadHarnessState(sessionEnvironment).state;
907
874
  if (!harness.hooks) return [];
@@ -926,14 +893,16 @@ async function runServerRuntime(options, runtime) {
926
893
  onNotice: notice
927
894
  };
928
895
  };
929
- mountSessionApis = (sessionOptions, host) => serveSessionApis({
896
+ mountSessionApis = async (sessionOptions, host) => serveSessionApis({
897
+ parentScope: await hub.sessionParentScope(sessionOptions.workspaceId),
930
898
  sessionId: sessionOptions.sessionId,
899
+ platform,
931
900
  cwd: sessionOptions.cwd,
932
901
  environment: sessionOptions.environment,
933
902
  directEvents: hub.directEvents,
934
903
  requestApi: (mount, basePath, request) => hub.requestApi(mount, basePath, request),
935
904
  publishActivity: (activity) => hub.setSessionActivity?.(sessionOptions.sessionId, activity),
936
- shareFile: (filePath, label) => remoteRuntime === void 0 ? Promise.reject(new Error(DOOM_SHARE_FILE_REMOTE_OFF_MESSAGE)) : remoteRuntime.fileShares.mint({
905
+ shareFile: (filePath, label) => remoteRuntime === void 0 ? Promise.reject(new Error(PO_SHARE_FILE_REMOTE_OFF_MESSAGE)) : remoteRuntime.fileShares.mint({
937
906
  sessionId: sessionOptions.sessionId,
938
907
  cwd: sessionOptions.cwd,
939
908
  path: filePath,
@@ -960,10 +929,11 @@ async function runServerRuntime(options, runtime) {
960
929
  sessionService: hub.sessionService,
961
930
  mediaArbitration,
962
931
  executionBudget,
932
+ editPresence: hub.editPresence,
963
933
  peerAgents,
964
934
  pluginRegistry: hub.pluginRegistry,
965
935
  apis: [],
966
- facets: pendingSessions.get(sessionOptions.sessionId)?.bundle.facets ?? [],
936
+ packages: pendingSessions.get(sessionOptions.sessionId)?.bundle.packages ?? [],
967
937
  workspaceId: sessionOptions.workspaceId,
968
938
  workspaceRoot: sessionOptions.repoRoot,
969
939
  ...host.sessionContext === void 0 ? {} : { sessionContext: host.sessionContext },
@@ -977,11 +947,11 @@ async function runServerRuntime(options, runtime) {
977
947
  })
978
948
  };
979
949
  },
980
- prepareFacets: (root) => {
950
+ preparePackages: (root) => {
981
951
  sessionServiceRoots.set(host, root);
982
- host.prepareFacets(root);
952
+ host.preparePackages(root);
983
953
  },
984
- activateFacets: host.activateFacets,
954
+ activatePackages: host.activatePackages,
985
955
  canDispatch: host.canDispatch,
986
956
  telemetry,
987
957
  onNotice: notice
@@ -1080,6 +1050,7 @@ async function runServerRuntime(options, runtime) {
1080
1050
  };
1081
1051
  const inheritedWorkspaceId = groupingWorkspaceId ?? (request.parentSessionId ? hub.session(request.parentSessionId)?.workspaceId ?? openSessions.list().find((record) => record.sessionId === request.parentSessionId)?.workspaceId : void 0);
1082
1052
  const explicit = sessionSelectionArgs(request);
1053
+ const openStartedAt = Date.now();
1083
1054
  const start = (async () => {
1084
1055
  const parent = request.parentSessionId !== void 0 && (sessionId === void 0 || request.reservationId !== void 0) ? sessionManager.get(request.parentSessionId) : void 0;
1085
1056
  let initialFastMode;
@@ -1089,7 +1060,6 @@ async function runServerRuntime(options, runtime) {
1089
1060
  initialFastMode = state.fastMode;
1090
1061
  }
1091
1062
  const childIdentity = resolveSessionIdentity([], identity);
1092
- if (sessionId !== void 0 && request.reservationId === void 0) childIdentity.agentArgs.push("--session", path.join(serverDirectory, "sessions", "durable-v1", `${childIdentity.identity.sessionId}.sqlite`));
1093
1063
  const childEnvironment = {
1094
1064
  ...baseEnvironment,
1095
1065
  ...request.environment
@@ -1097,15 +1067,8 @@ async function runServerRuntime(options, runtime) {
1097
1067
  for (const key of [HARNESS_STATE_POINTER, ...Object.values(HARNESS_STATE_KEYS)]) delete childEnvironment[key];
1098
1068
  const workspace = inheritedWorkspaceId === void 0 ? await admitWorkspace(request.cwd) : hub.workspaces().find((candidate) => candidate.id === inheritedWorkspaceId && candidate.available !== false);
1099
1069
  if (workspace === void 0) throw new Error("The session workspace is unavailable.");
1100
- await checkScope(globalRoot, { scope: "global" });
1101
1070
  syncCheckpoint(globalRoot, "The global scope");
1102
- if (inheritedWorkspaceId !== void 0) {
1103
- await checkScope(workspace.root, {
1104
- scope: "workspace",
1105
- workspaceId: workspace.id
1106
- });
1107
- syncCheckpoint(workspace.root, workspaceLabel(workspace.root, workspace.name));
1108
- }
1071
+ if (inheritedWorkspaceId !== void 0) syncCheckpoint(workspace.root, workspaceLabel(workspace.root, workspace.name));
1109
1072
  const member = isMemberCheckout(request.cwd, workspace);
1110
1073
  const childContext = await buildHarnessContext(resolveHarnessOptions({
1111
1074
  args: [
@@ -1148,6 +1111,7 @@ async function runServerRuntime(options, runtime) {
1148
1111
  pinned: explicit.pinned,
1149
1112
  ...initialFastMode === void 0 ? {} : { initialFastMode },
1150
1113
  ...request.reservationId === void 0 ? {} : { initialAgentLocked: true },
1114
+ ...sessionId !== void 0 && request.reservationId === void 0 ? { resume: true } : {},
1151
1115
  ...request.selection?.minorModes === void 0 ? {} : { minorModes: request.selection.minorModes },
1152
1116
  ...request.tools === void 0 ? {} : { allowedTools: request.tools }
1153
1117
  }));
@@ -1162,7 +1126,8 @@ async function runServerRuntime(options, runtime) {
1162
1126
  name: created.name,
1163
1127
  createdAt: created.createdAt,
1164
1128
  ...created.parentSessionId === void 0 ? {} : { parentSessionId: created.parentSessionId },
1165
- ...created.sessionProvenance === void 0 ? {} : { sessionProvenance: created.sessionProvenance }
1129
+ ...created.sessionProvenance === void 0 ? {} : { sessionProvenance: created.sessionProvenance },
1130
+ ...created.groups === void 0 || created.groups.length === 0 ? {} : { groups: [...created.groups] }
1166
1131
  }) === false) throw new Error("The new session could not be durably recorded.");
1167
1132
  }
1168
1133
  return {
@@ -1179,6 +1144,10 @@ async function runServerRuntime(options, runtime) {
1179
1144
  throw error;
1180
1145
  }
1181
1146
  })();
1147
+ start.then(() => "success", () => "failure").then((outcome) => telemetry.recordEvent("po_server.session_open", {
1148
+ duration_ms: Date.now() - openStartedAt,
1149
+ outcome
1150
+ })).catch((error) => rawNotice(`session open telemetry failed: ${String(error)}`));
1182
1151
  if (request.reservationId !== void 0) reservedOpens.set(identity.sessionId, start);
1183
1152
  try {
1184
1153
  return await start;
@@ -1187,6 +1156,8 @@ async function runServerRuntime(options, runtime) {
1187
1156
  }
1188
1157
  };
1189
1158
  const checkAllScopes = async () => {
1159
+ bundler.invalidate();
1160
+ syncCheckpoints.invalidate();
1190
1161
  await checkScope(globalRoot, { scope: "global" });
1191
1162
  for (const workspace of hub.workspaces()) if (workspace.available !== false) await checkScope(workspace.root, {
1192
1163
  scope: "workspace",
@@ -1197,7 +1168,7 @@ async function runServerRuntime(options, runtime) {
1197
1168
  /**
1198
1169
  * A finished background sync goes through the same live reload: the read-only refresh
1199
1170
  * republishes a changed build, and each scope re-imports only packages whose URLs moved.
1200
- * Session facets and the MCP app switch at the next session. The warnings are re-read
1171
+ * Session packages and the MCP app switch at the next session. The warnings are re-read
1201
1172
  * without requesting another sync, so a sync that could not fix a root never loops.
1202
1173
  */
1203
1174
  pickUpSync = async () => {
@@ -1205,12 +1176,21 @@ async function runServerRuntime(options, runtime) {
1205
1176
  syncCheckpoint(globalRoot, "The global scope", false);
1206
1177
  for (const workspace of hub.workspaces()) if (workspace.available !== false) syncCheckpoint(workspace.root, workspaceLabel(workspace.root, workspace.name), false);
1207
1178
  };
1179
+ pickUpChange = () => {
1180
+ pickUpSync().catch((error) => notice(`Extension reload failed: ${String(error)}`));
1181
+ };
1208
1182
  });
1209
1183
  const workspaceResumes = /* @__PURE__ */ new Map();
1184
+ const reportedUnreadable = /* @__PURE__ */ new Set();
1185
+ const unreadableHistory = (sessionId, error) => {
1186
+ if (reportedUnreadable.has(sessionId)) return;
1187
+ reportedUnreadable.add(sessionId);
1188
+ notice(`Saved session ${sessionId} is hidden from History: ${error instanceof Error ? error.message : String(error)}`);
1189
+ };
1210
1190
  const savedHistory = async (workspaceId) => {
1211
1191
  const root = hub.workspaces().find((workspace) => workspace.id === workspaceId && workspace.available !== false)?.root;
1212
1192
  if (!root) throw new Error("Workspace not found.");
1213
- return listSavedSessionRecords(path.join(serverDirectory, "sessions"), root, new Set(hub.snapshot().map((active) => active.id)), workspaceId);
1193
+ return listSavedSessionRecords(platform.sessions, root, new Set(hub.snapshot().map((active) => active.id)), workspaceId, unreadableHistory);
1214
1194
  };
1215
1195
  const validateExecution = (target, workspaceId) => {
1216
1196
  const root = hub.workspaces().find((workspace) => workspace.id === workspaceId && workspace.available !== false)?.root;
@@ -1227,6 +1207,9 @@ async function runServerRuntime(options, runtime) {
1227
1207
  ...record.parentSessionId === void 0 ? {} : { parentSessionId: record.parentSessionId },
1228
1208
  ...record.sessionProvenance === void 0 ? {} : { sessionProvenance: record.sessionProvenance }
1229
1209
  }, record.sessionId, record.workspaceId);
1210
+ const groups = record.groups ?? [];
1211
+ const opened = hub.session(record.sessionId)?.groups ?? [];
1212
+ if (groups.length !== opened.length || groups.some((group, index) => opened[index] !== group)) await hub.runtime(record.sessionId)?.setGroups(groups);
1230
1213
  };
1231
1214
  cockpit = await serveHeadlessServer({
1232
1215
  port: options.webPort,
@@ -1263,14 +1246,14 @@ async function runServerRuntime(options, runtime) {
1263
1246
  sessionHistory: (session) => {
1264
1247
  const workspaceRoot = hub.workspaces().find((workspace) => workspace.id === session.workspaceId)?.root;
1265
1248
  if (!workspaceRoot) throw new Error("Session workspace not found.");
1266
- return listSavedSessions(path.join(piAgentDirectory(baseEnvironment), "server", "sessions"), workspaceRoot, new Set(hub.snapshot().map((active) => active.id)), session.workspaceId);
1249
+ return listSavedSessions(platform.sessions, workspaceRoot, new Set(hub.snapshot().map((active) => active.id)), session.workspaceId, unreadableHistory);
1267
1250
  },
1268
1251
  readDormantTranscript: (record, request, context) => {
1269
1252
  const workspaceRoot = hub.workspaces().find((workspace) => workspace.id === record.workspaceId)?.root;
1270
1253
  if (!workspaceRoot || record.groupingRoot !== void 0 && record.groupingRoot !== workspaceRoot) throw new Error("Saved transcript unavailable.");
1271
1254
  const owner = fs.realpathSync(findRepositoryRoot(record.cwd));
1272
1255
  if (record.repoRoot !== void 0 && record.repoRoot !== owner) throw new Error("Saved transcript checkout has changed.");
1273
- return readSqliteTranscript(path.join(piAgentDirectory(baseEnvironment), "server", "sessions", "durable-v1", `${record.sessionId}.sqlite`), request, context, {
1256
+ return readSqliteTranscript(platform.sessions, record.sessionId, request, context, {
1274
1257
  sessionId: record.sessionId,
1275
1258
  workspaceRoot: owner,
1276
1259
  workspaceId: record.workspaceId,
@@ -1316,6 +1299,12 @@ async function runServerRuntime(options, runtime) {
1316
1299
  },
1317
1300
  dormantSessions: () => openSessions.list(),
1318
1301
  removeDormantSession: (record) => openSessions.remove(record.sessionId),
1302
+ setDormantGroups: (record, groups) => {
1303
+ if (!openSessions.add({
1304
+ ...record,
1305
+ groups: [...groups]
1306
+ })) throw new Error("The session groups could not be durably recorded.");
1307
+ },
1319
1308
  reviveSession: reviveRecord,
1320
1309
  requestAsset: (request) => webCompositions?.request(request) ?? Promise.resolve(void 0),
1321
1310
  compositions: () => {
@@ -1389,6 +1378,7 @@ async function runServerRuntime(options, runtime) {
1389
1378
  stopIdleRestartPoke();
1390
1379
  stopResourceMonitor();
1391
1380
  executionBudget.close();
1381
+ watcher.close();
1392
1382
  stopPersistSessionNames();
1393
1383
  clearInterval(eventLoopMonitor);
1394
1384
  await bounded(telemetry.recordEvent("po_server.shutdown"), "shutdown telemetry", notice);