@bdsqqq/pi 0.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.
Files changed (99) hide show
  1. package/dist/chunk-DsIazq42.js +26 -0
  2. package/dist/command-palette-B97yKqne.js +406 -0
  3. package/dist/core/agents-md.d.ts +22 -0
  4. package/dist/core/agents-md.js +174 -0
  5. package/dist/core/box-chrome.d.ts +56 -0
  6. package/dist/core/box-chrome.js +207 -0
  7. package/dist/core/box-format.d.ts +82 -0
  8. package/dist/core/box-format.js +381 -0
  9. package/dist/core/config.d.ts +14 -0
  10. package/dist/core/config.js +201 -0
  11. package/dist/core/file-tracker.d.ts +65 -0
  12. package/dist/core/file-tracker.js +439 -0
  13. package/dist/core/github-api.d.ts +45 -0
  14. package/dist/core/github-api.js +101 -0
  15. package/dist/core/html-to-md.d.ts +5 -0
  16. package/dist/core/html-to-md.js +289 -0
  17. package/dist/core/interpolate.d.ts +44 -0
  18. package/dist/core/interpolate.js +475 -0
  19. package/dist/core/mutex.d.ts +8 -0
  20. package/dist/core/mutex.js +142 -0
  21. package/dist/core/output-buffer.d.ts +80 -0
  22. package/dist/core/output-buffer.js +517 -0
  23. package/dist/core/permissions.d.ts +19 -0
  24. package/dist/core/permissions.js +140 -0
  25. package/dist/core/pi-spawn.d.ts +62 -0
  26. package/dist/core/pi-spawn.js +244 -0
  27. package/dist/core/prompt-patch.d.ts +11 -0
  28. package/dist/core/prompt-patch.js +16 -0
  29. package/dist/core/show-renderer.d.ts +10 -0
  30. package/dist/core/show-renderer.js +39 -0
  31. package/dist/core/show.d.ts +29 -0
  32. package/dist/core/show.js +288 -0
  33. package/dist/core/sub-agent-render.d.ts +56 -0
  34. package/dist/core/sub-agent-render.js +579 -0
  35. package/dist/core/tool-cost.d.ts +17 -0
  36. package/dist/core/tool-cost.js +58 -0
  37. package/dist/core/tui.d.ts +9 -0
  38. package/dist/core/tui.js +33 -0
  39. package/dist/editor-BljciPdx.js +537 -0
  40. package/dist/extensions/bash.d.ts +12 -0
  41. package/dist/extensions/bash.js +261 -0
  42. package/dist/extensions/code-review.d.ts +14 -0
  43. package/dist/extensions/code-review.js +175 -0
  44. package/dist/extensions/command-palette.d.ts +6 -0
  45. package/dist/extensions/command-palette.js +2 -0
  46. package/dist/extensions/create-file.d.ts +7 -0
  47. package/dist/extensions/create-file.js +88 -0
  48. package/dist/extensions/edit-file.d.ts +7 -0
  49. package/dist/extensions/edit-file.js +395 -0
  50. package/dist/extensions/editor.d.ts +6 -0
  51. package/dist/extensions/editor.js +2 -0
  52. package/dist/extensions/finder.d.ts +13 -0
  53. package/dist/extensions/finder.js +108 -0
  54. package/dist/extensions/format-file.d.ts +11 -0
  55. package/dist/extensions/format-file.js +145 -0
  56. package/dist/extensions/github.d.ts +13 -0
  57. package/dist/extensions/github.js +527 -0
  58. package/dist/extensions/glob.d.ts +10 -0
  59. package/dist/extensions/glob.js +163 -0
  60. package/dist/extensions/grep.d.ts +13 -0
  61. package/dist/extensions/grep.js +356 -0
  62. package/dist/extensions/handoff.d.ts +6 -0
  63. package/dist/extensions/handoff.js +277 -0
  64. package/dist/extensions/librarian.d.ts +13 -0
  65. package/dist/extensions/librarian.js +113 -0
  66. package/dist/extensions/look-at.d.ts +13 -0
  67. package/dist/extensions/look-at.js +121 -0
  68. package/dist/extensions/ls.d.ts +8 -0
  69. package/dist/extensions/ls.js +87 -0
  70. package/dist/extensions/mermaid.d.ts +20 -0
  71. package/dist/extensions/mermaid.js +2 -0
  72. package/dist/extensions/oracle.d.ts +13 -0
  73. package/dist/extensions/oracle.js +143 -0
  74. package/dist/extensions/read-session.d.ts +13 -0
  75. package/dist/extensions/read-session.js +265 -0
  76. package/dist/extensions/read-web-page.d.ts +11 -0
  77. package/dist/extensions/read-web-page.js +234 -0
  78. package/dist/extensions/read.d.ts +23 -0
  79. package/dist/extensions/read.js +323 -0
  80. package/dist/extensions/search-sessions.d.ts +29 -0
  81. package/dist/extensions/search-sessions.js +426 -0
  82. package/dist/extensions/session-name.d.ts +6 -0
  83. package/dist/extensions/session-name.js +54 -0
  84. package/dist/extensions/skill.d.ts +7 -0
  85. package/dist/extensions/skill.js +232 -0
  86. package/dist/extensions/system-prompt.d.ts +6 -0
  87. package/dist/extensions/system-prompt.js +31 -0
  88. package/dist/extensions/task.d.ts +11 -0
  89. package/dist/extensions/task.js +114 -0
  90. package/dist/extensions/tool-harness.d.ts +6 -0
  91. package/dist/extensions/tool-harness.js +37 -0
  92. package/dist/extensions/undo-edit.d.ts +7 -0
  93. package/dist/extensions/undo-edit.js +127 -0
  94. package/dist/extensions/web-search.d.ts +12 -0
  95. package/dist/extensions/web-search.js +254 -0
  96. package/dist/extensions.d.ts +29 -0
  97. package/dist/extensions.js +29 -0
  98. package/dist/mermaid-C7xCVBrw.js +95296 -0
  99. package/package.json +67 -0
