@sellable/install 0.1.758-wip.startup-campaign.20260920.2 → 0.1.758

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.
@@ -3,13 +3,13 @@ FROM ${HERMES_IMAGE}
3
3
 
4
4
  USER root
5
5
 
6
- ARG INSTALLER_PACKAGE=@sellable/install@0.1.758-wip.startup-campaign.20260920.2
7
- ARG MCP_PACKAGE=@sellable/mcp@0.1.939-wip.startup-campaign.20260919.2
6
+ ARG INSTALLER_PACKAGE=@sellable/install@0.1.758
7
+ ARG MCP_PACKAGE=@sellable/mcp@0.1.938
8
8
  ARG INSTALLER_INTEGRITY
9
- ARG MCP_INTEGRITY=sha512-gIgLlP1rpRRQloy4VzKnkeTc1ylnjvzqNmn58wliTAt4iEH/EFGB+FpcsDyoqQGkdeohhyjP9QDc3twlwcWw2w==
9
+ ARG MCP_INTEGRITY=sha512-wcVCiCXVvKeE/SufP+2iXk8zgzwYWh78M/1vwa7oorF9UZbzut9szyZV47t4iMX9owYgBVaGwdlOC6eX8VQX4A==
10
10
 
11
- RUN test "${INSTALLER_PACKAGE}" = "@sellable/install@0.1.758-wip.startup-campaign.20260920.2" \
12
- && test "${MCP_PACKAGE}" = "@sellable/mcp@0.1.939-wip.startup-campaign.20260919.2" \
11
+ RUN test "${INSTALLER_PACKAGE}" = "@sellable/install@0.1.758" \
12
+ && test "${MCP_PACKAGE}" = "@sellable/mcp@0.1.938" \
13
13
  && test -n "${INSTALLER_INTEGRITY}" \
14
14
  && test "$(npm view "${INSTALLER_PACKAGE}" dist.integrity)" = "${INSTALLER_INTEGRITY}" \
15
15
  && test "$(npm view "${MCP_PACKAGE}" dist.integrity)" = "${MCP_INTEGRITY}" \
@@ -23,9 +23,9 @@ RUN test "${INSTALLER_PACKAGE}" = "@sellable/install@0.1.758-wip.startup-campaig
23
23
  && mkdir -p /opt/sellable-agent/install-root /opt/sellable-agent/mcp-root \
24
24
  && npm install --prefix /opt/sellable-agent/install-root --omit=dev --ignore-scripts --no-audit --no-fund "${INSTALLER_PACKAGE}" \
25
25
  && npm install --prefix /opt/sellable-agent/mcp-root --omit=dev --ignore-scripts --no-audit --no-fund "${MCP_PACKAGE}" \
26
- && node --input-type=module -e "import { readFileSync } from 'node:fs'; const install = JSON.parse(readFileSync('/opt/sellable-agent/install-root/node_modules/@sellable/install/package.json')); const mcp = JSON.parse(readFileSync('/opt/sellable-agent/mcp-root/node_modules/@sellable/mcp/package.json')); if (install.name !== '@sellable/install' || install.version !== '0.1.758-wip.startup-campaign.20260920.2' || mcp.name !== '@sellable/mcp' || mcp.version !== '0.1.939-wip.startup-campaign.20260919.2') throw new Error('package identity rejected');" \
26
+ && node --input-type=module -e "import { readFileSync } from 'node:fs'; const install = JSON.parse(readFileSync('/opt/sellable-agent/install-root/node_modules/@sellable/install/package.json')); const mcp = JSON.parse(readFileSync('/opt/sellable-agent/mcp-root/node_modules/@sellable/mcp/package.json')); if (install.name !== '@sellable/install' || install.version !== '0.1.758' || mcp.name !== '@sellable/mcp' || mcp.version !== '0.1.938') throw new Error('package identity rejected');" \
27
27
  && node --input-type=module -e "import { buildExternalRuntimeClosure } from '/opt/sellable-agent/install-root/node_modules/@sellable/install/lib/sellable-agent/external-runtime-builder.mjs'; const built = buildExternalRuntimeClosure({ mcpPackageRoot: '/opt/sellable-agent/mcp-root/node_modules/@sellable/mcp', mcpNodeModulesRoot: '/opt/sellable-agent/mcp-root/node_modules', hermesSourceRoot: '/opt/hermes', ownerUid: 0, ownerGid: 0 }); if (!built.closureDigest) throw new Error('runtime closure rejected');" \
