pi-extmgr 0.1.20 → 0.1.22

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.
@@ -7,9 +7,10 @@ import type {
7
7
  ExtensionCommandContext,
8
8
  ExtensionContext,
9
9
  } from "@mariozechner/pi-coding-agent";
10
- import { readFile, writeFile, mkdir, access, rename, rm } from "node:fs/promises";
10
+ import { readFile, writeFile, mkdir, rename, rm } from "node:fs/promises";
11
11
  import { homedir } from "node:os";
12
12
  import { join } from "node:path";
13
+ import { fileExists } from "./fs.js";
13
14
 
14
15
  export interface AutoUpdateConfig {
15
16
  intervalMs: number;
@@ -38,6 +39,16 @@ function isRecord(value: unknown): value is Record<string, unknown> {
38
39
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
39
40
  }
40
41
 
42
+ function isValidStringArray(value: unknown): value is string[] {
43
+ return Array.isArray(value) && value.every((item): item is string => typeof item === "string");
44
+ }
45
+
46
+ function sanitizeStringArray(value: unknown): string[] | undefined {
47
+ if (!isValidStringArray(value)) return undefined;
48
+ const sanitized = value.map((s) => s.trim()).filter(Boolean);
49
+ return sanitized.length > 0 ? sanitized : undefined;
50
+ }
51
+
41
52
  function sanitizeAutoUpdateConfig(input: unknown): AutoUpdateConfig {
42
53
  if (!isRecord(input)) {
43
54
  return { ...DEFAULT_CONFIG };
@@ -74,15 +85,9 @@ function sanitizeAutoUpdateConfig(input: unknown): AutoUpdateConfig {
74
85
  config.nextCheck = input.nextCheck;
75
86
  }
76
87
 
77
- if (Array.isArray(input.updatesAvailable)) {
78
- const updates = input.updatesAvailable
79
- .filter((value): value is string => typeof value === "string")
80
- .map((value) => value.trim())
81
- .filter(Boolean);
82
-
83
- if (updates.length > 0) {
84
- config.updatesAvailable = updates;
85
- }
88
+ const updates = sanitizeStringArray(input.updatesAvailable);
89
+ if (updates) {
90
+ config.updatesAvailable = updates;
86
91
  }
87
92
 
88
93
  if (!config.enabled || config.intervalMs === 0) {
@@ -112,18 +117,6 @@ function getSessionConfig(
112
117
  return undefined;
113
118
  }
114
119
 
115
- /**
116
- * Checks if a file exists
117
- */
118
- async function fileExists(path: string): Promise<boolean> {
119
- try {
120
- await access(path);
121
- return true;
122
- } catch {
123
- return false;
124
- }
125
- }
126
-
127
120
  /**
128
121
  * Ensures the settings directory exists
129
122
  */
@@ -198,7 +191,6 @@ async function writeConfigToDisk(config: AutoUpdateConfig): Promise<void> {
198
191
 
199
192
  function enqueueConfigWrite(config: AutoUpdateConfig): void {
200
193
  settingsWriteQueue = settingsWriteQueue
201
- .catch(() => undefined)
202
194
  .then(() => writeConfigToDisk(config))
203
195
  .catch((error) => {
204
196
  console.warn("[extmgr] Failed to write settings:", error);
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Timer utilities for auto-update functionality.
3
+ */
4
+
5
+ export type TimerCallback = () => void;
6
+
7
+ let timerId: ReturnType<typeof setInterval> | null = null;
8
+
9
+ /**
10
+ * Start a recurring timer with the given interval and callback.
11
+ * Clears any existing timer first.
12
+ */
13
+ export function startTimer(intervalMs: number, callback: TimerCallback): void {
14
+ stopTimer();
15
+
16
+ if (intervalMs <= 0) return;
17
+
18
+ timerId = setInterval(callback, intervalMs);
19
+ }
20
+
21
+ /**
22
+ * Stop the current timer if running.
23
+ */
24
+ export function stopTimer(): void {
25
+ if (!timerId) return;
26
+
27
+ clearInterval(timerId);
28
+ timerId = null;
29
+ }
30
+
31
+ /**
32
+ * Check if a timer is currently running.
33
+ */
34
+ export function isTimerRunning(): boolean {
35
+ return timerId !== null;
36
+ }