claude-code-infinite 1.0.19 → 1.0.21

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.
Files changed (73) hide show
  1. package/README.md +95 -5
  2. package/dist/auto-update-runner.d.ts +52 -0
  3. package/dist/auto-update-runner.d.ts.map +1 -0
  4. package/dist/auto-update-runner.js +307 -0
  5. package/dist/auto-update-runner.js.map +1 -0
  6. package/dist/auto-update-setup.d.ts +38 -0
  7. package/dist/auto-update-setup.d.ts.map +1 -0
  8. package/dist/auto-update-setup.js +72 -0
  9. package/dist/auto-update-setup.js.map +1 -0
  10. package/dist/auto-update.d.ts +170 -0
  11. package/dist/auto-update.d.ts.map +1 -0
  12. package/dist/auto-update.js +401 -0
  13. package/dist/auto-update.js.map +1 -0
  14. package/dist/cc-request.d.ts +17 -0
  15. package/dist/cc-request.d.ts.map +1 -1
  16. package/dist/cc-request.js +22 -0
  17. package/dist/cc-request.js.map +1 -1
  18. package/dist/cli-main.js +35 -7
  19. package/dist/cli-main.js.map +1 -1
  20. package/dist/config.d.ts +4 -0
  21. package/dist/config.d.ts.map +1 -1
  22. package/dist/config.js.map +1 -1
  23. package/dist/count-tokens.d.ts +38 -3
  24. package/dist/count-tokens.d.ts.map +1 -1
  25. package/dist/count-tokens.js +88 -19
  26. package/dist/count-tokens.js.map +1 -1
  27. package/dist/memtree-finder.d.ts +11 -0
  28. package/dist/memtree-finder.d.ts.map +1 -1
  29. package/dist/memtree-finder.js +18 -0
  30. package/dist/memtree-finder.js.map +1 -1
  31. package/dist/memtree-mcp-config.d.ts.map +1 -1
  32. package/dist/memtree-mcp-config.js +4 -2
  33. package/dist/memtree-mcp-config.js.map +1 -1
  34. package/dist/memtree-mcp.d.ts +24 -4
  35. package/dist/memtree-mcp.d.ts.map +1 -1
  36. package/dist/memtree-mcp.js +47 -14
  37. package/dist/memtree-mcp.js.map +1 -1
  38. package/dist/memtree-tools.d.ts +17 -1
  39. package/dist/memtree-tools.d.ts.map +1 -1
  40. package/dist/memtree-tools.js +50 -2
  41. package/dist/memtree-tools.js.map +1 -1
  42. package/dist/memtree.d.ts +10 -1
  43. package/dist/memtree.d.ts.map +1 -1
  44. package/dist/memtree.js +54 -19
  45. package/dist/memtree.js.map +1 -1
  46. package/dist/notices.d.ts +6 -1
  47. package/dist/notices.d.ts.map +1 -1
  48. package/dist/notices.js +16 -4
  49. package/dist/notices.js.map +1 -1
  50. package/dist/proxy.d.ts +17 -1
  51. package/dist/proxy.d.ts.map +1 -1
  52. package/dist/proxy.js +137 -53
  53. package/dist/proxy.js.map +1 -1
  54. package/dist/reqlog.d.ts +10 -0
  55. package/dist/reqlog.d.ts.map +1 -1
  56. package/dist/reqlog.js.map +1 -1
  57. package/dist/request-sizing.d.ts +21 -2
  58. package/dist/request-sizing.d.ts.map +1 -1
  59. package/dist/request-sizing.js +60 -7
  60. package/dist/request-sizing.js.map +1 -1
  61. package/dist/token-estimate.d.ts +35 -0
  62. package/dist/token-estimate.d.ts.map +1 -0
  63. package/dist/token-estimate.js +97 -0
  64. package/dist/token-estimate.js.map +1 -0
  65. package/dist/update-check.d.ts +23 -4
  66. package/dist/update-check.d.ts.map +1 -1
  67. package/dist/update-check.js +79 -12
  68. package/dist/update-check.js.map +1 -1
  69. package/dist/update-lock.d.ts +68 -0
  70. package/dist/update-lock.d.ts.map +1 -0
  71. package/dist/update-lock.js +176 -0
  72. package/dist/update-lock.js.map +1 -0
  73. package/package.json +1 -1
