@sagmans/dsh-tui 0.3.0 → 0.4.0

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 (113) hide show
  1. package/README.md +158 -6
  2. package/cordis.patch.yml +14 -0
  3. package/lib/agent/projections.d.ts +22 -6
  4. package/lib/agent/projections.d.ts.map +1 -1
  5. package/lib/agent/projections.js +21 -10
  6. package/lib/agent/projections.js.map +1 -1
  7. package/lib/agent/prompt-history.d.ts +89 -0
  8. package/lib/agent/prompt-history.d.ts.map +1 -0
  9. package/lib/agent/prompt-history.js +380 -0
  10. package/lib/agent/prompt-history.js.map +1 -0
  11. package/lib/agent/status.d.ts +6 -0
  12. package/lib/agent/status.d.ts.map +1 -1
  13. package/lib/agent/status.js +1 -0
  14. package/lib/agent/status.js.map +1 -1
  15. package/lib/herdr/client.d.ts +57 -0
  16. package/lib/herdr/client.d.ts.map +1 -0
  17. package/lib/herdr/client.js +218 -0
  18. package/lib/herdr/client.js.map +1 -0
  19. package/lib/herdr/constants.d.ts +93 -0
  20. package/lib/herdr/constants.d.ts.map +1 -0
  21. package/lib/herdr/constants.js +79 -0
  22. package/lib/herdr/constants.js.map +1 -0
  23. package/lib/herdr/reporter.d.ts +60 -0
  24. package/lib/herdr/reporter.d.ts.map +1 -0
  25. package/lib/herdr/reporter.js +217 -0
  26. package/lib/herdr/reporter.js.map +1 -0
  27. package/lib/herdr/state.d.ts +57 -0
  28. package/lib/herdr/state.d.ts.map +1 -0
  29. package/lib/herdr/state.js +62 -0
  30. package/lib/herdr/state.js.map +1 -0
  31. package/lib/index.d.ts.map +1 -1
  32. package/lib/index.js +252 -20
  33. package/lib/index.js.map +1 -1
  34. package/lib/input/actions.d.ts +1 -1
  35. package/lib/input/actions.d.ts.map +1 -1
  36. package/lib/input/actions.js +3 -0
  37. package/lib/input/actions.js.map +1 -1
  38. package/lib/input/ghost.d.ts +46 -0
  39. package/lib/input/ghost.d.ts.map +1 -0
  40. package/lib/input/ghost.js +58 -0
  41. package/lib/input/ghost.js.map +1 -0
  42. package/lib/input/keymap.d.ts.map +1 -1
  43. package/lib/input/keymap.js +2 -0
  44. package/lib/input/keymap.js.map +1 -1
  45. package/lib/input/submission.d.ts +24 -1
  46. package/lib/input/submission.d.ts.map +1 -1
  47. package/lib/input/submission.js +28 -1
  48. package/lib/input/submission.js.map +1 -1
  49. package/lib/stash/lock.d.ts +72 -0
  50. package/lib/stash/lock.d.ts.map +1 -0
  51. package/lib/stash/lock.js +374 -0
  52. package/lib/stash/lock.js.map +1 -0
  53. package/lib/stash/paths.d.ts +22 -0
  54. package/lib/stash/paths.d.ts.map +1 -0
  55. package/lib/stash/paths.js +83 -0
  56. package/lib/stash/paths.js.map +1 -0
  57. package/lib/stash/private-fs.d.ts +61 -0
  58. package/lib/stash/private-fs.d.ts.map +1 -0
  59. package/lib/stash/private-fs.js +379 -0
  60. package/lib/stash/private-fs.js.map +1 -0
  61. package/lib/stash/schema.d.ts +57 -0
  62. package/lib/stash/schema.d.ts.map +1 -0
  63. package/lib/stash/schema.js +127 -0
  64. package/lib/stash/schema.js.map +1 -0
  65. package/lib/stash/store.d.ts +92 -0
  66. package/lib/stash/store.d.ts.map +1 -0
  67. package/lib/stash/store.js +262 -0
  68. package/lib/stash/store.js.map +1 -0
  69. package/lib/stash.d.ts +91 -0
  70. package/lib/stash.d.ts.map +1 -0
  71. package/lib/stash.js +296 -0
  72. package/lib/stash.js.map +1 -0
  73. package/lib/theme-settings.d.ts +37 -8
  74. package/lib/theme-settings.d.ts.map +1 -1
  75. package/lib/theme-settings.js +60 -3
  76. package/lib/theme-settings.js.map +1 -1
  77. package/lib/theme-tokens.d.ts +1 -1
  78. package/lib/theme-tokens.d.ts.map +1 -1
  79. package/lib/theme-tokens.js +8 -0
  80. package/lib/theme-tokens.js.map +1 -1
  81. package/lib/todo-guard.d.ts +116 -0
  82. package/lib/todo-guard.d.ts.map +1 -0
  83. package/lib/todo-guard.js +259 -0
  84. package/lib/todo-guard.js.map +1 -0
  85. package/lib/ui/editor.d.ts +41 -1
  86. package/lib/ui/editor.d.ts.map +1 -1
  87. package/lib/ui/editor.js +98 -4
  88. package/lib/ui/editor.js.map +1 -1
  89. package/lib/ui/history-picker.d.ts +15 -0
  90. package/lib/ui/history-picker.d.ts.map +1 -0
  91. package/lib/ui/history-picker.js +26 -0
  92. package/lib/ui/history-picker.js.map +1 -0
  93. package/lib/ui/picker.d.ts +11 -1
  94. package/lib/ui/picker.d.ts.map +1 -1
  95. package/lib/ui/picker.js +17 -2
  96. package/lib/ui/picker.js.map +1 -1
  97. package/lib/ui/prompt.d.ts +2 -0
  98. package/lib/ui/prompt.d.ts.map +1 -1
  99. package/lib/ui/prompt.js +4 -0
  100. package/lib/ui/prompt.js.map +1 -1
  101. package/lib/ui/stash-picker.d.ts +43 -0
  102. package/lib/ui/stash-picker.d.ts.map +1 -0
  103. package/lib/ui/stash-picker.js +78 -0
  104. package/lib/ui/stash-picker.js.map +1 -0
  105. package/lib/ui/status.d.ts +2 -0
  106. package/lib/ui/status.d.ts.map +1 -1
  107. package/lib/ui/status.js +7 -0
  108. package/lib/ui/status.js.map +1 -1
  109. package/lib/work.d.ts +3 -1
  110. package/lib/work.d.ts.map +1 -1
  111. package/lib/work.js +9 -1
  112. package/lib/work.js.map +1 -1
  113. package/package.json +5 -1
