pi-scout 0.1.0 → 0.1.2

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,18 @@ This project follows the spirit of [Keep a Changelog](https://keepachangelog.com
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.1.2] - 2026-06-06
10
+
11
+ ### Changed
12
+
13
+ - Update `author` field to full name for monorepo consistency.
14
+
15
+ ## [0.1.1] - TBD
16
+
17
+ ### Added
18
+
19
+ - Add install/update telemetry ping to `mocito.dev`, gated by Pi telemetry/offline settings and disabled in CI.
20
+
9
21
  ## [0.1.0] - TBD
10
22
 
11
23
  ### Added
package/README.md CHANGED
@@ -43,6 +43,14 @@ pi -e /path/to/pi-mono/packages/pi-scout --print "list your tools"
43
43
 
44
44
  This is an npm-compatible TypeScript Pi package. There is no runtime build step.
45
45
 
46
+ ## Configuration
47
+
48
+ | Variable | Purpose |
49
+ |---|---|
50
+ | `PI_SCOUT_TMPDIR` | Overrides the parent directory for temporary clones. |
51
+ | `PI_OFFLINE=1` | Disables install/update telemetry. |
52
+ | `PI_TELEMETRY=0` | Disables install/update telemetry. |
53
+
46
54
  ## Quick usage
47
55
 
48
56
  Open the Pi Scout menu:
@@ -75,6 +83,7 @@ After a repository is registered, the agent sees its local path in the system pr
75
83
 
76
84
  ## Notes
77
85
 
86
+ - On startup, Pi Scout sends a best-effort install/update telemetry ping once per package version unless Pi telemetry is disabled, offline mode is enabled, or Pi runs in CI.
78
87
  - Pi Scout uses local file access for exploration. It does not provide web search or remote content-fetching tools.
79
88
  - Registering a Git URL still uses `git clone`, so Git may contact the configured remote.
80
89
  - Registered repositories are intended as read-only references unless the user explicitly asks otherwise.
package/SECURITY.md CHANGED
@@ -23,4 +23,6 @@ The maintainer will acknowledge reports as soon as practical and coordinate disc
23
23
 
24
24
  Do not commit API keys, tokens, credentials, local settings, or machine-specific paths.
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, offline mode is enabled, or Pi runs in CI. The ping includes only the package name, version, and parsed platform/runtime/architecture from its User-Agent; it does not include prompts, repository sources, clone paths, config values, or API keys.
27
+
26
28
  `pi-scout` stores repository records under Pi's agent directory and clones registered repositories into the OS temporary directory. It does not provide web search or content-fetching tools, but registering a Git URL uses `git clone`, which may contact the configured remote. Registered repository paths are appended to the system prompt so the agent can inspect them with local file tools.
@@ -1,5 +1,6 @@
1
1
  import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
2
2
  import { Type } from "typebox";
3
+ import { reportInstallTelemetry } from "../src/install-telemetry.js";
3
4
  import { buildScoutPrompt, formatRepo, loadPrunedState, registerRepo, removeRepo } from "../src/index.js";
4
5
 
