lightnow-cli 1.3.0__tar.gz → 1.3.1__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.
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/.github/workflows/release.yml +24 -0
- lightnow_cli-1.3.1/.release-please-manifest.json +3 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/CHANGELOG.md +7 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/PKG-INFO +1 -1
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/docs/release.md +10 -6
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/lightnow_cli/__init__.py +1 -1
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/lightnow_cli/commands/integrations.py +12 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/pyproject.toml +1 -1
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/tests/test_integrations.py +45 -0
- lightnow_cli-1.3.0/.release-please-manifest.json +0 -3
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/.github/workflows/ci.yml +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/.github/workflows/release-please.yml +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/.gitignore +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/CONTRIBUTING.md +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/LICENSE +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/Makefile +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/README.md +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/SECURITY.md +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/docs/development.md +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/examples/README.md +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/examples/docs.md +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/examples/openapi.json +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/examples/server.json +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/lightnow_cli/authenticated_http.py +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/lightnow_cli/client.py +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/lightnow_cli/commands/__init__.py +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/lightnow_cli/commands/auth.py +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/lightnow_cli/commands/context.py +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/lightnow_cli/commands/publish.py +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/lightnow_cli/commands/query.py +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/lightnow_cli/commands/runner.py +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/lightnow_cli/commands/validate.py +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/lightnow_cli/config.py +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/lightnow_cli/main.py +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/lightnow_cli/tls.py +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/lightnow_cli/validation.py +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/release-please-config.json +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/tests/__init__.py +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/tests/test_auth_flow.py +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/tests/test_authenticated_http.py +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/tests/test_cli.py +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/tests/test_client.py +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/tests/test_config.py +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/tests/test_context.py +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/tests/test_tls.py +0 -0
- {lightnow_cli-1.3.0 → lightnow_cli-1.3.1}/tests/test_validation.py +0 -0
|
@@ -96,3 +96,27 @@ jobs:
|
|
|
96
96
|
|
|
97
97
|
- name: Publish distributions to PyPI
|
|
98
98
|
uses: pypa/gh-action-pypi-publish@release/v1
|
|
99
|
+
|
|
100
|
+
update-homebrew:
|
|
101
|
+
name: Update Homebrew formula
|
|
102
|
+
runs-on: ubuntu-latest
|
|
103
|
+
needs: publish-pypi
|
|
104
|
+
|
|
105
|
+
steps:
|
|
106
|
+
- name: Dispatch published version to Homebrew tap
|
|
107
|
+
env:
|
|
108
|
+
GH_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
|
|
109
|
+
TAG_NAME: ${{ github.ref_name }}
|
|
110
|
+
run: |
|
|
111
|
+
version="${TAG_NAME#v}"
|
|
112
|
+
payload="$(jq -n \
|
|
113
|
+
--arg formula "lightnow-cli" \
|
|
114
|
+
--arg version "$version" \
|
|
115
|
+
'{event_type: "python-release-published", client_payload: {formula: $formula, version: $version}}')"
|
|
116
|
+
curl --fail-with-body --silent --show-error \
|
|
117
|
+
--request POST \
|
|
118
|
+
--header "Accept: application/vnd.github+json" \
|
|
119
|
+
--header "Authorization: Bearer ${GH_TOKEN}" \
|
|
120
|
+
--header "X-GitHub-Api-Version: 2022-11-28" \
|
|
121
|
+
https://api.github.com/repos/lightnow-ai/homebrew-tap/dispatches \
|
|
122
|
+
--data "$payload"
|
|
@@ -4,6 +4,13 @@ All notable changes to the LightNow CLI are documented here.
|
|
|
4
4
|
|
|
5
5
|
This project follows semantic versioning.
|
|
6
6
|
|
|
7
|
+
## [1.3.1](https://github.com/lightnow-ai/lightnow-cli/compare/v1.3.0...v1.3.1) (2026-07-17)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Bug Fixes
|
|
11
|
+
|
|
12
|
+
* **sync:** replace existing codex proxy connection ([c09b7f7](https://github.com/lightnow-ai/lightnow-cli/commit/c09b7f75f9d78c943ed7556b10b10ff99dbb2008))
|
|
13
|
+
|
|
7
14
|
## [1.3.0](https://github.com/lightnow-ai/lightnow-cli/compare/v1.2.0...v1.3.0) (2026-07-15)
|
|
8
15
|
|
|
9
16
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lightnow-cli
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.1
|
|
4
4
|
Summary: Official LightNow CLI for MCP registry discovery, client config sync, and local MCP runner workflows
|
|
5
5
|
Project-URL: Homepage, https://github.com/lightnow-ai/lightnow-cli
|
|
6
6
|
Project-URL: Repository, https://github.com/lightnow-ai/lightnow-cli
|
|
@@ -19,6 +19,9 @@ Required GitHub setup:
|
|
|
19
19
|
- Repository secret: `RELEASE_PLEASE_TOKEN`
|
|
20
20
|
- Token permissions: contents, pull requests, and issues read/write for this
|
|
21
21
|
repository
|
|
22
|
+
- Repository secret: `HOMEBREW_TAP_TOKEN`
|
|
23
|
+
- Token permissions: contents read/write for `lightnow-ai/homebrew-tap`; the
|
|
24
|
+
token is used only to send the post-PyPI repository dispatch
|
|
22
25
|
- Repository Actions setting: allow GitHub Actions to create pull requests
|
|
23
26
|
|
|
24
27
|
Use a real PAT or GitHub App token for `RELEASE_PLEASE_TOKEN`, not the default
|
|
@@ -33,7 +36,9 @@ Normal release flow:
|
|
|
33
36
|
4. Release Please creates the `vX.Y.Z` tag and GitHub Release.
|
|
34
37
|
5. The existing tag-based `Release` workflow builds and publishes PyPI
|
|
35
38
|
distributions through Trusted Publishing.
|
|
36
|
-
6.
|
|
39
|
+
6. After PyPI succeeds, the release workflow dispatches the exact published
|
|
40
|
+
version to `lightnow-ai/homebrew-tap`. The tap regenerates, audits, installs,
|
|
41
|
+
and tests the formula before committing it.
|
|
37
42
|
|
|
38
43
|
Manual release checklist for fallback or first-time setup:
|
|
39
44
|
|
|
@@ -64,11 +69,10 @@ Manual release checklist for fallback or first-time setup:
|
|
|
64
69
|
- `twine check` passes,
|
|
65
70
|
- a GitHub Release is created with generated release notes and distribution artifacts,
|
|
66
71
|
- PyPI publish succeeds through Trusted Publishing.
|
|
67
|
-
8.
|
|
68
|
-
|
|
69
|
-
-
|
|
70
|
-
|
|
71
|
-
- run `brew audit`, `brew install --build-from-source`, and `brew test`.
|
|
72
|
+
8. Verify the `Update formula` workflow in `lightnow-ai/homebrew-tap`. For a
|
|
73
|
+
recovery run, dispatch it manually with formula `lightnow-cli` and the exact
|
|
74
|
+
already-published version; it uses the same generation and verification path
|
|
75
|
+
as the automatic release dispatch.
|
|
72
76
|
|
|
73
77
|
Do not publish with long-lived local PyPI tokens.
|
|
74
78
|
|
|
@@ -602,6 +602,8 @@ def sync(
|
|
|
602
602
|
)
|
|
603
603
|
if local_proxy and remove_unmanaged_client_servers:
|
|
604
604
|
removed_direct_servers = direct_server_aliases(existing, export_format)
|
|
605
|
+
if local_proxy and client == "codex" and export_format == "toml":
|
|
606
|
+
existing = remove_codex_mcp_server_alias(existing, connection)
|
|
605
607
|
if (
|
|
606
608
|
local_proxy
|
|
607
609
|
and remove_unmanaged_client_servers
|
|
@@ -2281,6 +2283,16 @@ def prepare_codex_local_proxy_config(existing: str) -> str:
|
|
|
2281
2283
|
return strip_codex_mcp_server_tables(existing, preserved)
|
|
2282
2284
|
|
|
2283
2285
|
|
|
2286
|
+
def remove_codex_mcp_server_alias(existing: str, alias: str) -> str:
|
|
2287
|
+
"""Remove one Codex MCP table before writing its managed replacement."""
|
|
2288
|
+
if not existing.strip():
|
|
2289
|
+
return existing
|
|
2290
|
+
entries = extract_mcp_entries(existing, "toml")
|
|
2291
|
+
if alias not in entries:
|
|
2292
|
+
return existing
|
|
2293
|
+
return strip_codex_mcp_server_tables(existing, set(entries) - {alias})
|
|
2294
|
+
|
|
2295
|
+
|
|
2284
2296
|
def prepare_json_local_proxy_config(existing: str) -> str:
|
|
2285
2297
|
"""Remove direct JSON servers while preserving existing proxy connections."""
|
|
2286
2298
|
if not existing.strip():
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "lightnow-cli"
|
|
7
|
-
version = "1.3.
|
|
7
|
+
version = "1.3.1"
|
|
8
8
|
description = "Official LightNow CLI for MCP registry discovery, client config sync, and local MCP runner workflows"
|
|
9
9
|
authors = [{name = "LightNow Team"}]
|
|
10
10
|
license = {text = "Apache-2.0"}
|
|
@@ -1491,6 +1491,51 @@ def test_sync_local_proxy_replaces_existing_codex_mcp_servers() -> None:
|
|
|
1491
1491
|
assert proxy_payload["upstreams"] == {}
|
|
1492
1492
|
|
|
1493
1493
|
|
|
1494
|
+
def test_sync_local_proxy_replaces_legacy_unmanaged_codex_connection_once() -> None:
|
|
1495
|
+
"""Re-sync migrates a pre-marker LightNow entry without duplicating its table."""
|
|
1496
|
+
runner = CliRunner()
|
|
1497
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
1498
|
+
target = Path(tmp) / "config.toml"
|
|
1499
|
+
proxy_config = Path(tmp) / "codex.yaml"
|
|
1500
|
+
target.write_text(
|
|
1501
|
+
'model = "gpt-5.5"\n\n'
|
|
1502
|
+
"[mcp_servers.lightnow]\n"
|
|
1503
|
+
'command = "lightnow-proxy"\n'
|
|
1504
|
+
'args = ["--config", "/tmp/legacy.yaml", "--transport", "stdio"]\n\n'
|
|
1505
|
+
"[mcp_servers.computer-use]\n"
|
|
1506
|
+
'command = "computer-use"\n\n'
|
|
1507
|
+
"[plugins.browser]\n"
|
|
1508
|
+
"enabled = true\n"
|
|
1509
|
+
)
|
|
1510
|
+
with patch(
|
|
1511
|
+
"lightnow_cli.commands.integrations.require_access_token",
|
|
1512
|
+
return_value="token",
|
|
1513
|
+
):
|
|
1514
|
+
result = runner.invoke(
|
|
1515
|
+
app,
|
|
1516
|
+
[
|
|
1517
|
+
"sync",
|
|
1518
|
+
"--client",
|
|
1519
|
+
"codex",
|
|
1520
|
+
"--local-proxy",
|
|
1521
|
+
"--yes",
|
|
1522
|
+
"--local-proxy-config-path",
|
|
1523
|
+
str(proxy_config),
|
|
1524
|
+
"--config-path",
|
|
1525
|
+
str(target),
|
|
1526
|
+
],
|
|
1527
|
+
)
|
|
1528
|
+
|
|
1529
|
+
patched = target.read_text()
|
|
1530
|
+
payload = tomllib.loads(patched)
|
|
1531
|
+
|
|
1532
|
+
assert result.exit_code == 0
|
|
1533
|
+
assert patched.count("[mcp_servers.lightnow]") == 1
|
|
1534
|
+
assert set(payload["mcp_servers"]) == {"lightnow"}
|
|
1535
|
+
assert payload["mcp_servers"]["lightnow"]["args"][1] == str(proxy_config)
|
|
1536
|
+
assert payload["plugins"]["browser"]["enabled"] is True
|
|
1537
|
+
|
|
1538
|
+
|
|
1494
1539
|
def test_sync_local_proxy_updates_default_profile_config_alias() -> None:
|
|
1495
1540
|
"""Default-profile sync also updates the config path used by lightnow-proxy --health."""
|
|
1496
1541
|
runner = CliRunner()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|