feat: connect ECC to canonical Ito compute CLI (#2558)

This commit is contained in:
Affaan Mustafa 2026-07-23 19:28:55 -07:00 committed by GitHub
parent 9d54ee222d
commit bc774282e6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
32 changed files with 1043 additions and 1275 deletions

View file

@ -29,7 +29,7 @@ const COMMANDS = {
},
ito: {
script: 'ito.js',
description: 'Prepare a read-only sandbox handoff to the Itô compute desk',
description: 'Invoke the separately installed canonical Itô compute CLI',
},
'install-plan': {
script: 'install-plan.js',
@ -138,8 +138,9 @@ Examples:
ecc catalog show framework:nextjs
ecc consult "security reviews"
ecc control-pane --port 8765
ecc ito rent --accelerator h100 --count 1 --hours 24
ecc --dry-run ito rent --accelerator h100 --count 1 --hours 24 --json
ecc ito auth
ecc ito find --gpu h200 --count 8 --nodes 1 --gpus-per-node 8 --days 30 --storage-tb 1 --start-window 2099-08-15 --max-rate 3.00 --form-factor bare_metal --contract-type reservation --fabric infiniband --region us-east-1
ecc ito status --json
ecc list-installed --json
ecc doctor --target cursor
ecc repair --dry-run
@ -232,7 +233,12 @@ function runCommand(commandName, args) {
{
cwd: process.cwd(),
env: commandName === 'ito'
? { ...createSafeItoEnvironment(process.env, { includeControls: true }) }
? {
...createSafeItoEnvironment(process.env, {
includeControls: true,
includeItoRuntime: true,
}),
}
: process.env,
encoding: 'utf8',
maxBuffer: 10 * 1024 * 1024,

View file

@ -2,306 +2,210 @@
"use strict";
const fs = require("fs");
const path = require("path");
const { spawnSync } = require("child_process");
const { createSafeItoEnvironment } = require("./lib/ito-environment");
const DESK_URL = "https://compute.itomarkets.com/desk";
const SCHEMA_VERSION = "ito.compute.handoff.v1";
const SUPPORTED_ACCELERATORS = Object.freeze({
h100: "h100",
"h100-pcie": "h100-pcie",
"h100-sxm": "h100-sxm",
});
const REQUIRED_INTENT_OPTIONS = Object.freeze([
"accelerator",
"count",
"hours",
]);
const SUPPORTED_COMMANDS = Object.freeze(["auth", "find", "status"]);
const CANONICAL_REPOSITORY = "https://github.com/Ito-Markets/ito-cloud-runtime.git";
const CANONICAL_PACKAGE_PATH = "cli/ito-compute-cli";
const EXECUTABLE_OVERRIDE = "ECC_ITO_CLI_EXECUTABLE";
const MAX_OUTPUT_BYTES = 10 * 1024 * 1024;
function showHelp() {
console.log(`
ECC × Itô compute handoff
ECC × Itô local CLI bridge
Usage:
ecc ito rent --accelerator <h100|h100-pcie|h100-sxm> --count <1-64> --hours <1-720> [options]
ecc ito auth
ecc ito find <all required RFQ options>
ecc ito status
ecc ito <auth|find|status> --json
Options:
--dry-run Emit the exact handoff without opening a browser
--no-open Emit the exact handoff for manual browser navigation
--json Emit the versioned response envelope as JSON
--help Show this help
The bridge invokes the separately installed canonical Itô CLI and returns its
real stdout, stderr, and exit code unchanged. It performs no browser navigation
and adds no lock, workload, inference, evaluation, or purchase path.
Example:
ecc ito rent --accelerator h100 --count 1 --hours 24
Important:
- "find" reads live inventory and submits an authenticated RFQ.
- Obtain explicit buyer authority and every hard constraint before invoking it.
- "status" reads live RFQ and procurement status.
- Inventory and RFQs are not reservations; only a returned firm quote is firm.
This command creates a sandbox-only, read-only intent. It opens the Itô desk
for manual copy; sign-in may be required. It does not send the intent into Itô,
file an RFQ, request or accept a quote, call a procurement endpoint, approve
funds, or place an order. Stop before "Pay & buy".
The canonical package is currently unpublished. Install it locally:
Canonical source: Ito-Markets/ito-cloud-runtime/${CANONICAL_PACKAGE_PATH}
git clone ${CANONICAL_REPOSITORY}
cd ito-cloud-runtime/${CANONICAL_PACKAGE_PATH}
npm ci
npm run check
Then set ${EXECUTABLE_OVERRIDE} to the explicit absolute built entry:
/absolute/path/to/ito-cloud-runtime/${CANONICAL_PACKAGE_PATH}/dist/bin/ito.js
For safety, ECC never discovers this credential-bearing client through PATH.
The same package's MCP server exposes only:
ito_auth
ito_find
ito_status
Configure the MCP command as "node" with this absolute argument:
/absolute/path/to/ito-cloud-runtime/${CANONICAL_PACKAGE_PATH}/dist/bin/ito-mcp.js
Inject ITO_API_KEY into the child process from 1Password or the launching
environment. Never put the key in arguments, tracked files, or chat.
`);
}
function readValue(args, index, option) {
const value = args[index + 1];
if (value === undefined || value.startsWith("--")) {
throw new Error(`--${option} requires a value`);
}
return value;
}
function parseInteger(raw, option, minimum, maximum) {
if (!/^[0-9]+$/.test(raw)) {
throw new Error(`--${option} must be an integer between ${minimum} and ${maximum}`);
}
const value = Number(raw);
if (!Number.isSafeInteger(value) || value < minimum || value > maximum) {
throw new Error(`--${option} must be an integer between ${minimum} and ${maximum}`);
}
return value;
}
function parseAccelerator(raw) {
const normalized = String(raw).trim().toLowerCase();
const accelerator = SUPPORTED_ACCELERATORS[normalized];
if (!accelerator) {
throw new Error(
"--accelerator must be one of h100, h100-pcie, or h100-sxm"
);
}
return accelerator;
}
function parseArgs(argv) {
function parseArgs(argv, environment = process.env) {
const args = [...argv];
if (args.includes("--help") || args.includes("-h")) {
return { help: true };
if (
args.length === 0
|| args.includes("--help")
|| args.includes("-h")
) {
return Object.freeze({ help: true, invocationArgs: [] });
}
const command = args.shift();
if (command !== "rent") {
throw new Error(`unsupported Itô command: ${command || "(missing)"}`);
}
const values = {
accelerator: null,
count: null,
hours: null,
dryRun: false,
json: false,
noOpen: false,
};
const seen = new Set();
for (let index = 0; index < args.length; index += 1) {
const arg = args[index];
if (arg === "--dry-run") {
if (seen.has("dry-run")) throw new Error("--dry-run may only be provided once");
seen.add("dry-run");
values.dryRun = true;
continue;
}
if (arg === "--json") {
if (seen.has("json")) throw new Error("--json may only be provided once");
seen.add("json");
values.json = true;
continue;
}
if (arg === "--no-open") {
if (seen.has("no-open")) throw new Error("--no-open may only be provided once");
seen.add("no-open");
values.noOpen = true;
continue;
}
const option = arg.startsWith("--") ? arg.slice(2) : "";
if (!REQUIRED_INTENT_OPTIONS.includes(option)) {
throw new Error(`unsupported option: ${arg}`);
}
if (seen.has(option)) {
throw new Error(`--${option} may only be provided once`);
}
seen.add(option);
const raw = readValue(args, index, option);
if (option === "accelerator") values.accelerator = parseAccelerator(raw);
if (option === "count") values.count = parseInteger(raw, option, 1, 64);
if (option === "hours") values.hours = parseInteger(raw, option, 1, 720);
index += 1;
}
const missing = REQUIRED_INTENT_OPTIONS.filter((option) => values[option] === null);
if (missing.length > 0) {
if (environment.ECC_DRY_RUN === "1" || args.includes("--dry-run")) {
throw new Error(
`missing required rental intent option${missing.length === 1 ? "" : "s"}: `
+ missing.map((option) => `--${option}`).join(", ")
"Itô compute has no paper or dry-run success mode. No CLI operation was invoked."
);
}
return {
help: false,
command,
options: Object.freeze({
...values,
dryRun: values.dryRun || process.env.ECC_DRY_RUN === "1",
}),
};
}
function buildHandoffMessage(intent) {
const accelerator = intent.accelerator.toUpperCase();
return [
"[ECC sandbox-only compute handoff]",
`Source: ECC CLI. Need ${intent.count} × ${accelerator} for ${intent.hours} hours.`,
"Treat this as a read-only requirement for review.",
"Do not file an RFQ, request or accept a quote, place an order, approve funds, or contact a counterparty without a separate explicit human action in Itô.",
].join(" ");
}
function createEnvelope({ success, state, data, error }) {
return Object.freeze({
schemaVersion: SCHEMA_VERSION,
success,
state,
data,
error,
links: Object.freeze({ desk: DESK_URL }),
});
}
function createInvalidEnvelope(message) {
return createEnvelope({
success: false,
state: "invalid_request",
data: null,
error: Object.freeze({
code: "INVALID_ARGUMENT",
message,
}),
});
}
function defaultOpenUrl(url) {
let executable;
let args;
const testExecutable = process.env.NODE_ENV === "test"
? process.env.ECC_ITO_BROWSER_EXECUTABLE
: null;
if (testExecutable) {
if (process.platform === "win32" && /\.(?:bat|cmd)$/i.test(testExecutable)) {
executable = process.env.ComSpec || "cmd.exe";
args = ["/d", "/s", "/c", testExecutable, url];
} else {
executable = testExecutable;
args = [url];
}
} else if (process.platform === "darwin") {
executable = "open";
args = [url];
} else if (process.platform === "win32") {
executable = "cmd.exe";
args = ["/d", "/s", "/c", "start", "", url];
} else {
executable = "xdg-open";
args = [url];
const jsonIndexes = args
.map((value, index) => (value === "--json" ? index : -1))
.filter((index) => index >= 0);
if (jsonIndexes.length > 1) {
throw new Error("--json may only be provided once");
}
const withoutJson = args.filter((value) => value !== "--json");
const command = withoutJson.shift();
if (!SUPPORTED_COMMANDS.includes(command)) {
throw new Error(
`Unsupported Itô command "${command || "(missing)"}"; ECC permits only auth, find, and status.`
);
}
const result = spawnSync(executable, args, {
env: { ...createSafeItoEnvironment(process.env) },
stdio: "ignore",
windowsHide: true,
shell: false,
});
return !result.error && result.status === 0;
}
function createHandoff(options, openUrl = defaultOpenUrl) {
const shouldOpen = !options.dryRun && !options.noOpen;
const opened = shouldOpen ? openUrl(DESK_URL) : false;
const intent = Object.freeze({
accelerator: options.accelerator,
count: options.count,
hours: options.hours,
});
return createEnvelope({
success: true,
state: "manual_handoff",
data: Object.freeze({
authenticated: null,
dryRun: options.dryRun,
opened,
intent,
provenance: Object.freeze({
source: "ecc-cli",
command: "ecc ito rent",
}),
authority: Object.freeze({
environment: "sandbox",
readOnly: true,
liveRfq: false,
procurementMutation: false,
quoteAcceptance: false,
fundsApproval: false,
orderCreation: false,
outreach: false,
}),
handoff: Object.freeze({
transport: "manual_copy",
destination: "ito-desk",
acceptedByIto: false,
signInMayBeRequired: true,
message: buildHandoffMessage(intent),
limitation: "Itô /desk currently exposes no supported structured ECC intake or deep-link contract.",
}),
approvalGate: 'Stop before "Pay & buy".',
priceQuote: null,
orderId: null,
}),
error: null,
return Object.freeze({
help: false,
invocationArgs: Object.freeze([
...(jsonIndexes.length === 1 ? ["--json"] : []),
command,
...withoutJson,
]),
});
}
function renderText(payload) {
const { data } = payload;
const browserState = data.dryRun
? "Dry-run: browser not opened."
: data.opened
? "Opened the Itô desk; sign-in may be required."
: "Browser not opened; sign-in may be required at the Itô desk.";
return [
"ECC × Itô sandbox compute handoff",
"",
browserState,
`Desk: ${payload.links.desk}`,
"Transport: manual copy; Itô has not accepted this intent.",
`Message: ${data.handoff.message}`,
`Limitation: ${data.handoff.limitation}`,
`Approval gate: ${data.approvalGate}`,
"",
"ECC does not file an RFQ, request or accept a quote, use credentials, approve funds, create an order, or contact a counterparty.",
].join("\n");
function resolveItoExecutable(environment = process.env) {
const configured = environment[EXECUTABLE_OVERRIDE]?.trim();
if (!configured) {
throw new Error([
"The canonical ito-compute-cli is unpublished and ECC will not resolve",
`a credential-bearing "ito" executable from PATH. Build it from`,
`${CANONICAL_REPOSITORY.replace(/\.git$/, "")}/${CANONICAL_PACKAGE_PATH},`,
"run npm ci and npm run check, then set",
`${EXECUTABLE_OVERRIDE} to the explicit absolute dist/bin/ito.js path.`,
].join(" "));
}
if (!path.isAbsolute(configured)) {
throw new Error(
`${EXECUTABLE_OVERRIDE} must be an absolute path explicitly configured by the operator.`
);
}
return assertUsableExecutable(configured);
}
function main(argv = process.argv.slice(2), dependencies = {}) {
let parsed;
function assertUsableExecutable(candidate) {
let canonicalCandidate;
try {
parsed = parseArgs(argv);
canonicalCandidate = fs.realpathSync.native(candidate);
} catch {
throw new Error(
`${EXECUTABLE_OVERRIDE} does not point to a readable local Itô CLI file.`
);
}
if (!isUsableExecutable(canonicalCandidate)) {
throw new Error(
`${EXECUTABLE_OVERRIDE} does not point to a readable local Itô CLI file.`
);
}
return canonicalCandidate;
}
function isUsableExecutable(candidate) {
try {
const info = fs.statSync(candidate);
if (!info.isFile()) return false;
if (process.platform !== "win32" && path.extname(candidate) !== ".js") {
fs.accessSync(candidate, fs.constants.X_OK);
} else {
fs.accessSync(candidate, fs.constants.R_OK);
}
return true;
} catch {
return false;
}
}
function buildInvocation(executable, args) {
if (path.extname(executable).toLowerCase() === ".js") {
return Object.freeze({
executable: process.execPath,
args: Object.freeze([executable, ...args]),
});
}
if (
process.platform === "win32"
&& /\.(?:bat|cmd|ps1)$/i.test(executable)
) {
throw new Error(
`Refusing to invoke the Itô CLI through a shell shim. Set ${EXECUTABLE_OVERRIDE} to the absolute dist/bin/ito.js path.`
);
}
return Object.freeze({ executable, args: Object.freeze([...args]) });
}
function invokeIto(executable, args, environment = process.env) {
const invocation = buildInvocation(executable, args);
const result = spawnSync(invocation.executable, invocation.args, {
cwd: process.cwd(),
encoding: "utf8",
env: {
...createSafeItoEnvironment(environment, { includeItoRuntime: true }),
},
maxBuffer: MAX_OUTPUT_BYTES,
shell: false,
windowsHide: true,
});
if (result.stdout) process.stdout.write(result.stdout);
if (result.stderr) process.stderr.write(result.stderr);
if (result.error) {
throw new Error(`The local Itô CLI could not be started: ${result.error.message}`);
}
if (typeof result.status === "number") return result.status;
if (result.signal) {
throw new Error(`The local Itô CLI terminated by signal ${result.signal}.`);
}
return 1;
}
function main(argv = process.argv.slice(2), environment = process.env) {
try {
const parsed = parseArgs(argv, environment);
if (parsed.help) {
showHelp();
return 0;
}
const executable = resolveItoExecutable(environment);
return invokeIto(executable, parsed.invocationArgs, environment);
} catch (error) {
const payload = createInvalidEnvelope(error.message);
if (argv.includes("--json")) console.log(JSON.stringify(payload, null, 2));
else console.error(`Error: ${error.message}`);
console.error(`Error: ${error.message}`);
return 1;
}
if (parsed.help) {
showHelp();
return 0;
}
const payload = createHandoff(parsed.options, dependencies.openUrl);
if (parsed.options.json) console.log(JSON.stringify(payload, null, 2));
else console.log(renderText(payload));
return 0;
}
if (require.main === module) {
@ -309,13 +213,13 @@ if (require.main === module) {
}
module.exports = Object.freeze({
DESK_URL,
SCHEMA_VERSION,
buildHandoffMessage,
createHandoff,
createInvalidEnvelope,
CANONICAL_PACKAGE_PATH,
CANONICAL_REPOSITORY,
EXECUTABLE_OVERRIDE,
SUPPORTED_COMMANDS,
buildInvocation,
invokeIto,
main,
parseAccelerator,
parseArgs,
renderText,
resolveItoExecutable,
});

View file

@ -6,8 +6,11 @@ function getComputeSponsorCopy() {
return "Run or self-host any open-source model. Itô is ECC's preferred compute sponsor: "
+ 'open its dashboard to sign in and rent or manage GPUs at '
+ ITO_COMPUTE_URL
+ '. Any GPU provider works. ECC only provides this link; it does not provision '
+ 'compute or serving. Managed inference through Itô is not live yet.';
+ '. Any GPU provider works. This sponsorship link is passive: it does not invoke '
+ 'an RFQ, reserve capacity, provision compute, or configure serving. Separately, '
+ 'the opt-in "ecc ito find" bridge invokes the explicitly configured canonical '
+ 'Itô CLI and submits a live authenticated RFQ; it does not reserve capacity. '
+ 'Managed inference through Itô is not live yet.';
}
module.exports = Object.freeze({

View file

@ -23,6 +23,18 @@ const SYSTEM_ENVIRONMENT_KEYS = Object.freeze([
"XDG_RUNTIME_DIR",
]);
const ITO_RUNTIME_ENVIRONMENT_KEYS = Object.freeze([
"ITO_API_KEY",
"ITO_API_URL",
"ITO_INVENTORY_URL",
]);
const ECC_ITO_CONTROL_KEYS = Object.freeze([
"ECC_DRY_RUN",
"ECC_ITO_CLI_EXECUTABLE",
"NODE_ENV",
]);
function copyDefined(source, target, key) {
if (typeof source[key] === "string") {
target[key] = source[key];
@ -38,11 +50,15 @@ function createSafeItoEnvironment(source = process.env, options = {}) {
if (key.startsWith("LC_")) copyDefined(source, safe, key);
}
if (options.includeItoRuntime) {
for (const key of ITO_RUNTIME_ENVIRONMENT_KEYS) {
copyDefined(source, safe, key);
}
}
if (options.includeControls) {
copyDefined(source, safe, "ECC_DRY_RUN");
copyDefined(source, safe, "NODE_ENV");
if (source.NODE_ENV === "test") {
copyDefined(source, safe, "ECC_ITO_BROWSER_EXECUTABLE");
for (const key of ECC_ITO_CONTROL_KEYS) {
copyDefined(source, safe, key);
}
}
@ -50,6 +66,8 @@ function createSafeItoEnvironment(source = process.env, options = {}) {
}
module.exports = Object.freeze({
ECC_ITO_CONTROL_KEYS,
ITO_RUNTIME_ENVIRONMENT_KEYS,
SYSTEM_ENVIRONMENT_KEYS,
createSafeItoEnvironment,
});