umans-gate 0.1.2 → 0.1.4

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.
Files changed (58) hide show
  1. package/CHANGELOG.md +154 -0
  2. package/README.md +165 -45
  3. package/npm-shim.cjs +71 -0
  4. package/package.json +16 -80
  5. package/dashboard/dist/assets/alert-dialog-DlhAyxD3.js +0 -2
  6. package/dashboard/dist/assets/alert-dialog-DlhAyxD3.js.map +0 -1
  7. package/dashboard/dist/assets/clear-confirm-dialog-BOcl93wD.js +0 -2
  8. package/dashboard/dist/assets/clear-confirm-dialog-BOcl93wD.js.map +0 -1
  9. package/dashboard/dist/assets/config-tab-pnBjiSyC.js +0 -4
  10. package/dashboard/dist/assets/config-tab-pnBjiSyC.js.map +0 -1
  11. package/dashboard/dist/assets/economics-tab-BJXa5ydD.js +0 -2
  12. package/dashboard/dist/assets/economics-tab-BJXa5ydD.js.map +0 -1
  13. package/dashboard/dist/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  14. package/dashboard/dist/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  15. package/dashboard/dist/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  16. package/dashboard/dist/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  17. package/dashboard/dist/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  18. package/dashboard/dist/assets/headers-viewer-C9FKdG-_.js +0 -2
  19. package/dashboard/dist/assets/headers-viewer-C9FKdG-_.js.map +0 -1
  20. package/dashboard/dist/assets/index-72wCsW4_.js +0 -3
  21. package/dashboard/dist/assets/index-72wCsW4_.js.map +0 -1
  22. package/dashboard/dist/assets/index-DFhG4t-C.css +0 -1
  23. package/dashboard/dist/assets/json-viewer-CXkZMoVn.js +0 -2
  24. package/dashboard/dist/assets/json-viewer-CXkZMoVn.js.map +0 -1
  25. package/dashboard/dist/assets/mode-toggle-BxkGFiYG.js +0 -2
  26. package/dashboard/dist/assets/mode-toggle-BxkGFiYG.js.map +0 -1
  27. package/dashboard/dist/assets/models-tab-Deqk3WT3.js +0 -2
  28. package/dashboard/dist/assets/models-tab-Deqk3WT3.js.map +0 -1
  29. package/dashboard/dist/assets/performance-meter-Bd152C4C.js +0 -2
  30. package/dashboard/dist/assets/performance-meter-Bd152C4C.js.map +0 -1
  31. package/dashboard/dist/assets/select-mZPf2BR3.js +0 -2
  32. package/dashboard/dist/assets/select-mZPf2BR3.js.map +0 -1
  33. package/dashboard/dist/assets/sheet-BgQXtbdw.js +0 -2
  34. package/dashboard/dist/assets/sheet-BgQXtbdw.js.map +0 -1
  35. package/dashboard/dist/assets/sonner-DGu1DGeO.js +0 -2
  36. package/dashboard/dist/assets/sonner-DGu1DGeO.js.map +0 -1
  37. package/dashboard/dist/assets/sse-viewer-BHnn3FcY.js +0 -3
  38. package/dashboard/dist/assets/sse-viewer-BHnn3FcY.js.map +0 -1
  39. package/dashboard/dist/assets/use-capture-done-listener-u5RxfYQP.js +0 -2
  40. package/dashboard/dist/assets/use-capture-done-listener-u5RxfYQP.js.map +0 -1
  41. package/dashboard/dist/assets/use-models-B4MLkfpt.js +0 -2
  42. package/dashboard/dist/assets/use-models-B4MLkfpt.js.map +0 -1
  43. package/dashboard/dist/assets/use-polling-resource-D_vWHFwW.js +0 -2
  44. package/dashboard/dist/assets/use-polling-resource-D_vWHFwW.js.map +0 -1
  45. package/dashboard/dist/assets/vendor-CVKsgXJU.js +0 -312
  46. package/dashboard/dist/assets/vendor-CVKsgXJU.js.map +0 -1
  47. package/dashboard/dist/assets/vendor-DtX4s2-2.css +0 -1
  48. package/dashboard/dist/assets/vendor-react-Dtud3GyP.js +0 -41
  49. package/dashboard/dist/assets/vendor-react-Dtud3GyP.js.map +0 -1
  50. package/dashboard/dist/assets/vision-calls-BquNiDzm.js +0 -3
  51. package/dashboard/dist/assets/vision-calls-BquNiDzm.js.map +0 -1
  52. package/dashboard/dist/index.html +0 -34
  53. package/dist/cli.d.ts +0 -1
  54. package/dist/cli.js +0 -6788
  55. package/dist/cli.js.map +0 -1
  56. package/dist/index.d.ts +0 -1094
  57. package/dist/index.js +0 -6443
  58. package/dist/index.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,160 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.1.4] - 2026-07-14
