sessionlog 0.0.1

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 (219) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +388 -0
  3. package/dist/agent/agents/claude-code.d.ts +76 -0
  4. package/dist/agent/agents/claude-code.d.ts.map +1 -0
  5. package/dist/agent/agents/claude-code.js +769 -0
  6. package/dist/agent/agents/claude-code.js.map +1 -0
  7. package/dist/agent/agents/cursor.d.ts +35 -0
  8. package/dist/agent/agents/cursor.d.ts.map +1 -0
  9. package/dist/agent/agents/cursor.js +294 -0
  10. package/dist/agent/agents/cursor.js.map +1 -0
  11. package/dist/agent/agents/gemini-cli.d.ts +62 -0
  12. package/dist/agent/agents/gemini-cli.d.ts.map +1 -0
  13. package/dist/agent/agents/gemini-cli.js +474 -0
  14. package/dist/agent/agents/gemini-cli.js.map +1 -0
  15. package/dist/agent/agents/opencode.d.ts +100 -0
  16. package/dist/agent/agents/opencode.d.ts.map +1 -0
  17. package/dist/agent/agents/opencode.js +423 -0
  18. package/dist/agent/agents/opencode.js.map +1 -0
  19. package/dist/agent/registry.d.ts +54 -0
  20. package/dist/agent/registry.d.ts.map +1 -0
  21. package/dist/agent/registry.js +123 -0
  22. package/dist/agent/registry.js.map +1 -0
  23. package/dist/agent/session-types.d.ts +45 -0
  24. package/dist/agent/session-types.d.ts.map +1 -0
  25. package/dist/agent/session-types.js +48 -0
  26. package/dist/agent/session-types.js.map +1 -0
  27. package/dist/agent/types.d.ts +126 -0
  28. package/dist/agent/types.d.ts.map +1 -0
  29. package/dist/agent/types.js +40 -0
  30. package/dist/agent/types.js.map +1 -0
  31. package/dist/cli.d.ts +12 -0
  32. package/dist/cli.d.ts.map +1 -0
  33. package/dist/cli.js +425 -0
  34. package/dist/cli.js.map +1 -0
  35. package/dist/commands/clean.d.ts +30 -0
  36. package/dist/commands/clean.d.ts.map +1 -0
  37. package/dist/commands/clean.js +98 -0
  38. package/dist/commands/clean.js.map +1 -0
  39. package/dist/commands/disable.d.ts +23 -0
  40. package/dist/commands/disable.d.ts.map +1 -0
  41. package/dist/commands/disable.js +57 -0
  42. package/dist/commands/disable.js.map +1 -0
  43. package/dist/commands/doctor.d.ts +43 -0
  44. package/dist/commands/doctor.d.ts.map +1 -0
  45. package/dist/commands/doctor.js +97 -0
  46. package/dist/commands/doctor.js.map +1 -0
  47. package/dist/commands/enable.d.ts +37 -0
  48. package/dist/commands/enable.d.ts.map +1 -0
  49. package/dist/commands/enable.js +133 -0
  50. package/dist/commands/enable.js.map +1 -0
  51. package/dist/commands/explain.d.ts +68 -0
  52. package/dist/commands/explain.d.ts.map +1 -0
  53. package/dist/commands/explain.js +182 -0
  54. package/dist/commands/explain.js.map +1 -0
  55. package/dist/commands/reset.d.ts +23 -0
  56. package/dist/commands/reset.d.ts.map +1 -0
  57. package/dist/commands/reset.js +68 -0
  58. package/dist/commands/reset.js.map +1 -0
  59. package/dist/commands/resume.d.ts +42 -0
  60. package/dist/commands/resume.d.ts.map +1 -0
  61. package/dist/commands/resume.js +133 -0
  62. package/dist/commands/resume.js.map +1 -0
  63. package/dist/commands/rewind.d.ts +34 -0
  64. package/dist/commands/rewind.d.ts.map +1 -0
  65. package/dist/commands/rewind.js +155 -0
  66. package/dist/commands/rewind.js.map +1 -0
  67. package/dist/commands/status.d.ts +51 -0
  68. package/dist/commands/status.d.ts.map +1 -0
  69. package/dist/commands/status.js +112 -0
  70. package/dist/commands/status.js.map +1 -0
  71. package/dist/config.d.ts +40 -0
  72. package/dist/config.d.ts.map +1 -0
  73. package/dist/config.js +127 -0
  74. package/dist/config.js.map +1 -0
  75. package/dist/git-operations.d.ts +191 -0
  76. package/dist/git-operations.d.ts.map +1 -0
  77. package/dist/git-operations.js +462 -0
  78. package/dist/git-operations.js.map +1 -0
  79. package/dist/hooks/git-hooks.d.ts +22 -0
  80. package/dist/hooks/git-hooks.d.ts.map +1 -0
  81. package/dist/hooks/git-hooks.js +139 -0
  82. package/dist/hooks/git-hooks.js.map +1 -0
  83. package/dist/hooks/lifecycle.d.ts +21 -0
  84. package/dist/hooks/lifecycle.d.ts.map +1 -0
  85. package/dist/hooks/lifecycle.js +179 -0
  86. package/dist/hooks/lifecycle.js.map +1 -0
  87. package/dist/index.d.ts +76 -0
  88. package/dist/index.d.ts.map +1 -0
  89. package/dist/index.js +166 -0
  90. package/dist/index.js.map +1 -0
  91. package/dist/security/redaction.d.ts +35 -0
  92. package/dist/security/redaction.d.ts.map +1 -0
  93. package/dist/security/redaction.js +239 -0
  94. package/dist/security/redaction.js.map +1 -0
  95. package/dist/session/state-machine.d.ts +90 -0
  96. package/dist/session/state-machine.d.ts.map +1 -0
  97. package/dist/session/state-machine.js +345 -0
  98. package/dist/session/state-machine.js.map +1 -0
  99. package/dist/store/checkpoint-store.d.ts +59 -0
  100. package/dist/store/checkpoint-store.d.ts.map +1 -0
  101. package/dist/store/checkpoint-store.js +321 -0
  102. package/dist/store/checkpoint-store.js.map +1 -0
  103. package/dist/store/native-store.d.ts +14 -0
  104. package/dist/store/native-store.d.ts.map +1 -0
  105. package/dist/store/native-store.js +159 -0
  106. package/dist/store/native-store.js.map +1 -0
  107. package/dist/store/provider-types.d.ts +78 -0
  108. package/dist/store/provider-types.d.ts.map +1 -0
  109. package/dist/store/provider-types.js +12 -0
  110. package/dist/store/provider-types.js.map +1 -0
  111. package/dist/store/session-store.d.ts +36 -0
  112. package/dist/store/session-store.d.ts.map +1 -0
  113. package/dist/store/session-store.js +193 -0
  114. package/dist/store/session-store.js.map +1 -0
  115. package/dist/strategy/attribution.d.ts +39 -0
  116. package/dist/strategy/attribution.d.ts.map +1 -0
  117. package/dist/strategy/attribution.js +225 -0
  118. package/dist/strategy/attribution.js.map +1 -0
  119. package/dist/strategy/common.d.ts +57 -0
  120. package/dist/strategy/common.d.ts.map +1 -0
  121. package/dist/strategy/common.js +156 -0
  122. package/dist/strategy/common.js.map +1 -0
  123. package/dist/strategy/content-overlap.d.ts +33 -0
  124. package/dist/strategy/content-overlap.d.ts.map +1 -0
  125. package/dist/strategy/content-overlap.js +176 -0
  126. package/dist/strategy/content-overlap.js.map +1 -0
  127. package/dist/strategy/manual-commit.d.ts +36 -0
  128. package/dist/strategy/manual-commit.d.ts.map +1 -0
  129. package/dist/strategy/manual-commit.js +717 -0
  130. package/dist/strategy/manual-commit.js.map +1 -0
  131. package/dist/strategy/types.d.ts +163 -0
  132. package/dist/strategy/types.d.ts.map +1 -0
  133. package/dist/strategy/types.js +48 -0
  134. package/dist/strategy/types.js.map +1 -0
  135. package/dist/summarize/claude-generator.d.ts +25 -0
  136. package/dist/summarize/claude-generator.d.ts.map +1 -0
  137. package/dist/summarize/claude-generator.js +87 -0
  138. package/dist/summarize/claude-generator.js.map +1 -0
  139. package/dist/summarize/summarize.d.ts +52 -0
  140. package/dist/summarize/summarize.d.ts.map +1 -0
  141. package/dist/summarize/summarize.js +335 -0
  142. package/dist/summarize/summarize.js.map +1 -0
  143. package/dist/types.d.ts +293 -0
  144. package/dist/types.d.ts.map +1 -0
  145. package/dist/types.js +94 -0
  146. package/dist/types.js.map +1 -0
  147. package/dist/utils/chunk-files.d.ts +25 -0
  148. package/dist/utils/chunk-files.d.ts.map +1 -0
  149. package/dist/utils/chunk-files.js +47 -0
  150. package/dist/utils/chunk-files.js.map +1 -0
  151. package/dist/utils/commit-message.d.ts +11 -0
  152. package/dist/utils/commit-message.d.ts.map +1 -0
  153. package/dist/utils/commit-message.js +54 -0
  154. package/dist/utils/commit-message.js.map +1 -0
  155. package/dist/utils/detect-agent.d.ts +19 -0
  156. package/dist/utils/detect-agent.d.ts.map +1 -0
  157. package/dist/utils/detect-agent.js +34 -0
  158. package/dist/utils/detect-agent.js.map +1 -0
  159. package/dist/utils/hook-managers.d.ts +24 -0
  160. package/dist/utils/hook-managers.d.ts.map +1 -0
  161. package/dist/utils/hook-managers.js +96 -0
  162. package/dist/utils/hook-managers.js.map +1 -0
  163. package/dist/utils/ide-tags.d.ts +12 -0
  164. package/dist/utils/ide-tags.d.ts.map +1 -0
  165. package/dist/utils/ide-tags.js +30 -0
  166. package/dist/utils/ide-tags.js.map +1 -0
  167. package/dist/utils/paths.d.ts +32 -0
  168. package/dist/utils/paths.d.ts.map +1 -0
  169. package/dist/utils/paths.js +55 -0
  170. package/dist/utils/paths.js.map +1 -0
  171. package/dist/utils/preview-rewind.d.ts +23 -0
  172. package/dist/utils/preview-rewind.d.ts.map +1 -0
  173. package/dist/utils/preview-rewind.js +63 -0
  174. package/dist/utils/preview-rewind.js.map +1 -0
  175. package/dist/utils/rewind-conflict.d.ts +52 -0
  176. package/dist/utils/rewind-conflict.d.ts.map +1 -0
  177. package/dist/utils/rewind-conflict.js +79 -0
  178. package/dist/utils/rewind-conflict.js.map +1 -0
  179. package/dist/utils/shadow-branch.d.ts +44 -0
  180. package/dist/utils/shadow-branch.d.ts.map +1 -0
  181. package/dist/utils/shadow-branch.js +93 -0
  182. package/dist/utils/shadow-branch.js.map +1 -0
  183. package/dist/utils/string-utils.d.ts +24 -0
  184. package/dist/utils/string-utils.d.ts.map +1 -0
  185. package/dist/utils/string-utils.js +47 -0
  186. package/dist/utils/string-utils.js.map +1 -0
  187. package/dist/utils/todo-extract.d.ts +52 -0
  188. package/dist/utils/todo-extract.d.ts.map +1 -0
  189. package/dist/utils/todo-extract.js +167 -0
  190. package/dist/utils/todo-extract.js.map +1 -0
  191. package/dist/utils/trailers.d.ts +36 -0
  192. package/dist/utils/trailers.d.ts.map +1 -0
  193. package/dist/utils/trailers.js +148 -0
  194. package/dist/utils/trailers.js.map +1 -0
  195. package/dist/utils/transcript-parse.d.ts +57 -0
  196. package/dist/utils/transcript-parse.d.ts.map +1 -0
  197. package/dist/utils/transcript-parse.js +126 -0
  198. package/dist/utils/transcript-parse.js.map +1 -0
  199. package/dist/utils/transcript-timestamp.d.ts +22 -0
  200. package/dist/utils/transcript-timestamp.d.ts.map +1 -0
  201. package/dist/utils/transcript-timestamp.js +56 -0
  202. package/dist/utils/transcript-timestamp.js.map +1 -0
  203. package/dist/utils/tree-ops.d.ts +47 -0
  204. package/dist/utils/tree-ops.d.ts.map +1 -0
  205. package/dist/utils/tree-ops.js +145 -0
  206. package/dist/utils/tree-ops.js.map +1 -0
  207. package/dist/utils/tty.d.ts +25 -0
  208. package/dist/utils/tty.d.ts.map +1 -0
  209. package/dist/utils/tty.js +70 -0
  210. package/dist/utils/tty.js.map +1 -0
  211. package/dist/utils/validation.d.ts +31 -0
  212. package/dist/utils/validation.d.ts.map +1 -0
  213. package/dist/utils/validation.js +59 -0
  214. package/dist/utils/validation.js.map +1 -0
  215. package/dist/utils/worktree.d.ts +16 -0
  216. package/dist/utils/worktree.d.ts.map +1 -0
  217. package/dist/utils/worktree.js +50 -0
  218. package/dist/utils/worktree.js.map +1 -0
  219. package/package.json +64 -0
