@sellable/install 0.1.433-wip.146.20260728144000 → 0.1.433
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/bin/sellable-install.mjs +0 -3
- package/container/Dockerfile +4 -4
- package/container/README.md +2 -2
- package/lib/sellable-agent/fly-customer-image/Dockerfile +3 -3
- package/lib/sellable-agent/fly-customer-image/customer-runtime.mjs +2 -2
- package/lib/sellable-agent/host-bootstrap.mjs +1 -2
- package/lib/sellable-agent/host-worker.mjs +1 -2
- package/lib/sellable-agent/profile-materializer.mjs +1 -2
- package/lib/sellable-agent/provisioning-adapter.mjs +4 -5
- package/package.json +1 -1
- package/skill-templates/refill-sends.md +6 -74
package/bin/sellable-install.mjs
CHANGED
|
@@ -1194,9 +1194,6 @@ const CREATE_EVERGREEN_CAMPAIGNS_ALLOWED_TOOLS = [
|
|
|
1194
1194
|
];
|
|
1195
1195
|
|
|
1196
1196
|
const REFILL_SENDS_ALLOWED_TOOLS = [
|
|
1197
|
-
"mcp__sellable__refill_v3_sender_date_eligibility",
|
|
1198
|
-
"mcp__sellable__refill_v3_supply_assessment",
|
|
1199
|
-
"mcp__sellable__refill_v3_workspace_inventory",
|
|
1200
1197
|
"mcp__sellable__refill_sends",
|
|
1201
1198
|
"mcp__sellable__get_auth_status",
|
|
1202
1199
|
"mcp__sellable__start_cli_login",
|
package/container/Dockerfile
CHANGED
|
@@ -3,12 +3,12 @@ FROM ${HERMES_IMAGE}
|
|
|
3
3
|
|
|
4
4
|
USER root
|
|
5
5
|
|
|
6
|
-
ARG INSTALLER_PACKAGE=@sellable/install@0.1.433
|
|
6
|
+
ARG INSTALLER_PACKAGE=@sellable/install@0.1.433
|
|
7
7
|
ARG MCP_PACKAGE=@sellable/mcp@0.1.760-wip.phase143.20260727100513
|
|
8
8
|
ARG INSTALLER_INTEGRITY
|
|
9
9
|
ARG MCP_INTEGRITY=sha512-muNXHuRnLTfsnW+MQUvK+p0VBZETDKeevr70iRliXyqE3/SLrZQJLL1laJzMo+qiUs9jMXMHdKOQfQqLiwJvtg==
|
|
10
10
|
|
|
11
|
-
RUN test "${INSTALLER_PACKAGE}" = "@sellable/install@0.1.433
|
|
11
|
+
RUN test "${INSTALLER_PACKAGE}" = "@sellable/install@0.1.433" \
|
|
12
12
|
&& test "${MCP_PACKAGE}" = "@sellable/mcp@0.1.760-wip.phase143.20260727100513" \
|
|
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.433-wip.146.20260728144
|
|
|
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.433
|
|
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.433' || mcp.name !== '@sellable/mcp' || mcp.version !== '0.1.760-wip.phase143.20260727100513') 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.433
|
|
28
|
+
&& node --input-type=module -e "import { chmodSync, writeFileSync } from 'node:fs'; const release = { installerPackage: '@sellable/install@0.1.433', installerIntegrity: process.argv[1], mcpPackage: '@sellable/mcp@0.1.760-wip.phase143.20260727100513', 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
|
package/container/README.md
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
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.433
|
|
6
|
+
`@sellable/install@0.1.433` is
|
|
7
7
|
published:
|
|
8
8
|
|
|
9
9
|
```sh
|
|
10
10
|
docker build --platform linux/amd64 \
|
|
11
11
|
--build-arg INSTALLER_INTEGRITY='sha512-…' \
|
|
12
|
-
--tag sellable-agent-host:0.1.433
|
|
12
|
+
--tag sellable-agent-host:0.1.433 .
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
Create a private `bootstrap/` directory owned by root with mode `0700`. It must contain `bootstrap.json`, `provider-auth`, and `slack-app`, each owned by root with mode `0600`. `bootstrap.json` contains only non-secret identities, hashes, package integrities, and the control-plane URL. The other two files contain the provider JSON and global Slack app token whose hashes are pinned by `bootstrap.json`.
|
|
@@ -3,9 +3,9 @@ FROM ${HERMES_IMAGE}
|
|
|
3
3
|
|
|
4
4
|
USER root
|
|
5
5
|
|
|
6
|
-
ARG MCP_PACKAGE=@sellable/mcp@0.1.
|
|
7
|
-
ARG MCP_INTEGRITY=sha512-
|
|
8
|
-
ARG INSTALLER_PACKAGE=@sellable/install@0.1.433
|
|
6
|
+
ARG MCP_PACKAGE=@sellable/mcp@0.1.772
|
|
7
|
+
ARG MCP_INTEGRITY=sha512-9tSeLbH9U4Bg/XP0mriN1laMiU6MgNGnJMdXVxQTMvaZ7Mx84CCO7g1EPB7SLjX97XR8W37p1LbG7avl4K5QyA==
|
|
8
|
+
ARG INSTALLER_PACKAGE=@sellable/install@0.1.433
|
|
9
9
|
ARG HERMES_VERSION=0.19.0
|
|
10
10
|
ARG MCP_TRUST_ROOT_B64
|
|
11
11
|
ARG TIRITH_VERSION=0.3.3
|
|
@@ -63,9 +63,9 @@ const RUNTIME_GENERATION = Number(
|
|
|
63
63
|
const BOOT_SESSION_ID = randomUUID();
|
|
64
64
|
const HERMES_VERSION = process.env.SELLABLE_AGENT_HERMES_VERSION ?? "0.19.0";
|
|
65
65
|
const INSTALLER_PACKAGE =
|
|
66
|
-
process.env.SELLABLE_AGENT_INSTALLER_PACKAGE ?? "@sellable/install@0.1.433
|
|
66
|
+
process.env.SELLABLE_AGENT_INSTALLER_PACKAGE ?? "@sellable/install@0.1.433";
|
|
67
67
|
const MCP_PACKAGE =
|
|
68
|
-
process.env.SELLABLE_AGENT_MCP_PACKAGE ?? "@sellable/mcp@0.1.
|
|
68
|
+
process.env.SELLABLE_AGENT_MCP_PACKAGE ?? "@sellable/mcp@0.1.772";
|
|
69
69
|
|
|
70
70
|
const sha256 = (value) => createHash("sha256").update(value).digest("hex");
|
|
71
71
|
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -38,8 +38,7 @@ 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 =
|
|
42
|
-
"@sellable/install@0.1.433-wip.146.20260728144000";
|
|
41
|
+
const INSTALLER_PACKAGE = "@sellable/install@0.1.433";
|
|
43
42
|
const MCP_PACKAGE = "@sellable/mcp@0.1.760-wip.phase143.20260727100513";
|
|
44
43
|
const HERMES_VERSION = "0.18.0";
|
|
45
44
|
const SHA256 = /^[a-f0-9]{64}$/;
|
|
@@ -1513,8 +1513,7 @@ export function compileClaimToProfileDesired(activeClaim, config) {
|
|
|
1513
1513
|
]) ||
|
|
1514
1514
|
pinned.hermesCli !== "hermes" ||
|
|
1515
1515
|
pinned.hermesVersion !== "0.18.0" ||
|
|
1516
|
-
pinned.installerPackage !==
|
|
1517
|
-
"@sellable/install@0.1.433-wip.146.20260728144000" ||
|
|
1516
|
+
pinned.installerPackage !== "@sellable/install@0.1.433" ||
|
|
1518
1517
|
pinned.mcpPackage !==
|
|
1519
1518
|
"@sellable/mcp@0.1.760-wip.phase143.20260727100513" ||
|
|
1520
1519
|
!Array.isArray(policy.toolInclude) ||
|
|
@@ -192,8 +192,7 @@ function validateDesired(desired) {
|
|
|
192
192
|
desired.serviceCredentialGeneration < 1 ||
|
|
193
193
|
desired.hermesCli !== "hermes" ||
|
|
194
194
|
desired.hermesVersion !== "0.18.0" ||
|
|
195
|
-
desired.installerPackage !==
|
|
196
|
-
"@sellable/install@0.1.433-wip.146.20260728144000" ||
|
|
195
|
+
desired.installerPackage !== "@sellable/install@0.1.433" ||
|
|
197
196
|
desired.mcpPackage !==
|
|
198
197
|
"@sellable/mcp@0.1.760-wip.phase143.20260727100513" ||
|
|
199
198
|
!Array.isArray(desired.toolInclude) ||
|
|
@@ -25,8 +25,7 @@ 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 =
|
|
29
|
-
"@sellable/install@0.1.433-wip.146.20260728144000";
|
|
28
|
+
export const PINNED_INSTALL_PACKAGE = "@sellable/install@0.1.433";
|
|
30
29
|
export const PINNED_MCP_PACKAGE =
|
|
31
30
|
"@sellable/mcp@0.1.760-wip.phase143.20260727100513";
|
|
32
31
|
|
|
@@ -613,7 +612,7 @@ function inspectProvisionedProfile({
|
|
|
613
612
|
!matchesReadback(manifest, request) ||
|
|
614
613
|
manifest.serviceCredentialReference !== serviceCredentialReference ||
|
|
615
614
|
manifest.installerPackage !== PINNED_INSTALL_PACKAGE ||
|
|
616
|
-
manifest.installerVersion !== "0.1.433
|
|
615
|
+
manifest.installerVersion !== "0.1.433" ||
|
|
617
616
|
manifest.mcpPackage !== PINNED_MCP_PACKAGE ||
|
|
618
617
|
manifest.credentialKeyVersion !== credentialKeyVersion ||
|
|
619
618
|
!/^[a-f0-9]{16}$/.test(manifest.credentialFingerprint) ||
|
|
@@ -827,7 +826,7 @@ function successReceipt({
|
|
|
827
826
|
subject: `agent-profile:${observed.profileId}`,
|
|
828
827
|
cli: {
|
|
829
828
|
installPackage: PINNED_INSTALL_PACKAGE,
|
|
830
|
-
installVersion: "0.1.433
|
|
829
|
+
installVersion: "0.1.433",
|
|
831
830
|
mcpPackage: PINNED_MCP_PACKAGE,
|
|
832
831
|
command: "hermes profile bootstrap",
|
|
833
832
|
},
|
|
@@ -875,7 +874,7 @@ function failure(code, stages, extra = {}, request = null) {
|
|
|
875
874
|
: "agent-profile:unbound",
|
|
876
875
|
cli: {
|
|
877
876
|
installPackage: PINNED_INSTALL_PACKAGE,
|
|
878
|
-
installVersion: "0.1.433
|
|
877
|
+
installVersion: "0.1.433",
|
|
879
878
|
mcpPackage: PINNED_MCP_PACKAGE,
|
|
880
879
|
command: "hermes profile bootstrap",
|
|
881
880
|
},
|
package/package.json
CHANGED
|
@@ -3,9 +3,6 @@ name: refill-sends
|
|
|
3
3
|
description: Refill projected sends across a workspace or selected senders through the canonical fenced coordinator.
|
|
4
4
|
visibility: public
|
|
5
5
|
allowed-tools:
|
|
6
|
-
- mcp__sellable__refill_v3_sender_date_eligibility
|
|
7
|
-
- mcp__sellable__refill_v3_supply_assessment
|
|
8
|
-
- mcp__sellable__refill_v3_workspace_inventory
|
|
9
6
|
- mcp__sellable__refill_sends
|
|
10
7
|
- mcp__sellable__get_refill_target_plan
|
|
11
8
|
- mcp__sellable__get_scheduler_fill_capacity
|
|
@@ -33,79 +30,14 @@ Host commands:
|
|
|
33
30
|
- Claude Code: `/sellable:refill-sends`
|
|
34
31
|
- Codex: `$sellable:refill-sends`
|
|
35
32
|
|
|
36
|
-
## Refill v3 Calls 1–3a — progressive observation gate
|
|
37
|
-
|
|
38
|
-
Use this gate only when the operator explicitly requests `--observe-v3`,
|
|
39
|
-
explicitly asks to inspect or preview Refill V3 eligibility and supply without
|
|
40
|
-
refilling, or invokes a UAT request that names Calls 1–3a. An ordinary fill or
|
|
41
|
-
refill intent without `--observe-v3` skips this gate and continues at
|
|
42
|
-
`Entry and exact scope` below.
|
|
43
|
-
|
|
44
|
-
Do not combine `--observe-v3` with `--yolo`, scheduled execution, or legacy
|
|
45
|
-
execution in one invocation. If they are combined, stop with no tool call and
|
|
46
|
-
ask the operator to choose observation or execution.
|
|
47
|
-
|
|
48
|
-
1. Call `get_auth_status`. If Sellable authentication is not valid, run only
|
|
49
|
-
the returned login flow and recheck authentication.
|
|
50
|
-
2. Load
|
|
51
|
-
`get_subskill_asset({ subskillName: "refill-sends", assetPath: "core/flow.v3.json" })`
|
|
52
|
-
completely. Require `workflow:"refill-sends-v3"` and `version:3`. Follow
|
|
53
|
-
only the current state's `allowedTools`, `doNotLoad`, and transition.
|
|
54
|
-
3. Resolve the exact workspace by explicit ID, exact name, install mapping, or
|
|
55
|
-
an unambiguous accessible-workspace match using `get_active_workspace` and
|
|
56
|
-
`list_workspaces`. Never change the active workspace.
|
|
57
|
-
4. Call
|
|
58
|
-
`refill_v3_workspace_inventory({ workspaceId, detail: "concise" })` exactly
|
|
59
|
-
once.
|
|
60
|
-
5. For each globally eligible sender and requested sender-local date, call
|
|
61
|
-
`refill_v3_sender_date_eligibility` exactly once with the server-issued
|
|
62
|
-
`runId` and `fence`. Never call it for a globally ineligible sender.
|
|
63
|
-
6. Evaluate the invite and paid lane results independently. A typed blocker
|
|
64
|
-
terminates only that lane; it never suppresses another positively eligible
|
|
65
|
-
lane. For every positively eligible lane, call
|
|
66
|
-
`refill_v3_supply_assessment` exactly once for each campaign/lane tuple
|
|
67
|
-
issued by inventory. Pass the backend-applied quota as the assessment
|
|
68
|
-
bound; never invent or substitute a campaign, lane, sender, date, run
|
|
69
|
-
identity, or fence.
|
|
70
|
-
7. Render the complete inventory, sender/date eligibility, and supply result,
|
|
71
|
-
including every typed blocker. The observation run is terminal only after
|
|
72
|
-
every issued lane is terminal.
|
|
73
|
-
|
|
74
|
-
A sender whose LinkedIn account is connected but whose Sales Navigator status
|
|
75
|
-
is disconnected remains eligible for real non-Sales-Nav lanes. For Thomas or
|
|
76
|
-
any equivalent sender, the paid InMail lane must return
|
|
77
|
-
`sales_nav_disconnected` at eligibility and transition only that paid lane
|
|
78
|
-
directly to terminal `blocked`: do not call supply for the blocked paid lane,
|
|
79
|
-
refresh a provider, invoke Sales Navigator, or schedule or place anything.
|
|
80
|
-
Open InMail without a trusted classic route is likewise terminal only for that
|
|
81
|
-
open-InMail lane. Continue Thomas's positively eligible invite lane through its
|
|
82
|
-
issued campaign/lane tuples.
|
|
83
|
-
|
|
84
|
-
While `--observe-v3` is selected, do not load `refill-sends-workflow`, call
|
|
85
|
-
`get_refill_target_plan`, or call `refill_sends`. The host consumes
|
|
86
|
-
`--observe-v3`; never pass it to `refill_sends`. Calls 1–3a are backend-owned
|
|
87
|
-
observation calls; they may append their fenced decision ledger and Call 2 may
|
|
88
|
-
perform its bounded single-flight paid-credit cache refresh. They never approve
|
|
89
|
-
or enrich rows, acquire supply, change campaign state, invoke a Sales Navigator
|
|
90
|
-
provider action, schedule, place, or send. Between calls, retain the
|
|
91
|
-
server-issued `runId` and `fence`; never reconstruct downstream policy in the
|
|
92
|
-
host.
|
|
93
|
-
|
|
94
|
-
The sections below remain the default path for ordinary fill and refill
|
|
95
|
-
requests. `refill_sends` remains the only mutation execution owner; this
|
|
96
|
-
explicit observation gate does not introduce another mutation owner.
|
|
97
|
-
|
|
98
33
|
## Entry and exact scope
|
|
99
34
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
inclusive; `targetDate` is one sender-local scheduler-fillable date. Skip
|
|
107
|
-
no-send days and never extend beyond the requested date. Finish the full D1
|
|
108
|
-
reread before D2.
|
|
35
|
+
Accepted request fields are `--yolo`, `workspaceId`, `--sender`/`senderIds`/
|
|
36
|
+
`senderNames`, `actionTypes`, `--until`/`untilDate`, `--target-date`/
|
|
37
|
+
`targetDate`, and compatibility `horizonSendDays`. Omitted dates mean the
|
|
38
|
+
scheduler-forward 48-hour window. `untilDate` is sender-local and inclusive;
|
|
39
|
+
`targetDate` is one sender-local scheduler-fillable date. Skip no-send days and
|
|
40
|
+
never extend beyond the requested date. Finish the full D1 reread before D2.
|
|
109
41
|
|
|
110
42
|
```text
|
|
111
43
|
refill_sends({ yolo?: boolean, executionMode?: "manual" | "scheduled" | "yolo", requireWorkspace?: boolean, workspaceId?: string, senders?: string[], senderIds?: string[], senderNames?: string[], actionTypes?: ("send_invite" | "send_inmail_closed")[], horizonSendDays?: number, untilDate?: "YYYY-MM-DD", targetDate?: "YYYY-MM-DD", runHandle?: RefillRunHandleV1, targetConfig?: RefillTargetConfigV1, reportingContext?: RefillReportingContextV2, messageTemplateRevision?: MessageTemplateRevisionV1 })
|