28
- && node --input-type=module -e "import { chmodSync, writeFileSync } from 'node:fs'; const release = { installerPackage: '@sellable/install@0.1.758-wip.startup-campaign.20260920.2', installerIntegrity: process.argv[1], mcpPackage: '@sellable/mcp@0.1.939-wip.startup-campaign.20260919.2', mcpIntegrity: process.argv[2] }; writeFileSync('/opt/sellable-agent/release.json', JSON.stringify(release) + '\\n', { mode: 0o444 }); chmodSync('/opt/sellable-agent/release.json', 0o444);" "${INSTALLER_INTEGRITY}" "${MCP_INTEGRITY}" \
28
+ && node --input-type=module -e "import { chmodSync, writeFileSync } from 'node:fs'; const release = { installerPackage: '@sellable/install@0.1.758', installerIntegrity: process.argv[1], mcpPackage: '@sellable/mcp@0.1.938', mcpIntegrity: process.argv[2] }; writeFileSync('/opt/sellable-agent/release.json', JSON.stringify(release) + '\\n', { mode: 0o444 }); chmodSync('/opt/sellable-agent/release.json', 0o444);" "${INSTALLER_INTEGRITY}" "${MCP_INTEGRITY}" \
29
29
  && npm cache clean --force
30
30
 
31
31
  COPY entrypoint.sh /usr/local/bin/sellable-agent-container-entrypoint
@@ -3,7 +3,7 @@
3
3
  This image is a dedicated Agent worker/runtime boundary beside an existing Hermes dashboard. It never replaces or reconfigures the dashboard container.
4
4
 
5
5
  Build from this directory after
6
- `@sellable/install@0.1.758-wip.startup-campaign.20260920.2` is
6
+ `@sellable/install@0.1.758` is
7
7
  published:
8
8
 