5
6
  const RegisterRepoParams = Type.Object({
@@ -12,6 +13,8 @@ const RemoveRepoParams = Type.Object({
12
13
  });
13
14
 
14
15
  export default function piScout(pi: ExtensionAPI) {
16
+ reportInstallTelemetry();
17
+
15
18
  let scoutRmRegistered = false;
16
19
 
17
20
  function setToolActive(name: string, active: boolean): void {
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "pi-scout",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Register local reference codebases for Pi agent exploration.",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
- "author": "jvm",
7
+ "author": "Jose Mocito",
8
8
  "repository": {
9
9
  "type": "git",
10
10
  "url": "git+https://github.com/jvm/pi-mono.git",
@@ -51,7 +51,7 @@
51
51
  "typebox": "*"
52
52
  },
53
53
  "devDependencies": {
54
- "@earendil-works/pi-coding-agent": "^0.74.0",
54
+ "@earendil-works/pi-coding-agent": "^0.75.4",
55
55
  "@types/node": "^25.6.2",
56
56
  "typebox": "^1.1.33",
57
57
  "typescript": "^6.0.3"
@@ -0,0 +1,104 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { mkdir, writeFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { getAgentDir } from "@earendil-works/pi-coding-agent";
6
+
7
+ const PACKAGE_NAME = "pi-scout";
8
+ const INSTALL_TELEMETRY_URL = "https://mocito.dev/api/report-install";
9
+ const INSTALL_TELEMETRY_TIMEOUT_MS = 5000;
10
+ const CI_ENVIRONMENT_VARIABLES = [
11
+ "APPVEYOR",
12
+ "BITBUCKET_BUILD_NUMBER",
13
+ "BUILDKITE",
14
+ "CIRCLECI",
15
+ "CODESPACES",
16
+ "DRONE",
17
+ "GITHUB_ACTIONS",
18
+ "GITLAB_CI",
19
+ "JENKINS_URL",
20
+ "NETLIFY",
21
+ "TEAMCITY_VERSION",
22
+ "TF_BUILD",
23
+ "TRAVIS",
24
+ "VERCEL",
25
+ ];
26
+
27
+ interface InstallTelemetryState {
28
+ lastReportedVersion?: string;
29
+ }
30
+
31
+ interface PiSettingsDocument {
32
+ enableInstallTelemetry?: unknown;
33
+ }
34
+
35
+ function readJsonFile(path: string): unknown {
36
+ try {
37
+ return JSON.parse(readFileSync(path, "utf8")) as unknown;
38
+ } catch {
39
+ return {};
40
+ }
41
+ }
42
+
43
+ function isTruthyEnvFlag(value: string | undefined): boolean {
44
+ if (!value) return false;
45
+ return value === "1" || value.toLowerCase() === "true" || value.toLowerCase() === "yes";
46
+ }
47
+
48
+ function isPresentEnvFlag(value: string | undefined): boolean {
49
+ if (!value) return false;
50
+ const normalized = value.toLowerCase();
51
+ return normalized !== "0" && normalized !== "false" && normalized !== "no";
52
+ }
53
+
54
+ function isCiEnvironment(): boolean {
55
+ if (isTruthyEnvFlag(process.env.CI)) return true;
56
+ return CI_ENVIRONMENT_VARIABLES.some((name) => isPresentEnvFlag(process.env[name]));
57
+ }
58
+
59
+ function isInstallTelemetryEnabled(): boolean {
60
+ if (isCiEnvironment()) return false;
61
+ if (isTruthyEnvFlag(process.env.PI_OFFLINE)) return false;
62
+ if (process.env.PI_TELEMETRY !== undefined) return isTruthyEnvFlag(process.env.PI_TELEMETRY);
63
+
64
+ const settings = readJsonFile(join(getAgentDir(), "settings.json")) as PiSettingsDocument;
65
+ return settings.enableInstallTelemetry !== false;
66
+ }
67
+
68
+ function getPackageVersion(): string {
69
+ const packageJson = readJsonFile(fileURLToPath(new URL("../package.json", import.meta.url))) as { version?: unknown };
70
+ return typeof packageJson.version === "string" && packageJson.version.length > 0 ? packageJson.version : "0.0.0";
71
+ }
72
+
73
+ function getInstallTelemetryUserAgent(version: string): string {
74
+ const runtimeVersions = process.versions as NodeJS.ProcessVersions & { bun?: string };
75
+ const runtime = runtimeVersions.bun ? `bun/${runtimeVersions.bun}` : `node/${process.version}`;
76
+ return `${PACKAGE_NAME}/${version} (${process.platform}; ${runtime}; ${process.arch})`;
77
+ }
78
+
79
+ async function reportInstallTelemetryAsync(): Promise<void> {
80
+ try {
81
+ if (!isInstallTelemetryEnabled()) return;
82
+
83
+ const version = getPackageVersion();
84
+ const extensionsDir = join(getAgentDir(), "extensions");
85
+ const statePath = join(extensionsDir, "pi-scout-install.json");
86
+ const state = readJsonFile(statePath) as InstallTelemetryState;
87
+ if (state.lastReportedVersion === version) return;
88
+
89
+ await mkdir(extensionsDir, { recursive: true });
90
+ await writeFile(statePath, `${JSON.stringify({ lastReportedVersion: version }, null, 2)}\n`, "utf8");
91
+
92
+ const params = new URLSearchParams({ tool: PACKAGE_NAME, version });
93
+ await fetch(`${INSTALL_TELEMETRY_URL}?${params.toString()}`, {
94
+ headers: { "User-Agent": getInstallTelemetryUserAgent(version) },
95
+ signal: AbortSignal.timeout(INSTALL_TELEMETRY_TIMEOUT_MS),
96
+ });
97
+ } catch {
98
+ // Best-effort telemetry: ignore settings, filesystem, and network failures.
99
+ }
100
+ }
101
+
102
+ export function reportInstallTelemetry(): void {
103
+ void reportInstallTelemetryAsync();
104
+ }