@ob1-sg/horizon 0.1.10 → 0.1.11

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 (153) hide show
  1. package/dist/cli.d.ts +3 -0
  2. package/dist/cli.d.ts.map +1 -0
  3. package/dist/cli.js +43 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/config.d.ts +10 -0
  6. package/dist/config.d.ts.map +1 -0
  7. package/dist/config.js +293 -0
  8. package/dist/config.js.map +1 -0
  9. package/dist/index.d.ts +4 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +629 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/lib/__tests__/attachment-downloader.test.d.ts +2 -0
  14. package/dist/lib/__tests__/attachment-downloader.test.d.ts.map +1 -0
  15. package/dist/lib/__tests__/attachment-downloader.test.js +163 -0
  16. package/dist/lib/__tests__/attachment-downloader.test.js.map +1 -0
  17. package/dist/lib/__tests__/cli-detection.test.d.ts +2 -0
  18. package/dist/lib/__tests__/cli-detection.test.d.ts.map +1 -0
  19. package/dist/lib/__tests__/cli-detection.test.js +119 -0
  20. package/dist/lib/__tests__/cli-detection.test.js.map +1 -0
  21. package/dist/lib/__tests__/config.test.d.ts +2 -0
  22. package/dist/lib/__tests__/config.test.d.ts.map +1 -0
  23. package/dist/lib/__tests__/config.test.js +291 -0
  24. package/dist/lib/__tests__/config.test.js.map +1 -0
  25. package/dist/lib/__tests__/gcp.test.d.ts +2 -0
  26. package/dist/lib/__tests__/gcp.test.d.ts.map +1 -0
  27. package/dist/lib/__tests__/gcp.test.js +104 -0
  28. package/dist/lib/__tests__/gcp.test.js.map +1 -0
  29. package/dist/lib/__tests__/git.test.d.ts +2 -0
  30. package/dist/lib/__tests__/git.test.d.ts.map +1 -0
  31. package/dist/lib/__tests__/git.test.js +62 -0
  32. package/dist/lib/__tests__/git.test.js.map +1 -0
  33. package/dist/lib/__tests__/linear-quick-check.test.d.ts +2 -0
  34. package/dist/lib/__tests__/linear-quick-check.test.d.ts.map +1 -0
  35. package/dist/lib/__tests__/linear-quick-check.test.js +152 -0
  36. package/dist/lib/__tests__/linear-quick-check.test.js.map +1 -0
  37. package/dist/lib/__tests__/loop-instance-name.test.d.ts +2 -0
  38. package/dist/lib/__tests__/loop-instance-name.test.d.ts.map +1 -0
  39. package/dist/lib/__tests__/loop-instance-name.test.js +90 -0
  40. package/dist/lib/__tests__/loop-instance-name.test.js.map +1 -0
  41. package/dist/lib/__tests__/output-logger.test.d.ts +2 -0
  42. package/dist/lib/__tests__/output-logger.test.d.ts.map +1 -0
  43. package/dist/lib/__tests__/output-logger.test.js +136 -0
  44. package/dist/lib/__tests__/output-logger.test.js.map +1 -0
  45. package/dist/lib/__tests__/prompts.test.d.ts +2 -0
  46. package/dist/lib/__tests__/prompts.test.d.ts.map +1 -0
  47. package/dist/lib/__tests__/prompts.test.js +70 -0
  48. package/dist/lib/__tests__/prompts.test.js.map +1 -0
  49. package/dist/lib/__tests__/provider.test.d.ts +2 -0
  50. package/dist/lib/__tests__/provider.test.d.ts.map +1 -0
  51. package/dist/lib/__tests__/provider.test.js +89 -0
  52. package/dist/lib/__tests__/provider.test.js.map +1 -0
  53. package/dist/lib/__tests__/rate-limit.test.d.ts +2 -0
  54. package/dist/lib/__tests__/rate-limit.test.d.ts.map +1 -0
  55. package/dist/lib/__tests__/rate-limit.test.js +275 -0
  56. package/dist/lib/__tests__/rate-limit.test.js.map +1 -0
  57. package/dist/lib/__tests__/readline.test.d.ts +2 -0
  58. package/dist/lib/__tests__/readline.test.d.ts.map +1 -0
  59. package/dist/lib/__tests__/readline.test.js +55 -0
  60. package/dist/lib/__tests__/readline.test.js.map +1 -0
  61. package/dist/lib/__tests__/stats-logger.test.d.ts +2 -0
  62. package/dist/lib/__tests__/stats-logger.test.d.ts.map +1 -0
  63. package/dist/lib/__tests__/stats-logger.test.js +297 -0
  64. package/dist/lib/__tests__/stats-logger.test.js.map +1 -0
  65. package/dist/lib/__tests__/update-checker.test.d.ts +2 -0
  66. package/dist/lib/__tests__/update-checker.test.d.ts.map +1 -0
  67. package/dist/lib/__tests__/update-checker.test.js +141 -0
  68. package/dist/lib/__tests__/update-checker.test.js.map +1 -0
  69. package/dist/lib/__tests__/version.test.d.ts +2 -0
  70. package/dist/lib/__tests__/version.test.d.ts.map +1 -0
  71. package/dist/lib/__tests__/version.test.js +51 -0
  72. package/dist/lib/__tests__/version.test.js.map +1 -0
  73. package/dist/lib/attachment-downloader.d.ts +26 -0
  74. package/dist/lib/attachment-downloader.d.ts.map +1 -0
  75. package/dist/lib/attachment-downloader.js +259 -0
  76. package/dist/lib/attachment-downloader.js.map +1 -0
  77. package/dist/lib/claude.d.ts +6 -0
  78. package/dist/lib/claude.d.ts.map +1 -0
  79. package/dist/lib/claude.js +358 -0
  80. package/dist/lib/claude.js.map +1 -0
  81. package/dist/lib/cli-detection.d.ts +25 -0
  82. package/dist/lib/cli-detection.d.ts.map +1 -0
  83. package/dist/lib/cli-detection.js +53 -0
  84. package/dist/lib/cli-detection.js.map +1 -0
  85. package/dist/lib/codex.d.ts +4 -0
  86. package/dist/lib/codex.d.ts.map +1 -0
  87. package/dist/lib/codex.js +285 -0
  88. package/dist/lib/codex.js.map +1 -0
  89. package/dist/lib/gcp.d.ts +21 -0
  90. package/dist/lib/gcp.d.ts.map +1 -0
  91. package/dist/lib/gcp.js +96 -0
  92. package/dist/lib/gcp.js.map +1 -0
  93. package/dist/lib/git.d.ts +3 -0
  94. package/dist/lib/git.d.ts.map +1 -0
  95. package/dist/lib/git.js +24 -0
  96. package/dist/lib/git.js.map +1 -0
  97. package/dist/lib/init-project.d.ts +13 -0
  98. package/dist/lib/init-project.d.ts.map +1 -0
  99. package/dist/lib/init-project.js +420 -0
  100. package/dist/lib/init-project.js.map +1 -0
  101. package/dist/lib/linear-api.d.ts +32 -0
  102. package/dist/lib/linear-api.d.ts.map +1 -0
  103. package/dist/lib/linear-api.js +267 -0
  104. package/dist/lib/linear-api.js.map +1 -0
  105. package/dist/lib/linear-quick-check.d.ts +13 -0
  106. package/dist/lib/linear-quick-check.d.ts.map +1 -0
  107. package/dist/lib/linear-quick-check.js +61 -0
  108. package/dist/lib/linear-quick-check.js.map +1 -0
  109. package/dist/lib/loop-instance-name.d.ts +29 -0
  110. package/dist/lib/loop-instance-name.d.ts.map +1 -0
  111. package/dist/lib/loop-instance-name.js +105 -0
  112. package/dist/lib/loop-instance-name.js.map +1 -0
  113. package/dist/lib/output-logger.d.ts +23 -0
  114. package/dist/lib/output-logger.d.ts.map +1 -0
  115. package/dist/lib/output-logger.js +104 -0
  116. package/dist/lib/output-logger.js.map +1 -0
  117. package/dist/lib/prompts.d.ts +17 -0
  118. package/dist/lib/prompts.d.ts.map +1 -0
  119. package/dist/lib/prompts.js +65 -0
  120. package/dist/lib/prompts.js.map +1 -0
  121. package/dist/lib/provider.d.ts +32 -0
  122. package/dist/lib/provider.d.ts.map +1 -0
  123. package/dist/lib/provider.js +27 -0
  124. package/dist/lib/provider.js.map +1 -0
  125. package/dist/lib/rate-limit.d.ts +14 -0
  126. package/dist/lib/rate-limit.d.ts.map +1 -0
  127. package/dist/lib/rate-limit.js +154 -0
  128. package/dist/lib/rate-limit.js.map +1 -0
  129. package/dist/lib/readline.d.ts +4 -0
  130. package/dist/lib/readline.d.ts.map +1 -0
  131. package/dist/lib/readline.js +39 -0
  132. package/dist/lib/readline.js.map +1 -0
  133. package/dist/lib/setup.d.ts +123 -0
  134. package/dist/lib/setup.d.ts.map +1 -0
  135. package/dist/lib/setup.js +492 -0
  136. package/dist/lib/setup.js.map +1 -0
  137. package/dist/lib/stats-logger.d.ts +92 -0
  138. package/dist/lib/stats-logger.d.ts.map +1 -0
  139. package/dist/lib/stats-logger.js +258 -0
  140. package/dist/lib/stats-logger.js.map +1 -0
  141. package/dist/lib/update-checker.d.ts +17 -0
  142. package/dist/lib/update-checker.d.ts.map +1 -0
  143. package/dist/lib/update-checker.js +140 -0
  144. package/dist/lib/update-checker.js.map +1 -0
  145. package/dist/lib/version.d.ts +10 -0
  146. package/dist/lib/version.d.ts.map +1 -0
  147. package/dist/lib/version.js +37 -0
  148. package/dist/lib/version.js.map +1 -0
  149. package/dist/types.d.ts +92 -0
  150. package/dist/types.d.ts.map +1 -0
  151. package/dist/types.js +3 -0
  152. package/dist/types.js.map +1 -0
  153. package/package.json +1 -1
