pi-set-model 0.1.6 → 0.1.7
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 +10 -0
- package/README.md +1 -1
- package/package.json +1 -1
- package/set-model.ts +18 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.7 - 2026-08-29
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- Require Pi 0.84.4 or newer; this is the development, type-compatibility, and test baseline.
|
|
8
|
+
|
|
9
|
+
### Security
|
|
10
|
+
|
|
11
|
+
- Write preferences through an exclusively created, owner-only, randomly named temporary file before atomically replacing the preference file.
|
|
12
|
+
|
|
3
13
|
## 0.1.6 - 2026-08-27
|
|
4
14
|
|
|
5
15
|
### Changed
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# pi-set-model
|
|
2
2
|
|
|
3
|
-
Remembers Pi's selected model and thinking level for each project folder. Requires Pi 0.84.
|
|
3
|
+
Remembers Pi's selected model and thinking level for each project folder. Requires Pi 0.84.4 or newer.
|
|
4
4
|
|
|
5
5
|
After selecting a model and thinking level, explicitly save that combination for the current working directory with `/set-model set`. New Pi sessions opened in that directory restore it, rather than retaining the model selected in another project. Later thinking-level changes for the saved model automatically update the preference to match Pi's footer. A later `/model` change does not replace the saved project model unless you run `/set-model set` again.
|
|
6
6
|
|
package/package.json
CHANGED
package/set-model.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// Copyright © 2026 kapper.net - KAPPER NETWORK-COMMUNICATIONS GmbH
|
|
2
2
|
// SPDX-License-Identifier: EUPL-1.2
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { randomUUID } from "node:crypto";
|
|
5
|
+
import { mkdir, open, readFile, rename, unlink } from "node:fs/promises";
|
|
5
6
|
import { dirname, join } from "node:path";
|
|
6
7
|
import { clampThinkingLevel } from "@earendil-works/pi-ai";
|
|
7
8
|
import { CONFIG_DIR_NAME, type ExtensionAPI, type ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
@@ -60,9 +61,22 @@ export async function loadPreference(path: string): Promise<ProjectPreference |
|
|
|
60
61
|
|
|
61
62
|
export async function savePreference(path: string, preference: ProjectPreference): Promise<void> {
|
|
62
63
|
await mkdir(dirname(path), { recursive: true });
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
// Keep the temporary file in the destination directory so rename is atomic,
|
|
65
|
+
// while using an unpredictable, exclusively-created path to avoid clobbering
|
|
66
|
+
// or following files supplied by another local process.
|
|
67
|
+
const temporaryPath = `${path}.tmp-${randomUUID()}`;
|
|
68
|
+
let temporaryFile: Awaited<ReturnType<typeof open>> | undefined;
|
|
69
|
+
try {
|
|
70
|
+
temporaryFile = await open(temporaryPath, "wx", 0o600);
|
|
71
|
+
await temporaryFile.writeFile(`${JSON.stringify(preference, null, 2)}\n`, "utf8");
|
|
72
|
+
await temporaryFile.sync();
|
|
73
|
+
await temporaryFile.close();
|
|
74
|
+
temporaryFile = undefined;
|
|
75
|
+
await rename(temporaryPath, path);
|
|
76
|
+
} finally {
|
|
77
|
+
await temporaryFile?.close().catch(() => {});
|
|
78
|
+
await unlink(temporaryPath).catch(() => {});
|
|
79
|
+
}
|
|
66
80
|
}
|
|
67
81
|
|
|
68
82
|
export default function setModelExtension(pi: ExtensionAPI) {
|