@mkterswingman/5mghost-yonder 0.0.14 → 0.0.16

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.
@@ -11,7 +11,14 @@ export function readSharedAuth(authPath) {
11
11
  }
12
12
  }
13
13
  export function writeSharedAuth(authPath, data) {
14
- mkdirSync(dirname(authPath), { recursive: true });
14
+ const authDir = dirname(authPath);
15
+ mkdirSync(authDir, { recursive: true });
16
+ try {
17
+ chmodSync(authDir, 0o700);
18
+ }
19
+ catch {
20
+ // Why: best-effort hardening; Windows may ignore POSIX-style directory modes.
21
+ }
15
22
  const tempPath = `${authPath}.tmp`;
16
23
  writeFileSync(tempPath, JSON.stringify(data, null, 2), { encoding: "utf8", mode: 0o600 });
17
24
  renameSync(tempPath, authPath);
@@ -6,7 +6,9 @@ export interface YtDlpSchedulerState {
6
6
  }
7
7
  interface YtDlpSchedulerOptions {
8
8
  minIntervalMs?: number;
9
+ maxIntervalMs?: number;
9
10
  rateLimitBackoffMs?: number;
11
+ nextIntervalMs?: () => number;
10
12
  now?: () => number;
11
13
  sleep?: (ms: number) => Promise<void>;
12
14
  }
@@ -14,6 +16,7 @@ export interface YtDlpScheduler {
14
16
  schedule<T>(task: () => Promise<T>): Promise<T>;
15
17
  markRateLimited(): void;
16
18
  getState(): YtDlpSchedulerState;
19
+ sampleNextIntervalMs(): number;
17
20
  }
18
21
  export declare function createYtDlpScheduler(options?: YtDlpSchedulerOptions): YtDlpScheduler;
19
22
  export declare function scheduleYtDlp<T>(task: () => Promise<T>): Promise<T>;
@@ -1,10 +1,19 @@
1
- const DEFAULT_MIN_INTERVAL_MS = 5_000;
1
+ const DEFAULT_MIN_INTERVAL_MS = 3_000;
2
+ const DEFAULT_MAX_INTERVAL_MS = 7_000;
2
3
  const DEFAULT_RATE_LIMIT_BACKOFF_MS = 10 * 60_000;
3
4
  export function createYtDlpScheduler(options = {}) {
4
5
  const now = options.now ?? Date.now;
5
6
  const sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
6
7
  const minIntervalMs = options.minIntervalMs ?? DEFAULT_MIN_INTERVAL_MS;
8
+ const maxIntervalMs = options.maxIntervalMs ?? DEFAULT_MAX_INTERVAL_MS;
7
9
  const rateLimitBackoffMs = options.rateLimitBackoffMs ?? DEFAULT_RATE_LIMIT_BACKOFF_MS;
10
+ const sampleNextIntervalMs = options.nextIntervalMs ??
11
+ (() => {
12
+ if (maxIntervalMs <= minIntervalMs) {
13
+ return minIntervalMs;
14
+ }
15
+ return minIntervalMs + Math.floor(Math.random() * (maxIntervalMs - minIntervalMs + 1));
16
+ });
8
17
  let running = false;
9
18
  let pendingCount = 0;
10
19
  let nextAvailableAt = null;
@@ -36,7 +45,7 @@ export function createYtDlpScheduler(options = {}) {
36
45
  }
37
46
  finally {
38
47
  running = false;
39
- nextAvailableAt = Math.max(nextAvailableAt ?? 0, now() + minIntervalMs);
48
+ nextAvailableAt = Math.max(nextAvailableAt ?? 0, now() + sampleNextIntervalMs());
40
49
  release();
41
50
  }
42
51
  },
@@ -52,6 +61,9 @@ export function createYtDlpScheduler(options = {}) {
52
61
  wouldThrottle: running || pendingCount > 0 || (next != null && next > now()),
53
62
  };
54
63
  },
64
+ sampleNextIntervalMs() {
65
+ return sampleNextIntervalMs();
66
+ },
55
67
  };
56
68
  }
57
69
  const globalYtDlpScheduler = createYtDlpScheduler();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mkterswingman/5mghost-yonder",
3
- "version": "0.0.14",
3
+ "version": "0.0.16",
4
4
  "description": "Internal MCP client with local data tools and remote API proxy",
5
5
  "type": "module",
6
6
  "bin": {