@jmcombs/pi-context7 2.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.ts +78 -21
- package/package.json +2 -2
package/index.ts
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* 3. `/context7_setup` runs the same onboarding flow on demand.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
+
import type { JsonObject, JsonValue } from "@earendil-works/pi-ai";
|
|
19
20
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
20
21
|
import { onboardSecret, resolveSecret } from "@jmcombs/pi-1password";
|
|
21
22
|
import { type Static, Type } from "typebox";
|
|
@@ -33,22 +34,6 @@ interface InfoSnippet {
|
|
|
33
34
|
content?: string;
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
interface Context7SearchResult {
|
|
37
|
-
id: string;
|
|
38
|
-
title: string;
|
|
39
|
-
[key: string]: unknown;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
interface Context7SearchResponse {
|
|
43
|
-
results?: Context7SearchResult[];
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
interface Context7DocsResponse {
|
|
47
|
-
codeSnippets?: CodeSnippet[];
|
|
48
|
-
infoSnippets?: InfoSnippet[];
|
|
49
|
-
[key: string]: unknown;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
37
|
// -- Tool parameter schemas
|
|
53
38
|
|
|
54
39
|
const context7SearchSchema = Type.Object({
|
|
@@ -75,8 +60,57 @@ export type Context7GetDocsInput = Static<typeof context7GetDocsSchema>;
|
|
|
75
60
|
|
|
76
61
|
// -- Helpers
|
|
77
62
|
|
|
78
|
-
function
|
|
79
|
-
|
|
63
|
+
export function isJsonValue(value: unknown): value is JsonValue {
|
|
64
|
+
if (value === null) return true;
|
|
65
|
+
switch (typeof value) {
|
|
66
|
+
case "boolean":
|
|
67
|
+
case "number":
|
|
68
|
+
case "string":
|
|
69
|
+
return true;
|
|
70
|
+
case "object": {
|
|
71
|
+
if (Array.isArray(value)) return value.every(isJsonValue);
|
|
72
|
+
const nested: unknown[] = Object.values(value);
|
|
73
|
+
return nested.every(isJsonValue);
|
|
74
|
+
}
|
|
75
|
+
default:
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function asJsonObject(value: JsonValue): JsonObject | undefined {
|
|
81
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return undefined;
|
|
82
|
+
return value as JsonObject;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function formatDocs(data: JsonValue, query: string): string {
|
|
86
|
+
const obj = asJsonObject(data);
|
|
87
|
+
const codeSnippetsRaw = obj && Array.isArray(obj.codeSnippets) ? obj.codeSnippets : [];
|
|
88
|
+
const infoSnippetsRaw = obj && Array.isArray(obj.infoSnippets) ? obj.infoSnippets : [];
|
|
89
|
+
const codeSnippets: CodeSnippet[] = [];
|
|
90
|
+
for (const snippet of codeSnippetsRaw) {
|
|
91
|
+
const item = asJsonObject(snippet);
|
|
92
|
+
if (!item) continue;
|
|
93
|
+
const next: CodeSnippet = {};
|
|
94
|
+
if (typeof item.codeTitle === "string") next.codeTitle = item.codeTitle;
|
|
95
|
+
if (Array.isArray(item.codeList)) {
|
|
96
|
+
next.codeList = item.codeList.flatMap((entry) => {
|
|
97
|
+
const codeItem = asJsonObject(entry);
|
|
98
|
+
if (!codeItem) return [];
|
|
99
|
+
const language = typeof codeItem.language === "string" ? codeItem.language : undefined;
|
|
100
|
+
const code = typeof codeItem.code === "string" ? codeItem.code : undefined;
|
|
101
|
+
return [{ language, code }];
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
codeSnippets.push(next);
|
|
105
|
+
}
|
|
106
|
+
const infoSnippets: InfoSnippet[] = [];
|
|
107
|
+
for (const snippet of infoSnippetsRaw) {
|
|
108
|
+
const item = asJsonObject(snippet);
|
|
109
|
+
if (!item) continue;
|
|
110
|
+
const next: InfoSnippet = {};
|
|
111
|
+
if (typeof item.content === "string") next.content = item.content;
|
|
112
|
+
infoSnippets.push(next);
|
|
113
|
+
}
|
|
80
114
|
|
|
81
115
|
if (codeSnippets.length === 0 && infoSnippets.length === 0) {
|
|
82
116
|
return `No documentation snippets found for ${query}.`;
|
|
@@ -212,8 +246,24 @@ export default function (pi: ExtensionAPI): void {
|
|
|
212
246
|
};
|
|
213
247
|
}
|
|
214
248
|
|
|
215
|
-
const
|
|
216
|
-
|
|
249
|
+
const parsed: unknown = await response.json();
|
|
250
|
+
if (!isJsonValue(parsed)) {
|
|
251
|
+
return {
|
|
252
|
+
content: [{ type: "text", text: "Context7 API returned invalid JSON." }],
|
|
253
|
+
details: { error: "invalid_json" },
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
const data = parsed;
|
|
257
|
+
const obj = asJsonObject(data);
|
|
258
|
+
const libsRaw = obj && Array.isArray(obj.results) ? obj.results : [];
|
|
259
|
+
const libs: { id: string; title: string }[] = [];
|
|
260
|
+
for (const lib of libsRaw) {
|
|
261
|
+
const item = asJsonObject(lib);
|
|
262
|
+
if (!item) continue;
|
|
263
|
+
if (typeof item.id === "string" && typeof item.title === "string") {
|
|
264
|
+
libs.push({ id: item.id, title: item.title });
|
|
265
|
+
}
|
|
266
|
+
}
|
|
217
267
|
|
|
218
268
|
if (libs.length === 0) {
|
|
219
269
|
return {
|
|
@@ -346,7 +396,14 @@ export default function (pi: ExtensionAPI): void {
|
|
|
346
396
|
};
|
|
347
397
|
}
|
|
348
398
|
|
|
349
|
-
const
|
|
399
|
+
const parsed: unknown = await response.json();
|
|
400
|
+
if (!isJsonValue(parsed)) {
|
|
401
|
+
return {
|
|
402
|
+
content: [{ type: "text", text: "Context7 API returned invalid JSON." }],
|
|
403
|
+
details: { error: "invalid_json" },
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
const data = parsed;
|
|
350
407
|
return {
|
|
351
408
|
content: [{ type: "text", text: formatDocs(data, params.query) }],
|
|
352
409
|
details: { libraryId: params.libraryId, query: params.query, raw: data },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jmcombs/pi-context7",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Real-time documentation for the Pi coding agent via Context7.",
|
|
6
6
|
"homepage": "https://github.com/jmcombs/pi-extensions/tree/main/packages/context7",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"image": "https://raw.githubusercontent.com/jmcombs/pi-extensions/main/assets/context7/preview.png"
|
|
35
35
|
},
|
|
36
36
|
"engines": {
|
|
37
|
-
"node": ">=22.
|
|
37
|
+
"node": ">=22.19.0"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@jmcombs/pi-1password": "^1.0.2 || ^2.0.0"
|