11
+
12
+ ### Changed
13
+
14
+ - **npm package naming**: platform binary packages renamed from unscoped
15
+ `umans-gate-<target>` to scoped `@codegiveness/umans-gate-<target>`
16
+ (e.g. `@codegiveness/umans-gate-darwin-arm64`). This follows the
17
+ industry convention used by `@esbuild/*`, `@rollup/rollup-*`, and
18
+ `@swc/core-*` for platform-specific binary packages. The main package
19
+ `umans-gate` is unchanged — `optionalDependencies` now reference the
20
+ scoped packages.
21
+ - **npm-shim.cjs**: updated binary resolution paths to find
22
+ `@codegiveness/umans-gate-<target>` in `node_modules/@codegiveness/`.
23
+ - **pack-npm.sh**: main package now includes README.md, LICENSE, and
24
+ CHANGELOG.md in the published files so npm registry pages display
25
+ the current README. Added keywords, homepage, and bugs fields to
26
+ the generated package.json.
27
+ - **Release workflow**: publish step globs updated to
28
+ `release/npm/@codegiveness/umans-gate-*/`.
29
+
30
+ ### Fixed
31
+
32
+ - **Release workflow awk extraction**: the awk command extracting per-version
33
+ release notes from CHANGELOG.md self-terminated on the matching header line,
34
+ producing only `## [VERSION] - DATE` as release notes. Fixed with corrected
35
+ awk logic that extracts the full version section body.
36
+ - **CodeQL workflow efficiency**: added `paths-ignore` for markdown, docs, and
37
+ LICENSE files — CodeQL no longer runs on doc-only changes (matching CI
38
+ workflow behavior).
39
+ - **CI workflow professionalization**: split monolithic CI into `quality` job
40
+ (typecheck + lint + build, 3-OS matrix: ubuntu/macos/windows) and `test` job
41
+ (ubuntu-only). Dropped Bun 1.1.0 from matrix (caused 158 test failures on
42
+ ubuntu). Added dashboard asset build step before tests (`src/embedded-assets.ts`
43
+ has static imports to gitignored `dashboard/dist/`). Replaced fragile
44
+ `sleep(900)` in test helper with health-check polling (`GET /health`).
45
+ Added `--timeout 30000` to test command (bunfig.toml `timeout` key is not
46
+ respected by Bun).
47
+ - **Stuck master CI runs**: `cancel-in-progress` was only enabled for
48
+ `pull_request` events — a stuck `in_progress` run held the concurrency
49
+ group lock indefinitely, blocking all master push runs (stayed `pending`
50
+ with 0 jobs). Fixed: `cancel-in-progress: true` for all events.
51
+ - **CI permissions hardening**: added `permissions: contents: read`
52
+ (least-privilege) and `timeout-minutes: 15` to both CI jobs.
53
+ - **Dependabot hardening**: configured major-version bump ignores for
54
+ critical dependencies (commander, lru-cache, @types/bun, react, react-dom,
55
+ lucide-react, @types/react, @types/react-dom, vite, tailwind-merge, sonner,
56
+ typescript, @vitejs/plugin-react, @base-ui/react). Closed 13 dangerous
57
+ major-bump PRs.
58
+ - **Release workflow**: `--notes-file CHANGELOG.md` dumped the entire
59
+ changelog as release notes — now extracts only the matching version
60
+ section. Added `--frozen-lockfile` to all `bun install` steps. Added
61
+ `timeout-minutes: 20` to prevent hung release builds.
62
+ - **Test helper singleton race condition**: `echo-upstream.ts` used a
63
+ module-level singleton server that would break under parallel test
64
+ execution. Refactored to per-instance servers with explicit lifecycle
65
+ management.
66
+ - **CI dependency drift**: added `--frozen-lockfile` to all `bun install`
67
+ steps in CI to fail fast on lockfile drift.
68
+ - **Stale draft releases**: deleted 5 stale draft releases from failed
69
+ release workflow runs.
70
+
71
+ ### Added
72
+
73
+ - **Branch protection** on master: requires 4 CI checks (Quality
74
+ ubuntu/macos/windows + Tests), 1 code-owner review, linear history,
75
+ stale review dismissal, no force pushes.
76
+ - **Repo settings professionalized**: squash-only merges, delete-branch-on-merge,
77
+ wiki disabled, discussions disabled, secret scanning enabled, push protection
78
+ enabled.
79
+ - **CODEOWNERS** (`.github/CODEOWNERS`) for automated review routing.
80
+ - **Dependabot update grouping**: minor and patch updates are now grouped into
81
+ a single PR per ecosystem (root npm, dashboard npm) to reduce PR noise.
82
+
83
+ ### Changed
84
+
85
+ - **ROADMAP**: updated Current State from v0.1.0 → v0.1.3 with npm distribution,
86
+ self-update, platform binaries, and provenance as completed items. Added
87
+ umans-open-stack cross-reference section.
88
+ - **CONTRIBUTING.md / GOVERNANCE.md**: fixed `main` → `master` branch references.
89
+ - **PRODUCT.md**: repositioned from "Bun-based" to "npm-installable (powered by Bun)"
90
+ with npm-first success criteria.
91
+ - **TROUBLESHOOTING.md**: added npm-first user commands alongside dev commands.
92
+ - **bug_report.yml**: added install method field (npm/npx/standalone/source); Bun
93
+ version now conditional on dev-from-source only.
94
+ - **ci.yml**: removed stale `main` from branch triggers (only `master` exists).
95
+ - **package.json keywords**: expanded from 10 → 18 keywords for npm discoverability
96
+ (added `claude`, `prompt-engineering`, `observability`, `sqlite`, `bun`,
97
+ `developer-tools`, `api-proxy`, `prompt-caching`).
98
+ - **ARCHITECTURE.md**: added umans-open-stack cross-reference with
99
+ playbook-to-implementation mapping table.
100
+
101
+ ### Security
102
+
103
+ - **SECURITY.md**: added account security section — 2FA requirement for npm
104
+ publisher + GitHub org admins, token rotation policy, quarterly access review.
105
+
106
+ ## [0.1.3] - 2026-07-14
107
+
108
+ ### Fixed
109
+
110
+ - **npm package republish**: v0.1.2 was published via the now-deleted
111
+ `publish.yml` workflow (raw `npm publish` on repo `package.json`), which
112
+ shipped `dist/cli.js` with a `#!/usr/bin/env bun` shebang and `engines: { bun:
113
+ ">=1.1.0" }` — **requiring Bun to run**. This contradicted the "no
114
+ prerequisites" promise. v0.1.3 republishes via `release.yml` which runs
115
+ `scripts/pack-npm.sh` to produce the correct shim-based package (`bin:
116
+ npm-shim.cjs` + 6 platform `optionalDependencies` with pre-compiled
117
+ standalone binaries). `npx umans-gate` now works without Bun installed.
118
+ - **ARCHITECTURE.md**: fixed wrong file paths in umans-open-stack mapping table
119
+ (`src/gate.ts` → `src/limiter/gate.ts`, `src/vision.ts` → `src/vision/handoff.ts`).
120
+ - **README.md**: removed misleading `.env.example` reference (file only has
121
+ `UMANS_API_KEY=`; reworded to reference config variables generally).
122
+ - **README.md**: fixed `vision_*` incorrectly listed as hot-reloadable — moved
123
+ to `restartRequired` (matches `RESTART_REQUIRED_FIELDS` in `src/config.ts`).
124
+ - **SECURITY.md**: softened "SLSA Level 3 provenance" to "npm provenance
125
+ attestation" for accuracy and consistency with ROADMAP.md.
126
+ - **docs/proxy-modifications.md**: fixed stale "24h TTL" → "7-day TTL" and
127
+ "transcoded to JPEG" → "transcoded to the configured format (PNG/JPEG)".
128
+ - **AGENTS.md**: fixed stale config field names `target` (removed from config)
129
+ and `stamp_cache_ttl` (replaced by `stamp_claude_code_enabled`).
130
+ - **CHANGELOG.md**: removed duplicate entries between [Unreleased] and [0.1.3].
131
+ - **MAINTAINERS.md**: populated template with actual maintainer (`@codegiveness`).
132
+ - **Startup banner** (`src/banner.ts`): version is now read from `package.json`
133
+ instead of being hardcoded at `v0.1.0`. Every prior release printed the wrong
134
+ version on startup.
135
+ - **`clean` script** (`package.json`): `capture.db` → `umans-gate.db` (3 file
136
+ suffixes). `bun run clean` now correctly removes the actual database.
137
+ - **`biome.json`**: `capture.db*` → `umans-gate.db*` (stale entry from DB rename).
138
+ - **ARCHITECTURE.md**: fixed ASCII diagram alignment after `capture.db` →
139
+ `umans-gate.db` rename (SQLite box widened to fit text, `┴` connector
140
+ aligned with proxy box `┬` above).
141
+ - **Benchmark result files**: untracked 36 stale files across three benchmark
142
+ directories (`benchmark/vision-handoff/results/`, `benchmark/proxy-optimizations/results/`,
143
+ and `benchmark/concurrency-gate/results.json`) — they contained old
144
+ `umans-ai/umans-gate` URLs in vision-test descriptions and a partially-redacted
145
+ API key (`sk-f1qgI...tmJI`). Updated `.gitignore` to also match `results.json`
146
+ files directly in benchmark directories (not just `results/` subdirectories).
147
+ - **README badge**: removed misleading "Runtime: Bun" badge (contradicts "No
148
+ prerequisites for npm/npx"). Added CodeQL badge.
149
+ - **CI lint failures**: added `src/embedded-assets.ts` to `biome.json` ignore
150
+ list (generated file with long import lines that Biome wanted to reformat).
151
+ Auto-fixed `package.json` `files` array formatting (Biome wanted inline).
152
+ These two pre-existing lint errors caused ALL CI runs and ALL Dependabot PRs
153
+ to fail.
154
+ - **Release workflow resilience**: `release.yml` now retries each npm publish
155
+ step 3 times with 15s delays. Platform package publish failures no longer
156
+ block the main shim from publishing (previously `win32-arm64` spam detection
157
+ failure prevented the entire release).
158
+
159
+ ### Added
160
+
161
+ - **CodeQL code scanning** (`.github/workflows/codeql.yml`) — weekly automated
162
+ security analysis for JavaScript/TypeScript.
163
+
10
164
  ## [0.1.2] - 2026-07-14
11
165
 
12
166
  ### Fixed
package/README.md CHANGED
@@ -1,25 +1,32 @@
1
1
  # umans-gate
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/umans-gate.svg)](https://www.npmjs.com/package/umans-gate)
4
+ [![npm downloads](https://img.shields.io/npm/dm/umans-gate.svg)](https://www.npmjs.com/package/umans-gate)
4
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
- [![Runtime: Bun](https://img.shields.io/badge/Runtime-Bun-fbf0df.svg)](https://bun.sh)
6
- [![CI](https://github.com/umans-ai/umans-gate/actions/workflows/ci.yml/badge.svg)](https://github.com/umans-ai/umans-gate/actions/workflows/ci.yml)
6
+ [![CI](https://github.com/codegiveness/umans-gate/actions/workflows/ci.yml/badge.svg)](https://github.com/codegiveness/umans-gate/actions/workflows/ci.yml)
7
+ [![CodeQL](https://github.com/codegiveness/umans-gate/actions/workflows/codeql.yml/badge.svg)](https://github.com/codegiveness/umans-gate/actions/workflows/codeql.yml)
7
8
 
8
- > **Disclaimer:** This is a community project. The author is not an official
9
- > Umans developer just a contributor building tools around the Umans API.
10
- > "umans" and related marks belong to their respective owners.
9
+ > A capture proxy for LLM APIs. Point your harness at it, and every
10
+ > request/response is stored in SQLite with a live inspection dashboard.
11
+ > Built for the [umans-open-stack](https://github.com/umans-ai/umans-open-stack)
12
+ > community.
11
13
 
12
- LLM capture proxy with Anthropic `cache_control` TTL stamping, vision handoff,
13
- concurrency gating, rate limiting, and a live inspection dashboard.
14
+ **Setup in 30 seconds. Set it and forget it.**
14
15
 
15
- Point your LLM harness at `http://localhost:1945`, and every request/response is
16
- captured to SQLite with a live WebSocket-updating inspector UI at
17
- `http://localhost:1945/dashboard/`.
16
+ ```bash
17
+ npx umans-gate
18
+ ```
19
+
20
+ That's it. The proxy starts on `http://localhost:1945` and the inspector
21
+ dashboard opens at `http://localhost:1945/dashboard/`. Point any
22
+ Anthropic or OpenAI-compatible harness at the proxy URL — every
23
+ request and response is captured automatically.
18
24
 
19
25
  ## Table of Contents
20
26
 
21
- - [Features](#features)
27
+ - [Install](#install)
22
28
  - [Quick Start](#quick-start)
29
+ - [Updating](#updating)
23
30
  - [Configuration](#configuration)
24
31
  - [Config Fields](#config-fields)
25
32
  - [Hot Reload and Restart](#hot-reload-and-restart)
@@ -32,50 +39,150 @@ captured to SQLite with a live WebSocket-updating inspector UI at
32
39
  - [Development](#development)
33
40
  - [Project Structure](#project-structure)
34
41
  - [Documentation](#documentation)
42
+ - [Related Projects](#related-projects)
35
43
  - [Contributing](#contributing)
36
44
  - [License](#license)
37
45
 
38
- ## Features
39
-
40
- - **Capture proxy**: intercepts all LLM API traffic (Anthropic, OpenAI-compatible) and stores it in SQLite with optional zstd compression
41
- - **Stamp pipeline**: unified stamping orchestrator that applies TTL, `top_k`, `max_tokens`, `thinking`, `output_config`, `context_management`, and `temperature` stamps in the correct order — toggled by a single `stamp_claude_code_enabled` switch
42
- - **Vision handoff**: replaces image blocks with text descriptions generated by a vision model (`umans-flash`), enabling text-only models to "see" images. Descriptions are cached (7-day TTL) with persistent SQLite storage
43
- - **Concurrency gate**: semaphore + circuit breaker with intention-based reservations (main vs vision), hard cap, soft limit driven by `/v1/usage`, queue timeout, and over-subscription fallback
44
- - **Rate limiting**: sliding-window weighted rate limiter for pro-tier request limits, auto-derived from `/v1/usage` or explicitly configured
45
- - **Connection warmer**: periodic `/v1/models` pings keep TLS warm, skipping when real traffic occurred recently
46
- - **Usage tracking**: fetches and reconciles `/v1/usage` to size concurrency limits, detect rate-boxing, and manage priority demotion
47
- - **Live inspector dashboard**: React + shadcn/ui dashboard with WebSocket live updates
48
- - **SSE rendering**: streaming responses are captured and rendered with expandable event previews
49
- - **Ring buffer storage**: keeps the last N captures (default 200) with WAL mode SQLite
50
- - **Write-behind queue**: batched database writes to minimize blocking during streaming
51
- - **Worker-based capture pipeline**: offloads capture writes to a worker thread for non-blocking streaming
52
- - **Hop-by-hop header stripping**: correct HTTP proxy behavior
53
- - **Protocol flexibility**: configurable upstream HTTP/1.1 (default) or HTTP/2
46
+ ## Install
54
47
 
55
- ## Quick Start
48
+ **npm (recommended for end users):**
56
49
 
57
50
  ```bash
58
- # Install
59
- bun install
51
+ npm install -g umans-gate
52
+ umans-gate
53
+ ```
54
+
55
+ **npx (no install, run once):**
60
56
 
61
- # Start the proxy (reads config.json + env overrides)
57
+ ```bash
58
+ npx umans-gate
59
+ ```
60
+
61
+ **Bun (for developers):**
62
+
63
+ ```bash
64
+ git clone https://github.com/codegiveness/umans-gate.git
65
+ cd umans-gate
66
+ bun install
62
67
  bun src/cli.ts
68
+ ```
69
+
70
+ > **No prerequisites for npm/npx.** The npm package bundles a pre-compiled
71
+ > standalone binary for your platform. For development from source,
72
+ > [Bun](https://bun.sh) ≥ 1.1.0 is required.
73
+
74
+ ### Platform Support
75
+
76
+ Pre-compiled binaries are published for:
77
+
78
+ | OS | Architecture | npm Package |
79
+ |----|-------------|-------------|
80
+ | macOS | arm64 (Apple Silicon) | `umans-gate-darwin-arm64` |
81
+ | macOS | x64 (Intel) | `umans-gate-darwin-x64` |
82
+ | Linux | x64 | `umans-gate-linux-x64` |
83
+ | Linux | arm64 | `umans-gate-linux-arm64` |
84
+ | Windows | x64 | `umans-gate-win32-x64` |
85
+ | Windows | arm64 | `umans-gate-win32-arm64` |
86
+
87
+ The main `umans-gate` package automatically detects your platform and
88
+ installs the correct binary.
89
+
90
+ ## Quick Start
91
+
92
+ 1. **Start the proxy:**
93
+
94
+ ```bash
95
+ umans-gate
96
+ ```
97
+
98
+ 2. **Point your harness** to `http://localhost:1945` as the base URL:
99
+
100
+ ```bash
101
+ # Anthropic API
102
+ export ANTHROPIC_BASE_URL=http://localhost:1945
63
103
 
64
- # Or after build:
65
- bun run build
66
- ./dist/cli.js
104
+ # OpenAI-compatible API
105
+ export OPENAI_BASE_URL=http://localhost:1945
106
+ ```
107
+
108
+ 3. **Open the inspector dashboard** at `http://localhost:1945/dashboard/`
109
+
110
+ Every request and response is captured to SQLite with live WebSocket
111
+ updates. The dashboard shows full request/response bodies, streaming
112
+ SSE events, timing, token economics, and more.
113
+
114
+ 4. **Set your API key** (optional but recommended):
115
+
116
+ ```bash
117
+ # Option A: environment variable
118
+ export UMANS_API_KEY=your-key-here
119
+
120
+ # Option B: config.json (persists across restarts)
121
+ umans-gate config show # see current config + file path
122
+ # Edit config.json and set "umans_api_key"
123
+ # Or use the dashboard Config tab at /dashboard/
124
+ ```
125
+
126
+ Setting `UMANS_API_KEY` enables `/v1/usage` polling, concurrency gate
127
+ sizing, rate-limit validation, and vision handoff.
128
+
129
+ ### What It Does
130
+
131
+ | Feature | Description |
132
+ |---------|-------------|
133
+ | **Capture proxy** | Intercepts all LLM API traffic (Anthropic, OpenAI-compatible) and stores it in SQLite with optional zstd compression |
134
+ | **Stamp pipeline** | Applies TTL, `top_k`, `max_tokens`, `thinking`, `output_config`, `context_management`, and `temperature` stamps — toggled by a single switch |
135
+ | **Vision handoff** | Replaces image blocks with text descriptions from a vision model, enabling text-only models to "see" images. Descriptions are cached (7-day TTL) with persistent SQLite storage |
136
+ | **Concurrency gate** | Semaphore + circuit breaker with intention-based reservations, hard cap, soft limit driven by `/v1/usage`, queue timeout, and over-subscription fallback |
137
+ | **Rate limiting** | Sliding-window weighted rate limiter for pro-tier request limits, auto-derived from `/v1/usage` or explicitly configured |
138
+ | **Connection warmer** | Periodic `/v1/models` pings keep TLS warm, skipping when real traffic occurred recently |
139
+ | **Usage tracking** | Fetches and reconciles `/v1/usage` to size concurrency limits, detect rate-boxing, and manage priority demotion |
140
+ | **Live inspector** | React + shadcn/ui dashboard with WebSocket live updates |
141
+ | **SSE rendering** | Streaming responses are captured and rendered with expandable event previews |
142
+ | **Ring buffer storage** | Keeps the last N captures (default 200) with WAL mode SQLite |
143
+ | **Write-behind queue** | Batched database writes to minimize blocking during streaming |
144
+ | **Worker-based capture** | Offloads capture writes to a worker thread for non-blocking streaming |
145
+ | **Hop-by-hop header stripping** | Correct HTTP proxy behavior |
146
+ | **Protocol flexibility** | Configurable upstream HTTP/1.1 (default) or HTTP/2 |
147
+
148
+ ## Updating
149
+
150
+ ```bash
151
+ umans-gate update # self-update (npm global or standalone binary)
67
152
  ```
68
153
 
69
- Point your harness base URL to `http://localhost:1945` and open the inspector at `http://localhost:1945/dashboard/`.
154
+ The updater detects your install method (npm global, standalone
155
+ executable, or dev) and performs the appropriate action. For npm global
156
+ installs, it runs `npm update -g umans-gate`. For standalone binaries,
157
+ it points you to the latest GitHub Release.
158
+
159
+ To check for updates without installing:
160
+
161
+ ```bash
162
+ umans-gate update --check
163
+ ```
164
+
165
+ ### Uninstall
166
+
167
+ ```bash
168
+ umans-gate uninstall # removes config, database, and binary
169
+ ```
170
+
171
+ Or manually:
172
+
173
+ ```bash
174
+ npm uninstall -g umans-gate
175
+ rm -rf ~/.config/umans-gate
176
+ ```
70
177
 
71
178
  ## Configuration
72
179
 
73
- > **⚠️ Dashboard-first:** The recommended way to change configuration is via
180
+ > **Dashboard-first:** The recommended way to change configuration is via
74
181
  > the **Config** tab in the dashboard at `http://localhost:1945/dashboard/`.
75
182
  > Editing `config.json` directly works, but the dashboard validates against
76
- > the upstream `/v1/usage` hard cap, shows field descriptions, and can hot-reload
77
- > or restart the server for you. If you do edit the file, restart the server
78
- > afterward (the dashboard auto-reloads on save).
183
+ > the upstream `/v1/usage` hard cap, shows field descriptions, and can
184
+ > hot-reload or restart the server for you. If you do edit the file,
185
+ > restart the server afterward (the dashboard auto-reloads on save).
79
186
 
80
187
  Configuration is loaded from a JSON file with environment variable overrides.
81
188
 
@@ -92,8 +199,8 @@ On first run, `loadConfig()` writes a `config.json` with defaults to the
92
199
  resolved path if it does not already exist. Existing configs are never
93
200
  overwritten.
94
201
 
95
- All env vars from `.env.example` have JSON equivalents using `snake_case`
96
- (e.g., `UPSTREAM_PROTOCOL` → `upstream_protocol`).
202
+ All configuration variables have JSON equivalents using `snake_case`
203
+ (e.g., `UPSTREAM_PROTOCOL` → `upstream_protocol` in `config.json`).
97
204
 
98
205
  ### Config Fields
99
206
 
@@ -149,9 +256,9 @@ hardcoded — not configurable.
149
256
 
150
257
  The dashboard's Config tab can save changes and trigger a hot reload
151
258
  via `POST /dashboard/api/config/reload`. Hot-reloadable fields (e.g.
152
- `stamp_claude_code_enabled`, `breaker_*`, `rate_limit_*`, `vision_*`)
259
+ `stamp_claude_code_enabled`, `breaker_*`, `rate_limit_*`)
153
260
  apply live; fields marked `restartRequired` (e.g. `port`, `db_path`,
154
- `upstream_protocol`) require a server restart.
261
+ `upstream_protocol`, `vision_*`) require a server restart.
155
262
 
156
263
  The dashboard also has a **Restart** button (`POST /dashboard/api/restart`)
157
264
  that calls `process.exit(0)`. This requires an external process manager
@@ -302,6 +409,7 @@ umans-gate/
302
409
  │ ├── model-policy.ts # model-aware stamping decisions
303
410
  │ ├── compress.ts # zstd body compression
304
411
  │ ├── vision-description-store.ts # persistent vision description storage
412
+ │ ├── updater.ts # self-update logic
305
413
  │ ├── helpers.ts # shared utilities
306
414
  │ ├── logger.ts # structured scoped logging
307
415
  │ ├── banner.ts # startup banner
@@ -318,7 +426,7 @@ umans-gate/
318
426
  │ │ ├── persistent-cache.ts # SQLite-backed description cache
319
427
  │ │ ├── transcode.ts # image transcoding
320
428
  │ │ ├── wrapper.ts # description wrapper + policy
321
- │ │ └── sink.ts # vision record sink
429
+ │ │ └── sink.ts # vision record sink
322
430
  │ ├── workers/ # worker-based capture pipeline
323
431
  │ └── shared/ # extracted domain helpers
324
432
  ├── dashboard/ # React + shadcn/ui dashboard
@@ -327,8 +435,9 @@ umans-gate/
327
435
  │ ├── ARCHITECTURE.md # system architecture
328
436
  │ ├── TROUBLESHOOTING.md # troubleshooting guide
329
437
  │ ├── BENCHMARKS.md # benchmark results
438
+ │ ├── PRODUCT.md # product positioning and users
330
439
  │ └── proxy-modifications.md # proxy modification inventory
331
- ├── benchmark/ # benchmark scripts + results
440
+ ├── benchmark/ # benchmark scripts
332
441
  ├── .github/ # issue templates, workflows, PR template
333
442
  └── dist/ # build output (gitignored)
334
443
  ```
@@ -339,10 +448,21 @@ umans-gate/
339
448
  - [Proxy Modifications](docs/proxy-modifications.md) — complete inventory of proxy modifications
340
449
  - [Troubleshooting](docs/TROUBLESHOOTING.md) — common issues and solutions
341
450
  - [Benchmarks](docs/BENCHMARKS.md) — benchmark methodology and results
451
+ - [Product](docs/PRODUCT.md) — product positioning and target users
342
452
  - [Dashboard Design System](dashboard/DESIGN.md) — design system documentation
343
453
  - [Changelog](CHANGELOG.md) — version history
344
454
  - [Contributing](CONTRIBUTING.md) — how to contribute
345
455
  - [Roadmap](ROADMAP.md) — future plans
456
+ - [Security Policy](SECURITY.md) — vulnerability reporting and security practices
457
+
458
+ ## Related Projects
459
+
460
+ - **[umans-open-stack](https://github.com/umans-ai/umans-open-stack)** — A
461
+ curated set of open source playbooks and tools tested with Umans. umans-gate
462
+ implements several patterns documented there: concurrency gating, vision
463
+ handoff, cache_control TTL stamping, and workflow orchestration. If you're
464
+ using umans-gate, the open-stack playbooks explain the why behind each
465
+ feature.
346
466
 
347
467
  ## Contributing
348
468
 
package/npm-shim.cjs ADDED
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env node
2
+ // Thin launcher: finds the platform binary and exec's it.
3
+ // Uses require() (CommonJS) intentionally — .cjs extension forces CJS parsing.
4
+ const { spawnSync, execSync } = require("node:child_process");
5
+ const path = require("node:path");
6
+ const fs = require("node:fs");
7
+
8
+ const platform = process.platform;
9
+ const arch = process.arch;
10
+
11
+ const SCOPE = "@codegiveness";
12
+ const platformMap = {
13
+ darwin: { arm64: "darwin-arm64", x64: "darwin-x64" },
14
+ linux: { arm64: "linux-arm64", x64: "linux-x64" },
15
+ win32: { arm64: "win32-arm64", x64: "win32-x64" },
16
+ };
17
+
18
+ const target = platformMap[platform]?.[arch];
19
+ if (!target) {
20
+ console.error(`umans-gate: unsupported platform ${platform}-${arch}`);
21
+ process.exit(1);
22
+ }
23
+
24
+ const ext = platform === "win32" ? ".exe" : "";
25
+ const binName = `umans-gate-${target}${ext}`;
26
+
27
+ // Search order for the platform binary:
28
+ // 1. Sibling to this shim (npm local install: node_modules/umans-gate-<target>/)
29
+ // 2. Global npm prefix (npm global install: node_modules/umans-gate-<target>/)
30
+ // 3. require.resolve fallback
31
+ let binPath = null;
32
+
33
+ // Try 1: sibling directory (npm hoists optionalDependencies to top-level node_modules/)
34
+ // When umans-gate is installed, @codegiveness/umans-gate-<target> is a sibling package.
35
+ const localPath = path.join(__dirname, "..", SCOPE, `umans-gate-${target}`, binName);
36
+ if (fs.existsSync(localPath)) {
37
+ binPath = localPath;
38
+ }
39
+
40
+ // Try 2: global npm prefix
41
+ if (!binPath) {
42
+ try {
43
+ const globalPrefix = execSync("npm root -g", { encoding: "utf8" }).trim();
44
+ const globalPath = path.join(globalPrefix, SCOPE, `umans-gate-${target}`, binName);
45
+ if (fs.existsSync(globalPath)) {
46
+ binPath = globalPath;
47
+ }
48
+ } catch {
49
+ // npm not available — skip
50
+ }
51
+ }
52
+
53
+ // Try 3: require.resolve the platform package
54
+ if (!binPath) {
55
+ try {
56
+ const pkgPath = require.resolve(`${SCOPE}/umans-gate-${target}/package.json`);
57
+ binPath = path.join(path.dirname(pkgPath), binName);
58
+ } catch {
59
+ // Package not found — fall through to error
60
+ }
61
+ }
62
+
63
+ if (!binPath || !fs.existsSync(binPath)) {
64
+ console.error(`umans-gate: platform binary not found for ${target}.`);
65
+ console.error(` Tried: ${localPath}`);
66
+ console.error(` Install it with: npm install ${SCOPE}/umans-gate-${target}`);
67
+ process.exit(1);
68
+ }
69
+
70
+ const result = spawnSync(binPath, process.argv.slice(2), { stdio: "inherit" });
71
+ process.exit(result.status || 1);
package/package.json CHANGED
@@ -1,85 +1,21 @@
1
1
  {
2
2
  "name": "umans-gate",
3
- "version": "0.1.2",
4
- "description": "LLM capture proxy with Anthropic cache_control TTL stamping and live inspection dashboard",
5
- "type": "module",
3
+ "version": "0.1.4",
4
+ "description": "LLM capture proxy with Anthropic cache_control TTL stamping, vision handoff, concurrency gating, rate limiting, and a live inspection dashboard",
5
+ "repository": { "type": "git", "url": "git+https://github.com/codegiveness/umans-gate.git" },
6
+ "homepage": "https://github.com/codegiveness/umans-gate#readme",
7
+ "bugs": { "url": "https://github.com/codegiveness/umans-gate/issues" },
6
8
  "license": "MIT",
7
- "author": "umans.ai",
8
- "publishConfig": {
9
- "access": "public",
10
- "registry": "https://registry.npmjs.org/"
11
- },
12
- "homepage": "https://github.com/umans-ai/umans-gate",
13
- "repository": {
14
- "type": "git",
15
- "url": "git+https://github.com/codegiveness/umans-gate.git"
16
- },
17
- "bugs": {
18
- "url": "https://github.com/umans-ai/umans-gate/issues"
19
- },
20
- "keywords": [
21
- "llm",
22
- "proxy",
23
- "capture",
24
- "anthropic",
25
- "openai",
26
- "cache-control",
27
- "ttl",
28
- "inspector",
29
- "debugger",
30
- "websocket"
31
- ],
32
- "bin": {
33
- "umans-gate": "dist/cli.js"
34
- },
35
- "main": "./dist/index.js",
36
- "module": "./dist/index.js",
37
- "types": "./dist/index.d.ts",
38
- "exports": {
39
- ".": {
40
- "types": "./dist/index.d.ts",
41
- "import": "./dist/index.js",
42
- "default": "./dist/index.js"
43
- },
44
- "./package.json": "./package.json"
45
- },
46
- "files": [
47
- "dist",
48
- "dashboard/dist",
49
- "README.md",
50
- "LICENSE",
51
- "CHANGELOG.md"
52
- ],
53
- "engines": {
54
- "bun": ">=1.1.0"
55
- },
56
- "scripts": {
57
- "dev": "bun src/cli.ts",
58
- "build": "bun run build:dashboard && bun run build:embed-assets && bun run build:server",
59
- "build:server": "bash scripts/build-server.sh",
60
- "build:dashboard": "cd dashboard && bun run build",
61
- "build:embed-assets": "bun scripts/embed-assets.ts",
62
- "test": "bun test",
63
- "test:dashboard": "cd dashboard && bun run test",
64
- "test:dashboard:watch": "cd dashboard && bun run test:watch",
65
- "test:all": "bun run test && bun run test:dashboard",
66
- "lint": "biome check .",
67
- "lint:fix": "biome check --write .",
68
- "format": "biome format --write .",
69
- "typecheck": "tsc --noEmit",
70
- "clean": "rm -rf dist dashboard/dist dashboard/node_modules capture.db capture.db-shm capture.db-wal",
71
- "prepublishOnly": "bun run build"
72
- },
73
- "devDependencies": {
74
- "@biomejs/biome": "^1.9.4",
75
- "@playwright/test": "^1.61.1",
76
- "playwright": "^1.61.1",
77
- "tsup": "^8.3.5",
78
- "typescript": "^5.7.2"
79
- },
80
- "dependencies": {
81
- "@types/bun": "^1.3.14",
82
- "commander": "^12",
83
- "lru-cache": "^11.5.1"
9
+ "bin": { "umans-gate": "./npm-shim.cjs" },
10
+ "files": ["npm-shim.cjs", "dist", "README.md", "LICENSE", "CHANGELOG.md"],
11
+ "engines": { "node": ">=18.0.0" },
12
+ "keywords": ["llm", "proxy", "capture", "anthropic", "openai", "cache-control", "ttl", "inspector", "debugger", "websocket", "claude", "prompt-engineering", "observability", "sqlite", "bun", "developer-tools", "api-proxy", "prompt-caching"],
13
+ "optionalDependencies": {
14
+ "@codegiveness/umans-gate-darwin-arm64": "0.1.4",
15
+ "@codegiveness/umans-gate-darwin-x64": "0.1.4",
16
+ "@codegiveness/umans-gate-linux-x64": "0.1.4",
17
+ "@codegiveness/umans-gate-linux-arm64": "0.1.4",
18
+ "@codegiveness/umans-gate-win32-x64": "0.1.4",
19
+ "@codegiveness/umans-gate-win32-arm64": "0.1.4"
84
20
  }
85
21
  }
@@ -1,2 +0,0 @@
1
- import{j as e,r as d}from"./vendor-react-Dtud3GyP.js";import{c as o,B as n}from"./index-72wCsW4_.js";import{aC as u,aD as c,aE as f,aF as m,aG as g,aH as p,aI as x,aJ as D}from"./vendor-CVKsgXJU.js";function h({...a}){return e.jsx(u,{"data-slot":"alert-dialog",...a})}function v({...a}){return e.jsx(D,{"data-slot":"alert-dialog-trigger",...a})}function j({...a}){return e.jsx(p,{"data-slot":"alert-dialog-portal",...a})}function A({className:a,...t}){return e.jsx(x,{"data-slot":"alert-dialog-overlay",className:o("fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",a),...t})}function N({className:a,size:t="default",...l}){return e.jsxs(j,{children:[e.jsx(A,{}),e.jsx(c,{"data-slot":"alert-dialog-content","data-size":t,className:o("group/alert-dialog-content fixed top-1/2 left-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-popover p-4 text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",a),...l})]})}function y({className:a,...t}){return e.jsx("div",{"data-slot":"alert-dialog-header",className:o("grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-4 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]",a),...t})}function C({className:a,...t}){return e.jsx("div",{"data-slot":"alert-dialog-footer",className:o("-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end",a),...t})}function k({className:a,...t}){return e.jsx(f,{"data-slot":"alert-dialog-title",className:o("font-heading text-base font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2",a),...t})}function R({className:a,...t}){return e.jsx(m,{"data-slot":"alert-dialog-description",className:o("text-sm text-balance text-muted-foreground md:text-pretty *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground",a),...t})}const T=d.forwardRef(function({className:t,variant:l="default",size:r="default",...s},i){return e.jsx(g,{ref:i,"data-slot":"alert-dialog-action",className:o(t),render:e.jsx(n,{variant:l,size:r}),...s})}),_=d.forwardRef(function({className:t,variant:l="outline",size:r="default",...s},i){return e.jsx(g,{ref:i,"data-slot":"alert-dialog-cancel",className:o(t),render:e.jsx(n,{variant:l,size:r}),...s})});export{h as A,v as a,N as b,y as c,k as d,R as e,C as f,_ as g,T as h};
2
- //# sourceMappingURL=alert-dialog-DlhAyxD3.js.map