@searls/turbocommit 0.15.1 → 0.15.2

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/README.md CHANGED
@@ -33,7 +33,9 @@ turbocommit registers hooks with the harnesses you use:
33
33
  checkout, unchanged and otherwise-unclaimed paths are committed separately
34
34
  as recovered shell changes. Evidence is scoped to its exact worktree and is
35
35
  permanently discarded if file contents or executable modes change, or if an
36
- unfinished shell snapshot expires.
36
+ unfinished shell snapshot expires. Claims from a session whose turn has been
37
+ idle for over an hour no longer block shell attribution, so a turn that never
38
+ stopped cannot leave its paths unowned forever.
37
39
  - **PostToolUseFailure**, **Stop**, and **SessionEnd** finalize shell snapshots
38
40
  whose normal post hook did not arrive. Claude normally finishes within its
39
41
  SessionEnd hook. If its internal deadline expires, Turbocommit stores the
package/lib/track.js CHANGED
@@ -8,6 +8,11 @@ const { turbocommitDir } = require('./session')
8
8
  const { canonicalRoot, canonicalTrackedPath, changedPathsInRepository, gitCommonDir } = require('./git')
9
9
 
10
10
  const BASH_SNAPSHOT_TTL_MS = 60 * 60 * 1000
11
+ // A session's tracking file is rewritten on every tool call and deleted when
12
+ // its turn stops. One that has been idle this long belongs to a turn that
13
+ // never stopped, so its claims must not block other sessions from owning
14
+ // paths they change with shell commands.
15
+ const CLAIM_TTL_MS = 60 * 60 * 1000
11
16
 
12
17
  /**
13
18
  * Directory under the git common dir where turbocommit stores tracking state.
@@ -431,9 +436,11 @@ function claimedPathsBySessions (root, excludedSessionId) {
431
436
  } catch {
432
437
  files = []
433
438
  }
439
+ const cutoff = Date.now() - CLAIM_TTL_MS
434
440
  for (const file of files) {
435
441
  if (file === excludedSessionId + '.jsonl' || !file.endsWith('.jsonl')) continue
436
442
  try {
443
+ if (fs.statSync(path.join(dir, file)).mtimeMs < cutoff) continue
437
444
  const entries = fs.readFileSync(path.join(dir, file), 'utf8').trim().split('\n')
438
445
  for (const line of entries) {
439
446
  const entry = JSON.parse(line)
@@ -452,6 +459,7 @@ function claimedPathsBySessions (root, excludedSessionId) {
452
459
  for (const file of claims) {
453
460
  if (!file.endsWith('.json')) continue
454
461
  try {
462
+ if (fs.statSync(path.join(claimsDir, file)).mtimeMs < cutoff) continue
455
463
  const claim = JSON.parse(fs.readFileSync(path.join(claimsDir, file), 'utf8'))
456
464
  if (claim.sessionId === excludedSessionId || !Array.isArray(claim.entry?.files)) continue
457
465
  for (const claimed of claim.entry.files) result.add(canonicalTrackedPath(claimed))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@searls/turbocommit",
3
- "version": "0.15.1",
3
+ "version": "0.15.2",
4
4
  "description": "Auto-commit after every AI coding agent turn",
5
5
  "bin": {
6
6
  "turbocommit": "./cli.js"