@compilr-dev/sdk 0.7.16 → 0.7.17
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.
|
@@ -13,6 +13,13 @@ export declare function createDocumentTools(config: PlatformToolsConfig): (impor
|
|
|
13
13
|
doc_type: string;
|
|
14
14
|
title: string;
|
|
15
15
|
content: string;
|
|
16
|
+
}> | import("@compilr-dev/agents").Tool<{
|
|
17
|
+
project_id?: number;
|
|
18
|
+
doc_type: string;
|
|
19
|
+
startLine?: number;
|
|
20
|
+
maxLines?: number;
|
|
21
|
+
section?: string;
|
|
22
|
+
summary_only?: boolean;
|
|
16
23
|
}> | import("@compilr-dev/agents").Tool<{
|
|
17
24
|
project_id?: number;
|
|
18
25
|
doc_type: string;
|
|
@@ -114,7 +114,9 @@ export function createDocumentTools(config) {
|
|
|
114
114
|
// ---------------------------------------------------------------------------
|
|
115
115
|
const projectDocumentGetTool = defineTool({
|
|
116
116
|
name: 'project_document_get',
|
|
117
|
-
description: 'Get a project document by type.
|
|
117
|
+
description: 'Get a project document by type. ' +
|
|
118
|
+
'Use maxLines/startLine for partial reads, section to read a specific heading, ' +
|
|
119
|
+
'or summary_only to get the document structure without full content.',
|
|
118
120
|
inputSchema: {
|
|
119
121
|
type: 'object',
|
|
120
122
|
properties: {
|
|
@@ -123,6 +125,24 @@ export function createDocumentTools(config) {
|
|
|
123
125
|
enum: DOC_TYPE_ENUM,
|
|
124
126
|
description: 'Document type to retrieve',
|
|
125
127
|
},
|
|
128
|
+
startLine: {
|
|
129
|
+
type: 'number',
|
|
130
|
+
description: 'Line number to start reading from (1-indexed, default: 1)',
|
|
131
|
+
},
|
|
132
|
+
maxLines: {
|
|
133
|
+
type: 'number',
|
|
134
|
+
description: 'Maximum number of lines to return (default: all)',
|
|
135
|
+
},
|
|
136
|
+
section: {
|
|
137
|
+
type: 'string',
|
|
138
|
+
description: 'Read only a specific section by its markdown heading (e.g., "## Methods"). ' +
|
|
139
|
+
'Returns the heading and all content until the next heading of equal or higher level.',
|
|
140
|
+
},
|
|
141
|
+
summary_only: {
|
|
142
|
+
type: 'boolean',
|
|
143
|
+
description: 'If true, returns only the document structure: headings with line numbers and character counts per section. ' +
|
|
144
|
+
'Useful for navigating large documents before reading specific parts.',
|
|
145
|
+
},
|
|
126
146
|
project_id: {
|
|
127
147
|
type: 'number',
|
|
128
148
|
description: 'Override active project.',
|
|
@@ -144,13 +164,104 @@ export function createDocumentTools(config) {
|
|
|
144
164
|
message: `No ${input.doc_type} document found for this project`,
|
|
145
165
|
});
|
|
146
166
|
}
|
|
167
|
+
const allLines = doc.content.split('\n');
|
|
168
|
+
const totalLines = allLines.length;
|
|
169
|
+
const totalChars = doc.content.length;
|
|
170
|
+
// ── summary_only: return document structure ──
|
|
171
|
+
if (input.summary_only) {
|
|
172
|
+
const sections = [];
|
|
173
|
+
for (let i = 0; i < allLines.length; i++) {
|
|
174
|
+
const match = allLines[i].match(/^(#{1,6})\s+(.+)/);
|
|
175
|
+
if (match) {
|
|
176
|
+
// Close previous section
|
|
177
|
+
if (sections.length > 0) {
|
|
178
|
+
const prev = sections[sections.length - 1];
|
|
179
|
+
prev.chars = allLines.slice(prev.line - 1, i).join('\n').length;
|
|
180
|
+
}
|
|
181
|
+
sections.push({
|
|
182
|
+
heading: allLines[i].trim(),
|
|
183
|
+
line: i + 1, // 1-indexed
|
|
184
|
+
chars: 0,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// Close last section
|
|
189
|
+
if (sections.length > 0) {
|
|
190
|
+
const prev = sections[sections.length - 1];
|
|
191
|
+
prev.chars = allLines.slice(prev.line - 1).join('\n').length;
|
|
192
|
+
}
|
|
193
|
+
return createSuccessResult({
|
|
194
|
+
success: true,
|
|
195
|
+
document: {
|
|
196
|
+
id: doc.id,
|
|
197
|
+
docType: doc.docType,
|
|
198
|
+
title: doc.title,
|
|
199
|
+
totalLines,
|
|
200
|
+
totalChars,
|
|
201
|
+
sections,
|
|
202
|
+
hint: 'Use section param to read a specific heading, or startLine/maxLines for line ranges',
|
|
203
|
+
updatedAt: doc.updatedAt.toISOString(),
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
// ── section: extract content under a specific heading ──
|
|
208
|
+
if (input.section) {
|
|
209
|
+
const heading = input.section.trim();
|
|
210
|
+
const headingLevel = heading.match(/^(#{1,6})\s/)?.[1]?.length ?? 2;
|
|
211
|
+
let sectionStart = -1;
|
|
212
|
+
let sectionEnd = allLines.length;
|
|
213
|
+
for (let i = 0; i < allLines.length; i++) {
|
|
214
|
+
const line = allLines[i].trim();
|
|
215
|
+
if (sectionStart === -1) {
|
|
216
|
+
if (line === heading) {
|
|
217
|
+
sectionStart = i;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
const nextMatch = line.match(/^(#{1,6})\s/);
|
|
222
|
+
if (nextMatch && nextMatch[1].length <= headingLevel) {
|
|
223
|
+
sectionEnd = i;
|
|
224
|
+
break;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (sectionStart === -1) {
|
|
229
|
+
const headings = allLines
|
|
230
|
+
.filter((l) => l.trim().match(/^#{1,6}\s/))
|
|
231
|
+
.map((l) => l.trim());
|
|
232
|
+
return createErrorResult(`Section "${heading}" not found. Available headings: ${headings.join(', ') || '(none)'}`);
|
|
233
|
+
}
|
|
234
|
+
return createSuccessResult({
|
|
235
|
+
success: true,
|
|
236
|
+
document: {
|
|
237
|
+
id: doc.id,
|
|
238
|
+
docType: doc.docType,
|
|
239
|
+
title: doc.title,
|
|
240
|
+
content: allLines.slice(sectionStart, sectionEnd).join('\n'),
|
|
241
|
+
totalLines,
|
|
242
|
+
sectionLines: { start: sectionStart + 1, end: sectionEnd },
|
|
243
|
+
updatedAt: doc.updatedAt.toISOString(),
|
|
244
|
+
},
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
// ── startLine/maxLines: line range ──
|
|
248
|
+
let content = doc.content;
|
|
249
|
+
let truncated = false;
|
|
250
|
+
if (input.startLine || input.maxLines) {
|
|
251
|
+
const start = Math.max(0, (input.startLine ?? 1) - 1);
|
|
252
|
+
const end = input.maxLines ? start + input.maxLines : allLines.length;
|
|
253
|
+
content = allLines.slice(start, end).join('\n');
|
|
254
|
+
truncated = end < allLines.length;
|
|
255
|
+
}
|
|
147
256
|
return createSuccessResult({
|
|
148
257
|
success: true,
|
|
149
258
|
document: {
|
|
150
259
|
id: doc.id,
|
|
151
260
|
docType: doc.docType,
|
|
152
261
|
title: doc.title,
|
|
153
|
-
content
|
|
262
|
+
content,
|
|
263
|
+
totalLines,
|
|
264
|
+
...(truncated ? { truncated: true, hint: 'Use startLine/maxLines to read more' } : {}),
|
|
154
265
|
createdAt: doc.createdAt.toISOString(),
|
|
155
266
|
updatedAt: doc.updatedAt.toISOString(),
|
|
156
267
|
},
|