@berthdev/berth 0.0.0-stage → 0.2.1-rc.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 (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +16 -2
  3. package/dist/src/agents/claude-name.d.ts +1 -0
  4. package/dist/src/agents/claude-name.js +57 -0
  5. package/dist/src/agents/claude-name.js.map +1 -0
  6. package/dist/src/agents/commands.d.ts +23 -0
  7. package/dist/src/agents/commands.js +48 -0
  8. package/dist/src/agents/commands.js.map +1 -0
  9. package/dist/src/agents/hooks.d.ts +13 -0
  10. package/dist/src/agents/hooks.js +141 -0
  11. package/dist/src/agents/hooks.js.map +1 -0
  12. package/dist/src/agents/registry.d.ts +33 -0
  13. package/dist/src/agents/registry.js +141 -0
  14. package/dist/src/agents/registry.js.map +1 -0
  15. package/dist/src/cli/main.d.ts +4 -0
  16. package/dist/src/cli/main.js +236 -0
  17. package/dist/src/cli/main.js.map +1 -0
  18. package/dist/src/config/index.d.ts +21 -0
  19. package/dist/src/config/index.js +77 -0
  20. package/dist/src/config/index.js.map +1 -0
  21. package/dist/src/context.d.ts +9 -0
  22. package/dist/src/context.js +12 -0
  23. package/dist/src/context.js.map +1 -0
  24. package/dist/src/errors.d.ts +13 -0
  25. package/dist/src/errors.js +17 -0
  26. package/dist/src/errors.js.map +1 -0
  27. package/dist/src/index.d.ts +17 -0
  28. package/dist/src/index.js +18 -0
  29. package/dist/src/index.js.map +1 -0
  30. package/dist/src/iterm2/install.d.ts +29 -0
  31. package/dist/src/iterm2/install.js +112 -0
  32. package/dist/src/iterm2/install.js.map +1 -0
  33. package/dist/src/present/attach.d.ts +16 -0
  34. package/dist/src/present/attach.js +31 -0
  35. package/dist/src/present/attach.js.map +1 -0
  36. package/dist/src/present/state.d.ts +14 -0
  37. package/dist/src/present/state.js +63 -0
  38. package/dist/src/present/state.js.map +1 -0
  39. package/dist/src/registry/doctor.d.ts +7 -0
  40. package/dist/src/registry/doctor.js +31 -0
  41. package/dist/src/registry/doctor.js.map +1 -0
  42. package/dist/src/registry/sessions.d.ts +47 -0
  43. package/dist/src/registry/sessions.js +138 -0
  44. package/dist/src/registry/sessions.js.map +1 -0
  45. package/dist/src/restore/ensure.d.ts +17 -0
  46. package/dist/src/restore/ensure.js +57 -0
  47. package/dist/src/restore/ensure.js.map +1 -0
  48. package/dist/src/restore/lock.d.ts +6 -0
  49. package/dist/src/restore/lock.js +74 -0
  50. package/dist/src/restore/lock.js.map +1 -0
  51. package/dist/src/shell.d.ts +6 -0
  52. package/dist/src/shell.js +68 -0
  53. package/dist/src/shell.js.map +1 -0
  54. package/dist/src/snapshot/store.d.ts +29 -0
  55. package/dist/src/snapshot/store.js +90 -0
  56. package/dist/src/snapshot/store.js.map +1 -0
  57. package/dist/src/snapshot/take.d.ts +5 -0
  58. package/dist/src/snapshot/take.js +33 -0
  59. package/dist/src/snapshot/take.js.map +1 -0
  60. package/dist/src/tmux/client.d.ts +49 -0
  61. package/dist/src/tmux/client.js +111 -0
  62. package/dist/src/tmux/client.js.map +1 -0
  63. package/dist/src/tmux/install.d.ts +4 -0
  64. package/dist/src/tmux/install.js +64 -0
  65. package/dist/src/tmux/install.js.map +1 -0
  66. package/dist/src/tools.d.ts +5 -0
  67. package/dist/src/tools.js +16 -0
  68. package/dist/src/tools.js.map +1 -0
  69. package/package.json +49 -4
@@ -0,0 +1,236 @@
1
+ #!/usr/bin/env node
2
+ import { spawnSync } from 'node:child_process';
3
+ import { readFileSync, realpathSync } from 'node:fs';
4
+ import { resolve } from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+ import { parseArgs } from 'node:util';
7
+ import { createContext } from '../context.js';
8
+ import { BerthError, ExitCode } from '../errors.js';
9
+ import { handleHook, installHooks, uninstallHooks } from '../agents/hooks.js';
10
+ import { adopt, bellRang, checkOrigin, create, list, requireLive, stamp } from '../registry/sessions.js';
11
+ import { doctor } from '../registry/doctor.js';
12
+ import { takeSnapshot } from '../snapshot/take.js';
13
+ import { ensure, restoreFrom } from '../restore/ensure.js';
14
+ import { presentState } from '../present/state.js';
15
+ import { installTmux, uninstallTmux } from '../tmux/install.js';
16
+ import { installIterm2, reattach, uninstallIterm2 } from '../iterm2/install.js';
17
+ import { clientAttached } from '../present/attach.js';
18
+ import { toolsFor } from '../tools.js';
19
+ const USAGE = `usage: berth <command> [options]
20
+
21
+ ls [--json] all sessions
22
+ new <agent> [--name N] [--cwd D] [--origin O] [-- agent args]
23
+ adopt <session> --agent <id> [--origin O]
24
+ attach <session> [--origin O]
25
+ stamp [--session S] key=value...
26
+ snapshot
27
+ ensure [--origin O] [<session>]
28
+ restore [--origin O] [--session S] [<snapshot dir>]
29
+ show <session> [<snapshot dir>]
30
+ doctor [--json]
31
+ hooks install|uninstall <agent>
32
+ tmux install|uninstall snapshot hooks in ~/.tmux.conf
33
+ iterm2 install|uninstall Berth for iTerm2 (AutoLaunch script)
34
+ iterm2 reattach <session> rebuild if missing, print attach command
35
+ present <session> show its state on attached terminals
36
+
37
+ global: --socket <name> tmux -L socket (overrides BERTH_TMUX_SOCKET)
38
+ --socket-path <path> tmux -S socket (set by Berth's tmux hooks)
39
+
40
+ run by hooks: hook <agent> <event>, bell --session S, attached --session S --tty T --termtype X`;
41
+ function parse(args, options) {
42
+ try {
43
+ return parseArgs({ args, options, allowPositionals: true, strict: true });
44
+ }
45
+ catch (error) {
46
+ throw new BerthError(error.message, ExitCode.usage);
47
+ }
48
+ }
49
+ function need(value, what) {
50
+ if (!value)
51
+ throw new BerthError(`missing ${what}\n${USAGE}`, ExitCode.usage);
52
+ return value;
53
+ }
54
+ function formatRows(rows) {
55
+ const lines = rows.map((r) => [r.name, r.managed ? r.agent : '-', r.state || '-', r.managed ? r.origin : '-', r.live ? 'live' : 'stopped', r.conversation ? 'bound' : '-', r.cwd].join('\t'));
56
+ return ['NAME\tAGENT\tSTATE\tORIGIN\tLIVE\tCONV\tCWD', ...lines].join('\n');
57
+ }
58
+ function formatResults(results) {
59
+ if (results.length === 0)
60
+ return 'nothing to restore';
61
+ return results.map((r) => `${r.name}\t${r.outcome}${r.detail ? `\t${r.detail}` : ''}`).join('\n');
62
+ }
63
+ function cliPath() {
64
+ return realpathSync(fileURLToPath(import.meta.url));
65
+ }
66
+ function readStdin() {
67
+ try {
68
+ return readFileSync(0, 'utf8');
69
+ }
70
+ catch {
71
+ return '';
72
+ }
73
+ }
74
+ function run(ctx, command, rest, out) {
75
+ switch (command) {
76
+ case 'ls': {
77
+ const { values } = parse(rest, { json: { type: 'boolean' } });
78
+ const rows = list(ctx);
79
+ out(values.json ? JSON.stringify(rows, null, 2) : formatRows(rows));
80
+ return ExitCode.ok;
81
+ }
82
+ case 'new': {
83
+ const dash = rest.indexOf('--');
84
+ const own = dash >= 0 ? rest.slice(0, dash) : rest;
85
+ const extraArgs = dash >= 0 ? rest.slice(dash + 1) : [];
86
+ const { values, positionals } = parse(own, { name: { type: 'string' }, cwd: { type: 'string' }, origin: { type: 'string' } });
87
+ const name = create(ctx, {
88
+ agent: need(positionals[0], 'agent'),
89
+ cwd: resolve(values.cwd ?? process.cwd()),
90
+ name: values.name,
91
+ origin: values.origin,
92
+ extraArgs,
93
+ });
94
+ out(name);
95
+ return ExitCode.ok;
96
+ }
97
+ case 'adopt': {
98
+ const { values, positionals } = parse(rest, { agent: { type: 'string' }, origin: { type: 'string' } });
99
+ adopt(ctx, need(positionals[0], 'session'), need(values.agent, '--agent'), values.origin);
100
+ return ExitCode.ok;
101
+ }
102
+ case 'attach': {
103
+ const { values, positionals } = parse(rest, { origin: { type: 'string' } });
104
+ const name = need(positionals[0], 'session');
105
+ requireLive(ctx, name);
106
+ if (values.origin)
107
+ stamp(ctx, name, { origin: checkOrigin(values.origin) });
108
+ const [bin, ...args] = ctx.tmux.attachArgv(name);
109
+ return spawnSync(bin, args, { stdio: 'inherit' }).status ?? ExitCode.failure;
110
+ }
111
+ case 'stamp': {
112
+ const { values, positionals } = parse(rest, { session: { type: 'string' } });
113
+ const pairs = Object.fromEntries(positionals.map((p) => {
114
+ const eq = p.indexOf('=');
115
+ if (eq <= 0)
116
+ throw new BerthError(`expected key=value, got ${p}`, ExitCode.usage);
117
+ return [p.slice(0, eq), p.slice(eq + 1)];
118
+ }));
119
+ const session = values.session ?? (process.env.TMUX_PANE ? ctx.tmux.sessionOfPane(process.env.TMUX_PANE) : undefined);
120
+ stamp(ctx, need(session, '--session (not inside a tmux pane)'), pairs);
121
+ return ExitCode.ok;
122
+ }
123
+ case 'snapshot':
124
+ out(takeSnapshot(ctx));
125
+ return ExitCode.ok;
126
+ case 'present': {
127
+ const name = need(rest[0], 'session');
128
+ requireLive(ctx, name);
129
+ const meta = ctx.tmux.listSessions().find((s) => s.name === name)?.meta ?? {};
130
+ out(String(presentState(ctx.tmux, name, meta.state ?? '', { note: meta.note })));
131
+ return ExitCode.ok;
132
+ }
133
+ case 'tmux': {
134
+ if (rest[0] === 'install')
135
+ out(installTmux(ctx.tmux, cliPath()));
136
+ else if (rest[0] === 'uninstall')
137
+ out(uninstallTmux(ctx.tmux));
138
+ else
139
+ throw new BerthError(`tmux: expected install or uninstall\n${USAGE}`, ExitCode.usage);
140
+ return ExitCode.ok;
141
+ }
142
+ case 'iterm2': {
143
+ if (rest[0] === 'install')
144
+ out(installIterm2(toolsFor(ctx, cliPath())).script);
145
+ else if (rest[0] === 'uninstall')
146
+ out(uninstallIterm2().script);
147
+ else if (rest[0] === 'reattach')
148
+ out(reattach(ctx, toolsFor(ctx, cliPath()), need(rest[1], 'session')));
149
+ else
150
+ throw new BerthError(`iterm2: expected install, uninstall or reattach\n${USAGE}`, ExitCode.usage);
151
+ return ExitCode.ok;
152
+ }
153
+ case 'attached': {
154
+ const { values } = parse(rest, { session: { type: 'string' }, tty: { type: 'string' }, termtype: { type: 'string' } });
155
+ clientAttached(ctx, { session: need(values.session, '--session'), tty: need(values.tty, '--tty'), termtype: values.termtype ?? '' });
156
+ return ExitCode.ok;
157
+ }
158
+ case 'ensure': {
159
+ const { values, positionals } = parse(rest, { origin: { type: 'string' } });
160
+ out(formatResults(ensure(ctx, { origin: values.origin, session: positionals[0] })));
161
+ return ExitCode.ok;
162
+ }
163
+ case 'restore': {
164
+ const { values, positionals } = parse(rest, { origin: { type: 'string' }, session: { type: 'string' } });
165
+ const snapshot = positionals[0] ? ctx.store.read(resolve(positionals[0])) : ctx.store.newest();
166
+ out(formatResults(restoreFrom(ctx, snapshot, { origin: values.origin, session: values.session })));
167
+ return ExitCode.ok;
168
+ }
169
+ case 'show': {
170
+ const { positionals } = parse(rest, {});
171
+ const dir = positionals[1] ? resolve(positionals[1]) : ctx.store.newest()?.dir;
172
+ if (!dir)
173
+ throw new BerthError('no snapshots yet', ExitCode.notFound);
174
+ out(ctx.store.scrollback(dir, need(positionals[0], 'session')));
175
+ return ExitCode.ok;
176
+ }
177
+ case 'doctor': {
178
+ const { values } = parse(rest, { json: { type: 'boolean' } });
179
+ const findings = doctor(ctx);
180
+ out(values.json ? JSON.stringify(findings, null, 2) : findings.map((f) => `${f.session ? `${f.session}: ` : ''}${f.problem}`).join('\n') || 'ok');
181
+ return ExitCode.ok;
182
+ }
183
+ case 'hooks': {
184
+ const [action, agent] = rest;
185
+ if (action === 'install')
186
+ out(installHooks(need(agent, 'agent'), cliPath()));
187
+ else if (action === 'uninstall')
188
+ out(uninstallHooks(need(agent, 'agent')));
189
+ else
190
+ throw new BerthError(`hooks: expected install or uninstall\n${USAGE}`, ExitCode.usage);
191
+ return ExitCode.ok;
192
+ }
193
+ case 'bell': {
194
+ const { values } = parse(rest, { session: { type: 'string' } });
195
+ bellRang(ctx, need(values.session, '--session'));
196
+ return ExitCode.ok;
197
+ }
198
+ case 'hook': {
199
+ handleHook(need(rest[0], 'agent'), need(rest[1], 'event'), readStdin());
200
+ return ExitCode.ok;
201
+ }
202
+ default:
203
+ throw new BerthError(USAGE, ExitCode.usage);
204
+ }
205
+ }
206
+ export function main(argv, out = (t) => process.stdout.write(`${t}\n`)) {
207
+ const args = [...argv];
208
+ const env = { ...process.env };
209
+ for (const [flag, variable] of [['--socket', 'BERTH_TMUX_SOCKET'], ['--socket-path', 'BERTH_TMUX_SOCKET_PATH']]) {
210
+ const at = args.indexOf(flag);
211
+ if (at < 0)
212
+ continue;
213
+ env[variable] = need(args[at + 1], `${flag} value`);
214
+ args.splice(at, 2);
215
+ }
216
+ const [command, ...rest] = args;
217
+ if (!command || command === '-h' || command === '--help') {
218
+ out(USAGE);
219
+ return command ? ExitCode.ok : ExitCode.usage;
220
+ }
221
+ try {
222
+ return run(createContext(env), command, rest, out);
223
+ }
224
+ catch (error) {
225
+ if (error instanceof BerthError) {
226
+ process.stderr.write(`berth: ${error.message}\n`);
227
+ return error.code;
228
+ }
229
+ process.stderr.write(`berth: ${error.message}\n`);
230
+ return ExitCode.failure;
231
+ }
232
+ }
233
+ if (process.argv[1] && realpathSync(process.argv[1]) === cliPath()) {
234
+ process.exitCode = main(process.argv.slice(2));
235
+ }
236
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../../src/cli/main.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ export interface AgentOverride {
2
+ launch?: string;
3
+ resume?: string;
4
+ }
5
+ export interface BerthConfig {
6
+ tmuxBin: string;
7
+ tmuxSocket?: string;
8
+ /** `-S` socket path; set by tmux hooks, which know the server they run in. */
9
+ tmuxSocketPath?: string;
10
+ stateDir: string;
11
+ snapshotRoot: string;
12
+ scrollbackLines: number;
13
+ retention: number;
14
+ agents: Record<string, AgentOverride>;
15
+ /** Command a restored iTerm2 pane runs to attach; `{session}` is the session name (spec §7.3). */
16
+ iterm2Attach?: string;
17
+ }
18
+ type Env = Record<string, string | undefined>;
19
+ /** Precedence: environment > config file > defaults (flags are applied by the CLI). */
20
+ export declare function loadConfig(env?: Env): BerthConfig;
21
+ export {};
@@ -0,0 +1,77 @@
1
+ import { readFileSync, existsSync } from 'node:fs';
2
+ import { homedir } from 'node:os';
3
+ import { basename, join } from 'node:path';
4
+ import { parse } from 'smol-toml';
5
+ import { BerthError, ExitCode } from '../errors.js';
6
+ function configPath(env) {
7
+ if (env.BERTH_CONFIG)
8
+ return env.BERTH_CONFIG;
9
+ const base = env.XDG_CONFIG_HOME || join(env.HOME || homedir(), '.config');
10
+ return join(base, 'berth', 'config.toml');
11
+ }
12
+ function defaultStateDir(env) {
13
+ const base = env.XDG_STATE_HOME || join(env.HOME || homedir(), '.local', 'state');
14
+ return join(base, 'berth');
15
+ }
16
+ function readFile(path) {
17
+ if (!existsSync(path))
18
+ return {};
19
+ try {
20
+ return parse(readFileSync(path, 'utf8'));
21
+ }
22
+ catch (error) {
23
+ throw new BerthError(`cannot read config ${path}: ${error.message}`, ExitCode.usage);
24
+ }
25
+ }
26
+ function positiveInt(value, name, fallback) {
27
+ if (value === undefined)
28
+ return fallback;
29
+ if (typeof value !== 'number' || !Number.isInteger(value) || value < 1) {
30
+ throw new BerthError(`config: ${name} must be a positive integer`, ExitCode.usage);
31
+ }
32
+ return value;
33
+ }
34
+ function agentOverrides(value) {
35
+ if (value === undefined)
36
+ return {};
37
+ if (typeof value !== 'object' || value === null)
38
+ throw new BerthError('config: [agents] must be a table', ExitCode.usage);
39
+ const result = {};
40
+ for (const [id, raw] of Object.entries(value)) {
41
+ const entry = raw;
42
+ for (const key of ['launch', 'resume']) {
43
+ if (entry[key] !== undefined && typeof entry[key] !== 'string') {
44
+ throw new BerthError(`config: agents.${id}.${key} must be a string`, ExitCode.usage);
45
+ }
46
+ }
47
+ result[id] = { launch: entry.launch, resume: entry.resume };
48
+ }
49
+ return result;
50
+ }
51
+ /** Precedence: environment > config file > defaults (flags are applied by the CLI). */
52
+ export function loadConfig(env = process.env) {
53
+ const file = readFile(configPath(env));
54
+ const tmux = (file.tmux ?? {});
55
+ const snapshot = (file.snapshot ?? {});
56
+ const tmuxSocket = env.BERTH_TMUX_SOCKET || (typeof tmux.socket === 'string' ? tmux.socket : undefined);
57
+ const tmuxSocketPath = env.BERTH_TMUX_SOCKET_PATH || undefined;
58
+ // State is per tmux server: snapshots and locks of one server never restore
59
+ // into another. A server is named by its socket (its -L name is the basename).
60
+ const server = tmuxSocketPath ? basename(tmuxSocketPath) : (tmuxSocket ?? 'default');
61
+ const baseState = env.BERTH_STATE_DIR || (typeof file.state_dir === 'string' ? file.state_dir : defaultStateDir(env));
62
+ const stateDir = join(baseState, 'servers', server);
63
+ return {
64
+ tmuxBin: env.BERTH_TMUX || (typeof tmux.binary === 'string' ? tmux.binary : 'tmux'),
65
+ tmuxSocket,
66
+ tmuxSocketPath,
67
+ stateDir,
68
+ snapshotRoot: typeof snapshot.root === 'string' ? join(snapshot.root, server) : join(stateDir, 'snapshots'),
69
+ scrollbackLines: positiveInt(snapshot.scrollback_lines, 'snapshot.scrollback_lines', 3000),
70
+ retention: positiveInt(snapshot.keep, 'snapshot.keep', 5),
71
+ agents: agentOverrides(file.agents),
72
+ iterm2Attach: typeof file.iterm2?.attach === 'string'
73
+ ? file.iterm2.attach
74
+ : undefined,
75
+ };
76
+ }
77
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/config/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { type BerthConfig } from './config/index.js';
2
+ import { SnapshotStore } from './snapshot/store.js';
3
+ import { Tmux } from './tmux/client.js';
4
+ export interface Context {
5
+ config: BerthConfig;
6
+ tmux: Tmux;
7
+ store: SnapshotStore;
8
+ }
9
+ export declare function createContext(env?: Record<string, string | undefined>): Context;
@@ -0,0 +1,12 @@
1
+ import { loadConfig } from './config/index.js';
2
+ import { SnapshotStore } from './snapshot/store.js';
3
+ import { Tmux } from './tmux/client.js';
4
+ export function createContext(env = process.env) {
5
+ const config = loadConfig(env);
6
+ return {
7
+ config,
8
+ tmux: new Tmux({ bin: config.tmuxBin, socket: config.tmuxSocket, socketPath: config.tmuxSocketPath }),
9
+ store: new SnapshotStore(config.snapshotRoot),
10
+ };
11
+ }
12
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAoB,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAQxC,MAAM,UAAU,aAAa,CAAC,MAA0C,OAAO,CAAC,GAAG;IACjF,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IAC/B,OAAO;QACL,MAAM;QACN,IAAI,EAAE,IAAI,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,UAAU,EAAE,MAAM,CAAC,cAAc,EAAE,CAAC;QACrG,KAAK,EAAE,IAAI,aAAa,CAAC,MAAM,CAAC,YAAY,CAAC;KAC9C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,13 @@
1
+ /** Exit codes, see design/implementation.md §2.3. */
2
+ export declare const ExitCode: {
3
+ readonly ok: 0;
4
+ readonly failure: 1;
5
+ readonly usage: 2;
6
+ readonly tmuxUnavailable: 3;
7
+ readonly notFound: 4;
8
+ };
9
+ export type ExitCodeValue = (typeof ExitCode)[keyof typeof ExitCode];
10
+ export declare class BerthError extends Error {
11
+ readonly code: ExitCodeValue;
12
+ constructor(message: string, code?: ExitCodeValue);
13
+ }
@@ -0,0 +1,17 @@
1
+ /** Exit codes, see design/implementation.md §2.3. */
2
+ export const ExitCode = {
3
+ ok: 0,
4
+ failure: 1,
5
+ usage: 2,
6
+ tmuxUnavailable: 3,
7
+ notFound: 4,
8
+ };
9
+ export class BerthError extends Error {
10
+ code;
11
+ constructor(message, code = ExitCode.failure) {
12
+ super(message);
13
+ this.code = code;
14
+ this.name = 'BerthError';
15
+ }
16
+ }
17
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,EAAE,EAAE,CAAC;IACL,OAAO,EAAE,CAAC;IACV,KAAK,EAAE,CAAC;IACR,eAAe,EAAE,CAAC;IAClB,QAAQ,EAAE,CAAC;CACH,CAAC;AAIX,MAAM,OAAO,UAAW,SAAQ,KAAK;IACG;IAAtC,YAAY,OAAe,EAAW,OAAsB,QAAQ,CAAC,OAAO;QAC1E,KAAK,CAAC,OAAO,CAAC,CAAC;QADqB,SAAI,GAAJ,IAAI,CAAkC;QAE1E,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;IAC3B,CAAC;CACF"}
@@ -0,0 +1,17 @@
1
+ export { createContext, type Context } from './context.js';
2
+ export { loadConfig, type BerthConfig } from './config/index.js';
3
+ export { BerthError, ExitCode } from './errors.js';
4
+ export { Tmux, type LiveSession, type SessionMeta } from './tmux/client.js';
5
+ export { ADAPTERS, getAdapter, type Adapter } from './agents/registry.js';
6
+ export { keptArgs, launchCommand, resumeCommand } from './agents/commands.js';
7
+ export { installHooks, uninstallHooks, handleHook, metaForEvent } from './agents/hooks.js';
8
+ export { list, create, adopt, stamp, bellRang, clearBell, BELL_NOTE, type SessionRow } from './registry/sessions.js';
9
+ export { doctor } from './registry/doctor.js';
10
+ export { SnapshotStore, type Snapshot, type SnapshotSession } from './snapshot/store.js';
11
+ export { takeSnapshot } from './snapshot/take.js';
12
+ export { ensure, restoreFrom, type RestoreResult } from './restore/ensure.js';
13
+ export { presentState, sequencesFor } from './present/state.js';
14
+ export { installTmux, uninstallTmux } from './tmux/install.js';
15
+ export { installIterm2, uninstallIterm2, reattach, attachCommand, autoLaunchScript, type Tools } from './iterm2/install.js';
16
+ export { clientAttached, PANE_VARIABLE } from './present/attach.js';
17
+ export { toolsFor, resolveBinary } from './tools.js';
@@ -0,0 +1,18 @@
1
+ export { createContext } from './context.js';
2
+ export { loadConfig } from './config/index.js';
3
+ export { BerthError, ExitCode } from './errors.js';
4
+ export { Tmux } from './tmux/client.js';
5
+ export { ADAPTERS, getAdapter } from './agents/registry.js';
6
+ export { keptArgs, launchCommand, resumeCommand } from './agents/commands.js';
7
+ export { installHooks, uninstallHooks, handleHook, metaForEvent } from './agents/hooks.js';
8
+ export { list, create, adopt, stamp, bellRang, clearBell, BELL_NOTE } from './registry/sessions.js';
9
+ export { doctor } from './registry/doctor.js';
10
+ export { SnapshotStore } from './snapshot/store.js';
11
+ export { takeSnapshot } from './snapshot/take.js';
12
+ export { ensure, restoreFrom } from './restore/ensure.js';
13
+ export { presentState, sequencesFor } from './present/state.js';
14
+ export { installTmux, uninstallTmux } from './tmux/install.js';
15
+ export { installIterm2, uninstallIterm2, reattach, attachCommand, autoLaunchScript } from './iterm2/install.js';
16
+ export { clientAttached, PANE_VARIABLE } from './present/attach.js';
17
+ export { toolsFor, resolveBinary } from './tools.js';
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAgB,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAoB,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,IAAI,EAAsC,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAgB,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC3F,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAmB,MAAM,wBAAwB,CAAC;AACrH,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAuC,MAAM,qBAAqB,CAAC;AACzF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAsB,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,QAAQ,EAAE,aAAa,EAAE,gBAAgB,EAAc,MAAM,qBAAqB,CAAC;AAC5H,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,29 @@
1
+ import type { Context } from '../context.js';
2
+ /**
3
+ * Berth for iTerm2 (spec §7): iTerm2 restores windows, tabs and split panes;
4
+ * an AutoLaunch script puts each restored pane back in its session. iTerm2
5
+ * starts AutoLaunch scripts with a minimal PATH, so every tool is referenced
6
+ * by absolute path.
7
+ */
8
+ export interface Iterm2Paths {
9
+ script: string;
10
+ /** Written by earlier versions (one profile per session); removed on install. */
11
+ legacyProfiles: string;
12
+ }
13
+ export declare function iterm2Paths(env?: NodeJS.ProcessEnv): Iterm2Paths;
14
+ export interface Tools {
15
+ node: string;
16
+ cli: string;
17
+ tmux: string;
18
+ socket?: string;
19
+ /** PATH at install time: AutoLaunch scripts get a minimal one, without tmux or the agents. */
20
+ path?: string;
21
+ }
22
+ /** Command that attaches a pane to `session`: the configured template, or tmux attach. */
23
+ export declare function attachCommand(ctx: Context, tools: Tools, session: string): string;
24
+ /** `berth iterm2 reattach <session>`: rebuild the session if missing, return its attach command. */
25
+ export declare function reattach(ctx: Context, tools: Tools, session: string): string;
26
+ export declare function autoLaunchScript(tools: Tools): string;
27
+ export declare function installIterm2(tools: Tools, env?: NodeJS.ProcessEnv): Iterm2Paths;
28
+ export declare function uninstallIterm2(env?: NodeJS.ProcessEnv): Iterm2Paths;
29
+ export declare function iterm2Installed(env?: NodeJS.ProcessEnv): boolean;
@@ -0,0 +1,112 @@
1
+ import { existsSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
2
+ import { homedir } from 'node:os';
3
+ import { dirname, join } from 'node:path';
4
+ import { BerthError, ExitCode } from '../errors.js';
5
+ import { ensure } from '../restore/ensure.js';
6
+ import { renderTemplate, shellQuote } from '../shell.js';
7
+ import { PANE_VARIABLE } from '../present/attach.js';
8
+ export function iterm2Paths(env = process.env) {
9
+ const base = join(env.HOME || homedir(), 'Library', 'Application Support', 'iTerm2');
10
+ return {
11
+ script: join(base, 'Scripts', 'AutoLaunch', 'berth.py'),
12
+ legacyProfiles: join(base, 'DynamicProfiles', 'berth.json'),
13
+ };
14
+ }
15
+ /** Command that attaches a pane to `session`: the configured template, or tmux attach. */
16
+ export function attachCommand(ctx, tools, session) {
17
+ const template = ctx.config.iterm2Attach;
18
+ if (template)
19
+ return renderTemplate(template, { session });
20
+ const socket = tools.socket ? ` -L ${shellQuote(tools.socket)}` : '';
21
+ return `${shellQuote(tools.tmux)}${socket} attach-session -t ${shellQuote(`=${session}`)}`;
22
+ }
23
+ /** `berth iterm2 reattach <session>`: rebuild the session if missing, return its attach command. */
24
+ export function reattach(ctx, tools, session) {
25
+ if (!ctx.tmux.hasSession(session))
26
+ ensure(ctx, { session });
27
+ if (!ctx.tmux.hasSession(session))
28
+ throw new BerthError(`cannot restore session ${session}`, ExitCode.notFound);
29
+ return attachCommand(ctx, tools, session);
30
+ }
31
+ export function autoLaunchScript(tools) {
32
+ const berth = JSON.stringify([tools.node, tools.cli, ...(tools.socket ? ['--socket', tools.socket] : [])]);
33
+ return `#!/usr/bin/env python3
34
+ """Berth for iTerm2: put each pane iTerm2 restored back in its agent session.
35
+
36
+ Generated by \`berth iterm2 install\`; do not edit. iTerm2 restores the
37
+ windows, tabs and split panes; Berth marked each pane with the session it
38
+ showed (user variable ${PANE_VARIABLE}). This script asks the berth CLI to
39
+ rebuild a missing session and to give the command that attaches it, and
40
+ types that command into the pane. It holds no session logic.
41
+ """
42
+ import asyncio
43
+ import os
44
+ import subprocess
45
+
46
+ import iterm2
47
+
48
+ BERTH = ${berth}
49
+ VARIABLE = "user.${PANE_VARIABLE}"
50
+ # Recorded at install: iTerm2's PATH for AutoLaunch has neither tmux nor the agent CLIs.
51
+ ENV = dict(os.environ, PATH=${JSON.stringify(tools.path ?? '')} or os.environ.get("PATH", ""))
52
+
53
+
54
+ def attach_command(session_name):
55
+ try:
56
+ done = subprocess.run(BERTH + ["iterm2", "reattach", session_name], capture_output=True, text=True, timeout=120, env=ENV)
57
+ except (OSError, subprocess.SubprocessError):
58
+ return None
59
+ command = done.stdout.strip()
60
+ return command if done.returncode == 0 and command else None
61
+
62
+
63
+ async def panes(app):
64
+ for window in app.terminal_windows:
65
+ for tab in window.tabs:
66
+ for session in tab.sessions:
67
+ yield session
68
+
69
+
70
+ async def main(connection):
71
+ app = await iterm2.async_get_app(connection)
72
+ # Window restoration may still be running when AutoLaunch starts.
73
+ for _ in range(20):
74
+ if app.terminal_windows:
75
+ break
76
+ await asyncio.sleep(0.5)
77
+ await asyncio.sleep(1)
78
+ async for session in panes(app):
79
+ name = await session.async_get_variable(VARIABLE)
80
+ if not name:
81
+ continue
82
+ job = await session.async_get_variable("jobName")
83
+ if job == "tmux":
84
+ continue # still attached (iTerm2 kept the process alive)
85
+ command = await asyncio.get_running_loop().run_in_executor(None, attach_command, name)
86
+ if command:
87
+ await session.async_send_text(command + "\\n")
88
+ else:
89
+ # Shown on the screen only, never run by the shell.
90
+ await session.async_inject(("berth: could not restore session %s\\r\\n" % name).encode())
91
+
92
+
93
+ iterm2.run_until_complete(main)
94
+ `;
95
+ }
96
+ export function installIterm2(tools, env = process.env) {
97
+ const paths = iterm2Paths(env);
98
+ mkdirSync(dirname(paths.script), { recursive: true });
99
+ writeFileSync(paths.script, autoLaunchScript(tools), { mode: 0o755 });
100
+ rmSync(paths.legacyProfiles, { force: true });
101
+ return paths;
102
+ }
103
+ export function uninstallIterm2(env = process.env) {
104
+ const paths = iterm2Paths(env);
105
+ rmSync(paths.script, { force: true });
106
+ rmSync(paths.legacyProfiles, { force: true });
107
+ return paths;
108
+ }
109
+ export function iterm2Installed(env = process.env) {
110
+ return existsSync(iterm2Paths(env).script);
111
+ }
112
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/iterm2/install.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { Context } from '../context.js';
2
+ /** iTerm2 user variable naming the session a pane shows (spec §7.3). */
3
+ export declare const PANE_VARIABLE = "berthSession";
4
+ export declare function setUserVar(name: string, value: string): string;
5
+ export interface AttachedClient {
6
+ session: string;
7
+ tty: string;
8
+ termtype: string;
9
+ }
10
+ /**
11
+ * A client attached to a session, or switched to one (tmux hooks
12
+ * client-attached / client-session-changed). For iTerm2 the pane is marked
13
+ * with the session's name and the session's origin becomes iterm2; every
14
+ * client is shown the session's current state.
15
+ */
16
+ export declare function clientAttached(ctx: Context, client: AttachedClient): void;