@berthdev/berth 0.3.6 → 0.4.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.
Files changed (136) hide show
  1. package/README.md +7 -1
  2. package/dist/src/agents/capabilities.d.ts +13 -0
  3. package/dist/src/agents/capabilities.js +52 -0
  4. package/dist/src/agents/capabilities.js.map +1 -0
  5. package/dist/src/agents/codex-binding.d.ts +10 -0
  6. package/dist/src/agents/codex-binding.js +105 -0
  7. package/dist/src/agents/codex-binding.js.map +1 -0
  8. package/dist/src/agents/commands.d.ts +4 -2
  9. package/dist/src/agents/commands.js +41 -9
  10. package/dist/src/agents/commands.js.map +1 -1
  11. package/dist/src/agents/copilot-state.d.ts +3 -0
  12. package/dist/src/agents/copilot-state.js +94 -0
  13. package/dist/src/agents/copilot-state.js.map +1 -0
  14. package/dist/src/agents/gemini-state.d.ts +3 -0
  15. package/dist/src/agents/gemini-state.js +41 -0
  16. package/dist/src/agents/gemini-state.js.map +1 -0
  17. package/dist/src/agents/hook-files.d.ts +1 -3
  18. package/dist/src/agents/hook-files.js +69 -53
  19. package/dist/src/agents/hook-files.js.map +1 -1
  20. package/dist/src/agents/hook-health.d.ts +4 -0
  21. package/dist/src/agents/hook-health.js +95 -0
  22. package/dist/src/agents/hook-health.js.map +1 -0
  23. package/dist/src/agents/hooks.d.ts +4 -1
  24. package/dist/src/agents/hooks.js +153 -21
  25. package/dist/src/agents/hooks.js.map +1 -1
  26. package/dist/src/agents/jsonl-titles.d.ts +8 -0
  27. package/dist/src/agents/jsonl-titles.js +124 -0
  28. package/dist/src/agents/jsonl-titles.js.map +1 -0
  29. package/dist/src/agents/late-binding.d.ts +2 -0
  30. package/dist/src/agents/late-binding.js +25 -0
  31. package/dist/src/agents/late-binding.js.map +1 -0
  32. package/dist/src/agents/profile.d.ts +14 -0
  33. package/dist/src/agents/profile.js +75 -0
  34. package/dist/src/agents/profile.js.map +1 -0
  35. package/dist/src/agents/registry.d.ts +12 -3
  36. package/dist/src/agents/registry.js +52 -19
  37. package/dist/src/agents/registry.js.map +1 -1
  38. package/dist/src/agents/roots.d.ts +2 -0
  39. package/dist/src/agents/roots.js +21 -0
  40. package/dist/src/agents/roots.js.map +1 -0
  41. package/dist/src/agents/titles.d.ts +14 -0
  42. package/dist/src/agents/titles.js +82 -0
  43. package/dist/src/agents/titles.js.map +1 -0
  44. package/dist/src/agents/transcript-cursor.d.ts +9 -0
  45. package/dist/src/agents/transcript-cursor.js +86 -0
  46. package/dist/src/agents/transcript-cursor.js.map +1 -0
  47. package/dist/src/cli/main.js +40 -7
  48. package/dist/src/cli/main.js.map +1 -1
  49. package/dist/src/config/index.d.ts +6 -0
  50. package/dist/src/config/index.js +37 -6
  51. package/dist/src/config/index.js.map +1 -1
  52. package/dist/src/config/write.d.ts +2 -0
  53. package/dist/src/config/write.js +41 -0
  54. package/dist/src/config/write.js.map +1 -0
  55. package/dist/src/context.js +1 -1
  56. package/dist/src/context.js.map +1 -1
  57. package/dist/src/index.d.ts +11 -5
  58. package/dist/src/index.js +10 -4
  59. package/dist/src/index.js.map +1 -1
  60. package/dist/src/iterm2/install.d.ts +2 -0
  61. package/dist/src/iterm2/install.js +37 -12
  62. package/dist/src/iterm2/install.js.map +1 -1
  63. package/dist/src/present/attach.js +17 -5
  64. package/dist/src/present/attach.js.map +1 -1
  65. package/dist/src/present/state.d.ts +3 -0
  66. package/dist/src/present/state.js +12 -8
  67. package/dist/src/present/state.js.map +1 -1
  68. package/dist/src/process-arguments.d.ts +2 -0
  69. package/dist/src/process-arguments.js +59 -0
  70. package/dist/src/process-arguments.js.map +1 -0
  71. package/dist/src/process-directory.d.ts +2 -0
  72. package/dist/src/process-directory.js +37 -0
  73. package/dist/src/process-directory.js.map +1 -0
  74. package/dist/src/process-owner.d.ts +7 -0
  75. package/dist/src/process-owner.js +51 -0
  76. package/dist/src/process-owner.js.map +1 -0
  77. package/dist/src/registry/directory.d.ts +2 -0
  78. package/dist/src/registry/directory.js +19 -0
  79. package/dist/src/registry/directory.js.map +1 -0
  80. package/dist/src/registry/discover.d.ts +15 -5
  81. package/dist/src/registry/discover.js +135 -38
  82. package/dist/src/registry/discover.js.map +1 -1
  83. package/dist/src/registry/doctor.d.ts +5 -1
  84. package/dist/src/registry/doctor.js +53 -12
  85. package/dist/src/registry/doctor.js.map +1 -1
  86. package/dist/src/registry/hosts.d.ts +28 -0
  87. package/dist/src/registry/hosts.js +73 -0
  88. package/dist/src/registry/hosts.js.map +1 -0
  89. package/dist/src/registry/launch.d.ts +3 -0
  90. package/dist/src/registry/launch.js +29 -0
  91. package/dist/src/registry/launch.js.map +1 -0
  92. package/dist/src/registry/native-state.d.ts +20 -0
  93. package/dist/src/registry/native-state.js +127 -0
  94. package/dist/src/registry/native-state.js.map +1 -0
  95. package/dist/src/registry/sessions.d.ts +21 -3
  96. package/dist/src/registry/sessions.js +178 -37
  97. package/dist/src/registry/sessions.js.map +1 -1
  98. package/dist/src/restore/ensure.d.ts +12 -2
  99. package/dist/src/restore/ensure.js +171 -37
  100. package/dist/src/restore/ensure.js.map +1 -1
  101. package/dist/src/restore/lock.d.ts +3 -5
  102. package/dist/src/restore/lock.js +82 -52
  103. package/dist/src/restore/lock.js.map +1 -1
  104. package/dist/src/restore/status.d.ts +9 -0
  105. package/dist/src/restore/status.js +16 -0
  106. package/dist/src/restore/status.js.map +1 -0
  107. package/dist/src/snapshot/identity.d.ts +7 -0
  108. package/dist/src/snapshot/identity.js +20 -0
  109. package/dist/src/snapshot/identity.js.map +1 -0
  110. package/dist/src/snapshot/lifecycle.d.ts +9 -0
  111. package/dist/src/snapshot/lifecycle.js +37 -0
  112. package/dist/src/snapshot/lifecycle.js.map +1 -0
  113. package/dist/src/snapshot/store.d.ts +11 -1
  114. package/dist/src/snapshot/store.js +28 -9
  115. package/dist/src/snapshot/store.js.map +1 -1
  116. package/dist/src/snapshot/take.d.ts +2 -1
  117. package/dist/src/snapshot/take.js +29 -25
  118. package/dist/src/snapshot/take.js.map +1 -1
  119. package/dist/src/tmux/client.d.ts +6 -2
  120. package/dist/src/tmux/client.js +49 -25
  121. package/dist/src/tmux/client.js.map +1 -1
  122. package/dist/src/tmux/connections.d.ts +22 -0
  123. package/dist/src/tmux/connections.js +70 -0
  124. package/dist/src/tmux/connections.js.map +1 -0
  125. package/dist/src/tmux/fields.d.ts +7 -0
  126. package/dist/src/tmux/fields.js +23 -0
  127. package/dist/src/tmux/fields.js.map +1 -0
  128. package/dist/src/tmux/install.js +31 -18
  129. package/dist/src/tmux/install.js.map +1 -1
  130. package/dist/src/tools.d.ts +3 -1
  131. package/dist/src/tools.js +23 -11
  132. package/dist/src/tools.js.map +1 -1
  133. package/package.json +1 -1
  134. package/dist/src/agents/name-key.d.ts +0 -1
  135. package/dist/src/agents/name-key.js +0 -66
  136. package/dist/src/agents/name-key.js.map +0 -1
