@sellable/install 0.1.812 → 0.1.813

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,12 +3,12 @@ FROM ${HERMES_IMAGE}
3
3
 
4
4
  USER root
5
5
 
6
- ARG INSTALLER_PACKAGE=@sellable/install@0.1.812
6
+ ARG INSTALLER_PACKAGE=@sellable/install@0.1.813
7
7
  ARG MCP_PACKAGE=@sellable/mcp@0.1.959
8
8
  ARG INSTALLER_INTEGRITY
9
9
  ARG MCP_INTEGRITY=sha512-sOEIaI/O41qIhxuiLSx6zWz31I5MG+oJuVqfWKnIRBhfWnbjeLbNlPKaE6U88T0jby5sa0S5Vhtn77MRKEnE5Q==
10
10
 
11
- RUN test "${INSTALLER_PACKAGE}" = "@sellable/install@0.1.812" \
11
+ RUN test "${INSTALLER_PACKAGE}" = "@sellable/install@0.1.813" \
12
12
  && test "${MCP_PACKAGE}" = "@sellable/mcp@0.1.959" \
13
13
  && test -n "${INSTALLER_INTEGRITY}" \
14
14
  && test "$(npm view "${INSTALLER_PACKAGE}" dist.integrity)" = "${INSTALLER_INTEGRITY}" \
@@ -23,9 +23,9 @@ RUN test "${INSTALLER_PACKAGE}" = "@sellable/install@0.1.812" \
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.812' || mcp.name !== '@sellable/mcp' || mcp.version !== '0.1.959') 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.813' || mcp.name !== '@sellable/mcp' || mcp.version !== '0.1.959') 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.812', installerIntegrity: process.argv[1], mcpPackage: '@sellable/mcp@0.1.959', 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.813', installerIntegrity: process.argv[1], mcpPackage: '@sellable/mcp@0.1.959', 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.812` is
6
+ `@sellable/install@0.1.813` is
7
7
  published:
8
8
 
9
9
  ```sh
@@ -169,7 +169,7 @@ COPY fly-admin-image/start-admin-runtime /usr/local/lib/sellable-agent/admin-run
169
169
  COPY fly-customer-image/customer-runtime.mjs /usr/local/lib/sellable-agent/fly-customer-image/customer-runtime.mjs
170
170
  COPY hermes-first-welcome.mjs /usr/local/lib/sellable-agent/hermes-first-welcome.mjs
171
171
  COPY fly-customer-image/hermes-runs-client.mjs /usr/local/lib/sellable-agent/fly-customer-image/hermes-runs-client.mjs
172
- COPY fly-customer-image/endpoint-model-selection.mjs fly-customer-image/runs-api-connections.mjs fly-customer-image/claude-code-runs-api.mjs fly-customer-image/claude-code-mcp-session.mjs fly-customer-image/openai-runs-client.mjs fly-customer-image/runs-api-health-check.mjs fly-customer-image/public-endpoint-guard.mjs fly-customer-image/workspace-connection-client.mjs /usr/local/lib/sellable-agent/fly-customer-image/
172
+ COPY fly-customer-image/endpoint-model-selection.mjs fly-customer-image/runs-api-connections.mjs fly-customer-image/claude-code-runs-api.mjs fly-customer-image/openai-runs-client.mjs fly-customer-image/runs-api-health-check.mjs fly-customer-image/public-endpoint-guard.mjs fly-customer-image/workspace-connection-client.mjs /usr/local/lib/sellable-agent/fly-customer-image/
173
173
  COPY fly-customer-image/opener-stage-execution.mjs /usr/local/lib/sellable-agent/fly-customer-image/opener-stage-execution.mjs
174
174
  COPY fly-customer-image/endpoint-uat-completion-gate.mjs /usr/local/lib/sellable-agent/fly-customer-image/endpoint-uat-completion-gate.mjs
175
175
  COPY fly-customer-image/customer-runtime-phase-telemetry.mjs /usr/local/lib/sellable-agent/fly-customer-image/customer-runtime-phase-telemetry.mjs
@@ -276,7 +276,6 @@ RUN set -eux; \
276
276
  /usr/local/lib/sellable-agent/fly-customer-image/endpoint-model-selection.mjs \
277
277
  /usr/local/lib/sellable-agent/fly-customer-image/runs-api-connections.mjs \
278
278
  /usr/local/lib/sellable-agent/fly-customer-image/claude-code-runs-api.mjs \
279
- /usr/local/lib/sellable-agent/fly-customer-image/claude-code-mcp-session.mjs \
280
279
  /usr/local/lib/sellable-agent/fly-customer-image/public-endpoint-guard.mjs \
281
280
  /usr/local/lib/sellable-agent/fly-customer-image/workspace-connection-client.mjs \
282
281
  /usr/local/lib/sellable-agent/fly-customer-image/opener-stage-execution.mjs \
