@magicpixelart/cli 0.5.2 → 0.5.3
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 +15 -0
- package/dist/config.js +14 -6
- package/dist/util/atomicWrite.js +6 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.5.3] — 2026-06-02
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **Continuous `.magicpixel/state.json.<pid>.<hex>.tmp` churn in watch mode.**
|
|
15
|
+
`saveState()` still used `atomicWrite`, and because watch mode persists
|
|
16
|
+
state every poll, editors like VS Code visibly filled `.magicpixel/` with
|
|
17
|
+
staged `state.json.*.tmp` files before the rename landed or when file
|
|
18
|
+
watchers raced the staging path. State saves now use a direct `writeFile`
|
|
19
|
+
with `0600` permissions instead. This is safe because `state.json` is a
|
|
20
|
+
recoverable cache: if a process dies mid-write, `loadState()` already
|
|
21
|
+
quarantines corrupt JSON and the next sync re-derives the snapshot from the
|
|
22
|
+
manifest and local files. `atomicWrite` remains for durable config,
|
|
23
|
+
credentials, `AGENTS.md`, package metadata, and generated index files.
|
|
24
|
+
|
|
10
25
|
## [0.5.2] — 2026-06-02
|
|
11
26
|
|
|
12
27
|
### Fixed
|
package/dist/config.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readFile, mkdir, rename } from 'node:fs/promises';
|
|
1
|
+
import { readFile, mkdir, rename, writeFile, chmod } from 'node:fs/promises';
|
|
2
2
|
import { existsSync } from 'node:fs';
|
|
3
3
|
import { dirname, resolve } from 'node:path';
|
|
4
4
|
import { assertSafeOutDir, MAX_GLOB_LEN, validateEndpointUrl } from './util/security.js';
|
|
@@ -151,11 +151,19 @@ export async function saveState(state, cwd = process.cwd()) {
|
|
|
151
151
|
const path = statePath(cwd);
|
|
152
152
|
try {
|
|
153
153
|
await mkdir(dirname(path), { recursive: true });
|
|
154
|
-
//
|
|
155
|
-
//
|
|
156
|
-
//
|
|
157
|
-
//
|
|
158
|
-
|
|
154
|
+
// state.json is saved on every watch tick, so it must not use a visible
|
|
155
|
+
// stage-and-rename tmp path (`state.json.<pid>.<hex>.tmp`) that churns in
|
|
156
|
+
// VS Code / Vite file watchers. A torn state write is recoverable: loadState
|
|
157
|
+
// quarantines corrupt JSON and the next sync re-derives state from disk +
|
|
158
|
+
// manifest, so direct writeFile is the safer UX trade-off here. Keep
|
|
159
|
+
// atomicWrite for durable config/credentials/index writers.
|
|
160
|
+
await writeFile(path, JSON.stringify(state, null, 2) + '\n', { encoding: 'utf8', mode: 0o600 });
|
|
161
|
+
try {
|
|
162
|
+
await chmod(path, 0o600);
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
// Windows / read-only FS — ignore. The contents are non-secret sync state.
|
|
166
|
+
}
|
|
159
167
|
}
|
|
160
168
|
catch (e) {
|
|
161
169
|
throw friendlyFsError(e, {
|
package/dist/util/atomicWrite.js
CHANGED
|
@@ -3,13 +3,13 @@ import { tmpPathFor } from './security.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* Stage-and-rename file write. A crash mid-write can never leave a truncated
|
|
5
5
|
* file on disk — the rename is atomic on every POSIX FS and on NTFS. Used
|
|
6
|
-
* everywhere a corrupted target would break the project (
|
|
7
|
-
*
|
|
8
|
-
* asset
|
|
6
|
+
* everywhere a corrupted target would break the project (package.json,
|
|
7
|
+
* magicpixel.json, credentials, AGENTS.md, generated index files). High-churn
|
|
8
|
+
* `state.json` saves and asset PNG writes intentionally use direct writeFile;
|
|
9
|
+
* see CHANGELOG 0.5.2/0.5.3 for the watcher/HMR trade-offs.
|
|
9
10
|
*
|
|
10
|
-
* Accepts `string | Uint8Array`
|
|
11
|
-
*
|
|
12
|
-
* sites — see CHANGELOG 0.5.1).
|
|
11
|
+
* Accepts `string | Uint8Array` for callers that need binary-safe atomic
|
|
12
|
+
* writes, though asset bytes currently avoid this path for HMR compatibility.
|
|
13
13
|
*
|
|
14
14
|
* CRITICAL: On ANY failure between staging and rename, the tmp file is
|
|
15
15
|
* unlinked before the original error is rethrown. Without this, every rare
|