@@ -1,39 +1,63 @@
1
+ import { codexProcessBinding } from '../agents/codex-binding.js';
2
+ import { captureProfile, readProfile, profileRoot } from '../agents/profile.js';
3
+ import { formatFields, readFields } from '../tmux/fields.js';
4
+ import { processDirectory } from '../process-directory.js';
5
+ import { processArguments } from '../process-arguments.js';
6
+ import { shellQuote, shellSplit } from '../shell.js';
7
+ import { processLifetime } from '../process-owner.js';
8
+ import { withLock } from '../restore/lock.js';
1
9
  import { spawnSync } from 'node:child_process';
2
- import { readlinkSync } from 'node:fs';
3
10
  import { ADAPTERS } from '../agents/registry.js';
4
11
  import { isIterm2 } from '../present/state.js';
12
+ const argumentCache = new WeakMap();
13
+ export const ARGUMENTS_UNAVAILABLE = 'Launch arguments could not be verified. Check process access (macOS also requires /usr/bin/perl) before restoring.';
14
+ export const BINDING_UNVERIFIED = 'Recovery binding needs verification. No agent process identity was recorded; verified identity evidence must confirm the conversation.';
15
+ export const PRODUCER_CHANGED = 'Agent producer changed. Verify the conversation before restoring.';
5
16
  const MAX_DEPTH = 6;