@@ -1 +1 @@
1
- {"version":3,"file":"keymap.js","sourceRoot":"","sources":["../../src/input/keymap.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"keymap.js","sourceRoot":"","sources":["../../src/input/keymap.ts"],"names":[],"mappings":"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"}
@@ -46,6 +46,29 @@ export type Submission = {
46
46
  readonly kind: 'copy';
47
47
  } | {
48
48
  readonly kind: 'plan';
49
+ } | {
50
+ readonly kind: 'history';
51
+ readonly argument: string;
52
+ } | {
53
+ readonly kind: 'stash';
54
+ readonly argument: string;
55
+ }
56
+ /** The chord: park whatever the editor is holding, which a typed command cannot do. */
57
+ | {
58
+ readonly kind: 'stash-draft';
59
+ } | {
60
+ readonly kind: 'stash-pop';
61
+ readonly selector: string;
62
+ } | {
63
+ readonly kind: 'stash-apply';
64
+ readonly selector: string;
65
+ } | {
66
+ readonly kind: 'stash-list';
67
+ } | {
68
+ readonly kind: 'stash-drop';
69
+ readonly selector: string;
70
+ } | {
71
+ readonly kind: 'stash-clear';
49
72
  } | {
50
73
  readonly kind: 'command';
51
74
  readonly name: string;
@@ -55,7 +78,7 @@ export type Submission = {
55
78
  readonly text: string;
56
79
  };
57
80
  /** Commands the surface answers itself, without a model turn. */
58
- export declare const LOCAL_COMMANDS: readonly ["/help", "/status", "/model", "/preset", "/todo", "/theme", "/keys", "/jobs", "/subagents", "/fork", "/new", "/rename", "/export", "/copy", "/clear", "/resume", "/quit", "/exit"];
81
+ export declare const LOCAL_COMMANDS: readonly ["/help", "/status", "/model", "/preset", "/todo", "/theme", "/keys", "/jobs", "/subagents", "/fork", "/new", "/rename", "/export", "/copy", "/history", "/clear", "/resume", "/quit", "/exit", "/stash", "/stash-pop", "/stash-apply", "/stash-list", "/stash-drop", "/stash-clear"];
59
82
  /** What each local command does, shown in the editor's completion menu. */
60
83
  export declare const LOCAL_COMMAND_DESCRIPTIONS: Readonly<Record<string, string>>;
61
84
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"submission.d.ts","sourceRoot":"","sources":["../../src/input/submission.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,MAAM,MAAM,UAAU,GAClB;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC1B;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC1B;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAC3B;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAC3B;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACtD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACpD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACzD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC1B;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACpD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC1E;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAEtD,iEAAiE;AACjE,eAAO,MAAM,cAAc,8LAEjB,CAAA;AAEV,2EAA2E;AAC3E,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAmBvE,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CA4C3D"}
1
+ {"version":3,"file":"submission.d.ts","sourceRoot":"","sources":["../../src/input/submission.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  /** Commands the surface answers itself, without a model turn. */
2
2
  export const LOCAL_COMMANDS = [
3
- '/help', '/status', '/model', '/preset', '/todo', '/theme', '/keys', '/jobs', '/subagents', '/fork', '/new', '/rename', '/export', '/copy', '/clear', '/resume', '/quit', '/exit',
3
+ '/help', '/status', '/model', '/preset', '/todo', '/theme', '/keys', '/jobs', '/subagents', '/fork', '/new', '/rename', '/export', '/copy', '/history', '/clear', '/resume', '/quit', '/exit',
4
+ '/stash', '/stash-pop', '/stash-apply', '/stash-list', '/stash-drop', '/stash-clear',
4
5
  ];
5
6
  /** What each local command does, shown in the editor's completion menu. */
6
7
  export const LOCAL_COMMAND_DESCRIPTIONS = {
@@ -16,10 +17,17 @@ export const LOCAL_COMMAND_DESCRIPTIONS = {
16
17
  '/fork': 'branch this conversation and continue in the branch',
17
18
  '/new': 'start a fresh session without leaving the terminal',
18
19
  '/copy': 'copy the last answer to the clipboard through the terminal',
20
+ '/history': 'show where prompt history is kept; /history clear forgets every prompt',
19
21
  '/rename': 'give this session a title the picker will show',
20
22
  '/export': 'write the visible transcript to a markdown file',
21
23
  '/clear': 'clear the visible transcript',
22
24
  '/resume': 'open another stored session',
25
+ '/stash': 'store the draft typed after it; ctrl+x then s parks the editor',
26
+ '/stash-pop': 'put a stashed draft (newest by default) into the editor and remove it',
27
+ '/stash-apply': 'put a stashed draft (newest by default) into the editor and keep it',
28
+ '/stash-list': 'open the stashes for this directory; enter pops one',
29
+ '/stash-drop': 'delete a stashed draft (newest by default) without using it',
30
+ '/stash-clear': 'delete every stashed draft for this directory after a confirmation',
23
31
  '/quit': 'leave and print the resume command',
24
32
  '/exit': 'leave and print the resume command',
25
33
  };
@@ -74,9 +82,28 @@ export function classifySubmission(text) {
74
82
  }
75
83
  if (trimmed === '/copy')
76
84
  return { kind: 'copy' };
85
+ if (trimmed === '/history' || trimmed.startsWith('/history ')) {
86
+ return { kind: 'history', argument: trimmed.slice('/history'.length).trim() };
87
+ }
77
88
  if (trimmed === '/new' || trimmed.startsWith('/new ')) {
78
89
  return { kind: 'new', title: trimmed.slice('/new'.length).trim() };
79
90
  }
91
+ if (trimmed === '/stash-pop' || trimmed.startsWith('/stash-pop ')) {
92
+ return { kind: 'stash-pop', selector: trimmed.slice('/stash-pop'.length).trim() };
93
+ }
94
+ if (trimmed === '/stash-apply' || trimmed.startsWith('/stash-apply ')) {
95
+ return { kind: 'stash-apply', selector: trimmed.slice('/stash-apply'.length).trim() };
96
+ }
97
+ if (trimmed === '/stash-list')
98
+ return { kind: 'stash-list' };
99
+ if (trimmed === '/stash-drop' || trimmed.startsWith('/stash-drop ')) {
100
+ return { kind: 'stash-drop', selector: trimmed.slice('/stash-drop'.length).trim() };
101
+ }
102
+ if (trimmed === '/stash-clear')
103
+ return { kind: 'stash-clear' };
104
+ if (trimmed === '/stash' || trimmed.startsWith('/stash ')) {
105
+ return { kind: 'stash', argument: trimmed.slice('/stash'.length).trim() };
106
+ }
80
107
  if (trimmed.startsWith('/')) {
81
108
  const [head = ''] = trimmed.slice(1).split(/\s+/u, 1);
82
109
  const name = head.toLowerCase();
@@ -1 +1 @@
1
- {"version":3,"file":"submission.js","sourceRoot":"","sources":["../../src/input/submission.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"submission.js","sourceRoot":"","sources":["../../src/input/submission.ts"],"names":[],"mappings":"AAiCA,iEAAiE;AACjE,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO;IAC7L,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc;CAC5E,CAAA;AAEV,2EAA2E;AAC3E,MAAM,CAAC,MAAM,0BAA0B,GAAqC;IAC1E,OAAO,EAAE,oCAAoC;IAC7C,SAAS,EAAE,mDAAmD;IAC9D,QAAQ,EAAE,qFAAqF;IAC/F,SAAS,EAAE,kDAAkD;IAC7D,OAAO,EAAE,6CAA6C;IACtD,YAAY,EAAE,uFAAuF;IACrG,OAAO,EAAE,6CAA6C;IACtD,QAAQ,EAAE,kDAAkD;IAC5D,OAAO,EAAE,mEAAmE;IAC5E,OAAO,EAAE,qDAAqD;IAC9D,MAAM,EAAE,oDAAoD;IAC5D,OAAO,EAAE,4DAA4D;IACrE,UAAU,EAAE,wEAAwE;IACpF,SAAS,EAAE,gDAAgD;IAC3D,SAAS,EAAE,iDAAiD;IAC5D,QAAQ,EAAE,8BAA8B;IACxC,SAAS,EAAE,6BAA6B;IACxC,QAAQ,EAAE,gEAAgE;IAC1E,YAAY,EAAE,uEAAuE;IACrF,cAAc,EAAE,qEAAqE;IACrF,aAAa,EAAE,qDAAqD;IACpE,aAAa,EAAE,6DAA6D;IAC5E,cAAc,EAAE,oEAAoE;IACpF,OAAO,EAAE,oCAAoC;IAC7C,OAAO,EAAE,oCAAoC;CAC9C,CAAA;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;IAC3B,IAAI,OAAO,KAAK,EAAE;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IAC5C,IAAI,OAAO,KAAK,OAAO,IAAI,OAAO,KAAK,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;IACvE,IAAI,OAAO,KAAK,QAAQ;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IAClD,IAAI,OAAO,KAAK,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;IAChD,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;IACpD,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;IACpD,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAA;IAC3E,CAAC;IACD,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5D,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAA;IAC7E,CAAC;IACD,IAAI,OAAO,KAAK,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAA;IACzE,CAAC;IACD,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5D,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAA;IAC1E,CAAC;IACD,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5D,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAA;IACzE,CAAC;IACD,IAAI,OAAO,KAAK,YAAY,IAAI,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAClE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAA;IACnF,CAAC;IACD,IAAI,OAAO,KAAK,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAA;IACtE,CAAC;IACD,IAAI,OAAO,KAAK,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;IAChD,IAAI,OAAO,KAAK,QAAQ;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IAClD,IAAI,OAAO,KAAK,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAA;IACzE,CAAC;IACD,IAAI,OAAO,KAAK,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;IAChD,IAAI,OAAO,KAAK,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC9D,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAA;IAC/E,CAAC;IACD,IAAI,OAAO,KAAK,MAAM,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACtD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAA;IACpE,CAAC;IACD,IAAI,OAAO,KAAK,YAAY,IAAI,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAClE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAA;IACnF,CAAC;IACD,IAAI,OAAO,KAAK,cAAc,IAAI,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACtE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAA;IACvF,CAAC;IACD,IAAI,OAAO,KAAK,aAAa;QAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAA;IAC5D,IAAI,OAAO,KAAK,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QACpE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAA;IACrF,CAAC;IACD,IAAI,OAAO,KAAK,cAAc;QAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAA;IAC9D,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAA;IAC3E,CAAC;IACD,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5B,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;QACrD,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAA;QAC/B,OAAO,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IACnF,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;AAC1C,CAAC"}
@@ -0,0 +1,72 @@
1
+ /** Which step failed after a write already committed, so the loss is never implied. */
2
+ export type StashFailurePhase = 'directory-sync' | 'lock-release';
3
+ export interface StashFailure {
4
+ readonly phase: StashFailurePhase;
5
+ readonly error: unknown;
6
+ }
7
+ /**
8
+ * A mutation that landed on disk while a later step failed.
9
+ *
10
+ * The write is not undone — reporting it as a failure would tell the reader
11
+ * their draft was lost when it is readable — so the failure travels beside the
12
+ * result and the caller reports success plus the warning.
13
+ */
14
+ export declare class StashCommittedError<Result = unknown> extends Error {
15
+ readonly committed = true;
16
+ readonly result: Result;
17
+ readonly failure: StashFailure;
18
+ /** Set when the lock could not be released either, so both are reported. */
19
+ readonly releaseFailure: StashFailure | undefined;
20
+ constructor(result: Result, failure: StashFailure, releaseFailure?: StashFailure);
21
+ }
22
+ export interface StashMutationResult<Result> {
23
+ readonly didPersist: boolean;
24
+ readonly result: Result;
25
+ }
26
+ interface LockOwner {
27
+ readonly pid: number;
28
+ readonly host: string;
29
+ readonly token: string;
30
+ readonly createdAt: string;
31
+ }
32
+ /** Take the file lock for a read that must not observe a half-written file. */
33
+ export declare function withStashFileLock<Result>(filePath: string, operation: () => Promise<Result>): Promise<Result>;
34
+ /**
35
+ * Take the lock for a mutation, and classify an unlock failure as committed.
36
+ *
37
+ * Only a callback that reports `didPersist` turns a failed unlock into a
38
+ * committed error: an unlock failure after a refused mutation is an ordinary
39
+ * failure.
40
+ */
41
+ export declare function withStashMutationLock<Result>(filePath: string, operation: () => Promise<StashMutationResult<Result>>): Promise<Result>;
42
+ /**
43
+ * The claim a reclaimer takes, named after the bank whose lock it guards.
44
+ *
45
+ * Exported because it is the path a timeout tells the reader to clear by hand.
46
+ */
47
+ export declare function reclaimMutexPath(lockDir: string): string;
48
+ /**
49
+ * What a reclaim is allowed to act on: one reading of the lock, with the
50
+ * identity of the directory it was read from.
51
+ *
52
+ * The owner bytes alone are not enough, because the directory that held them can
53
+ * be released and replaced between the reading and the removal. A lock is only
54
+ * removed when both the identity and the token still match what was judged.
55
+ */
56
+ export interface LockObservation {
57
+ readonly owner: LockOwner | undefined;
58
+ readonly device: number;
59
+ readonly inode: number;
60
+ readonly modified: number;
61
+ }
62
+ /** Read a lock and the identity of the directory it was read from, in one pass. */
63
+ export declare function observeLock(lockDir: string): Promise<LockObservation | undefined>;
64
+ /**
65
+ * Remove the lock a judgement was made about, and nothing that replaced it.
66
+ *
67
+ * Exported so the race this exists for can be driven from a test: hold an
68
+ * observation, publish a live lock in its place, and the removal has to refuse.
69
+ */
70
+ export declare function removeObservedLock(lockDir: string, observed: LockObservation): Promise<boolean>;
71
+ export {};
72
+ //# sourceMappingURL=lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../src/stash/lock.ts"],"names":[],"mappings":"AAiDA,uFAAuF;AACvF,MAAM,MAAM,iBAAiB,GAAG,gBAAgB,GAAG,cAAc,CAAA;AAEjE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAA;IACjC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CACxB;AAED;;;;;;GAMG;AACH,qBAAa,mBAAmB,CAAC,MAAM,GAAG,OAAO,CAAE,SAAQ,KAAK;IAC9D,QAAQ,CAAC,SAAS,QAAO;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;IAC9B,4EAA4E;IAC5E,QAAQ,CAAC,cAAc,EAAE,YAAY,GAAG,SAAS,CAAA;gBAErC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,cAAc,CAAC,EAAE,YAAY;CAYjF;AAED,MAAM,WAAW,mBAAmB,CAAC,MAAM;IACzC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED,UAAU,SAAS;IACjB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC3B;AAED,+EAA+E;AAC/E,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAE7G;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAChD,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,OAAO,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,GACpD,OAAO,CAAC,MAAM,CAAC,CAGjB;AAkGD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGxD;AAyGD;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,CAAA;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B;AAED,mFAAmF;AACnF,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAUvF;AA+BD;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAOrG"}
@@ -0,0 +1,374 @@
1
+ // Private cross-process lock for one stash file.
2
+ //
3
+ // Two `dsh --profile tui` runs can share a working directory, so every read that
4
+ // feeds a write and every write itself happens under an exclusive directory
5
+ // lock: none of them can lose another's entry to a read-modify-write race.
6
+ // Ownership is recorded in the lock so a lock left by a crashed process is
7
+ // reclaimed rather than wedging the bank forever.
8
+ //
9
+ // Releasing *moves* the lock out of its path with one atomic rename before it
10
+ // judges or deletes it, and reclaiming judges a lock and removes it under a
11
+ // separate claim that only one contender can take. Removing the path on the
12
+ // strength of an earlier look would let a contender delete the live lock that
13
+ // replaced the one it judged, and two writers would then run at once.
14
+ import { createHash } from 'node:crypto';
15
+ import { link, mkdir, rename, rm } from 'node:fs/promises';
16
+ import { hostname } from 'node:os';
17
+ import path from 'node:path';
18
+ import { setTimeout as delay } from 'node:timers/promises';
19
+ import { assertPrivateDirectory, ensurePrivateDirectory, hasErrorCode, PRIVATE_DIR_MODE, readPrivateTextFile, removePrivateDirectory, writePrivateFileExclusive, } from "./private-fs.js";
20
+ import { createNewId } from "./schema.js";
21
+ const LOCK_RETRY_MS = 25;
22
+ const LOCK_TIMEOUT_MS = 2000;
23
+ const LOCK_STALE_MS = 30_000;
24
+ const LOCK_OWNER_FILE = 'owner.json';
25
+ const LOCK_TAKEOVER_SUFFIX = '.taken';
26
+ /**
27
+ * The name reclaimers link their claim file onto, so exactly one of them wins.
28
+ *
29
+ * A storage directory holds a bank per working directory, so the claim is named
30
+ * after the bank it guards: one crashed reclaimer then stops recovery for that
31
+ * bank alone instead of for every directory that shares the storage. The name is
32
+ * a digest rather than the key itself, because a key at the sanitizer's limit
33
+ * plus a suffix and a token is longer than the longest name a filesystem accepts.
34
+ */
35
+ const RECLAIM_PREFIX = '.claim-';
36
+ const RECLAIM_DIGEST_LENGTH = 16;
37
+ const LOCK_CHANGED_MESSAGE = 'stash lock changed before release';
38
+ /**
39
+ * A mutation that landed on disk while a later step failed.
40
+ *
41
+ * The write is not undone — reporting it as a failure would tell the reader
42
+ * their draft was lost when it is readable — so the failure travels beside the
43
+ * result and the caller reports success plus the warning.
44
+ */
45
+ export class StashCommittedError extends Error {
46
+ committed = true;
47
+ result;
48
+ failure;
49
+ /** Set when the lock could not be released either, so both are reported. */
50
+ releaseFailure;
51
+ constructor(result, failure, releaseFailure) {
52
+ super(releaseFailure === undefined
53
+ ? `stash mutation committed but ${failure.phase} failed`
54
+ : `stash mutation committed but ${failure.phase} and ${releaseFailure.phase} failed`, { cause: failure.error });
55
+ this.name = 'StashCommittedError';
56
+ this.result = result;
57
+ this.failure = failure;
58
+ this.releaseFailure = releaseFailure;
59
+ }
60
+ }
61
+ /** Take the file lock for a read that must not observe a half-written file. */
62
+ export function withStashFileLock(filePath, operation) {
63
+ return withStashLock(filePath, operation, false);
64
+ }
65
+ /**
66
+ * Take the lock for a mutation, and classify an unlock failure as committed.
67
+ *
68
+ * Only a callback that reports `didPersist` turns a failed unlock into a
69
+ * committed error: an unlock failure after a refused mutation is an ordinary
70
+ * failure.
71
+ */
72
+ export async function withStashMutationLock(filePath, operation) {
73
+ const outcome = await withStashLock(filePath, operation, true);
74
+ return outcome.result;
75
+ }
76
+ async function withStashLock(filePath, operation, mutation) {
77
+ await ensurePrivateDirectory(path.dirname(filePath));
78
+ const lockDir = `${filePath}.lock`;
79
+ const owner = await acquireStashLock(lockDir);
80
+ let result;
81
+ try {
82
+ result = await operation();
83
+ }
84
+ catch (operationError) {
85
+ try {
86
+ await releaseStashLock(lockDir, owner);
87
+ }
88
+ catch (releaseError) {
89
+ if (operationError instanceof StashCommittedError) {
90
+ // The mutation is on disk, and the caller has to keep hearing that: an
91
+ // AggregateError would read as a plain failure, and a retry of an
92
+ // index-based drop would then delete the draft that followed the one
93
+ // already removed. Both failed steps travel on the committed error.
94
+ throw new StashCommittedError(operationError.result, operationError.failure, {
95
+ phase: 'lock-release',
96
+ error: releaseError,
97
+ });
98
+ }
99
+ throw new AggregateError([operationError, releaseError], 'stash operation and lock release both failed');
100
+ }
101
+ throw operationError;
102
+ }
103
+ try {
104
+ await releaseStashLock(lockDir, owner);
105
+ }
106
+ catch (releaseError) {
107
+ if (mutation && isPersistedMutation(result)) {
108
+ throw new StashCommittedError(result.result, { phase: 'lock-release', error: releaseError });
109
+ }
110
+ // A read already has its answer, and the answer cannot be wrong because the
111
+ // lock outlived it: the next contender reclaims a lock whose owner is gone.
112
+ // Failing here would throw away what the caller just learned — including the
113
+ // path of a bank that was quarantined while it was being read.
114
+ if (mutation)
115
+ throw releaseError;
116
+ }
117
+ return result;
118
+ }
119
+ function isPersistedMutation(value) {
120
+ return (typeof value === 'object' &&
121
+ value !== null &&
122
+ 'didPersist' in value &&
123
+ value.didPersist === true &&
124
+ 'result' in value);
125
+ }
126
+ async function acquireStashLock(lockDir) {
127
+ const deadline = Date.now() + LOCK_TIMEOUT_MS;
128
+ for (;;) {
129
+ try {
130
+ await mkdir(lockDir, { mode: PRIVATE_DIR_MODE });
131
+ try {
132
+ await assertPrivateDirectory(lockDir, 'stash lock');
133
+ return await writeLockOwner(lockDir);
134
+ }
135
+ catch (error) {
136
+ // Losing the name while publishing it is a retry, not a failure: a
137
+ // contender that judged a lock abandoned can take the name away, and the
138
+ // owner write then either finds the name gone or finds a successor's
139
+ // owner file. Deleting the directory in either case would be deleting a
140
+ // lock this process never held, and the successor would lose its turn.
141
+ if (hasErrorCode(error, 'ENOENT') || hasErrorCode(error, 'EEXIST')) {
142
+ if (Date.now() >= deadline)
143
+ throw lockTimeout(lockDir);
144
+ continue;
145
+ }
146
+ throw error;
147
+ }
148
+ }
149
+ catch (error) {
150
+ if (!hasErrorCode(error, 'EEXIST'))
151
+ throw error;
152
+ try {
153
+ await assertPrivateDirectory(lockDir, 'stash lock');
154
+ }
155
+ catch (validationError) {
156
+ if (hasErrorCode(validationError, 'ENOENT'))
157
+ continue;
158
+ throw validationError;
159
+ }
160
+ if (await reclaimAbandonedLock(lockDir))
161
+ continue;
162
+ if (Date.now() >= deadline)
163
+ throw lockTimeout(lockDir);
164
+ await delay(LOCK_RETRY_MS);
165
+ }
166
+ }
167
+ }
168
+ function lockTimeout(lockDir) {
169
+ const mutex = reclaimMutexPath(lockDir);
170
+ return new Error(`timed out waiting for the stash lock at ${lockDir}; remove it and ${mutex} once no surface is running`);
171
+ }
172
+ /**
173
+ * The claim a reclaimer takes, named after the bank whose lock it guards.
174
+ *
175
+ * Exported because it is the path a timeout tells the reader to clear by hand.
176
+ */
177
+ export function reclaimMutexPath(lockDir) {
178
+ const digest = createHash('sha256').update(path.basename(lockDir), 'utf8').digest('hex');
179
+ return path.join(path.dirname(lockDir), `${RECLAIM_PREFIX}${digest.slice(0, RECLAIM_DIGEST_LENGTH)}`);
180
+ }
181
+ async function writeLockOwner(lockDir) {
182
+ const owner = {
183
+ pid: process.pid,
184
+ host: hostname(),
185
+ token: createNewId(),
186
+ createdAt: new Date().toISOString(),
187
+ };
188
+ await writePrivateFileExclusive(path.join(lockDir, LOCK_OWNER_FILE), `${JSON.stringify(owner)}\n`);
189
+ return owner;
190
+ }
191
+ async function readLockOwner(lockDir) {
192
+ let text;
193
+ try {
194
+ await assertPrivateDirectory(lockDir, 'stash lock');
195
+ text = (await readPrivateTextFile(path.join(lockDir, LOCK_OWNER_FILE), 'lock owner file')).text;
196
+ }
197
+ catch (error) {
198
+ if (hasErrorCode(error, 'ENOENT'))
199
+ return undefined;
200
+ throw error;
201
+ }
202
+ try {
203
+ const value = JSON.parse(text);
204
+ return isLockOwner(value) ? value : undefined;
205
+ }
206
+ catch {
207
+ return undefined;
208
+ }
209
+ }
210
+ function isLockOwner(value) {
211
+ return (typeof value === 'object' &&
212
+ value !== null &&
213
+ 'pid' in value &&
214
+ Number.isSafeInteger(value.pid) &&
215
+ 'host' in value &&
216
+ typeof value.host === 'string' &&
217
+ 'token' in value &&
218
+ typeof value.token === 'string' &&
219
+ value.token.length > 0 &&
220
+ 'createdAt' in value &&
221
+ typeof value.createdAt === 'string');
222
+ }
223
+ async function releaseStashLock(lockDir, expected) {
224
+ const taken = await takeLockDirectory(lockDir);
225
+ if (taken === undefined)
226
+ throw new Error(LOCK_CHANGED_MESSAGE);
227
+ const owner = await readLockOwner(taken);
228
+ if (owner?.token !== expected.token) {
229
+ await putBackLockDirectory(taken, lockDir);
230
+ throw new Error(LOCK_CHANGED_MESSAGE);
231
+ }
232
+ await removePrivateDirectory(taken, 'stash lock');
233
+ }
234
+ /**
235
+ * Move the lock out of its path, so only this caller can act on what it finds.
236
+ *
237
+ * One rename is atomic: two contenders cannot both take the same lock, and a
238
+ * lock published afterwards lands at the original path rather than under this
239
+ * name. Nothing is ever deleted through the path a fresh lock would occupy.
240
+ */
241
+ async function takeLockDirectory(lockDir) {
242
+ const taken = `${lockDir}${LOCK_TAKEOVER_SUFFIX}.${createNewId()}`;
243
+ try {
244
+ await rename(lockDir, taken);
245
+ }
246
+ catch (error) {
247
+ if (hasErrorCode(error, 'ENOENT') || hasErrorCode(error, 'ENOTEMPTY') || hasErrorCode(error, 'EEXIST')) {
248
+ return undefined;
249
+ }
250
+ throw error;
251
+ }
252
+ return taken;
253
+ }
254
+ /**
255
+ * Put a lock back that turned out to belong to someone else.
256
+ *
257
+ * A fresh lock at the original path means this one can never be restored. It is
258
+ * left where it is rather than deleted: whoever holds it is running, so a lock
259
+ * that is merely hard to find costs a warning on release, while a deleted one
260
+ * costs a second writer in the bank.
261
+ */
262
+ async function putBackLockDirectory(taken, lockDir) {
263
+ try {
264
+ await rename(taken, lockDir);
265
+ }
266
+ catch (error) {
267
+ if (hasErrorCode(error, 'ENOENT'))
268
+ return;
269
+ throw error;
270
+ }
271
+ }
272
+ function processIsAlive(pid) {
273
+ try {
274
+ process.kill(pid, 0);
275
+ return true;
276
+ }
277
+ catch (error) {
278
+ // Only ESRCH proves the process is gone; every other failure (permissions,
279
+ // an unknown error) is uncertainty and must keep the lock held.
280
+ return !hasErrorCode(error, 'ESRCH');
281
+ }
282
+ }
283
+ /** Read a lock and the identity of the directory it was read from, in one pass. */
284
+ export async function observeLock(lockDir) {
285
+ let stats;
286
+ try {
287
+ stats = await assertPrivateDirectory(lockDir, 'stash lock');
288
+ }
289
+ catch (error) {
290
+ if (hasErrorCode(error, 'ENOENT'))
291
+ return undefined;
292
+ throw error;
293
+ }
294
+ const owner = await readLockOwner(lockDir);
295
+ return { owner, device: stats.dev, inode: stats.ino, modified: stats.mtimeMs };
296
+ }
297
+ /**
298
+ * Reclaim a lock whose owner is gone.
299
+ *
300
+ * Reclaimers serialize on a claim file created by link, which exactly one of
301
+ * them can win, so only one of them ever judges and removes a given lock. The
302
+ * winner looks once, decides from that look, and then removes only if the lock
303
+ * still is the directory it looked at: a holder that released in between would
304
+ * otherwise leave its successor's live lock to be deleted, and both writers
305
+ * would then run at once.
306
+ *
307
+ * A reclaimer killed inside that section leaves the claim file behind, and every
308
+ * later reclaim fails closed at the timeout instead of guessing. That message
309
+ * names the file, because clearing it by hand is the one recovery that cannot
310
+ * cost an update.
311
+ */
312
+ async function reclaimAbandonedLock(lockDir) {
313
+ const mutex = reclaimMutexPath(lockDir);
314
+ const claim = await claimReclaim(mutex);
315
+ if (claim === undefined)
316
+ return false;
317
+ try {
318
+ const observed = await observeLock(lockDir);
319
+ if (observed === undefined || !isAbandonedLock(observed))
320
+ return false;
321
+ return await removeObservedLock(lockDir, observed);
322
+ }
323
+ finally {
324
+ await rm(claim, { force: true }).catch(() => undefined);
325
+ await rm(mutex, { force: true }).catch(() => undefined);
326
+ }
327
+ }
328
+ /**
329
+ * Remove the lock a judgement was made about, and nothing that replaced it.
330
+ *
331
+ * Exported so the race this exists for can be driven from a test: hold an
332
+ * observation, publish a live lock in its place, and the removal has to refuse.
333
+ */
334
+ export async function removeObservedLock(lockDir, observed) {
335
+ const current = await observeLock(lockDir);
336
+ if (current === undefined)
337
+ return false;
338
+ if (current.device !== observed.device || current.inode !== observed.inode)
339
+ return false;
340
+ if (current.owner?.token !== observed.owner?.token)
341
+ return false;
342
+ await removePrivateDirectory(lockDir, 'stash lock');
343
+ return true;
344
+ }
345
+ /** Whether one observation of a lock shows an owner that can no longer hold it. */
346
+ function isAbandonedLock(observed) {
347
+ if (observed.owner === undefined)
348
+ return Date.now() - observed.modified > LOCK_STALE_MS;
349
+ if (observed.owner.host !== hostname())
350
+ return false;
351
+ return !processIsAlive(observed.owner.pid);
352
+ }
353
+ /**
354
+ * Win the right to reclaim, by linking a private claim file onto one name.
355
+ *
356
+ * `link` is the atomic test-and-set this needs: it fails when the name exists,
357
+ * and it never replaces what is already there, so a contender that loses reads
358
+ * the winner's claim rather than breaking it.
359
+ */
360
+ async function claimReclaim(mutex) {
361
+ const claim = `${mutex}.${createNewId()}`;
362
+ await writePrivateFileExclusive(claim, `${JSON.stringify({ pid: process.pid, host: hostname() })}\n`);
363
+ try {
364
+ await link(claim, mutex);
365
+ return claim;
366
+ }
367
+ catch (error) {
368
+ await rm(claim, { force: true }).catch(() => undefined);
369
+ if (hasErrorCode(error, 'EEXIST'))
370
+ return undefined;
371
+ throw error;
372
+ }
373
+ }
374
+ //# sourceMappingURL=lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock.js","sourceRoot":"","sources":["../../src/stash/lock.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /** The stash file for one working directory. */
2
+ export interface StashPaths {
3
+ /** The exact working directory this bank belongs to. */
4
+ readonly cwd: string;
5
+ /** Flattened cwd, used as the on-disk key. */
6
+ readonly key: string;
7
+ /** JSON file holding this directory's stash entries. */
8
+ readonly file: string;
9
+ }
10
+ export declare function sanitizeCwd(cwd: string): string;
11
+ /**
12
+ * The directory the harness keeps its own state in.
13
+ *
14
+ * DSH_HOME is the one thing that moves that directory, and it is resolved the
15
+ * same way the settings document resolves it, so a scratch home keeps stash data
16
+ * out of a reader's real home during a test run.
17
+ */
18
+ export declare function dshHomeDir(env?: NodeJS.ProcessEnv, home?: string): string;
19
+ /** The root every working directory's stash file sits under. */
20
+ export declare function stashBaseDir(env?: NodeJS.ProcessEnv, home?: string): string;
21
+ export declare function resolveStashPaths(cwd: string, baseDir?: string): StashPaths;
22
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/stash/paths.ts"],"names":[],"mappings":"AAyCA,gDAAgD;AAChD,MAAM,WAAW,UAAU;IACzB,wDAAwD;IACxD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,8CAA8C;IAC9C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,wDAAwD;IACxD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAuBD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAM/C;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,EAAE,IAAI,GAAE,MAAkB,GAAG,MAAM,CAGjG;AAED,gEAAgE;AAChE,wBAAgB,YAAY,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,EAAE,IAAI,GAAE,MAAkB,GAAG,MAAM,CAEnG;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,MAAuB,GAAG,UAAU,CAG3F"}