@clinebot/core 0.0.0

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 (200) hide show
  1. package/README.md +88 -0
  2. package/dist/account/cline-account-service.d.ts +34 -0
  3. package/dist/account/index.d.ts +3 -0
  4. package/dist/account/rpc.d.ts +38 -0
  5. package/dist/account/types.d.ts +74 -0
  6. package/dist/agents/agent-config-loader.d.ts +18 -0
  7. package/dist/agents/agent-config-parser.d.ts +25 -0
  8. package/dist/agents/hooks-config-loader.d.ts +23 -0
  9. package/dist/agents/index.d.ts +11 -0
  10. package/dist/agents/plugin-config-loader.d.ts +22 -0
  11. package/dist/agents/plugin-loader.d.ts +9 -0
  12. package/dist/agents/plugin-sandbox.d.ts +12 -0
  13. package/dist/agents/unified-config-file-watcher.d.ts +77 -0
  14. package/dist/agents/user-instruction-config-loader.d.ts +63 -0
  15. package/dist/auth/client.d.ts +11 -0
  16. package/dist/auth/cline.d.ts +41 -0
  17. package/dist/auth/codex.d.ts +39 -0
  18. package/dist/auth/oca.d.ts +22 -0
  19. package/dist/auth/server.d.ts +22 -0
  20. package/dist/auth/types.d.ts +72 -0
  21. package/dist/auth/utils.d.ts +32 -0
  22. package/dist/chat/chat-schema.d.ts +145 -0
  23. package/dist/default-tools/constants.d.ts +23 -0
  24. package/dist/default-tools/definitions.d.ts +96 -0
  25. package/dist/default-tools/executors/apply-patch-parser.d.ts +68 -0
  26. package/dist/default-tools/executors/apply-patch.d.ts +26 -0
  27. package/dist/default-tools/executors/bash.d.ts +49 -0
  28. package/dist/default-tools/executors/editor.d.ts +31 -0
  29. package/dist/default-tools/executors/file-read.d.ts +40 -0
  30. package/dist/default-tools/executors/index.d.ts +44 -0
  31. package/dist/default-tools/executors/search.d.ts +50 -0
  32. package/dist/default-tools/executors/web-fetch.d.ts +58 -0
  33. package/dist/default-tools/index.d.ts +57 -0
  34. package/dist/default-tools/presets.d.ts +124 -0
  35. package/dist/default-tools/schemas.d.ts +121 -0
  36. package/dist/default-tools/types.d.ts +237 -0
  37. package/dist/index.d.ts +23 -0
  38. package/dist/index.js +220 -0
  39. package/dist/input/file-indexer.d.ts +5 -0
  40. package/dist/input/index.d.ts +4 -0
  41. package/dist/input/mention-enricher.d.ts +12 -0
  42. package/dist/mcp/config-loader.d.ts +15 -0
  43. package/dist/mcp/index.d.ts +4 -0
  44. package/dist/mcp/manager.d.ts +24 -0
  45. package/dist/mcp/types.d.ts +66 -0
  46. package/dist/runtime/hook-file-hooks.d.ts +18 -0
  47. package/dist/runtime/rules.d.ts +5 -0
  48. package/dist/runtime/runtime-builder.d.ts +5 -0
  49. package/dist/runtime/sandbox/subprocess-sandbox.d.ts +19 -0
  50. package/dist/runtime/session-runtime.d.ts +36 -0
  51. package/dist/runtime/tool-approval.d.ts +9 -0
  52. package/dist/runtime/workflows.d.ts +13 -0
  53. package/dist/server/index.d.ts +47 -0
  54. package/dist/server/index.js +641 -0
  55. package/dist/session/default-session-manager.d.ts +77 -0
  56. package/dist/session/rpc-session-service.d.ts +12 -0
  57. package/dist/session/runtime-oauth-token-manager.d.ts +28 -0
  58. package/dist/session/session-artifacts.d.ts +19 -0
  59. package/dist/session/session-graph.d.ts +15 -0
  60. package/dist/session/session-host.d.ts +21 -0
  61. package/dist/session/session-manager.d.ts +50 -0
  62. package/dist/session/session-manifest.d.ts +30 -0
  63. package/dist/session/session-service.d.ts +113 -0
  64. package/dist/session/sqlite-rpc-session-backend.d.ts +30 -0
  65. package/dist/session/unified-session-persistence-service.d.ts +93 -0
  66. package/dist/session/workspace-manager.d.ts +28 -0
  67. package/dist/session/workspace-manifest.d.ts +25 -0
  68. package/dist/storage/provider-settings-legacy-migration.d.ts +13 -0
  69. package/dist/storage/provider-settings-manager.d.ts +20 -0
  70. package/dist/storage/sqlite-session-store.d.ts +29 -0
  71. package/dist/storage/sqlite-team-store.d.ts +31 -0
  72. package/dist/storage/team-store.d.ts +2 -0
  73. package/dist/team/index.d.ts +1 -0
  74. package/dist/team/projections.d.ts +8 -0
  75. package/dist/types/common.d.ts +10 -0
  76. package/dist/types/config.d.ts +37 -0
  77. package/dist/types/events.d.ts +54 -0
  78. package/dist/types/provider-settings.d.ts +20 -0
  79. package/dist/types/sessions.d.ts +9 -0
  80. package/dist/types/storage.d.ts +37 -0
  81. package/dist/types/workspace.d.ts +7 -0
  82. package/dist/types.d.ts +26 -0
  83. package/package.json +63 -0
  84. package/src/account/cline-account-service.test.ts +101 -0
  85. package/src/account/cline-account-service.ts +267 -0
  86. package/src/account/index.ts +20 -0
  87. package/src/account/rpc.test.ts +62 -0
  88. package/src/account/rpc.ts +172 -0
  89. package/src/account/types.ts +80 -0
  90. package/src/agents/agent-config-loader.test.ts +234 -0
  91. package/src/agents/agent-config-loader.ts +107 -0
  92. package/src/agents/agent-config-parser.ts +191 -0
  93. package/src/agents/hooks-config-loader.ts +97 -0
  94. package/src/agents/index.ts +84 -0
  95. package/src/agents/plugin-config-loader.test.ts +91 -0
  96. package/src/agents/plugin-config-loader.ts +160 -0
  97. package/src/agents/plugin-loader.test.ts +102 -0
  98. package/src/agents/plugin-loader.ts +105 -0
  99. package/src/agents/plugin-sandbox.test.ts +120 -0
  100. package/src/agents/plugin-sandbox.ts +471 -0
  101. package/src/agents/unified-config-file-watcher.test.ts +196 -0
  102. package/src/agents/unified-config-file-watcher.ts +483 -0
  103. package/src/agents/user-instruction-config-loader.test.ts +158 -0
  104. package/src/agents/user-instruction-config-loader.ts +438 -0
  105. package/src/auth/client.test.ts +40 -0
  106. package/src/auth/client.ts +25 -0
  107. package/src/auth/cline.test.ts +130 -0
  108. package/src/auth/cline.ts +414 -0
  109. package/src/auth/codex.test.ts +170 -0
  110. package/src/auth/codex.ts +466 -0
  111. package/src/auth/oca.test.ts +215 -0
  112. package/src/auth/oca.ts +546 -0
  113. package/src/auth/server.ts +216 -0
  114. package/src/auth/types.ts +78 -0
  115. package/src/auth/utils.test.ts +128 -0
  116. package/src/auth/utils.ts +247 -0
  117. package/src/chat/chat-schema.ts +82 -0
  118. package/src/default-tools/constants.ts +35 -0
  119. package/src/default-tools/definitions.test.ts +233 -0
  120. package/src/default-tools/definitions.ts +632 -0
  121. package/src/default-tools/executors/apply-patch-parser.ts +520 -0
  122. package/src/default-tools/executors/apply-patch.ts +359 -0
  123. package/src/default-tools/executors/bash.ts +205 -0
  124. package/src/default-tools/executors/editor.ts +231 -0
  125. package/src/default-tools/executors/file-read.test.ts +25 -0
  126. package/src/default-tools/executors/file-read.ts +94 -0
  127. package/src/default-tools/executors/index.ts +75 -0
  128. package/src/default-tools/executors/search.ts +278 -0
  129. package/src/default-tools/executors/web-fetch.ts +259 -0
  130. package/src/default-tools/index.ts +161 -0
  131. package/src/default-tools/presets.test.ts +63 -0
  132. package/src/default-tools/presets.ts +168 -0
  133. package/src/default-tools/schemas.ts +228 -0
  134. package/src/default-tools/types.ts +324 -0
  135. package/src/index.ts +119 -0
  136. package/src/input/file-indexer.d.ts +11 -0
  137. package/src/input/file-indexer.test.ts +87 -0
  138. package/src/input/file-indexer.ts +280 -0
  139. package/src/input/index.ts +7 -0
  140. package/src/input/mention-enricher.test.ts +82 -0
  141. package/src/input/mention-enricher.ts +119 -0
  142. package/src/mcp/config-loader.test.ts +238 -0
  143. package/src/mcp/config-loader.ts +219 -0
  144. package/src/mcp/index.ts +26 -0
  145. package/src/mcp/manager.test.ts +106 -0
  146. package/src/mcp/manager.ts +262 -0
  147. package/src/mcp/types.ts +88 -0
  148. package/src/runtime/hook-file-hooks.test.ts +106 -0
  149. package/src/runtime/hook-file-hooks.ts +736 -0
  150. package/src/runtime/index.ts +27 -0
  151. package/src/runtime/rules.ts +34 -0
  152. package/src/runtime/runtime-builder.team-persistence.test.ts +203 -0
  153. package/src/runtime/runtime-builder.test.ts +215 -0
  154. package/src/runtime/runtime-builder.ts +515 -0
  155. package/src/runtime/runtime-parity.test.ts +132 -0
  156. package/src/runtime/sandbox/subprocess-sandbox.ts +207 -0
  157. package/src/runtime/session-runtime.ts +44 -0
  158. package/src/runtime/tool-approval.ts +104 -0
  159. package/src/runtime/workflows.test.ts +119 -0
  160. package/src/runtime/workflows.ts +54 -0
  161. package/src/server/index.ts +282 -0
  162. package/src/session/default-session-manager.e2e.test.ts +354 -0
  163. package/src/session/default-session-manager.test.ts +816 -0
  164. package/src/session/default-session-manager.ts +1286 -0
  165. package/src/session/index.ts +37 -0
  166. package/src/session/rpc-session-service.ts +189 -0
  167. package/src/session/runtime-oauth-token-manager.test.ts +137 -0
  168. package/src/session/runtime-oauth-token-manager.ts +265 -0
  169. package/src/session/session-artifacts.ts +106 -0
  170. package/src/session/session-graph.ts +90 -0
  171. package/src/session/session-host.ts +190 -0
  172. package/src/session/session-manager.ts +56 -0
  173. package/src/session/session-manifest.ts +29 -0
  174. package/src/session/session-service.team-persistence.test.ts +48 -0
  175. package/src/session/session-service.ts +610 -0
  176. package/src/session/sqlite-rpc-session-backend.ts +303 -0
  177. package/src/session/unified-session-persistence-service.ts +781 -0
  178. package/src/session/workspace-manager.ts +98 -0
  179. package/src/session/workspace-manifest.ts +100 -0
  180. package/src/storage/artifact-store.ts +1 -0
  181. package/src/storage/index.ts +11 -0
  182. package/src/storage/provider-settings-legacy-migration.test.ts +175 -0
  183. package/src/storage/provider-settings-legacy-migration.ts +637 -0
  184. package/src/storage/provider-settings-manager.test.ts +111 -0
  185. package/src/storage/provider-settings-manager.ts +129 -0
  186. package/src/storage/session-store.ts +1 -0
  187. package/src/storage/sqlite-session-store.ts +270 -0
  188. package/src/storage/sqlite-team-store.ts +443 -0
  189. package/src/storage/team-store.ts +5 -0
  190. package/src/team/index.ts +4 -0
  191. package/src/team/projections.ts +285 -0
  192. package/src/types/common.ts +14 -0
  193. package/src/types/config.ts +64 -0
  194. package/src/types/events.ts +46 -0
  195. package/src/types/index.ts +24 -0
  196. package/src/types/provider-settings.ts +43 -0
  197. package/src/types/sessions.ts +16 -0
  198. package/src/types/storage.ts +64 -0
  199. package/src/types/workspace.ts +7 -0
  200. package/src/types.ts +127 -0