6
- function processes() {
7
- const ps = spawnSync('ps', ['-axo', 'pid=,ppid=,args='], { encoding: 'utf8' });
17
+ export function processes() {
18
+ const ps = spawnSync('ps', ['-axo', 'pid=,ppid=,args='], { encoding: 'utf8', timeout: 2000, killSignal: 'SIGKILL', maxBuffer: 8 * 1024 * 1024 });
8
19
  if (ps.status !== 0)
9
20
  return [];
10
21
  return ps.stdout.split('\n').flatMap((line) => {
11
22
  const m = /^\s*(\d+)\s+(\d+)\s+(.*)$/.exec(line);
12
- return m ? [{ pid: Number(m[1]), ppid: Number(m[2]), args: m[3] }] : [];
23
+ return m ? [{ pid: Number(m[1]), ppid: Number(m[2]), args: m[3], native: true }] : [];
13
24
  });
14
25
  }
15
26
  const BINARIES = new Map(ADAPTERS.filter((a) => a.binary).map((a) => [a.binary, a.id]));
16
27
  const program = (word = '') => word.split('/').pop() ?? '';
28
+ const INTERPRETERS = new Set(['node', 'nodejs', 'bun', 'deno', 'sh', 'bash', 'zsh', 'dash', 'ksh', 'python', 'python3', 'ruby', 'perl']);
17
29
  /**
18
30
  * The agent among a process and its descendants: a program named like an
19
31
  * agent binary, or a script so named run by an interpreter (`node <cli>`).
20
32
  * Names are what matter: some agents run as a binary named after its version,
21
33
  * so tmux's pane_current_command does not tell.
22
34
  */
23
- export function agentAmong(rootPid, procs) {
24
- for (let level = [rootPid], depth = 0; level.length && depth < MAX_DEPTH; depth++) {
25
- for (const p of procs.filter((q) => level.includes(q.pid))) {
26
- const words = p.args.split(/\s+/);
27
- const direct = BINARIES.get(program(words[0]));
28
- if (direct)
29
- return { agent: direct, argv: [program(words[0]), ...words.slice(1)].join(' '), pid: p.pid };
30
- const viaInterpreter = BINARIES.get(program(words[1]));
31
- if (viaInterpreter)
32
- return { agent: viaInterpreter, argv: [program(words[1]), ...words.slice(2)].join(' '), pid: p.pid };
33
- }
34
- level = procs.filter((q) => level.includes(q.ppid)).map((q) => q.pid);
35
+ export function agentsAmong(rootPid, procs, depth = 0) {
36
+ if (depth >= MAX_DEPTH)
37
+ return [];
38
+ const process = procs.find((p) => p.pid === rootPid);
39
+ if (process) {
40
+ if (process.native && !argumentCache.has(process))
41
+ argumentCache.set(process, processArguments(process.pid));
42
+ const exact = process.native ? argumentCache.get(process) : shellSplit(process.args);
43
+ const words = exact ?? process.args.split(/\s+/);
44
+ const index = BINARIES.has(program(words[0])) ? 0 : INTERPRETERS.has(program(words[0])) && BINARIES.has(program(words[1])) ? 1 : -1;
45
+ if (index >= 0)
46
+ return [{ agent: BINARIES.get(program(words[index])), argv: exact ? [program(words[index]), ...words.slice(index + 1)].map(shellQuote).join(' ') : '', pid: process.pid, ...(!exact ? { argvIssue: ARGUMENTS_UNAVAILABLE } : {}) }];
35
47
  }
36
- return undefined;
48
+ return procs.filter((p) => p.ppid === rootPid).flatMap((p) => agentsAmong(p.pid, procs, depth + 1));
49
+ }
50
+ export function agentAmong(rootPid, procs) {
51
+ const found = agentsAmong(rootPid, procs);
52
+ return found.length === 1 ? found[0] : undefined;
53
+ }
54
+ export function sessionProducers(ctx, session, procs = processes(), allPanes) {
55
+ const output = allPanes ?? ctx.tmux.run(['list-panes', '-a', '-F', formatFields(['session_name', 'pane_id', 'pane_pid', 'pane_current_path'])], true).stdout;
56
+ return readFields(output, 4).flatMap(([name, pane, pid, cwd]) => {
57
+ if (name !== session)
58
+ return [];
59
+ return agentsAmong(Number(pid), procs).map((found) => ({ ...found, pane, cwd: cwdOf(found.pid) || cwd }));
60
+ });
37
61
  }
38
62
  /**
39
63
  * A process's working directory. The pane's current path is not it: tmux
@@ -41,15 +65,7 @@ export function agentAmong(rootPid, procs) {
41
65
  * when the agent runs under one.
42
66
  */
43
67
  export function cwdOf(pid) {
44
- try {
45
- return readlinkSync(`/proc/${pid}/cwd`);
46
- }
47
- catch {
48
- // Not Linux: ask lsof.
49
- }
50
- const r = spawnSync('lsof', ['-a', '-p', String(pid), '-d', 'cwd', '-Fn'], { encoding: 'utf8' });
51
- const line = (r.stdout ?? '').split('\n').find((l) => l.startsWith('n'));
52
- return line ? line.slice(1) : undefined;
68
+ return processDirectory(pid);
53
69
  }
54
70
  /** The agent running in a session's active pane, if any. */
55
71
  export function detectAgent(ctx, session) {
@@ -57,32 +73,113 @@ export function detectAgent(ctx, session) {
57
73
  return pid ? agentAmong(pid, processes()) : undefined;
58
74
  }
59
75
  /**
60
- * Stamp every unmanaged live session whose active pane runs an agent. Returns
76
+ * Stamp every unmanaged session or managed shell whose active pane runs an agent. Returns
61
77
  * the sessions stamped; the caller snapshots. Never throws.
62
78
  */
63
79
  export function discover(ctx) {
80
+ return withLock(ctx.config.stateDir, () => discoverLocked(ctx));
81
+ }
82
+ function discoverLocked(ctx) {
64
83
  if (!ctx.config.autoAdopt)
65
84
  return [];
66
85
  try {
67
- const unmanaged = ctx.tmux.listSessions().filter((s) => !s.meta.agent);
68
- if (unmanaged.length === 0)
86
+ const candidates = ctx.tmux.listSessions();
87
+ if (candidates.length === 0)
69
88
  return [];
70
- const panes = ctx.tmux.run(['list-panes', '-a', '-F', '#{session_name}\t#{pane_active}\t#{window_active}\t#{pane_pid}\t#{pane_current_path}'], true);
71
- const clients = ctx.tmux.run(['list-clients', '-F', '#{client_session}\t#{client_termtype}'], true);
89
+ const clients = ctx.tmux.run(['list-clients', '-F', formatFields(['client_session', 'client_termtype'])], true);
72
90
  const procs = processes();
91
+ const panes = ctx.tmux.run(['list-panes', '-a', '-F', formatFields(['session_name', 'pane_id', 'pane_pid', 'pane_current_path'])], true).stdout;
73
92
  const stamped = [];
74
- for (const s of unmanaged) {
75
- const pane = panes.stdout.split('\n').map((l) => l.split('\t')).find(([name, active, windowActive]) => name === s.name && active === '1' && windowActive === '1');
76
- if (!pane)
93
+ const nativePool = candidates.filter(row => !row.meta.agent || ['shell', 'codex'].includes(row.meta.agent));
94
+ const nativeStart = Math.floor(Date.now() / 2_000) % Math.max(1, nativePool.length);
95
+ const nativeCandidates = new Set(Array.from({ length: Math.min(2, nativePool.length) }, (_, index) => nativePool[(nativeStart + index) % nativePool.length].name));
96
+ for (const s of candidates) {
97
+ const producers = sessionProducers(ctx, s.name, procs, panes);
98
+ if (producers.length > 1) {
99
+ const issue = 'Multiple independent agents. Move each agent to its own tmux session before restoring.';
100
+ if (s.meta.bindingIssue !== issue) {
101
+ ctx.tmux.setMeta(s.name, { bindingIssue: issue });
102
+ stamped.push(s.name);
103
+ }
77
104
  continue;
78
- const found = agentAmong(Number(pane[3]), procs);
105
+ }
106
+ const found = producers[0];
79
107
  if (!found)
80
108
  continue;
81
- const iterm2 = clients.stdout.split('\n').some((l) => {
82
- const [session, termtype = ''] = l.split('\t');
109
+ const lifetime = processLifetime(found.pid)?.key;
110
+ if (!lifetime)
111
+ continue;
112
+ if (found.agent === 'codex' && !shellSplit(found.argv).some(word => ['app-server', 'exec', 'mcp-server', 'review'].includes(word))
113
+ && (!s.meta.agent || s.meta.agent === 'codex' || s.meta.agent === 'shell')
114
+ && !found.argvIssue && nativeCandidates.has(s.name)
115
+ && (!s.meta.recovery || s.meta.recovery === 'confirmed')
116
+ && (!s.meta.conversation || !s.meta.profile || s.meta.bindingIssue === PRODUCER_CHANGED || s.meta.bindingIssue === BINDING_UNVERIFIED)) {
117
+ const binding = codexProcessBinding(found.pid, lifetime);
118
+ const profile = readProfile('codex', s.meta.profile);
119
+ if (binding && (!s.meta.conversation || s.meta.conversation === binding.conversation)
120
+ && (!profile || profileRoot('codex', profile) === binding.root)
121
+ && (!s.meta.bindingIssue || [PRODUCER_CHANGED, BINDING_UNVERIFIED].includes(s.meta.bindingIssue))) {
122
+ const current = ctx.tmux.listSessions().find(row => row.name === s.name);
123
+ const owners = sessionProducers(ctx, s.name);
124
+ if (current?.sessionId === s.sessionId && current.serverStart === s.serverStart
125
+ && owners.length === 1 && owners[0].pid === found.pid && owners[0].pane === found.pane
126
+ && processLifetime(found.pid)?.key === lifetime) {
127
+ ctx.tmux.setMeta(s.name, { agent: 'codex', conversation: binding.conversation,
128
+ profile: JSON.stringify(profile ?? captureProfile('codex', { ...ctx.env, CODEX_HOME: binding.root })),
129
+ producerPane: found.pane, producerLifetime: lifetime, bindingIssue: '',
130
+ cwd: s.meta.cwd || found.cwd || s.path, argv: found.argv, argvVerified: '1' });
131
+ ctx.tmux.setTitle(s.name);
132
+ stamped.push(s.name);
133
+ continue;
134
+ }
135
+ }
136
+ }
137
+ if (s.meta.agent && s.meta.agent !== 'shell') {
138
+ if (found.argvIssue) {
139
+ if (!s.meta.bindingIssue) {
140
+ ctx.tmux.setMeta(s.name, { bindingIssue: found.argvIssue });
141
+ stamped.push(s.name);
142
+ }
143
+ continue;
144
+ }
145
+ if (s.meta.bindingIssue === ARGUMENTS_UNAVAILABLE) {
146
+ ctx.tmux.setMeta(s.name, { bindingIssue: '', argv: found.argv, argvVerified: '1' });
147
+ stamped.push(s.name);
148
+ }
149
+ if (s.meta.agent !== found.agent || (s.meta.producerPane && s.meta.producerPane !== found.pane)
150
+ || (s.meta.producerLifetime && s.meta.producerLifetime !== lifetime)) {
151
+ const issue = PRODUCER_CHANGED;
152
+ if (s.meta.bindingIssue !== issue) {
153
+ ctx.tmux.setMeta(s.name, { bindingIssue: issue });
154
+ stamped.push(s.name);
155
+ }
156
+ }
157
+ else if (!s.meta.producerLifetime && s.meta.conversation && (!s.meta.recovery || s.meta.recovery === 'confirmed')) {
158
+ if (!s.meta.bindingIssue || s.meta.bindingIssue === PRODUCER_CHANGED) {
159
+ ctx.tmux.setMeta(s.name, { bindingIssue: BINDING_UNVERIFIED });
160
+ stamped.push(s.name);
161
+ }
162
+ }
163
+ else if (!s.meta.producerPane || !s.meta.producerLifetime || s.meta.argvVerified !== '1') {
164
+ ctx.tmux.setMeta(s.name, { producerPane: found.pane, producerLifetime: lifetime,
165
+ ...(s.meta.argvVerified !== '1' ? { argv: found.argv, argvVerified: '1' } : {}),
166
+ });
167
+ stamped.push(s.name);
168
+ }
169
+ continue;
170
+ }
171
+ const iterm2 = readFields(clients.stdout, 2).some(([session, termtype]) => {
83
172
  return session === s.name && isIterm2(termtype);
84
173
  });
85
- ctx.tmux.setMeta(s.name, { agent: found.agent, cwd: cwdOf(found.pid) || pane[4] || s.path, argv: found.argv, origin: iterm2 ? 'iterm2' : 'none' });
174
+ ctx.tmux.setMeta(s.name, {
175
+ agent: found.agent,
176
+ producerPane: found.pane,
177
+ producerLifetime: lifetime,
178
+ cwd: found.cwd || s.path,
179
+ argv: found.argv, argvVerified: found.argvIssue ? '' : '1',
180
+ ...(found.argvIssue ? { bindingIssue: found.argvIssue } : {}),
181
+ origin: s.meta.origin && s.meta.origin !== 'none' ? s.meta.origin : iterm2 ? 'iterm2' : 'none',
182
+ });
86
183
  ctx.tmux.setTitle(s.name);
87
184
  stamped.push(s.name);
88
185
  }
@@ -1 +1 @@
1
- {"version":3,"file":"discover.js","sourceRoot":"","sources":["../../../src/registry/discover.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAiB/C,MAAM,SAAS,GAAG,CAAC,CAAC;AAEpB,SAAS,SAAS;IAChB,MAAM,EAAE,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,kBAAkB,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IAC/E,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAC/B,OAAO,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QAC5C,MAAM,CAAC,GAAG,2BAA2B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjD,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1E,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACxF,MAAM,OAAO,GAAG,CAAC,IAAI,GAAG,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;AAE3D;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,OAAe,EAAE,KAAa;IACvD,KAAK,IAAI,KAAK,GAAG,CAAC,OAAO,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,KAAK,CAAC,MAAM,IAAI,KAAK,GAAG,SAAS,EAAE,KAAK,EAAE,EAAE,CAAC;QAClF,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YAC3D,MAAM,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAClC,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/C,IAAI,MAAM;gBAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;YACzG,MAAM,cAAc,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACvD,IAAI,cAAc;gBAAE,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;QAC3H,CAAC;QACD,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAC,GAAW;IAC/B,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,SAAS,GAAG,MAAM,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,uBAAuB;IACzB,CAAC;IACD,MAAM,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IACjG,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IACzE,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC1C,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,WAAW,CAAC,GAAY,EAAE,OAAe;IACvD,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,OAAO,GAAG,EAAE,aAAa,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IACrH,OAAO,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACxD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAY;IACnC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS;QAAE,OAAO,EAAE,CAAC;IACrC,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvE,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QACtC,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,sFAAsF,CAAC,EAAE,IAAI,CAAC,CAAC;QACrJ,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,cAAc,EAAE,IAAI,EAAE,uCAAuC,CAAC,EAAE,IAAI,CAAC,CAAC;QACpG,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;YAC1B,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,IAAI,MAAM,KAAK,GAAG,IAAI,YAAY,KAAK,GAAG,CAAC,CAAC;YAClK,IAAI,CAAC,IAAI;gBAAE,SAAS;YACpB,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YACjD,IAAI,CAAC,KAAK;gBAAE,SAAS;YACrB,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;gBACnD,MAAM,CAAC,OAAO,EAAE,QAAQ,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC/C,OAAO,OAAO,KAAK,CAAC,CAAC,IAAI,IAAI,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAClD,CAAC,CAAC,CAAC;YACH,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;YACnJ,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"discover.js","sourceRoot":"","sources":["../../../src/registry/discover.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,11 @@
1
+ import { type AgentProfile } from '../agents/profile.js';
1
2
  import type { Context } from '../context.js';
2
3
  export interface Finding {
3
4
  session?: string;
4
5
  problem: string;
6
+ severity?: 'info' | 'warning';
7
+ installHooksFor?: string;
8
+ profile?: AgentProfile;
5
9
  }
6
10
  /** Drift and gaps worth a user's attention; empty when all is well. */
7
- export declare function doctor(ctx: Context, env?: NodeJS.ProcessEnv): Finding[];
11
+ export declare function doctor(ctx: Context, env?: Record<string, string | undefined>): Finding[];
@@ -1,30 +1,71 @@
1
+ import { assessCapability, versionInspector } from '../agents/capabilities.js';
2
+ import { profileKey } from '../agents/profile.js';
3
+ import { usableDirectory } from './directory.js';
1
4
  import { existsSync } from 'node:fs';
5
+ import { launchCommand } from '../agents/commands.js';
6
+ import { shellSplit } from '../shell.js';
7
+ import { executableOnPath } from '../tools.js';
2
8
  import { getAdapter } from '../agents/registry.js';
3
- import { hooksInstalled } from '../agents/hooks.js';
4
9
  import { list } from './sessions.js';
5
10
  /** Drift and gaps worth a user's attention; empty when all is well. */
6
- export function doctor(ctx, env = process.env) {
11
+ export function doctor(ctx, env = ctx.env) {
7
12
  const findings = [];
8
- const agentsInUse = new Set();
13
+ if (process.platform === 'darwin' && !existsSync('/usr/bin/perl'))
14
+ findings.push({ problem: 'System Perl is unavailable; macOS launch arguments cannot be verified for recovery.' });
15
+ if (ctx.config.legacySnapshotRoot)
16
+ findings.push({ problem: `Legacy snapshots require endpoint verification: ${ctx.config.legacySnapshotRoot}. After verifying the source server, use berth restore with an explicit snapshot directory.` });
17
+ const version = ctx.tmux.run(['-V'], true);
18
+ const major = /tmux\s+(\d+)/.exec(version.stdout)?.[1];
19
+ if (!version.ok || !major)
20
+ findings.push({ problem: 'Could not verify tmux version. Berth requires tmux 3.0 or later.' });
21
+ else if (Number(major) < 3)
22
+ findings.push({ problem: `Unsupported tmux version: ${version.stdout.trim()}; install tmux 3.0 or later.` });
23
+ const checkedProfiles = new Set();
24
+ const checkedVersions = new Set();
25
+ const inspectVersion = versionInspector(env);
9
26
  for (const row of list(ctx)) {
10
27
  if (!row.managed)
11
28
  continue;
12
- agentsInUse.add(row.agent);
13
29
  const adapter = getAdapter(row.agent);
14
30
  if (!adapter) {
15
31
  findings.push({ session: row.name, problem: `unknown agent ${row.agent}` });
16
32
  continue;
17
33
  }
18
- if (!existsSync(row.cwd))
34
+ const versionKey = JSON.stringify([row.agent, executableOnPath(adapter.binary, env, row.cwd)]);
35
+ if (row.agent !== 'shell' && !checkedVersions.has(versionKey)) {
36
+ checkedVersions.add(versionKey);
37
+ const overrides = ctx.config.agents[row.agent];
38
+ if (overrides?.launch !== undefined || overrides?.resume !== undefined) {
39
+ findings.push({ session: row.name, severity: 'info', problem: `${adapter.displayName}: custom launch/resume template; version not inspected. Verify hook support in that launcher.` });
40
+ }
41
+ else {
42
+ const observed = inspectVersion(adapter, row.cwd);
43
+ const assessment = observed.version ? assessCapability(row.agent, observed.version) : undefined;
44
+ findings.push({ session: row.name, severity: assessment?.severity ?? 'info',
45
+ problem: `${adapter.displayName} configured CLI (${observed.executable}): ${observed.version ?? observed.detail}. ${assessment?.detail ?? 'Version compatibility remains unverified.'}` });
46
+ }
47
+ }
48
+ if (!usableDirectory(row.cwd))
19
49
  findings.push({ session: row.name, problem: `working directory missing: ${row.cwd}` });
20
- if (adapter.resume && !row.conversation)
21
- findings.push({ session: row.name, problem: 'conversation not bound; restore will start fresh' });
22
- }
23
- for (const agent of agentsInUse) {
24
- const adapter = getAdapter(agent);
25
- if (adapter?.hookTarget && !hooksInstalled(agent, env)) {
26
- findings.push({ problem: `hooks for ${adapter.displayName} not installed (berth hooks install ${agent})` });
50
+ if (row.bindingIssue)
51
+ findings.push({ session: row.name, problem: row.bindingIssue });
52
+ if (row.recovery && row.recovery !== 'confirmed')
53
+ findings.push({ session: row.name, problem: `recovery ${row.recovery}: ${row.recoveryDetail ?? 'inspect the terminal'}` });
54
+ const command = launchCommand({ adapter, name: row.name, cwd: row.cwd, overrides: ctx.config.agents });
55
+ const [binary] = shellSplit(command);
56
+ if (binary && !executableOnPath(binary, env, row.cwd))
57
+ findings.push({ session: row.name, problem: `executable unavailable: ${binary}; install it or correct the agent template` });
58
+ if (row.agent !== 'shell' && !row.profile)
59
+ findings.push({ session: row.name, problem: 'agent profile unknown; a verified start hook can report it, or choose a recovery profile once the session is stopped' });
60
+ if ((row.hooks === 'missing' || row.hooks === 'broken') && row.profile) {
61
+ const key = profileKey(row.agent, row.profile);
62
+ if (!checkedProfiles.has(key)) {
63
+ checkedProfiles.add(key);
64
+ findings.push({ session: row.name, installHooksFor: row.agent, profile: row.profile, problem: `hooks for ${adapter.displayName} ${row.hooks === 'broken' ? 'are incomplete or have missing runtime files' : 'are not installed'} in this session profile` });
65
+ }
27
66
  }
67
+ if (adapter.resume && !row.conversation)
68
+ findings.push({ session: row.name, problem: 'conversation not bound; automatic recovery is unavailable. Use the agent conversation picker or start a new session explicitly' });
28
69
  }
29
70
  return findings;
30
71
  }
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/registry/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAOrC,uEAAuE;AACvE,MAAM,UAAU,MAAM,CAAC,GAAY,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG;IACpD,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5B,IAAI,CAAC,GAAG,CAAC,OAAO;YAAE,SAAS;QAC3B,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC3B,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,iBAAiB,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC5E,SAAS;QACX,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,8BAA8B,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACjH,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,YAAY;YAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,kDAAkD,EAAE,CAAC,CAAC;IAC7I,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,WAAW,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,OAAO,EAAE,UAAU,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC;YACvD,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,aAAa,OAAO,CAAC,WAAW,uCAAuC,KAAK,GAAG,EAAE,CAAC,CAAC;QAC9G,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/registry/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ export interface WorkspaceIdentity {
2
+ key: string;
3
+ label: string;
4
+ }
5
+ export interface HostRecord {
6
+ lifetime?: string;
7
+ id: string;
8
+ pid: number;
9
+ seenAt: number;
10
+ application: string;
11
+ workspace?: WorkspaceIdentity;
12
+ terminalPids: number[];
13
+ }
14
+ export declare function workspaceIdentity(folders: readonly string[], workspaceFile?: string, label?: string): WorkspaceIdentity | undefined;
15
+ export declare function registeredHosts(stateDir: string): HostRecord[];
16
+ /** One window's runtime evidence and exclusive startup claim, scoped to one tmux server. */
17
+ export declare class HostRegistration {
18
+ private readonly stateDir;
19
+ private readonly application;
20
+ readonly workspace?: WorkspaceIdentity | undefined;
21
+ readonly id: `${string}-${string}-${string}-${string}-${string}`;
22
+ private readonly dir;
23
+ private claimed?;
24
+ constructor(stateDir: string, application: string, workspace?: WorkspaceIdentity | undefined);
25
+ update(terminalPids: readonly number[]): void;
26
+ claimStartup(): boolean;
27
+ dispose(): void;
28
+ }
@@ -0,0 +1,73 @@
1
+ import { processLifetime, processOwnerAlive } from '../process-owner.js';
2
+ import { createHash, randomUUID } from 'node:crypto';
3
+ import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, statSync, writeFileSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+ import { withLock } from '../restore/lock.js';
6
+ export function workspaceIdentity(folders, workspaceFile = '', label = '') {
7
+ if (!folders.length && !workspaceFile)
8
+ return undefined;
9
+ const roots = [...new Set(folders)].sort();
10
+ return { key: createHash('sha256').update(JSON.stringify([workspaceFile, roots])).digest('hex'), label: label || roots.join(', ') || workspaceFile };
11
+ }
12
+ function read(file) {
13
+ try {
14
+ const record = JSON.parse(readFileSync(file, 'utf8'));
15
+ return typeof record.id === 'string' && processOwnerAlive(record.pid, record.lifetime, statSync(file).mtimeMs) ? record : undefined;
16
+ }
17
+ catch (error) {
18
+ if (error.code === 'ENOENT' || error instanceof SyntaxError)
19
+ return undefined;
20
+ throw error;
21
+ }
22
+ }
23
+ export function registeredHosts(stateDir) {
24
+ const dir = join(stateDir, 'hosts');
25
+ if (!existsSync(dir))
26
+ return [];
27
+ return readdirSync(dir).filter((name) => name.endsWith('.json')).flatMap((name) => {
28
+ const record = read(join(dir, name));
29
+ return record && Date.now() - record.seenAt < 45_000 && Array.isArray(record.terminalPids) ? [record] : [];
30
+ });
31
+ }
32
+ /** One window's runtime evidence and exclusive startup claim, scoped to one tmux server. */
33
+ export class HostRegistration {
34
+ stateDir;
35
+ application;
36
+ workspace;
37
+ id = randomUUID();
38
+ dir;
39
+ claimed;
40
+ constructor(stateDir, application, workspace) {
41
+ this.stateDir = stateDir;
42
+ this.application = application;
43
+ this.workspace = workspace;
44
+ this.dir = join(stateDir, 'hosts');
45
+ }
46
+ update(terminalPids) {
47
+ mkdirSync(this.dir, { recursive: true });
48
+ const record = { id: this.id, pid: process.pid, lifetime: processLifetime(process.pid).key, seenAt: Date.now(), application: this.application, workspace: this.workspace, terminalPids: [...terminalPids] };
49
+ const file = join(this.dir, `${this.id}.json`);
50
+ writeFileSync(`${file}.tmp`, JSON.stringify(record), { mode: 0o600 });
51
+ renameSync(`${file}.tmp`, file);
52
+ }
53
+ claimStartup() {
54
+ if (!this.workspace)
55
+ return false;
56
+ const dir = join(this.stateDir, 'host-claims');
57
+ return withLock(dir, () => {
58
+ const file = join(dir, `${this.workspace.key}.json`);
59
+ const owner = read(file);
60
+ if (owner && owner.id !== this.id)
61
+ return false;
62
+ writeFileSync(file, JSON.stringify({ id: this.id, pid: process.pid, lifetime: processLifetime(process.pid).key }), { mode: 0o600 });
63
+ this.claimed = file;
64
+ return true;
65
+ }, 1000);
66
+ }
67
+ dispose() {
68
+ rmSync(join(this.dir, `${this.id}.json`), { force: true });
69
+ if (this.claimed && read(this.claimed)?.id === this.id)
70
+ rmSync(this.claimed, { force: true });
71
+ }
72
+ }
73
+ //# sourceMappingURL=hosts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hosts.js","sourceRoot":"","sources":["../../../src/registry/hosts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Context } from '../context.js';
2
+ /** Stage identity before execution, and clean up only this attempt's immutable session. */
3
+ export declare function withPlaceholder<T>(ctx: Context, name: string, cwd: string, start: () => T): T;
@@ -0,0 +1,29 @@
1
+ import { BerthError } from '../errors.js';
2
+ import { watchClosures } from '../snapshot/lifecycle.js';
3
+ import { sameDirectory } from './directory.js';
4
+ import { shellQuote } from '../shell.js';
5
+ /** Stage identity before execution, and clean up only this attempt's immutable session. */
6
+ export function withPlaceholder(ctx, name, cwd, start) {
7
+ const idle = `ELECTRON_RUN_AS_NODE=1 ${shellQuote(process.execPath)} -e ${shellQuote('setInterval(() => {}, 3600000)')}`;
8
+ const sessionId = ctx.tmux.newSession(name, cwd, idle);
9
+ try {
10
+ watchClosures(ctx);
11
+ if (!sameDirectory(ctx.tmux.paneCurrentPath(name) ?? '', cwd)) {
12
+ throw new BerthError('Terminal did not start in the requested folder.');
13
+ }
14
+ return start();
15
+ }
16
+ catch (error) {
17
+ const current = ctx.tmux.run(['display-message', '-p', '-t', `=${name}:`, '#{session_id}'], true);
18
+ if (current.ok && current.stdout.trim() === sessionId) {
19
+ try {
20
+ ctx.tmux.killSession(name);
21
+ }
22
+ catch {
23
+ ctx.tmux.setMeta(name, { recovery: 'failed', recoveryDetail: `Launch failed: ${error.message}` });
24
+ }
25
+ }
26
+ throw error;
27
+ }
28
+ }
29
+ //# sourceMappingURL=launch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launch.js","sourceRoot":"","sources":["../../../src/registry/launch.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,2FAA2F;AAC3F,MAAM,UAAU,eAAe,CAAI,GAAY,EAAE,IAAY,EAAE,GAAW,EAAE,KAAc;IACxF,MAAM,IAAI,GAAG,0BAA0B,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,UAAU,CAAC,gCAAgC,CAAC,EAAE,CAAC;IACzH,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IACvD,IAAI,CAAC;QACH,aAAa,CAAC,GAAG,CAAC,CAAC;QACnB,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC;YAC9D,MAAM,IAAI,UAAU,CAAC,iDAAiD,CAAC,CAAC;QAC1E,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;IACjB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,GAAG,EAAE,eAAe,CAAC,EAAE,IAAI,CAAC,CAAC;QAClG,IAAI,OAAO,CAAC,EAAE,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;YACtD,IAAI,CAAC;gBAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YAAC,CAAC;YACnC,MAAM,CAAC;gBACL,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,cAAc,EAAE,kBAAmB,KAAe,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAC/G,CAAC;QACH,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { Context } from '../context.js';
2
+ import type { LiveSession } from '../tmux/client.js';
3
+ export interface NativeCandidate {
4
+ session: LiveSession;
5
+ pid: number;
6
+ bornAt: number;
7
+ }
8
+ interface NativeObservation extends NativeCandidate {
9
+ state?: 'working';
10
+ }
11
+ /** Called under the state lock; one least-recently attempted profile per pass. */
12
+ export declare function prepareNativeState(ctx: Context): NativeCandidate[];
13
+ /** Native schemas are versioned externally; unknown or ambiguous data is inert. */
14
+ export declare function nativeIdle(data: unknown, candidate: NativeCandidate): boolean;
15
+ /** No shared state lock may be held while invoking the native CLI. */
16
+ export declare function observeNativeState(ctx: Context, candidates: NativeCandidate[]): NativeObservation[];
17
+ export declare function sameNativeCandidate(before: LiveSession, after: LiveSession): boolean;
18
+ /** Called under the state lock; observations never establish session identity. */
19
+ export declare function applyNativeState(ctx: Context, observations: NativeObservation[]): void;
20
+ export {};