@@ -61,10 +61,7 @@ import {
61
61
  SELLABLE_BROWSER_TOOLSET_DEFAULT_MARKER,
62
62
  sellableSlackToolsetsForMaterialization,
63
63
  } from "../fly-capabilities-bridge.mjs";
64
- import {
65
- startConfiguredClaudeRunsApis,
66
- startPublicClaudeRunsApi,
67
- } from "../fly-customer-image/claude-code-runs-api.mjs";
64
+ import { startPublicClaudeRunsApi } from "../fly-customer-image/claude-code-runs-api.mjs";
68
65
  import { createCustomerEndpointRelay } from "../fly-customer-image/customer-runtime.mjs";
69
66
  import { createHermesSessionRetention } from "../fly-customer-image/hermes-runs-client.mjs";
70
67
  import {
@@ -909,32 +906,6 @@ function installAdminMcpRuntimeBinding(
909
906
  );
910
907
  }
911
908
 
912
- // The profile's `sellable` MCP server exactly as Hermes runs it, so a Claude
913
- // Code tool-lane run sees the same tools, through the same context proxy.
914
- function profileSellableMcpServer(profileRoot) {
915
- const path = join(profileRoot, "config.yaml");
916
- const stat = lstatSync(path);
917
- if (stat.isSymbolicLink() || !stat.isFile()) return null;
918
- const document = parseDocument(readFileSync(path, "utf8"));
919
- if (document.errors.length > 0) return null;
920
- const server = document.toJS().mcp_servers?.sellable;
921
- if (
922
- server?.command !== NODE ||
923
- JSON.stringify(server.args) !== JSON.stringify([MCP_CONTEXT_PROXY]) ||
924
- !server.env ||
925
- typeof server.env !== "object"
926
- ) {
927
- return null;
928
- }
929
- return {
930
- command: NODE,
931
- args: [MCP_CONTEXT_PROXY],
932
- env: Object.fromEntries(
933
- Object.entries(server.env).map(([key, value]) => [key, String(value)])
934
- ),
935
- };
936
- }
937
-
938
909
  function installAdminModelConfig(profileRoot, modelConfig) {
939
910
  const path = join(profileRoot, "config.yaml");
940
911
  const stat = lstatSync(path);
@@ -3852,23 +3823,6 @@ async function runAdminProduction() {
3852
3823
  let activeLaunch = null;
3853
3824
  let activeModelHealthReporter = null;
3854
3825
  let shutdownMemorySnapshot = null;
3855
- let customRunsServices = null;
3856
- try {
3857
- customRunsServices = await startConfiguredClaudeRunsApis({
3858
- diagnostic: (value) => process.stderr.write(`${JSON.stringify(value)}\n`),
3859
- toolLanes: {
3860
- turnDescriptorPath: join(MCP_TURN_CONTEXT_ROOT, "turn-context.json"),
3861
- server: () =>
3862
- activeLaunch
3863
- ? profileSellableMcpServer(activeLaunch.profile.profileHome)
3864
- : null,
3865
- },
3866
- });
3867
- } catch {
3868
- process.stderr.write(
3869
- `${JSON.stringify({ ok: false, code: "custom_runs_api_start_failed" })}\n`
3870
- );
3871
- }
3872
3826
  let publicRunsService = null;
3873
3827
  try {
3874
3828
  publicRunsService = await startPublicClaudeRunsApi({
@@ -4515,7 +4469,6 @@ async function runAdminProduction() {
4515
4469
  );
4516
4470
  }
4517
4471
  await endpointLoop;
4518
- await customRunsServices?.stop();
4519
4472
  await publicRunsService?.stop();
4520
4473
  await activeModelHealthReporter?.stop();
4521
4474
  await stopNativeGateway(activeGateway);
@@ -8,7 +8,7 @@ ENV PLAYWRIGHT_BROWSERS_PATH=/opt/hermes/.playwright
8
8
 
9
9
  ARG MCP_PACKAGE=@sellable/mcp@0.1.959
10
10
  ARG MCP_INTEGRITY=sha512-sOEIaI/O41qIhxuiLSx6zWz31I5MG+oJuVqfWKnIRBhfWnbjeLbNlPKaE6U88T0jby5sa0S5Vhtn77MRKEnE5Q==
11
- ARG INSTALLER_PACKAGE=@sellable/install@0.1.812
11
+ ARG INSTALLER_PACKAGE=@sellable/install@0.1.813
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
@@ -1,6 +1,5 @@
1
1
  import type { SpawnOptions } from "node:child_process";
2
2
  import type { Server } from "node:http";
3
- import type { RunsApiConnection } from "./runs-api-connections.mjs";
4
3
 
5
4
  export const CLAUDE_RUNS_MAX_CONCURRENCY: number;
6
5
  export type ClaudeRunsRequest = {
@@ -10,25 +9,15 @@ export type ClaudeRunsRequest = {
10
9
  model: string;
11
10
  effort: string;
12
11
  sessionId: string;
13
- tools: ClaudeRunsTools | ClaudeRunsRemoteTools | null;
14
- /** Remote tools: the run's private MCP config file, written by the service. */
12
+ tools: ClaudeRunsRemoteTools | null;
13
+ /** The run's private MCP config file, written by the service. */
15
14
  mcpConfigPath?: string;
16
15
  };
17
- export type ClaudeRunsToolServer = {
18
- command: string;
19
- args: string[];
20
- env: Record<string, string>;
21
- };
22
- export type ClaudeRunsTools = { names: string[]; server: ClaudeRunsToolServer };
23
- /** The run's own remote MCP server and grant (public mode). */
16
+ /** The run's own remote MCP server and grant. */
24
17
  export type ClaudeRunsRemoteTools = {
25
18
  names: string[];
26
19
  remote: { url: string; authorization: string };
27
20
  };
28
- export type ClaudeRunsToolLanes = {
29
- turnDescriptorPath: string;
30
- server(): ClaudeRunsToolServer | null;
31
- };
32
21
  export type ClaudeRunsResult = {
33
22
  output: string;
34
23
  runtime: { provider: string; model: string };
@@ -37,10 +26,7 @@ export type ClaudeRunsResult = {
37
26
  export type ClaudeRunsServer = Server & { stopActiveRuns(): Promise<void> };
38
27
  export type ClaudeRunsApiOptions = {
39
28
  token: string;
40
- /** Required in loopback mode; the public listener has none. */
41
- connection?: RunsApiConnection;
42
- mode?: "loopback" | "public";
43
- /** The CLI and account root; defaults to the connection's localRoot. */
29
+ /** The CLI and account root; defaults to /opt/data/private-opener. */
44
30
  root?: string;
45
31
  execute?:
46
32
  | ((request: ClaudeRunsRequest) => {
@@ -51,7 +37,6 @@ export type ClaudeRunsApiOptions = {
51
37
  audit?: (entry: Record<string, unknown>) => void;
52
38
  maxConcurrency?: number;
53
39
  maxToolConcurrency?: number;
54
- toolLanes?: ClaudeRunsToolLanes | null;
55
40
  checkAuthentication?: (
56
41
  configDir: string
57
42
  ) => Promise<"READY" | "SIGN_IN_REQUIRED" | "UNAVAILABLE">;
@@ -62,21 +47,11 @@ export type ClaudeRunsApiOptions = {
62
47
  ) => { promise: Promise<ClaudeRunsResult>; stop(code?: string): void };
63
48
  now?: () => number;
64
49
  };
65
- export function validateClaudeRunsRequest(
66
- body: unknown,
67
- /** null: the public rule (claude-* model, low/medium/high effort). */
68
- models: RunsApiConnection["models"] | null
69
- ): ClaudeRunsRequest;
70
- export function endpointToolNames(options: {
71
- turnDescriptorPath: string;
72
- sessionId: string;
73
- /** Absent: every run gets the tools its own turn descriptor allows. */
74
- toolEndpointIds?: string[];
75
- }): string[] | null;
50
+ /** Any claude-* model at low/medium/high effort, with optional remote tools. */
51
+ export function validateClaudeRunsRequest(body: unknown): ClaudeRunsRequest;
76
52
  export function claudeInvocation(
77
53
  request: ClaudeRunsRequest,
78
54
  root: string,
79
- mcpSpecPath?: string | null,
80
55
  configDir?: string
81
56
  ): { command: string; args: string[]; options: SpawnOptions };
82
57
  export function claudeAccountDirs(root: string): string[];
@@ -84,6 +59,16 @@ export function claudeUsageLimit(
84
59
  stdout: string,
85
60
  now?: number
86
61
  ): { retryAt: number } | null;
62
+ /** Why a CLI run failed, for the audit only: never its text. */
63
+ export function claudeFailureFacts(
64
+ stdout: string,
65
+ exitCode: number | null
66
+ ): {
67
+ exitCode: number | null;
68
+ apiErrorStatus: number | null;
69
+ terminalReason: string | null;
70
+ subtype: string | null;
71
+ };
87
72
  export function parseClaudeResult(
88
73
  stdout: string,
89
74
  request: ClaudeRunsRequest
@@ -100,14 +85,6 @@ export function startClaudeRun(
100
85
  export function createClaudeRunsApi(
101
86
  options: ClaudeRunsApiOptions
102
87
  ): ClaudeRunsServer;
103
- export function startConfiguredClaudeRunsApis(options?: {
104
- env?: Record<string, string | undefined>;
105
- diagnostic?: (entry: Record<string, unknown>) => void;
106
- createApi?: typeof createClaudeRunsApi;
107
- readToken?: (path: string) => string;
108
- toolLanes?: ClaudeRunsToolLanes | null;
109
- }): Promise<{ stop(): Promise<void> }>;
110
-
111
88
  export function startPublicClaudeRunsApi(options?: {
112
89
  env?: Record<string, string | undefined>;
113
90
  diagnostic?: (entry: Record<string, unknown>) => void;