9
9
  ```sh
@@ -28,7 +28,7 @@ import {
28
28
 
29
29
  const MANIFEST_VERSION = "sellable-agent-external-runtime-closure/v1";
30
30
  const MCP_PACKAGE = "@sellable/mcp";
31
- const MCP_VERSION = "0.1.939-wip.startup-campaign.20260919.2";
31
+ const MCP_VERSION = "0.1.938";
32
32
  const SAFE_COMPONENT = /^[A-Za-z0-9@._+-]+$/;
33
33
  const HERMES_EXCLUDES = new Set([".git", ".playwright", "node_modules"]);
34
34
 
@@ -6,9 +6,9 @@ USER root
6
6
 
7
7
  ENV PLAYWRIGHT_BROWSERS_PATH=/opt/hermes/.playwright
8
8
 
9
- ARG MCP_PACKAGE=@sellable/mcp@0.1.939-wip.startup-campaign.20260919.2
10
- ARG MCP_INTEGRITY=sha512-gIgLlP1rpRRQloy4VzKnkeTc1ylnjvzqNmn58wliTAt4iEH/EFGB+FpcsDyoqQGkdeohhyjP9QDc3twlwcWw2w==
11
- ARG INSTALLER_PACKAGE=@sellable/install@0.1.758-wip.startup-campaign.20260920.2
9
+ ARG MCP_PACKAGE=@sellable/mcp@0.1.938
10
+ ARG MCP_INTEGRITY=sha512-wcVCiCXVvKeE/SufP+2iXk8zgzwYWh78M/1vwa7oorF9UZbzut9szyZV47t4iMX9owYgBVaGwdlOC6eX8VQX4A==
11
+ ARG INSTALLER_PACKAGE=@sellable/install@0.1.758
12
12
  ARG ADMIN_MCP_PACKAGE=@sellable/admin-mcp@0.1.202
13
13
  ARG ADMIN_MCP_INTEGRITY=sha512-ym3aye/0vQ8tfULJlKz9JFOxvIQsl1G+n3np+TTgK/tecwNblBo/j3AkTnRqH9iomKzPbZzP+n4tEQsvsU8ByA==
14
14
  ARG TUS_JS_CLIENT_VERSION=4.3.1
@@ -115,7 +115,6 @@ RUN set -eux; \
115
115
  "${DEFAULT_PROFILE_BUNDLE_VERSION}" "${DEFAULT_PROFILE_BUNDLE_DIGEST}" \
116
116
  && node --input-type=module -e \
117
117
  'import { installHermesAgentBridge, HERMES_AGENT_BRIDGE_DEDICATED_V0213_CONTRACT } from "/usr/local/lib/sellable-agent/hermes-bridge.mjs"; installHermesAgentBridge({ sourceRoot: "/opt/hermes", contract: HERMES_AGENT_BRIDGE_DEDICATED_V0213_CONTRACT });' \
118
- && /opt/hermes/.venv/bin/python -m compileall -q /opt/hermes/hermes_cli /opt/hermes/providers \
119
118
  && node --input-type=module -e \
120
119
  'await import("/usr/local/lib/sellable-agent/fly-runtime-identity.mjs");' \
121
120
  && node --input-type=module -e \
@@ -122,9 +122,9 @@ const RUNTIME_GENERATION = Number(
122
122
  const BOOT_SESSION_ID = randomUUID();
123
123
  const HERMES_VERSION = process.env.SELLABLE_AGENT_HERMES_VERSION ?? "0.21.3";
124
124
  const INSTALLER_PACKAGE =
125
- process.env.SELLABLE_AGENT_INSTALLER_PACKAGE ?? "@sellable/install@0.1.758-wip.startup-campaign.20260920.2";
125
+ process.env.SELLABLE_AGENT_INSTALLER_PACKAGE ?? "@sellable/install@0.1.758";
126
126
  const MCP_PACKAGE =
127
- process.env.SELLABLE_AGENT_MCP_PACKAGE ?? "@sellable/mcp@0.1.939-wip.startup-campaign.20260919.2";
127
+ process.env.SELLABLE_AGENT_MCP_PACKAGE ?? "@sellable/mcp@0.1.938";
128
128
  export const ENDPOINT_MAX_CONCURRENT_RUNS = 10;
129
129
  const DEFAULT_PROFILE_BUNDLE_ROOT =
130
130
  "/usr/local/share/sellable-agent/default-profile-bundle";
@@ -233,6 +233,14 @@ const TRANSIENT_PROFILE_PATHS = new Set([
233
233
  // symlink remains rejected below.
234
234
  ".config/pulse",
235
235
  ]);
236
+
237
+ export function isHermesTransientProfilePath(relativePath) {
238
+ const [topLevel] = relativePath.split("/", 1);
239
+ return (
240
+ TRANSIENT_PROFILE_ROOTS.has(topLevel) ||
241
+ TRANSIENT_PROFILE_PATHS.has(relativePath)
242
+ );
243
+ }
236
244
  // The encrypted Fly volume remains the authoritative full profile. The
237
245
  // portable disaster-recovery archive also carries state.db and sessions so a
238
246
  // replacement volume retains chat history and Slack thread routing. Caches,
@@ -464,10 +472,7 @@ function mergeHermesStateEntries(
464
472
  // runtime root, so it is disposable legacy state rather than profile
465
473
  // content.
466
474
  const relativePath = relativeRoot ? `${relativeRoot}/${name}` : name;
467
- if (
468
- (!relativeRoot && TRANSIENT_PROFILE_ROOTS.has(name)) ||
469
- TRANSIENT_PROFILE_PATHS.has(relativePath)
470
- ) {
475
+ if (isHermesTransientProfilePath(relativePath)) {
471
476
  continue;
472
477
  }
473
478
  const from = join(source, name);
@@ -38,8 +38,8 @@ import { installAgentHostServices } from "./service-installer.mjs";
38
38
  const PACKAGE_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "../..");
39
39
  const VERSION = "sellable-agent-host-bootstrap/v1";
40
40
  const RECEIPT_VERSION = "sellable-agent-host-registration/v1";
41
- const INSTALLER_PACKAGE = "@sellable/install@0.1.758-wip.startup-campaign.20260920.2";
42
- const MCP_PACKAGE = "@sellable/mcp@0.1.939-wip.startup-campaign.20260919.2";
41
+ const INSTALLER_PACKAGE = "@sellable/install@0.1.758";
42
+ const MCP_PACKAGE = "@sellable/mcp@0.1.938";
43
43
  const HERMES_VERSION = "0.18.0";
44
44
  const SHA256 = /^[a-f0-9]{64}$/;
45
45
  const SHA256_16 = /^[a-f0-9]{16}$/;
@@ -1546,8 +1546,8 @@ export function compileClaimToProfileDesired(activeClaim, config) {
1546
1546
  ]) ||
1547
1547
  pinned.hermesCli !== "hermes" ||
1548
1548
  pinned.hermesVersion !== "0.18.0" ||
1549
- pinned.installerPackage !== "@sellable/install@0.1.758-wip.startup-campaign.20260920.2" ||
1550
- pinned.mcpPackage !== "@sellable/mcp@0.1.939-wip.startup-campaign.20260919.2" ||
1549
+ pinned.installerPackage !== "@sellable/install@0.1.758" ||
1550
+ pinned.mcpPackage !== "@sellable/mcp@0.1.938" ||
1551
1551
  !Array.isArray(policy.toolInclude) ||
1552
1552
  policy.toolInclude.length === 0 ||
1553
1553
  !Number.isSafeInteger(slack.generation) ||
@@ -42,6 +42,7 @@ import {
42
42
  HERMES_SNAPSHOT_HOOKS,
43
43
  HERMES_SNAPSHOT_HOOK_ALLOWLIST_BYTES,
44
44
  applyHermesSellableHostedPolicy,
45
+ isHermesTransientProfilePath,
45
46
  linkHermesState,
46
47
  mergeHermesState,
47
48
  } from "./hermes-memory-snapshot.mjs";
@@ -311,8 +312,8 @@ function validateDesired(desired) {
311
312
  desired.serviceCredentialGeneration < 1 ||
312
313
  desired.hermesCli !== "hermes" ||
313
314
  desired.hermesVersion !== "0.18.0" ||
314
- desired.installerPackage !== "@sellable/install@0.1.758-wip.startup-campaign.20260920.2" ||
315
- desired.mcpPackage !== "@sellable/mcp@0.1.939-wip.startup-campaign.20260919.2" ||
315
+ desired.installerPackage !== "@sellable/install@0.1.758" ||
316
+ desired.mcpPackage !== "@sellable/mcp@0.1.938" ||
316
317
  !Array.isArray(desired.toolInclude) ||
317
318
  desired.toolInclude.length === 0 ||
318
319
  desired.toolInclude.some((tool) => !/^[a-z][a-z0-9_]{0,127}$/.test(tool)) ||
@@ -897,16 +898,21 @@ function renderStagedProfile(stageRoot, desired) {
897
898
  return manifest;
898
899
  }
899
900
 
900
- function inventory(root) {
901
+ function inventory(root, { skipTransient = false } = {}) {
901
902
  const files = [];
902
903
  const walk = (pathValue, relativePath) => {
903
904
  const link = lstatSync(pathValue);
904
905
  if (link.isSymbolicLink()) throw new Error("profile symlink rejected");
905
906
  if (link.isDirectory()) {
906
907
  for (const name of readdirSync(pathValue).sort()) {
908
+ const nextRelative = relativePath
909
+ ? `${relativePath}/${name}`
910
+ : name;
911
+ if (skipTransient && isHermesTransientProfilePath(nextRelative))
912
+ continue;
907
913
  walk(
908
914
  join(pathValue, name),
909
- relativePath ? `${relativePath}/${name}` : name
915
+ nextRelative
910
916
  );
911
917
  }
912
918
  return;
@@ -2784,7 +2790,12 @@ export function validateNativeSlackCustomerProfile({ desired, profileRoot }) {
2784
2790
  ) {
2785
2791
  return { ok: false, code: "native_slack_profile_path_invalid" };
2786
2792
  }
2787
- const found = inventory(profileRoot);
2793
+ // Runtime caches and live gateway coordination files are disposable and
2794
+ // can contain large dependency trees, sockets, or symlinks. They are
2795
+ // already excluded from profile replacement and snapshots; traversing
2796
+ // them here only blocks the lifecycle heartbeat before replacement even
2797
+ // starts. Keep the closed inventory walk for every durable path.
2798
+ const found = inventory(profileRoot, { skipTransient: true });
2788
2799
  const serverOwned = [...NATIVE_SLACK_CUSTOMER_PROFILE_INVENTORY].sort();
2789
2800
  if (serverOwned.some((logicalPath) => !found.includes(logicalPath))) {
2790
2801
  return { ok: false, code: "native_slack_profile_inventory_open" };
@@ -25,8 +25,8 @@ import { fileURLToPath } from "node:url";
25
25
  import { deriveContainedProfileId } from "./profile-materializer.mjs";
26
26
 
27
27
  export const PROVISIONING_ACTION = "PROVISION_HERMES_PROFILE";
28
- export const PINNED_INSTALL_PACKAGE = "@sellable/install@0.1.758-wip.startup-campaign.20260920.2";
29
- export const PINNED_MCP_PACKAGE = "@sellable/mcp@0.1.939-wip.startup-campaign.20260919.2";
28
+ export const PINNED_INSTALL_PACKAGE = "@sellable/install@0.1.758";
29
+ export const PINNED_MCP_PACKAGE = "@sellable/mcp@0.1.938";
30
30
  const PINNED_INSTALL_VERSION = PINNED_INSTALL_PACKAGE.slice(
31
31
  PINNED_INSTALL_PACKAGE.lastIndexOf("@") + 1
32
32
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/install",
3
- "version": "0.1.758-wip.startup-campaign.20260920.2",
3
+ "version": "0.1.758",
4
4
  "type": "module",
5
5
  "description": "One-command installer for Sellable MCP in Claude Code, Codex, and Hermes",
6
6
  "bin": {