@aliou/pi-dev-kit 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +8 -4
- package/src/skills/pi-extension/SKILL.md +51 -37
- package/src/skills/pi-extension/references/additional-apis.md +41 -1
- package/src/skills/pi-extension/references/structure.md +116 -2
- package/src/skills/pi-extension/references/testing.md +129 -0
- package/src/skills/pi-extension/references/tools.md +674 -156
- package/src/tools/changelog-tool.ts +172 -284
- package/src/tools/docs-tool.ts +87 -146
- package/src/tools/package-manager-tool.ts +98 -127
- package/src/tools/utils.ts +0 -24
- package/src/tools/version-tool.ts +13 -20
|
@@ -20,7 +20,7 @@ const GITHUB_RAW_CHANGELOG_URL =
|
|
|
20
20
|
// Params
|
|
21
21
|
// ---------------------------------------------------------------------------
|
|
22
22
|
|
|
23
|
-
const
|
|
23
|
+
const ChangelogParamsSchema = Type.Object({
|
|
24
24
|
version: Type.Optional(
|
|
25
25
|
Type.String({
|
|
26
26
|
description:
|
|
@@ -29,10 +29,10 @@ const ChangelogParams = Type.Object({
|
|
|
29
29
|
),
|
|
30
30
|
});
|
|
31
31
|
|
|
32
|
-
type
|
|
32
|
+
type ChangelogParams = Static<typeof ChangelogParamsSchema>;
|
|
33
33
|
|
|
34
|
-
const
|
|
35
|
-
type
|
|
34
|
+
const ChangelogVersionsParamsSchema = Type.Object({});
|
|
35
|
+
type ChangelogVersionsParams = Record<string, never>;
|
|
36
36
|
|
|
37
37
|
// ---------------------------------------------------------------------------
|
|
38
38
|
// Types
|
|
@@ -44,21 +44,15 @@ interface ChangelogEntry {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
interface ChangelogDetails {
|
|
47
|
-
success: boolean;
|
|
48
|
-
message: string;
|
|
49
47
|
changelog?: ChangelogEntry;
|
|
50
48
|
source?: "local" | "github";
|
|
51
49
|
}
|
|
52
50
|
|
|
53
51
|
interface ChangelogVersionsDetails {
|
|
54
|
-
success: boolean;
|
|
55
|
-
message: string;
|
|
56
52
|
versions?: string[];
|
|
57
53
|
source?: "local" | "github";
|
|
58
54
|
}
|
|
59
55
|
|
|
60
|
-
type ExecuteResult = AgentToolResult<ChangelogDetails>;
|
|
61
|
-
|
|
62
56
|
// ---------------------------------------------------------------------------
|
|
63
57
|
// Parsing
|
|
64
58
|
// ---------------------------------------------------------------------------
|
|
@@ -115,56 +109,36 @@ function parseChangelogEntries(changelogContent: string): ParsedChangelog {
|
|
|
115
109
|
function findChangelogEntry(
|
|
116
110
|
changelogContent: string,
|
|
117
111
|
requestedVersion?: string,
|
|
118
|
-
): {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
try {
|
|
124
|
-
const { entries } = parseChangelogEntries(changelogContent);
|
|
125
|
-
if (entries.length === 0) {
|
|
126
|
-
return { success: false, message: "No version entries found" };
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
if (requestedVersion) {
|
|
130
|
-
const normalizedRequested = requestedVersion.replace(/^v/, "");
|
|
131
|
-
const entry = entries.find(
|
|
132
|
-
(e) =>
|
|
133
|
-
e.version === requestedVersion ||
|
|
134
|
-
e.version === `v${normalizedRequested}` ||
|
|
135
|
-
e.version.replace(/^v/, "") === normalizedRequested,
|
|
136
|
-
);
|
|
137
|
-
|
|
138
|
-
if (entry) {
|
|
139
|
-
return {
|
|
140
|
-
success: true,
|
|
141
|
-
changelog: { version: entry.version, content: entry.content },
|
|
142
|
-
message: `Found changelog for version ${entry.version}`,
|
|
143
|
-
};
|
|
144
|
-
}
|
|
112
|
+
): ChangelogEntry {
|
|
113
|
+
const { entries } = parseChangelogEntries(changelogContent);
|
|
114
|
+
if (entries.length === 0) {
|
|
115
|
+
throw new Error("No version entries found in changelog");
|
|
116
|
+
}
|
|
145
117
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
118
|
+
if (requestedVersion) {
|
|
119
|
+
const normalizedRequested = requestedVersion.replace(/^v/, "");
|
|
120
|
+
const entry = entries.find(
|
|
121
|
+
(e) =>
|
|
122
|
+
e.version === requestedVersion ||
|
|
123
|
+
e.version === `v${normalizedRequested}` ||
|
|
124
|
+
e.version.replace(/^v/, "") === normalizedRequested,
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
if (entry) {
|
|
128
|
+
return { version: entry.version, content: entry.content };
|
|
151
129
|
}
|
|
152
130
|
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
} catch (error) {
|
|
163
|
-
return {
|
|
164
|
-
success: false,
|
|
165
|
-
message: `Error parsing changelog: ${error instanceof Error ? error.message : String(error)}`,
|
|
166
|
-
};
|
|
131
|
+
const allVersions = entries.map((e) => e.version);
|
|
132
|
+
throw new Error(
|
|
133
|
+
`Version ${requestedVersion} not found. Available versions: ${allVersions.join(", ")}`,
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const latest = entries[0];
|
|
138
|
+
if (!latest) {
|
|
139
|
+
throw new Error("No version entries found in changelog");
|
|
167
140
|
}
|
|
141
|
+
return { version: latest.version, content: latest.content };
|
|
168
142
|
}
|
|
169
143
|
|
|
170
144
|
// ---------------------------------------------------------------------------
|
|
@@ -188,21 +162,34 @@ function isNewerThanInstalled(requestedVersion: string): boolean {
|
|
|
188
162
|
return false;
|
|
189
163
|
}
|
|
190
164
|
|
|
191
|
-
async function fetchGithubChangelog(): Promise<string
|
|
165
|
+
async function fetchGithubChangelog(): Promise<string> {
|
|
192
166
|
try {
|
|
193
167
|
const res = await fetch(GITHUB_RAW_CHANGELOG_URL);
|
|
194
|
-
if (!res.ok)
|
|
168
|
+
if (!res.ok) {
|
|
169
|
+
throw new Error(
|
|
170
|
+
`Failed to fetch changelog from GitHub: ${res.status} ${res.statusText}`,
|
|
171
|
+
);
|
|
172
|
+
}
|
|
195
173
|
return await res.text();
|
|
196
|
-
} catch {
|
|
197
|
-
|
|
174
|
+
} catch (error) {
|
|
175
|
+
if (error instanceof Error && error.message.includes("Failed to fetch")) {
|
|
176
|
+
throw error;
|
|
177
|
+
}
|
|
178
|
+
throw new Error(
|
|
179
|
+
`Failed to fetch changelog from GitHub: ${error instanceof Error ? error.message : String(error)}`,
|
|
180
|
+
);
|
|
198
181
|
}
|
|
199
182
|
}
|
|
200
183
|
|
|
201
|
-
function readLocalChangelog(): { content: string; piPath: string }
|
|
184
|
+
function readLocalChangelog(): { content: string; piPath: string } {
|
|
202
185
|
const piPath = findPiInstallation();
|
|
203
|
-
if (!piPath)
|
|
186
|
+
if (!piPath) {
|
|
187
|
+
throw new Error("Could not locate Pi installation");
|
|
188
|
+
}
|
|
204
189
|
const changelogPath = path.join(piPath, "CHANGELOG.md");
|
|
205
|
-
if (!fs.existsSync(changelogPath))
|
|
190
|
+
if (!fs.existsSync(changelogPath)) {
|
|
191
|
+
throw new Error(`Changelog file not found at ${changelogPath}`);
|
|
192
|
+
}
|
|
206
193
|
return { content: fs.readFileSync(changelogPath, "utf-8"), piPath };
|
|
207
194
|
}
|
|
208
195
|
|
|
@@ -249,110 +236,58 @@ function renderChangelogContent(
|
|
|
249
236
|
// ---------------------------------------------------------------------------
|
|
250
237
|
|
|
251
238
|
export function setupChangelogTool(pi: ExtensionAPI) {
|
|
252
|
-
pi.registerTool<typeof
|
|
239
|
+
pi.registerTool<typeof ChangelogParamsSchema, ChangelogDetails>({
|
|
253
240
|
name: "pi_changelog",
|
|
254
241
|
label: "Pi Changelog",
|
|
255
242
|
description:
|
|
256
243
|
"Get changelog entry for a Pi version. Returns latest by default. Use pi_changelog_versions to list all available versions.",
|
|
244
|
+
promptSnippet: `pi_changelog version="1.2.3" // Get changelog for specific version
|
|
245
|
+
pi_changelog // Get latest changelog`,
|
|
246
|
+
promptGuidelines: [
|
|
247
|
+
"Use this tool to check what's new in a Pi version",
|
|
248
|
+
"Use pi_changelog_versions first to list available versions",
|
|
249
|
+
"Leave version empty to get the latest changelog",
|
|
250
|
+
],
|
|
257
251
|
|
|
258
|
-
parameters:
|
|
252
|
+
parameters: ChangelogParamsSchema,
|
|
259
253
|
|
|
260
254
|
async execute(
|
|
261
255
|
_toolCallId: string,
|
|
262
|
-
params:
|
|
256
|
+
params: ChangelogParams,
|
|
263
257
|
_signal: AbortSignal | undefined,
|
|
264
258
|
_onUpdate: unknown,
|
|
265
259
|
_ctx: ExtensionContext,
|
|
266
|
-
): Promise<
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
content: [
|
|
274
|
-
{
|
|
275
|
-
type: "text",
|
|
276
|
-
text: `Version ${params.version} is newer than installed (${VERSION}) and GitHub fetch failed.`,
|
|
277
|
-
},
|
|
278
|
-
],
|
|
279
|
-
details: {
|
|
280
|
-
success: false,
|
|
281
|
-
message: `Version ${params.version} is newer than installed (${VERSION}) and GitHub fetch failed.`,
|
|
282
|
-
},
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
const result = findChangelogEntry(githubContent, params.version);
|
|
287
|
-
if (!result.success || !result.changelog) {
|
|
288
|
-
return {
|
|
289
|
-
content: [{ type: "text", text: result.message }],
|
|
290
|
-
details: {
|
|
291
|
-
success: false,
|
|
292
|
-
message: result.message,
|
|
293
|
-
source: "github",
|
|
294
|
-
},
|
|
295
|
-
};
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
const message = `${result.message} (from GitHub)\n\n## ${result.changelog.version}\n\n${result.changelog.content}`;
|
|
299
|
-
return {
|
|
300
|
-
content: [{ type: "text", text: message }],
|
|
301
|
-
details: {
|
|
302
|
-
success: true,
|
|
303
|
-
message: `${result.message} (from GitHub)`,
|
|
304
|
-
changelog: result.changelog,
|
|
305
|
-
source: "github",
|
|
306
|
-
},
|
|
307
|
-
};
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
// Local
|
|
311
|
-
const local = readLocalChangelog();
|
|
312
|
-
if (!local) {
|
|
313
|
-
return {
|
|
314
|
-
content: [
|
|
315
|
-
{
|
|
316
|
-
type: "text",
|
|
317
|
-
text: "Could not locate Pi installation or CHANGELOG.md",
|
|
318
|
-
},
|
|
319
|
-
],
|
|
320
|
-
details: {
|
|
321
|
-
success: false,
|
|
322
|
-
message: "Could not locate Pi installation or CHANGELOG.md",
|
|
323
|
-
},
|
|
324
|
-
};
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
const result = findChangelogEntry(local.content, params.version);
|
|
328
|
-
if (!result.success || !result.changelog) {
|
|
329
|
-
return {
|
|
330
|
-
content: [{ type: "text", text: result.message }],
|
|
331
|
-
details: { success: false, message: result.message },
|
|
332
|
-
};
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
const { changelog } = result;
|
|
336
|
-
const message = `${result.message}\n\n## ${changelog.version}\n\n${changelog.content}`;
|
|
260
|
+
): Promise<AgentToolResult<ChangelogDetails>> {
|
|
261
|
+
// Newer than installed -> fetch from GitHub
|
|
262
|
+
if (params.version && isNewerThanInstalled(params.version)) {
|
|
263
|
+
const githubContent = await fetchGithubChangelog();
|
|
264
|
+
const changelog = findChangelogEntry(githubContent, params.version);
|
|
265
|
+
|
|
266
|
+
const message = `Changelog for ${changelog.version} (from GitHub)\n\n## ${changelog.version}\n\n${changelog.content}`;
|
|
337
267
|
return {
|
|
338
268
|
content: [{ type: "text", text: message }],
|
|
339
269
|
details: {
|
|
340
|
-
success: true,
|
|
341
|
-
message: result.message,
|
|
342
270
|
changelog,
|
|
343
|
-
source: "
|
|
271
|
+
source: "github",
|
|
344
272
|
},
|
|
345
273
|
};
|
|
346
|
-
} catch (error) {
|
|
347
|
-
const message = `Error reading Pi changelog: ${error instanceof Error ? error.message : String(error)}`;
|
|
348
|
-
return {
|
|
349
|
-
content: [{ type: "text", text: message }],
|
|
350
|
-
details: { success: false, message },
|
|
351
|
-
};
|
|
352
274
|
}
|
|
275
|
+
|
|
276
|
+
// Local
|
|
277
|
+
const local = readLocalChangelog();
|
|
278
|
+
const changelog = findChangelogEntry(local.content, params.version);
|
|
279
|
+
|
|
280
|
+
const message = `Changelog for ${changelog.version}\n\n## ${changelog.version}\n\n${changelog.content}`;
|
|
281
|
+
return {
|
|
282
|
+
content: [{ type: "text", text: message }],
|
|
283
|
+
details: {
|
|
284
|
+
changelog,
|
|
285
|
+
source: "local",
|
|
286
|
+
},
|
|
287
|
+
};
|
|
353
288
|
},
|
|
354
289
|
|
|
355
|
-
renderCall(args:
|
|
290
|
+
renderCall(args: ChangelogParams, theme: Theme) {
|
|
356
291
|
return new ToolCallHeader(
|
|
357
292
|
{
|
|
358
293
|
toolName: "Pi Changelog",
|
|
@@ -369,7 +304,8 @@ export function setupChangelogTool(pi: ExtensionAPI) {
|
|
|
369
304
|
) {
|
|
370
305
|
const { details } = result;
|
|
371
306
|
|
|
372
|
-
|
|
307
|
+
// Check for missing expected fields to detect errors
|
|
308
|
+
if (!details?.changelog) {
|
|
373
309
|
const text = result.content[0];
|
|
374
310
|
return new Text(
|
|
375
311
|
text?.type === "text" && text.text ? text.text : "No result",
|
|
@@ -382,62 +318,57 @@ export function setupChangelogTool(pi: ExtensionAPI) {
|
|
|
382
318
|
{ label: string; value: string; showCollapsed?: boolean } | Text
|
|
383
319
|
> = [];
|
|
384
320
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
321
|
+
const lines: string[] = [];
|
|
322
|
+
|
|
323
|
+
if (options.expanded) {
|
|
324
|
+
// Expanded view: show full changelog content
|
|
325
|
+
lines.push(
|
|
326
|
+
theme.fg(
|
|
327
|
+
"accent",
|
|
328
|
+
theme.bold(`Version: ${details.changelog.version}`),
|
|
329
|
+
),
|
|
330
|
+
"",
|
|
331
|
+
);
|
|
332
|
+
lines.push(...renderChangelogContent(details.changelog.content, theme));
|
|
333
|
+
fields.push(new Text(lines.join("\n"), 0, 0));
|
|
397
334
|
} else {
|
|
398
|
-
|
|
399
|
-
const sourceTag =
|
|
400
|
-
details.source === "github" ? theme.fg("muted", " (github)") : "";
|
|
401
|
-
lines.push(theme.fg("success", details.message) + sourceTag, "");
|
|
335
|
+
// Collapsed view: show version + first few lines of changelog + expand hint
|
|
402
336
|
lines.push(
|
|
403
|
-
theme.fg(
|
|
337
|
+
theme.fg(
|
|
338
|
+
"accent",
|
|
339
|
+
theme.bold(`Version: ${details.changelog.version}`),
|
|
340
|
+
),
|
|
404
341
|
"",
|
|
405
342
|
);
|
|
406
343
|
lines.push(
|
|
407
344
|
...renderChangelogContent(
|
|
408
345
|
details.changelog.content,
|
|
409
346
|
theme,
|
|
410
|
-
|
|
347
|
+
COLLAPSED_LINES,
|
|
411
348
|
),
|
|
412
349
|
);
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
theme.fg("muted", `${keyHint("app.tools.expand", "to expand")}`),
|
|
418
|
-
);
|
|
419
|
-
}
|
|
420
|
-
|
|
350
|
+
lines.push(
|
|
351
|
+
"",
|
|
352
|
+
theme.fg("muted", `${keyHint("app.tools.expand", "to expand")}`),
|
|
353
|
+
);
|
|
421
354
|
fields.push(new Text(lines.join("\n"), 0, 0));
|
|
422
355
|
}
|
|
423
356
|
|
|
357
|
+
// Footer: show source tag only
|
|
358
|
+
const footer = new ToolFooter(theme, {
|
|
359
|
+
items: [
|
|
360
|
+
{
|
|
361
|
+
label: "source",
|
|
362
|
+
value: details.source ?? "local",
|
|
363
|
+
tone: "accent",
|
|
364
|
+
},
|
|
365
|
+
],
|
|
366
|
+
});
|
|
367
|
+
|
|
424
368
|
return new ToolBody(
|
|
425
369
|
{
|
|
426
370
|
fields,
|
|
427
|
-
footer
|
|
428
|
-
items: [
|
|
429
|
-
{
|
|
430
|
-
label: "status",
|
|
431
|
-
value: details.success ? "ok" : "error",
|
|
432
|
-
tone: details.success ? "success" : "error",
|
|
433
|
-
},
|
|
434
|
-
{
|
|
435
|
-
label: "source",
|
|
436
|
-
value: details.source ?? "local",
|
|
437
|
-
tone: "accent",
|
|
438
|
-
},
|
|
439
|
-
],
|
|
440
|
-
}),
|
|
371
|
+
footer,
|
|
441
372
|
},
|
|
442
373
|
options,
|
|
443
374
|
theme,
|
|
@@ -449,72 +380,44 @@ export function setupChangelogTool(pi: ExtensionAPI) {
|
|
|
449
380
|
// pi_changelog_versions
|
|
450
381
|
// -------------------------------------------------------------------------
|
|
451
382
|
|
|
452
|
-
pi.registerTool<
|
|
383
|
+
pi.registerTool<
|
|
384
|
+
typeof ChangelogVersionsParamsSchema,
|
|
385
|
+
ChangelogVersionsDetails
|
|
386
|
+
>({
|
|
453
387
|
name: "pi_changelog_versions",
|
|
454
388
|
label: "Pi Changelog Versions",
|
|
455
389
|
description: "List all available Pi changelog versions",
|
|
390
|
+
promptSnippet: `pi_changelog_versions // List all available versions`,
|
|
456
391
|
|
|
457
|
-
parameters:
|
|
392
|
+
parameters: ChangelogVersionsParamsSchema,
|
|
458
393
|
|
|
459
394
|
async execute(
|
|
460
395
|
_toolCallId: string,
|
|
461
|
-
_params:
|
|
396
|
+
_params: ChangelogVersionsParams,
|
|
462
397
|
_signal: AbortSignal | undefined,
|
|
463
398
|
_onUpdate: unknown,
|
|
464
399
|
_ctx: ExtensionContext,
|
|
465
400
|
): Promise<AgentToolResult<ChangelogVersionsDetails>> {
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
if (!local) {
|
|
469
|
-
return {
|
|
470
|
-
content: [
|
|
471
|
-
{
|
|
472
|
-
type: "text",
|
|
473
|
-
text: "Could not locate Pi installation or CHANGELOG.md",
|
|
474
|
-
},
|
|
475
|
-
],
|
|
476
|
-
details: {
|
|
477
|
-
success: false,
|
|
478
|
-
message: "Could not locate Pi installation or CHANGELOG.md",
|
|
479
|
-
},
|
|
480
|
-
};
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
const { entries } = parseChangelogEntries(local.content);
|
|
484
|
-
if (entries.length === 0) {
|
|
485
|
-
return {
|
|
486
|
-
content: [
|
|
487
|
-
{ type: "text", text: "No version entries found in changelog" },
|
|
488
|
-
],
|
|
489
|
-
details: {
|
|
490
|
-
success: false,
|
|
491
|
-
message: "No version entries found in changelog",
|
|
492
|
-
},
|
|
493
|
-
};
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
const versions = entries.map((e) => e.version);
|
|
497
|
-
const message = `${versions.length} versions available:\n${versions.join(", ")}`;
|
|
401
|
+
const local = readLocalChangelog();
|
|
402
|
+
const { entries } = parseChangelogEntries(local.content);
|
|
498
403
|
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
details: {
|
|
502
|
-
success: true,
|
|
503
|
-
message: `Found ${versions.length} versions`,
|
|
504
|
-
versions,
|
|
505
|
-
source: "local",
|
|
506
|
-
},
|
|
507
|
-
};
|
|
508
|
-
} catch (error) {
|
|
509
|
-
const message = `Error reading changelog: ${error instanceof Error ? error.message : String(error)}`;
|
|
510
|
-
return {
|
|
511
|
-
content: [{ type: "text", text: message }],
|
|
512
|
-
details: { success: false, message },
|
|
513
|
-
};
|
|
404
|
+
if (entries.length === 0) {
|
|
405
|
+
throw new Error("No version entries found in changelog");
|
|
514
406
|
}
|
|
407
|
+
|
|
408
|
+
const versions = entries.map((e) => e.version);
|
|
409
|
+
const message = `${versions.length} versions available:\n${versions.join(", ")}`;
|
|
410
|
+
|
|
411
|
+
return {
|
|
412
|
+
content: [{ type: "text", text: message }],
|
|
413
|
+
details: {
|
|
414
|
+
versions,
|
|
415
|
+
source: "local",
|
|
416
|
+
},
|
|
417
|
+
};
|
|
515
418
|
},
|
|
516
419
|
|
|
517
|
-
renderCall(_args:
|
|
420
|
+
renderCall(_args: ChangelogVersionsParams, theme: Theme) {
|
|
518
421
|
return new ToolCallHeader({ toolName: "Pi Changelog Versions" }, theme);
|
|
519
422
|
},
|
|
520
423
|
|
|
@@ -525,7 +428,8 @@ export function setupChangelogTool(pi: ExtensionAPI) {
|
|
|
525
428
|
) {
|
|
526
429
|
const { details } = result;
|
|
527
430
|
|
|
528
|
-
|
|
431
|
+
// Check for missing expected fields to detect errors
|
|
432
|
+
if (!details?.versions) {
|
|
529
433
|
const text = result.content[0];
|
|
530
434
|
return new Text(
|
|
531
435
|
text?.type === "text" && text.text ? text.text : "No result",
|
|
@@ -538,55 +442,39 @@ export function setupChangelogTool(pi: ExtensionAPI) {
|
|
|
538
442
|
{ label: string; value: string; showCollapsed?: boolean } | Text
|
|
539
443
|
> = [];
|
|
540
444
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
"",
|
|
557
|
-
];
|
|
558
|
-
const cols = 6;
|
|
559
|
-
const maxLen = Math.max(
|
|
560
|
-
...details.versions.map((version) => version.length),
|
|
561
|
-
);
|
|
562
|
-
const colWidth = maxLen + 2;
|
|
563
|
-
for (let i = 0; i < details.versions.length; i += cols) {
|
|
564
|
-
const row = details.versions
|
|
565
|
-
.slice(i, i + cols)
|
|
566
|
-
.map((version) => version.padEnd(colWidth))
|
|
567
|
-
.join("");
|
|
568
|
-
lines.push(theme.fg("dim", row));
|
|
569
|
-
}
|
|
570
|
-
fields.push(new Text(lines.join("\n"), 0, 0));
|
|
445
|
+
const lines: string[] = [
|
|
446
|
+
theme.fg("accent", `${details.versions.length} versions available:`),
|
|
447
|
+
"",
|
|
448
|
+
];
|
|
449
|
+
const cols = 6;
|
|
450
|
+
const maxLen = Math.max(
|
|
451
|
+
...details.versions.map((version) => version.length),
|
|
452
|
+
);
|
|
453
|
+
const colWidth = maxLen + 2;
|
|
454
|
+
for (let i = 0; i < details.versions.length; i += cols) {
|
|
455
|
+
const row = details.versions
|
|
456
|
+
.slice(i, i + cols)
|
|
457
|
+
.map((version) => version.padEnd(colWidth))
|
|
458
|
+
.join("");
|
|
459
|
+
lines.push(theme.fg("dim", row));
|
|
571
460
|
}
|
|
461
|
+
fields.push(new Text(lines.join("\n"), 0, 0));
|
|
462
|
+
|
|
463
|
+
// Footer: just show version count
|
|
464
|
+
const footer = new ToolFooter(theme, {
|
|
465
|
+
items: [
|
|
466
|
+
{
|
|
467
|
+
label: "count",
|
|
468
|
+
value: String(details.versions.length),
|
|
469
|
+
tone: "accent",
|
|
470
|
+
},
|
|
471
|
+
],
|
|
472
|
+
});
|
|
572
473
|
|
|
573
474
|
return new ToolBody(
|
|
574
475
|
{
|
|
575
476
|
fields,
|
|
576
|
-
footer
|
|
577
|
-
items: [
|
|
578
|
-
{
|
|
579
|
-
label: "status",
|
|
580
|
-
value: details.success ? "ok" : "error",
|
|
581
|
-
tone: details.success ? "success" : "error",
|
|
582
|
-
},
|
|
583
|
-
{
|
|
584
|
-
label: "versions",
|
|
585
|
-
value: String(details.versions?.length ?? 0),
|
|
586
|
-
tone: "accent",
|
|
587
|
-
},
|
|
588
|
-
],
|
|
589
|
-
}),
|
|
477
|
+
footer,
|
|
590
478
|
},
|
|
591
479
|
options,
|
|
592
480
|
theme,
|