@@ -0,0 +1,282 @@
1
+ /**
2
+ * @clinebot/core/server
3
+ *
4
+ * Node/runtime services for host applications (CLI, desktop runtime, servers).
5
+ */
6
+
7
+ export {
8
+ type ClineAccountBalance,
9
+ type ClineAccountOperations,
10
+ type ClineAccountOrganization,
11
+ type ClineAccountOrganizationBalance,
12
+ type ClineAccountOrganizationUsageTransaction,
13
+ type ClineAccountPaymentTransaction,
14
+ ClineAccountService,
15
+ type ClineAccountServiceOptions,
16
+ type ClineAccountUsageTransaction,
17
+ type ClineAccountUser,
18
+ executeRpcClineAccountAction,
19
+ isRpcClineAccountActionRequest,
20
+ RpcClineAccountService,
21
+ type RpcProviderActionExecutor,
22
+ } from "../account";
23
+ export type {
24
+ AgentConfigWatcher,
25
+ AgentConfigWatcherEvent,
26
+ AgentYamlConfig,
27
+ BuildAgentConfigOverridesOptions,
28
+ CreateAgentConfigWatcherOptions,
29
+ CreateInstructionWatcherOptions,
30
+ CreateRulesConfigDefinitionOptions,
31
+ CreateSkillsConfigDefinitionOptions,
32
+ CreateUserInstructionConfigWatcherOptions,
33
+ CreateWorkflowsConfigDefinitionOptions,
34
+ HookConfigFileEntry,
35
+ LoadAgentPluginFromPathOptions,
36
+ ParseMarkdownFrontmatterResult,
37
+ ParseYamlFrontmatterResult,
38
+ ResolveAgentPluginPathsOptions,
39
+ RuleConfig,
40
+ SkillConfig,
41
+ UnifiedConfigDefinition,
42
+ UnifiedConfigFileCandidate,
43
+ UnifiedConfigFileContext,
44
+ UnifiedConfigRecord,
45
+ UnifiedConfigWatcherEvent,
46
+ UnifiedConfigWatcherOptions,
47
+ UserInstructionConfig,
48
+ UserInstructionConfigType,
49
+ UserInstructionConfigWatcher,
50
+ UserInstructionConfigWatcherEvent,
51
+ WorkflowConfig,
52
+ } from "../agents";
53
+ export {
54
+ createAgentConfigDefinition,
55
+ createAgentConfigWatcher,
56
+ createRulesConfigDefinition,
57
+ createSkillsConfigDefinition,
58
+ createUserInstructionConfigWatcher,
59
+ createWorkflowsConfigDefinition,
60
+ discoverPluginModulePaths,
61
+ HOOK_CONFIG_FILE_EVENT_MAP,
62
+ HOOKS_CONFIG_DIRECTORY_NAME,
63
+ HookConfigFileName,
64
+ listHookConfigFiles,
65
+ loadAgentPluginFromPath,
66
+ loadAgentPluginsFromPaths,
67
+ parseAgentConfigFromYaml,
68
+ parsePartialAgentConfigFromYaml,
69
+ parseRuleConfigFromMarkdown,
70
+ parseSkillConfigFromMarkdown,
71
+ parseWorkflowConfigFromMarkdown,
72
+ RULES_CONFIG_DIRECTORY_NAME,
73
+ resolveAgentPluginPaths,
74
+ resolveAgentTools,
75
+ resolveAndLoadAgentPlugins,
76
+ resolveDocumentsHooksDirectoryPath,
77
+ resolveDocumentsRulesDirectoryPath,
78
+ resolveDocumentsWorkflowsDirectoryPath,
79
+ resolveHooksConfigSearchPaths,
80
+ resolvePluginConfigSearchPaths,
81
+ resolveRulesConfigSearchPaths,
82
+ resolveSkillsConfigSearchPaths,
83
+ resolveWorkflowsConfigSearchPaths,
84
+ SKILLS_CONFIG_DIRECTORY_NAME,
85
+ toHookConfigFileName,
86
+ toPartialAgentConfig,
87
+ UnifiedConfigFileWatcher,
88
+ WORKFLOWS_CONFIG_DIRECTORY_NAME,
89
+ } from "../agents";
90
+ export {
91
+ createOAuthClientCallbacks,
92
+ type OAuthClientCallbacksOptions,
93
+ } from "../auth/client";
94
+ export {
95
+ createClineOAuthProvider,
96
+ getValidClineCredentials,
97
+ loginClineOAuth,
98
+ refreshClineToken,
99
+ } from "../auth/cline";
100
+ export {
101
+ getValidOpenAICodexCredentials,
102
+ isOpenAICodexTokenExpired,
103
+ loginOpenAICodex,
104
+ normalizeOpenAICodexCredentials,
105
+ openaiCodexOAuthProvider,
106
+ refreshOpenAICodexToken,
107
+ } from "../auth/codex";
108
+ export {
109
+ createOcaOAuthProvider,
110
+ createOcaRequestHeaders,
111
+ DEFAULT_EXTERNAL_IDCS_CLIENT_ID,
112
+ DEFAULT_EXTERNAL_IDCS_SCOPES,
113
+ DEFAULT_EXTERNAL_IDCS_URL,
114
+ DEFAULT_EXTERNAL_OCA_BASE_URL,
115
+ DEFAULT_INTERNAL_IDCS_CLIENT_ID,
116
+ DEFAULT_INTERNAL_IDCS_SCOPES,
117
+ DEFAULT_INTERNAL_IDCS_URL,
118
+ DEFAULT_INTERNAL_OCA_BASE_URL,
119
+ generateOcaOpcRequestId,
120
+ getValidOcaCredentials,
121
+ loginOcaOAuth,
122
+ OCI_HEADER_OPC_REQUEST_ID,
123
+ refreshOcaToken,
124
+ } from "../auth/oca";
125
+ export { startLocalOAuthServer } from "../auth/server";
126
+ export type {
127
+ OAuthCredentials,
128
+ OAuthLoginCallbacks,
129
+ OAuthPrompt,
130
+ OAuthProviderInterface,
131
+ OcaClientMetadata,
132
+ OcaMode,
133
+ OcaOAuthConfig,
134
+ OcaOAuthEnvironmentConfig,
135
+ OcaOAuthProviderOptions,
136
+ OcaTokenResolution,
137
+ } from "../auth/types";
138
+ export {
139
+ ALL_DEFAULT_TOOL_NAMES,
140
+ type AskQuestionExecutor,
141
+ type CreateBuiltinToolsOptions,
142
+ type CreateDefaultToolsOptions,
143
+ createBuiltinTools,
144
+ createDefaultExecutors,
145
+ createDefaultTools,
146
+ createDefaultToolsWithPreset,
147
+ createToolPoliciesWithPreset,
148
+ type DefaultExecutorsOptions,
149
+ type DefaultToolName,
150
+ DefaultToolNames,
151
+ type DefaultToolsConfig,
152
+ type ToolExecutors,
153
+ type ToolPolicyPresetName,
154
+ type ToolPresetName,
155
+ ToolPresets,
156
+ } from "../default-tools";
157
+ export type {
158
+ FastFileIndexOptions,
159
+ MentionEnricherOptions,
160
+ MentionEnrichmentResult,
161
+ } from "../input";
162
+ export {
163
+ enrichPromptWithMentions,
164
+ getFileIndex,
165
+ prewarmFileIndex,
166
+ } from "../input";
167
+
168
+ export type {
169
+ LoadMcpSettingsOptions,
170
+ McpConnectionStatus,
171
+ McpManager,
172
+ McpManagerOptions,
173
+ McpServerClient,
174
+ McpServerClientFactory,
175
+ McpServerRegistration,
176
+ McpServerSnapshot,
177
+ McpServerTransportConfig,
178
+ McpSettingsFile,
179
+ McpSseTransportConfig,
180
+ McpStdioTransportConfig,
181
+ McpStreamableHttpTransportConfig,
182
+ RegisterMcpServersFromSettingsOptions,
183
+ } from "../mcp";
184
+ export {
185
+ hasMcpSettingsFile,
186
+ InMemoryMcpManager,
187
+ loadMcpSettingsFile,
188
+ registerMcpServersFromSettingsFile,
189
+ resolveDefaultMcpSettingsPath,
190
+ resolveMcpServerRegistrations,
191
+ } from "../mcp";
192
+ export {
193
+ formatRulesForSystemPrompt,
194
+ isRuleEnabled,
195
+ listEnabledRulesFromWatcher,
196
+ loadRulesForSystemPromptFromWatcher,
197
+ } from "../runtime/rules";
198
+ export {
199
+ createTeamName,
200
+ DefaultRuntimeBuilder,
201
+ } from "../runtime/runtime-builder";
202
+ export {
203
+ type SandboxCallOptions,
204
+ SubprocessSandbox,
205
+ type SubprocessSandboxOptions,
206
+ } from "../runtime/sandbox/subprocess-sandbox";
207
+ export type {
208
+ BuiltRuntime,
209
+ RuntimeBuilder,
210
+ RuntimeBuilderInput,
211
+ SessionRuntime,
212
+ } from "../runtime/session-runtime";
213
+ export {
214
+ type DesktopToolApprovalOptions,
215
+ requestDesktopToolApproval,
216
+ } from "../runtime/tool-approval";
217
+ export type { AvailableWorkflow } from "../runtime/workflows";
218
+ export {
219
+ listAvailableWorkflowsFromWatcher,
220
+ resolveWorkflowSlashCommandFromWatcher,
221
+ } from "../runtime/workflows";
222
+ export { DefaultSessionManager } from "../session/default-session-manager";
223
+ export { RpcCoreSessionService } from "../session/rpc-session-service";
224
+ export {
225
+ deriveSubsessionStatus,
226
+ makeSubSessionId,
227
+ makeTeamTaskSubSessionId,
228
+ sanitizeSessionToken,
229
+ } from "../session/session-graph";
230
+ export type {
231
+ CreateSessionHostOptions,
232
+ SessionHost,
233
+ } from "../session/session-host";
234
+ export { createSessionHost } from "../session/session-host";
235
+ export type {
236
+ SendSessionInput,
237
+ SessionManager,
238
+ StartSessionInput,
239
+ StartSessionResult,
240
+ } from "../session/session-manager";
241
+ export type { SessionManifest } from "../session/session-manifest";
242
+ export type {
243
+ CreateRootSessionWithArtifactsInput,
244
+ RootSessionArtifacts,
245
+ } from "../session/session-service";
246
+ export { CoreSessionService } from "../session/session-service";
247
+ export {
248
+ createSqliteRpcSessionBackend,
249
+ SqliteRpcSessionBackend,
250
+ type SqliteRpcSessionBackendOptions,
251
+ } from "../session/sqlite-rpc-session-backend";
252
+ export type {
253
+ WorkspaceManager,
254
+ WorkspaceManagerEvent,
255
+ } from "../session/workspace-manager";
256
+ export { InMemoryWorkspaceManager } from "../session/workspace-manager";
257
+ export type { WorkspaceManifest } from "../session/workspace-manifest";
258
+ export {
259
+ buildWorkspaceMetadata,
260
+ emptyWorkspaceManifest,
261
+ generateWorkspaceInfo,
262
+ normalizeWorkspacePath,
263
+ upsertWorkspaceInfo,
264
+ WorkspaceInfoSchema,
265
+ WorkspaceManifestSchema,
266
+ } from "../session/workspace-manifest";
267
+ export {
268
+ type MigrateLegacyProviderSettingsOptions,
269
+ type MigrateLegacyProviderSettingsResult,
270
+ migrateLegacyProviderSettings,
271
+ } from "../storage/provider-settings-legacy-migration";
272
+ export { ProviderSettingsManager } from "../storage/provider-settings-manager";
273
+ export { SqliteSessionStore } from "../storage/sqlite-session-store";
274
+ export type { SessionStatus } from "../types/common";
275
+ export { SESSION_STATUSES, SessionSource } from "../types/common";
276
+ export type {
277
+ CoreAgentMode,
278
+ CoreModelConfig,
279
+ CoreRuntimeFeatures,
280
+ CoreSessionConfig,
281
+ } from "../types/config";
282
+ export type { WorkspaceInfo } from "../types/workspace";
@@ -0,0 +1,354 @@
1
+ import {
2
+ existsSync,
3
+ mkdirSync,
4
+ mkdtempSync,
5
+ readFileSync,
6
+ rmSync,
7
+ unlinkSync,
8
+ writeFileSync,
9
+ } from "node:fs";
10
+ import { tmpdir } from "node:os";
11
+ import { join } from "node:path";
12
+ import type { AgentResult } from "@clinebot/agents";
13
+ import type { providers as LlmsProviders } from "@clinebot/llms";
14
+ import { nanoid } from "nanoid";
15
+ import { afterEach, describe, expect, it, vi } from "vitest";
16
+ import type { SessionSource, SessionStatus } from "../types/common";
17
+ import { DefaultSessionManager } from "./default-session-manager";
18
+ import type { SessionManifest } from "./session-manifest";
19
+ import type { RootSessionArtifacts, SessionRowShape } from "./session-service";
20
+
21
+ function nowIso(): string {
22
+ return new Date().toISOString();
23
+ }
24
+
25
+ function createResult(overrides: Partial<AgentResult> = {}): AgentResult {
26
+ return {
27
+ text: "ok",
28
+ iterations: 1,
29
+ finishReason: "completed",
30
+ usage: {
31
+ inputTokens: 1,
32
+ outputTokens: 2,
33
+ totalCost: 0,
34
+ },
35
+ messages: [],
36
+ toolCalls: [],
37
+ durationMs: 1,
38
+ model: {
39
+ id: "mock-model",
40
+ provider: "mock-provider",
41
+ },
42
+ startedAt: new Date("2026-01-01T00:00:00.000Z"),
43
+ endedAt: new Date("2026-01-01T00:00:01.000Z"),
44
+ ...overrides,
45
+ };
46
+ }
47
+
48
+ class LocalFileSessionService {
49
+ private readonly rows = new Map<string, SessionRowShape>();
50
+
51
+ constructor(private readonly sessionsDir: string) {}
52
+
53
+ ensureSessionsDir(): string {
54
+ mkdirSync(this.sessionsDir, { recursive: true });
55
+ return this.sessionsDir;
56
+ }
57
+
58
+ createRootSessionWithArtifacts(input: {
59
+ sessionId: string;
60
+ source: SessionSource;
61
+ pid: number;
62
+ interactive: boolean;
63
+ provider: string;
64
+ model: string;
65
+ cwd: string;
66
+ workspaceRoot: string;
67
+ teamName?: string;
68
+ enableTools: boolean;
69
+ enableSpawn: boolean;
70
+ enableTeams: boolean;
71
+ prompt?: string;
72
+ startedAt?: string;
73
+ }): RootSessionArtifacts {
74
+ const startedAt = input.startedAt ?? nowIso();
75
+ const sessionId = input.sessionId.trim() || `${Date.now()}_${nanoid(5)}`;
76
+ const sessionPath = join(this.sessionsDir, sessionId);
77
+ mkdirSync(sessionPath, { recursive: true });
78
+
79
+ const manifestPath = join(sessionPath, `${sessionId}.json`);
80
+ const transcriptPath = join(sessionPath, `${sessionId}.log`);
81
+ const hookPath = join(sessionPath, `${sessionId}.hooks.jsonl`);
82
+ const messagesPath = join(sessionPath, `${sessionId}.messages.json`);
83
+ const prompt = input.prompt?.trim() || undefined;
84
+ const manifest: SessionManifest = {
85
+ version: 1,
86
+ session_id: sessionId,
87
+ source: input.source,
88
+ pid: input.pid,
89
+ started_at: startedAt,
90
+ status: "running",
91
+ interactive: input.interactive,
92
+ provider: input.provider,
93
+ model: input.model,
94
+ cwd: input.cwd,
95
+ workspace_root: input.workspaceRoot,
96
+ team_name: input.teamName,
97
+ enable_tools: input.enableTools,
98
+ enable_spawn: input.enableSpawn,
99
+ enable_teams: input.enableTeams,
100
+ prompt,
101
+ messages_path: messagesPath,
102
+ };
103
+ writeFileSync(
104
+ manifestPath,
105
+ `${JSON.stringify(manifest, null, 2)}\n`,
106
+ "utf8",
107
+ );
108
+ writeFileSync(transcriptPath, "", "utf8");
109
+ writeFileSync(hookPath, "", "utf8");
110
+ writeFileSync(
111
+ messagesPath,
112
+ `${JSON.stringify({ version: 1, updated_at: startedAt, messages: [] }, null, 2)}\n`,
113
+ "utf8",
114
+ );
115
+
116
+ this.rows.set(sessionId, {
117
+ session_id: sessionId,
118
+ source: input.source,
119
+ pid: input.pid,
120
+ started_at: startedAt,
121
+ ended_at: null,
122
+ exit_code: null,
123
+ status: "running",
124
+ status_lock: 0,
125
+ interactive: input.interactive ? 1 : 0,
126
+ provider: input.provider,
127
+ model: input.model,
128
+ cwd: input.cwd,
129
+ workspace_root: input.workspaceRoot,
130
+ team_name: input.teamName ?? null,
131
+ enable_tools: input.enableTools ? 1 : 0,
132
+ enable_spawn: input.enableSpawn ? 1 : 0,
133
+ enable_teams: input.enableTeams ? 1 : 0,
134
+ parent_session_id: null,
135
+ parent_agent_id: null,
136
+ agent_id: null,
137
+ conversation_id: null,
138
+ is_subagent: 0,
139
+ prompt: prompt ?? null,
140
+ transcript_path: transcriptPath,
141
+ hook_path: hookPath,
142
+ messages_path: messagesPath,
143
+ updated_at: startedAt,
144
+ });
145
+
146
+ return {
147
+ manifestPath,
148
+ transcriptPath,
149
+ hookPath,
150
+ messagesPath,
151
+ manifest,
152
+ };
153
+ }
154
+
155
+ persistSessionMessages(
156
+ sessionId: string,
157
+ messages: LlmsProviders.Message[],
158
+ ): void {
159
+ const row = this.rows.get(sessionId);
160
+ if (!row?.messages_path) {
161
+ throw new Error(`session not found: ${sessionId}`);
162
+ }
163
+ writeFileSync(
164
+ row.messages_path,
165
+ `${JSON.stringify({ version: 1, updated_at: nowIso(), messages }, null, 2)}\n`,
166
+ "utf8",
167
+ );
168
+ }
169
+
170
+ updateSessionStatus(
171
+ sessionId: string,
172
+ status: SessionStatus,
173
+ exitCode?: number | null,
174
+ ): { updated: boolean; endedAt?: string } {
175
+ const row = this.rows.get(sessionId);
176
+ if (!row) {
177
+ return { updated: false };
178
+ }
179
+ const endedAt = nowIso();
180
+ row.status = status;
181
+ row.ended_at = endedAt;
182
+ row.exit_code = typeof exitCode === "number" ? exitCode : null;
183
+ row.updated_at = endedAt;
184
+ row.status_lock = (row.status_lock ?? 0) + 1;
185
+ return { updated: true, endedAt };
186
+ }
187
+
188
+ writeSessionManifest(manifestPath: string, manifest: SessionManifest): void {
189
+ writeFileSync(
190
+ manifestPath,
191
+ `${JSON.stringify(manifest, null, 2)}\n`,
192
+ "utf8",
193
+ );
194
+ }
195
+
196
+ listSessions(limit = 200): SessionRowShape[] {
197
+ return Array.from(this.rows.values()).slice(0, limit);
198
+ }
199
+
200
+ deleteSession(sessionId: string): { deleted: boolean } {
201
+ const row = this.rows.get(sessionId);
202
+ if (!row) {
203
+ return { deleted: false };
204
+ }
205
+ this.rows.delete(sessionId);
206
+ unlinkSync(row.transcript_path);
207
+ unlinkSync(row.hook_path);
208
+ unlinkSync(row.messages_path ?? "");
209
+ unlinkSync(join(this.sessionsDir, sessionId, `${sessionId}.json`));
210
+ return { deleted: true };
211
+ }
212
+ }
213
+
214
+ describe("DefaultSessionManager e2e", () => {
215
+ const tempDirs: string[] = [];
216
+
217
+ afterEach(() => {
218
+ for (const dir of tempDirs.splice(0)) {
219
+ rmSync(dir, { recursive: true, force: true });
220
+ }
221
+ });
222
+
223
+ it("runs an interactive lifecycle with real artifact files", async () => {
224
+ const sessionsDir = mkdtempSync(join(tmpdir(), "core-e2e-sessions-"));
225
+ tempDirs.push(sessionsDir);
226
+
227
+ const sessionService = new LocalFileSessionService(sessionsDir);
228
+ const runtimeShutdown = vi.fn();
229
+ const runtimeBuilder = {
230
+ build: vi.fn().mockReturnValue({
231
+ tools: [],
232
+ shutdown: runtimeShutdown,
233
+ }),
234
+ };
235
+
236
+ let messages: LlmsProviders.Message[] = [];
237
+ let turn = 0;
238
+ const run = vi.fn(async (prompt: string) => {
239
+ turn += 1;
240
+ messages = [
241
+ ...messages,
242
+ {
243
+ role: "user",
244
+ content: [{ type: "text", text: prompt }],
245
+ },
246
+ {
247
+ role: "assistant",
248
+ content: [{ type: "text", text: `reply:${turn}:${prompt}` }],
249
+ },
250
+ ] as LlmsProviders.Message[];
251
+ return createResult({
252
+ text: `reply:${turn}:${prompt}`,
253
+ messages: [...messages],
254
+ });
255
+ });
256
+ const continueFn = vi.fn(async (prompt: string) => {
257
+ turn += 1;
258
+ messages = [
259
+ ...messages,
260
+ {
261
+ role: "user",
262
+ content: [{ type: "text", text: prompt }],
263
+ },
264
+ {
265
+ role: "assistant",
266
+ content: [{ type: "text", text: `reply:${turn}:${prompt}` }],
267
+ },
268
+ ] as LlmsProviders.Message[];
269
+ return createResult({
270
+ text: `reply:${turn}:${prompt}`,
271
+ messages: [...messages],
272
+ });
273
+ });
274
+ const agentShutdown = vi.fn().mockResolvedValue(undefined);
275
+
276
+ const manager = new DefaultSessionManager({
277
+ distinctId: `test-${nanoid(5)}`,
278
+ sessionService: sessionService as never,
279
+ runtimeBuilder: runtimeBuilder as never,
280
+ createAgent: () =>
281
+ ({
282
+ run,
283
+ continue: continueFn,
284
+ abort: vi.fn(),
285
+ restore: vi.fn((baseline: LlmsProviders.Message[]) => {
286
+ messages = [...baseline];
287
+ }),
288
+ updateConnection: vi.fn(),
289
+ shutdown: agentShutdown,
290
+ getMessages: vi.fn(() => [...messages]),
291
+ messages: [],
292
+ }) as never,
293
+ });
294
+
295
+ const started = await manager.start({
296
+ interactive: true,
297
+ config: {
298
+ providerId: "anthropic",
299
+ modelId: "claude-sonnet-4-6",
300
+ apiKey: "test-key",
301
+ cwd: sessionsDir,
302
+ systemPrompt: "You are a test agent",
303
+ enableTools: false,
304
+ enableSpawnAgent: false,
305
+ enableAgentTeams: false,
306
+ },
307
+ });
308
+
309
+ expect(started.sessionId.length).toBeGreaterThan(0);
310
+ expect(existsSync(started.manifestPath)).toBe(false);
311
+ expect(existsSync(started.messagesPath)).toBe(false);
312
+
313
+ const first = await manager.send({
314
+ sessionId: started.sessionId,
315
+ prompt: "first prompt",
316
+ });
317
+ const second = await manager.send({
318
+ sessionId: started.sessionId,
319
+ prompt: "second prompt",
320
+ });
321
+ expect(existsSync(started.manifestPath)).toBe(true);
322
+ expect(existsSync(started.messagesPath)).toBe(true);
323
+
324
+ expect(first?.text).toContain("first prompt");
325
+ expect(second?.text).toContain("second prompt");
326
+ expect(run).toHaveBeenCalledTimes(1);
327
+ expect(continueFn).toHaveBeenCalledTimes(1);
328
+
329
+ const persistedMessages = await manager.readMessages(started.sessionId);
330
+ expect(persistedMessages.length).toBeGreaterThan(0);
331
+ expect(JSON.stringify(persistedMessages)).toContain("second prompt");
332
+
333
+ const listed = await manager.list(20);
334
+ expect(
335
+ listed.some((session) => session.sessionId === started.sessionId),
336
+ ).toBe(true);
337
+
338
+ await manager.stop(started.sessionId);
339
+ const stopped = await manager.get(started.sessionId);
340
+ expect(stopped?.status).toBe("cancelled");
341
+ expect(agentShutdown).toHaveBeenCalledTimes(1);
342
+ expect(runtimeShutdown).toHaveBeenCalledTimes(1);
343
+ const parsedManifest = JSON.parse(
344
+ readFileSync(started.manifestPath, "utf8"),
345
+ ) as SessionManifest;
346
+ expect(parsedManifest.status).toBe("cancelled");
347
+
348
+ const deleted = await manager.delete(started.sessionId);
349
+ expect(deleted).toBe(true);
350
+ expect(await manager.get(started.sessionId)).toBeUndefined();
351
+ expect(existsSync(started.manifestPath)).toBe(false);
352
+ expect(existsSync(started.messagesPath)).toBe(false);
353
+ });
354
+ });