modelmux-cli 0.0.0-stage → 0.3.0
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/LICENSE +202 -0
- package/README.md +24 -2
- package/dist/_shared/providers/claude.json +34 -0
- package/dist/_shared/providers/codex.json +35 -0
- package/dist/_shared/release.json +4 -0
- package/dist/_shared/schema/provider.schema.json +81 -0
- package/dist/_shared/templates/compose-service.json +12 -0
- package/dist/_shared/templates/config/curl.json +8 -0
- package/dist/_shared/templates/config/env.json +8 -0
- package/dist/_shared/templates/config/langchain.json +8 -0
- package/dist/_shared/templates/config/litellm.json +8 -0
- package/dist/_shared/templates/config/openai-python.json +8 -0
- package/dist/args.js +422 -0
- package/dist/bin.js +4 -0
- package/dist/browser.js +51 -0
- package/dist/cli.js +60 -0
- package/dist/clientconfig.js +89 -0
- package/dist/commands/basic.js +72 -0
- package/dist/commands/configCmd.js +62 -0
- package/dist/commands/doctor.js +194 -0
- package/dist/commands/login.js +185 -0
- package/dist/commands/logout.js +57 -0
- package/dist/commands/up.js +204 -0
- package/dist/commands/upgrade.js +46 -0
- package/dist/config.js +97 -0
- package/dist/console.js +93 -0
- package/dist/context.js +36 -0
- package/dist/docker.js +294 -0
- package/dist/errors.js +49 -0
- package/dist/files.js +45 -0
- package/dist/health.js +78 -0
- package/dist/interrupt.js +43 -0
- package/dist/main.js +85 -0
- package/dist/paths.js +51 -0
- package/dist/ports.js +25 -0
- package/dist/prompt.js +69 -0
- package/dist/providers.js +178 -0
- package/dist/redact.js +33 -0
- package/dist/release.js +52 -0
- package/dist/secretsStore.js +61 -0
- package/dist/stack.js +220 -0
- package/dist/terminal.js +46 -0
- package/dist/text.js +40 -0
- package/dist/updates.js +59 -0
- package/dist/version.js +15 -0
- package/package.json +41 -4
package/dist/text.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** Python-compatible formatting, so messages match the Python CLI exactly. */
|
|
2
|
+
/** Python's `repr()` of a string: 'value' (or "value" if it contains only '). */
|
|
3
|
+
export function repr(value) {
|
|
4
|
+
const quote = value.includes("'") && !value.includes('"') ? '"' : "'";
|
|
5
|
+
let out = "";
|
|
6
|
+
for (const ch of value) {
|
|
7
|
+
const code = ch.codePointAt(0) ?? 0;
|
|
8
|
+
if (ch === "\\")
|
|
9
|
+
out += "\\\\";
|
|
10
|
+
else if (ch === quote)
|
|
11
|
+
out += `\\${ch}`;
|
|
12
|
+
else if (ch === "\n")
|
|
13
|
+
out += "\\n";
|
|
14
|
+
else if (ch === "\r")
|
|
15
|
+
out += "\\r";
|
|
16
|
+
else if (ch === "\t")
|
|
17
|
+
out += "\\t";
|
|
18
|
+
else if (code < 0x20 || code === 0x7f)
|
|
19
|
+
out += `\\x${code.toString(16).padStart(2, "0")}`;
|
|
20
|
+
else
|
|
21
|
+
out += ch;
|
|
22
|
+
}
|
|
23
|
+
return quote + out + quote;
|
|
24
|
+
}
|
|
25
|
+
/** Python's `shlex.quote()`. */
|
|
26
|
+
export function shellQuote(value) {
|
|
27
|
+
if (value === "")
|
|
28
|
+
return "''";
|
|
29
|
+
if (/^[\w@%+=:,./-]+$/.test(value))
|
|
30
|
+
return value;
|
|
31
|
+
return "'" + value.replaceAll("'", `'"'"'`) + "'";
|
|
32
|
+
}
|
|
33
|
+
/** Python's `shlex.join()`. */
|
|
34
|
+
export function shellJoin(args) {
|
|
35
|
+
return args.map(shellQuote).join(" ");
|
|
36
|
+
}
|
|
37
|
+
/** Sorted copy of string keys, like Python's `sorted()` on str (code point order). */
|
|
38
|
+
export function sortedStrings(values) {
|
|
39
|
+
return [...values].sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
|
|
40
|
+
}
|
package/dist/updates.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Network checks used only by `doctor` and `upgrade` (never in the background).
|
|
3
|
+
*
|
|
4
|
+
* Node honours the usual proxy variables (HTTPS_PROXY / NO_PROXY) for these
|
|
5
|
+
* requests when NODE_USE_ENV_PROXY=1 is set.
|
|
6
|
+
*/
|
|
7
|
+
export const PACKAGE = "modelmux-cli";
|
|
8
|
+
export const NPM_URL = `https://registry.npmjs.org/${PACKAGE}/latest`;
|
|
9
|
+
export const REGISTRY_URL = "https://ghcr.io/v2/";
|
|
10
|
+
export const UPGRADE_HINT = `npm install -g ${PACKAGE}@latest (or: npx ${PACKAGE}@latest)`;
|
|
11
|
+
const RELEASE = /^\d+(\.\d+)*$/;
|
|
12
|
+
/** Plain releases only ("1.2.3"); pre-releases and build metadata are ignored. */
|
|
13
|
+
export function parseVersion(value) {
|
|
14
|
+
return RELEASE.test(value) ? value.split(".").map(Number) : null;
|
|
15
|
+
}
|
|
16
|
+
/** Python's tuple comparison: element by element, then the longer one wins. */
|
|
17
|
+
function compare(a, b) {
|
|
18
|
+
for (let i = 0; i < Math.min(a.length, b.length); i++) {
|
|
19
|
+
if (a[i] !== b[i])
|
|
20
|
+
return a[i] - b[i];
|
|
21
|
+
}
|
|
22
|
+
return a.length - b.length;
|
|
23
|
+
}
|
|
24
|
+
/** The newest modelmux-cli on npm, or null if it cannot be checked. */
|
|
25
|
+
async function fetchLatestVersion(timeout = 5.0) {
|
|
26
|
+
try {
|
|
27
|
+
const response = await fetch(NPM_URL, { signal: AbortSignal.timeout(timeout * 1000) });
|
|
28
|
+
if (!response.ok)
|
|
29
|
+
return null;
|
|
30
|
+
const data = await response.json();
|
|
31
|
+
const version = typeof data === "object" && data !== null ? data.version : null;
|
|
32
|
+
return typeof version === "string" ? version : null;
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export function newerAvailable(current, latest) {
|
|
39
|
+
if (latest === null)
|
|
40
|
+
return false;
|
|
41
|
+
const now = parseVersion(current);
|
|
42
|
+
const next = parseVersion(latest);
|
|
43
|
+
return now !== null && next !== null && compare(next, now) > 0;
|
|
44
|
+
}
|
|
45
|
+
/** Can we reach the image registry? Any HTTP answer (even 401) counts. */
|
|
46
|
+
async function isRegistryReachable(timeout = 5.0) {
|
|
47
|
+
try {
|
|
48
|
+
await fetch(REGISTRY_URL, { signal: AbortSignal.timeout(timeout * 1000) });
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/** The network checks. Replaceable in tests. */
|
|
56
|
+
export const registry = {
|
|
57
|
+
latestVersion: fetchLatestVersion,
|
|
58
|
+
registryReachable: isRegistryReachable,
|
|
59
|
+
};
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** This package's version, from package.json (one level above src/ and dist/). */
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
function readVersion() {
|
|
6
|
+
try {
|
|
7
|
+
const file = path.join(path.dirname(fileURLToPath(import.meta.url)), "..", "package.json");
|
|
8
|
+
const data = JSON.parse(readFileSync(file, "utf8"));
|
|
9
|
+
return typeof data.version === "string" ? data.version : "0.0.0";
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return "0.0.0";
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export const VERSION = readVersion();
|
package/package.json
CHANGED
|
@@ -1,6 +1,43 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "modelmux-cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Set up, log in to and run ModelMux: AI coding CLIs as an OpenAI-compatible API",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"modelmux": "dist/bin.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=22"
|
|
15
|
+
},
|
|
16
|
+
"homepage": "https://github.com/smit153/modelmux",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/smit153/modelmux.git",
|
|
20
|
+
"directory": "cli/node"
|
|
21
|
+
},
|
|
22
|
+
"bugs": "https://github.com/smit153/modelmux/issues",
|
|
23
|
+
"keywords": [
|
|
24
|
+
"claude-code",
|
|
25
|
+
"codex",
|
|
26
|
+
"openai",
|
|
27
|
+
"docker",
|
|
28
|
+
"cli"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "node scripts/build.mjs clean && tsc -p tsconfig.build.json && node scripts/build.mjs shared",
|
|
32
|
+
"typecheck": "tsc -p tsconfig.json",
|
|
33
|
+
"test": "node --test \"test/**/*.test.ts\"",
|
|
34
|
+
"prepack": "npm run build"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/node": "^22.20.5",
|
|
38
|
+
"typescript": "^7.0.2"
|
|
39
|
+
},
|
|
40
|
+
"publishConfig": {
|
|
41
|
+
"access": "public"
|
|
42
|
+
}
|
|
43
|
+
}
|