@berthdev/berth 0.3.5 → 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.
- package/README.md +7 -1
- package/dist/src/agents/capabilities.d.ts +13 -0
- package/dist/src/agents/capabilities.js +52 -0
- package/dist/src/agents/capabilities.js.map +1 -0
- package/dist/src/agents/codex-binding.d.ts +10 -0
- package/dist/src/agents/codex-binding.js +105 -0
- package/dist/src/agents/codex-binding.js.map +1 -0
- package/dist/src/agents/commands.d.ts +4 -2
- package/dist/src/agents/commands.js +41 -9
- package/dist/src/agents/commands.js.map +1 -1
- package/dist/src/agents/copilot-state.d.ts +3 -0
- package/dist/src/agents/copilot-state.js +94 -0
- package/dist/src/agents/copilot-state.js.map +1 -0
- package/dist/src/agents/gemini-state.d.ts +3 -0
- package/dist/src/agents/gemini-state.js +41 -0
- package/dist/src/agents/gemini-state.js.map +1 -0
- package/dist/src/agents/hook-files.d.ts +1 -3
- package/dist/src/agents/hook-files.js +69 -53
- package/dist/src/agents/hook-files.js.map +1 -1
- package/dist/src/agents/hook-health.d.ts +4 -0
- package/dist/src/agents/hook-health.js +95 -0
- package/dist/src/agents/hook-health.js.map +1 -0
- package/dist/src/agents/hooks.d.ts +4 -1
- package/dist/src/agents/hooks.js +155 -22
- package/dist/src/agents/hooks.js.map +1 -1
- package/dist/src/agents/jsonl-titles.d.ts +8 -0
- package/dist/src/agents/jsonl-titles.js +124 -0
- package/dist/src/agents/jsonl-titles.js.map +1 -0
- package/dist/src/agents/late-binding.d.ts +2 -0
- package/dist/src/agents/late-binding.js +25 -0
- package/dist/src/agents/late-binding.js.map +1 -0
- package/dist/src/agents/profile.d.ts +14 -0
- package/dist/src/agents/profile.js +75 -0
- package/dist/src/agents/profile.js.map +1 -0
- package/dist/src/agents/registry.d.ts +12 -3
- package/dist/src/agents/registry.js +52 -19
- package/dist/src/agents/registry.js.map +1 -1
- package/dist/src/agents/roots.d.ts +2 -0
- package/dist/src/agents/roots.js +21 -0
- package/dist/src/agents/roots.js.map +1 -0
- package/dist/src/agents/titles.d.ts +14 -0
- package/dist/src/agents/titles.js +82 -0
- package/dist/src/agents/titles.js.map +1 -0
- package/dist/src/agents/transcript-cursor.d.ts +9 -0
- package/dist/src/agents/transcript-cursor.js +86 -0
- package/dist/src/agents/transcript-cursor.js.map +1 -0
- package/dist/src/cli/main.js +40 -7
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/config/index.d.ts +6 -0
- package/dist/src/config/index.js +37 -6
- package/dist/src/config/index.js.map +1 -1
- package/dist/src/config/write.d.ts +2 -0
- package/dist/src/config/write.js +41 -0
- package/dist/src/config/write.js.map +1 -0
- package/dist/src/context.js +1 -1
- package/dist/src/context.js.map +1 -1
- package/dist/src/index.d.ts +11 -5
- package/dist/src/index.js +10 -4
- package/dist/src/index.js.map +1 -1
- package/dist/src/iterm2/install.d.ts +2 -0
- package/dist/src/iterm2/install.js +37 -12
- package/dist/src/iterm2/install.js.map +1 -1
- package/dist/src/present/attach.js +17 -5
- package/dist/src/present/attach.js.map +1 -1
- package/dist/src/present/state.d.ts +3 -0
- package/dist/src/present/state.js +12 -8
- package/dist/src/present/state.js.map +1 -1
- package/dist/src/process-arguments.d.ts +2 -0
- package/dist/src/process-arguments.js +59 -0
- package/dist/src/process-arguments.js.map +1 -0
- package/dist/src/process-directory.d.ts +2 -0
- package/dist/src/process-directory.js +37 -0
- package/dist/src/process-directory.js.map +1 -0
- package/dist/src/process-owner.d.ts +7 -0
- package/dist/src/process-owner.js +51 -0
- package/dist/src/process-owner.js.map +1 -0
- package/dist/src/registry/directory.d.ts +2 -0
- package/dist/src/registry/directory.js +19 -0
- package/dist/src/registry/directory.js.map +1 -0
- package/dist/src/registry/discover.d.ts +15 -5
- package/dist/src/registry/discover.js +135 -38
- package/dist/src/registry/discover.js.map +1 -1
- package/dist/src/registry/doctor.d.ts +5 -1
- package/dist/src/registry/doctor.js +53 -12
- package/dist/src/registry/doctor.js.map +1 -1
- package/dist/src/registry/hosts.d.ts +28 -0
- package/dist/src/registry/hosts.js +73 -0
- package/dist/src/registry/hosts.js.map +1 -0
- package/dist/src/registry/launch.d.ts +3 -0
- package/dist/src/registry/launch.js +29 -0
- package/dist/src/registry/launch.js.map +1 -0
- package/dist/src/registry/native-state.d.ts +20 -0
- package/dist/src/registry/native-state.js +127 -0
- package/dist/src/registry/native-state.js.map +1 -0
- package/dist/src/registry/sessions.d.ts +21 -3
- package/dist/src/registry/sessions.js +178 -37
- package/dist/src/registry/sessions.js.map +1 -1
- package/dist/src/restore/ensure.d.ts +12 -2
- package/dist/src/restore/ensure.js +171 -37
- package/dist/src/restore/ensure.js.map +1 -1
- package/dist/src/restore/lock.d.ts +3 -5
- package/dist/src/restore/lock.js +82 -52
- package/dist/src/restore/lock.js.map +1 -1
- package/dist/src/restore/status.d.ts +9 -0
- package/dist/src/restore/status.js +16 -0
- package/dist/src/restore/status.js.map +1 -0
- package/dist/src/snapshot/identity.d.ts +7 -0
- package/dist/src/snapshot/identity.js +20 -0
- package/dist/src/snapshot/identity.js.map +1 -0
- package/dist/src/snapshot/lifecycle.d.ts +9 -0
- package/dist/src/snapshot/lifecycle.js +37 -0
- package/dist/src/snapshot/lifecycle.js.map +1 -0
- package/dist/src/snapshot/store.d.ts +11 -1
- package/dist/src/snapshot/store.js +28 -9
- package/dist/src/snapshot/store.js.map +1 -1
- package/dist/src/snapshot/take.d.ts +2 -1
- package/dist/src/snapshot/take.js +29 -25
- package/dist/src/snapshot/take.js.map +1 -1
- package/dist/src/tmux/client.d.ts +6 -2
- package/dist/src/tmux/client.js +49 -25
- package/dist/src/tmux/client.js.map +1 -1
- package/dist/src/tmux/connections.d.ts +22 -0
- package/dist/src/tmux/connections.js +70 -0
- package/dist/src/tmux/connections.js.map +1 -0
- package/dist/src/tmux/fields.d.ts +7 -0
- package/dist/src/tmux/fields.js +23 -0
- package/dist/src/tmux/fields.js.map +1 -0
- package/dist/src/tmux/install.js +31 -18
- package/dist/src/tmux/install.js.map +1 -1
- package/dist/src/tools.d.ts +3 -1
- package/dist/src/tools.js +23 -11
- package/dist/src/tools.js.map +1 -1
- package/package.json +1 -1
- package/dist/src/agents/name-key.d.ts +0 -1
- package/dist/src/agents/name-key.js +0 -66
- package/dist/src/agents/name-key.js.map +0 -1
package/dist/src/index.js.map
CHANGED
|
@@ -1 +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,UAAU,EAAE,QAAQ,EAAmB,MAAM,mBAAmB,CAAC;
|
|
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,UAAU,EAAE,QAAQ,EAAE,iBAAiB,EAAE,iBAAiB,EAAmB,MAAM,mBAAmB,CAAC;AACxK,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAmB,MAAM,wBAAwB,CAAC;AACrJ,OAAO,EAAE,MAAM,EAAgB,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAuC,MAAM,qBAAqB,CAAC;AACzF,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,kBAAkB,EAAsB,MAAM,qBAAqB,CAAC;AACvJ,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACrF,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;AAErD,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,eAAe,EAAuB,MAAM,uBAAuB,CAAC;AAEpI,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,eAAe,EAA0B,MAAM,qBAAqB,CAAC;AAEnH,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,kBAAkB,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAqB,MAAM,qBAAqB,CAAC;AAEjJ,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -17,7 +17,7 @@ export function attachCommand(ctx, tools, session) {
|
|
|
17
17
|
const template = ctx.config.iterm2Attach;
|
|
18
18
|
if (template)
|
|
19
19
|
return renderTemplate(template, { session });
|
|
20
|
-
const socket = tools.socket ? ` -L ${shellQuote(tools.socket)}` : '';
|
|
20
|
+
const socket = tools.socketPath ? ` -S ${shellQuote(tools.socketPath)}` : tools.socket ? ` -L ${shellQuote(tools.socket)}` : '';
|
|
21
21
|
return `${shellQuote(tools.tmux)}${socket} attach-session -t ${shellQuote(`=${session}`)}`;
|
|
22
22
|
}
|
|
23
23
|
/** `berth iterm2 reattach <session>`: rebuild the session if missing, return its attach command. */
|
|
@@ -29,7 +29,7 @@ export function reattach(ctx, tools, session) {
|
|
|
29
29
|
return attachCommand(ctx, tools, session);
|
|
30
30
|
}
|
|
31
31
|
export function autoLaunchScript(tools) {
|
|
32
|
-
const berth = JSON.stringify([tools.node, tools.cli, ...(tools.socket ? ['--socket', tools.socket] : [])]);
|
|
32
|
+
const berth = JSON.stringify([tools.node, tools.cli, ...(tools.socketPath ? ['--socket-path', tools.socketPath] : tools.socket ? ['--socket', tools.socket] : [])]);
|
|
33
33
|
return `#!/usr/bin/env python3
|
|
34
34
|
"""Berth for iTerm2: put each pane iTerm2 restored back in its agent session.
|
|
35
35
|
|
|
@@ -48,7 +48,8 @@ import iterm2
|
|
|
48
48
|
BERTH = ${berth}
|
|
49
49
|
VARIABLE = "user.${PANE_VARIABLE}"
|
|
50
50
|
# Recorded at install: iTerm2's PATH for AutoLaunch has neither tmux nor the agent CLIs.
|
|
51
|
-
ENV = dict(os.environ,
|
|
51
|
+
ENV = dict(os.environ, **${JSON.stringify(tools.env ?? {})})
|
|
52
|
+
ENV["PATH"] = ${JSON.stringify(tools.path ?? '')} or os.environ.get("PATH", "")
|
|
52
53
|
|
|
53
54
|
|
|
54
55
|
def attach_command(session_name):
|
|
@@ -67,6 +68,38 @@ async def panes(app):
|
|
|
67
68
|
yield session
|
|
68
69
|
|
|
69
70
|
|
|
71
|
+
async def ready_prompt(connection, session, name):
|
|
72
|
+
if await session.async_get_variable(VARIABLE) != name:
|
|
73
|
+
return None
|
|
74
|
+
job = await session.async_get_variable("jobName")
|
|
75
|
+
if os.path.basename(job or "").lstrip("-") not in {"sh", "bash", "zsh", "fish", "tcsh", "xonsh"}:
|
|
76
|
+
return None
|
|
77
|
+
prompt = await iterm2.async_get_last_prompt(connection, session.session_id)
|
|
78
|
+
if prompt and prompt.state == iterm2.PromptState.EDITING and prompt.command == "":
|
|
79
|
+
return prompt.unique_id
|
|
80
|
+
return None
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
async def restore_pane(connection, session, name):
|
|
84
|
+
try:
|
|
85
|
+
async with iterm2.Transaction(connection):
|
|
86
|
+
prompt_id = await ready_prompt(connection, session, name)
|
|
87
|
+
if not prompt_id:
|
|
88
|
+
print("Berth: reattach deferred for %s; use berth iterm2 reattach from a ready shell." % name)
|
|
89
|
+
return
|
|
90
|
+
command = await asyncio.get_running_loop().run_in_executor(None, attach_command, name)
|
|
91
|
+
if not command:
|
|
92
|
+
print("Berth: could not restore %s; inspect berth doctor." % name)
|
|
93
|
+
return
|
|
94
|
+
async with iterm2.Transaction(connection):
|
|
95
|
+
if await ready_prompt(connection, session, name) == prompt_id:
|
|
96
|
+
await session.async_send_text(command + "\\n")
|
|
97
|
+
else:
|
|
98
|
+
print("Berth: pane changed while restoring %s; automatic attachment deferred." % name)
|
|
99
|
+
except (AttributeError, iterm2.RPCException) as error:
|
|
100
|
+
print("Berth: cannot verify shell readiness for %s: %s" % (name, error))
|
|
101
|
+
|
|
102
|
+
|
|
70
103
|
async def main(connection):
|
|
71
104
|
app = await iterm2.async_get_app(connection)
|
|
72
105
|
# Window restoration may still be running when AutoLaunch starts.
|
|
@@ -79,15 +112,7 @@ async def main(connection):
|
|
|
79
112
|
name = await session.async_get_variable(VARIABLE)
|
|
80
113
|
if not name:
|
|
81
114
|
continue
|
|
82
|
-
|
|
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())
|
|
115
|
+
await restore_pane(connection, session, name)
|
|
91
116
|
|
|
92
117
|
|
|
93
118
|
iterm2.run_until_complete(main)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/iterm2/install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACvE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAerD,MAAM,UAAU,WAAW,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG;IAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,EAAE,EAAE,SAAS,EAAE,qBAAqB,EAAE,QAAQ,CAAC,CAAC;IACrF,OAAO;QACL,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,CAAC;QACvD,cAAc,EAAE,IAAI,CAAC,IAAI,EAAE,iBAAiB,EAAE,YAAY,CAAC;KAC5D,CAAC;AACJ,CAAC;
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/iterm2/install.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import { withLock } from '../restore/lock.js';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import { profileEnvironment, readProfile } from '../agents/profile.js';
|
|
1
4
|
import { appendFileSync } from 'node:fs';
|
|
2
5
|
import { stamp } from '../registry/sessions.js';
|
|
3
|
-
import { isIterm2, presentState } from './state.js';
|
|
6
|
+
import { clientsOf, isIterm2, presentState } from './state.js';
|
|
4
7
|
import { hookHint, hookStatus } from '../agents/hooks.js';
|
|
5
8
|
import { adoptDiscovered } from '../snapshot/take.js';
|
|
6
9
|
/** iTerm2 user variable naming the session a pane shows (spec §7.3). */
|
|
@@ -15,6 +18,13 @@ export function setUserVar(name, value) {
|
|
|
15
18
|
* client is shown the session's current state.
|
|
16
19
|
*/
|
|
17
20
|
export function clientAttached(ctx, client) {
|
|
21
|
+
withLock(ctx.config.stateDir, () => attachCurrentClient(ctx, client), 3000);
|
|
22
|
+
}
|
|
23
|
+
function attachCurrentClient(ctx, event) {
|
|
24
|
+
const current = clientsOf(ctx.tmux, event.session).find((client) => client.tty === event.tty);
|
|
25
|
+
if (!current)
|
|
26
|
+
return;
|
|
27
|
+
const client = { ...current, session: event.session };
|
|
18
28
|
adoptDiscovered(ctx);
|
|
19
29
|
const live = ctx.tmux.listSessions().find((s) => s.name === client.session);
|
|
20
30
|
if (!live?.meta.agent)
|
|
@@ -31,17 +41,19 @@ export function clientAttached(ctx, client) {
|
|
|
31
41
|
}
|
|
32
42
|
presentState(ctx.tmux, client.session, live.meta.state ?? '', { note: live.meta.note, clients: [{ tty: client.tty, termtype: client.termtype }] });
|
|
33
43
|
if (live.meta.origin !== 'vscode')
|
|
34
|
-
hintHooksOnce(ctx, live.meta.agent, client.tty);
|
|
44
|
+
hintHooksOnce(ctx, live.meta.agent, client.tty, live.meta.profile);
|
|
35
45
|
}
|
|
36
46
|
const HINT_SECONDS = 10;
|
|
37
47
|
/**
|
|
38
48
|
* Terminals other than VS Code (which asks in its own UI) get the hooks hint
|
|
39
49
|
* in tmux's status line, once per agent per tmux server.
|
|
40
50
|
*/
|
|
41
|
-
function hintHooksOnce(ctx, agent, tty) {
|
|
42
|
-
|
|
51
|
+
function hintHooksOnce(ctx, agent, tty, rawProfile) {
|
|
52
|
+
const profile = readProfile(agent, rawProfile);
|
|
53
|
+
if (!profile || hookStatus(agent, profileEnvironment(agent, profile, ctx.env)) !== 'missing')
|
|
43
54
|
return;
|
|
44
|
-
const
|
|
55
|
+
const key = createHash('sha256').update(JSON.stringify(profile.environment)).digest('hex').slice(0, 12);
|
|
56
|
+
const flag = `@berth_hinted_${agent}_${key}`;
|
|
45
57
|
if (ctx.tmux.run(['show-option', '-gqv', flag], true).stdout.trim())
|
|
46
58
|
return;
|
|
47
59
|
ctx.tmux.run(['set-option', '-g', flag, '1'], true);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attach.js","sourceRoot":"","sources":["../../../src/present/attach.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEzC,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"attach.js","sourceRoot":"","sources":["../../../src/present/attach.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Context } from '../context.js';
|
|
1
2
|
import type { Tmux } from '../tmux/client.js';
|
|
2
3
|
export declare function isIterm2(termtype: string): boolean;
|
|
3
4
|
export declare function sequencesFor(state: string, session: string, iterm2: boolean, note?: string): string;
|
|
@@ -12,3 +13,5 @@ export interface PresentOptions {
|
|
|
12
13
|
}
|
|
13
14
|
/** Write the state to each attached terminal; failures are ignored (best effort). */
|
|
14
15
|
export declare function presentState(tmux: Tmux, session: string, state: string, options?: PresentOptions): number;
|
|
16
|
+
/** Attachment must not replay an inventory state older than a hook or acknowledgement. */
|
|
17
|
+
export declare function presentCurrentState(ctx: Context, session: string): void;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { withLock } from '../restore/lock.js';
|
|
2
|
+
import { formatFields, readFields } from '../tmux/fields.js';
|
|
1
3
|
import { appendFileSync } from 'node:fs';
|
|
2
4
|
/**
|
|
3
5
|
* Show a session's agent state on every terminal attached to it (spec §6, §7.4).
|
|
@@ -34,16 +36,10 @@ export function sequencesFor(state, session, iterm2, note = '') {
|
|
|
34
36
|
return `${OSC}9;4;${PROGRESS[state] ?? '0'};0${ST}${OSC}2;${glyph ? `${glyph} ` : ''}${session}${ST}`;
|
|
35
37
|
}
|
|
36
38
|
export function clientsOf(tmux, session) {
|
|
37
|
-
const result = tmux.run(['list-clients', '-t', `=${session}`, '-F', '
|
|
39
|
+
const result = tmux.run(['list-clients', '-t', `=${session}`, '-F', formatFields(['client_tty', 'client_termtype'])], true);
|
|
38
40
|
if (!result.ok)
|
|
39
41
|
return [];
|
|
40
|
-
return result.stdout
|
|
41
|
-
.split('\n')
|
|
42
|
-
.filter(Boolean)
|
|
43
|
-
.map((line) => {
|
|
44
|
-
const [tty, termtype = ''] = line.split('\t');
|
|
45
|
-
return { tty, termtype };
|
|
46
|
-
});
|
|
42
|
+
return readFields(result.stdout, 2).map(([tty, termtype]) => ({ tty, termtype }));
|
|
47
43
|
}
|
|
48
44
|
/** Write the state to each attached terminal; failures are ignored (best effort). */
|
|
49
45
|
export function presentState(tmux, session, state, options = {}) {
|
|
@@ -60,4 +56,12 @@ export function presentState(tmux, session, state, options = {}) {
|
|
|
60
56
|
}
|
|
61
57
|
return written;
|
|
62
58
|
}
|
|
59
|
+
/** Attachment must not replay an inventory state older than a hook or acknowledgement. */
|
|
60
|
+
export function presentCurrentState(ctx, session) {
|
|
61
|
+
withLock(ctx.config.stateDir, () => {
|
|
62
|
+
const live = ctx.tmux.listSessions().find((row) => row.name === session);
|
|
63
|
+
if (live)
|
|
64
|
+
presentState(ctx.tmux, session, live.meta.state ?? '', { note: live.meta.note });
|
|
65
|
+
}, 3000);
|
|
66
|
+
}
|
|
63
67
|
//# sourceMappingURL=state.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/present/state.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../../src/present/state.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
const MAX_BYTES = 16 * 1024 * 1024;
|
|
4
|
+
// Darwin: SYS___sysctl=202, CTL_KERN=1, KERN_PROCARGS2=49.
|
|
5
|
+
// Keep the bridge inline so the CLI and extension bundle share the same reader.
|
|
6
|
+
// It returns argc argv entries only; environment strings never leave this process.
|
|
7
|
+
// XNU exec_extract_strings aligns the saved executable path to 8 bytes for
|
|
8
|
+
// supported 64-bit macOS processes. kern_procargs2 removes the 16-byte
|
|
9
|
+
// executable_path= prefix and prepends argc (4 bytes). Do not skip NULs: they
|
|
10
|
+
// may be empty argv entries, and skipping them would expose environment data.
|
|
11
|
+
const DARWIN_ARGV = String.raw `use strict;
|
|
12
|
+
use warnings;
|
|
13
|
+
my $pid = shift @ARGV;
|
|
14
|
+
my $mib = pack('i3', 1, 49, $pid);
|
|
15
|
+
my $size = pack('Q', 0);
|
|
16
|
+
syscall(202, $mib, 3, 0, $size, 0, 0) == 0 or die "size";
|
|
17
|
+
my $length = unpack('Q', $size);
|
|
18
|
+
$length > 4 && $length <= 16777216 or die "bound";
|
|
19
|
+
my $buf = "\0" x $length;
|
|
20
|
+
syscall(202, $mib, 3, $buf, $size, 0, 0) == 0 or die "read";
|
|
21
|
+
$buf = substr($buf, 0, unpack('Q', $size));
|
|
22
|
+
my $argc = unpack('i', $buf);
|
|
23
|
+
my $path_end = index($buf, "\0", 4);
|
|
24
|
+
$path_end >= 4 && $argc > 0 && $argc <= 65536 or die "header";
|
|
25
|
+
my $start = 4 + int(($path_end - 4 + 1 + 7) / 8) * 8;
|
|
26
|
+
$start < length($buf) or die "alignment";
|
|
27
|
+
substr($buf, $path_end, $start - $path_end) !~ /[^\0]/ or die "padding";
|
|
28
|
+
my $end = $start;
|
|
29
|
+
for (1 .. $argc) { $end = index($buf, "\0", $end); $end >= 0 or die "truncated"; $end++; }
|
|
30
|
+
print substr($buf, $start, $end - $start);
|
|
31
|
+
`;
|
|
32
|
+
/** Process display strings are not a shell command and cannot recover word boundaries. */
|
|
33
|
+
export function processArguments(pid) {
|
|
34
|
+
if (!Number.isSafeInteger(pid) || pid < 1 || pid > 0x7fffffff)
|
|
35
|
+
return undefined;
|
|
36
|
+
try {
|
|
37
|
+
let bytes;
|
|
38
|
+
if (process.platform === 'linux')
|
|
39
|
+
bytes = readFileSync(`/proc/${pid}/cmdline`);
|
|
40
|
+
else if (process.platform === 'darwin') {
|
|
41
|
+
const result = spawnSync('/usr/bin/perl', ['-e', DARWIN_ARGV, String(pid)], {
|
|
42
|
+
timeout: 1000, killSignal: 'SIGKILL', maxBuffer: MAX_BYTES, encoding: 'buffer',
|
|
43
|
+
});
|
|
44
|
+
if (result.status !== 0 || result.error)
|
|
45
|
+
return undefined;
|
|
46
|
+
bytes = result.stdout;
|
|
47
|
+
}
|
|
48
|
+
else
|
|
49
|
+
return undefined;
|
|
50
|
+
if (!bytes.length || bytes.length > MAX_BYTES || bytes.at(-1) !== 0)
|
|
51
|
+
return undefined;
|
|
52
|
+
const words = new TextDecoder('utf-8', { fatal: true }).decode(bytes).slice(0, -1).split('\0');
|
|
53
|
+
return words[0] ? words : undefined;
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=process-arguments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-arguments.js","sourceRoot":"","sources":["../../src/process-arguments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,MAAM,SAAS,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AACnC,2DAA2D;AAC3D,gFAAgF;AAChF,mFAAmF;AACnF,2EAA2E;AAC3E,uEAAuE;AACvE,8EAA8E;AAC9E,8EAA8E;AAC9E,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;CAoB7B,CAAC;AAEF,0FAA0F;AAC1F,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,UAAU;QAAE,OAAO,SAAS,CAAC;IAChF,IAAI,CAAC;QACH,IAAI,KAAa,CAAC;QAClB,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;YAAE,KAAK,GAAG,YAAY,CAAC,SAAS,GAAG,UAAU,CAAC,CAAC;aAC1E,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACvC,MAAM,MAAM,GAAG,SAAS,CAAC,eAAe,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE;gBAC1E,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ;aAC/E,CAAC,CAAC;YACH,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK;gBAAE,OAAO,SAAS,CAAC;YAC1D,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;QACxB,CAAC;;YAAM,OAAO,SAAS,CAAC;QACxB,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,GAAG,SAAS,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QACtF,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC/F,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,SAAS,CAAC;IAAC,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { readlinkSync } from 'node:fs';
|
|
3
|
+
// Darwin proc_info(336), PROC_INFO_CALL_PIDINFO(2), PROC_PIDVNODEPATHINFO(9).
|
|
4
|
+
// proc_vnodepathinfo contains two vnode_info_path structures; each ends with
|
|
5
|
+
// vip_path[MAXPATHLEN=1024]. Derive the offset from the returned structure size.
|
|
6
|
+
const DARWIN_CWD = String.raw `
|
|
7
|
+
use strict;
|
|
8
|
+
use warnings;
|
|
9
|
+
my $pid = int(shift @ARGV);
|
|
10
|
+
my $buffer = "\0" x 16384;
|
|
11
|
+
my $size = syscall(336, 2, $pid, 9, 0, $buffer, 16384);
|
|
12
|
+
$size > 2048 && $size <= 16384 && $size % 2 == 0 or die "process directory unavailable";
|
|
13
|
+
my $path = substr($buffer, $size / 2 - 1024, 1024);
|
|
14
|
+
my $end = index($path, "\0");
|
|
15
|
+
$end > 0 or die "invalid directory";
|
|
16
|
+
print substr($path, 0, $end);
|
|
17
|
+
`;
|
|
18
|
+
/** Read directory identity, never a terminal-escaped rendering of its name. */
|
|
19
|
+
export function processDirectory(pid) {
|
|
20
|
+
if (!Number.isSafeInteger(pid) || pid < 1 || pid > 0x7fffffff)
|
|
21
|
+
return undefined;
|
|
22
|
+
try {
|
|
23
|
+
if (process.platform === 'linux')
|
|
24
|
+
return readlinkSync(`/proc/${pid}/cwd`);
|
|
25
|
+
if (process.platform !== 'darwin')
|
|
26
|
+
return undefined;
|
|
27
|
+
const result = spawnSync('/usr/bin/perl', ['-e', DARWIN_CWD, String(pid)], { timeout: 1000, killSignal: 'SIGKILL', maxBuffer: 16384 });
|
|
28
|
+
if (result.status !== 0 || result.error || !result.stdout.length)
|
|
29
|
+
return undefined;
|
|
30
|
+
const path = new TextDecoder('utf-8', { fatal: true }).decode(result.stdout);
|
|
31
|
+
return path.startsWith('/') ? path : undefined;
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=process-directory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-directory.js","sourceRoot":"","sources":["../../src/process-directory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,8EAA8E;AAC9E,6EAA6E;AAC7E,iFAAiF;AACjF,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;CAW5B,CAAC;AAEF,+EAA+E;AAC/E,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,UAAU;QAAE,OAAO,SAAS,CAAC;IAChF,IAAI,CAAC;QACH,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;YAAE,OAAO,YAAY,CAAC,SAAS,GAAG,MAAM,CAAC,CAAC;QAC1E,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAC;QACpD,MAAM,MAAM,GAAG,SAAS,CAAC,eAAe,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QACvI,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM;YAAE,OAAO,SAAS,CAAC;QACnF,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC7E,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,SAAS,CAAC;IAAC,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface ProcessLifetime {
|
|
2
|
+
key: string;
|
|
3
|
+
bornAt: number;
|
|
4
|
+
}
|
|
5
|
+
/** Process birth plus boot identity, not PID existence alone. */
|
|
6
|
+
export declare function processLifetime(pid: number): ProcessLifetime | undefined;
|
|
7
|
+
export declare function processOwnerAlive(pid: number, lifetime: string | undefined, recordedAt: number): boolean;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
let own;
|
|
4
|
+
let boot;
|
|
5
|
+
function bootIdentity() {
|
|
6
|
+
if (boot)
|
|
7
|
+
return boot;
|
|
8
|
+
if (process.platform === 'linux')
|
|
9
|
+
boot = readFileSync('/proc/sys/kernel/random/boot_id', 'utf8').trim();
|
|
10
|
+
else {
|
|
11
|
+
const result = spawnSync('sysctl', ['-n', 'kern.boottime'], { encoding: 'utf8', timeout: 1000, killSignal: 'SIGKILL' });
|
|
12
|
+
if (result.status !== 0)
|
|
13
|
+
throw new Error('Cannot verify machine boot identity.');
|
|
14
|
+
boot = result.stdout.trim();
|
|
15
|
+
}
|
|
16
|
+
return boot;
|
|
17
|
+
}
|
|
18
|
+
/** Process birth plus boot identity, not PID existence alone. */
|
|
19
|
+
export function processLifetime(pid) {
|
|
20
|
+
if (!Number.isSafeInteger(pid) || pid <= 0)
|
|
21
|
+
return undefined;
|
|
22
|
+
if (pid === process.pid && own)
|
|
23
|
+
return own;
|
|
24
|
+
const result = spawnSync('ps', ['-p', String(pid), '-o', 'lstart='], {
|
|
25
|
+
env: { ...process.env, LC_ALL: 'C' }, encoding: 'utf8', timeout: 1000, killSignal: 'SIGKILL',
|
|
26
|
+
});
|
|
27
|
+
if (result.status !== 0 || !result.stdout.trim()) {
|
|
28
|
+
try {
|
|
29
|
+
process.kill(pid, 0);
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
if (error.code === 'ESRCH')
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
throw new Error(`Cannot verify process lifetime for ${pid}.`);
|
|
36
|
+
}
|
|
37
|
+
const bornAt = Date.parse(result.stdout.trim());
|
|
38
|
+
if (!Number.isFinite(bornAt))
|
|
39
|
+
throw new Error(`Invalid process lifetime for ${pid}.`);
|
|
40
|
+
const lifetime = { key: `${bootIdentity()}:${pid}:${bornAt}`, bornAt };
|
|
41
|
+
if (pid === process.pid)
|
|
42
|
+
own = lifetime;
|
|
43
|
+
return lifetime;
|
|
44
|
+
}
|
|
45
|
+
export function processOwnerAlive(pid, lifetime, recordedAt) {
|
|
46
|
+
const current = processLifetime(pid);
|
|
47
|
+
if (!current)
|
|
48
|
+
return false;
|
|
49
|
+
return lifetime ? current.key === lifetime : current.bornAt <= recordedAt;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=process-owner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-owner.js","sourceRoot":"","sources":["../../src/process-owner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGvC,IAAI,GAAgC,CAAC;AACrC,IAAI,IAAwB,CAAC;AAC7B,SAAS,YAAY;IACnB,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IACtB,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,IAAI,GAAG,YAAY,CAAC,iCAAiC,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;SACnG,CAAC;QACJ,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,eAAe,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC;QACxH,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QACjF,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC9B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IAC7D,IAAI,GAAG,KAAK,OAAO,CAAC,GAAG,IAAI,GAAG;QAAE,OAAO,GAAG,CAAC;IAC3C,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,EAAE;QACnE,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS;KAC7F,CAAC,CAAC;IACH,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QACjD,IAAI,CAAC;YAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAAC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAC3C,IAAK,KAA+B,CAAC,IAAI,KAAK,OAAO;gBAAE,OAAO,SAAS,CAAC;QAC1E,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,sCAAsC,GAAG,GAAG,CAAC,CAAC;IAChE,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAChD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,GAAG,GAAG,CAAC,CAAC;IACtF,MAAM,QAAQ,GAAG,EAAE,GAAG,EAAE,GAAG,YAAY,EAAE,IAAI,GAAG,IAAI,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC;IACvE,IAAI,GAAG,KAAK,OAAO,CAAC,GAAG;QAAE,GAAG,GAAG,QAAQ,CAAC;IACxC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAW,EAAE,QAA4B,EAAE,UAAkB;IAC7F,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IACrC,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAC3B,OAAO,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,IAAI,UAAU,CAAC;AAC5E,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { accessSync, constants, realpathSync, statSync } from 'node:fs';
|
|
2
|
+
export function usableDirectory(path) {
|
|
3
|
+
try {
|
|
4
|
+
accessSync(path, constants.X_OK);
|
|
5
|
+
return statSync(path).isDirectory();
|
|
6
|
+
}
|
|
7
|
+
catch {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export function sameDirectory(left, right) {
|
|
12
|
+
try {
|
|
13
|
+
return realpathSync(left) === realpathSync(right);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=directory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directory.js","sourceRoot":"","sources":["../../../src/registry/directory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExE,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,IAAI,CAAC;QAAC,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;QAAC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IAAC,CAAC;IAC9E,MAAM,CAAC;QAAC,OAAO,KAAK,CAAC;IAAC,CAAC;AACzB,CAAC;AACD,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,KAAa;IACvD,IAAI,CAAC;QAAC,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,YAAY,CAAC,KAAK,CAAC,CAAC;IAAC,CAAC;IAC1D,MAAM,CAAC;QAAC,OAAO,KAAK,CAAC;IAAC,CAAC;AACzB,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Context } from '../context.js';
|
|
2
2
|
/**
|
|
3
|
-
* Discovery (spec §4.3):
|
|
4
|
-
* session from
|
|
3
|
+
* Discovery (spec §4.3): an unbound session or managed shell is recognised as
|
|
4
|
+
* an agent session from its active pane, so any launcher - or none -
|
|
5
5
|
* gets its sessions managed without knowing Berth.
|
|
6
6
|
*/
|
|
7
7
|
export interface Detected {
|
|
@@ -9,19 +9,30 @@ export interface Detected {
|
|
|
9
9
|
/** The agent's command line, starting with its binary. */
|
|
10
10
|
argv: string;
|
|
11
11
|
pid: number;
|
|
12
|
+
argvIssue?: string;
|
|
12
13
|
}
|
|
13
|
-
interface Proc {
|
|
14
|
+
export interface Proc {
|
|
14
15
|
pid: number;
|
|
15
16
|
ppid: number;
|
|
16
17
|
args: string;
|
|
18
|
+
native?: boolean;
|
|
17
19
|
}
|
|
20
|
+
export declare const ARGUMENTS_UNAVAILABLE = "Launch arguments could not be verified. Check process access (macOS also requires /usr/bin/perl) before restoring.";
|
|
21
|
+
export declare const BINDING_UNVERIFIED = "Recovery binding needs verification. No agent process identity was recorded; verified identity evidence must confirm the conversation.";
|
|
22
|
+
export declare const PRODUCER_CHANGED = "Agent producer changed. Verify the conversation before restoring.";
|
|
23
|
+
export declare function processes(): Proc[];
|
|
18
24
|
/**
|
|
19
25
|
* The agent among a process and its descendants: a program named like an
|
|
20
26
|
* agent binary, or a script so named run by an interpreter (`node <cli>`).
|
|
21
27
|
* Names are what matter: some agents run as a binary named after its version,
|
|
22
28
|
* so tmux's pane_current_command does not tell.
|
|
23
29
|
*/
|
|
30
|
+
export declare function agentsAmong(rootPid: number, procs: Proc[], depth?: number): Detected[];
|
|
24
31
|
export declare function agentAmong(rootPid: number, procs: Proc[]): Detected | undefined;
|
|
32
|
+
export declare function sessionProducers(ctx: Context, session: string, procs?: Proc[], allPanes?: string): (Detected & {
|
|
33
|
+
pane: string;
|
|
34
|
+
cwd: string;
|
|
35
|
+
})[];
|
|
25
36
|
/**
|
|
26
37
|
* A process's working directory. The pane's current path is not it: tmux
|
|
27
38
|
* reads the foreground process group's leader, which is a launcher's shell
|
|
@@ -31,8 +42,7 @@ export declare function cwdOf(pid: number): string | undefined;
|
|
|
31
42
|
/** The agent running in a session's active pane, if any. */
|
|
32
43
|
export declare function detectAgent(ctx: Context, session: string): Detected | undefined;
|
|
33
44
|
/**
|
|
34
|
-
* Stamp every unmanaged
|
|
45
|
+
* Stamp every unmanaged session or managed shell whose active pane runs an agent. Returns
|
|
35
46
|
* the sessions stamped; the caller snapshots. Never throws.
|
|
36
47
|
*/
|
|
37
48
|
export declare function discover(ctx: Context): string[];
|
|
38
|
-
export {};
|