agentbridge-cli 0.1.11__tar.gz → 0.1.12__tar.gz
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.
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/.codex/skills/build-release/SKILL.md +26 -11
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/.codex/skills/build-release/scripts/release_build.py +41 -1
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/.github/dependabot.yml +19 -0
- agentbridge_cli-0.1.12/.github/workflows/ci.yml +52 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/.github/workflows/release.yml +131 -16
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/.gitignore +2 -0
- agentbridge_cli-0.1.11/README.md → agentbridge_cli-0.1.12/PKG-INFO +70 -5
- agentbridge_cli-0.1.11/PKG-INFO → agentbridge_cli-0.1.12/README.md +38 -35
- agentbridge_cli-0.1.12/agentbridge/_build_info.py +1 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/agentbridge/dashboard.py +46 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/agentbridge/pool.py +1 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/agentbridge/server.py +55 -16
- agentbridge_cli-0.1.12/agentbridge/static/brand/android-chrome-192.png +0 -0
- agentbridge_cli-0.1.12/agentbridge/static/brand/android-chrome-512.png +0 -0
- agentbridge_cli-0.1.12/agentbridge/static/brand/apple-touch-icon.png +0 -0
- agentbridge_cli-0.1.12/agentbridge/static/brand/favicon-16.png +0 -0
- agentbridge_cli-0.1.12/agentbridge/static/brand/favicon-32.png +0 -0
- agentbridge_cli-0.1.12/agentbridge/static/brand/favicon-48.png +0 -0
- agentbridge_cli-0.1.12/agentbridge/static/brand/favicon.ico +0 -0
- agentbridge_cli-0.1.12/agentbridge/static/brand/favicon.svg +11 -0
- {agentbridge_cli-0.1.11/image-assets/web-seo → agentbridge_cli-0.1.12/agentbridge/static/brand}/site.webmanifest +4 -4
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/agentbridge/templates/dashboard/base.html +28 -21
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/agentbridge/templates/dashboard/chat.html +1 -1
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/agentbridge/templates/dashboard/page.html +1 -1
- agentbridge_cli-0.1.12/design-qa/agentbridge-popover-final.png +0 -0
- agentbridge_cli-0.1.12/design-qa/agentbridge-popover-normalized.png +0 -0
- agentbridge_cli-0.1.12/design-qa/agentbridge-popover-pass-1.jpeg +0 -0
- agentbridge_cli-0.1.12/design-qa/implementation-header-activity.png +0 -0
- agentbridge_cli-0.1.12/design-qa/reference-header-activity.png +0 -0
- agentbridge_cli-0.1.12/design-qa/reference-panel.png +0 -0
- agentbridge_cli-0.1.12/design-qa.md +43 -0
- agentbridge_cli-0.1.12/image-assets/apple-store/app-store-icon-1024.png +0 -0
- agentbridge_cli-0.1.12/image-assets/icon/icon-1024.png +0 -0
- agentbridge_cli-0.1.12/image-assets/logo/logo-1024.png +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/image-assets/manifest.json +14 -2
- agentbridge_cli-0.1.12/image-assets/sources/icon-source-keyed.png +0 -0
- agentbridge_cli-0.1.12/image-assets/sources/icon-source.png +0 -0
- agentbridge_cli-0.1.12/image-assets/sources/logo-source-keyed.png +0 -0
- agentbridge_cli-0.1.12/image-assets/sources/logo-source.png +0 -0
- agentbridge_cli-0.1.12/image-assets/sources/social-background-source.png +0 -0
- agentbridge_cli-0.1.12/image-assets/sources/social-source.png +0 -0
- agentbridge_cli-0.1.12/image-assets/web-seo/android-chrome-192.png +0 -0
- agentbridge_cli-0.1.12/image-assets/web-seo/android-chrome-512.png +0 -0
- agentbridge_cli-0.1.12/image-assets/web-seo/apple-touch-icon.png +0 -0
- agentbridge_cli-0.1.12/image-assets/web-seo/favicon/favicon-16.png +0 -0
- agentbridge_cli-0.1.12/image-assets/web-seo/favicon/favicon-32.png +0 -0
- agentbridge_cli-0.1.12/image-assets/web-seo/favicon/favicon-48.png +0 -0
- agentbridge_cli-0.1.12/image-assets/web-seo/favicon/favicon.ico +0 -0
- agentbridge_cli-0.1.12/image-assets/web-seo/favicon/favicon.svg +11 -0
- agentbridge_cli-0.1.12/image-assets/web-seo/og-image-1200x630.png +0 -0
- agentbridge_cli-0.1.12/image-assets/web-seo/site.webmanifest +21 -0
- agentbridge_cli-0.1.12/logo.png +0 -0
- agentbridge_cli-0.1.12/macos/Package.swift +21 -0
- agentbridge_cli-0.1.12/macos/README.md +46 -0
- agentbridge_cli-0.1.12/macos/Sources/AgentBridgeMenuBar/AgentBridgeMenuBarApp.swift +172 -0
- agentbridge_cli-0.1.12/macos/Sources/AgentBridgeMenuBar/BrandMark.swift +40 -0
- agentbridge_cli-0.1.12/macos/Sources/AgentBridgeMenuBar/HealthClient.swift +67 -0
- agentbridge_cli-0.1.12/macos/Sources/AgentBridgeMenuBar/ServerController.swift +266 -0
- agentbridge_cli-0.1.12/macos/Sources/AgentBridgeMenuBar/ServerLauncher.swift +116 -0
- agentbridge_cli-0.1.12/macos/Sources/AgentBridgeMenuBar/SettingsView.swift +225 -0
- agentbridge_cli-0.1.12/macos/Sources/AgentBridgeMenuBar/StatusModels.swift +131 -0
- agentbridge_cli-0.1.12/macos/Sources/AgentBridgeMenuBar/StatusPopover.swift +284 -0
- agentbridge_cli-0.1.12/macos/Tests/AgentBridgeMenuBarTests/StatusModelsTests.swift +74 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/pyproject.toml +26 -7
- agentbridge_cli-0.1.12/scripts/build_macos_app.sh +156 -0
- agentbridge_cli-0.1.12/scripts/verify_macos_app.sh +25 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/tests/test_dashboard.py +50 -2
- agentbridge_cli-0.1.12/tests/test_dependency_security.py +74 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/tests/test_pool.py +5 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/tests/test_server.py +28 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/uv.lock +553 -99
- agentbridge_cli-0.1.11/.github/workflows/ci.yml +0 -36
- agentbridge_cli-0.1.11/agentbridge/_build_info.py +0 -1
- agentbridge_cli-0.1.11/image-assets/icon/icon-1024.png +0 -0
- agentbridge_cli-0.1.11/image-assets/logo/logo-1024.png +0 -0
- agentbridge_cli-0.1.11/image-assets/sources/icon-source-keyed.png +0 -0
- agentbridge_cli-0.1.11/image-assets/sources/icon-source.png +0 -0
- agentbridge_cli-0.1.11/image-assets/sources/logo-source-keyed.png +0 -0
- agentbridge_cli-0.1.11/image-assets/sources/logo-source.png +0 -0
- agentbridge_cli-0.1.11/image-assets/sources/social-background-source.png +0 -0
- agentbridge_cli-0.1.11/image-assets/sources/social-source.png +0 -0
- agentbridge_cli-0.1.11/image-assets/web-seo/android-chrome-192.png +0 -0
- agentbridge_cli-0.1.11/image-assets/web-seo/android-chrome-512.png +0 -0
- agentbridge_cli-0.1.11/image-assets/web-seo/apple-touch-icon.png +0 -0
- agentbridge_cli-0.1.11/image-assets/web-seo/favicon/favicon-16.png +0 -0
- agentbridge_cli-0.1.11/image-assets/web-seo/favicon/favicon-32.png +0 -0
- agentbridge_cli-0.1.11/image-assets/web-seo/favicon/favicon-48.png +0 -0
- agentbridge_cli-0.1.11/image-assets/web-seo/favicon/favicon.ico +0 -0
- agentbridge_cli-0.1.11/image-assets/web-seo/og-image-1200x630.png +0 -0
- agentbridge_cli-0.1.11/logo.png +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/.codex/config.toml +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/.codex/skills/build-release/agents/openai.yaml +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/.env.example +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/.github/workflows/dependency-review.yml +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/AGENTS.md +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/CLAUDE.md +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/LICENSE +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/Makefile +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/TODO.txt +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/agentbridge/__init__.py +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/agentbridge/config.py +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/agentbridge/models.py +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/agentbridge/templates/dashboard/detail.html +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/agentbridge/templates/dashboard/pool.html +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/agentbridge/templates/dashboard/requests.html +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/architecture.png +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/docs/plans/2026-02-14-dashboard-design.md +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/docs/plans/2026-02-14-dashboard-implementation.md +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/hatch_build.py +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/scripts/dashboard_load_test.py +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/tests/fixtures/ocr_test_document.png +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/tests/test_config.py +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/tests/test_image_utils.py +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/tests/test_model_mapping.py +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/tests/test_models.py +0 -0
- {agentbridge_cli-0.1.11 → agentbridge_cli-0.1.12}/tests/test_session_logger.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: build-release
|
|
3
|
-
description: Build, publish, and verify AgentBridge releases. Use when the user invokes /build-release or asks to cut, launch, tag, publish, monitor, or verify
|
|
3
|
+
description: Build, publish, and verify AgentBridge releases. Use when the user invokes /build-release or asks to cut, launch, tag, publish, monitor, or verify the agentbridge-cli PyPI package or macOS app.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Build Release
|
|
@@ -9,7 +9,8 @@ Use the repository-owned GitHub Actions workflow and PyPI Trusted Publishing.
|
|
|
9
9
|
Do not create a local tag or upload with local credentials: pushing a new
|
|
10
10
|
`pyproject.toml` version to `main` triggers `.github/workflows/release.yml`,
|
|
11
11
|
which tests, scans, builds, creates `v<version>`, creates the GitHub Release,
|
|
12
|
-
|
|
12
|
+
publishes `agentbridge-cli`, and, when macOS publishing is enabled, attaches
|
|
13
|
+
signed and notarized arm64 and x86_64 DMGs.
|
|
13
14
|
|
|
14
15
|
Use the next unused patch version unless the user requests another valid,
|
|
15
16
|
unused semantic version. Treat an untagged version absent from PyPI as pending.
|
|
@@ -28,6 +29,13 @@ git log --oneline HEAD..origin/main
|
|
|
28
29
|
Stop on unrelated changes, unpublished commits, divergence, or another branch.
|
|
29
30
|
Do not clean, pull, commit unrelated files, or switch branches.
|
|
30
31
|
|
|
32
|
+
Require the repository variable `MACOS_RELEASE_ENABLED` to be `true` and verify
|
|
33
|
+
that these Actions secrets are configured before a release expected to contain
|
|
34
|
+
the macOS app: `APPLE_CERTIFICATE_BASE64`, `APPLE_CERTIFICATE_PASSWORD`,
|
|
35
|
+
`APPLE_KEYCHAIN_PASSWORD`, `APPLE_NOTARY_APPLE_ID`, `APPLE_NOTARY_PASSWORD`, and
|
|
36
|
+
`APPLE_TEAM_ID`. Secret names may be inspected with `gh secret list`; never read
|
|
37
|
+
or print secret values.
|
|
38
|
+
|
|
31
39
|
2. Select the release version from the repository root:
|
|
32
40
|
|
|
33
41
|
```bash
|
|
@@ -47,10 +55,12 @@ uv lock
|
|
|
47
55
|
python3 .codex/skills/build-release/scripts/release_build.py preflight --version <version>
|
|
48
56
|
```
|
|
49
57
|
|
|
50
|
-
The preflight requires consistent project and lock metadata, an
|
|
51
|
-
version and tag, clean patch formatting, a frozen lock,
|
|
52
|
-
|
|
53
|
-
|
|
58
|
+
The preflight requires macOS. It checks consistent project and lock metadata, an
|
|
59
|
+
unused PyPI version and tag, clean patch formatting, a frozen lock, Python 3.12
|
|
60
|
+
and 3.13 tests, Ruff, Swift tests, a self-contained app/DMG build for the current
|
|
61
|
+
Mac architecture, app signature and embedded-runtime smoke tests, wheel and
|
|
62
|
+
sdist audits, and a wheel installation smoke test. CI builds and notarizes both
|
|
63
|
+
macOS architectures. Stop at the exact failed gate.
|
|
54
64
|
|
|
55
65
|
4. Review and publish the release commit:
|
|
56
66
|
|
|
@@ -87,12 +97,17 @@ python3 .codex/skills/build-release/scripts/release_build.py wait-pypi --version
|
|
|
87
97
|
gh release view v<version> --json url,tagName,assets
|
|
88
98
|
```
|
|
89
99
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
100
|
+
When macOS publishing is enabled, require both
|
|
101
|
+
`AgentBridge-<version>-macos-arm64.dmg` and
|
|
102
|
+
`AgentBridge-<version>-macos-x86_64.dmg` plus their `.sha256` files in the
|
|
103
|
+
release assets. Do not report success until PyPI returns exact-version files and
|
|
104
|
+
all required GitHub assets exist. If the workflow fails, inspect
|
|
105
|
+
`gh run view <run-id> --log-failed` and report the failed gate before considering
|
|
106
|
+
recovery.
|
|
93
107
|
|
|
94
108
|
## Final Response
|
|
95
109
|
|
|
96
110
|
Lead with the exact PyPI version URL. Report the tag, release workflow URL and
|
|
97
|
-
conclusion, GitHub Release URL, pushed commit,
|
|
98
|
-
On failure, report the exact command or job
|
|
111
|
+
conclusion, GitHub Release URL, pushed commit, every Python distribution, and
|
|
112
|
+
every macOS DMG/checksum filename. On failure, report the exact command or job
|
|
113
|
+
and the next safe recovery action.
|
|
@@ -7,6 +7,7 @@ import argparse
|
|
|
7
7
|
import email.parser
|
|
8
8
|
import hashlib
|
|
9
9
|
import json
|
|
10
|
+
import platform
|
|
10
11
|
import re
|
|
11
12
|
import subprocess
|
|
12
13
|
import sys
|
|
@@ -307,6 +308,40 @@ def smoke_wheel(wheel: Path, version: str) -> None:
|
|
|
307
308
|
run([str(installed_python), "-c", code])
|
|
308
309
|
|
|
309
310
|
|
|
311
|
+
def preflight_macos_app(version: str) -> dict[str, object]:
|
|
312
|
+
if sys.platform != "darwin":
|
|
313
|
+
raise SystemExit("the AgentBridge release preflight requires macOS for app validation")
|
|
314
|
+
|
|
315
|
+
architecture = platform.machine()
|
|
316
|
+
if architecture not in {"arm64", "x86_64"}:
|
|
317
|
+
raise SystemExit(f"unsupported macOS release architecture: {architecture}")
|
|
318
|
+
|
|
319
|
+
run(["swift", "test", "--package-path", "macos"])
|
|
320
|
+
run(["scripts/build_macos_app.sh"])
|
|
321
|
+
|
|
322
|
+
output = REPO_ROOT / "build" / "macos" / architecture
|
|
323
|
+
app = output / "AgentBridge.app"
|
|
324
|
+
dmg = output / f"AgentBridge-{version}-macos-{architecture}.dmg"
|
|
325
|
+
checksum = Path(f"{dmg}.sha256")
|
|
326
|
+
run(["scripts/verify_macos_app.sh", str(app)])
|
|
327
|
+
|
|
328
|
+
if not dmg.is_file() or not checksum.is_file():
|
|
329
|
+
raise SystemExit(f"macOS release artifacts are missing under {output}")
|
|
330
|
+
recorded_hash = checksum.read_text(encoding="utf-8").split(maxsplit=1)[0]
|
|
331
|
+
actual_hash = sha256(dmg)
|
|
332
|
+
if recorded_hash != actual_hash:
|
|
333
|
+
raise SystemExit(f"macOS DMG checksum mismatch: {dmg.name}")
|
|
334
|
+
|
|
335
|
+
result = {
|
|
336
|
+
"file": dmg.name,
|
|
337
|
+
"sha256": actual_hash,
|
|
338
|
+
"architecture": architecture,
|
|
339
|
+
"signing": "local preflight signature",
|
|
340
|
+
}
|
|
341
|
+
print(json.dumps({"macos_app": result}, indent=2))
|
|
342
|
+
return result
|
|
343
|
+
|
|
344
|
+
|
|
310
345
|
def preflight(args: argparse.Namespace) -> None:
|
|
311
346
|
version = args.version
|
|
312
347
|
check_version(version)
|
|
@@ -342,6 +377,7 @@ def preflight(args: argparse.Namespace) -> None:
|
|
|
342
377
|
".codex/skills/build-release/scripts/release_build.py",
|
|
343
378
|
]
|
|
344
379
|
)
|
|
380
|
+
macos_result = preflight_macos_app(version)
|
|
345
381
|
with tempfile.TemporaryDirectory(prefix="agentbridge-release-") as directory:
|
|
346
382
|
output = Path(directory) / "dist"
|
|
347
383
|
run(["uv", "build", "--out-dir", str(output)])
|
|
@@ -356,7 +392,11 @@ def preflight(args: argparse.Namespace) -> None:
|
|
|
356
392
|
smoke_wheel(wheels[0], version)
|
|
357
393
|
print(
|
|
358
394
|
json.dumps(
|
|
359
|
-
{
|
|
395
|
+
{
|
|
396
|
+
"package": PACKAGE_NAME,
|
|
397
|
+
"version": version,
|
|
398
|
+
"artifacts": results + [macos_result],
|
|
399
|
+
},
|
|
360
400
|
indent=2,
|
|
361
401
|
)
|
|
362
402
|
)
|
|
@@ -10,6 +10,18 @@ updates:
|
|
|
10
10
|
cooldown:
|
|
11
11
|
default-days: 7
|
|
12
12
|
open-pull-requests-limit: 5
|
|
13
|
+
groups:
|
|
14
|
+
security-updates:
|
|
15
|
+
applies-to: security-updates
|
|
16
|
+
patterns:
|
|
17
|
+
- "*"
|
|
18
|
+
minor-and-patch:
|
|
19
|
+
applies-to: version-updates
|
|
20
|
+
update-types:
|
|
21
|
+
- minor
|
|
22
|
+
- patch
|
|
23
|
+
patterns:
|
|
24
|
+
- "*"
|
|
13
25
|
|
|
14
26
|
- package-ecosystem: github-actions
|
|
15
27
|
directory: /
|
|
@@ -21,3 +33,10 @@ updates:
|
|
|
21
33
|
cooldown:
|
|
22
34
|
default-days: 7
|
|
23
35
|
open-pull-requests-limit: 5
|
|
36
|
+
groups:
|
|
37
|
+
minor-and-patch:
|
|
38
|
+
update-types:
|
|
39
|
+
- minor
|
|
40
|
+
- patch
|
|
41
|
+
patterns:
|
|
42
|
+
- "*"
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
merge_group:
|
|
9
|
+
types:
|
|
10
|
+
- checks_requested
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
test:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
strategy:
|
|
19
|
+
matrix:
|
|
20
|
+
python-version: ["3.12", "3.13"]
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
23
|
+
with:
|
|
24
|
+
persist-credentials: false
|
|
25
|
+
|
|
26
|
+
- name: Install uv
|
|
27
|
+
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
|
|
28
|
+
with:
|
|
29
|
+
enable-cache: true
|
|
30
|
+
cache-dependency-glob: "uv.lock"
|
|
31
|
+
|
|
32
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
33
|
+
run: uv python install ${{ matrix.python-version }}
|
|
34
|
+
|
|
35
|
+
- name: Install dependencies
|
|
36
|
+
run: uv sync --frozen --extra test --python ${{ matrix.python-version }}
|
|
37
|
+
|
|
38
|
+
- name: Audit dependencies
|
|
39
|
+
run: uv run --frozen --extra test --python ${{ matrix.python-version }} pip-audit
|
|
40
|
+
|
|
41
|
+
- name: Lint
|
|
42
|
+
run: uv run --frozen --extra test --python ${{ matrix.python-version }} ruff check agentbridge tests
|
|
43
|
+
|
|
44
|
+
- name: Run tests
|
|
45
|
+
run: uv run --frozen --extra test --python ${{ matrix.python-version }} pytest -q
|
|
46
|
+
|
|
47
|
+
- name: Smoke test CLI
|
|
48
|
+
run: uv run --frozen --python ${{ matrix.python-version }} agentbridge --help
|
|
49
|
+
|
|
50
|
+
- name: Build package
|
|
51
|
+
if: matrix.python-version == '3.12'
|
|
52
|
+
run: uv build
|
|
@@ -28,7 +28,7 @@ jobs:
|
|
|
28
28
|
outputs:
|
|
29
29
|
should-publish: ${{ steps.publish.outputs.should-publish }}
|
|
30
30
|
steps:
|
|
31
|
-
- uses: actions/checkout@
|
|
31
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
32
32
|
with:
|
|
33
33
|
fetch-depth: 0
|
|
34
34
|
persist-credentials: false
|
|
@@ -52,36 +52,51 @@ jobs:
|
|
|
52
52
|
matrix:
|
|
53
53
|
python-version: ["3.12", "3.13"]
|
|
54
54
|
steps:
|
|
55
|
-
- uses: actions/checkout@
|
|
55
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
56
56
|
with:
|
|
57
57
|
persist-credentials: false
|
|
58
58
|
- name: Install uv
|
|
59
|
-
uses: astral-sh/setup-uv@
|
|
59
|
+
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
|
|
60
60
|
with:
|
|
61
61
|
enable-cache: true
|
|
62
62
|
cache-dependency-glob: "uv.lock"
|
|
63
63
|
- name: Set up Python ${{ matrix.python-version }}
|
|
64
64
|
run: uv python install ${{ matrix.python-version }}
|
|
65
65
|
- name: Install dependencies
|
|
66
|
-
run: uv sync --
|
|
66
|
+
run: uv sync --frozen --extra test --python ${{ matrix.python-version }}
|
|
67
|
+
- name: Audit dependencies
|
|
68
|
+
run: uv run --frozen --extra test --python ${{ matrix.python-version }} pip-audit
|
|
69
|
+
- name: Lint
|
|
70
|
+
run: uv run --frozen --extra test --python ${{ matrix.python-version }} ruff check agentbridge tests
|
|
67
71
|
- name: Run tests
|
|
68
|
-
run: uv run --python ${{ matrix.python-version }} pytest
|
|
72
|
+
run: uv run --frozen --extra test --python ${{ matrix.python-version }} pytest -q
|
|
69
73
|
|
|
70
74
|
pii-scan:
|
|
71
75
|
runs-on: ubuntu-latest
|
|
72
76
|
permissions:
|
|
73
77
|
contents: read
|
|
74
78
|
steps:
|
|
75
|
-
- uses: actions/checkout@
|
|
79
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
76
80
|
with:
|
|
77
81
|
persist-credentials: false
|
|
78
82
|
- name: Run gitleaks
|
|
79
|
-
uses: gitleaks/gitleaks-action@
|
|
83
|
+
uses: gitleaks/gitleaks-action@e0c47f4f8be36e29cdc102c57e68cb5cbf0e8d1e # v3.0.0
|
|
80
84
|
env:
|
|
81
85
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
82
86
|
|
|
87
|
+
macos-test:
|
|
88
|
+
runs-on: macos-15
|
|
89
|
+
permissions:
|
|
90
|
+
contents: read
|
|
91
|
+
steps:
|
|
92
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
93
|
+
with:
|
|
94
|
+
persist-credentials: false
|
|
95
|
+
- name: Test menu-bar app
|
|
96
|
+
run: swift test --package-path macos
|
|
97
|
+
|
|
83
98
|
build:
|
|
84
|
-
needs: [changes, test, pii-scan]
|
|
99
|
+
needs: [changes, test, pii-scan, macos-test]
|
|
85
100
|
if: needs.changes.outputs.should-publish == 'true'
|
|
86
101
|
runs-on: ubuntu-latest
|
|
87
102
|
timeout-minutes: 15
|
|
@@ -91,7 +106,7 @@ jobs:
|
|
|
91
106
|
publish: ${{ steps.check-version.outputs.tag_exists == 'false' }}
|
|
92
107
|
tag: ${{ steps.check-version.outputs.tag }}
|
|
93
108
|
steps:
|
|
94
|
-
- uses: actions/checkout@
|
|
109
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
95
110
|
with:
|
|
96
111
|
fetch-depth: 0
|
|
97
112
|
persist-credentials: false
|
|
@@ -122,7 +137,7 @@ jobs:
|
|
|
122
137
|
echo "Version ${version} maps to ${tag}; tag_exists=${tag_exists}"
|
|
123
138
|
- name: Setup uv
|
|
124
139
|
if: steps.check-version.outputs.tag_exists == 'false'
|
|
125
|
-
uses: astral-sh/setup-uv@
|
|
140
|
+
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
|
|
126
141
|
with:
|
|
127
142
|
enable-cache: true
|
|
128
143
|
cache-dependency-glob: "uv.lock"
|
|
@@ -175,26 +190,126 @@ jobs:
|
|
|
175
190
|
PY
|
|
176
191
|
- name: Store package artifacts
|
|
177
192
|
if: steps.check-version.outputs.tag_exists == 'false'
|
|
178
|
-
uses: actions/upload-artifact@
|
|
193
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
179
194
|
with:
|
|
180
195
|
name: python-package-${{ github.sha }}
|
|
181
196
|
path: dist/
|
|
182
197
|
if-no-files-found: error
|
|
183
198
|
retention-days: 1
|
|
184
199
|
|
|
200
|
+
macos-app:
|
|
201
|
+
needs: [build]
|
|
202
|
+
if: >-
|
|
203
|
+
needs.build.outputs.publish == 'true' &&
|
|
204
|
+
vars.MACOS_RELEASE_ENABLED == 'true'
|
|
205
|
+
strategy:
|
|
206
|
+
fail-fast: false
|
|
207
|
+
matrix:
|
|
208
|
+
include:
|
|
209
|
+
- runner: macos-15
|
|
210
|
+
architecture: arm64
|
|
211
|
+
- runner: macos-15-intel
|
|
212
|
+
architecture: x86_64
|
|
213
|
+
runs-on: ${{ matrix.runner }}
|
|
214
|
+
timeout-minutes: 30
|
|
215
|
+
permissions:
|
|
216
|
+
contents: read
|
|
217
|
+
steps:
|
|
218
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
219
|
+
with:
|
|
220
|
+
persist-credentials: false
|
|
221
|
+
- name: Install uv
|
|
222
|
+
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
|
|
223
|
+
with:
|
|
224
|
+
enable-cache: true
|
|
225
|
+
cache-dependency-glob: "uv.lock"
|
|
226
|
+
- name: Install Python 3.12
|
|
227
|
+
run: uv python install 3.12
|
|
228
|
+
- name: Import Developer ID certificate
|
|
229
|
+
env:
|
|
230
|
+
APPLE_CERTIFICATE_BASE64: ${{ secrets.APPLE_CERTIFICATE_BASE64 }}
|
|
231
|
+
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
|
232
|
+
KEYCHAIN_PASSWORD: ${{ secrets.APPLE_KEYCHAIN_PASSWORD }}
|
|
233
|
+
shell: bash
|
|
234
|
+
run: |
|
|
235
|
+
certificate_path="$RUNNER_TEMP/developer-id.p12"
|
|
236
|
+
keychain_path="$RUNNER_TEMP/agentbridge-signing.keychain-db"
|
|
237
|
+
echo "$APPLE_CERTIFICATE_BASE64" | base64 -D > "$certificate_path"
|
|
238
|
+
security create-keychain -p "$KEYCHAIN_PASSWORD" "$keychain_path"
|
|
239
|
+
security set-keychain-settings -lut 21600 "$keychain_path"
|
|
240
|
+
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$keychain_path"
|
|
241
|
+
security import "$certificate_path" \
|
|
242
|
+
-P "$APPLE_CERTIFICATE_PASSWORD" \
|
|
243
|
+
-A \
|
|
244
|
+
-t cert \
|
|
245
|
+
-f pkcs12 \
|
|
246
|
+
-k "$keychain_path"
|
|
247
|
+
security list-keychain -d user -s "$keychain_path"
|
|
248
|
+
security set-key-partition-list \
|
|
249
|
+
-S apple-tool:,apple: \
|
|
250
|
+
-s \
|
|
251
|
+
-k "$KEYCHAIN_PASSWORD" \
|
|
252
|
+
"$keychain_path"
|
|
253
|
+
identity="$(security find-identity -v -p codesigning "$keychain_path" \
|
|
254
|
+
| sed -n 's/.*"\(Developer ID Application:.*\)"/\1/p' \
|
|
255
|
+
| head -1)"
|
|
256
|
+
test -n "$identity"
|
|
257
|
+
echo "CODE_SIGN_IDENTITY=$identity" >> "$GITHUB_ENV"
|
|
258
|
+
- name: Build signed application
|
|
259
|
+
run: scripts/build_macos_app.sh
|
|
260
|
+
- name: Verify embedded application
|
|
261
|
+
run: scripts/verify_macos_app.sh "build/macos/${{ matrix.architecture }}/AgentBridge.app"
|
|
262
|
+
- name: Notarize and staple disk image
|
|
263
|
+
env:
|
|
264
|
+
APPLE_ID: ${{ secrets.APPLE_NOTARY_APPLE_ID }}
|
|
265
|
+
APPLE_APP_PASSWORD: ${{ secrets.APPLE_NOTARY_PASSWORD }}
|
|
266
|
+
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
|
267
|
+
shell: bash
|
|
268
|
+
run: |
|
|
269
|
+
dmg="$(find "build/macos/${{ matrix.architecture }}" -maxdepth 1 -name '*.dmg' -print -quit)"
|
|
270
|
+
test -n "$dmg"
|
|
271
|
+
xcrun notarytool submit "$dmg" \
|
|
272
|
+
--apple-id "$APPLE_ID" \
|
|
273
|
+
--password "$APPLE_APP_PASSWORD" \
|
|
274
|
+
--team-id "$APPLE_TEAM_ID" \
|
|
275
|
+
--wait
|
|
276
|
+
xcrun stapler staple "$dmg"
|
|
277
|
+
xcrun stapler validate "$dmg"
|
|
278
|
+
shasum -a 256 "$dmg" > "$dmg.sha256"
|
|
279
|
+
- name: Store macOS artifacts
|
|
280
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
281
|
+
with:
|
|
282
|
+
name: macos-app-${{ matrix.architecture }}-${{ github.sha }}
|
|
283
|
+
path: |
|
|
284
|
+
build/macos/${{ matrix.architecture }}/*.dmg
|
|
285
|
+
build/macos/${{ matrix.architecture }}/*.dmg.sha256
|
|
286
|
+
if-no-files-found: error
|
|
287
|
+
retention-days: 1
|
|
288
|
+
|
|
185
289
|
release:
|
|
186
|
-
needs: [build, publish]
|
|
187
|
-
if:
|
|
290
|
+
needs: [build, publish, macos-app]
|
|
291
|
+
if: >-
|
|
292
|
+
always() &&
|
|
293
|
+
needs.build.outputs.publish == 'true' &&
|
|
294
|
+
needs.publish.result == 'success' &&
|
|
295
|
+
(needs.macos-app.result == 'success' || needs.macos-app.result == 'skipped')
|
|
188
296
|
runs-on: ubuntu-latest
|
|
189
297
|
timeout-minutes: 10
|
|
190
298
|
permissions:
|
|
191
299
|
contents: write
|
|
192
300
|
steps:
|
|
193
301
|
- name: Download package artifacts
|
|
194
|
-
uses: actions/download-artifact@
|
|
302
|
+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
195
303
|
with:
|
|
196
304
|
name: python-package-${{ github.sha }}
|
|
197
305
|
path: dist/
|
|
306
|
+
- name: Download macOS artifacts
|
|
307
|
+
if: needs.macos-app.result == 'success'
|
|
308
|
+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
309
|
+
with:
|
|
310
|
+
pattern: macos-app-*-${{ github.sha }}
|
|
311
|
+
path: dist/
|
|
312
|
+
merge-multiple: true
|
|
198
313
|
- name: Create GitHub release
|
|
199
314
|
run: gh release create "$TAG" --title "$TAG" --generate-notes dist/*
|
|
200
315
|
env:
|
|
@@ -215,9 +330,9 @@ jobs:
|
|
|
215
330
|
id-token: write
|
|
216
331
|
steps:
|
|
217
332
|
- name: Setup uv
|
|
218
|
-
uses: astral-sh/setup-uv@
|
|
333
|
+
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
|
|
219
334
|
- name: Download package artifacts
|
|
220
|
-
uses: actions/download-artifact@
|
|
335
|
+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
221
336
|
with:
|
|
222
337
|
name: python-package-${{ github.sha }}
|
|
223
338
|
path: dist/
|
|
@@ -1,10 +1,42 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: agentbridge-cli
|
|
3
|
+
Version: 0.1.12
|
|
4
|
+
Summary: Bridge OpenAI tools to Claude Code SDK, Codex CLI, and OpenRouter
|
|
5
|
+
Project-URL: Homepage, https://github.com/tsilva/agentbridge
|
|
6
|
+
Project-URL: Repository, https://github.com/tsilva/agentbridge
|
|
7
|
+
Project-URL: Issues, https://github.com/tsilva/agentbridge/issues
|
|
8
|
+
Author: tsilva
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: anthropic,api,bridge,claude,claude-code,codex,fastapi,llm,openai,streaming
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Framework :: FastAPI
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
19
|
+
Requires-Python: >=3.12
|
|
20
|
+
Requires-Dist: claude-agent-sdk>=0.2.132
|
|
21
|
+
Requires-Dist: fastapi>=0.141.1
|
|
22
|
+
Requires-Dist: jinja2>=3.1.0
|
|
23
|
+
Requires-Dist: openrouter==1.1.31
|
|
24
|
+
Requires-Dist: pillow>=12.3.0
|
|
25
|
+
Requires-Dist: uvicorn[standard]>=0.32.0
|
|
26
|
+
Provides-Extra: test
|
|
27
|
+
Requires-Dist: pip-audit>=2.9.0; extra == 'test'
|
|
28
|
+
Requires-Dist: pytest-asyncio>=1.4.0; extra == 'test'
|
|
29
|
+
Requires-Dist: pytest>=9.1.1; extra == 'test'
|
|
30
|
+
Requires-Dist: ruff>=0.15.0; extra == 'test'
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
1
33
|
<div align="center">
|
|
2
|
-
<img src="./logo.png" alt="
|
|
34
|
+
<img src="./logo.png" alt="AgentBridge" width="512" />
|
|
3
35
|
|
|
4
|
-
|
|
36
|
+
**OpenAI-compatible routing for Claude Code, Codex, and OpenRouter — use your subscriptions anywhere.**
|
|
5
37
|
</div>
|
|
6
38
|
|
|
7
|
-
|
|
39
|
+
AgentBridge is a local API bridge for developers who want to connect OpenAI-compatible apps to Claude Code, Codex, or OpenRouter. Run one server, choose a backend with a namespaced model ID, and point existing Chat Completions clients at `http://localhost:8082/api/v1`.
|
|
8
40
|
|
|
9
41
|
It supports streaming and non-streaming responses, image and PDF inputs where the backend accepts them, native Codex image editing, strict JSON Schema output, OpenAI-style tool calls, a live dashboard, and local JSON session logs.
|
|
10
42
|
|
|
@@ -12,6 +44,31 @@ It supports streaming and non-streaming responses, image and PDF inputs where th
|
|
|
12
44
|
|
|
13
45
|
## Install
|
|
14
46
|
|
|
47
|
+
### macOS menu-bar app
|
|
48
|
+
|
|
49
|
+
Build the app locally on macOS 13 or later. This requires
|
|
50
|
+
[uv](https://docs.astral.sh/uv/) and the Xcode Command Line Tools, but it does
|
|
51
|
+
not require an Apple Developer account:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
git clone https://github.com/tsilva/agentbridge.git
|
|
55
|
+
cd agentbridge
|
|
56
|
+
scripts/build_macos_app.sh
|
|
57
|
+
open "build/macos/$(uname -m)/AgentBridge-"*.dmg
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Drag `AgentBridge.app` to Applications and open it. The menu-bar window shows
|
|
61
|
+
live server health and activity, starts and stops the local server, opens the
|
|
62
|
+
dashboard, and provides settings for the port, worker count, and launch at
|
|
63
|
+
login. See [`macos/README.md`](macos/README.md) for development instructions.
|
|
64
|
+
|
|
65
|
+
The app contains its own Python 3.12 runtime and AgentBridge dependencies. It
|
|
66
|
+
does not bundle the Claude Code or Codex executables: installed provider tools
|
|
67
|
+
and their existing authentication state remain in the user account. Mutable
|
|
68
|
+
configuration and logs continue to live under `~/.config/agentbridge/`.
|
|
69
|
+
|
|
70
|
+
### Command line
|
|
71
|
+
|
|
15
72
|
```bash
|
|
16
73
|
uv tool install agentbridge-cli
|
|
17
74
|
agentbridge
|
|
@@ -97,14 +154,17 @@ agentbridge --workers 3 # set Claude pool and Code
|
|
|
97
154
|
agentbridge --version # print package and git version
|
|
98
155
|
uv run --frozen --extra test pytest -q # run tests
|
|
99
156
|
uv run --frozen --extra test ruff check agentbridge tests # lint Python
|
|
157
|
+
swift test --package-path macos # test the macOS app
|
|
158
|
+
scripts/build_macos_app.sh # build a local signed app and DMG
|
|
100
159
|
uv lock --check # verify the lockfile
|
|
101
160
|
uv build # build wheel and source distribution
|
|
102
161
|
```
|
|
103
162
|
|
|
104
163
|
## Notes
|
|
105
164
|
|
|
106
|
-
- Python 3.12
|
|
165
|
+
- The CLI requires Python 3.12+; the macOS app bundles Python. At least one authenticated backend is required for provider requests.
|
|
107
166
|
- Public routes include `POST /api/v1/chat/completions`, `POST /api/v1/images`, `GET /api/v1/models`, `GET /api/v1/capabilities`, `GET /health`, `/dashboard`, and `/dashboard/chat`.
|
|
167
|
+
- `GET /health` includes safe operator status used by the menu-bar app: version, start time, uptime, configured workers, active requests, and pool state when initialized.
|
|
108
168
|
- `PORT`, `POOL_SIZE`, `CLAUDE_TIMEOUT`, `CODEX_TIMEOUT`, `CODEX_IMAGE_TIMEOUT`, and `OPENROUTER_TIMEOUT` control the server port, pool size, and provider timeouts. `--workers` overrides `POOL_SIZE`; Codex chat and native image generation default to 600-second timeouts, while Claude and OpenRouter default to 120 seconds.
|
|
109
169
|
- `MAX_IMAGE_INPUT_BYTES`, `MAX_IMAGE_OUTPUT_BYTES`, and `MAX_IMAGE_PIXELS` bound native image requests. Defaults are 64 MiB input, 32 MiB output, and 40 million pixels.
|
|
110
170
|
- `AGENTBRIDGE_CONFIG_DIR` moves the user configuration directory. `LOG_DIR` moves session logs, and `MAX_LOG_FILES` limits retained JSON logs.
|
|
@@ -116,7 +176,12 @@ uv build # build wheel and source d
|
|
|
116
176
|
|
|
117
177
|
## Publishing
|
|
118
178
|
|
|
119
|
-
Releases use the `Release` GitHub Actions workflow and PyPI Trusted Publishing
|
|
179
|
+
Releases use the `Release` GitHub Actions workflow and PyPI Trusted Publishing
|
|
180
|
+
for the `agentbridge-cli` project. The publisher is scoped to owner `tsilva`,
|
|
181
|
+
repository `agentbridge`, workflow `release.yml`, and environment `pypi`; no
|
|
182
|
+
PyPI API token is required. GitHub Releases contain the Python distributions;
|
|
183
|
+
the macOS app is tested in CI and built locally from source. Releases through
|
|
184
|
+
`0.1.10` remain available under the previous `agentbridge-py` distribution name.
|
|
120
185
|
|
|
121
186
|
## Architecture
|
|
122
187
|
|