@promptbook/cli 0.114.0-13 → 0.114.0-18

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 (231) hide show
  1. package/apps/agents-server/next.config.ts +6 -0
  2. package/apps/agents-server/src/app/admin/_components/AdminFilterFields.tsx +84 -0
  3. package/apps/agents-server/src/app/admin/_components/AdminMetricCard.tsx +36 -0
  4. package/apps/agents-server/src/app/admin/_components/AdminTaskManagerTabs.tsx +97 -0
  5. package/apps/agents-server/src/app/admin/planned-messages/PlannedMessageManagerClient.tsx +103 -0
  6. package/apps/agents-server/src/app/admin/planned-messages/PlannedMessageManagerEditDialog.tsx +232 -0
  7. package/apps/agents-server/src/app/admin/planned-messages/PlannedMessageManagerFiltersCard.tsx +195 -0
  8. package/apps/agents-server/src/app/admin/planned-messages/PlannedMessageManagerRow.tsx +189 -0
  9. package/apps/agents-server/src/app/admin/planned-messages/PlannedMessageManagerSummaryMetrics.tsx +60 -0
  10. package/apps/agents-server/src/app/admin/planned-messages/PlannedMessageManagerTableCard.tsx +147 -0
  11. package/apps/agents-server/src/app/admin/planned-messages/page.tsx +17 -0
  12. package/apps/agents-server/src/app/admin/planned-messages/plannedMessageEditForm.ts +186 -0
  13. package/apps/agents-server/src/app/admin/planned-messages/plannedMessageManagerDialogs.ts +46 -0
  14. package/apps/agents-server/src/app/admin/planned-messages/plannedMessageManagerPresentation.tsx +188 -0
  15. package/apps/agents-server/src/app/admin/planned-messages/resolvePlannedMessageSortValue.ts +115 -0
  16. package/apps/agents-server/src/app/admin/planned-messages/usePlannedMessageManagerData.ts +116 -0
  17. package/apps/agents-server/src/app/admin/planned-messages/usePlannedMessageManagerState.ts +289 -0
  18. package/apps/agents-server/src/app/admin/task-manager/TaskManagerClient.tsx +7 -2
  19. package/apps/agents-server/src/app/admin/task-manager/TaskManagerFiltersCard.tsx +7 -73
  20. package/apps/agents-server/src/app/admin/task-manager/TaskManagerSummaryMetrics.tsx +5 -30
  21. package/apps/agents-server/src/app/admin/task-manager/[taskId]/TaskManagerTaskDetailClient.tsx +1 -1
  22. package/apps/agents-server/src/app/agents/[agentName]/api/book/reference-diagnostics/route.ts +30 -7
  23. package/apps/agents-server/src/app/agents/[agentName]/api/book/route.ts +1 -0
  24. package/apps/agents-server/src/app/agents/[agentName]/api/book/test.http +3 -3
  25. package/apps/agents-server/src/app/agents/[agentName]/book/BookEditorMissingReferences.tsx +106 -12
  26. package/apps/agents-server/src/app/agents/[agentName]/book/BookEditorWrapper.tsx +3 -0
  27. package/apps/agents-server/src/app/agents/[agentName]/book/useBookEditorDiagnostics.ts +12 -0
  28. package/apps/agents-server/src/app/agents/[agentName]/book/useBookEditorWrapper.tsx +2 -0
  29. package/apps/agents-server/src/app/agents/[agentName]/chat/AgentGoalChatPlannedMessages.tsx +46 -3
  30. package/apps/agents-server/src/app/api/admin/default-agents/reinstate/route.ts +5 -1
  31. package/apps/agents-server/src/app/api/admin/planned-messages/[timeoutId]/route.ts +80 -0
  32. package/apps/agents-server/src/app/api/admin/planned-messages/route.ts +19 -0
  33. package/apps/agents-server/src/app/api/internal/agent-goal-chat-planned-messages/route.ts +30 -2
  34. package/apps/agents-server/src/components/DefaultAgents/ReinstateBundledAgentsButton.tsx +7 -0
  35. package/apps/agents-server/src/components/DefaultAgents/coreAgentsAdminRoute.ts +6 -0
  36. package/apps/agents-server/src/components/Header/buildHeaderSystemMenuItems.ts +7 -0
  37. package/apps/agents-server/src/components/Homepage/DefaultAgentsStatusNotice.tsx +1 -7
  38. package/apps/agents-server/src/database/migrations/2026-08-1800-user-chat-timeout-schedule.sql +11 -0
  39. package/apps/agents-server/src/instrumentation-node.ts +18 -0
  40. package/apps/agents-server/src/languages/ServerTranslationKeys.ts +4 -0
  41. package/apps/agents-server/src/languages/translations/czech.yaml +4 -0
  42. package/apps/agents-server/src/languages/translations/english.yaml +4 -0
  43. package/apps/agents-server/src/tools/agentGoalChatTimeoutToolFunctions.ts +62 -15
  44. package/apps/agents-server/src/tools/agentGoalChatTimeoutTools.ts +63 -9
  45. package/apps/agents-server/src/utils/adminEntityLookups/loadAgentNamesByPermanentId.ts +45 -0
  46. package/apps/agents-server/src/utils/adminEntityLookups/loadUsernamesByUserId.ts +36 -0
  47. package/apps/agents-server/src/utils/adminEntityLookups.ts +2 -0
  48. package/apps/agents-server/src/utils/agentGoalChat/agentGoalChatPlannedMessageActions.ts +299 -52
  49. package/apps/agents-server/src/utils/agentGoalChat/createAgentGoalChatNoteContent.ts +45 -17
  50. package/apps/agents-server/src/utils/agentGoalChat.ts +1 -0
  51. package/apps/agents-server/src/utils/agentProjects/agentProjectIdentity.ts +46 -0
  52. package/apps/agents-server/src/utils/agentProjects/agentProjectRuntimeAutostartScheduler.ts +162 -0
  53. package/apps/agents-server/src/utils/agentProjects/agentProjectRuntimeDesiredState.ts +252 -0
  54. package/apps/agents-server/src/utils/agentProjects/agentProjectRuntimeDisplay.ts +6 -3
  55. package/apps/agents-server/src/utils/agentProjects/agentProjectRuntimeDomains.ts +2 -44
  56. package/apps/agents-server/src/utils/agentProjects/agentProjectRuntimePaths.ts +25 -0
  57. package/apps/agents-server/src/utils/agentProjects/agentProjectRuntimePm2.ts +4 -3
  58. package/apps/agents-server/src/utils/agentProjects/agentProjectRuntimeRegistry.ts +77 -24
  59. package/apps/agents-server/src/utils/agentProjects/agentProjectStateMutationQueue.ts +58 -0
  60. package/apps/agents-server/src/utils/agentProjects/listAllLocalAgentProjectIdentities.ts +48 -0
  61. package/apps/agents-server/src/utils/agentProjects/resolveAgentProjectRuntimeEnvironmentFlag.ts +23 -0
  62. package/apps/agents-server/src/utils/agentProjects/resolveAgentProjectRuntimeStatus.ts +73 -0
  63. package/apps/agents-server/src/utils/agentProjects/startDefaultAgentProjectRuntimes.ts +110 -0
  64. package/apps/agents-server/src/utils/agentReferenceResolver/MissingCoreAgentRecovery.ts +19 -0
  65. package/apps/agents-server/src/utils/agentReferenceResolver/bookScopedAgentReferences.ts +7 -0
  66. package/apps/agents-server/src/utils/agentReferenceResolver/createAgentInheritanceDiagnostics.ts +457 -0
  67. package/apps/agents-server/src/utils/agentReferenceResolver/createUnresolvedAgentReferenceDiagnostics.ts +27 -0
  68. package/apps/agents-server/src/utils/agentReferenceResolver/resolveCoreAgentAwareMissingReferences.ts +156 -0
  69. package/apps/agents-server/src/utils/chatMessageChips/createAnsweredMessageChipToolCalls.ts +15 -3
  70. package/apps/agents-server/src/utils/chatMessageChips/createPlannedMessageChipToolCalls.ts +8 -3
  71. package/apps/agents-server/src/utils/chatMessageChips/createTouchedExternalSourceChipToolCalls.ts +39 -0
  72. package/apps/agents-server/src/utils/chatMessageChips/createTouchedProjectChipResult.ts +45 -0
  73. package/apps/agents-server/src/utils/chatMessageChips/createTouchedProjectChipToolCalls.ts +58 -24
  74. package/apps/agents-server/src/utils/cronExpression/CronExpression.ts +63 -0
  75. package/apps/agents-server/src/utils/cronExpression/normalizeCronExpression.ts +34 -0
  76. package/apps/agents-server/src/utils/cronExpression/normalizeCronExpressionWhitespace.ts +11 -0
  77. package/apps/agents-server/src/utils/cronExpression/parseCronExpression.ts +41 -0
  78. package/apps/agents-server/src/utils/cronExpression/parseCronExpressionField.ts +140 -0
  79. package/apps/agents-server/src/utils/cronExpression/resolveNextCronRun.ts +100 -0
  80. package/apps/agents-server/src/utils/cronExpression/throwInvalidCronExpressionField.ts +20 -0
  81. package/apps/agents-server/src/utils/cronExpression.ts +10 -0
  82. package/apps/agents-server/src/utils/explicitFromCommitment.ts +130 -0
  83. package/apps/agents-server/src/utils/getAdminChatTasksResponse/getAdminChatTasks/loadAdminChatTaskFallbackData.ts +3 -77
  84. package/apps/agents-server/src/utils/localChatRunner/applyLocalAgentPlannedMessageCommands.ts +53 -4
  85. package/apps/agents-server/src/utils/localChatRunner/prepareLocalAgentPlannedMessagesSidecar.ts +15 -7
  86. package/apps/agents-server/src/utils/localChatRunner/processLocalUserChatJob.ts +8 -0
  87. package/apps/agents-server/src/utils/manGoOnboarding/manGoOnboardingAgentBooks.ts +5 -11
  88. package/apps/agents-server/src/utils/manGoOnboarding/manGoOnboardingAgentRuntime.ts +2 -2
  89. package/apps/agents-server/src/utils/managementApi/managementApiSchemas.ts +2 -2
  90. package/apps/agents-server/src/utils/plannedMessageManager/cancelManagedPlannedMessage.ts +35 -0
  91. package/apps/agents-server/src/utils/plannedMessageManager/collectPlannedMessageAgentOptions.ts +56 -0
  92. package/apps/agents-server/src/utils/plannedMessageManager/createPlannedMessageManagerCounters.ts +104 -0
  93. package/apps/agents-server/src/utils/plannedMessageManager/filterPlannedMessages.ts +191 -0
  94. package/apps/agents-server/src/utils/plannedMessageManager/getPlannedMessageManagerResponse.ts +55 -0
  95. package/apps/agents-server/src/utils/plannedMessageManager/isPlannedMessageStillPlanned.ts +18 -0
  96. package/apps/agents-server/src/utils/plannedMessageManager/loadPlannedMessageManagerRecord.ts +32 -0
  97. package/apps/agents-server/src/utils/plannedMessageManager/mapPlannedMessageManagerRecord.ts +73 -0
  98. package/apps/agents-server/src/utils/plannedMessageManager/parsePlannedMessageManagerUpdateRequest.ts +76 -0
  99. package/apps/agents-server/src/utils/plannedMessageManager/resolvePlannedMessageEndReason.ts +59 -0
  100. package/apps/agents-server/src/utils/plannedMessageManager/resolvePlannedMessageLifecycle.ts +99 -0
  101. package/apps/agents-server/src/utils/plannedMessageManager/resolvePlannedMessageRecurrenceKind.ts +40 -0
  102. package/apps/agents-server/src/utils/plannedMessageManager/updateManagedPlannedMessage.ts +121 -0
  103. package/apps/agents-server/src/utils/plannedMessagesAdmin.ts +200 -0
  104. package/apps/agents-server/src/utils/resolveInheritedAgentSource.ts +114 -95
  105. package/apps/agents-server/src/utils/userChatClient.ts +4 -0
  106. package/apps/agents-server/src/utils/userChatTimeout/UserChatTimeoutRecord.ts +37 -1
  107. package/apps/agents-server/src/utils/userChatTimeout/agentScopedTimeoutBulkActions.ts +11 -17
  108. package/apps/agents-server/src/utils/userChatTimeout/createTimeoutWakeUpMessage.ts +37 -13
  109. package/apps/agents-server/src/utils/userChatTimeout/plannedMessageSchedule/PlannedMessageSchedule.ts +52 -0
  110. package/apps/agents-server/src/utils/userChatTimeout/plannedMessageSchedule/hasPlannedMessageRecurrence.ts +13 -0
  111. package/apps/agents-server/src/utils/userChatTimeout/plannedMessageSchedule/isPlannedMessageScheduleFinished.ts +30 -0
  112. package/apps/agents-server/src/utils/userChatTimeout/plannedMessageSchedule/normalizePlannedMessageScheduleValues.ts +62 -0
  113. package/apps/agents-server/src/utils/userChatTimeout/plannedMessageSchedule/parsePlannedMessageSchedule.ts +202 -0
  114. package/apps/agents-server/src/utils/userChatTimeout/plannedMessageSchedule/resolvePlannedMessageDueAt.ts +121 -0
  115. package/apps/agents-server/src/utils/userChatTimeout/plannedMessageSchedule.ts +12 -0
  116. package/apps/agents-server/src/utils/userChatTimeout/setAgentScopedUserChatTimeoutPausedState.ts +66 -0
  117. package/apps/agents-server/src/utils/userChatTimeout/userChatTimeoutStore/createUserChatTimeout.ts +76 -5
  118. package/apps/agents-server/src/utils/userChatTimeout/userChatTimeoutStore/listAllUserChatTimeouts.ts +37 -0
  119. package/apps/agents-server/src/utils/userChatTimeout/userChatTimeoutStore/mapUserChatTimeoutRow.ts +9 -0
  120. package/apps/agents-server/src/utils/userChatTimeout/userChatTimeoutStore/repeatFiredUserChatTimeout.ts +19 -9
  121. package/apps/agents-server/src/utils/userChatTimeout/userChatTimeoutStore/updateAgentScopedUserChatTimeout.ts +39 -6
  122. package/apps/agents-server/src/utils/userChatTimeout/userChatTimeoutStore.ts +1 -0
  123. package/apps/agents-server/src/utils/userChatTimeout/userChatTimeoutWorker.ts +110 -11
  124. package/apps/agents-server/src/utils/userChatTimeout.ts +16 -0
  125. package/apps/agents-server/src/utils/vpsSelfUpdate/vpsSelfUpdateCron.ts +23 -316
  126. package/apps/agents-server/tests/e2e/support/AgentManagementApi.ts +3 -3
  127. package/esm/index.es.js +951 -102
  128. package/esm/index.es.js.map +1 -1
  129. package/esm/scripts/run-agent-messages/git/commitAgentProjectChanges.d.ts +15 -0
  130. package/esm/scripts/run-agent-messages/git/commitAnsweredMessageProjectChanges.d.ts +24 -0
  131. package/esm/scripts/run-agent-messages/git/ensureAgentProjectGitRepository.d.ts +20 -0
  132. package/esm/scripts/run-agent-messages/git/readAgentProjectCommitChange.d.ts +11 -0
  133. package/esm/scripts/run-agent-messages/git/runAgentProjectGitCommand.d.ts +29 -0
  134. package/esm/scripts/run-agent-messages/messages/buildAgentGoalChatPromptSection.d.ts +3 -3
  135. package/esm/scripts/run-agent-messages/messages/listAgentProjectDirectoryNames.d.ts +7 -0
  136. package/esm/scripts/run-agent-messages/messages/resolveAnsweredMessageTouches.d.ts +29 -0
  137. package/esm/scripts/run-codex-prompts/ping/pingCoderHarnessPeriodically.d.ts +22 -0
  138. package/esm/src/book-3.0/AgentMessageRunReport.d.ts +18 -0
  139. package/esm/src/book-3.0/AgentPlannedMessagesSidecar.d.ts +38 -5
  140. package/esm/src/book-3.0/describeAgentPlannedMessageSchedule.d.ts +31 -0
  141. package/esm/src/book-components/BookEditor/createDeprecatedCommitmentDiagnostics.browser.d.ts +1 -9
  142. package/esm/src/book-components/BookEditor/createDuplicateFromCommitmentDiagnostics.d.ts +28 -0
  143. package/esm/src/book-components/BookEditor/createDuplicateFromCommitmentDiagnostics.test.d.ts +1 -0
  144. package/esm/src/book-components/Chat/Chat/renderAgentProjectDiff.d.ts +13 -0
  145. package/esm/src/book-components/Chat/Chat/renderAgentProjectToolCallDetails.d.ts +16 -0
  146. package/esm/src/book-components/Chat/utils/agentProjectToolCall.d.ts +39 -0
  147. package/esm/src/book-components/Chat/utils/agentProjectToolCall.test.d.ts +1 -0
  148. package/esm/src/book-components/Chat/utils/externalSourceToolCall.d.ts +38 -0
  149. package/esm/src/book-components/Chat/utils/timeoutToolCallPresentation.d.ts +6 -0
  150. package/esm/src/cli/cli-commands/coder/waitOptions.d.ts +12 -0
  151. package/esm/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabase.d.ts +15 -0
  152. package/esm/src/utils/agent-message-runtime/AgentMessageProjectChange.d.ts +76 -0
  153. package/esm/src/utils/agent-message-runtime/AgentMessageTouchedExternalSource.d.ts +45 -0
  154. package/esm/src/utils/agent-message-runtime/parseAgentMessageRuntimeLogEvents.d.ts +3 -0
  155. package/esm/src/utils/agent-message-runtime/resolveAgentMessageTouchedExternalSources.d.ts +18 -0
  156. package/esm/src/utils/agent-message-runtime/resolveAgentMessageTouchedExternalSources.test.d.ts +1 -0
  157. package/esm/src/utils/random/$generateBookBoilerplate.test.d.ts +1 -0
  158. package/esm/src/version.d.ts +1 -1
  159. package/package.json +1 -1
  160. package/src/book-2.0/agent-source/string_book.ts +1 -1
  161. package/src/book-2.0/book-language-documentation/czechBookLanguageManualDictionary.ts +6 -1
  162. package/src/book-2.0/book-language-documentation/englishBookLanguageManualDictionary.ts +6 -1
  163. package/src/book-3.0/AgentMessageRunReport.ts +59 -0
  164. package/src/book-3.0/AgentPlannedMessagesSidecar.ts +64 -9
  165. package/src/book-3.0/describeAgentPlannedMessageSchedule.ts +94 -0
  166. package/src/book-components/BookEditor/BookEditorMonaco.tsx +2 -0
  167. package/src/book-components/BookEditor/createDeprecatedCommitmentDiagnostics.browser.ts +3 -11
  168. package/src/book-components/BookEditor/createDuplicateFromCommitmentDiagnostics.ts +71 -0
  169. package/src/book-components/Chat/Chat/Chat.module.css +165 -18
  170. package/src/book-components/Chat/Chat/ChatMessageMap.tsx +0 -1
  171. package/src/book-components/Chat/Chat/renderAgentProjectDiff.tsx +85 -0
  172. package/src/book-components/Chat/Chat/renderAgentProjectToolCallDetails.tsx +206 -0
  173. package/src/book-components/Chat/Chat/renderToolCallDetails.tsx +8 -0
  174. package/src/book-components/Chat/MarkdownContent/MarkdownContent.tsx +2 -3
  175. package/src/book-components/Chat/utils/agentProjectToolCall.ts +82 -5
  176. package/src/book-components/Chat/utils/externalSourceToolCall.ts +65 -0
  177. package/src/book-components/Chat/utils/getToolCallChipletInfo.ts +36 -0
  178. package/src/book-components/Chat/utils/renderMarkdown.ts +3 -10
  179. package/src/book-components/Chat/utils/timeoutToolCallPresentation.ts +12 -1
  180. package/src/cli/cli-commands/coder/ping.ts +35 -9
  181. package/src/cli/cli-commands/coder/waitOptions.ts +33 -0
  182. package/src/cli/cli-commands/common/harness/$applyHarnessInstallationStatus.ts +3 -1
  183. package/src/cli/cli-commands/common/harness/$checkHarnessInstallation.ts +3 -1
  184. package/src/cli/cli-commands/common/harnessUpdateCliOptions.ts +1 -4
  185. package/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabase.ts +47 -3
  186. package/src/commands/FORMAT/formatCommandParser.ts +4 -2
  187. package/src/commitments/FROM/FROM.ts +13 -0
  188. package/src/other/templates/getTemplatesPipelineCollection.ts +819 -751
  189. package/src/utils/agent-message-runtime/AgentMessageProjectChange.ts +183 -0
  190. package/src/utils/agent-message-runtime/AgentMessageTouchedExternalSource.ts +80 -0
  191. package/src/utils/agent-message-runtime/parseAgentMessageRuntimeLogEvents.ts +3 -0
  192. package/src/utils/agent-message-runtime/resolveAgentMessageRuntimeActivity.ts +2 -4
  193. package/src/utils/agent-message-runtime/resolveAgentMessageTouchedExternalSources.ts +341 -0
  194. package/src/utils/random/$generateBookBoilerplate.ts +1 -1
  195. package/src/version.ts +2 -2
  196. package/src/versions.txt +5 -0
  197. package/umd/index.umd.js +950 -101
  198. package/umd/index.umd.js.map +1 -1
  199. package/umd/scripts/run-agent-messages/git/commitAgentProjectChanges.d.ts +15 -0
  200. package/umd/scripts/run-agent-messages/git/commitAnsweredMessageProjectChanges.d.ts +24 -0
  201. package/umd/scripts/run-agent-messages/git/ensureAgentProjectGitRepository.d.ts +20 -0
  202. package/umd/scripts/run-agent-messages/git/readAgentProjectCommitChange.d.ts +11 -0
  203. package/umd/scripts/run-agent-messages/git/runAgentProjectGitCommand.d.ts +29 -0
  204. package/umd/scripts/run-agent-messages/messages/buildAgentGoalChatPromptSection.d.ts +3 -3
  205. package/umd/scripts/run-agent-messages/messages/listAgentProjectDirectoryNames.d.ts +7 -0
  206. package/umd/scripts/run-agent-messages/messages/resolveAnsweredMessageTouches.d.ts +29 -0
  207. package/umd/scripts/run-codex-prompts/ping/pingCoderHarnessPeriodically.d.ts +22 -0
  208. package/umd/src/book-3.0/AgentMessageRunReport.d.ts +18 -0
  209. package/umd/src/book-3.0/AgentPlannedMessagesSidecar.d.ts +38 -5
  210. package/umd/src/book-3.0/describeAgentPlannedMessageSchedule.d.ts +31 -0
  211. package/umd/src/book-components/BookEditor/createDeprecatedCommitmentDiagnostics.browser.d.ts +1 -9
  212. package/umd/src/book-components/BookEditor/createDuplicateFromCommitmentDiagnostics.d.ts +28 -0
  213. package/umd/src/book-components/BookEditor/createDuplicateFromCommitmentDiagnostics.test.d.ts +1 -0
  214. package/umd/src/book-components/Chat/Chat/renderAgentProjectDiff.d.ts +13 -0
  215. package/umd/src/book-components/Chat/Chat/renderAgentProjectToolCallDetails.d.ts +16 -0
  216. package/umd/src/book-components/Chat/utils/agentProjectToolCall.d.ts +39 -0
  217. package/umd/src/book-components/Chat/utils/agentProjectToolCall.test.d.ts +1 -0
  218. package/umd/src/book-components/Chat/utils/externalSourceToolCall.d.ts +38 -0
  219. package/umd/src/book-components/Chat/utils/timeoutToolCallPresentation.d.ts +6 -0
  220. package/umd/src/cli/cli-commands/coder/waitOptions.d.ts +12 -0
  221. package/umd/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabase.d.ts +15 -0
  222. package/umd/src/utils/agent-message-runtime/AgentMessageProjectChange.d.ts +76 -0
  223. package/umd/src/utils/agent-message-runtime/AgentMessageTouchedExternalSource.d.ts +45 -0
  224. package/umd/src/utils/agent-message-runtime/parseAgentMessageRuntimeLogEvents.d.ts +3 -0
  225. package/umd/src/utils/agent-message-runtime/resolveAgentMessageTouchedExternalSources.d.ts +18 -0
  226. package/umd/src/utils/agent-message-runtime/resolveAgentMessageTouchedExternalSources.test.d.ts +1 -0
  227. package/umd/src/utils/random/$generateBookBoilerplate.test.d.ts +1 -0
  228. package/umd/src/version.d.ts +1 -1
  229. package/apps/agents-server/src/app/admin/task-manager/TaskManagerScopeTabs.tsx +0 -74
  230. package/esm/scripts/run-agent-messages/messages/resolveTouchedAgentProjects.d.ts +0 -15
  231. package/umd/scripts/run-agent-messages/messages/resolveTouchedAgentProjects.d.ts +0 -15
