@berthdev/berth 0.3.6 → 0.4.3

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 +69 -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 +142 -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 +19 -0
  93. package/dist/src/registry/native-state.js +135 -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 +179 -38
  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 +24 -0
  123. package/dist/src/tmux/connections.js +86 -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, processOwnerAlive } 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,120 @@ 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
+ const sameLifetime = !!s.meta.producerLifetime && processOwnerAlive(found.pid, s.meta.producerLifetime, Date.now());
150
+ if (sameLifetime && s.meta.agent === found.agent && s.meta.producerPane === found.pane
151
+ && (!s.meta.bindingIssue || s.meta.bindingIssue === PRODUCER_CHANGED)
152
+ && (s.meta.producerLifetime !== lifetime || s.meta.bindingIssue === PRODUCER_CHANGED)) {
153
+ ctx.tmux.setMeta(s.name, { producerLifetime: lifetime, bindingIssue: '' });
154
+ stamped.push(s.name);
155
+ }
156
+ if (s.meta.agent !== found.agent || (s.meta.producerPane && s.meta.producerPane !== found.pane)
157
+ || (s.meta.producerLifetime && !sameLifetime)) {
158
+ const issue = PRODUCER_CHANGED;
159
+ if (s.meta.bindingIssue !== issue) {
160
+ ctx.tmux.setMeta(s.name, { bindingIssue: issue });
161
+ stamped.push(s.name);
162
+ }
163
+ }
164
+ else if (!s.meta.producerLifetime && s.meta.conversation && (!s.meta.recovery || s.meta.recovery === 'confirmed')) {
165
+ if (!s.meta.bindingIssue || s.meta.bindingIssue === PRODUCER_CHANGED) {
166
+ ctx.tmux.setMeta(s.name, { bindingIssue: BINDING_UNVERIFIED });
167
+ stamped.push(s.name);
168
+ }
169
+ }
170
+ else if (!s.meta.producerPane || !s.meta.producerLifetime || s.meta.argvVerified !== '1') {
171
+ ctx.tmux.setMeta(s.name, { producerPane: found.pane, producerLifetime: lifetime,
172
+ ...(s.meta.argvVerified !== '1' ? { argv: found.argv, argvVerified: '1' } : {}),
173
+ });
174
+ stamped.push(s.name);
175
+ }
176
+ continue;
177
+ }
178
+ const iterm2 = readFields(clients.stdout, 2).some(([session, termtype]) => {
83
179
  return session === s.name && isIterm2(termtype);
84
180
  });
85
- ctx.tmux.setMeta(s.name, { agent: found.agent, cwd: cwdOf(found.pid) || pane[4] || s.path, argv: found.argv, origin: iterm2 ? 'iterm2' : 'none' });
181
+ ctx.tmux.setMeta(s.name, {
182
+ agent: found.agent,
183
+ producerPane: found.pane,
184
+ producerLifetime: lifetime,
185
+ cwd: found.cwd || s.path,
186
+ argv: found.argv, argvVerified: found.argvIssue ? '' : '1',
187
+ ...(found.argvIssue ? { bindingIssue: found.argvIssue } : {}),
188
+ origin: s.meta.origin && s.meta.origin !== 'none' ? s.meta.origin : iterm2 ? 'iterm2' : 'none',
189
+ });
86
190
  ctx.tmux.setTitle(s.name);
87
191
  stamped.push(s.name);
88
192
  }
@@ -1 +1 @@
1
- {"version":3,"file":"discover.js","sourceRoot":"","sources":["../../../src/registry/discover.ts"],"names":[],"mappings":"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"}
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,19 @@
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' | 'waiting';
10
+ }
11
+ /** Called under the state lock; one least-recently attempted profile per pass. */
12
+ export declare function prepareNativeState(ctx: Context): NativeCandidate[];
13
+ export declare function nativeIdle(data: unknown, candidate: NativeCandidate): boolean;
14
+ /** No shared state lock may be held while invoking the native CLI. */
15
+ export declare function observeNativeState(ctx: Context, candidates: NativeCandidate[]): NativeObservation[];
16
+ export declare function sameNativeCandidate(before: LiveSession, after: LiveSession): boolean;
17
+ /** Called under the state lock; observations never establish session identity. */
18
+ export declare function applyNativeState(ctx: Context, observations: NativeObservation[]): void;
19
+ export {};