@@ -0,0 +1,259 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import { getRepoRoot } from '../config.js';
4
+ // Pattern to match Linear upload URLs in markdown content
5
+ const LINEAR_UPLOAD_PATTERN = /https:\/\/uploads\.linear\.app\/[^\s\)\]"'<>]+/g;
6
+ // Pattern to match markdown image syntax with alt text: ![alt text](url)
7
+ const MARKDOWN_IMAGE_PATTERN = /!\[([^\]]*)\]\((https:\/\/uploads\.linear\.app\/[^\s\)]+)\)/g;
8
+ // Pattern to match markdown link syntax with link text: [link text](url)
9
+ const MARKDOWN_LINK_PATTERN = /\[([^\]]+)\]\((https:\/\/uploads\.linear\.app\/[^\s\)]+)\)/g;
10
+ // Size limit warning threshold (10MB)
11
+ const SIZE_WARNING_THRESHOLD = 10 * 1024 * 1024;
12
+ // Map Content-Type to file extension
13
+ const CONTENT_TYPE_TO_EXT = {
14
+ 'image/png': '.png',
15
+ 'image/jpeg': '.jpg',
16
+ 'image/jpg': '.jpg',
17
+ 'image/gif': '.gif',
18
+ 'image/webp': '.webp',
19
+ 'image/svg+xml': '.svg',
20
+ 'application/pdf': '.pdf',
21
+ 'text/plain': '.txt',
22
+ 'application/json': '.json',
23
+ 'application/zip': '.zip',
24
+ };
25
+ /**
26
+ * Extracts Linear upload URLs from markdown content (descriptions, comments, etc.)
27
+ * Preserves original filenames from markdown alt text (e.g., ![image.png](url))
28
+ */
29
+ export function extractLinearUrls(markdown) {
30
+ const seen = new Set();
31
+ const attachments = [];
32
+ // First, extract images with alt text (which contains the original filename)
33
+ // This gives us the best filename info: ![Screenshot 2026-01-27.png](url)
34
+ const imageMatches = [...markdown.matchAll(MARKDOWN_IMAGE_PATTERN)];
35
+ for (const match of imageMatches) {
36
+ const [, altText, url] = match;
37
+ if (seen.has(url))
38
+ continue;
39
+ seen.add(url);
40
+ // Use alt text as filename if it looks like a filename (has extension)
41
+ const filename = hasFileExtension(altText) ? altText : getFilenameFromUrl(url);
42
+ // Generate a unique ID from URL hash
43
+ const id = Buffer.from(url).toString('base64').slice(0, 12);
44
+ attachments.push({
45
+ id,
46
+ url,
47
+ filename: decodeURIComponent(filename),
48
+ source: 'embedded',
49
+ });
50
+ }
51
+ // Then extract markdown links: [filename.md](url)
52
+ const linkMatches = [...markdown.matchAll(MARKDOWN_LINK_PATTERN)];
53
+ for (const match of linkMatches) {
54
+ const [, linkText, url] = match;
55
+ if (seen.has(url))
56
+ continue;
57
+ seen.add(url);
58
+ // Use link text as filename if it looks like a filename (has extension)
59
+ const filename = hasFileExtension(linkText) ? linkText : getFilenameFromUrl(url);
60
+ const id = Buffer.from(url).toString('base64').slice(0, 12);
61
+ attachments.push({
62
+ id,
63
+ url,
64
+ filename: decodeURIComponent(filename),
65
+ source: 'embedded',
66
+ });
67
+ }
68
+ // Finally extract any standalone URLs that weren't in markdown syntax
69
+ const urls = markdown.match(LINEAR_UPLOAD_PATTERN) || [];
70
+ for (const url of urls) {
71
+ if (seen.has(url))
72
+ continue;
73
+ seen.add(url);
74
+ const filename = getFilenameFromUrl(url);
75
+ const id = Buffer.from(url).toString('base64').slice(0, 12);
76
+ attachments.push({
77
+ id,
78
+ url,
79
+ filename: decodeURIComponent(filename),
80
+ source: 'embedded',
81
+ });
82
+ }
83
+ return attachments;
84
+ }
85
+ /**
86
+ * Checks if a string looks like a filename (has a file extension)
87
+ */
88
+ function hasFileExtension(text) {
89
+ return /\.\w{2,5}$/.test(text.trim());
90
+ }
91
+ /**
92
+ * Extracts filename from URL path (fallback when no alt text available)
93
+ */
94
+ function getFilenameFromUrl(url) {
95
+ const urlPath = new URL(url).pathname;
96
+ const segments = urlPath.split('/');
97
+ return segments[segments.length - 1] || 'attachment';
98
+ }
99
+ /**
100
+ * Parses attachment metadata from Agent 1's output.
101
+ * Looks for the Attachments section and extracts Linear upload URLs.
102
+ */
103
+ export function parseAgent1Attachments(agent1Output) {
104
+ // First extract any URLs from the entire output (embedded images in description)
105
+ const allUrls = extractLinearUrls(agent1Output);
106
+ // Also look for explicit attachment section
107
+ // Agent 1 outputs attachments like:
108
+ // ### Attachments
109
+ // - Screenshot: https://uploads.linear.app/...
110
+ const attachmentSection = agent1Output.match(/### Attachments\n([\s\S]*?)(?=\n###|\n---|\n##|$)/);
111
+ if (attachmentSection) {
112
+ const sectionUrls = extractLinearUrls(attachmentSection[1]);
113
+ // Mark these as explicit attachments
114
+ for (const att of sectionUrls) {
115
+ const existing = allUrls.find(a => a.url === att.url);
116
+ if (existing) {
117
+ existing.source = 'attachment';
118
+ }
119
+ else {
120
+ att.source = 'attachment';
121
+ allUrls.push(att);
122
+ }
123
+ }
124
+ }
125
+ return allUrls;
126
+ }
127
+ /**
128
+ * Ensures the attachment directory exists for a given issue
129
+ */
130
+ export function ensureAttachmentDir(issueIdentifier) {
131
+ const attachmentsDir = path.join(getRepoRoot(), '.horizon', 'attachments', issueIdentifier);
132
+ if (!fs.existsSync(attachmentsDir)) {
133
+ fs.mkdirSync(attachmentsDir, { recursive: true });
134
+ }
135
+ return attachmentsDir;
136
+ }
137
+ /**
138
+ * Sanitizes a filename for safe filesystem use
139
+ */
140
+ function sanitizeFilename(filename) {
141
+ // Remove or replace problematic characters
142
+ return filename
143
+ .replace(/[<>:"/\\|?*]/g, '-')
144
+ .replace(/\s+/g, '-')
145
+ .replace(/-+/g, '-')
146
+ .slice(0, 200); // Limit length
147
+ }
148
+ /**
149
+ * Gets file extension from Content-Type header
150
+ */
151
+ function getExtensionFromContentType(contentType) {
152
+ if (!contentType)
153
+ return null;
154
+ // Content-Type can include charset, e.g., "image/png; charset=utf-8"
155
+ const mimeType = contentType.split(';')[0].trim().toLowerCase();
156
+ return CONTENT_TYPE_TO_EXT[mimeType] || null;
157
+ }
158
+ /**
159
+ * Ensures a filename has an extension, inferring from Content-Type if needed
160
+ */
161
+ function ensureFileExtension(filename, contentType) {
162
+ if (hasFileExtension(filename)) {
163
+ return filename;
164
+ }
165
+ const ext = getExtensionFromContentType(contentType);
166
+ return ext ? `${filename}${ext}` : filename;
167
+ }
168
+ /**
169
+ * Downloads a single attachment from Linear
170
+ */
171
+ async function downloadAttachment(_apiKey, attachment, outputDir) {
172
+ try {
173
+ // Linear attachment URLs are pre-signed with ?signature= query parameters
174
+ // No Authorization header needed - the signature provides access
175
+ const response = await fetch(attachment.url);
176
+ if (!response.ok) {
177
+ return {
178
+ success: false,
179
+ error: `HTTP ${response.status}: ${response.statusText}`,
180
+ };
181
+ }
182
+ // Check content length for warning
183
+ const contentLength = response.headers.get('content-length');
184
+ if (contentLength && parseInt(contentLength, 10) > SIZE_WARNING_THRESHOLD) {
185
+ console.log(` Warning: Large file (${Math.round(parseInt(contentLength, 10) / 1024 / 1024)}MB): ${attachment.filename}`);
186
+ }
187
+ const buffer = await response.arrayBuffer();
188
+ // Ensure filename has extension (use Content-Type as fallback)
189
+ const contentType = response.headers.get('content-type');
190
+ const filenameWithExt = ensureFileExtension(attachment.filename, contentType);
191
+ const sanitizedFilename = sanitizeFilename(filenameWithExt);
192
+ const localPath = path.join(outputDir, sanitizedFilename);
193
+ fs.writeFileSync(localPath, Buffer.from(buffer));
194
+ return { success: true, localPath };
195
+ }
196
+ catch (error) {
197
+ const message = error instanceof Error ? error.message : String(error);
198
+ return { success: false, error: message };
199
+ }
200
+ }
201
+ /**
202
+ * Downloads all attachments for an issue.
203
+ * Returns the local file paths for successfully downloaded files.
204
+ */
205
+ export async function downloadIssueAttachments(apiKey, issueIdentifier, attachments) {
206
+ if (attachments.length === 0) {
207
+ return { success: true, attachments: [], errors: [] };
208
+ }
209
+ console.log(`Downloading ${attachments.length} attachment(s) for ${issueIdentifier}...`);
210
+ const outputDir = ensureAttachmentDir(issueIdentifier);
211
+ const downloaded = [];
212
+ const errors = [];
213
+ for (const attachment of attachments) {
214
+ console.log(` Downloading: ${attachment.filename}`);
215
+ const result = await downloadAttachment(apiKey, attachment, outputDir);
216
+ if (result.success && result.localPath) {
217
+ downloaded.push({
218
+ originalUrl: attachment.url,
219
+ localPath: result.localPath,
220
+ filename: attachment.filename,
221
+ });
222
+ console.log(` ✓ Saved to ${result.localPath}`);
223
+ }
224
+ else {
225
+ const errorMsg = `Failed to download ${attachment.filename}: ${result.error}`;
226
+ errors.push(errorMsg);
227
+ console.log(` ✗ ${result.error}`);
228
+ }
229
+ }
230
+ console.log(` Downloaded ${downloaded.length}/${attachments.length} files`);
231
+ return {
232
+ success: errors.length === 0,
233
+ attachments: downloaded,
234
+ errors,
235
+ };
236
+ }
237
+ /**
238
+ * Main entry point: Downloads attachments from Agent 1's output.
239
+ * Returns an array of local file paths that Agent 2 can read.
240
+ */
241
+ export async function downloadAttachmentsFromAgent1Output(apiKey, agent1Output, issueIdentifier) {
242
+ // Parse attachments from Agent 1's output
243
+ const attachments = parseAgent1Attachments(agent1Output);
244
+ if (attachments.length === 0) {
245
+ return [];
246
+ }
247
+ // Download all attachments
248
+ const result = await downloadIssueAttachments(apiKey, issueIdentifier, attachments);
249
+ // Log any errors but don't crash
250
+ if (result.errors.length > 0) {
251
+ console.log(' Some attachments failed to download:');
252
+ for (const error of result.errors) {
253
+ console.log(` - ${error}`);
254
+ }
255
+ }
256
+ // Return the local file paths
257
+ return result.attachments.map(a => a.localPath);
258
+ }
259
+ //# sourceMappingURL=attachment-downloader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachment-downloader.js","sourceRoot":"","sources":["../../src/lib/attachment-downloader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { ClaudeResult, ClaudeOptions } from '../types.js';
2
+ import { LLMProvider } from './provider.js';
3
+ export declare function spawnClaude(options: ClaudeOptions, agentNumber?: number): Promise<ClaudeResult>;
4
+ export declare function extractFinalOutput(streamOutput: string): string;
5
+ export declare function createClaudeProvider(): LLMProvider;
6
+ //# sourceMappingURL=claude.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/lib/claude.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAe,MAAM,aAAa,CAAC;AAIvE,OAAO,EAAE,WAAW,EAA2D,MAAM,eAAe,CAAC;AAmLrG,wBAAsB,WAAW,CAAC,OAAO,EAAE,aAAa,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAmIrG;AAGD,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAgC/D;AAqDD,wBAAgB,oBAAoB,IAAI,WAAW,CAElD"}
@@ -0,0 +1,358 @@
1
+ import { spawn } from 'child_process';
2
+ import { existsSync } from 'fs';
3
+ import { join } from 'path';
4
+ import { parseRateLimitReset, isRateLimitError } from './rate-limit.js';
5
+ import { getConfig, getRepoRoot } from '../config.js';
6
+ import { logAgentOutput, logTerminalOutput } from './output-logger.js';
7
+ import { registerClaudeProvider } from './provider.js';
8
+ // ANSI color codes
9
+ const BOLD = '\x1b[1m';
10
+ const DIM = '\x1b[2m';
11
+ const YELLOW = '\x1b[33m';
12
+ const GREEN = '\x1b[32m';
13
+ const RESET = '\x1b[0m';
14
+ // Track subagent ID -> description mapping
15
+ const subagentMap = new Map();
16
+ // Helper: Extract short model name
17
+ function modelName(model) {
18
+ if (!model)
19
+ return '?';
20
+ if (model.includes('opus'))
21
+ return 'opus';
22
+ if (model.includes('sonnet'))
23
+ return 'sonnet';
24
+ if (model.includes('haiku'))
25
+ return 'haiku';
26
+ return model;
27
+ }
28
+ // Helper: Calculate context usage percentage (168K effective limit)
29
+ function contextPct(usage) {
30
+ const total = (usage.cache_creation_input_tokens || 0) + (usage.cache_read_input_tokens || 0);
31
+ return Math.floor((total * 100) / 168000);
32
+ }
33
+ // Helper: Clean up file paths for display
34
+ function cleanPath(path) {
35
+ return path
36
+ .replace(/\/home\/ubuntu\/repos\/[^/]+\//g, '')
37
+ .replace(/\/Users\/[^/]+\/repos\/[^/]+\//g, '');
38
+ }
39
+ // Helper: Extract the most useful value from tool input
40
+ function extractToolValue(input) {
41
+ if (input.file_path)
42
+ return cleanPath(String(input.file_path));
43
+ if (input.path && input.pattern)
44
+ return `${input.pattern} in ${cleanPath(String(input.path))}`;
45
+ if (input.pattern)
46
+ return String(input.pattern);
47
+ if (input.command)
48
+ return String(input.command).substring(0, 80).replace(/\n/g, ' ');
49
+ if (input.query)
50
+ return String(input.query).substring(0, 80);
51
+ if (input.content)
52
+ return '(content)';
53
+ if (input.todos)
54
+ return '(todos)';
55
+ return JSON.stringify(input).substring(0, 80).replace(/\n/g, ' ');
56
+ }
57
+ // Format numbers with commas
58
+ function formatNumber(num) {
59
+ return num.toLocaleString();
60
+ }
61
+ // Process a single JSON line and return formatted output
62
+ function processJsonLine(json) {
63
+ // System init
64
+ if (json.type === 'system' && json.subtype === 'init') {
65
+ const tools = Array.isArray(json.tools) ? json.tools.length : 0;
66
+ return `${BOLD}\n🚀 SESSION START\n Model: ${json.model}\n Tools: ${tools} available${RESET}`;
67
+ }
68
+ // System status
69
+ if (json.type === 'system' && json.subtype === 'status') {
70
+ return `${DIM}⏳ ${String(json.status).toUpperCase()}...${RESET}`;
71
+ }
72
+ // Context compaction
73
+ if (json.type === 'system' && json.subtype === 'compact_boundary') {
74
+ const metadata = json.compact_metadata;
75
+ const preTokens = metadata?.pre_tokens ? Math.floor(metadata.pre_tokens / 1000) : '?';
76
+ return `${DIM}📦 Context compacted (was ${preTokens}k tokens)${RESET}`;
77
+ }
78
+ // Task notification
79
+ if (json.type === 'system' && json.subtype === 'task_notification') {
80
+ return `${GREEN}✅ DONE: ${json.summary}${RESET}`;
81
+ }
82
+ // Result (session end)
83
+ if (json.type === 'result') {
84
+ const modelUsage = json.modelUsage;
85
+ let totalIn = 0, totalOut = 0, totalCacheRead = 0, totalCacheWrite = 0;
86
+ const modelBreakdown = [];
87
+ if (modelUsage) {
88
+ for (const [model, usage] of Object.entries(modelUsage)) {
89
+ const inTokens = usage.inputTokens || 0;
90
+ const outTokens = usage.outputTokens || 0;
91
+ const cacheRead = usage.cacheReadInputTokens || 0;
92
+ const cacheWrite = usage.cacheCreationInputTokens || 0;
93
+ const cost = usage.costUSD || 0;
94
+ totalIn += inTokens;
95
+ totalOut += outTokens;
96
+ totalCacheRead += cacheRead;
97
+ totalCacheWrite += cacheWrite;
98
+ const shortModel = model.split('-')[1] || model;
99
+ modelBreakdown.push(`${shortModel}: in=${formatNumber(inTokens)} out=${formatNumber(outTokens)} ` +
100
+ `cache_read=${formatNumber(cacheRead)} cache_write=${formatNumber(cacheWrite)} $${cost.toFixed(2)}`);
101
+ }
102
+ }
103
+ const durationSec = Math.floor((json.duration_ms || 0) / 1000);
104
+ const totalCost = (json.total_cost_usd || 0).toFixed(2);
105
+ const numTurns = json.num_turns || 0;
106
+ return `${BOLD}\n📊 SESSION END
107
+ Duration: ${durationSec}s
108
+ Cost: $${totalCost}
109
+ Turns: ${numTurns}
110
+ ${modelBreakdown.join('\n ')}
111
+ TOTAL: in=${formatNumber(totalIn)} out=${formatNumber(totalOut)} cache_read=${formatNumber(totalCacheRead)} cache_write=${formatNumber(totalCacheWrite)}${RESET}`;
112
+ }
113
+ // Assistant messages
114
+ if (json.type === 'assistant') {
115
+ const message = json.message;
116
+ const model = modelName(message?.model);
117
+ const pct = message?.usage ? contextPct(message.usage) : 0;
118
+ const parentId = json.parent_tool_use_id;
119
+ const content = message?.content || [];
120
+ const lines = [];
121
+ for (const item of content) {
122
+ if (item.name === 'Task') {
123
+ // Main agent spawning a subagent
124
+ const input = item.input;
125
+ const desc = input?.description || 'unknown';
126
+ const agentType = input?.subagent_type || 'unknown';
127
+ // Store mapping for later
128
+ if (item.id) {
129
+ subagentMap.set(item.id, desc);
130
+ }
131
+ lines.push(`${YELLOW}\n🤖 [${model}/main/${pct}%] SPAWN: ${desc}\n Agent: ${agentType}${RESET}`);
132
+ }
133
+ else if (item.name === 'TaskOutput') {
134
+ // Skip TaskOutput messages
135
+ continue;
136
+ }
137
+ else if (item.type === 'tool_use') {
138
+ const value = item.input ? extractToolValue(item.input) : '';
139
+ if (parentId === null) {
140
+ // Main agent tool call
141
+ lines.push(`${DIM}🔧 [${model}/main/${pct}%] ${item.name}: ${value}${RESET}`);
142
+ }
143
+ else {
144
+ // Subagent tool call - resolve parent ID to description
145
+ const parentDesc = subagentMap.get(parentId) || parentId;
146
+ lines.push(`${DIM} [${model}/${parentDesc}] ${item.name}: ${value}${RESET}`);
147
+ }
148
+ }
149
+ else if (item.type === 'text' && item.text) {
150
+ if (parentId === null) {
151
+ // Main agent text - show full text
152
+ lines.push(`💬 [${model}/main/${pct}%] ${item.text}`);
153
+ }
154
+ // Skip subagent text to reduce noise
155
+ }
156
+ }
157
+ return lines.length > 0 ? lines.join('\n') : null;
158
+ }
159
+ return null;
160
+ }
161
+ // Legacy function for backwards compatibility
162
+ export async function spawnClaude(options, agentNumber) {
163
+ // Clear subagent map for new session
164
+ subagentMap.clear();
165
+ return new Promise((resolve, reject) => {
166
+ const config = getConfig();
167
+ const args = [
168
+ '-p',
169
+ '--dangerously-skip-permissions',
170
+ '--output-format=stream-json',
171
+ '--model', options.model,
172
+ '--verbose',
173
+ ];
174
+ // Add MCP config if it exists in .horizon/mcp.json
175
+ const mcpConfigPath = join(getRepoRoot(), '.horizon', 'mcp.json');
176
+ if (existsSync(mcpConfigPath)) {
177
+ args.push('--mcp-config', mcpConfigPath);
178
+ }
179
+ // Add allowed tools restriction if specified
180
+ if (options.allowedTools && options.allowedTools.length > 0) {
181
+ args.push('--allowedTools', options.allowedTools.join(','));
182
+ }
183
+ const spawnMsg = `${BOLD}Spawning: claude ${args.join(' ')}${RESET}`;
184
+ const cwdMsg = `${DIM} Working directory: ${config.workingDirectory}${RESET}`;
185
+ console.log(spawnMsg);
186
+ console.log(cwdMsg);
187
+ // Log spawn info to terminal log
188
+ if (agentNumber !== undefined) {
189
+ logTerminalOutput(agentNumber, spawnMsg).catch(() => { });
190
+ logTerminalOutput(agentNumber, cwdMsg).catch(() => { });
191
+ }
192
+ const proc = spawn('claude', args, {
193
+ stdio: ['pipe', 'pipe', 'pipe'],
194
+ cwd: config.workingDirectory,
195
+ });
196
+ proc.stdin.write(options.prompt);
197
+ proc.stdin.end();
198
+ let output = '';
199
+ let rateLimited = false;
200
+ let retryAfterMs;
201
+ let cost = 0;
202
+ let duration = 0;
203
+ proc.stdout.on('data', (chunk) => {
204
+ const text = chunk.toString();
205
+ output += text;
206
+ // Parse streaming JSON output
207
+ for (const line of text.split('\n')) {
208
+ if (!line.trim())
209
+ continue;
210
+ // Persist raw line to output log file if agent number provided
211
+ if (agentNumber !== undefined) {
212
+ logAgentOutput(agentNumber, line).catch(() => {
213
+ // Silently ignore logging errors
214
+ });
215
+ }
216
+ try {
217
+ const json = JSON.parse(line);
218
+ // Check for rate limits
219
+ if (json.error === 'rate_limit') {
220
+ rateLimited = true;
221
+ retryAfterMs = parseRateLimitReset(json);
222
+ }
223
+ if (json.type === 'result' && json.is_error) {
224
+ const resultText = String(json.result || '');
225
+ if (isRateLimitError(resultText)) {
226
+ rateLimited = true;
227
+ retryAfterMs = parseRateLimitReset(json);
228
+ }
229
+ }
230
+ // Capture final stats
231
+ if (json.type === 'result') {
232
+ cost = json.total_cost_usd || 0;
233
+ duration = json.duration_ms || 0;
234
+ }
235
+ // Process and log the line
236
+ const formatted = processJsonLine(json);
237
+ if (formatted) {
238
+ console.log(formatted);
239
+ // Persist formatted terminal output to separate log file
240
+ if (agentNumber !== undefined) {
241
+ logTerminalOutput(agentNumber, formatted).catch(() => {
242
+ // Silently ignore logging errors
243
+ });
244
+ }
245
+ }
246
+ }
247
+ catch {
248
+ // Not JSON or parse error, ignore
249
+ }
250
+ }
251
+ });
252
+ proc.stderr.on('data', (chunk) => {
253
+ const text = chunk.toString().trim();
254
+ if (text) {
255
+ const stderrMsg = `${DIM}stderr: ${text}${RESET}`;
256
+ console.error(stderrMsg);
257
+ // Log stderr to terminal log
258
+ if (agentNumber !== undefined) {
259
+ logTerminalOutput(agentNumber, stderrMsg).catch(() => { });
260
+ }
261
+ }
262
+ });
263
+ proc.on('close', (code) => {
264
+ resolve({
265
+ output,
266
+ rateLimited,
267
+ retryAfterMs,
268
+ cost,
269
+ duration,
270
+ exitCode: code || 0,
271
+ });
272
+ });
273
+ proc.on('error', (err) => {
274
+ reject(new Error(`Failed to spawn claude: ${err.message}`));
275
+ });
276
+ });
277
+ }
278
+ // Extract the final text output from Claude's streaming JSON
279
+ export function extractFinalOutput(streamOutput) {
280
+ const lines = streamOutput.split('\n');
281
+ let lastTextContent = '';
282
+ for (const line of lines) {
283
+ if (!line.trim())
284
+ continue;
285
+ try {
286
+ const json = JSON.parse(line);
287
+ // Look for assistant messages at the top level (not subagent)
288
+ if (json.type === 'assistant' && !json.parent_tool_use_id) {
289
+ const content = json.message?.content;
290
+ if (Array.isArray(content)) {
291
+ for (const item of content) {
292
+ if (item.type === 'text' && item.text) {
293
+ lastTextContent = item.text;
294
+ }
295
+ }
296
+ }
297
+ }
298
+ // Also check result type for final output
299
+ if (json.type === 'result' && !json.is_error && json.result) {
300
+ lastTextContent = String(json.result);
301
+ }
302
+ }
303
+ catch {
304
+ // Not JSON, ignore
305
+ }
306
+ }
307
+ return lastTextContent;
308
+ }
309
+ // Claude provider implementation
310
+ class ClaudeProvider {
311
+ name = 'claude';
312
+ async spawn(options, agentNumber) {
313
+ // Map model string to ClaudeModel type
314
+ const model = options.model || getConfig().claudeModel;
315
+ const result = await spawnClaude({
316
+ prompt: options.prompt,
317
+ model,
318
+ allowedTools: options.allowedTools,
319
+ }, agentNumber);
320
+ // Extract token usage from the output
321
+ const tokenUsage = { input: 0, output: 0, cached: 0 };
322
+ for (const line of result.output.split('\n')) {
323
+ if (!line.trim())
324
+ continue;
325
+ try {
326
+ const json = JSON.parse(line);
327
+ if (json.type === 'result' && json.modelUsage) {
328
+ for (const usage of Object.values(json.modelUsage)) {
329
+ tokenUsage.input += usage.inputTokens || 0;
330
+ tokenUsage.output += usage.outputTokens || 0;
331
+ tokenUsage.cached += usage.cacheReadInputTokens || 0;
332
+ }
333
+ }
334
+ }
335
+ catch {
336
+ // Ignore parse errors
337
+ }
338
+ }
339
+ return {
340
+ output: result.output,
341
+ finalOutput: extractFinalOutput(result.output),
342
+ rateLimited: result.rateLimited,
343
+ retryAfterMs: result.retryAfterMs,
344
+ cost: result.cost,
345
+ costEstimated: false, // Claude provides exact cost
346
+ duration: result.duration,
347
+ exitCode: result.exitCode,
348
+ tokenUsage,
349
+ };
350
+ }
351
+ }
352
+ // Factory function
353
+ export function createClaudeProvider() {
354
+ return new ClaudeProvider();
355
+ }
356
+ // Register the Claude provider
357
+ registerClaudeProvider(createClaudeProvider);
358
+ //# sourceMappingURL=claude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/lib/claude.ts"],"names":[],"mappings":"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"}