@@ -1,19 +1,29 @@
1
1
  /**
2
2
  * Startup check for a newer claude-code-infinite release on npm.
3
3
  *
4
- * Detect-and-tell only: ccc is Claude Code's parent process, so a silent
5
- * `npm -g` write mid-session is never acceptable. The result is surfaced
4
+ * The check only detects; installing is auto-update.ts, which acts on this
5
+ * result in the background where that is safe. The result is surfaced
6
6
  * inside Claude Code through the SessionStart banner (see notices.ts) — the
7
7
  * pre-launch terminal is covered by the TUI within a second, so a line printed
8
8
  * there is never read. Bounded by a short timeout and silent on every failure
9
9
  * (registry down, offline, malformed JSON, timeout) so startup is never gated
10
- * on the registry. `CCC_SKIP_UPDATE_CHECK=1` disables the fetch entirely.
10
+ * on the registry. The registry's answer is cached for a day, so most starts
11
+ * make no request at all. `CCC_NO_UPDATE_CHECK=1` (or the older
12
+ * `CCC_SKIP_UPDATE_CHECK=1`), or `"updateCheck": false` in
13
+ * ~/.claude-code-infinite/config.json, disables the check entirely (and
14
+ * with it auto-update).
11
15
  */
16
+ import * as fs from "node:fs";
17
+ import * as path from "node:path";
12
18
  export const PACKAGE_NAME = "claude-code-infinite";
13
19
  export const NPM_LATEST_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
20
+ export const NO_UPDATE_CHECK_ENV = "CCC_NO_UPDATE_CHECK";
21
+ /** The original opt-out name, still honored. */
14
22
  export const SKIP_UPDATE_CHECK_ENV = "CCC_SKIP_UPDATE_CHECK";
15
- export const UPGRADE_COMMAND = `npm install -g ${PACKAGE_NAME}`;
16
- const UPDATE_CHECK_TIMEOUT_MS = 2000;
23
+ export const UPGRADE_COMMAND = `npm i -g ${PACKAGE_NAME}@latest`;
24
+ export const UPDATE_CHECK_TIMEOUT_MS = 1500;
25
+ export const UPDATE_CHECK_CACHE_TTL_MS = 24 * 60 * 60 * 1000;
26
+ export const UPDATE_CHECK_CACHE_FILE = "update-check.json";
17
27
  // Dotted numeric core with an optional pre-release/build suffix, as npm
18
28
  // publishes it. Anything else (a tag name, an error page) is ignored.
19
29
  const VERSION_RE = /^v?(\d+)\.(\d+)\.(\d+)(?:[-+][0-9A-Za-z.-]{0,40})?$/;
@@ -22,12 +32,36 @@ const VERSION_RE = /^v?(\d+)\.(\d+)\.(\d+)(?:[-+][0-9A-Za-z.-]{0,40})?$/;
22
32
  * of `currentVersion`, else null. Never rejects.
23
33
  */
