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 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 the `globalThis["fetch"]` flag on `dist/index.js` /
1125
- `dist/job-store.js` is a substring-match false positive. Neither file
1126
- contains any actual fetch call; the matches are English-prose
1127
- occurrences in an error message, the `fetchWith` JSON field name, and
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
  [![CI](https://github.com/verivus-oss/llm-cli-gateway/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/verivus-oss/llm-cli-gateway/actions/workflows/ci.yml)
4
4
  [![Security](https://github.com/verivus-oss/llm-cli-gateway/actions/workflows/security.yml/badge.svg?branch=main)](https://github.com/verivus-oss/llm-cli-gateway/actions/workflows/security.yml)
5
5
  [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/verivus-oss/llm-cli-gateway/badge)](https://scorecard.dev/viewer/?uri=github.com/verivus-oss/llm-cli-gateway)
6
+ [![OpenSSF Best Practices](https://www.bestpractices.dev/projects/13025/badge)](https://www.bestpractices.dev/projects/13025)
6
7
  [![npm](https://img.shields.io/npm/v/llm-cli-gateway.svg)](https://www.npmjs.com/package/llm-cli-gateway)
8
+ [![npm weekly downloads](https://img.shields.io/npm/dw/llm-cli-gateway.svg)](https://www.npmjs.com/package/llm-cli-gateway)
9
+ [![npm monthly downloads](https://img.shields.io/npm/dm/llm-cli-gateway.svg)](https://www.npmjs.com/package/llm-cli-gateway)
10
+ [![GitHub release downloads](https://img.shields.io/github/downloads/verivus-oss/llm-cli-gateway/total.svg)](https://github.com/verivus-oss/llm-cli-gateway/releases)
7
11
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
8
12
  [![Releases: Sigstore signed](https://img.shields.io/badge/releases-Sigstore%20signed-2e7d32.svg)](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 MVP
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
- MVP release readiness 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, which findings are deferred to post-MVP work) is in [docs/personal-mcp/DOGFOODING_RESULTS.md](docs/personal-mcp/DOGFOODING_RESULTS.md).
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, ruff, bandit, and lychee on every push and PR (see `SECURITY.md` for the threat model)
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 MVP. 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).
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 fetch results long after the in-memory cache has evicted them.
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/verivusai-labs/llm-cli-gateway#per-project-isolation"
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
@@ -51,7 +51,7 @@ function truncateText(value, maxChars) {
51
51
  return { text: value, truncated: false };
52
52
  }
53
53
  return {
54
- text: value.slice(value.length - maxChars),
54
+ text: value.slice(0, maxChars),
55
55
  truncated: true,
56
56
  };
57
57
  }
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, fetch with llm_job_result.`,
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
- fetchWith: "llm_job_result",
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 fetch the partial output,
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.1",
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
- # Additionally, Socket may flag `dist/index.js` and `dist/job-store.js`
18
- # against the `globalThis["fetch"]` rule. This is a substring-match
19
- # false positive (verified for v1.6.0 by sub-agent investigation on
20
- # 2026-05-26; same matches exist in v1.5.35). Neither file contains
21
- # any `fetch(`, `globalThis.fetch`, polyfill import, or any other
22
- # network-call construct. The matches are:
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