@sellable/install 0.1.695 → 0.1.696

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.
@@ -651,6 +651,10 @@ export function mcpEndpointSessionActivated(session) {
651
651
  return endpointSessions.get(session)?.activated === true;
652
652
  }
653
653
 
654
+ function endpointSessionBody(session) {
655
+ return endpointSessions.get(session)?.body ?? null;
656
+ }
657
+
654
658
  function endpointSessionBodyMatches(left, right) {
655
659
  return ENDPOINT_EXPECTED_KEYS.every(
656
660
  (key) => stableJson(left[key]) === stableJson(right[key])
@@ -943,6 +947,22 @@ function isHermesSlackToolCall(request) {
943
947
  );
944
948
  }
945
949
 
950
+ function endpointHermesSessionId(body) {
951
+ if (body?.schemaVersion !== "sellable-agent-mcp-endpoint-run/v1") return null;
952
+ return `sellable_endpoint_${sha256(
953
+ `${body.conversationId}:${body.runId}:${body.attemptId}`
954
+ ).slice(0, 32)}`;
955
+ }
956
+
957
+ function isExactEndpointHermesSessionToolCall(request, body) {
958
+ if (!isHermesSlackToolCall(request)) return false;
959
+ const expectedSessionId = endpointHermesSessionId(body);
960
+ return Boolean(
961
+ expectedSessionId &&
962
+ request.params._meta.sellableAgent.sessionId === expectedSessionId
963
+ );
964
+ }
965
+
946
966
  function messageIdKey(id) {
947
967
  return id === undefined ? null : stableJson(id);
948
968
  }
@@ -1064,25 +1084,39 @@ export async function runMcpContextProxyStdio({
1064
1084
  for await (const line of inputLines) {
1065
1085
  const request = parseJsonRpcLine(line);
1066
1086
  if (!request) throw new Error("mcp_upstream_protocol_rejected");
1067
- // The patched Hermes bridge adds this exact request-scoped shape from its
1068
- // live Slack session ContextVar; the model controls only `arguments` and
1069
- // cannot author MCP `_meta`. Route that call directly even when this shared
1070
- // stdio transport previously served an endpoint run. The downstream
1071
- // credential boundary still verifies the Slack actor against the runtime's
1072
- // service principal and workspace identity. Endpoint calls carry no such
1073
- // metadata and remain descriptor-authorized below. Any metadata that does
1074
- // reach endpoint authorization is overwritten by the signed descriptor.
1075
- if (isHermesSlackToolCall(request)) {
1076
- await writeJsonLine(child.stdin, request);
1077
- continue;
1078
- }
1079
1087
  const candidate = existsSync(descriptorPath)
1080
1088
  ? descriptorCandidate(descriptorPath, descriptorRoot)
1081
1089
  : null;
1090
+ const activeBody = endpointSessionBody(endpointSession);
1091
+ const endpointBody =
1092
+ candidate?.body?.schemaVersion === "sellable-agent-mcp-endpoint-run/v1"
1093
+ ? candidate.body
1094
+ : activeBody?.schemaVersion === "sellable-agent-mcp-endpoint-run/v1"
1095
+ ? activeBody
1096
+ : null;
1082
1097
  const endpointMode = Boolean(
1083
- mcpEndpointSessionActivated(endpointSession) ||
1084
- candidate?.body?.schemaVersion === "sellable-agent-mcp-endpoint-run/v1"
1098
+ mcpEndpointSessionActivated(endpointSession) || endpointBody
1085
1099
  );
1100
+ // The patched Hermes bridge adds this exact request-scoped shape from its
1101
+ // live Slack session ContextVar; the model controls only `arguments` and
1102
+ // cannot author MCP `_meta`. Route genuine Slack calls directly even when
1103
+ // this shared stdio transport previously served an endpoint run. Hermes
1104
+ // also reuses its Slack-shaped ContextVar for endpoint calls, but gives
1105
+ // those calls the exact deterministic endpoint session id. Recover that
1106
+ // reserved shape through the signed endpoint authorization below so stale
1107
+ // Slack context cannot bypass the endpoint receipt path. Any unverified
1108
+ // descriptor can only select that fail-closed path; it is still validated
1109
+ // before its metadata reaches the downstream process.
1110
+ if (
1111
+ isHermesSlackToolCall(request) &&
1112
+ !(
1113
+ endpointMode &&
1114
+ isExactEndpointHermesSessionToolCall(request, endpointBody)
1115
+ )
1116
+ ) {
1117
+ await writeJsonLine(child.stdin, request);
1118
+ continue;
1119
+ }
1086
1120
  if (request.method === "tools/list" && endpointMode) {
1087
1121
  const expected = existsSync(descriptorPath)
1088
1122
  ? deriveExpectedMcpTurnBinding({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/install",
3
- "version": "0.1.695",
3
+ "version": "0.1.696",
4
4
  "type": "module",
5
5
  "description": "One-command installer for Sellable MCP in Claude Code, Codex, and Hermes",
6
6
  "bin": {