pi-web-kit 0.1.2 → 0.1.3

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/CHANGELOG.md CHANGED
@@ -6,6 +6,12 @@ This project follows the spirit of [Keep a Changelog](https://keepachangelog.com
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.1.3] - 2026-05-10
10
+
11
+ ### Added
12
+
13
+ - Install/update telemetry ping to `mocito.dev`, gated by Pi telemetry/offline settings and deduplicated per package version.
14
+
9
15
  ## [0.1.2] - 2026-05-09
10
16
 
11
17
  ### Changed
package/README.md CHANGED
@@ -98,6 +98,8 @@ Resolution order: defaults < environment variables < global config < project con
98
98
  ### Environment variables
99
99
 
100
100
  ```bash
101
+ PI_OFFLINE=1 # disables install/update telemetry
102
+ PI_TELEMETRY=0 # disables install/update telemetry
101
103
  PI_WEB_KIT_PROVIDER_SEARCH=exa_mcp|exa|tinyfish|brave|firecrawl
102
104
  PI_WEB_KIT_PROVIDER_FETCH=exa_mcp|exa|tinyfish|markdown_new|firecrawl
103
105
  EXA_API_KEY=...
package/SECURITY.md CHANGED
@@ -23,4 +23,6 @@ The maintainer will acknowledge reports as soon as practical and coordinate disc
23
23
 
24
24
  `pi-web-kit` sends search queries and fetched URLs to the configured third-party provider. Page content returned by providers is cached in memory for the lifetime of the Pi process, subject to TTL and size limits. API keys are read from environment variables or local config files and are used only for provider requests. Do not commit API keys, tokens, or config files containing secrets.
25
25
 
26
+ On startup, the extension sends a best-effort install/update telemetry ping to `mocito.dev` once per package version unless Pi telemetry is disabled or offline mode is enabled. The ping includes only the package name, version, and parsed platform/runtime/architecture from its User-Agent; it does not include prompts, queries, fetched URLs, file paths, config values, or API keys.
27
+
26
28
  The extension validates URLs before fetch calls and only accepts `http:` and `https:` URLs without embedded credentials. This validation reduces accidental misuse but does not sandbox provider responses or the local Pi process.
@@ -1,4 +1,7 @@
1
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
1
+ import { readFileSync } from "node:fs";
2
+ import { mkdir, writeFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ import { type ExtensionAPI, getAgentDir } from "@earendil-works/pi-coding-agent";
2
5
  import { Text } from "@earendil-works/pi-tui";
3
6
  import { Type } from "typebox";
4
7
  import { fetchCache, type CachedPage } from "../src/cache.js";
@@ -10,7 +13,14 @@ import { mapFetchResults } from "../src/providers/fallback.js";
10
13
  import type { FetchProviderName, SearchProviderName, WebFetchResult } from "../src/types.js";
11
14
  import { canonicalWebUrl, normalizeUrlInput } from "../src/urls.js";
12
15
 
16
+ const PACKAGE_NAME = "pi-web-kit";
17
+ const INSTALL_TELEMETRY_URL = "https://mocito.dev/api/report-install";
18
+ const INSTALL_TELEMETRY_TIMEOUT_MS = 5000;
19
+
20
+ type InstallTelemetryState = { lastReportedVersion?: string };
21
+
13
22
  export default function (pi: ExtensionAPI) {
23
+ void reportInstallTelemetry();
14
24
  pi.registerFlag("web-provider-search", {
15
25
  description: "Temporary pi-web-kit search provider override (exa_mcp, exa, tinyfish, brave, firecrawl)",
16
26
  type: "string",
@@ -158,6 +168,64 @@ function buildFetchDescription(provider: FetchProviderName): string {
158
168
  return `Fetch URL content with startup provider '${provider}'. Results are cached by URL/options; use offset/limit to read long pages in chunks. Restart/reload pi after provider changes.`;
159
169
  }
160
170
 
171
+ function readJsonFile(path: string): unknown {
172
+ try {
173
+ return JSON.parse(readFileSync(path, "utf8"));
174
+ } catch {
175
+ return {};
176
+ }
177
+ }
178
+
179
+ function isTruthyEnvFlag(value: string | undefined): boolean {
180
+ if (!value) return false;
181
+ return value === "1" || value.toLowerCase() === "true" || value.toLowerCase() === "yes";
182
+ }
183
+
184
+ function isInstallTelemetryEnabled(): boolean {
185
+ if (isTruthyEnvFlag(process.env.PI_OFFLINE)) return false;
186
+ if (process.env.PI_TELEMETRY !== undefined) return isTruthyEnvFlag(process.env.PI_TELEMETRY);
187
+ const settings = readJsonFile(join(getAgentDir(), "settings.json")) as { enableInstallTelemetry?: unknown };
188
+ return settings.enableInstallTelemetry !== false;
189
+ }
190
+
191
+ function getPackageVersion(): string {
192
+ try {
193
+ const packageJson = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")) as { version?: unknown };
194
+ return typeof packageJson.version === "string" && packageJson.version.length > 0 ? packageJson.version : "0.0.0";
195
+ } catch {
196
+ return "0.0.0";
197
+ }
198
+ }
199
+
200
+ function getInstallTelemetryUserAgent(version: string): string {
201
+ const runtimeVersions = process.versions as NodeJS.ProcessVersions & { bun?: string };
202
+ const runtime = runtimeVersions.bun ? `bun/${runtimeVersions.bun}` : `node/${process.version}`;
203
+ return `${PACKAGE_NAME}/${version} (${process.platform}; ${runtime}; ${process.arch})`;
204
+ }
205
+
206
+ export async function reportInstallTelemetry(): Promise<void> {
207
+ try {
208
+ if (!isInstallTelemetryEnabled()) return;
209
+
210
+ const version = getPackageVersion();
211
+ const telemetryDir = join(getAgentDir(), "extensions");
212
+ const statePath = join(telemetryDir, "pi-web-kit-install.json");
213
+ const state = readJsonFile(statePath) as InstallTelemetryState;
214
+ if (state.lastReportedVersion === version) return;
215
+
216
+ await mkdir(telemetryDir, { recursive: true });
217
+ await writeFile(statePath, `${JSON.stringify({ lastReportedVersion: version }, null, 2)}\n`);
218
+
219
+ const params = new URLSearchParams({ tool: PACKAGE_NAME, version });
220
+ await fetch(`${INSTALL_TELEMETRY_URL}?${params.toString()}`, {
221
+ headers: { "User-Agent": getInstallTelemetryUserAgent(version) },
222
+ signal: AbortSignal.timeout(INSTALL_TELEMETRY_TIMEOUT_MS),
223
+ });
224
+ } catch {
225
+ // Best-effort install telemetry: ignore settings, filesystem, and network failures.
226
+ }
227
+ }
228
+
161
229
  function normalizeQueries(params: Record<string, any>): string[] {
162
230
  const raw = Array.isArray(params.queries) ? params.queries : params.query ? [params.query] : [];
163
231
  const queries = [...new Set(raw.map((q) => String(q).trim()).filter(Boolean))];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-web-kit",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Context-efficient web search and fetch tools for Pi.",
5
5
  "type": "module",
6
6
  "license": "MIT",