@cotal-ai/connector-hermes 0.8.1 → 0.8.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/dist/extension.d.ts.map +1 -1
- package/dist/extension.js +5 -0
- package/dist/extension.js.map +1 -1
- package/dist/launch.js +6 -4
- package/dist/launch.js.map +1 -1
- package/dist/sidecar.d.ts.map +1 -1
- package/dist/sidecar.js +3 -1
- package/dist/sidecar.js.map +1 -1
- package/package.json +3 -3
- package/plugin/cotal/__init__.py +5 -0
- package/plugin/cotal/_sidecar/standalone.cjs +64 -10
- package/plugin/cotal/hooks.py +8 -5
package/dist/extension.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"AACA,OAAO,EAA2B,KAAK,SAAS,EAAoC,MAAM,gBAAgB,CAAC;AAW3G;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"AACA,OAAO,EAA2B,KAAK,SAAS,EAAoC,MAAM,gBAAgB,CAAC;AAW3G;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,EAAE,SAkC7B,CAAC"}
|
package/dist/extension.js
CHANGED
|
@@ -23,6 +23,11 @@ export const hermesConnector = {
|
|
|
23
23
|
name: "hermes",
|
|
24
24
|
requires: ["hermes"],
|
|
25
25
|
buildLaunch(opts) {
|
|
26
|
+
// Hermes is Unix-only: its sidecar bridge + hook relay use AF_UNIX `.sock` paths and a Python
|
|
27
|
+
// sidecar, none of which are ported to Windows. Fail loud rather than launch a half-wired agent
|
|
28
|
+
// the manager can't drive (no Windows named-pipe bridge, no cooperative shutdown). No fallback.
|
|
29
|
+
if (process.platform === "win32")
|
|
30
|
+
throw new Error("the Hermes connector is Unix-only (AF_UNIX bridge + Python sidecar) — not supported on Windows");
|
|
26
31
|
// OS allow-list + the named model-provider key (Hermes is model-agnostic; any one unlocks a
|
|
27
32
|
// provider), forwarded BY NAME — never `...process.env` — so the operator's unrelated secrets
|
|
28
33
|
// don't reach the gateway child (P3).
|
package/dist/extension.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension.js","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAoD,MAAM,gBAAgB,CAAC;AAC3G,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAElF;;;2DAG2D;AAC3D,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACnE,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,0BAA0B,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAChF,MAAM,YAAY,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,YAAY,SAAS,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAEtF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,eAAe,GAAc;IACxC,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,CAAC,QAAQ,CAAC;IACpB,WAAW,CAAC,IAAgB;QAC1B,4FAA4F;QAC5F,8FAA8F;QAC9F,sCAAsC;QACtC,MAAM,GAAG,GAA2B;YAClC,GAAG,SAAS,CAAC,EAAE,YAAY,EAAE,mBAAmB,EAAE,CAAC;YACnD,GAAG,MAAM,CAAC,IAAI,CAAC;YACf,WAAW,EAAE,IAAI,CAAC,KAAK;YACvB,UAAU,EAAE,IAAI,CAAC,IAAI;SACtB,CAAC;QACF,IAAI,IAAI,CAAC,IAAI;YAAE,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC;QAC1C,IAAI,IAAI,CAAC,EAAE;YAAE,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC;QACpC,IAAI,IAAI,CAAC,KAAK;YAAE,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC;QAC7C,IAAI,IAAI,CAAC,OAAO;YAAE,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC;QACnD,wFAAwF;QACxF,mFAAmF;QACnF,IAAI,IAAI,CAAC,UAAU;YAAE,GAAG,CAAC,gBAAgB,GAAG,IAAI,CAAC,UAAU,CAAC;QAC5D,gGAAgG;QAChG,8FAA8F;QAC9F,2FAA2F;QAC3F,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QACrF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;QAClE,IAAI,KAAK;YAAE,GAAG,CAAC,YAAY,GAAG,KAAK,CAAC;QACpC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC;IACrD,CAAC;CACF,CAAC;AAEF,QAAQ,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"extension.js","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAoD,MAAM,gBAAgB,CAAC;AAC3G,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAElF;;;2DAG2D;AAC3D,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AACnE,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,0BAA0B,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAChF,MAAM,YAAY,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,YAAY,SAAS,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAEtF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,eAAe,GAAc;IACxC,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,CAAC,QAAQ,CAAC;IACpB,WAAW,CAAC,IAAgB;QAC1B,8FAA8F;QAC9F,gGAAgG;QAChG,gGAAgG;QAChG,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;YAC9B,MAAM,IAAI,KAAK,CAAC,gGAAgG,CAAC,CAAC;QACpH,4FAA4F;QAC5F,8FAA8F;QAC9F,sCAAsC;QACtC,MAAM,GAAG,GAA2B;YAClC,GAAG,SAAS,CAAC,EAAE,YAAY,EAAE,mBAAmB,EAAE,CAAC;YACnD,GAAG,MAAM,CAAC,IAAI,CAAC;YACf,WAAW,EAAE,IAAI,CAAC,KAAK;YACvB,UAAU,EAAE,IAAI,CAAC,IAAI;SACtB,CAAC;QACF,IAAI,IAAI,CAAC,IAAI;YAAE,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC;QAC1C,IAAI,IAAI,CAAC,EAAE;YAAE,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC;QACpC,IAAI,IAAI,CAAC,KAAK;YAAE,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC;QAC7C,IAAI,IAAI,CAAC,OAAO;YAAE,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC;QACnD,wFAAwF;QACxF,mFAAmF;QACnF,IAAI,IAAI,CAAC,UAAU;YAAE,GAAG,CAAC,gBAAgB,GAAG,IAAI,CAAC,UAAU,CAAC;QAC5D,gGAAgG;QAChG,8FAA8F;QAC9F,2FAA2F;QAC3F,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QACrF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;QAClE,IAAI,KAAK;YAAE,GAAG,CAAC,YAAY,GAAG,KAAK,CAAC;QACpC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC;IACrD,CAAC;CACF,CAAC;AAEF,QAAQ,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC"}
|
package/dist/launch.js
CHANGED
|
@@ -19,7 +19,7 @@ import { tmpdir } from "node:os";
|
|
|
19
19
|
import { join } from "node:path";
|
|
20
20
|
import { fileURLToPath } from "node:url";
|
|
21
21
|
import { loadAgentFile } from "@cotal-ai/core";
|
|
22
|
-
import { hasIdentity, configFromEnv,
|
|
22
|
+
import { hasIdentity, configFromEnv, controlEndpoint, ORIENTATION_BOOTSTRAP } from "@cotal-ai/connector-core";
|
|
23
23
|
import { startSidecar } from "./sidecar.js";
|
|
24
24
|
/** Hermes API line this connector is written + pinned against (see pyproject.toml). A different
|
|
25
25
|
* major.minor may move the plugin/platform/hook signatures, so we assert and fail loudly. */
|
|
@@ -96,10 +96,11 @@ async function main() {
|
|
|
96
96
|
setupProfile(home, { model: process.env.HERMES_MODEL, persona });
|
|
97
97
|
// Paths shared by the sidecar and the gateway child — set in our env so startSidecar reads
|
|
98
98
|
// them, and forwarded verbatim to the child so the plugin connects to the same sockets/file.
|
|
99
|
-
const
|
|
99
|
+
const control = controlEndpoint(config.space, config.name);
|
|
100
100
|
const bridgeSock = bridgeSocketPath(config.space, config.name);
|
|
101
101
|
const toolsFile = join(home, "cotal-tools.json");
|
|
102
|
-
process.env.COTAL_CONTROL_SOCKET =
|
|
102
|
+
process.env.COTAL_CONTROL_SOCKET = control.path;
|
|
103
|
+
process.env.COTAL_CONTROL_TOKEN = control.token; // first-frame auth, shared sidecar↔plugin via env
|
|
103
104
|
process.env.COTAL_BRIDGE_SOCKET = bridgeSock;
|
|
104
105
|
process.env.COTAL_TOOLS_FILE = toolsFile;
|
|
105
106
|
const sidecar = startSidecar();
|
|
@@ -108,7 +109,8 @@ async function main() {
|
|
|
108
109
|
const childEnv = {
|
|
109
110
|
...process.env,
|
|
110
111
|
HERMES_HOME: home,
|
|
111
|
-
COTAL_CONTROL_SOCKET:
|
|
112
|
+
COTAL_CONTROL_SOCKET: control.path,
|
|
113
|
+
COTAL_CONTROL_TOKEN: control.token,
|
|
112
114
|
COTAL_BRIDGE_SOCKET: bridgeSock,
|
|
113
115
|
COTAL_TOOLS_FILE: toolsFile,
|
|
114
116
|
};
|
package/dist/launch.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"launch.js","sourceRoot":"","sources":["../src/launch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACnE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"launch.js","sourceRoot":"","sources":["../src/launch.ts"],"names":[],"mappings":"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"}
|
package/dist/sidecar.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sidecar.d.ts","sourceRoot":"","sources":["../src/sidecar.ts"],"names":[],"mappings":"AAgBA,OAAO,EAEL,SAAS,EAET,KAAK,WAAW,EACjB,MAAM,0BAA0B,CAAC;AAKlC,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAQD;gGACgG;AAChG,wBAAgB,YAAY,IAAI,OAAO,
|
|
1
|
+
{"version":3,"file":"sidecar.d.ts","sourceRoot":"","sources":["../src/sidecar.ts"],"names":[],"mappings":"AAgBA,OAAO,EAEL,SAAS,EAET,KAAK,WAAW,EACjB,MAAM,0BAA0B,CAAC;AAKlC,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAQD;gGACgG;AAChG,wBAAgB,YAAY,IAAI,OAAO,CAwCtC"}
|
package/dist/sidecar.js
CHANGED
|
@@ -32,9 +32,11 @@ export function startSidecar() {
|
|
|
32
32
|
const agent = new MeshAgent(config);
|
|
33
33
|
agent.start(); // background connect with retry
|
|
34
34
|
const controlSock = need("COTAL_CONTROL_SOCKET");
|
|
35
|
+
const controlToken = need("COTAL_CONTROL_TOKEN");
|
|
35
36
|
const bridgeSock = need("COTAL_BRIDGE_SOCKET");
|
|
36
37
|
const toolsFile = need("COTAL_TOOLS_FILE");
|
|
37
|
-
|
|
38
|
+
// Managed listener: own the endpoint (fatal bind) and authenticate every frame against the token.
|
|
39
|
+
const controlServer = startControlServer(agent, { path: controlSock, token: controlToken }, hermesHookHandle, { fatalBind: true });
|
|
38
40
|
const bridge = startBridgeServer(agent, config, bridgeSock);
|
|
39
41
|
// The plugin reads this at register(ctx) time to declare the cotal_* tools (full shared parity).
|
|
40
42
|
writeFileSync(toolsFile, JSON.stringify(hermesToolDescriptors(config)));
|
package/dist/sidecar.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sidecar.js","sourceRoot":"","sources":["../src/sidecar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EACL,aAAa,EACb,SAAS,EACT,kBAAkB,GAEnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAQzD,SAAS,IAAI,CAAC,IAAY;IACxB,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,wEAAwE,CAAC,CAAC;IACzG,OAAO,CAAC,CAAC;AACX,CAAC;AAED;gGACgG;AAChG,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAC/B,MAAM,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC,+DAA+D;IAC5F,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;IACpC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,gCAAgC;IAE/C,MAAM,WAAW,GAAG,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACjD,MAAM,UAAU,GAAG,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAE3C,MAAM,aAAa,GAAG,kBAAkB,
|
|
1
|
+
{"version":3,"file":"sidecar.js","sourceRoot":"","sources":["../src/sidecar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EACL,aAAa,EACb,SAAS,EACT,kBAAkB,GAEnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAQzD,SAAS,IAAI,CAAC,IAAY;IACxB,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,wEAAwE,CAAC,CAAC;IACzG,OAAO,CAAC,CAAC;AACX,CAAC;AAED;gGACgG;AAChG,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAC/B,MAAM,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC,+DAA+D;IAC5F,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;IACpC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,gCAAgC;IAE/C,MAAM,WAAW,GAAG,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACjD,MAAM,YAAY,GAAG,IAAI,CAAC,qBAAqB,CAAC,CAAC;IACjD,MAAM,UAAU,GAAG,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAE3C,kGAAkG;IAClG,MAAM,aAAa,GAAG,kBAAkB,CACtC,KAAK,EACL,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY,EAAE,EAC1C,gBAAgB,EAChB,EAAE,SAAS,EAAE,IAAI,EAAE,CACpB,CAAC;IACF,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;IAE5D,iGAAiG;IACjG,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAExE,OAAO;QACL,KAAK;QACL,MAAM;QACN,KAAK,CAAC,IAAI;YACR,IAAI,CAAC;gBACH,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,CAAC;YAAC,MAAM,CAAC;gBACP,YAAY;YACd,CAAC;YACD,IAAI,CAAC;gBACH,aAAa,CAAC,KAAK,EAAE,CAAC;YACxB,CAAC;YAAC,MAAM,CAAC;gBACP,YAAY;YACd,CAAC;YACD,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QACrB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cotal-ai/connector-hermes",
|
|
3
3
|
"description": "Cotal connector for the Hermes (Nous Research) agent.",
|
|
4
|
-
"version": "0.8.
|
|
4
|
+
"version": "0.8.2",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -23,14 +23,14 @@
|
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"tsx": "^4.22.4",
|
|
25
25
|
"zod": "^4.4.3",
|
|
26
|
-
"@cotal-ai/connector-core": "0.8.
|
|
26
|
+
"@cotal-ai/connector-core": "0.8.2"
|
|
27
27
|
},
|
|
28
28
|
"peerDependencies": {
|
|
29
29
|
"@cotal-ai/core": ">=0.1.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"esbuild": "^0.28.0",
|
|
33
|
-
"@cotal-ai/core": "0.8.
|
|
33
|
+
"@cotal-ai/core": "0.8.2"
|
|
34
34
|
},
|
|
35
35
|
"files": [
|
|
36
36
|
"bin",
|
package/plugin/cotal/__init__.py
CHANGED
|
@@ -16,6 +16,7 @@ in the environment. Two run modes:
|
|
|
16
16
|
from __future__ import annotations
|
|
17
17
|
|
|
18
18
|
import os
|
|
19
|
+
import secrets
|
|
19
20
|
import shutil
|
|
20
21
|
import subprocess
|
|
21
22
|
import tempfile
|
|
@@ -99,6 +100,10 @@ def _bootstrap_standalone_sidecar() -> None:
|
|
|
99
100
|
space = os.environ.get("COTAL_SPACE") or "(from COTAL_LINK)"
|
|
100
101
|
os.environ.setdefault("COTAL_BRIDGE_SOCKET", str(run_dir / "bridge.sock"))
|
|
101
102
|
os.environ.setdefault("COTAL_CONTROL_SOCKET", str(run_dir / "control.sock"))
|
|
103
|
+
# The sidecar (listener) and the lifecycle hooks (this process) authenticate the control plane
|
|
104
|
+
# with a shared first-frame token. Managed mode gets it from the launcher; standalone mints one
|
|
105
|
+
# here so both sides — they share this env — agree on it.
|
|
106
|
+
os.environ.setdefault("COTAL_CONTROL_TOKEN", secrets.token_urlsafe(32))
|
|
102
107
|
os.environ.setdefault("COTAL_TOOLS_FILE", str(run_dir / "cotal-tools.json"))
|
|
103
108
|
|
|
104
109
|
sidecar = _resolve_sidecar_js()
|
|
@@ -14946,6 +14946,8 @@ function assertValidName(name) {
|
|
|
14946
14946
|
throw new Error(`invalid name ${JSON.stringify(name)}: must be a single line`);
|
|
14947
14947
|
if (name.includes("/"))
|
|
14948
14948
|
throw new Error(`invalid name ${JSON.stringify(name)}: "/" is reserved (the owner/name separator)`);
|
|
14949
|
+
if (name.includes("\\"))
|
|
14950
|
+
throw new Error(`invalid name ${JSON.stringify(name)}: "\\" is reserved (a Windows path separator)`);
|
|
14949
14951
|
}
|
|
14950
14952
|
|
|
14951
14953
|
// ../../packages/core/dist/link.js
|
|
@@ -17040,6 +17042,9 @@ function loadAgentFile(path) {
|
|
|
17040
17042
|
};
|
|
17041
17043
|
}
|
|
17042
17044
|
|
|
17045
|
+
// ../../packages/core/dist/secret-fs.js
|
|
17046
|
+
var isWin = process.platform === "win32";
|
|
17047
|
+
|
|
17043
17048
|
// ../../packages/core/dist/endpoint.js
|
|
17044
17049
|
var import_node_events = require("node:events");
|
|
17045
17050
|
var import_node_crypto = require("node:crypto");
|
|
@@ -34912,26 +34917,61 @@ ${info}${caught}`);
|
|
|
34912
34917
|
// ../connector-core/dist/control.js
|
|
34913
34918
|
var import_node_net = require("node:net");
|
|
34914
34919
|
var import_node_fs3 = require("node:fs");
|
|
34915
|
-
|
|
34916
|
-
|
|
34920
|
+
var import_node_crypto2 = require("node:crypto");
|
|
34921
|
+
var MAX_FRAME_BYTES = 1 << 20;
|
|
34922
|
+
var AUTH_DEADLINE_MS = 5e3;
|
|
34923
|
+
function tokenMatches(presented, digest) {
|
|
34924
|
+
if (typeof presented !== "string")
|
|
34925
|
+
return false;
|
|
34926
|
+
return (0, import_node_crypto2.timingSafeEqual)((0, import_node_crypto2.createHash)("sha256").update(presented).digest(), digest);
|
|
34927
|
+
}
|
|
34928
|
+
function startControlServer(agent, endpoint, handle, opts = {}) {
|
|
34929
|
+
const { path } = endpoint;
|
|
34930
|
+
const digest = (0, import_node_crypto2.createHash)("sha256").update(endpoint.token).digest();
|
|
34931
|
+
if (process.platform !== "win32" && (0, import_node_fs3.existsSync)(path)) {
|
|
34917
34932
|
try {
|
|
34918
|
-
(0, import_node_fs3.unlinkSync)(
|
|
34933
|
+
(0, import_node_fs3.unlinkSync)(path);
|
|
34919
34934
|
} catch {
|
|
34920
34935
|
}
|
|
34921
34936
|
}
|
|
34922
34937
|
const server = (0, import_node_net.createServer)((sock) => {
|
|
34923
34938
|
let buf = "";
|
|
34939
|
+
let handled = false;
|
|
34924
34940
|
sock.setEncoding("utf8");
|
|
34941
|
+
const deadline = setTimeout(() => sock.destroy(), AUTH_DEADLINE_MS);
|
|
34942
|
+
deadline.unref?.();
|
|
34943
|
+
sock.on("close", () => clearTimeout(deadline));
|
|
34925
34944
|
sock.on("data", async (d) => {
|
|
34945
|
+
if (handled)
|
|
34946
|
+
return;
|
|
34926
34947
|
buf += d;
|
|
34948
|
+
if (buf.length > MAX_FRAME_BYTES) {
|
|
34949
|
+
sock.destroy();
|
|
34950
|
+
return;
|
|
34951
|
+
}
|
|
34927
34952
|
const nl = buf.indexOf("\n");
|
|
34928
34953
|
if (nl < 0)
|
|
34929
34954
|
return;
|
|
34930
|
-
|
|
34955
|
+
handled = true;
|
|
34956
|
+
clearTimeout(deadline);
|
|
34957
|
+
let frame = {};
|
|
34931
34958
|
try {
|
|
34932
|
-
|
|
34959
|
+
frame = JSON.parse(buf.slice(0, nl) || "{}");
|
|
34933
34960
|
} catch {
|
|
34934
34961
|
}
|
|
34962
|
+
if (!tokenMatches(frame.token, digest)) {
|
|
34963
|
+
sock.destroy();
|
|
34964
|
+
return;
|
|
34965
|
+
}
|
|
34966
|
+
if (frame.op === "shutdown") {
|
|
34967
|
+
try {
|
|
34968
|
+
sock.end(JSON.stringify({ ok: true }) + "\n");
|
|
34969
|
+
} catch {
|
|
34970
|
+
}
|
|
34971
|
+
opts.onShutdown?.();
|
|
34972
|
+
return;
|
|
34973
|
+
}
|
|
34974
|
+
const ev = frame.event ?? {};
|
|
34935
34975
|
const reply = await handle(agent, ev);
|
|
34936
34976
|
try {
|
|
34937
34977
|
sock.end(JSON.stringify(reply) + "\n");
|
|
@@ -34941,10 +34981,18 @@ function startControlServer(agent, socketPath, handle) {
|
|
|
34941
34981
|
sock.on("error", () => {
|
|
34942
34982
|
});
|
|
34943
34983
|
});
|
|
34944
|
-
|
|
34945
|
-
|
|
34946
|
-
|
|
34947
|
-
`)
|
|
34984
|
+
let bound = false;
|
|
34985
|
+
server.on("error", (e) => {
|
|
34986
|
+
process.stderr.write(`[cotal-connector] control server error: ${e.message}
|
|
34987
|
+
`);
|
|
34988
|
+
if (opts.fatalBind && !bound)
|
|
34989
|
+
process.exit(1);
|
|
34990
|
+
});
|
|
34991
|
+
server.listen(path, () => {
|
|
34992
|
+
bound = true;
|
|
34993
|
+
process.stderr.write(`[cotal-connector] control socket: ${path}
|
|
34994
|
+
`);
|
|
34995
|
+
});
|
|
34948
34996
|
return server;
|
|
34949
34997
|
}
|
|
34950
34998
|
|
|
@@ -35161,9 +35209,15 @@ function startSidecar() {
|
|
|
35161
35209
|
const agent = new MeshAgent(config2);
|
|
35162
35210
|
agent.start();
|
|
35163
35211
|
const controlSock = need("COTAL_CONTROL_SOCKET");
|
|
35212
|
+
const controlToken = need("COTAL_CONTROL_TOKEN");
|
|
35164
35213
|
const bridgeSock = need("COTAL_BRIDGE_SOCKET");
|
|
35165
35214
|
const toolsFile = need("COTAL_TOOLS_FILE");
|
|
35166
|
-
const controlServer = startControlServer(
|
|
35215
|
+
const controlServer = startControlServer(
|
|
35216
|
+
agent,
|
|
35217
|
+
{ path: controlSock, token: controlToken },
|
|
35218
|
+
hermesHookHandle,
|
|
35219
|
+
{ fatalBind: true }
|
|
35220
|
+
);
|
|
35167
35221
|
const bridge = startBridgeServer(agent, config2, bridgeSock);
|
|
35168
35222
|
(0, import_node_fs5.writeFileSync)(toolsFile, JSON.stringify(hermesToolDescriptors(config2)));
|
|
35169
35223
|
return {
|
package/plugin/cotal/hooks.py
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"""Hermes lifecycle hooks → Cotal presence (the relay.ts pattern, in Python).
|
|
2
2
|
|
|
3
3
|
Each hook makes a one-shot connection to connector-core's control socket
|
|
4
|
-
(``COTAL_CONTROL_SOCKET``), sends ``{"hook_event_name": ...}``, and
|
|
5
|
-
``hermesHookHandle`` turns it into a presence change.
|
|
6
|
-
|
|
4
|
+
(``COTAL_CONTROL_SOCKET``), sends ``{"token": ..., "event": {"hook_event_name": ...}}``, and
|
|
5
|
+
ignores the reply — the TS ``hermesHookHandle`` turns it into a presence change. The control server
|
|
6
|
+
validates ``token`` (constant-time) before doing anything, so a frame without it is dropped. Both
|
|
7
|
+
the path and token come from the launch env (shared with the sidecar). Hooks must never block the
|
|
8
|
+
gateway, so the connection has a short timeout and every error is swallowed.
|
|
7
9
|
|
|
8
10
|
Hermes hook callback signatures vary by version; these take ``*args, **kwargs`` and best-effort
|
|
9
11
|
extract what they need, so a signature change degrades to "no detail" rather than an exception.
|
|
@@ -21,9 +23,10 @@ _TIMEOUT_S = 2.0
|
|
|
21
23
|
def relay(event_name: str, **fields: Any) -> None:
|
|
22
24
|
"""Forward one lifecycle event to the connector's control socket; fire-and-forget."""
|
|
23
25
|
path = os.environ.get("COTAL_CONTROL_SOCKET")
|
|
24
|
-
|
|
26
|
+
token = os.environ.get("COTAL_CONTROL_TOKEN")
|
|
27
|
+
if not path or not token:
|
|
25
28
|
return
|
|
26
|
-
payload = {"hook_event_name": event_name, **fields}
|
|
29
|
+
payload = {"token": token, "event": {"hook_event_name": event_name, **fields}}
|
|
27
30
|
try:
|
|
28
31
|
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
|
29
32
|
s.settimeout(_TIMEOUT_S)
|