24
34
  export async function checkForUpdate(opts) {
25
- const env = opts.env ?? process.env;
26
- if (env[SKIP_UPDATE_CHECK_ENV] === "1")
35
+ if (!updateCheckEnabled(opts.env ?? process.env, opts.config ?? {}))
27
36
  return null;
28
37
  const current = parseVersion(opts.currentVersion);
29
38
  if (current === null)
30
39
  return null;
40
+ const latestRaw = await latestVersion(opts);
41
+ const latest = latestRaw === null ? null : parseReleaseVersion(latestRaw);
42
+ if (latest === null || compareVersions(latest, current) <= 0)
43
+ return null;
44
+ return { latest: latestRaw, current: opts.currentVersion };
45
+ }
46
+ /** False when the user opted out by env (either name) or config. */
47
+ export function updateCheckEnabled(env, config) {
48
+ if (env[NO_UPDATE_CHECK_ENV] === "1" || env[SKIP_UPDATE_CHECK_ENV] === "1")
49
+ return false;
50
+ return config.updateCheck !== false;
51
+ }
52
+ /** The registry's `latest`, from a fresh cache or a bounded fetch; null on any failure. */
53
+ async function latestVersion(opts) {
54
+ const now = (opts.now ?? Date.now)();
55
+ const cached = opts.cacheFile ? readCache(opts.cacheFile) : null;
56
+ const age = cached ? now - cached.checkedAt : -1;
57
+ if (cached && age >= 0 && age < UPDATE_CHECK_CACHE_TTL_MS)
58
+ return cached.latest;
59
+ const latest = await fetchLatestVersion(opts);
60
+ if (latest !== null && opts.cacheFile)
61
+ writeCache(opts.cacheFile, { checkedAt: now, latest });
62
+ return latest;
63
+ }
64
+ async function fetchLatestVersion(opts) {
31
65
  try {
32
66
  const fetchImpl = opts.fetchImpl ?? fetch;
33
67
  const res = await fetchImpl(opts.url ?? NPM_LATEST_URL, {
@@ -37,11 +71,8 @@ export async function checkForUpdate(opts) {
37
71
  if (!res.ok)
38
72
  return null;
39
73
  const body = (await res.json());
40
- const latestRaw = typeof body?.version === "string" ? body.version : "";
41
- const latest = parseVersion(latestRaw);
42
- if (latest === null || compareVersions(latest, current) <= 0)
43
- return null;
44
- return { latest: latestRaw, current: opts.currentVersion };
74
+ const version = typeof body?.version === "string" ? body.version : "";
75
+ return parseVersion(version) === null ? null : version;
45
76
  }
46
77
  catch {
47
78
  // Registry unreachable, timed out, or answered with something that is
@@ -49,6 +80,42 @@ export async function checkForUpdate(opts) {
49
80
  return null;
50
81
  }
51
82
  }
83
+ function readCache(file) {
84
+ try {
85
+ const data = JSON.parse(fs.readFileSync(file, "utf8"));
86
+ if (typeof data?.checkedAt !== "number" || typeof data.latest !== "string")
87
+ return null;
88
+ if (parseVersion(data.latest) === null)
89
+ return null;
90
+ return { checkedAt: data.checkedAt, latest: data.latest };
91
+ }
92
+ catch {
93
+ return null;
94
+ }
95
+ }
96
+ /** Best effort and atomic: a failed write only means the next start fetches again. */
97
+ function writeCache(file, cache) {
98
+ const tmp = `${file}.${process.pid}.tmp`;
99
+ try {
100
+ fs.mkdirSync(path.dirname(file), { recursive: true, mode: 0o700 });
101
+ fs.writeFileSync(tmp, JSON.stringify(cache), { mode: 0o600 });
102
+ fs.renameSync(tmp, file);
103
+ }
104
+ catch {
105
+ try {
106
+ fs.rmSync(tmp, { force: true });
107
+ }
108
+ catch {
109
+ // Nothing more to clean up.
110
+ }
111
+ }
112
+ }
113
+ /** A release version only: prereleases (`1.2.3-beta.1`) are never offered. */
114
+ function parseReleaseVersion(version) {
115
+ if (/^v?\d+\.\d+\.\d+-/.test(version.trim()))
116
+ return null;
117
+ return parseVersion(version);
118
+ }
52
119
  /** Parse `1.2.3` (optionally `v`-prefixed / suffixed) into numeric parts. */
53
120
  export function parseVersion(version) {
54
121
  const match = VERSION_RE.exec(version.trim());
@@ -1 +1 @@
1
- {"version":3,"file":"update-check.js","sourceRoot":"","sources":["../src/update-check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,sBAAsB,CAAC;AACnD,MAAM,CAAC,MAAM,cAAc,GAAG,8BAA8B,YAAY,SAAS,CAAC;AAClF,MAAM,CAAC,MAAM,qBAAqB,GAAG,uBAAuB,CAAC;AAC7D,MAAM,CAAC,MAAM,eAAe,GAAG,kBAAkB,YAAY,EAAE,CAAC;AAChE,MAAM,uBAAuB,GAAG,IAAI,CAAC;AAErC,wEAAwE;AACxE,sEAAsE;AACtE,MAAM,UAAU,GAAG,qDAAqD,CAAC;AAiBzE;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,IAAwB;IAExB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACpC,IAAI,GAAG,CAAC,qBAAqB,CAAC,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IACpD,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAClD,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAClC,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC;QAC1C,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,cAAc,EAAE;YACtD,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;YACvC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,IAAI,uBAAuB,CAAC;SACvE,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QACzB,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA0B,CAAC;QACzD,MAAM,SAAS,GAAG,OAAO,IAAI,EAAE,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACxE,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;QACvC,IAAI,MAAM,KAAK,IAAI,IAAI,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAC1E,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,sEAAsE;QACtE,iEAAiE;QACjE,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAC9C,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,eAAe,CAC7B,CAA2B,EAC3B,CAA2B;IAE3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
1
+ {"version":3,"file":"update-check.js","sourceRoot":"","sources":["../src/update-check.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * The auto-update install lock: at most one ccc installs at a time.
3
+ *
4
+ * A directory of entries, one per acquirer, each under its own random name and
5
+ * written whole (temp file, then rename). To acquire, write your entry, then
6
+ * look at everyone else's: if any other entry is live, remove yours and back
7
+ * off. Of two acquirers, whichever looks second sees the first, so at most one
8
+ * proceeds (when both look after both wrote, both back off; the next launch
9
+ * tries again). No process ever deletes or moves a file that a live process
10
+ * owns or may be creating: an entry is removed only by its owner, or by anyone
11
+ * once it is stale, and a stale entry's owner is gone and never writes again.
12
+ *
13
+ * Each entry has one writer at a time. The launching ccc creates it and,
14
+ * right after spawning the runner, records the runner's pid; the runner waits
15
+ * for that handoff before it writes or runs anything (auto-update-runner.ts),
16
+ * and from then on owns the entry, adding npm's process group while one runs.
17
+ * An entry is live while any process it names is alive (the launcher, the
18
+ * runner, or npm's group), however old: a lock is never taken from a live
19
+ * installer by age. A pid reused by an unrelated process can keep it held;
20
+ * callers treat a lock held for over UPDATE_LOCK_STALE_MS as stuck and fall
21
+ * back to the update hint (auto-update.ts). The runner marks its entry
22
+ * `spawning` before starting npm and clears it once npm's group is recorded:
23
+ * an entry left `spawning` by a dead runner may have an unrecorded npm
24
+ * running, so it stays live (fail closed) and, after an hour, the hint shows.
25
+ * Removing update.lock.d by hand clears it.
26
+ */
27
+ /** Longer than a healthy runner lives (install timeout + kill graces + deadline). */
28
+ export declare const UPDATE_LOCK_STALE_MS: number;
29
+ /** An unreadable entry (never written whole) is garbage only after this. */
30
+ export declare const DEAD_HOLDER_GRACE_MS: number;
31
+ export interface LockEntry {
32
+ token: string;
33
+ startedAt: number;
34
+ /** The launching ccc (or the runner, once it owns the entry). */
35
+ pid?: number;
36
+ /** The runner, recorded by the launcher right after spawning it. */
37
+ runner?: number;
38
+ /** The npm process group the runner started, while it may be alive. */
39
+ group?: number;
40
+ /** Set by the runner just before starting npm, cleared once `group` is recorded. */
41
+ spawning?: boolean;
42
+ }
43
+ /**
44
+ * Acquire the lock: the owner token, or null when another entry is live (or
45
+ * changed while being judged).
46
+ *
47
+ * Each other entry is read, its named processes checked, then read again: it
48
+ * counts as stale only if every named process was gone and the entry is
49
+ * unchanged. Only named processes ever write an entry (the launcher hands
50
+ * over to the runner, which adds npm's group), and a process found gone
51
+ * before the second read cannot write after it, so an entry unchanged across
52
+ * the check stays dead and is safe to remove. A change (say, a handoff landing
53
+ * mid-check) means it may have a live owner: back off.
54
+ */
55
+ export declare function acquireUpdateLock(lockDir: string, now: number,
56
+ /** Test-only: runs between the liveness checks and the second read. */
57
+ afterLivenessCheck?: () => void): string | null;
58
+ /** Remove this token's entry (only its owner ever does, or anyone once stale). */
59
+ export declare function releaseUpdateLock(lockDir: string, token: string): void;
60
+ /**
61
+ * The launcher's one write after creating the entry: the runner's pid, so the
62
+ * entry stays live while the runner exists, even before it has run a line.
63
+ */
64
+ export declare function setLockRunner(lockDir: string, token: string, runnerPid: number): boolean;
65
+ /** When the oldest live entry was taken, or null when the lock is free. */
66
+ export declare function liveLockSince(lockDir: string, now: number): number | null;
67
+ export declare function entryPath(lockDir: string, token: string): string;
68
+ //# sourceMappingURL=update-lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-lock.d.ts","sourceRoot":"","sources":["../src/update-lock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAMH,qFAAqF;AACrF,eAAO,MAAM,oBAAoB,QAAiB,CAAC;AACnD,4EAA4E;AAC5E,eAAO,MAAM,oBAAoB,QAAY,CAAC;AAG9C,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oFAAoF;IACpF,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM;AACX,uEAAuE;AACvE,kBAAkB,CAAC,EAAE,MAAM,IAAI,GAC9B,MAAM,GAAG,IAAI,CAYf;AAED,kFAAkF;AAClF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAGtE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAIxF;AAED,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGzE;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhE"}
@@ -0,0 +1,176 @@
1
+ /**
2
+ * The auto-update install lock: at most one ccc installs at a time.
3
+ *
4
+ * A directory of entries, one per acquirer, each under its own random name and
5
+ * written whole (temp file, then rename). To acquire, write your entry, then
6
+ * look at everyone else's: if any other entry is live, remove yours and back
7
+ * off. Of two acquirers, whichever looks second sees the first, so at most one
8
+ * proceeds (when both look after both wrote, both back off; the next launch
9
+ * tries again). No process ever deletes or moves a file that a live process
10
+ * owns or may be creating: an entry is removed only by its owner, or by anyone
11
+ * once it is stale, and a stale entry's owner is gone and never writes again.
12
+ *
13
+ * Each entry has one writer at a time. The launching ccc creates it and,
14
+ * right after spawning the runner, records the runner's pid; the runner waits
15
+ * for that handoff before it writes or runs anything (auto-update-runner.ts),
16
+ * and from then on owns the entry, adding npm's process group while one runs.
17
+ * An entry is live while any process it names is alive (the launcher, the
18
+ * runner, or npm's group), however old: a lock is never taken from a live
19
+ * installer by age. A pid reused by an unrelated process can keep it held;
20
+ * callers treat a lock held for over UPDATE_LOCK_STALE_MS as stuck and fall
21
+ * back to the update hint (auto-update.ts). The runner marks its entry
22
+ * `spawning` before starting npm and clears it once npm's group is recorded:
23
+ * an entry left `spawning` by a dead runner may have an unrecorded npm
24
+ * running, so it stays live (fail closed) and, after an hour, the hint shows.
25
+ * Removing update.lock.d by hand clears it.
26
+ */
27
+ import { randomUUID } from "node:crypto";
28
+ import * as fs from "node:fs";
29
+ import * as path from "node:path";
30
+ /** Longer than a healthy runner lives (install timeout + kill graces + deadline). */
31
+ export const UPDATE_LOCK_STALE_MS = 60 * 60 * 1000;
32
+ /** An unreadable entry (never written whole) is garbage only after this. */
33
+ export const DEAD_HOLDER_GRACE_MS = 30 * 1000;
34
+ const ENTRY_SUFFIX = ".json";
35
+ /**
36
+ * Acquire the lock: the owner token, or null when another entry is live (or
37
+ * changed while being judged).
38
+ *
39
+ * Each other entry is read, its named processes checked, then read again: it
40
+ * counts as stale only if every named process was gone and the entry is
41
+ * unchanged. Only named processes ever write an entry (the launcher hands
42
+ * over to the runner, which adds npm's group), and a process found gone
43
+ * before the second read cannot write after it, so an entry unchanged across
44
+ * the check stays dead and is safe to remove. A change (say, a handoff landing
45
+ * mid-check) means it may have a live owner: back off.
46
+ */
47
+ export function acquireUpdateLock(lockDir, now,
48
+ /** Test-only: runs between the liveness checks and the second read. */
49
+ afterLivenessCheck) {
50
+ const token = randomUUID();
51
+ if (!writeLockEntry(lockDir, { token, startedAt: now, pid: process.pid }))
52
+ return null;
53
+ const others = otherEntries(lockDir, token);
54
+ const allStale = others.every((entry) => entryIsStale(entry, now));
55
+ afterLivenessCheck?.();
56
+ if (!allStale || others.some((entry) => changedSince(entry))) {
57
+ releaseUpdateLock(lockDir, token);
58
+ return null;
59
+ }
60
+ for (const entry of others)
61
+ fs.rmSync(entry.file, { force: true });
62
+ return token;
63
+ }
64
+ /** Remove this token's entry (only its owner ever does, or anyone once stale). */
65
+ export function releaseUpdateLock(lockDir, token) {
66
+ if (!/^[0-9a-f-]{36}$/.test(token))
67
+ return;
68
+ fs.rmSync(entryPath(lockDir, token), { force: true });
69
+ }
70
+ /**
71
+ * The launcher's one write after creating the entry: the runner's pid, so the
72
+ * entry stays live while the runner exists, even before it has run a line.
73
+ */
74
+ export function setLockRunner(lockDir, token, runnerPid) {
75
+ const entry = readEntry(entryPath(lockDir, token))?.data;
76
+ if (entry?.token !== token)
77
+ return false;
78
+ return writeLockEntry(lockDir, { ...entry, runner: runnerPid });
79
+ }
80
+ /** When the oldest live entry was taken, or null when the lock is free. */
81
+ export function liveLockSince(lockDir, now) {
82
+ const live = otherEntries(lockDir, "").filter((e) => e.data && !entryIsStale(e, now));
83
+ return live.length ? Math.min(...live.map((e) => e.data.startedAt)) : null;
84
+ }
85
+ export function entryPath(lockDir, token) {
86
+ return path.join(lockDir, `${token}${ENTRY_SUFFIX}`);
87
+ }
88
+ /** Atomic: readers see a whole entry or none. */
89
+ function writeLockEntry(lockDir, entry) {
90
+ const tmp = path.join(lockDir, `.${entry.token}.${process.pid}.tmp`);
91
+ try {
92
+ fs.mkdirSync(lockDir, { recursive: true, mode: 0o700 });
93
+ fs.writeFileSync(tmp, JSON.stringify(entry), { mode: 0o600 });
94
+ fs.renameSync(tmp, entryPath(lockDir, entry.token));
95
+ return true;
96
+ }
97
+ catch {
98
+ fs.rmSync(tmp, { force: true });
99
+ return false;
100
+ }
101
+ }
102
+ /** True when the entry is no longer exactly what was read (gone counts as unchanged). */
103
+ function changedSince(entry) {
104
+ const again = readEntry(entry.file);
105
+ return again !== null && (again.raw !== entry.raw || again.mtimeMs !== entry.mtimeMs);
106
+ }
107
+ function otherEntries(lockDir, token) {
108
+ let names;
109
+ try {
110
+ names = fs.readdirSync(lockDir);
111
+ }
112
+ catch {
113
+ return [];
114
+ }
115
+ return names
116
+ .filter((name) => name.endsWith(ENTRY_SUFFIX) && !name.startsWith(".") && name !== `${token}${ENTRY_SUFFIX}`)
117
+ .map((name) => readEntry(path.join(lockDir, name)))
118
+ .filter((entry) => entry !== null);
119
+ }
120
+ /** null when the file is gone (released meanwhile). */
121
+ function readEntry(file) {
122
+ let mtimeMs;
123
+ let raw;
124
+ try {
125
+ mtimeMs = fs.statSync(file).mtimeMs;
126
+ raw = fs.readFileSync(file, "utf8");
127
+ }
128
+ catch {
129
+ return null;
130
+ }
131
+ return { file, data: parseEntry(raw), mtimeMs, raw };
132
+ }
133
+ function parseEntry(raw) {
134
+ try {
135
+ const data = JSON.parse(raw);
136
+ if (typeof data?.token !== "string" || typeof data.startedAt !== "number")
137
+ return null;
138
+ const int = (v) => (Number.isInteger(v) && v > 0 ? v : undefined);
139
+ return {
140
+ token: data.token,
141
+ startedAt: data.startedAt,
142
+ pid: int(data.pid),
143
+ runner: int(data.runner),
144
+ group: int(data.group),
145
+ ...(data.spawning === true ? { spawning: true } : {}),
146
+ };
147
+ }
148
+ catch {
149
+ return null;
150
+ }
151
+ }
152
+ /** Stale only when no process it names is alive (or it was never written whole). */
153
+ function entryIsStale(entry, now) {
154
+ if (entry.data === null)
155
+ return now - entry.mtimeMs > DEAD_HOLDER_GRACE_MS;
156
+ const { pid, runner, group } = entry.data;
157
+ if (pid !== undefined && processAlive(pid))
158
+ return false;
159
+ if (runner !== undefined && processAlive(runner))
160
+ return false;
161
+ if (group !== undefined && processAlive(-group))
162
+ return false;
163
+ // Its runner died while starting npm: npm may be running unrecorded.
164
+ return entry.data.spawning !== true;
165
+ }
166
+ /** Signal 0 to a pid (or, negative, a process group). */
167
+ function processAlive(pid) {
168
+ try {
169
+ process.kill(pid, 0);
170
+ return true;
171
+ }
172
+ catch (err) {
173
+ return err.code === "EPERM";
174
+ }
175
+ }
176
+ //# sourceMappingURL=update-lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-lock.js","sourceRoot":"","sources":["../src/update-lock.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-code-infinite",
3
- "version": "1.0.19",
3
+ "version": "1.0.21",
4
4
  "description": "Wrapper for Claude Code CLI",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",