@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.
- 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 +153 -21
- 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 +69 -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 +142 -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 +19 -0
- package/dist/src/registry/native-state.js +135 -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 +179 -38
- 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 +24 -0
- package/dist/src/tmux/connections.js +86 -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/README.md
CHANGED
|
@@ -13,5 +13,11 @@ berth tmux install # snapshot automatically as sessions change
|
|
|
13
13
|
berth ensure # after a reboot: rebuild and resume
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
Recovery requires a verified conversation ID and its profile. Installing hooks
|
|
17
|
+
cannot identify every conversation that was already running: the agent must
|
|
18
|
+
execute a supported event or expose verified native identity evidence. Codex's
|
|
19
|
+
shared-daemon TUI does not yet support passive binding. Berth preserves unknown
|
|
20
|
+
bindings rather than resuming the most recent conversation in a directory.
|
|
21
|
+
|
|
22
|
+
Requires Node ≥ 20 and tmux ≥ 3.0. macOS process discovery also uses system Perl. Behaviour is specified in the repository's
|
|
17
23
|
`design/spec.md`.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Adapter } from './registry.js';
|
|
2
|
+
export interface VersionObservation {
|
|
3
|
+
executable: string;
|
|
4
|
+
version?: string;
|
|
5
|
+
detail?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface CapabilityAssessment {
|
|
8
|
+
severity: 'info' | 'warning';
|
|
9
|
+
detail: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function assessCapability(agent: string, version: string): CapabilityAssessment;
|
|
12
|
+
/** Query only a standard adapter executable; never invoke a custom launcher. */
|
|
13
|
+
export declare function versionInspector(env: NodeJS.ProcessEnv): (adapter: Adapter, cwd?: string) => VersionObservation;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { executableOnPath } from '../tools.js';
|
|
3
|
+
/** Evidence refers to a tested release, not the current process or profile. */
|
|
4
|
+
const TESTED = {
|
|
5
|
+
claude: ['2.1.310'], codex: ['0.162.1', '0.166.0'], kimi: ['0.31.1'], opencode: ['1.19.5'], gemini: ['0.66.0'], copilot: ['1.0.105'],
|
|
6
|
+
};
|
|
7
|
+
export function assessCapability(agent, version) {
|
|
8
|
+
// Cursor's dated build format is distinct from its editor's semantic version.
|
|
9
|
+
// Source: https://cursor.com/changelog/cli-jan-16-2026 (checked 2026-11-01).
|
|
10
|
+
const dated = /^(20\d{2})\.(\d{2})\.(\d{2})(?:-[A-Za-z0-9.-]+)?$/.exec(version);
|
|
11
|
+
const date = dated && new Date(Date.UTC(Number(dated[1]), Number(dated[2]) - 1, Number(dated[3])));
|
|
12
|
+
const validDate = dated && date && date.getUTCFullYear() === Number(dated[1])
|
|
13
|
+
&& date.getUTCMonth() + 1 === Number(dated[2]) && date.getUTCDate() === Number(dated[3]);
|
|
14
|
+
if (agent === 'cursor' && validDate && dated.slice(1, 4).join('') < '20260116') {
|
|
15
|
+
return { severity: 'warning', detail: 'Predates the 2026-01-16 lifecycle hooks release. Update Cursor CLI, then verify a session binding and exact-ID recovery.' };
|
|
16
|
+
}
|
|
17
|
+
if (TESTED[agent]?.includes(version)) {
|
|
18
|
+
return { severity: 'info', detail: 'Berth tested this release on macOS with an isolated model fixture. Hook trust, binding and recovery in this profile still require their own acknowledgement.' };
|
|
19
|
+
}
|
|
20
|
+
return { severity: 'info', detail: 'This exact release has no Berth native acceptance record. Verify hook delivery and exact-ID recovery; hook files alone do not establish compatibility.' };
|
|
21
|
+
}
|
|
22
|
+
/** Query only a standard adapter executable; never invoke a custom launcher. */
|
|
23
|
+
export function versionInspector(env) {
|
|
24
|
+
const cache = new Map();
|
|
25
|
+
let probes = 0;
|
|
26
|
+
return (adapter, cwd = process.cwd()) => {
|
|
27
|
+
const executable = executableOnPath(adapter.binary, env, cwd);
|
|
28
|
+
if (!executable)
|
|
29
|
+
return { executable: adapter.binary, detail: 'executable unavailable' };
|
|
30
|
+
const prior = cache.get(executable);
|
|
31
|
+
if (prior)
|
|
32
|
+
return prior;
|
|
33
|
+
if (probes >= 8)
|
|
34
|
+
return { executable, detail: 'version query limit reached; inspect this executable separately' };
|
|
35
|
+
probes++;
|
|
36
|
+
let observation;
|
|
37
|
+
try {
|
|
38
|
+
const result = spawnSync(executable, ['--version'], { env, cwd, encoding: 'utf8',
|
|
39
|
+
stdio: ['ignore', 'pipe', 'pipe'], timeout: 1000, killSignal: 'SIGKILL', maxBuffer: 16 * 1024 });
|
|
40
|
+
const output = result.status === 0 && !result.error ? result.stdout.trim() : '';
|
|
41
|
+
const matches = [...output.matchAll(/(?:^|\s)v?(\d+\.\d+\.\d+(?:-[A-Za-z0-9.-]+)?)(?=$|\s|\()/g)].map((match) => match[1]);
|
|
42
|
+
const version = new Set(matches).size === 1 ? matches[0] : undefined;
|
|
43
|
+
observation = { executable, ...(version ? { version } : { detail: result.error ? 'version query failed or timed out' : 'version output unavailable or unrecognized' }) };
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
observation = { executable, detail: 'version query could not run' };
|
|
47
|
+
}
|
|
48
|
+
cache.set(executable, observation);
|
|
49
|
+
return observation;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../../src/agents/capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAM/C,+EAA+E;AAC/E,MAAM,MAAM,GAAgD;IAC1D,MAAM,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC,SAAS,CAAC;CACrI,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAAC,KAAa,EAAE,OAAe;IAC7D,8EAA8E;IAC9E,6EAA6E;IAC7E,MAAM,KAAK,GAAG,mDAAmD,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAChF,MAAM,IAAI,GAAG,KAAK,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnG,MAAM,SAAS,GAAG,KAAK,IAAI,IAAI,IAAI,IAAI,CAAC,cAAc,EAAE,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;WACxE,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3F,IAAI,KAAK,KAAK,QAAQ,IAAI,SAAS,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC;QAC/E,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,0HAA0H,EAAE,CAAC;IACrK,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,8JAA8J,EAAE,CAAC;IACtM,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,wJAAwJ,EAAE,CAAC;AAChM,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,gBAAgB,CAAC,GAAsB;IACrD,MAAM,KAAK,GAAG,IAAI,GAAG,EAA8B,CAAC;IACpD,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,OAAO,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE;QACtC,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QAC9D,IAAI,CAAC,UAAU;YAAE,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,wBAAwB,EAAE,CAAC;QACzF,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACpC,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;QACxB,IAAI,MAAM,IAAI,CAAC;YAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,iEAAiE,EAAE,CAAC;QAClH,MAAM,EAAE,CAAC;QACT,IAAI,WAA+B,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,SAAS,CAAC,UAAU,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM;gBAC9E,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;YACnG,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChF,MAAM,OAAO,GAAG,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,2DAA2D,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3H,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACrE,WAAW,GAAG,EAAE,UAAU,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,mCAAmC,CAAC,CAAC,CAAC,4CAA4C,EAAE,CAAC,EAAE,CAAC;QAC3K,CAAC;QAAC,MAAM,CAAC;YAAC,WAAW,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,6BAA6B,EAAE,CAAC;QAAC,CAAC;QAChF,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;QACnC,OAAO,WAAW,CAAC;IACrB,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface CodexBinding {
|
|
2
|
+
conversation: string;
|
|
3
|
+
root: string;
|
|
4
|
+
}
|
|
5
|
+
/** Only numeric descriptors open for writing; never a filename mentioned in output. */
|
|
6
|
+
export declare function writableFiles(output: string, pid: number): string[];
|
|
7
|
+
/** Read metadata only, never transcript text or the newest file in a directory. */
|
|
8
|
+
export declare function rolloutBinding(file: string, expectedInode?: number): CodexBinding | undefined;
|
|
9
|
+
/** The same writer must still own the same file and process after inspection. */
|
|
10
|
+
export declare function codexProcessBinding(pid: number, lifetime: string): CodexBinding | undefined;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { closeSync, fstatSync, openSync, readSync, realpathSync } from 'node:fs';
|
|
3
|
+
import { dirname, basename, sep } from 'node:path';
|
|
4
|
+
import { processLifetime } from '../process-owner.js';
|
|
5
|
+
const UUID = '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}';
|
|
6
|
+
const ROLLOUT = new RegExp(`^rollout-.+-(${UUID})\\.jsonl$`, 'i');
|
|
7
|
+
const HEADER_LIMIT = 1024 * 1024;
|
|
8
|
+
const failures = new Map();
|
|
9
|
+
/** Only numeric descriptors open for writing; never a filename mentioned in output. */
|
|
10
|
+
export function writableFiles(output, pid) {
|
|
11
|
+
let owner = false, descriptor = false, writable = false;
|
|
12
|
+
const files = [];
|
|
13
|
+
for (const field of output.split('\n')) {
|
|
14
|
+
if (field.startsWith('p')) {
|
|
15
|
+
owner = field === `p${pid}`;
|
|
16
|
+
descriptor = false;
|
|
17
|
+
writable = false;
|
|
18
|
+
}
|
|
19
|
+
else if (field.startsWith('f')) {
|
|
20
|
+
descriptor = /^f\d+$/.test(field);
|
|
21
|
+
writable = false;
|
|
22
|
+
}
|
|
23
|
+
else if (field.startsWith('a'))
|
|
24
|
+
writable = field === 'aw' || field === 'au';
|
|
25
|
+
else if (owner && descriptor && writable && field.startsWith('n/'))
|
|
26
|
+
files.push(field.slice(1));
|
|
27
|
+
}
|
|
28
|
+
return [...new Set(files)];
|
|
29
|
+
}
|
|
30
|
+
/** Read metadata only, never transcript text or the newest file in a directory. */
|
|
31
|
+
export function rolloutBinding(file, expectedInode) {
|
|
32
|
+
let fd;
|
|
33
|
+
try {
|
|
34
|
+
const canonical = realpathSync(file);
|
|
35
|
+
const match = ROLLOUT.exec(basename(canonical));
|
|
36
|
+
if (!match)
|
|
37
|
+
return undefined;
|
|
38
|
+
const parts = canonical.split(sep);
|
|
39
|
+
const index = parts.length - 5;
|
|
40
|
+
if (parts[index] !== 'sessions' || !/^\d{4}$/.test(parts[index + 1]) || !/^\d{2}$/.test(parts[index + 2]) || !/^\d{2}$/.test(parts[index + 3]))
|
|
41
|
+
return undefined;
|
|
42
|
+
fd = openSync(canonical, 'r');
|
|
43
|
+
const stat = fstatSync(fd);
|
|
44
|
+
if (!stat.isFile() || (expectedInode !== undefined && stat.ino !== expectedInode))
|
|
45
|
+
return undefined;
|
|
46
|
+
const bytes = Buffer.alloc(HEADER_LIMIT);
|
|
47
|
+
const count = readSync(fd, bytes, 0, bytes.length, 0);
|
|
48
|
+
const end = bytes.subarray(0, count).indexOf(10);
|
|
49
|
+
if (end < 0)
|
|
50
|
+
return undefined;
|
|
51
|
+
const record = JSON.parse(bytes.subarray(0, end).toString('utf8'));
|
|
52
|
+
const meta = record?.payload;
|
|
53
|
+
if (record?.type !== 'session_meta' || meta?.source !== 'cli' || meta.parent_thread_id || meta.agent_role || meta.agent_path)
|
|
54
|
+
return undefined;
|
|
55
|
+
if (typeof meta.id !== 'string' || meta.id.toLowerCase() !== match[1].toLowerCase())
|
|
56
|
+
return undefined;
|
|
57
|
+
return { conversation: meta.id, root: dirname(dirname(dirname(dirname(dirname(canonical))))) };
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
if (fd !== undefined)
|
|
64
|
+
closeSync(fd);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/** The same writer must still own the same file and process after inspection. */
|
|
68
|
+
export function codexProcessBinding(pid, lifetime) {
|
|
69
|
+
const key = `${pid}:${lifetime}`, now = Date.now();
|
|
70
|
+
if ((failures.get(key) ?? 0) > now)
|
|
71
|
+
return undefined;
|
|
72
|
+
for (const [entry, until] of failures)
|
|
73
|
+
if (until <= now)
|
|
74
|
+
failures.delete(entry);
|
|
75
|
+
const readFiles = () => {
|
|
76
|
+
const result = spawnSync('lsof', ['-n', '-P', '-a', '-p', String(pid), '-F', 'pfain'], {
|
|
77
|
+
encoding: 'utf8', timeout: 750, killSignal: 'SIGKILL', maxBuffer: 256 * 1024,
|
|
78
|
+
});
|
|
79
|
+
if (result.status !== 0 || result.error)
|
|
80
|
+
return [];
|
|
81
|
+
const files = new Set(writableFiles(result.stdout, pid));
|
|
82
|
+
return result.stdout.split(/(?=^f)/m).flatMap(block => {
|
|
83
|
+
const file = /^n(.+)$/m.exec(block)?.[1];
|
|
84
|
+
const inode = Number(/^i(\d+)$/m.exec(block)?.[1]);
|
|
85
|
+
return file && files.has(file) && ROLLOUT.test(basename(file)) && Number.isSafeInteger(inode) && inode > 0 ? [{ file, inode }] : [];
|
|
86
|
+
});
|
|
87
|
+
};
|
|
88
|
+
try {
|
|
89
|
+
if (processLifetime(pid)?.key !== lifetime)
|
|
90
|
+
return undefined;
|
|
91
|
+
const files = readFiles();
|
|
92
|
+
// Multiple writer files may represent concurrent threads, even when only one parses.
|
|
93
|
+
if (files.length === 1) {
|
|
94
|
+
const binding = rolloutBinding(files[0].file, files[0].inode);
|
|
95
|
+
if (binding && JSON.stringify(readFiles()) === JSON.stringify(files) && processLifetime(pid)?.key === lifetime)
|
|
96
|
+
return binding;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
catch { /* Optional native evidence must not interrupt discovery. */ }
|
|
100
|
+
if (failures.size >= 256)
|
|
101
|
+
failures.clear();
|
|
102
|
+
failures.set(key, now + 30_000);
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=codex-binding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-binding.js","sourceRoot":"","sources":["../../../src/agents/codex-binding.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,8 +3,8 @@ import { type Adapter } from './registry.js';
|
|
|
3
3
|
export declare function requireAdapter(id: string): Adapter;
|
|
4
4
|
/**
|
|
5
5
|
* Options from an original launch command that are kept on resume
|
|
6
|
-
* (implementation §3.2).
|
|
7
|
-
*
|
|
6
|
+
* (implementation §3.2). Parse known option arity before selecting the keep-set. Unknown syntax
|
|
7
|
+
* requires explicit review instead of interpreting its values as options.
|
|
8
8
|
*/
|
|
9
9
|
export declare function keptArgs(adapter: Adapter, argv: string): string[];
|
|
10
10
|
export interface CommandInput {
|
|
@@ -21,3 +21,5 @@ export declare function resumeCommand(input: CommandInput & {
|
|
|
21
21
|
conversation: string;
|
|
22
22
|
originalArgv: string;
|
|
23
23
|
}): string | undefined;
|
|
24
|
+
/** Unverified provenance or unsupported syntax requires explicit review. */
|
|
25
|
+
export declare function recoveryOptionsRequired(agent: string, argv: string, verified?: boolean): boolean;
|
|
@@ -9,23 +9,44 @@ export function requireAdapter(id) {
|
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
11
|
* Options from an original launch command that are kept on resume
|
|
12
|
-
* (implementation §3.2).
|
|
13
|
-
*
|
|
12
|
+
* (implementation §3.2). Parse known option arity before selecting the keep-set. Unknown syntax
|
|
13
|
+
* requires explicit review instead of interpreting its values as options.
|
|
14
14
|
*/
|
|
15
15
|
export function keptArgs(adapter, argv) {
|
|
16
16
|
const words = argv ? shellSplit(argv).slice(1) : [];
|
|
17
17
|
const kept = [];
|
|
18
18
|
for (let i = 0; i < words.length; i++) {
|
|
19
19
|
const word = words[i];
|
|
20
|
-
if (
|
|
20
|
+
if (word === '--')
|
|
21
|
+
break;
|
|
22
|
+
if (!word.startsWith('-') || word === '-')
|
|
21
23
|
continue;
|
|
22
24
|
const [flag] = word.split('=', 1);
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
const retain = Object.hasOwn(adapter.keep, flag);
|
|
26
|
+
const arity = retain ? adapter.keep[flag] : adapter.discard?.[flag];
|
|
27
|
+
if (arity === undefined)
|
|
28
|
+
throw new BerthError(`Review recovery options: unsupported option ${flag}.`);
|
|
29
|
+
const values = [];
|
|
30
|
+
if (word.includes('=')) {
|
|
31
|
+
if (arity === false)
|
|
32
|
+
throw new BerthError(`Unexpected value for ${flag}.`);
|
|
33
|
+
}
|
|
34
|
+
else if (arity === true) {
|
|
35
|
+
if (i + 1 >= words.length || words[i + 1] === '--')
|
|
36
|
+
throw new BerthError(`Missing value for ${flag}.`);
|
|
37
|
+
values.push(words[++i]);
|
|
38
|
+
}
|
|
39
|
+
else if (arity === 'optional' && i + 1 < words.length && !words[i + 1].startsWith('-')) {
|
|
40
|
+
values.push(words[++i]);
|
|
41
|
+
}
|
|
42
|
+
if (arity === 'many') {
|
|
43
|
+
while (i + 1 < words.length && !words[i + 1].startsWith('-'))
|
|
44
|
+
values.push(words[++i]);
|
|
45
|
+
if (!word.includes('=') && values.length === 0)
|
|
46
|
+
throw new BerthError(`Missing value for ${flag}.`);
|
|
47
|
+
}
|
|
48
|
+
if (retain)
|
|
49
|
+
kept.push(word, ...values);
|
|
29
50
|
}
|
|
30
51
|
return kept;
|
|
31
52
|
}
|
|
@@ -45,4 +66,15 @@ export function resumeCommand(input) {
|
|
|
45
66
|
const args = keptArgs(input.adapter, input.originalArgv).map(shellQuote).join(' ');
|
|
46
67
|
return renderTemplate(tpl, { name: input.name, cwd: input.cwd, conversation: input.conversation, args });
|
|
47
68
|
}
|
|
69
|
+
/** Unverified provenance or unsupported syntax requires explicit review. */
|
|
70
|
+
export function recoveryOptionsRequired(agent, argv, verified) {
|
|
71
|
+
if (agent === 'shell')
|
|
72
|
+
return false;
|
|
73
|
+
try {
|
|
74
|
+
return keptArgs(requireAdapter(agent), argv).length > 0 && verified !== true;
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
48
80
|
//# sourceMappingURL=commands.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../../src/agents/commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,UAAU,EAAgB,MAAM,eAAe,CAAC;AAEzD,MAAM,UAAU,cAAc,CAAC,EAAU;IACvC,MAAM,OAAO,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC;IAC/B,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,UAAU,CAAC,kBAAkB,EAAE,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC3E,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAgB,EAAE,IAAY;IACrD,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACpD,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../../src/agents/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare function copilotCursor(conversation: string, env: NodeJS.ProcessEnv): string;
|
|
2
|
+
/** Retry hooks are not terminal: require the native root turn-end and outcome. */
|
|
3
|
+
export declare function copilotState(value: string | undefined, conversation: string, env: NodeJS.ProcessEnv): '' | 'working' | undefined;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { agentRoot } from './roots.js';
|
|
3
|
+
import { transcriptCursor, transcriptTail } from './transcript-cursor.js';
|
|
4
|
+
function headerMatches(header, conversation) {
|
|
5
|
+
const data = header.data;
|
|
6
|
+
return header.type === 'session.start' && !!data && typeof data === 'object'
|
|
7
|
+
&& 'sessionId' in data && data.sessionId === conversation;
|
|
8
|
+
}
|
|
9
|
+
export function copilotCursor(conversation, env) {
|
|
10
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(conversation))
|
|
11
|
+
return '';
|
|
12
|
+
const root = agentRoot('copilot', env);
|
|
13
|
+
return transcriptCursor(join(root, 'session-state', conversation, 'events.jsonl'), root, (header) => headerMatches(header, conversation));
|
|
14
|
+
}
|
|
15
|
+
/** Retry hooks are not terminal: require the native root turn-end and outcome. */
|
|
16
|
+
export function copilotState(value, conversation, env) {
|
|
17
|
+
try {
|
|
18
|
+
const tail = transcriptTail(value, agentRoot('copilot', env), (header) => headerMatches(header, conversation));
|
|
19
|
+
if (!tail)
|
|
20
|
+
return undefined;
|
|
21
|
+
let turnId;
|
|
22
|
+
let ended = false;
|
|
23
|
+
let inactive = false;
|
|
24
|
+
let pending = {};
|
|
25
|
+
let completed = false;
|
|
26
|
+
let resumed = false;
|
|
27
|
+
for (const line of tail.lines) {
|
|
28
|
+
const row = JSON.parse(line);
|
|
29
|
+
const data = row?.data;
|
|
30
|
+
if (!row || typeof row.type !== 'string' || !data || typeof data !== 'object' || Array.isArray(data))
|
|
31
|
+
return undefined;
|
|
32
|
+
if (['assistant.turn_end', 'session.error', 'abort'].includes(row.type)
|
|
33
|
+
&& (data.agentId || data.parentAgentId || data.parentToolCallId || data.parentAgentTaskId))
|
|
34
|
+
return undefined;
|
|
35
|
+
if (['hook.start', 'hook.end', 'session.usage_record'].includes(row.type))
|
|
36
|
+
continue;
|
|
37
|
+
const timestamp = typeof row.timestamp === 'string' ? Date.parse(row.timestamp) : NaN;
|
|
38
|
+
if (!Number.isFinite(timestamp) || timestamp < tail.at || timestamp > Date.now())
|
|
39
|
+
return undefined;
|
|
40
|
+
if (row.type === 'permission.requested') {
|
|
41
|
+
const id = data.requestId;
|
|
42
|
+
const tool = data.permissionRequest?.toolCallId;
|
|
43
|
+
if (typeof id !== 'string' || !id || typeof tool !== 'string' || !tool
|
|
44
|
+
|| data.ownerSessionId !== conversation || Object.hasOwn(pending, id))
|
|
45
|
+
return undefined;
|
|
46
|
+
pending = { ...pending, [id]: tool };
|
|
47
|
+
resumed = false;
|
|
48
|
+
}
|
|
49
|
+
else if (row.type === 'permission.completed') {
|
|
50
|
+
const id = data.requestId;
|
|
51
|
+
if (typeof id !== 'string' || !Object.hasOwn(pending, id) || pending[id] !== data.toolCallId
|
|
52
|
+
|| !data.result || typeof data.result.kind !== 'string')
|
|
53
|
+
return undefined;
|
|
54
|
+
const { [id]: settled, ...remaining } = pending;
|
|
55
|
+
pending = remaining;
|
|
56
|
+
completed = true;
|
|
57
|
+
}
|
|
58
|
+
if (row.type === 'assistant.turn_end') {
|
|
59
|
+
ended = typeof data.turnId === 'string' && data.turnId.length > 0
|
|
60
|
+
&& (turnId === undefined || data.turnId === turnId);
|
|
61
|
+
inactive = false;
|
|
62
|
+
resumed = false;
|
|
63
|
+
}
|
|
64
|
+
else if (row.type === 'session.error') {
|
|
65
|
+
inactive = ended && typeof data.errorType === 'string' && typeof data.message === 'string' && data.message.trim().length > 0;
|
|
66
|
+
}
|
|
67
|
+
else if (row.type === 'abort') {
|
|
68
|
+
inactive = ended && data.reason === 'user_initiated';
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
if (!['assistant.message', 'tool.execution_start', 'tool.execution_complete', 'system.message',
|
|
72
|
+
'permission.requested', 'permission.completed', 'assistant.turn_start'].includes(row.type))
|
|
73
|
+
resumed = false;
|
|
74
|
+
if (row.type === 'user.message') {
|
|
75
|
+
turnId = undefined;
|
|
76
|
+
completed = false;
|
|
77
|
+
resumed = false;
|
|
78
|
+
pending = {};
|
|
79
|
+
}
|
|
80
|
+
if (row.type === 'assistant.turn_start') {
|
|
81
|
+
turnId = typeof data.turnId === 'string' ? data.turnId : undefined;
|
|
82
|
+
resumed = !!turnId && completed && Object.keys(pending).length === 0;
|
|
83
|
+
}
|
|
84
|
+
ended = false;
|
|
85
|
+
inactive = false;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return inactive ? '' : resumed && Object.keys(pending).length === 0 ? 'working' : undefined;
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=copilot-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-state.js","sourceRoot":"","sources":["../../../src/agents/copilot-state.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare function geminiCursor(file: unknown, conversation: string, env: NodeJS.ProcessEnv): string;
|
|
2
|
+
/** Native cancellation is terminal; an error additionally needs a completed-loop acknowledgement. */
|
|
3
|
+
export declare function geminiInactive(value: string | undefined, conversation: string, env: NodeJS.ProcessEnv, completed?: boolean): boolean;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { agentRoot } from './roots.js';
|
|
2
|
+
import { transcriptCursor, transcriptTail } from './transcript-cursor.js';
|
|
3
|
+
export function geminiCursor(file, conversation, env) {
|
|
4
|
+
return transcriptCursor(file, agentRoot('gemini', env), (header) => header.sessionId === conversation);
|
|
5
|
+
}
|
|
6
|
+
/** Native cancellation is terminal; an error additionally needs a completed-loop acknowledgement. */
|
|
7
|
+
export function geminiInactive(value, conversation, env, completed = false) {
|
|
8
|
+
try {
|
|
9
|
+
const tail = transcriptTail(value, agentRoot('gemini', env), (header) => header.sessionId === conversation);
|
|
10
|
+
if (!tail)
|
|
11
|
+
return false;
|
|
12
|
+
let last;
|
|
13
|
+
for (const line of tail.lines) {
|
|
14
|
+
const data = JSON.parse(line);
|
|
15
|
+
if (!data || typeof data !== 'object' || Array.isArray(data))
|
|
16
|
+
return false;
|
|
17
|
+
const row = data;
|
|
18
|
+
if (typeof row.type === 'string')
|
|
19
|
+
last = row;
|
|
20
|
+
else if (typeof row.$rewindTo === 'string' && row.$rewindTo.length > 0)
|
|
21
|
+
continue;
|
|
22
|
+
else if (!row.$set || typeof row.$set !== 'object' || Array.isArray(row.$set))
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
const timestamp = typeof last?.timestamp === 'string' ? Date.parse(last.timestamp) : NaN;
|
|
26
|
+
if (!last || typeof last.id !== 'string' || !Number.isFinite(timestamp)
|
|
27
|
+
|| timestamp < tail.at || timestamp > Date.now())
|
|
28
|
+
return false;
|
|
29
|
+
const content = typeof last.content === 'string' ? last.content : '';
|
|
30
|
+
if (last.type === 'info' && ['Request cancelled.', 'User cancelled the request.'].includes(content))
|
|
31
|
+
return true;
|
|
32
|
+
return completed && ((last.type === 'error' && content.trim().length > 0) || (last.type === 'info' && [
|
|
33
|
+
'This request failed. Press F12 for diagnostics, or run /settings and change "Error Verbosity" to full for full details.',
|
|
34
|
+
'Some internal tool attempts failed before this final error. Press F12 for diagnostics, or run /settings and change "Error Verbosity" to full for details.',
|
|
35
|
+
].includes(content)));
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=gemini-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-state.js","sourceRoot":"","sources":["../../../src/agents/gemini-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE1E,MAAM,UAAU,YAAY,CAAC,IAAa,EAAE,YAAoB,EAAE,GAAsB;IACtF,OAAO,gBAAgB,CAAC,IAAI,EAAE,SAAS,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,KAAK,YAAY,CAAC,CAAC;AACzG,CAAC;AAED,qGAAqG;AACrG,MAAM,UAAU,cAAc,CAAC,KAAyB,EAAE,YAAoB,EAAE,GAAsB,EAAE,SAAS,GAAG,KAAK;IACvH,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,EAAE,SAAS,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,KAAK,YAAY,CAAC,CAAC;QAC5G,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QACxB,IAAI,IAAyC,CAAC;QAC9C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACvC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;gBAAE,OAAO,KAAK,CAAC;YAC3E,MAAM,GAAG,GAAG,IAA+B,CAAC;YAC5C,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ;gBAAE,IAAI,GAAG,GAAG,CAAC;iBACxC,IAAI,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ,IAAI,GAAG,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAS;iBAC5E,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,OAAO,KAAK,CAAC;QAC9F,CAAC;QACD,MAAM,SAAS,GAAG,OAAO,IAAI,EAAE,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QACzF,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC;eAClE,SAAS,GAAG,IAAI,CAAC,EAAE,IAAI,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE;YAAE,OAAO,KAAK,CAAC;QACjE,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACrE,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,oBAAoB,EAAE,6BAA6B,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC;QACjH,OAAO,SAAS,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI;YACpG,yHAAyH;YACzH,2JAA2J;SAC5J,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,KAAK,CAAC;IAAC,CAAC;AAC3B,CAAC"}
|
|
@@ -14,8 +14,6 @@ interface HookFormat {
|
|
|
14
14
|
uninstall(file: string): void;
|
|
15
15
|
}
|
|
16
16
|
/** OpenCode loads every module in its plugins folder; this one forwards session events to `berth hook`. */
|
|
17
|
-
export declare function opencodePlugin(node: string, cli: string, events: string[]): string;
|
|
17
|
+
export declare function opencodePlugin(node: string, cli: string, events: string[], electron?: boolean): string;
|
|
18
18
|
export declare function hookFormat(target: HookTarget, cli?: string): HookFormat;
|
|
19
|
-
/** Whether the target file holds Berth's entries. */
|
|
20
|
-
export declare function containsBerth(file: string): boolean;
|
|
21
19
|
export {};
|