@@ -0,0 +1,423 @@
1
+ /**
2
+ * OpenCode Agent
3
+ *
4
+ * Implementation of the Entire agent interface for OpenCode.
5
+ * Handles JSON export format with messages array, OpenCode-specific
6
+ * plugin-based hook installation, and session lifecycle management.
7
+ *
8
+ * OpenCode uses `opencode export` CLI command for transcript access.
9
+ * Sessions are stored in JSON format: { info: {...}, messages: [...] }
10
+ */
11
+ import * as fs from 'node:fs';
12
+ import * as path from 'node:path';
13
+ import * as os from 'node:os';
14
+ import { AGENT_NAMES, AGENT_TYPES, EventType, emptyTokenUsage, } from '../../types.js';
15
+ import { registerAgent } from '../registry.js';
16
+ // ============================================================================
17
+ // Constants
18
+ // ============================================================================
19
+ const OPENCODE_DIR = '.opencode';
20
+ const HOOK_NAMES = [
21
+ 'session-start',
22
+ 'session-end',
23
+ 'turn-start',
24
+ 'turn-end',
25
+ 'compaction',
26
+ ];
27
+ /** Tools that modify files in OpenCode */
28
+ const FILE_MODIFICATION_TOOLS = new Set(['edit', 'write', 'patch']);
29
+ const ENTIRE_PLUGIN_MARKER = 'Auto-generated by `entire enable --agent opencode`';
30
+ // ============================================================================
31
+ // OpenCode Agent Implementation
32
+ // ============================================================================
33
+ class OpenCodeAgent {
34
+ name = AGENT_NAMES.OPENCODE;
35
+ type = AGENT_TYPES.OPENCODE;
36
+ description = 'OpenCode - AI-powered terminal coding agent';
37
+ isPreview = true;
38
+ protectedDirs = [OPENCODE_DIR];
39
+ async detectPresence(cwd) {
40
+ const repoRoot = cwd ?? process.cwd();
41
+ try {
42
+ await fs.promises.stat(path.join(repoRoot, OPENCODE_DIR));
43
+ return true;
44
+ }
45
+ catch {
46
+ try {
47
+ await fs.promises.stat(path.join(repoRoot, 'opencode.json'));
48
+ return true;
49
+ }
50
+ catch {
51
+ return false;
52
+ }
53
+ }
54
+ }
55
+ async getSessionDir(repoPath) {
56
+ if (process.env.ENTIRE_TEST_OPENCODE_PROJECT_DIR) {
57
+ return process.env.ENTIRE_TEST_OPENCODE_PROJECT_DIR;
58
+ }
59
+ const projectDir = sanitizePathForOpenCode(repoPath);
60
+ return path.join(os.tmpdir(), 'entire-opencode', projectDir);
61
+ }
62
+ getSessionID(input) {
63
+ return input.sessionID;
64
+ }
65
+ resolveSessionFile(sessionDir, agentSessionID) {
66
+ return path.join(sessionDir, `${agentSessionID}.json`);
67
+ }
68
+ async readTranscript(sessionRef) {
69
+ return fs.promises.readFile(sessionRef);
70
+ }
71
+ formatResumeCommand(sessionID) {
72
+ if (!sessionID.trim())
73
+ return 'opencode';
74
+ return `opencode -s ${sessionID}`;
75
+ }
76
+ // ===========================================================================
77
+ // HookSupport
78
+ // ===========================================================================
79
+ hookNames() {
80
+ return [...HOOK_NAMES];
81
+ }
82
+ parseHookEvent(hookName, stdin) {
83
+ try {
84
+ const data = JSON.parse(stdin);
85
+ const sessionID = String(data.session_id ?? data.sessionID ?? '');
86
+ switch (hookName) {
87
+ case 'session-start':
88
+ return {
89
+ type: EventType.SessionStart,
90
+ sessionID,
91
+ sessionRef: '',
92
+ timestamp: new Date(),
93
+ };
94
+ case 'turn-start':
95
+ return {
96
+ type: EventType.TurnStart,
97
+ sessionID,
98
+ sessionRef: '',
99
+ prompt: String(data.prompt ?? ''),
100
+ timestamp: new Date(),
101
+ };
102
+ case 'turn-end':
103
+ return {
104
+ type: EventType.TurnEnd,
105
+ sessionID,
106
+ sessionRef: '',
107
+ timestamp: new Date(),
108
+ };
109
+ case 'compaction':
110
+ return {
111
+ type: EventType.Compaction,
112
+ sessionID,
113
+ sessionRef: '',
114
+ timestamp: new Date(),
115
+ };
116
+ case 'session-end':
117
+ return {
118
+ type: EventType.SessionEnd,
119
+ sessionID,
120
+ sessionRef: '',
121
+ timestamp: new Date(),
122
+ };
123
+ default:
124
+ return null;
125
+ }
126
+ }
127
+ catch {
128
+ return null;
129
+ }
130
+ }
131
+ async installHooks(repoPath, force = false) {
132
+ const pluginPath = path.join(repoPath, OPENCODE_DIR, 'plugins', 'entire.ts');
133
+ // Check if already installed
134
+ if (!force) {
135
+ try {
136
+ const content = await fs.promises.readFile(pluginPath, 'utf-8');
137
+ if (content.includes(ENTIRE_PLUGIN_MARKER))
138
+ return 0;
139
+ }
140
+ catch {
141
+ // File doesn't exist, proceed with install
142
+ }
143
+ }
144
+ // Create plugin directory
145
+ await fs.promises.mkdir(path.dirname(pluginPath), { recursive: true });
146
+ // Write the plugin file
147
+ const pluginContent = generateOpenCodePlugin();
148
+ await fs.promises.writeFile(pluginPath, pluginContent, 'utf-8');
149
+ return 5; // 5 lifecycle hooks
150
+ }
151
+ async uninstallHooks(repoPath) {
152
+ const pluginPath = path.join(repoPath, OPENCODE_DIR, 'plugins', 'entire.ts');
153
+ try {
154
+ const content = await fs.promises.readFile(pluginPath, 'utf-8');
155
+ if (content.includes(ENTIRE_PLUGIN_MARKER)) {
156
+ await fs.promises.unlink(pluginPath);
157
+ }
158
+ }
159
+ catch {
160
+ // File doesn't exist
161
+ }
162
+ }
163
+ async areHooksInstalled(repoPath) {
164
+ const pluginPath = path.join(repoPath, OPENCODE_DIR, 'plugins', 'entire.ts');
165
+ try {
166
+ const content = await fs.promises.readFile(pluginPath, 'utf-8');
167
+ return content.includes(ENTIRE_PLUGIN_MARKER);
168
+ }
169
+ catch {
170
+ return false;
171
+ }
172
+ }
173
+ // ===========================================================================
174
+ // TranscriptAnalyzer
175
+ // ===========================================================================
176
+ async getTranscriptPosition(transcriptPath) {
177
+ try {
178
+ const data = await fs.promises.readFile(transcriptPath, 'utf-8');
179
+ const session = JSON.parse(data);
180
+ return session.messages?.length ?? 0;
181
+ }
182
+ catch {
183
+ return 0;
184
+ }
185
+ }
186
+ async extractModifiedFilesFromOffset(transcriptPath, startOffset) {
187
+ const data = await fs.promises.readFile(transcriptPath, 'utf-8');
188
+ const session = JSON.parse(data);
189
+ const files = new Set();
190
+ for (let i = startOffset; i < session.messages.length; i++) {
191
+ const msg = session.messages[i];
192
+ if (msg.info.role !== 'assistant')
193
+ continue;
194
+ for (const part of msg.parts) {
195
+ if (part.type !== 'tool' || !part.state)
196
+ continue;
197
+ if (!FILE_MODIFICATION_TOOLS.has(part.tool ?? ''))
198
+ continue;
199
+ const filePath = extractOpenCodeFilePath(part.state.input ?? {});
200
+ if (filePath)
201
+ files.add(filePath);
202
+ }
203
+ }
204
+ return { files: Array.from(files), currentPosition: session.messages.length };
205
+ }
206
+ async extractPrompts(sessionRef, fromOffset) {
207
+ const data = await fs.promises.readFile(sessionRef, 'utf-8');
208
+ const session = JSON.parse(data);
209
+ const prompts = [];
210
+ for (let i = fromOffset; i < session.messages.length; i++) {
211
+ const msg = session.messages[i];
212
+ if (msg.info.role !== 'user')
213
+ continue;
214
+ const content = extractTextFromParts(msg.parts);
215
+ if (content)
216
+ prompts.push(content);
217
+ }
218
+ return prompts;
219
+ }
220
+ async extractSummary(sessionRef) {
221
+ const data = await fs.promises.readFile(sessionRef, 'utf-8');
222
+ const session = JSON.parse(data);
223
+ for (let i = session.messages.length - 1; i >= 0; i--) {
224
+ const msg = session.messages[i];
225
+ if (msg.info.role === 'assistant') {
226
+ const content = extractTextFromParts(msg.parts);
227
+ if (content)
228
+ return content;
229
+ }
230
+ }
231
+ return '';
232
+ }
233
+ // ===========================================================================
234
+ // TokenCalculator
235
+ // ===========================================================================
236
+ async calculateTokenUsage(transcriptData, fromOffset) {
237
+ const usage = emptyTokenUsage();
238
+ try {
239
+ const session = JSON.parse(transcriptData.toString('utf-8'));
240
+ for (let i = fromOffset; i < session.messages.length; i++) {
241
+ const msg = session.messages[i];
242
+ if (msg.info.role !== 'assistant' || !msg.info.tokens)
243
+ continue;
244
+ usage.inputTokens += msg.info.tokens.input ?? 0;
245
+ usage.outputTokens += msg.info.tokens.output ?? 0;
246
+ usage.cacheReadTokens += msg.info.tokens.cache?.read ?? 0;
247
+ usage.cacheCreationTokens += msg.info.tokens.cache?.write ?? 0;
248
+ usage.apiCallCount++;
249
+ }
250
+ }
251
+ catch {
252
+ // Invalid transcript data
253
+ }
254
+ return usage;
255
+ }
256
+ // ===========================================================================
257
+ // TranscriptChunker
258
+ // ===========================================================================
259
+ async chunkTranscript(content, maxSize) {
260
+ try {
261
+ const session = JSON.parse(content.toString('utf-8'));
262
+ if (!session.messages?.length)
263
+ return [content];
264
+ const infoStr = JSON.stringify(session.info);
265
+ const baseSize = Buffer.byteLength(`{"info":${infoStr},"messages":[]}`);
266
+ const chunks = [];
267
+ let currentMessages = [];
268
+ let currentSize = baseSize;
269
+ for (const msg of session.messages) {
270
+ const msgStr = JSON.stringify(msg);
271
+ const msgSize = Buffer.byteLength(msgStr) + 1; // +1 for comma
272
+ if (currentSize + msgSize > maxSize && currentMessages.length > 0) {
273
+ chunks.push(Buffer.from(JSON.stringify({ info: session.info, messages: currentMessages })));
274
+ currentMessages = [];
275
+ currentSize = baseSize;
276
+ }
277
+ currentMessages.push(msg);
278
+ currentSize += msgSize;
279
+ }
280
+ if (currentMessages.length > 0) {
281
+ chunks.push(Buffer.from(JSON.stringify({ info: session.info, messages: currentMessages })));
282
+ }
283
+ return chunks.length > 0 ? chunks : [content];
284
+ }
285
+ catch {
286
+ return [content];
287
+ }
288
+ }
289
+ async reassembleTranscript(chunks) {
290
+ const allMessages = [];
291
+ let sessionInfo;
292
+ for (const chunk of chunks) {
293
+ const session = JSON.parse(chunk.toString('utf-8'));
294
+ if (!sessionInfo)
295
+ sessionInfo = session.info;
296
+ allMessages.push(...(session.messages ?? []));
297
+ }
298
+ return Buffer.from(JSON.stringify({ info: sessionInfo ?? { id: '' }, messages: allMessages }));
299
+ }
300
+ }
301
+ // ============================================================================
302
+ // Helpers
303
+ // ============================================================================
304
+ const nonAlphanumericRegex = /[^a-zA-Z0-9]/g;
305
+ function sanitizePathForOpenCode(repoPath) {
306
+ return repoPath.replace(nonAlphanumericRegex, '-');
307
+ }
308
+ function extractOpenCodeFilePath(input) {
309
+ for (const key of ['filePath', 'path']) {
310
+ if (typeof input[key] === 'string' && input[key])
311
+ return input[key];
312
+ }
313
+ return '';
314
+ }
315
+ /**
316
+ * Extract text content from OpenCode message parts.
317
+ */
318
+ export function extractTextFromParts(parts) {
319
+ const texts = [];
320
+ for (const part of parts) {
321
+ if (part.type === 'text' && part.text) {
322
+ texts.push(part.text);
323
+ }
324
+ }
325
+ return texts.join('\n');
326
+ }
327
+ /**
328
+ * Parse an OpenCode export session from raw bytes.
329
+ */
330
+ export function parseExportSession(data) {
331
+ const str = typeof data === 'string' ? data : data.toString('utf-8');
332
+ if (!str.trim())
333
+ return null;
334
+ return JSON.parse(str);
335
+ }
336
+ /**
337
+ * Extract all user prompts from raw export JSON.
338
+ */
339
+ export function extractAllUserPrompts(data) {
340
+ const session = parseExportSession(data);
341
+ if (!session)
342
+ return [];
343
+ const prompts = [];
344
+ for (const msg of session.messages) {
345
+ if (msg.info.role !== 'user')
346
+ continue;
347
+ const content = extractTextFromParts(msg.parts);
348
+ if (content)
349
+ prompts.push(content);
350
+ }
351
+ return prompts;
352
+ }
353
+ /**
354
+ * Generate the OpenCode plugin TypeScript source.
355
+ */
356
+ function generateOpenCodePlugin() {
357
+ return `// ${ENTIRE_PLUGIN_MARKER}
358
+ // This plugin integrates OpenCode with Entire for session tracking.
359
+ // Do not edit manually.
360
+
361
+ import type { Plugin } from "opencode";
362
+
363
+ const plugin: Plugin = {
364
+ name: "entire",
365
+ hooks: {
366
+ "session.start": async ({ session }) => {
367
+ const payload = JSON.stringify({ session_id: session.id });
368
+ const proc = Bun.spawn(["entire", "hooks", "opencode", "session-start"], {
369
+ stdin: new Blob([payload]),
370
+ stdout: "ignore",
371
+ stderr: "ignore",
372
+ });
373
+ await proc.exited;
374
+ },
375
+ "session.end": async ({ session }) => {
376
+ const payload = JSON.stringify({ session_id: session.id });
377
+ const proc = Bun.spawn(["entire", "hooks", "opencode", "session-end"], {
378
+ stdin: new Blob([payload]),
379
+ stdout: "ignore",
380
+ stderr: "ignore",
381
+ });
382
+ await proc.exited;
383
+ },
384
+ "message.create": async ({ message, session }) => {
385
+ if (message.role === "user") {
386
+ const text = message.parts
387
+ .filter((p: { type: string }) => p.type === "text")
388
+ .map((p: { text: string }) => p.text)
389
+ .join("\\n");
390
+ const payload = JSON.stringify({ session_id: session.id, prompt: text });
391
+ const proc = Bun.spawn(["entire", "hooks", "opencode", "turn-start"], {
392
+ stdin: new Blob([payload]),
393
+ stdout: "ignore",
394
+ stderr: "ignore",
395
+ });
396
+ await proc.exited;
397
+ }
398
+ },
399
+ "message.complete": async ({ message, session }) => {
400
+ if (message.role === "assistant") {
401
+ const payload = JSON.stringify({ session_id: session.id });
402
+ const proc = Bun.spawn(["entire", "hooks", "opencode", "turn-end"], {
403
+ stdin: new Blob([payload]),
404
+ stdout: "ignore",
405
+ stderr: "ignore",
406
+ });
407
+ await proc.exited;
408
+ }
409
+ },
410
+ },
411
+ };
412
+
413
+ export default plugin;
414
+ `;
415
+ }
416
+ // ============================================================================
417
+ // Registration
418
+ // ============================================================================
419
+ export function createOpenCodeAgent() {
420
+ return new OpenCodeAgent();
421
+ }
422
+ registerAgent(AGENT_NAMES.OPENCODE, () => new OpenCodeAgent());
423
+ //# sourceMappingURL=opencode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode.js","sourceRoot":"","sources":["../../../src/agent/agents/opencode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Agent Registry
3
+ *
4
+ * Central registry for AI agent implementations. Agents register
5
+ * themselves via factory functions and are discovered at runtime.
6
+ */
7
+ import type { AgentName, AgentType } from '../types.js';
8
+ import type { Agent } from './types.js';
9
+ export type AgentFactory = () => Agent;
10
+ /**
11
+ * Register an agent factory
12
+ */
13
+ export declare function registerAgent(name: AgentName, factory: AgentFactory): void;
14
+ /**
15
+ * Get an agent by name
16
+ */
17
+ export declare function getAgent(name: AgentName): Agent | null;
18
+ /**
19
+ * List all registered agent names (sorted)
20
+ */
21
+ export declare function listAgentNames(): AgentName[];
22
+ /**
23
+ * Get all registered agents
24
+ */
25
+ export declare function listAgents(): Agent[];
26
+ /**
27
+ * Detect which agents are present in the current environment
28
+ */
29
+ export declare function detectAgents(cwd?: string): Promise<Agent[]>;
30
+ /**
31
+ * Auto-detect the first present agent
32
+ */
33
+ export declare function detectAgent(cwd?: string): Promise<Agent | null>;
34
+ /**
35
+ * Get an agent by its human-readable type
36
+ */
37
+ export declare function getAgentByType(agentType: AgentType): Agent | null;
38
+ /**
39
+ * Get the default agent
40
+ */
41
+ export declare function getDefaultAgent(): Agent | null;
42
+ /**
43
+ * Get the union of all protected directories across all agents
44
+ */
45
+ export declare function allProtectedDirs(): string[];
46
+ /**
47
+ * Resolve an agent name, trying exact match then type match
48
+ */
49
+ export declare function resolveAgent(nameOrType: string): Agent | null;
50
+ /**
51
+ * Reset the registry (for testing)
52
+ */
53
+ export declare function resetRegistry(): void;
54
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/agent/registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAMxC,MAAM,MAAM,YAAY,GAAG,MAAM,KAAK,CAAC;AASvC;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI,CAG1E;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,KAAK,GAAG,IAAI,CAUtD;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,SAAS,EAAE,CAE5C;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,KAAK,EAAE,CAEpC;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CAgBjE;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAGrE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,SAAS,GAAG,KAAK,GAAG,IAAI,CAMjE;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,KAAK,GAAG,IAAI,CAE9C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAW3C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAO7D;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAGpC"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Agent Registry
3
+ *
4
+ * Central registry for AI agent implementations. Agents register
5
+ * themselves via factory functions and are discovered at runtime.
6
+ */
7
+ import { DEFAULT_AGENT_NAME } from '../types.js';
8
+ // ============================================================================
9
+ // Registry
10
+ // ============================================================================
11
+ const agents = new Map();
12
+ let cachedInstances = new Map();
13
+ /**
14
+ * Register an agent factory
15
+ */
16
+ export function registerAgent(name, factory) {
17
+ agents.set(name, factory);
18
+ cachedInstances.delete(name);
19
+ }
20
+ /**
21
+ * Get an agent by name
22
+ */
23
+ export function getAgent(name) {
24
+ const cached = cachedInstances.get(name);
25
+ if (cached)
26
+ return cached;
27
+ const factory = agents.get(name);
28
+ if (!factory)
29
+ return null;
30
+ const instance = factory();
31
+ cachedInstances.set(name, instance);
32
+ return instance;
33
+ }
34
+ /**
35
+ * List all registered agent names (sorted)
36
+ */
37
+ export function listAgentNames() {
38
+ return Array.from(agents.keys()).sort();
39
+ }
40
+ /**
41
+ * Get all registered agents
42
+ */
43
+ export function listAgents() {
44
+ return listAgentNames().map((name) => getAgent(name));
45
+ }
46
+ /**
47
+ * Detect which agents are present in the current environment
48
+ */
49
+ export async function detectAgents(cwd) {
50
+ const detected = [];
51
+ for (const name of listAgentNames()) {
52
+ const agent = getAgent(name);
53
+ if (!agent)
54
+ continue;
55
+ try {
56
+ const present = await agent.detectPresence(cwd);
57
+ if (present)
58
+ detected.push(agent);
59
+ }
60
+ catch {
61
+ // Skip agents that fail detection
62
+ }
63
+ }
64
+ return detected;
65
+ }
66
+ /**
67
+ * Auto-detect the first present agent
68
+ */
69
+ export async function detectAgent(cwd) {
70
+ const agents = await detectAgents(cwd);
71
+ return agents[0] ?? null;
72
+ }
73
+ /**
74
+ * Get an agent by its human-readable type
75
+ */
76
+ export function getAgentByType(agentType) {
77
+ for (const name of listAgentNames()) {
78
+ const agent = getAgent(name);
79
+ if (agent && agent.type === agentType)
80
+ return agent;
81
+ }
82
+ return null;
83
+ }
84
+ /**
85
+ * Get the default agent
86
+ */
87
+ export function getDefaultAgent() {
88
+ return getAgent(DEFAULT_AGENT_NAME);
89
+ }
90
+ /**
91
+ * Get the union of all protected directories across all agents
92
+ */
93
+ export function allProtectedDirs() {
94
+ const dirs = new Set();
95
+ for (const name of listAgentNames()) {
96
+ const agent = getAgent(name);
97
+ if (agent) {
98
+ for (const dir of agent.protectedDirs) {
99
+ dirs.add(dir);
100
+ }
101
+ }
102
+ }
103
+ return Array.from(dirs);
104
+ }
105
+ /**
106
+ * Resolve an agent name, trying exact match then type match
107
+ */
108
+ export function resolveAgent(nameOrType) {
109
+ // Try exact name match
110
+ const byName = getAgent(nameOrType);
111
+ if (byName)
112
+ return byName;
113
+ // Try type match
114
+ return getAgentByType(nameOrType);
115
+ }
116
+ /**
117
+ * Reset the registry (for testing)
118
+ */
119
+ export function resetRegistry() {
120
+ agents.clear();
121
+ cachedInstances = new Map();
122
+ }
123
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/agent/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Normalized Agent Session Type
3
+ *
4
+ * A shared, agent-agnostic representation of a coding session with typed
5
+ * entries. This provides a uniform interface for cross-agent operations.
6
+ *
7
+ * Ported from Go: agent/session.go
8
+ */
9
+ import type { AgentType } from '../types.js';
10
+ export declare const enum EntryType {
11
+ User = "user",
12
+ Assistant = "assistant",
13
+ Tool = "tool",
14
+ System = "system"
15
+ }
16
+ export interface SessionEntry {
17
+ type: EntryType;
18
+ uuid?: string;
19
+ timestamp?: string;
20
+ text?: string;
21
+ toolName?: string;
22
+ toolInput?: unknown;
23
+ toolResult?: unknown;
24
+ }
25
+ export interface AgentSession {
26
+ readonly agentType: AgentType;
27
+ readonly sessionID: string;
28
+ readonly entries: SessionEntry[];
29
+ /** Get the last user prompt text */
30
+ getLastUserPrompt(): string;
31
+ /** Get all user prompts */
32
+ getUserPrompts(): string[];
33
+ /** Get the total number of entries */
34
+ length(): number;
35
+ /** Truncate the session at a specific UUID (for partial replay) */
36
+ truncateAtUUID(uuid: string): AgentSession;
37
+ /** Find the tool result entry for a given tool use UUID */
38
+ findToolResultByUUID(uuid: string): SessionEntry | undefined;
39
+ /** Get all entries of a specific type */
40
+ getEntriesByType(type: EntryType): SessionEntry[];
41
+ /** Get entries from a specific offset */
42
+ slice(fromOffset: number): SessionEntry[];
43
+ }
44
+ export declare function createAgentSession(agentType: AgentType, sessionID: string, entries: SessionEntry[]): AgentSession;
45
+ //# sourceMappingURL=session-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-types.d.ts","sourceRoot":"","sources":["../../src/agent/session-types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAM7C,0BAAkB,SAAS;IACzB,IAAI,SAAS;IACb,SAAS,cAAc;IACvB,IAAI,SAAS;IACb,MAAM,WAAW;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAMD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,YAAY,EAAE,CAAC;IAEjC,oCAAoC;IACpC,iBAAiB,IAAI,MAAM,CAAC;IAE5B,2BAA2B;IAC3B,cAAc,IAAI,MAAM,EAAE,CAAC;IAE3B,sCAAsC;IACtC,MAAM,IAAI,MAAM,CAAC;IAEjB,mEAAmE;IACnE,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAAC;IAE3C,2DAA2D;IAC3D,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAAC;IAE7D,yCAAyC;IACzC,gBAAgB,CAAC,IAAI,EAAE,SAAS,GAAG,YAAY,EAAE,CAAC;IAElD,yCAAyC;IACzC,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,YAAY,EAAE,CAAC;CAC3C;AAMD,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,YAAY,EAAE,GACtB,YAAY,CAyCd"}