@@ -0,0 +1,254 @@
1
+ import { withPromptPatch } from "../core/prompt-patch.js";
2
+ import { boxRendererWindowed, osc8Link } from "../core/box-format.js";
3
+ import { getExtensionConfig } from "../core/config.js";
4
+ import { spawn } from "node:child_process";
5
+ import { Text } from "@mariozechner/pi-tui";
6
+ import { Type } from "@sinclair/typebox";
7
+ //#region packages/extensions/web-search/index.ts
8
+ /**
9
+ * web_search tool — direct HTTP call to Parallel AI's Search API.
10
+ *
11
+ * uses curl (not fetch/SDK) because pi extensions run in a nix-built
12
+ * environment where adding npm deps requires a rebuild. curl is always
13
+ * available and the single-endpoint usage doesn't justify the SDK.
14
+ *
15
+ * cost is derived from the response's usage array, not hardcoded —
16
+ * the API returns UsageItem[] with SKU counts, we multiply by known
17
+ * unit prices. if the API omits usage, we fall back to base search cost.
18
+ *
19
+ * refs:
20
+ * schema: https://docs.parallel.ai/public-openapi.json (UsageItem)
21
+ * pricing: https://docs.parallel.ai/pricing (Search API section)
22
+ */
23
+ const CONFIG_DEFAULTS = {
24
+ defaultMaxResults: 10,
25
+ endpoint: "https://api.parallel.ai/v1beta/search",
26
+ curlTimeoutSecs: 30
27
+ };
28
+ /** per-result excerpts for collapsed display — first 5 visual lines */
29
+ const COLLAPSED_EXCERPTS = [{
30
+ focus: "head",
31
+ context: 5
32
+ }];
33
+ /** per-unit pricing by SKU name ($/unit). ref: https://docs.parallel.ai/pricing */
34
+ const SKU_UNIT_COST = {
35
+ sku_search: .005,
36
+ sku_search_additional_results: .001
37
+ };
38
+ /** falls back to base search cost when API omits usage (e.g., older API versions). */
39
+ function costFromUsage(usage) {
40
+ if (!usage?.length) return SKU_UNIT_COST.sku_search ?? 0;
41
+ let total = 0;
42
+ for (const item of usage) total += (SKU_UNIT_COST[item.name] ?? 0) * item.count;
43
+ return total;
44
+ }
45
+ function searchParallel(apiKey, body, endpoint, curlTimeoutSecs, signal) {
46
+ return new Promise((resolve) => {
47
+ const payload = JSON.stringify(body);
48
+ const child = spawn("curl", [
49
+ "-sL",
50
+ "-X",
51
+ "POST",
52
+ "-H",
53
+ "Content-Type: application/json",
54
+ "-H",
55
+ `x-api-key: ${apiKey}`,
56
+ "-H",
57
+ "parallel-beta: search-extract-2025-10-10",
58
+ "-m",
59
+ String(curlTimeoutSecs),
60
+ "-d",
61
+ payload,
62
+ endpoint
63
+ ], { stdio: [
64
+ "ignore",
65
+ "pipe",
66
+ "pipe"
67
+ ] });
68
+ let stdout = "";
69
+ let stderr = "";
70
+ let aborted = false;
71
+ const onAbort = () => {
72
+ aborted = true;
73
+ if (!child.killed) child.kill("SIGTERM");
74
+ };
75
+ if (signal) if (signal.aborted) onAbort();
76
+ else signal.addEventListener("abort", onAbort, { once: true });
77
+ child.stdout?.on("data", (data) => {
78
+ stdout += data.toString("utf-8");
79
+ });
80
+ child.stderr?.on("data", (data) => {
81
+ stderr += data.toString("utf-8");
82
+ });
83
+ child.on("error", (err) => {
84
+ signal?.removeEventListener("abort", onAbort);
85
+ resolve({ error: `curl error: ${err.message}` });
86
+ });
87
+ child.on("close", (code) => {
88
+ signal?.removeEventListener("abort", onAbort);
89
+ if (aborted) {
90
+ resolve({ error: "search aborted" });
91
+ return;
92
+ }
93
+ if (code !== 0) {
94
+ resolve({ error: `search failed: ${stderr.trim() || `curl exited with code ${code}`}` });
95
+ return;
96
+ }
97
+ try {
98
+ resolve({ data: JSON.parse(stdout) });
99
+ } catch {
100
+ resolve({ error: `invalid response from Parallel API: ${stdout.slice(0, 200)}` });
101
+ }
102
+ });
103
+ });
104
+ }
105
+ function formatResults(results) {
106
+ if (results.length === 0) return {
107
+ text: "(no results found)",
108
+ headerLineIndices: []
109
+ };
110
+ const lines = [];
111
+ const headerLineIndices = [];
112
+ for (let i = 0; i < results.length; i++) {
113
+ const r = results[i];
114
+ headerLineIndices.push(lines.length);
115
+ lines.push(`### ${r.title || "(untitled)"}`);
116
+ lines.push(r.url);
117
+ if (r.publish_date) lines.push(`*${r.publish_date}*`);
118
+ if (r.excerpts?.length) {
119
+ lines.push("");
120
+ for (let j = 0; j < r.excerpts.length; j++) {
121
+ const excerptLines = r.excerpts[j].split("\n");
122
+ lines.push(...excerptLines);
123
+ if (j < r.excerpts.length - 1) lines.push("");
124
+ }
125
+ }
126
+ if (i < results.length - 1) {
127
+ lines.push("");
128
+ lines.push("---");
129
+ lines.push("");
130
+ }
131
+ }
132
+ return {
133
+ text: lines.join("\n"),
134
+ headerLineIndices
135
+ };
136
+ }
137
+ /** convert raw SearchResult[] into BoxSection[] for box-format rendering. */
138
+ function resultsToSections(results) {
139
+ return results.map((r) => {
140
+ const lines = [];
141
+ lines.push({
142
+ text: osc8Link(r.url, r.url),
143
+ highlight: true
144
+ });
145
+ if (r.publish_date) lines.push({
146
+ text: r.publish_date,
147
+ highlight: true
148
+ });
149
+ if (r.excerpts?.length) {
150
+ lines.push({
151
+ text: "",
152
+ highlight: false
153
+ });
154
+ for (let j = 0; j < r.excerpts.length; j++) {
155
+ for (const l of r.excerpts[j].split("\n")) lines.push({
156
+ text: l,
157
+ highlight: false
158
+ });
159
+ if (j < r.excerpts.length - 1) lines.push({
160
+ text: "",
161
+ highlight: false
162
+ });
163
+ }
164
+ }
165
+ return {
166
+ header: r.title || "(untitled)",
167
+ blocks: [{ lines }]
168
+ };
169
+ });
170
+ }
171
+ function createWebSearchTool(config = CONFIG_DEFAULTS) {
172
+ return {
173
+ name: "web_search",
174
+ label: "Web Search",
175
+ description: "Search the web for information relevant to a research objective.\n\nUse when you need up-to-date or precise documentation. Use `read_web_page` to fetch full content from a specific URL.\n\n# Examples\n\nGet API documentation for a specific provider\n```json\n{\"objective\":\"I want to know the request fields for the Stripe billing create customer API. Prefer Stripe's docs site.\"}\n```\n\nSee usage documentation for newly released library features\n```json\n{\"objective\":\"I want to know how to use SvelteKit remote functions, which is a new feature shipped in the last month.\",\"search_queries\":[\"sveltekit\",\"remote function\"]}\n```",
176
+ parameters: Type.Object({
177
+ objective: Type.String({ description: "A natural-language description of the broader task or research goal, including any source or freshness guidance." }),
178
+ search_queries: Type.Optional(Type.Array(Type.String(), { description: "Optional keyword queries to ensure matches for specific terms are prioritized (recommended for best results)." })),
179
+ max_results: Type.Optional(Type.Number({ description: `The maximum number of results to return (default: ${config.defaultMaxResults}).` }))
180
+ }),
181
+ async execute(_toolCallId, params, signal) {
182
+ const p = params;
183
+ const apiKey = process.env.PARALLEL_API_KEY;
184
+ if (!apiKey) return {
185
+ content: [{
186
+ type: "text",
187
+ text: "PARALLEL_API_KEY not set. add it to secrets.yaml and export in shell.nix."
188
+ }],
189
+ isError: true
190
+ };
191
+ const body = {
192
+ objective: p.objective,
193
+ max_results: p.max_results ?? config.defaultMaxResults,
194
+ excerpts: { max_chars_per_result: 2e3 }
195
+ };
196
+ if (p.search_queries?.length) body.search_queries = p.search_queries;
197
+ const { data, error } = await searchParallel(apiKey, body, config.endpoint, config.curlTimeoutSecs, signal);
198
+ if (error) return {
199
+ content: [{
200
+ type: "text",
201
+ text: error
202
+ }],
203
+ isError: true
204
+ };
205
+ if (!data?.results) return { content: [{
206
+ type: "text",
207
+ text: "(no results)"
208
+ }] };
209
+ const { text, headerLineIndices } = formatResults(data.results);
210
+ let output = text;
211
+ if (data.warnings?.length) output += `\n\n**Warnings:** ${data.warnings.join("; ")}`;
212
+ const resultSections = resultsToSections(data.results);
213
+ const details = {
214
+ cost: costFromUsage(data.usage),
215
+ matchLineIndices: headerLineIndices,
216
+ resultSections
217
+ };
218
+ return {
219
+ content: [{
220
+ type: "text",
221
+ text: output
222
+ }],
223
+ details
224
+ };
225
+ },
226
+ renderCall(args, theme) {
227
+ const objective = args.objective || "...";
228
+ const short = objective.length > 70 ? `${objective.slice(0, 70)}...` : objective;
229
+ let text = theme.fg("toolTitle", theme.bold("web_search ")) + theme.fg("dim", short);
230
+ if (args.search_queries?.length) text += theme.fg("muted", ` [${args.search_queries.join(", ")}]`);
231
+ return new Text(text, 0, 0);
232
+ },
233
+ renderResult(result, { expanded }, _theme) {
234
+ const sections = result.details?.resultSections;
235
+ if (!sections?.length) {
236
+ const text = result.content?.[0];
237
+ return new Text(text?.type === "text" ? text.text : "(no output)", 0, 0);
238
+ }
239
+ return boxRendererWindowed(() => sections, {
240
+ collapsed: {
241
+ maxSections: 3,
242
+ excerpts: COLLAPSED_EXCERPTS
243
+ },
244
+ expanded: {}
245
+ }, void 0, expanded);
246
+ }
247
+ };
248
+ }
249
+ function web_search_default(pi) {
250
+ const cfg = getExtensionConfig("@bds_pi/web-search", CONFIG_DEFAULTS);
251
+ pi.registerTool(withPromptPatch(createWebSearchTool(cfg)));
252
+ }
253
+ //#endregion
254
+ export { createWebSearchTool, web_search_default as default };
@@ -0,0 +1,29 @@
1
+ import export_default from "./extensions/bash.js";
2
+ import export_default$1 from "./extensions/code-review.js";
3
+ import commandPaletteExtension from "./extensions/command-palette.js";
4
+ import export_default$2 from "./extensions/create-file.js";
5
+ import export_default$3 from "./extensions/edit-file.js";
6
+ import export_default$4 from "./extensions/editor.js";
7
+ import export_default$5 from "./extensions/finder.js";
8
+ import export_default$6 from "./extensions/format-file.js";
9
+ import export_default$7 from "./extensions/github.js";
10
+ import export_default$8 from "./extensions/glob.js";
11
+ import export_default$9 from "./extensions/grep.js";
12
+ import export_default$10 from "./extensions/handoff.js";
13
+ import export_default$11 from "./extensions/librarian.js";
14
+ import export_default$12 from "./extensions/look-at.js";
15
+ import export_default$15 from "./extensions/read.js";
16
+ import export_default$13 from "./extensions/ls.js";
17
+ import mermaidInlineExtension from "./extensions/mermaid.js";
18
+ import export_default$14 from "./extensions/oracle.js";
19
+ import export_default$16 from "./extensions/read-session.js";
20
+ import export_default$17 from "./extensions/read-web-page.js";
21
+ import export_default$18 from "./extensions/search-sessions.js";
22
+ import export_default$19 from "./extensions/session-name.js";
23
+ import export_default$20 from "./extensions/skill.js";
24
+ import export_default$21 from "./extensions/system-prompt.js";
25
+ import export_default$22 from "./extensions/task.js";
26
+ import export_default$23 from "./extensions/tool-harness.js";
27
+ import export_default$24 from "./extensions/undo-edit.js";
28
+ import export_default$25 from "./extensions/web-search.js";
29
+ export { export_default as bash, export_default$1 as codeReview, commandPaletteExtension as commandPalette, export_default$2 as createFile, export_default$3 as editFile, export_default$4 as editor, export_default$5 as finder, export_default$6 as formatFile, export_default$7 as github, export_default$8 as glob, export_default$9 as grep, export_default$10 as handoff, export_default$11 as librarian, export_default$12 as lookAt, export_default$13 as ls, mermaidInlineExtension as mermaid, export_default$14 as oracle, export_default$15 as read, export_default$16 as readSession, export_default$17 as readWebPage, export_default$18 as searchSessions, export_default$19 as sessionName, export_default$20 as skill, export_default$21 as systemPrompt, export_default$22 as task, export_default$23 as toolHarness, export_default$24 as undoEdit, export_default$25 as webSearch };
@@ -0,0 +1,29 @@
1
+ import read_default from "./extensions/read.js";
2
+ import bash_default from "./extensions/bash.js";
3
+ import code_review_default from "./extensions/code-review.js";
4
+ import { t as commandPaletteExtension } from "./command-palette-B97yKqne.js";
5
+ import create_file_default from "./extensions/create-file.js";
6
+ import edit_file_default from "./extensions/edit-file.js";
7
+ import { t as editor_default } from "./editor-BljciPdx.js";
8
+ import finder_default from "./extensions/finder.js";
9
+ import format_file_default from "./extensions/format-file.js";
10
+ import github_default from "./extensions/github.js";
11
+ import glob_default from "./extensions/glob.js";
12
+ import grep_default from "./extensions/grep.js";
13
+ import handoff_default from "./extensions/handoff.js";
14
+ import librarian_default from "./extensions/librarian.js";
15
+ import look_at_default from "./extensions/look-at.js";
16
+ import ls_default from "./extensions/ls.js";
17
+ import { t as mermaidInlineExtension } from "./mermaid-C7xCVBrw.js";
18
+ import oracle_default from "./extensions/oracle.js";
19
+ import read_session_default from "./extensions/read-session.js";
20
+ import read_web_page_default from "./extensions/read-web-page.js";
21
+ import search_sessions_default from "./extensions/search-sessions.js";
22
+ import session_name_default from "./extensions/session-name.js";
23
+ import skill_default from "./extensions/skill.js";
24
+ import system_prompt_default from "./extensions/system-prompt.js";
25
+ import task_default from "./extensions/task.js";
26
+ import tool_harness_default from "./extensions/tool-harness.js";
27
+ import undo_edit_default from "./extensions/undo-edit.js";
28
+ import web_search_default from "./extensions/web-search.js";
29
+ export { bash_default as bash, code_review_default as codeReview, commandPaletteExtension as commandPalette, create_file_default as createFile, edit_file_default as editFile, editor_default as editor, finder_default as finder, format_file_default as formatFile, github_default as github, glob_default as glob, grep_default as grep, handoff_default as handoff, librarian_default as librarian, look_at_default as lookAt, ls_default as ls, mermaidInlineExtension as mermaid, oracle_default as oracle, read_default as read, read_session_default as readSession, read_web_page_default as readWebPage, search_sessions_default as searchSessions, session_name_default as sessionName, skill_default as skill, system_prompt_default as systemPrompt, task_default as task, tool_harness_default as toolHarness, undo_edit_default as undoEdit, web_search_default as webSearch };