scalemax 0.1.13 → 0.1.14

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.
@@ -13,14 +13,14 @@ export async function writeManagedConfig(ctx, id, name, file, content) {
13
13
  throw new Error(`Refusing to overwrite unmanaged configuration: ${file}`);
14
14
  }
15
15
  const backup = await backupFile(file, ctx.home);
16
- await atomicWrite(file, content, 0o600);
16
+ await atomicWrite(file, content, 0o600, ctx.platform);
17
17
  return { id, name, changed: true, path: file, message: backup ? `configured (backup: ${backup})` : 'configured' };
18
18
  }
19
19
  export async function writeMergedJsonConfig(ctx, id, name, file, build) {
20
20
  await fs.ensureDir(path.dirname(file));
21
21
  const existing = await readJson(file, {});
22
22
  const backup = await backupFile(file, ctx.home);
23
- await atomicWrite(file, build(existing), 0o600);
23
+ await atomicWrite(file, build(existing), 0o600, ctx.platform);
24
24
  return { id, name, changed: true, path: file, message: backup ? `configured (backup: ${backup})` : 'configured' };
25
25
  }
26
26
  async function latestRestorableBackup(file, home) {
@@ -1,5 +1,6 @@
1
1
  export declare function exists(p: string): Promise<boolean>;
2
- export declare function atomicWrite(file: string, content: string, mode?: number): Promise<void>;
2
+ export declare function syncParentDirectory(directory: string, platform?: NodeJS.Platform): Promise<void>;
3
+ export declare function atomicWrite(file: string, content: string, mode?: number, platform?: NodeJS.Platform): Promise<void>;
3
4
  export declare function backupNameFor(file: string): string;
4
5
  export declare function backupFile(file: string, home: string): Promise<string | undefined>;
5
6
  export declare function listBackups(file: string, home: string): Promise<string[]>;
package/dist/utils/fs.js CHANGED
@@ -4,7 +4,20 @@ import crypto from 'node:crypto';
4
4
  import path from 'node:path';
5
5
  import { backupDir, timestamp } from './paths.js';
6
6
  export async function exists(p) { return fs.pathExists(p); }
7
- export async function atomicWrite(file, content, mode = 0o600) {
7
+ export async function syncParentDirectory(directory, platform = process.platform) {
8
+ // Windows does not support fsync on directory handles and commonly returns EPERM.
9
+ // The file itself is still fsynced before the atomic rename on every platform.
10
+ if (platform === 'win32')
11
+ return;
12
+ const dir = await fsp.open(directory, 'r');
13
+ try {
14
+ await dir.sync();
15
+ }
16
+ finally {
17
+ await dir.close();
18
+ }
19
+ }
20
+ export async function atomicWrite(file, content, mode = 0o600, platform = process.platform) {
8
21
  await fs.ensureDir(path.dirname(file));
9
22
  const existing = await fs.lstat(file).catch(() => undefined);
10
23
  if (existing?.isSymbolicLink())
@@ -19,13 +32,7 @@ export async function atomicWrite(file, content, mode = 0o600) {
19
32
  handle = undefined;
20
33
  await fsp.rename(tmp, file);
21
34
  await fsp.chmod(file, mode);
22
- const dir = await fsp.open(path.dirname(file), 'r');
23
- try {
24
- await dir.sync();
25
- }
26
- finally {
27
- await dir.close();
28
- }
35
+ await syncParentDirectory(path.dirname(file), platform);
29
36
  }
30
37
  finally {
31
38
  if (handle)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scalemax",
3
- "version": "0.1.13",
3
+ "version": "0.1.14",
4
4
  "description": "Universal ScaleMax installer for AI coding clients",
5
5
  "type": "module",
6
6
  "bin": {