@@ -13,6 +13,7 @@ import type {
13
13
  AgentProjectRuntimeMode,
14
14
  AgentProjectRuntimeStatus,
15
15
  } from './AgentProjectRuntimeInfo';
16
+ import { isSameAgentProjectIdentity } from './agentProjectIdentity';
16
17
  import {
17
18
  AGENT_PROJECT_RUNTIME_DEFAULT_DEV_COMMAND,
18
19
  AGENT_PROJECT_RUNTIME_HOST,
@@ -21,6 +22,7 @@ import {
21
22
  AGENT_PROJECT_RUNTIME_STOP_POLL_INTERVAL_MS,
22
23
  AGENT_PROJECT_RUNTIME_STOP_TIMEOUT_MS,
23
24
  } from './agentProjectRuntimeConstants';
25
+ import { setAgentProjectRuntimeDesiredState } from './agentProjectRuntimeDesiredState';
24
26
  import {
25
27
  assignAgentProjectDomain,
26
28
  resolveAgentProjectDomainRecord,
@@ -207,6 +209,9 @@ export async function assignAgentProjectPort(
207
209
  /**
208
210
  * Starts one project using its npm `dev` script when available, otherwise a static file server.
209
211
  *
212
+ * Starting a project also makes it expected to be running, so a project which was stopped earlier
213
+ * is started again by itself after the next server restart.
214
+ *
210
215
  * @param options - Agent and project identification.
211
216
  * @returns Runtime info for the started project.
212
217
  */
@@ -216,6 +221,15 @@ export async function startAgentProjectRuntime(
216
221
  await hydrateAgentProjectRuntimeRegistryState();
217
222
 
218
223
  const project = await resolveExistingAgentProject(options);
224
+
225
+ // Note: The intent is remembered before the project is started so that a project which fails to
226
+ // start now is still tried again by the next automatic pass.
227
+ await setAgentProjectRuntimeDesiredState({
228
+ agentPermanentId: options.agentPermanentId,
229
+ projectName: project.projectName,
230
+ desiredState: 'running',
231
+ });
232
+
219
233
  const isDevRuntime = await hasAgentProjectDevScript(project.absolutePath);
220
234
  const preparedStart = await prepareAgentProjectRuntimeStart(options, project);
221
235
 
@@ -375,7 +389,9 @@ export async function listAgentProjectRuntimes(): Promise<ReadonlyArray<AgentPro
375
389
  }
376
390
 
377
391
  /**
378
- * Terminates one runtime by runtime id.
392
+ * Terminates one runtime by runtime id on explicit request.
393
+ *
394
+ * The project is remembered as stopped, so it stays down until it is started again.
379
395
  *
380
396
  * @param runtimeId - Runtime id.
381
397
  * @returns Terminated runtime info or `null` when it no longer exists.
@@ -389,14 +405,19 @@ export async function terminateAgentProjectRuntimeById(runtimeId: string): Promi
389
405
  return null;
390
406
  }
391
407
 
392
- await terminateAgentProjectRuntimeRecord(runtimeRecord);
393
- getAgentProjectRuntimeRegistryState().runtimesById.delete(runtimeId);
394
- await persistAgentProjectRuntimeRegistryState();
395
- return toAgentProjectRuntimeInfo(runtimeRecord);
408
+ await setAgentProjectRuntimeDesiredState({
409
+ agentPermanentId: runtimeRecord.agentPermanentId,
410
+ projectName: runtimeRecord.projectName,
411
+ desiredState: 'stopped',
412
+ });
413
+
414
+ return await removeAgentProjectRuntimeById(runtimeId);
396
415
  }
397
416
 
398
417
  /**
399
- * Terminates any runtime assigned to one project.
418
+ * Terminates any runtime assigned to one project on explicit request.
419
+ *
420
+ * The project is remembered as stopped, so it stays down until it is started again.
400
421
  *
401
422
  * @param options - Agent and project identification.
402
423
  * @returns Terminated runtime info or `null` when no runtime exists.
@@ -405,30 +426,64 @@ export async function terminateAgentProjectRuntimeForProject(
405
426
  options: AgentProjectRuntimeProjectOptions,
406
427
  ): Promise<AgentProjectRuntimeInfo | null> {
407
428
  await hydrateAgentProjectRuntimeRegistryState();
429
+ await setAgentProjectRuntimeDesiredState({
430
+ agentPermanentId: options.agentPermanentId,
431
+ projectName: options.projectName,
432
+ desiredState: 'stopped',
433
+ });
408
434
 
409
- const runtimeRecord = findAgentProjectRuntimeRecord(options.agentPermanentId, options.projectName);
435
+ return await removeAgentProjectRuntimeForProject(options);
436
+ }
437
+
438
+ /**
439
+ * Terminates all project runtimes in the current process.
440
+ *
441
+ * This is used by tests and process-level cleanup, so it says nothing about which projects should
442
+ * be running — every project keeps the state it is expected to be in.
443
+ */
444
+ export async function terminateAllAgentProjectRuntimes(): Promise<void> {
445
+ await hydrateAgentProjectRuntimeRegistryState();
446
+
447
+ const runtimeIds = [...getAgentProjectRuntimeRegistryState().runtimesById.keys()];
448
+
449
+ await Promise.all(runtimeIds.map((runtimeId) => removeAgentProjectRuntimeById(runtimeId)));
450
+ }
451
+
452
+ /**
453
+ * Terminates one runtime by runtime id without changing which state the project is expected to be in.
454
+ *
455
+ * @param runtimeId - Runtime id.
456
+ * @returns Terminated runtime info or `null` when it no longer exists.
457
+ */
458
+ async function removeAgentProjectRuntimeById(runtimeId: string): Promise<AgentProjectRuntimeInfo | null> {
459
+ const runtimeRecord = getAgentProjectRuntimeRegistryState().runtimesById.get(runtimeId);
410
460
 
411
461
  if (!runtimeRecord) {
412
462
  return null;
413
463
  }
414
464
 
415
465
  await terminateAgentProjectRuntimeRecord(runtimeRecord);
416
- getAgentProjectRuntimeRegistryState().runtimesById.delete(runtimeRecord.id);
466
+ getAgentProjectRuntimeRegistryState().runtimesById.delete(runtimeId);
417
467
  await persistAgentProjectRuntimeRegistryState();
418
468
  return toAgentProjectRuntimeInfo(runtimeRecord);
419
469
  }
420
470
 
421
471
  /**
422
- * Terminates all project runtimes in the current process.
472
+ * Terminates the runtime of one project without changing which state the project is expected to be in.
423
473
  *
424
- * This is used by tests and process-level cleanup.
474
+ * @param options - Agent and project identification.
475
+ * @returns Terminated runtime info or `null` when no runtime exists.
425
476
  */
426
- export async function terminateAllAgentProjectRuntimes(): Promise<void> {
427
- await hydrateAgentProjectRuntimeRegistryState();
477
+ async function removeAgentProjectRuntimeForProject(
478
+ options: AgentProjectRuntimeProjectOptions,
479
+ ): Promise<AgentProjectRuntimeInfo | null> {
480
+ const runtimeRecord = findAgentProjectRuntimeRecord(options.agentPermanentId, options.projectName);
428
481
 
429
- const runtimeIds = [...getAgentProjectRuntimeRegistryState().runtimesById.keys()];
482
+ if (!runtimeRecord) {
483
+ return null;
484
+ }
430
485
 
431
- await Promise.all(runtimeIds.map((runtimeId) => terminateAgentProjectRuntimeById(runtimeId)));
486
+ return await removeAgentProjectRuntimeById(runtimeRecord.id);
432
487
  }
433
488
 
434
489
  /**
@@ -438,7 +493,7 @@ async function prepareAgentProjectRuntimeStart(
438
493
  options: AgentProjectRuntimeProjectOptions,
439
494
  project: NonNullable<Awaited<ReturnType<typeof resolveAgentProjectInfo>>>,
440
495
  ): Promise<PreparedAgentProjectRuntimeStart> {
441
- await terminateAgentProjectRuntimeForProject({
496
+ await removeAgentProjectRuntimeForProject({
442
497
  agentPermanentId: options.agentPermanentId,
443
498
  projectName: project.projectName,
444
499
  });
@@ -595,12 +650,16 @@ function startChildProcessAgentProjectDevRuntime(runtimeRecord: MutableAgentProj
595
650
  }
596
651
 
597
652
  /**
598
- * Applies installer-managed nginx and SSL configuration when a public domain exists.
653
+ * Applies installer-managed nginx and SSL configuration when a project domain was added or changed.
654
+ *
655
+ * The generated nginx configuration resolves the runtime port of a project per request, so it only
656
+ * has to be regenerated when the set of project domains itself changes — never when an unchanged
657
+ * project is merely started again on a new port.
599
658
  */
600
659
  async function applyAgentProjectRuntimePublicConfiguration(
601
660
  domainAssignment: AgentProjectDomainAssignment,
602
661
  ): Promise<void> {
603
- if (!domainAssignment.record) {
662
+ if (!domainAssignment.record || !domainAssignment.isChanged) {
604
663
  return;
605
664
  }
606
665
 
@@ -642,14 +701,8 @@ function findAgentProjectRuntimeRecord(
642
701
  agentPermanentId: string,
643
702
  projectName: string,
644
703
  ): MutableAgentProjectRuntimeRecord | null {
645
- const normalizedAgentPermanentId = agentPermanentId.toLowerCase();
646
- const normalizedProjectName = projectName.toLowerCase();
647
-
648
704
  for (const runtimeRecord of getAgentProjectRuntimeRegistryState().runtimesById.values()) {
649
- if (
650
- runtimeRecord.agentPermanentId.toLowerCase() === normalizedAgentPermanentId &&
651
- runtimeRecord.projectName.toLowerCase() === normalizedProjectName
652
- ) {
705
+ if (isSameAgentProjectIdentity(runtimeRecord, { agentPermanentId, projectName })) {
653
706
  return runtimeRecord;
654
707
  }
655
708
  }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Global key used to keep one mutation queue per agent-project state file across module reloads.
3
+ */
4
+ const AGENT_PROJECT_STATE_MUTATION_QUEUES_GLOBAL_KEY = '__PROMPTBOOK_AGENT_PROJECT_STATE_MUTATION_QUEUES__';
5
+
6
+ /**
7
+ * Global object shape used for process-wide state-file mutation queues.
8
+ */
9
+ type AgentProjectStateMutationQueuesGlobal = typeof globalThis & {
10
+ [AGENT_PROJECT_STATE_MUTATION_QUEUES_GLOBAL_KEY]?: Map<string, Promise<void>>;
11
+ };
12
+
13
+ /**
14
+ * Runs one agent-project state mutation after all previously queued mutations of the same state file finished.
15
+ *
16
+ * The project state files are read-modify-write JSON documents, so two concurrent mutations would
17
+ * silently drop one of the two changes. Every mutation of one file goes through its own queue, while
18
+ * mutations of unrelated files still run in parallel.
19
+ *
20
+ * @param queueName - Stable name of the mutated state file.
21
+ * @param operation - Mutation to run exclusively for that state file.
22
+ * @returns Whatever the mutation returns.
23
+ */
24
+ export async function runAgentProjectStateMutation<TValue>(
25
+ queueName: string,
26
+ operation: () => Promise<TValue>,
27
+ ): Promise<TValue> {
28
+ const mutationQueues = getAgentProjectStateMutationQueues();
29
+ const previousMutation = mutationQueues.get(queueName) ?? Promise.resolve();
30
+ let releaseMutation!: () => void;
31
+
32
+ mutationQueues.set(
33
+ queueName,
34
+ new Promise<void>((resolve) => {
35
+ releaseMutation = resolve;
36
+ }),
37
+ );
38
+
39
+ await previousMutation.catch(() => undefined);
40
+
41
+ try {
42
+ return await operation();
43
+ } finally {
44
+ releaseMutation();
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Returns the process-wide mutation queues of all agent-project state files.
50
+ *
51
+ * @returns Mutable map of pending mutations keyed by state file name.
52
+ */
53
+ function getAgentProjectStateMutationQueues(): Map<string, Promise<void>> {
54
+ const mutationQueuesGlobal = globalThis as AgentProjectStateMutationQueuesGlobal;
55
+ mutationQueuesGlobal[AGENT_PROJECT_STATE_MUTATION_QUEUES_GLOBAL_KEY] ??= new Map();
56
+
57
+ return mutationQueuesGlobal[AGENT_PROJECT_STATE_MUTATION_QUEUES_GLOBAL_KEY]!;
58
+ }
@@ -0,0 +1,48 @@
1
+ import { readdir } from 'fs/promises';
2
+ import { resolveLocalAgentRootPath } from '../localChatRunner/ensureLocalAgentFolder';
3
+ import type { AgentProjectIdentity } from './agentProjectIdentity';
4
+ import { parseAgentPermanentIdFromDirectoryName } from './agentProjectsPaths';
5
+ import { isMissingPathError } from './isMissingPathError';
6
+ import { listAgentProjectNames } from './listAgentProjectNames';
7
+
8
+ /**
9
+ * Lists every project folder present on this machine, across all agents of all servers.
10
+ *
11
+ * Unlike `listAllAgentProjectSummaries` this never asks a database which agents exist and never
12
+ * measures a project tree — it only reads the two directory levels needed to name a project. That
13
+ * makes it usable before the first request is served, when no server database is selected yet.
14
+ *
15
+ * @returns Identities of all local agent projects ordered by agent and project name.
16
+ */
17
+ export async function listAllLocalAgentProjectIdentities(): Promise<ReadonlyArray<AgentProjectIdentity>> {
18
+ const localAgentRootPath = resolveLocalAgentRootPath();
19
+ let localAgentRootEntries;
20
+
21
+ try {
22
+ localAgentRootEntries = await readdir(localAgentRootPath, { withFileTypes: true });
23
+ } catch (error) {
24
+ if (isMissingPathError(error)) {
25
+ return [];
26
+ }
27
+
28
+ throw error;
29
+ }
30
+
31
+ const agentPermanentIds = localAgentRootEntries
32
+ .filter((localAgentRootEntry) => localAgentRootEntry.isDirectory())
33
+ .map((agentDirectoryEntry) => parseAgentPermanentIdFromDirectoryName(agentDirectoryEntry.name))
34
+ .filter((agentPermanentId): agentPermanentId is string => agentPermanentId !== null)
35
+ .sort((firstAgentPermanentId, secondAgentPermanentId) =>
36
+ firstAgentPermanentId.localeCompare(secondAgentPermanentId),
37
+ );
38
+
39
+ const identitiesPerAgent = await Promise.all(
40
+ agentPermanentIds.map(async (agentPermanentId): Promise<ReadonlyArray<AgentProjectIdentity>> => {
41
+ const projectNames = await listAgentProjectNames(agentPermanentId);
42
+
43
+ return projectNames.map((projectName) => ({ agentPermanentId, projectName }));
44
+ }),
45
+ );
46
+
47
+ return identitiesPerAgent.flat();
48
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Values accepted as an enabled on/off environment flag.
3
+ */
4
+ const ENABLED_ENVIRONMENT_FLAG_VALUES = ['1', 'true', 'yes', 'y'];
5
+
6
+ /**
7
+ * Reads one optional on/off environment flag used by the agent project runtime managers.
8
+ *
9
+ * An unset (or empty) variable is reported as `null` instead of `false`, so every caller keeps
10
+ * ownership of its own default while the accepted spellings of "enabled" stay defined in one place.
11
+ *
12
+ * @param environmentVariableName - Name of the environment variable to read.
13
+ * @returns `true` or `false` when the variable is set, `null` when it is not.
14
+ */
15
+ export function resolveAgentProjectRuntimeEnvironmentFlag(environmentVariableName: string): boolean | null {
16
+ const configuredValue = process.env[environmentVariableName]?.trim().toLowerCase();
17
+
18
+ if (!configuredValue) {
19
+ return null;
20
+ }
21
+
22
+ return ENABLED_ENVIRONMENT_FLAG_VALUES.includes(configuredValue);
23
+ }
@@ -0,0 +1,73 @@
1
+ import { formatAgentProjectRuntimeStatus } from './agentProjectRuntimeDisplay';
2
+ import { resolveAgentProjectRuntime } from './agentProjectRuntimeRegistry';
3
+ import { resolveAgentProjectPublicUrls } from './resolveAgentProjectPublicUrls';
4
+
5
+ /**
6
+ * Current runtime state of one project as shown on its project page.
7
+ */
8
+ export type AgentProjectRuntimeStatusInfo = {
9
+ /**
10
+ * Whether the project currently accepts requests on its assigned runtime port.
11
+ */
12
+ readonly isRunning: boolean;
13
+
14
+ /**
15
+ * Human-readable status label, the same one the project page shows.
16
+ */
17
+ readonly statusLabel: string;
18
+
19
+ /**
20
+ * Stable public project URL, or `null` when the project has no assigned domain or runtime.
21
+ *
22
+ * The URL stays the same while the project is stopped, so a link to it keeps working once the
23
+ * project is started again.
24
+ */
25
+ readonly projectUrl: string | null;
26
+ };
27
+
28
+ /**
29
+ * Resolves the runtime state of one single project.
30
+ *
31
+ * This is the one-project counterpart of `listAgentProjectChatReferences`, for surfaces which
32
+ * already know which project they show and must not pay for listing every project of the agent.
33
+ *
34
+ * @param agentPermanentId - Permanent id of the agent owning the project.
35
+ * @param projectName - Project directory name.
36
+ * @returns Runtime state of the project.
37
+ */
38
+ export async function resolveAgentProjectRuntimeStatus(
39
+ agentPermanentId: string,
40
+ projectName: string,
41
+ ): Promise<AgentProjectRuntimeStatusInfo> {
42
+ const runtime = await resolveAgentProjectRuntime(agentPermanentId, projectName);
43
+
44
+ return {
45
+ isRunning: runtime?.isRunning ?? false,
46
+ statusLabel: formatAgentProjectRuntimeStatus(runtime),
47
+ projectUrl: runtime?.publicUrl ?? (await resolveAssignedAgentProjectPublicUrl(agentPermanentId, projectName)),
48
+ };
49
+ }
50
+
51
+ /**
52
+ * Resolves the domain assigned to one project which currently has no runtime.
53
+ *
54
+ * The assignment is scoped by the domain the current server is reached under, which is known from
55
+ * the request headers only. A caller outside a request — such as the local chat runner finishing a
56
+ * message — therefore learns no URL instead of failing, and the project page link still works.
57
+ *
58
+ * @param agentPermanentId - Permanent id of the agent owning the project.
59
+ * @param projectName - Project directory name.
60
+ * @returns Assigned public project URL, or `null` when there is none to resolve.
61
+ *
62
+ * @private helper of `resolveAgentProjectRuntimeStatus`
63
+ */
64
+ async function resolveAssignedAgentProjectPublicUrl(
65
+ agentPermanentId: string,
66
+ projectName: string,
67
+ ): Promise<string | null> {
68
+ try {
69
+ return (await resolveAgentProjectPublicUrls(agentPermanentId)).get(projectName.toLowerCase()) ?? null;
70
+ } catch {
71
+ return null;
72
+ }
73
+ }
@@ -0,0 +1,110 @@
1
+ import { createAgentProjectIdentityKey, type AgentProjectIdentity } from './agentProjectIdentity';
2
+ import {
3
+ listAgentProjectRuntimeDesiredStates,
4
+ resolveAgentProjectRuntimeDesiredStateFromRecords,
5
+ } from './agentProjectRuntimeDesiredState';
6
+ import { listAgentProjectDomainRecords } from './agentProjectRuntimeDomains';
7
+ import { resolveAgentProjectRuntime, startAgentProjectRuntime } from './agentProjectRuntimeRegistry';
8
+ import { listAllLocalAgentProjectIdentities } from './listAllLocalAgentProjectIdentities';
9
+
10
+ /**
11
+ * Outcome of one pass which brings all projects into their desired state.
12
+ */
13
+ export type StartDefaultAgentProjectRuntimesReport = {
14
+ /**
15
+ * Number of projects started by this pass.
16
+ */
17
+ readonly startedProjectCount: number;
18
+
19
+ /**
20
+ * Number of projects which were already running or still coming up.
21
+ */
22
+ readonly runningProjectCount: number;
23
+
24
+ /**
25
+ * Number of projects left alone because they were explicitly stopped.
26
+ */
27
+ readonly stoppedProjectCount: number;
28
+
29
+ /**
30
+ * Number of projects which could not be started.
31
+ */
32
+ readonly failedProjectCount: number;
33
+ };
34
+
35
+ /**
36
+ * Starts every local project which is expected to be running but is not.
37
+ *
38
+ * This is what makes "running" the default state of a project: a project nobody explicitly stopped
39
+ * is started again after the server was restarted, after it crashed, and shortly after it was
40
+ * created. A project which somebody stopped stays stopped until it is started again.
41
+ *
42
+ * Projects are started one after another and one failing project never stops the pass, so a project
43
+ * with a broken dev command cannot keep every other project of the server down.
44
+ *
45
+ * @returns Summary of what the pass did.
46
+ */
47
+ export async function startDefaultAgentProjectRuntimes(): Promise<StartDefaultAgentProjectRuntimesReport> {
48
+ const [projectIdentities, desiredStateRecords, projectDomainRecords] = await Promise.all([
49
+ listAllLocalAgentProjectIdentities(),
50
+ listAgentProjectRuntimeDesiredStates(),
51
+ listAgentProjectDomainRecords(),
52
+ ]);
53
+ const serverDomainByProjectKey = new Map(
54
+ projectDomainRecords.map((projectDomainRecord) => [
55
+ createAgentProjectIdentityKey(projectDomainRecord),
56
+ projectDomainRecord.serverDomain,
57
+ ]),
58
+ );
59
+
60
+ let startedProjectCount = 0;
61
+ let runningProjectCount = 0;
62
+ let stoppedProjectCount = 0;
63
+ let failedProjectCount = 0;
64
+
65
+ for (const projectIdentity of projectIdentities) {
66
+ if (resolveAgentProjectRuntimeDesiredStateFromRecords(desiredStateRecords, projectIdentity) === 'stopped') {
67
+ stoppedProjectCount++;
68
+ continue;
69
+ }
70
+
71
+ if (await isAgentProjectRuntimeAlreadyUp(projectIdentity)) {
72
+ runningProjectCount++;
73
+ continue;
74
+ }
75
+
76
+ try {
77
+ await startAgentProjectRuntime({
78
+ agentPermanentId: projectIdentity.agentPermanentId,
79
+ projectName: projectIdentity.projectName,
80
+ // Note: Keeps the project on the domain it was already assigned to, which is the only
81
+ // way to tell servers of one VPS apart outside of a request.
82
+ serverDomain: serverDomainByProjectKey.get(createAgentProjectIdentityKey(projectIdentity)) ?? null,
83
+ });
84
+ startedProjectCount++;
85
+ } catch (error) {
86
+ failedProjectCount++;
87
+ console.error(
88
+ `[agent-project-runtimes] failed to start project \`${projectIdentity.projectName}\` of agent \`${projectIdentity.agentPermanentId}\``,
89
+ error,
90
+ );
91
+ }
92
+ }
93
+
94
+ return { startedProjectCount, runningProjectCount, stoppedProjectCount, failedProjectCount };
95
+ }
96
+
97
+ /**
98
+ * Returns whether one project already serves requests or is still coming up.
99
+ *
100
+ * A project which is still starting is left alone so that a slow dev command is not killed and
101
+ * restarted over and over by consecutive passes.
102
+ *
103
+ * @param projectIdentity - Agent and project identification.
104
+ * @returns `true` when the project must not be started again.
105
+ */
106
+ async function isAgentProjectRuntimeAlreadyUp(projectIdentity: AgentProjectIdentity): Promise<boolean> {
107
+ const runtime = await resolveAgentProjectRuntime(projectIdentity.agentPermanentId, projectIdentity.projectName);
108
+
109
+ return Boolean(runtime && (runtime.isRunning || runtime.status === 'starting'));
110
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Recovery offered for a missing agent reference that points to one of the bundled core agents.
3
+ *
4
+ * A core agent is never created from scratch like an ordinary missing reference — it is reinstated from the book
5
+ * bundled in the repository, together with every other core agent that happens to be missing at the same time.
6
+ *
7
+ * @private utility of Agents Server agent-reference diagnostics
8
+ */
9
+ export type MissingCoreAgentRecovery = {
10
+ /**
11
+ * Titles of every bundled core agent currently missing on this server, including the referenced one.
12
+ */
13
+ readonly missingCoreAgentTitles: ReadonlyArray<string>;
14
+
15
+ /**
16
+ * Whether the current user is allowed to reinstate the missing core agents.
17
+ */
18
+ readonly isReinstateAllowed: boolean;
19
+ };
@@ -2,6 +2,7 @@ import type { AgentReferenceResolver } from '../../../../../src/book-2.0/agent-s
2
2
  import { normalizeAgentName } from '../../../../../src/book-2.0/agent-source/normalizeAgentName';
3
3
  import { parseAgentSourceWithCommitments } from '../../../../../src/book-2.0/agent-source/parseAgentSourceWithCommitments';
4
4
  import { parseAgentSource } from '../../../../../src/book-2.0/agent-source/parseAgentSource';
5
+ import { resolvePseudoAgentKindFromReference } from '../../../../../src/book-2.0/agent-source/pseudoAgentReferences';
5
6
  import type { string_book } from '../../../../../src/book-2.0/agent-source/string_book';
6
7
  import type { AgentCollection } from '../../../../../src/collection/agent-collection/AgentCollection';
7
8
  import type { BookCommitment } from '../../../../../src/commitments/_base/BookCommitment';
@@ -220,6 +221,12 @@ export function createBookScopedAgentReferenceResolver(options: {
220
221
  chunks.push(content.slice(previousIndex, tokenMatch.index));
221
222
  previousIndex = tokenMatch.index + tokenMatch.length;
222
223
 
224
+ // Note: `Null`/`Void` (and other pseudo agents) are reserved language values, never embedded agents.
225
+ if (resolvePseudoAgentKindFromReference(tokenReference)) {
226
+ chunks.push(tokenMatch.token);
227
+ continue;
228
+ }
229
+
223
230
  if (!tokenReference || !embeddedSources.has(normalizedTokenReference)) {
224
231
  chunks.push(tokenMatch.token);
225
232
  continue;