pi-insomnia 0.1.3 → 0.2.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/CHANGELOG.md CHANGED
@@ -1,13 +1,28 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.3 - 2026-07-17
4
-
5
3
  All notable changes to this project will be documented in this file.
6
4
 
7
5
  This project follows the spirit of [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and uses semantic versioning for releases.
8
6
 
9
7
  ## [Unreleased]
10
8
 
9
+ ## [0.2.0] - 2026-10-09
10
+
11
+ ### Fixed
12
+
13
+ - Restrict the footer spinner to TUI mode while preserving sleep-inhibitor lifecycle in other modes.
14
+
15
+ ### Changed
16
+
17
+ - Update the shared Pi development and contract-test baseline to 1.1.0; require Node.js >=22.19.0 to match the host runtime. Pi remains a host-supplied peer dependency.
18
+ - Share install telemetry mechanics through `@mocito/install-telemetry` while preserving Pi-specific settings and state paths.
19
+
20
+ ### Fixed
21
+
22
+ - Let `enableInstallTelemetry: false` override an enabled `PI_TELEMETRY` environment flag.
23
+
24
+ ## [0.1.3] - 2026-07-17
25
+
11
26
  ### Fixed
12
27
 
13
28
  - Keep macOS sleep inhibition active across automatic retries, compaction retries, and queued follow-up work until Pi emits `agent_settled`.
@@ -20,7 +35,11 @@ This project follows the spirit of [Keep a Changelog](https://keepachangelog.com
20
35
 
21
36
  ## [0.1.1] - 2026-06-09
22
37
 
23
- ## [0.1.0] - TBD
38
+ ### Changed
39
+
40
+ - Replace the static footer icon with an animated Braille spinner while sleep inhibition is active.
41
+
42
+ ## [0.1.0] - 2026-06-08
24
43
 
25
44
  ### Added
26
45
 
package/README.md CHANGED
@@ -1,18 +1,22 @@
1
1
  # pi-insomnia
2
2
 
3
- A source-distributed [Pi](https://pi.dev) package that prevents macOS idle sleep while the Pi agent is working.
3
+ Keep long-running [Pi](https://pi.dev) tasks alive when you step away from your Mac.
4
+
5
+ `pi-insomnia` automatically prevents idle system sleep while Pi is working, then releases the sleep assertion as soon as the agent fully settles. No commands or manual activation needed.
4
6
 
5
7
  > [!WARNING]
6
8
  > Pi packages can execute arbitrary code through extensions. Review package source before installing any third-party Pi package.
7
9
 
8
10
  ## Features
9
11
 
10
- - Automatically starts a macOS sleep assertion when a Pi agent run starts.
11
- - Automatically releases the assertion when Pi settles after all retries, compaction, and queued follow-up work.
12
- - Cleans up on Pi session shutdown, reloads, and quits.
13
- - Uses the macOS built-in `/usr/bin/caffeinate` command; no third-party runtime dependency is required.
14
- - Shows a small `☕ sleep inhibited` footer status while active in UI modes.
15
- - No slash commands, tools, or manual activation needed.
12
+ - **Automatic protection** — inhibit idle sleep only while Pi has active work.
13
+ - **Full-run awareness** — stay awake through retries, compaction, and queued follow-up work, then release when Pi settles.
14
+ - **Zero setup** — use macOS built-in `caffeinate`; no commands, configuration, or third-party runtime dependency.
15
+ - **Visible state** — show a small braille spinner with `sleep inhibited` in the TUI footer while active.
16
+ - **Safe cleanup** — release assertions on session shutdown, reload, and quit.
17
+
18
+ The spinner uses palette-neutral text and does not run in print, JSON or RPC
19
+ mode. Sleep inhibition itself follows the same active-work lifecycle in all modes.
16
20
 
17
21
  ## Platform support
18
22
 
package/SECURITY.md CHANGED
@@ -25,4 +25,4 @@ Do not commit API keys, tokens, credentials, local settings, or machine-specific
25
25
 
26
26
  On macOS, the extension starts the system-provided `/usr/bin/caffeinate` helper while the Pi agent is working. It does not request elevated privileges, pass user prompts to the helper, or run shell commands. The helper is started directly with fixed arguments and is terminated when the agent becomes idle or the Pi session shuts down.
27
27
 
28
- 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, file paths, config values, environment variables, or API keys.
28
+ On startup, `@mocito/install-telemetry` sends a best-effort install/update telemetry ping to the configured telemetry endpoint 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, file paths, config values, environment variables, or API keys.
@@ -12,12 +12,12 @@ let spinnerTimer: ReturnType<typeof setInterval> | undefined;
12
12
  let spinnerFrame = 0;
13
13
 
14
14
  function setStatus(ctx: ExtensionContext, text: string | undefined): void {
15
- if (!ctx.hasUI) return;
15
+ if (ctx.mode !== "tui") return;
16
16
  ctx.ui.setStatus(STATUS_KEY, text);
17
17
  }
18
18
 
19
19
  function startSpinner(ctx: ExtensionContext): void {
20
- if (!ctx.hasUI || spinnerTimer) return;
20
+ if (ctx.mode !== "tui" || spinnerTimer) return;
21
21
  spinnerFrame = 0;
22
22
  setStatus(ctx, `${SPINNER_FRAMES[0]} sleep inhibited`);
23
23
  spinnerTimer = setInterval(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-insomnia",
3
- "version": "0.1.3",
3
+ "version": "0.2.0",
4
4
  "description": "Prevent macOS idle sleep while Pi agents are working.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -52,15 +52,18 @@
52
52
  "@earendil-works/pi-coding-agent": "*"
53
53
  },
54
54
  "devDependencies": {
55
- "@earendil-works/pi-coding-agent": "^0.80.0",
56
- "@types/node": "^26.1.0",
57
- "tsx": "^4.23.0",
58
- "typescript": "^6.0.3"
55
+ "@earendil-works/pi-coding-agent": "1.1.0",
56
+ "@types/node": "^26.6.3",
57
+ "tsx": "^4.23.15",
58
+ "typescript": "^7.0.2"
59
59
  },
60
60
  "publishConfig": {
61
61
  "access": "public"
62
62
  },
63
63
  "engines": {
64
- "node": ">=20.6.0"
64
+ "node": ">=22.19.0"
65
+ },
66
+ "dependencies": {
67
+ "@mocito/install-telemetry": "0.1.1"
65
68
  }
66
69
  }
@@ -1,12 +1,11 @@
1
1
  import { readFileSync } from "node:fs";
2
- import { mkdir, writeFile } from "node:fs/promises";
3
2
  import { join } from "node:path";
4
3
  import { fileURLToPath } from "node:url";
4
+ import { reportInstallTelemetry as report } from "@mocito/install-telemetry";
5
5
  import { getAgentDir } from "@earendil-works/pi-coding-agent";
6
6
 
7
7
  const PACKAGE_NAME = "pi-insomnia";
8
- const INSTALL_TELEMETRY_URL = "https://mocito.dev/api/report-install";
9
- const INSTALL_TELEMETRY_TIMEOUT_MS = 5000;
8
+ const INSTALL_TELEMETRY_ENDPOINT = "https://mocito.dev/api/report-install";
10
9
  const CI_ENVIRONMENT_VARIABLES = [
11
10
  "APPVEYOR",
12
11
  "BITBUCKET_BUILD_NUMBER",
@@ -24,10 +23,6 @@ const CI_ENVIRONMENT_VARIABLES = [
24
23
  "VERCEL",
25
24
  ];
26
25
 
27
- interface InstallTelemetryState {
28
- lastReportedVersion?: string;
29
- }
30
-
31
26
  interface PiSettingsDocument {
32
27
  enableInstallTelemetry?: unknown;
33
28
  }
@@ -51,18 +46,15 @@ function isPresentEnvFlag(value: string | undefined): boolean {
51
46
  return normalized !== "0" && normalized !== "false" && normalized !== "no";
52
47
  }
53
48
 
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);
49
+ export function isInstallTelemetryEnabled(env: NodeJS.ProcessEnv = process.env, settingsPath = join(getAgentDir(), "settings.json")): boolean {
50
+ if (isTruthyEnvFlag(env.CI)) return false;
51
+ if (CI_ENVIRONMENT_VARIABLES.some((name) => isPresentEnvFlag(env[name]))) return false;
52
+ if (isTruthyEnvFlag(env.PI_OFFLINE)) return false;
63
53
 
64
- const settings = readJsonFile(join(getAgentDir(), "settings.json")) as PiSettingsDocument;
65
- return settings.enableInstallTelemetry !== false;
54
+ const settings = readJsonFile(settingsPath) as PiSettingsDocument;
55
+ if (settings.enableInstallTelemetry === false) return false;
56
+ if (env.PI_TELEMETRY !== undefined) return isTruthyEnvFlag(env.PI_TELEMETRY);
57
+ return true;
66
58
  }
67
59
 
68
60
  function getPackageVersion(): string {
@@ -70,35 +62,16 @@ function getPackageVersion(): string {
70
62
  return typeof packageJson.version === "string" && packageJson.version.length > 0 ? packageJson.version : "0.0.0";
71
63
  }
72
64
 
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> {
65
+ export function reportInstallTelemetry(): void {
80
66
  try {
81
- if (!isInstallTelemetryEnabled()) return;
82
-
83
- const version = getPackageVersion();
84
- const extensionsDir = join(getAgentDir(), "extensions");
85
- const statePath = join(extensionsDir, "pi-insomnia-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
- });
67
+ void report({
68
+ endpoint: INSTALL_TELEMETRY_ENDPOINT,
69
+ tool: PACKAGE_NAME,
70
+ version: getPackageVersion(),
71
+ statePath: join(getAgentDir(), "extensions", "pi-insomnia-install.json"),
72
+ enabled: isInstallTelemetryEnabled(),
73
+ }).catch(() => undefined);
97
74
  } catch {
98
- // Best-effort telemetry: ignore settings, filesystem, and network failures.
75
+ // Best-effort telemetry: ignore local policy and filesystem failures.
99
76
  }
100
77
  }
101
-
102
- export function reportInstallTelemetry(): void {
103
- void reportInstallTelemetryAsync();
104
- }