@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.
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +43 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +10 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +293 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +629 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/__tests__/attachment-downloader.test.d.ts +2 -0
- package/dist/lib/__tests__/attachment-downloader.test.d.ts.map +1 -0
- package/dist/lib/__tests__/attachment-downloader.test.js +163 -0
- package/dist/lib/__tests__/attachment-downloader.test.js.map +1 -0
- package/dist/lib/__tests__/cli-detection.test.d.ts +2 -0
- package/dist/lib/__tests__/cli-detection.test.d.ts.map +1 -0
- package/dist/lib/__tests__/cli-detection.test.js +119 -0
- package/dist/lib/__tests__/cli-detection.test.js.map +1 -0
- package/dist/lib/__tests__/config.test.d.ts +2 -0
- package/dist/lib/__tests__/config.test.d.ts.map +1 -0
- package/dist/lib/__tests__/config.test.js +291 -0
- package/dist/lib/__tests__/config.test.js.map +1 -0
- package/dist/lib/__tests__/gcp.test.d.ts +2 -0
- package/dist/lib/__tests__/gcp.test.d.ts.map +1 -0
- package/dist/lib/__tests__/gcp.test.js +104 -0
- package/dist/lib/__tests__/gcp.test.js.map +1 -0
- package/dist/lib/__tests__/git.test.d.ts +2 -0
- package/dist/lib/__tests__/git.test.d.ts.map +1 -0
- package/dist/lib/__tests__/git.test.js +62 -0
- package/dist/lib/__tests__/git.test.js.map +1 -0
- package/dist/lib/__tests__/linear-quick-check.test.d.ts +2 -0
- package/dist/lib/__tests__/linear-quick-check.test.d.ts.map +1 -0
- package/dist/lib/__tests__/linear-quick-check.test.js +152 -0
- package/dist/lib/__tests__/linear-quick-check.test.js.map +1 -0
- package/dist/lib/__tests__/loop-instance-name.test.d.ts +2 -0
- package/dist/lib/__tests__/loop-instance-name.test.d.ts.map +1 -0
- package/dist/lib/__tests__/loop-instance-name.test.js +90 -0
- package/dist/lib/__tests__/loop-instance-name.test.js.map +1 -0
- package/dist/lib/__tests__/output-logger.test.d.ts +2 -0
- package/dist/lib/__tests__/output-logger.test.d.ts.map +1 -0
- package/dist/lib/__tests__/output-logger.test.js +136 -0
- package/dist/lib/__tests__/output-logger.test.js.map +1 -0
- package/dist/lib/__tests__/prompts.test.d.ts +2 -0
- package/dist/lib/__tests__/prompts.test.d.ts.map +1 -0
- package/dist/lib/__tests__/prompts.test.js +70 -0
- package/dist/lib/__tests__/prompts.test.js.map +1 -0
- package/dist/lib/__tests__/provider.test.d.ts +2 -0
- package/dist/lib/__tests__/provider.test.d.ts.map +1 -0
- package/dist/lib/__tests__/provider.test.js +89 -0
- package/dist/lib/__tests__/provider.test.js.map +1 -0
- package/dist/lib/__tests__/rate-limit.test.d.ts +2 -0
- package/dist/lib/__tests__/rate-limit.test.d.ts.map +1 -0
- package/dist/lib/__tests__/rate-limit.test.js +275 -0
- package/dist/lib/__tests__/rate-limit.test.js.map +1 -0
- package/dist/lib/__tests__/readline.test.d.ts +2 -0
- package/dist/lib/__tests__/readline.test.d.ts.map +1 -0
- package/dist/lib/__tests__/readline.test.js +55 -0
- package/dist/lib/__tests__/readline.test.js.map +1 -0
- package/dist/lib/__tests__/stats-logger.test.d.ts +2 -0
- package/dist/lib/__tests__/stats-logger.test.d.ts.map +1 -0
- package/dist/lib/__tests__/stats-logger.test.js +297 -0
- package/dist/lib/__tests__/stats-logger.test.js.map +1 -0
- package/dist/lib/__tests__/update-checker.test.d.ts +2 -0
- package/dist/lib/__tests__/update-checker.test.d.ts.map +1 -0
- package/dist/lib/__tests__/update-checker.test.js +141 -0
- package/dist/lib/__tests__/update-checker.test.js.map +1 -0
- package/dist/lib/__tests__/version.test.d.ts +2 -0
- package/dist/lib/__tests__/version.test.d.ts.map +1 -0
- package/dist/lib/__tests__/version.test.js +51 -0
- package/dist/lib/__tests__/version.test.js.map +1 -0
- package/dist/lib/attachment-downloader.d.ts +26 -0
- package/dist/lib/attachment-downloader.d.ts.map +1 -0
- package/dist/lib/attachment-downloader.js +259 -0
- package/dist/lib/attachment-downloader.js.map +1 -0
- package/dist/lib/claude.d.ts +6 -0
- package/dist/lib/claude.d.ts.map +1 -0
- package/dist/lib/claude.js +358 -0
- package/dist/lib/claude.js.map +1 -0
- package/dist/lib/cli-detection.d.ts +25 -0
- package/dist/lib/cli-detection.d.ts.map +1 -0
- package/dist/lib/cli-detection.js +53 -0
- package/dist/lib/cli-detection.js.map +1 -0
- package/dist/lib/codex.d.ts +4 -0
- package/dist/lib/codex.d.ts.map +1 -0
- package/dist/lib/codex.js +285 -0
- package/dist/lib/codex.js.map +1 -0
- package/dist/lib/gcp.d.ts +21 -0
- package/dist/lib/gcp.d.ts.map +1 -0
- package/dist/lib/gcp.js +96 -0
- package/dist/lib/gcp.js.map +1 -0
- package/dist/lib/git.d.ts +3 -0
- package/dist/lib/git.d.ts.map +1 -0
- package/dist/lib/git.js +24 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/init-project.d.ts +13 -0
- package/dist/lib/init-project.d.ts.map +1 -0
- package/dist/lib/init-project.js +420 -0
- package/dist/lib/init-project.js.map +1 -0
- package/dist/lib/linear-api.d.ts +32 -0
- package/dist/lib/linear-api.d.ts.map +1 -0
- package/dist/lib/linear-api.js +267 -0
- package/dist/lib/linear-api.js.map +1 -0
- package/dist/lib/linear-quick-check.d.ts +13 -0
- package/dist/lib/linear-quick-check.d.ts.map +1 -0
- package/dist/lib/linear-quick-check.js +61 -0
- package/dist/lib/linear-quick-check.js.map +1 -0
- package/dist/lib/loop-instance-name.d.ts +29 -0
- package/dist/lib/loop-instance-name.d.ts.map +1 -0
- package/dist/lib/loop-instance-name.js +105 -0
- package/dist/lib/loop-instance-name.js.map +1 -0
- package/dist/lib/output-logger.d.ts +23 -0
- package/dist/lib/output-logger.d.ts.map +1 -0
- package/dist/lib/output-logger.js +104 -0
- package/dist/lib/output-logger.js.map +1 -0
- package/dist/lib/prompts.d.ts +17 -0
- package/dist/lib/prompts.d.ts.map +1 -0
- package/dist/lib/prompts.js +65 -0
- package/dist/lib/prompts.js.map +1 -0
- package/dist/lib/provider.d.ts +32 -0
- package/dist/lib/provider.d.ts.map +1 -0
- package/dist/lib/provider.js +27 -0
- package/dist/lib/provider.js.map +1 -0
- package/dist/lib/rate-limit.d.ts +14 -0
- package/dist/lib/rate-limit.d.ts.map +1 -0
- package/dist/lib/rate-limit.js +154 -0
- package/dist/lib/rate-limit.js.map +1 -0
- package/dist/lib/readline.d.ts +4 -0
- package/dist/lib/readline.d.ts.map +1 -0
- package/dist/lib/readline.js +39 -0
- package/dist/lib/readline.js.map +1 -0
- package/dist/lib/setup.d.ts +123 -0
- package/dist/lib/setup.d.ts.map +1 -0
- package/dist/lib/setup.js +492 -0
- package/dist/lib/setup.js.map +1 -0
- package/dist/lib/stats-logger.d.ts +92 -0
- package/dist/lib/stats-logger.d.ts.map +1 -0
- package/dist/lib/stats-logger.js +258 -0
- package/dist/lib/stats-logger.js.map +1 -0
- package/dist/lib/update-checker.d.ts +17 -0
- package/dist/lib/update-checker.d.ts.map +1 -0
- package/dist/lib/update-checker.js +140 -0
- package/dist/lib/update-checker.js.map +1 -0
- package/dist/lib/version.d.ts +10 -0
- package/dist/lib/version.d.ts.map +1 -0
- package/dist/lib/version.js +37 -0
- package/dist/lib/version.js.map +1 -0
- package/dist/types.d.ts +92 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- 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: 
|
|
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., )
|
|
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: 
|
|
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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"}
|