llm-cli-gateway 1.15.1 → 1.15.3
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/CHANGELOG.md +54 -5
- package/README.md +10 -25
- package/dist/async-job-manager.js +1 -1
- package/dist/index.js +2 -2
- package/dist/job-store.js +1 -1
- package/package.json +1 -1
- package/socket.yml +6 -18
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,55 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to the llm-cli-gateway project.
|
|
4
4
|
|
|
5
|
+
## Unreleased
|
|
6
|
+
|
|
7
|
+
## [1.15.3] - 2026-05-29 — remove retired PyPI plugin
|
|
8
|
+
|
|
9
|
+
Patch release removing the retired Python `llm` plugin integration so the
|
|
10
|
+
project no longer depends on Simon Willison's `llm` package.
|
|
11
|
+
|
|
12
|
+
### Removed
|
|
13
|
+
|
|
14
|
+
- Removed `integrations/llm-plugin/`, including the `gateway-claude`,
|
|
15
|
+
`gateway-codex`, and `gateway-gemini` aliases that were registered through
|
|
16
|
+
the external `llm` package.
|
|
17
|
+
- Removed the PyPI trusted-publishing workflow. Releases now publish npm and
|
|
18
|
+
signed GitHub installer artifacts only.
|
|
19
|
+
- Removed the plugin-specific Dependabot and security-lint wiring for the
|
|
20
|
+
deleted Python package.
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- Removed README guidance that advertised `llm install llm-gateway` and
|
|
25
|
+
`llm -m gateway-*` usage.
|
|
26
|
+
- Added an archived PyPI retirement description explaining the supported npm
|
|
27
|
+
and direct-MCP install paths for users who discover the historical PyPI
|
|
28
|
+
package.
|
|
29
|
+
|
|
30
|
+
## [1.15.2] - 2026-05-29 — security quality follow-up
|
|
31
|
+
|
|
32
|
+
Patch release for GitHub Security & quality follow-up findings and Scorecard
|
|
33
|
+
documentation.
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
|
|
37
|
+
- Preserve the leading content when truncating async job stdout/stderr in
|
|
38
|
+
`llm_job_result`, matching bounded-result consumer expectations instead of
|
|
39
|
+
returning only the tail.
|
|
40
|
+
- Handle installer gateway log file close errors explicitly so failed flushes
|
|
41
|
+
from writable stdout/stderr log handles are surfaced to callers.
|
|
42
|
+
|
|
43
|
+
### Changed
|
|
44
|
+
|
|
45
|
+
- Moved non-canonical root Markdown into `docs/guides/` and `docs/archive/`
|
|
46
|
+
so the repository root stays focused on public entry points.
|
|
47
|
+
- Renamed async-defer result guidance from the old retrieval field to `collectWith`,
|
|
48
|
+
avoiding Socket substring false positives in generated package code.
|
|
49
|
+
- Recorded OpenSSF Scorecard `FuzzingID` as a valid roadmap/process item:
|
|
50
|
+
adding `fast-check` style property tests for parser, argv, and worktree
|
|
51
|
+
surfaces would improve the Scorecard signal, but the absence of fuzzing does
|
|
52
|
+
not block this patch release.
|
|
53
|
+
|
|
5
54
|
## [1.15.1] - 2026-05-29 — quality badges + Sigstore release signing
|
|
6
55
|
|
|
7
56
|
Release-infrastructure follow-up to v1.15.0.
|
|
@@ -1121,11 +1170,11 @@ Technical corrections from the multi-LLM voice + technical review:
|
|
|
1121
1170
|
|
|
1122
1171
|
### Fixed — `socket.yml` networkAccess false-positive documentation
|
|
1123
1172
|
|
|
1124
|
-
- Documented that
|
|
1125
|
-
`dist/job-store.js`
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
a code comment. Verified by sub-agent investigation, no code change
|
|
1173
|
+
- Documented that Socket's network-access flag on `dist/index.js` /
|
|
1174
|
+
`dist/job-store.js` was a substring-match false positive. Neither file
|
|
1175
|
+
contained a production network call; the matches were English-prose
|
|
1176
|
+
retrieval wording in an error message, a structured result-tool field name,
|
|
1177
|
+
and a code comment. Verified by sub-agent investigation, no code change
|
|
1129
1178
|
required, no attack-surface delta vs 1.5.35.
|
|
1130
1179
|
|
|
1131
1180
|
### Fixed — `lychee.toml` exclusions
|
package/README.md
CHANGED
|
@@ -3,7 +3,11 @@
|
|
|
3
3
|
[](https://github.com/verivus-oss/llm-cli-gateway/actions/workflows/ci.yml)
|
|
4
4
|
[](https://github.com/verivus-oss/llm-cli-gateway/actions/workflows/security.yml)
|
|
5
5
|
[](https://scorecard.dev/viewer/?uri=github.com/verivus-oss/llm-cli-gateway)
|
|
6
|
+
[](https://www.bestpractices.dev/projects/13025)
|
|
6
7
|
[](https://www.npmjs.com/package/llm-cli-gateway)
|
|
8
|
+
[](https://www.npmjs.com/package/llm-cli-gateway)
|
|
9
|
+
[](https://www.npmjs.com/package/llm-cli-gateway)
|
|
10
|
+
[](https://github.com/verivus-oss/llm-cli-gateway/releases)
|
|
7
11
|
[](LICENSE)
|
|
8
12
|
[](SECURITY.md#release-signing)
|
|
9
13
|
|
|
@@ -23,7 +27,7 @@ A Model Context Protocol (MCP) gateway for running Claude Code, Codex, Gemini, G
|
|
|
23
27
|
- Can run requests inside gateway-managed git worktrees for isolated multi-agent review and implementation loops.
|
|
24
28
|
- Ships personal-appliance setup surfaces: HTTP transport with bearer-token auth, `doctor --json`, setup UI artifacts, provider setup snippets, Docker fallback, and checked release bundles.
|
|
25
29
|
|
|
26
|
-
## Personal MCP Appliance
|
|
30
|
+
## Personal MCP Appliance
|
|
27
31
|
|
|
28
32
|
The personal-appliance contract keeps that surface intentionally narrow: one trusted user runs the gateway on a machine or volume they own, connects one MCP endpoint, and asks any connected client for cross-LLM validation.
|
|
29
33
|
|
|
@@ -31,7 +35,7 @@ The product contract is documented in [docs/personal-mcp/PRODUCT_CONTRACT.md](do
|
|
|
31
35
|
|
|
32
36
|
This project does not provide hosted multi-tenant credential custody. Provider credentials stay on the user's machine or user-owned deployment volume.
|
|
33
37
|
|
|
34
|
-
|
|
38
|
+
Release-readiness history is tracked in [docs/personal-mcp/RELEASE_READINESS.md](docs/personal-mcp/RELEASE_READINESS.md). Dogfooding evidence (which target LLMs guided setup, what unsafe suggestions were captured, and which findings were deferred from the initial personal-appliance rollout) is in [docs/personal-mcp/DOGFOODING_RESULTS.md](docs/personal-mcp/DOGFOODING_RESULTS.md).
|
|
35
39
|
|
|
36
40
|
Current personal-appliance artifacts include:
|
|
37
41
|
|
|
@@ -172,7 +176,7 @@ Opt-in flags (all default off) live under `[cache_awareness]` in `~/.llm-cli-gat
|
|
|
172
176
|
- **No Secret Leakage**: Generic session descriptions only (file permissions 0o600)
|
|
173
177
|
- **No ReDoS**: Bounded regex patterns prevent catastrophic backtracking
|
|
174
178
|
- **Type Safety**: Strict TypeScript with comprehensive error handling
|
|
175
|
-
- **Supply-chain hardening**: a dedicated `.github/workflows/security.yml` runs actionlint, zizmor, shellcheck, typos, osv-scanner, gitleaks,
|
|
179
|
+
- **Supply-chain hardening**: a dedicated `.github/workflows/security.yml` runs actionlint, zizmor, shellcheck, typos, osv-scanner, gitleaks, and lychee on every push and PR (see `SECURITY.md` for the threat model)
|
|
176
180
|
|
|
177
181
|
## Prerequisites
|
|
178
182
|
|
|
@@ -287,7 +291,7 @@ For clients that already support local stdio MCP servers, add a configuration li
|
|
|
287
291
|
}
|
|
288
292
|
```
|
|
289
293
|
|
|
290
|
-
This generic stdio example is not provider-support verification for the Personal MCP Appliance
|
|
294
|
+
This generic stdio example is not provider-support verification for the Personal MCP Appliance. Client-specific setup guides for ChatGPT, Claude web, Claude Desktop, Codex, Gemini CLI, Gemini web, and Grok remain gated by the provider-support matrix in [docs/personal-mcp/PRODUCT_CONTRACT.md](docs/personal-mcp/PRODUCT_CONTRACT.md).
|
|
291
295
|
|
|
292
296
|
### Available Tools
|
|
293
297
|
|
|
@@ -460,7 +464,7 @@ Execute a Grok CLI (xAI) request with session support.
|
|
|
460
464
|
Every async job is persisted to a job store as it transitions through running → completed/failed/canceled. This makes the gateway a durable collection layer:
|
|
461
465
|
|
|
462
466
|
- **Re-issuing a request is safe.** Identical `*_request` / `*_request_async` calls within the dedup window (default 1 hour) short-circuit onto the existing running or completed job — the caller gets back the same job ID instead of starting a duplicate run. This directly fixes the "agent times out polling, re-issues, and the whole job starts over" failure mode.
|
|
463
|
-
- **`llm_job_status` and `llm_job_result` work across gateway restarts.** Job rows live for 30 days by default; callers can
|
|
467
|
+
- **`llm_job_status` and `llm_job_result` work across gateway restarts.** Job rows live for 30 days by default; callers can collect results long after the in-memory cache has evicted them.
|
|
464
468
|
- **Jobs running at shutdown are marked `orphaned`** on the next gateway boot (the detached child can't be reattached to). Their captured partial output remains readable.
|
|
465
469
|
- **Pass `forceRefresh: true`** on any request tool to bypass dedup and force a fresh CLI run.
|
|
466
470
|
|
|
@@ -537,7 +541,7 @@ template_kind = "implementation-dag"
|
|
|
537
541
|
docs = "https://github.com/verivus-oss/agent-assurance/blob/main/SPEC.md"
|
|
538
542
|
confidentiality = "public"
|
|
539
543
|
title = "Per-project llm-cli-gateway persistence isolation"
|
|
540
|
-
spec = "https://github.com/
|
|
544
|
+
spec = "https://github.com/verivus-oss/llm-cli-gateway#per-project-isolation"
|
|
541
545
|
created = "YYYY-MM-DD"
|
|
542
546
|
total_units = 5
|
|
543
547
|
tier1_units = ["U01","U02","U03","U04","U05"]
|
|
@@ -966,25 +970,6 @@ Each CLI can be configured through its own configuration files:
|
|
|
966
970
|
- Codex: `~/.codex/config.toml`
|
|
967
971
|
- Gemini: `~/.gemini/config.json`
|
|
968
972
|
|
|
969
|
-
## For Fans of Simon Willison
|
|
970
|
-
|
|
971
|
-
Simon's `llm` tool made it trivially easy to talk to any LLM from the command line. But as AI-assisted development matures, the challenge shifts from "how do I call a model" to "how do I orchestrate multiple models reliably, and what did they actually do?"
|
|
972
|
-
|
|
973
|
-
**Multiple models increase the confidence factor.** When Claude writes code, Codex reviews it, and Gemini checks for bugs -- each bringing different training data and reasoning patterns -- the result is more robust than any single model alone. And often this isn't even enough. Having the models do iterative reviews is where you start getting real confidence.
|
|
974
|
-
|
|
975
|
-
**Every interaction should be queryable data.** Inspired by `llm`'s SQLite logging philosophy, the gateway records every request and response to a local SQLite database. Not just prompts and responses -- retry counts, circuit breaker states, approval decisions, thinking blocks, cost estimates. Open it with Datasette and you have a complete operational picture of your AI usage:
|
|
976
|
-
|
|
977
|
-
datasette ~/.llm-cli-gateway/logs.db
|
|
978
|
-
|
|
979
|
-
**The `llm-gateway` plugin bridges both worlds.** Install it, and your existing `llm` workflows gain orchestration features without changing how you work:
|
|
980
|
-
|
|
981
|
-
llm install llm-gateway
|
|
982
|
-
llm -m gateway-claude "explain this function"
|
|
983
|
-
|
|
984
|
-
Your gateway interactions appear in both `llm logs` (for your personal history) and the gateway's flight recorder (for operational observability). Two audiences, one workflow.
|
|
985
|
-
|
|
986
|
-
**Composability over monoliths.** The gateway doesn't replace `llm` -- it complements it. Use `llm` directly when you want simplicity. Route through the gateway when you want resilience, multi-model coordination, or detailed operational telemetry. The plugin is the bridge, not the destination.
|
|
987
|
-
|
|
988
973
|
## Development
|
|
989
974
|
|
|
990
975
|
### Project Structure
|
package/dist/index.js
CHANGED
|
@@ -486,7 +486,7 @@ cwd) {
|
|
|
486
486
|
jobId: job.id,
|
|
487
487
|
cli,
|
|
488
488
|
correlationId: corrId,
|
|
489
|
-
message: `Execution exceeded sync deadline (${SYNC_DEADLINE_MS}ms). Poll with llm_job_status,
|
|
489
|
+
message: `Execution exceeded sync deadline (${SYNC_DEADLINE_MS}ms). Poll with llm_job_status, collect with llm_job_result.`,
|
|
490
490
|
};
|
|
491
491
|
}
|
|
492
492
|
function isDeferredResponse(result) {
|
|
@@ -505,7 +505,7 @@ function buildDeferredToolResponse(deferred, sessionId) {
|
|
|
505
505
|
message: deferred.message,
|
|
506
506
|
sessionId: sessionId || null,
|
|
507
507
|
pollWith: "llm_job_status",
|
|
508
|
-
|
|
508
|
+
collectWith: "llm_job_result",
|
|
509
509
|
cancelWith: "llm_job_cancel",
|
|
510
510
|
}, null, 2),
|
|
511
511
|
},
|
package/dist/job-store.js
CHANGED
|
@@ -245,7 +245,7 @@ export class SqliteJobStore {
|
|
|
245
245
|
*/
|
|
246
246
|
markOrphanedOnStartup() {
|
|
247
247
|
const now = new Date().toISOString();
|
|
248
|
-
// Orphaned jobs retain a short window so callers can
|
|
248
|
+
// Orphaned jobs retain a short window so callers can collect the partial output,
|
|
249
249
|
// then evict. Reuse the standard retention.
|
|
250
250
|
const expiresAt = new Date(Date.now() + this.retentionMs).toISOString();
|
|
251
251
|
// SELECT before UPDATE — gateway boot is single-threaded so no row can
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "llm-cli-gateway",
|
|
3
|
-
"version": "1.15.
|
|
3
|
+
"version": "1.15.3",
|
|
4
4
|
"mcpName": "io.github.verivus-oss/llm-cli-gateway",
|
|
5
5
|
"description": "MCP server providing unified access to Claude Code, Codex, Gemini, Grok, and Mistral Vibe CLIs with session management, retry logic, async job orchestration, durable job results, and cross-LLM validation.",
|
|
6
6
|
"license": "MIT",
|
package/socket.yml
CHANGED
|
@@ -14,24 +14,12 @@ version: 2
|
|
|
14
14
|
# src/endpoint-exposure.ts also issues a HEAD probe when verifying
|
|
15
15
|
# tunnel reachability — opt-in via the start:http entry point only.
|
|
16
16
|
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
# - dist/index.js — the English word "fetch" inside an async-defer
|
|
24
|
-
# error message ("Poll with llm_job_status, fetch with
|
|
25
|
-
# llm_job_result.") AND the JSON field name `fetchWith:
|
|
26
|
-
# "llm_job_result"` (part of the deferred-job response contract).
|
|
27
|
-
# - dist/job-store.js — the word "fetch" inside a code comment on
|
|
28
|
-
# markOrphanedOnStartup() describing how callers retrieve partial
|
|
29
|
-
# output from SQLite.
|
|
30
|
-
# Verify with: `grep -rEn "\bfetch\(|globalThis\.fetch|globalThis\[" dist/`
|
|
31
|
-
# — returns empty. Production code does not import undici / node-fetch
|
|
32
|
-
# / axios / got. The cache-awareness slice (v1.6.0) introduced zero
|
|
33
|
-
# new network surfaces; all I/O is filesystem (SQLite, sessions.json)
|
|
34
|
-
# or in-process.
|
|
17
|
+
# Historical note: Socket previously flagged `dist/index.js` and
|
|
18
|
+
# `dist/job-store.js` because async-job prose used retrieval wording that
|
|
19
|
+
# resembled a browser-network primitive. The package now uses "collect" /
|
|
20
|
+
# `collectWith` wording for deferred job results. Production code does not
|
|
21
|
+
# import bundled HTTP client libraries; all default I/O is filesystem
|
|
22
|
+
# (SQLite, sessions.json) or explicit local CLI process I/O.
|
|
35
23
|
#
|
|
36
24
|
# shellAccess
|
|
37
25
|
# src/executor.ts uses child_process.spawn(cmd, args, { ... }) with a
|