@solongate/proxy 0.83.55 → 0.83.57
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/dist/api-client/audit.d.ts +0 -13
- package/dist/commands/index.js +154 -79
- package/dist/global-install.d.ts +28 -0
- package/dist/global-install.js +344 -129
- package/dist/hook-health.d.ts +26 -0
- package/dist/hook-launcher.d.ts +57 -0
- package/dist/index.js +507 -329
- package/dist/tui/index.js +418 -244
- package/dist/tui/local-log.d.ts +0 -2
- package/hooks/opencode-plugin.mjs +21 -1
- package/package.json +7 -7
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface HookStart {
|
|
2
|
+
ok: boolean;
|
|
3
|
+
/** The node the launcher resolved, when it resolved one. */
|
|
4
|
+
node?: string;
|
|
5
|
+
detail: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Run the launcher's own resolution and report what it found.
|
|
9
|
+
*
|
|
10
|
+
* It runs the INSTALLED launcher rather than reimplementing its search here.
|
|
11
|
+
* A second copy of the candidate list would drift from the first, and the drift
|
|
12
|
+
* would be invisible: the check would pass while the thing it stands for
|
|
13
|
+
* failed.
|
|
14
|
+
*/
|
|
15
|
+
export declare function hookCanStart(): HookStart;
|
|
16
|
+
export interface HookBeat {
|
|
17
|
+
hook: string;
|
|
18
|
+
at: Date;
|
|
19
|
+
/** What the launcher resolved that time, or `no-node` when it resolved nothing. */
|
|
20
|
+
node: string;
|
|
21
|
+
}
|
|
22
|
+
/** Every hook that has ever been invoked on this machine, newest first. */
|
|
23
|
+
export declare function hookBeats(): HookBeat[];
|
|
24
|
+
/** The guard's own beat, which is the one that means enforcement happened. */
|
|
25
|
+
export declare function guardBeat(): HookBeat | null;
|
|
26
|
+
export declare function agoLabel(d: Date): string;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The launcher that stands between an agent client and a hook script.
|
|
3
|
+
*
|
|
4
|
+
* WHY THIS EXISTS
|
|
5
|
+
*
|
|
6
|
+
* A hook is registered as a command string in somebody else's config file, and
|
|
7
|
+
* that string used to name a node binary by absolute path — `process.execPath`
|
|
8
|
+
* at install time. The absolute path was deliberate and is still right: Claude
|
|
9
|
+
* Code runs hooks in a non-interactive environment whose PATH frequently has no
|
|
10
|
+
* `node` on it, and bare `node` there fails with "command not found" while the
|
|
11
|
+
* client reports nothing at all.
|
|
12
|
+
*
|
|
13
|
+
* What was wrong is that `process.execPath` RESOLVES SYMLINKS. On the machines
|
|
14
|
+
* where this bit, that is the whole story:
|
|
15
|
+
*
|
|
16
|
+
* Homebrew /opt/homebrew/bin/node is a symlink into
|
|
17
|
+
* /opt/homebrew/Cellar/node/<version>/bin/node, so execPath records
|
|
18
|
+
* the VERSIONED path — and `brew upgrade` moves it and `brew
|
|
19
|
+
* cleanup` deletes it. The stable symlink was right there and we
|
|
20
|
+
* wrote down the thing it pointed at.
|
|
21
|
+
* nvm/fnm ~/.nvm/versions/node/v22.11.0/bin/node, and the version directory
|
|
22
|
+
* /volta goes away the moment that version is uninstalled or pruned.
|
|
23
|
+
*
|
|
24
|
+
* Linux distro node is /usr/bin/node and Windows node is under Program Files;
|
|
25
|
+
* neither moves. macOS is where node is nearly always under a version manager,
|
|
26
|
+
* which is why "it works everywhere except on the Mac" is the shape this took.
|
|
27
|
+
*
|
|
28
|
+
* When the recorded path is gone, the client spawns a command that cannot start.
|
|
29
|
+
* Nothing enforces, nothing is logged, and every status this CLI printed still
|
|
30
|
+
* said "guard registered" — because it was registered. It just could not run.
|
|
31
|
+
*
|
|
32
|
+
* WHAT THIS DOES
|
|
33
|
+
*
|
|
34
|
+
* Resolve node at RUN time, from a list that starts with the recorded path and
|
|
35
|
+
* falls through every place a Mac actually keeps one. Then exec the hook, so no
|
|
36
|
+
* extra process is left behind.
|
|
37
|
+
*
|
|
38
|
+
* And leave a mark. The launcher touches a beat file before it does anything
|
|
39
|
+
* else, which is the one fact nothing else in this product could establish: that
|
|
40
|
+
* the client invoked the hook at all. "Registered but never fired" and "fired
|
|
41
|
+
* but enforcing nothing" are different faults with different fixes and they
|
|
42
|
+
* looked identical from the outside.
|
|
43
|
+
*/
|
|
44
|
+
/** Where the launcher lives, relative to the hooks directory. */
|
|
45
|
+
export declare const LAUNCHER_NAME = "sg-run.sh";
|
|
46
|
+
/** Where the beat files live, relative to ~/.solongate. */
|
|
47
|
+
export declare const BEAT_DIR = ".beat";
|
|
48
|
+
/**
|
|
49
|
+
* The launcher, with the install-time node baked in.
|
|
50
|
+
*
|
|
51
|
+
* POSIX sh, because /bin/sh is the one interpreter every macOS and Linux has at
|
|
52
|
+
* a fixed path. It runs before every single tool call, so it forks nothing on
|
|
53
|
+
* the happy path: the candidate tests are builtins, the beat file is written by
|
|
54
|
+
* a redirect whose MTIME is the timestamp, and the hook is `exec`d rather than
|
|
55
|
+
* spawned.
|
|
56
|
+
*/
|
|
57
|
+
export declare function launcherScript(pinnedNode: string): string;
|