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.
- package/README.md +25 -17
- package/package.json +2 -2
- package/src/commands/registry.ts +12 -8
- package/src/constants.ts +48 -17
- package/src/packages/extensions.ts +252 -31
- package/src/packages/install.ts +17 -28
- package/src/packages/management.ts +2 -58
- package/src/types/index.ts +7 -6
- package/src/ui/footer.ts +67 -0
- package/src/ui/help.ts +1 -0
- package/src/ui/package-config.ts +361 -0
- package/src/ui/unified.ts +87 -163
- package/src/utils/auto-update.ts +10 -18
- package/src/utils/format.ts +31 -16
- package/src/utils/history.ts +22 -16
- package/src/utils/settings.ts +15 -23
- package/src/utils/timer.ts +36 -0
package/src/utils/settings.ts
CHANGED
|
@@ -7,9 +7,10 @@ import type {
|
|
|
7
7
|
ExtensionCommandContext,
|
|
8
8
|
ExtensionContext,
|
|
9
9
|
} from "@mariozechner/pi-coding-agent";
|
|
10
|
-
import { readFile, writeFile, mkdir,
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
+
}
|