swiftgate-cli 1.0.2__tar.gz → 1.0.4__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.
- swiftgate_cli-1.0.4/.gitignore +1 -0
- {swiftgate_cli-1.0.2 → swiftgate_cli-1.0.4}/PKG-INFO +1 -1
- {swiftgate_cli-1.0.2 → swiftgate_cli-1.0.4}/pyproject.toml +1 -1
- {swiftgate_cli-1.0.2 → swiftgate_cli-1.0.4}/src/swiftgate_cli/agent_bridge.py +40 -1
- {swiftgate_cli-1.0.2 → swiftgate_cli-1.0.4}/src/swiftgate_cli/config.py +6 -0
- {swiftgate_cli-1.0.2 → swiftgate_cli-1.0.4}/src/swiftgate_cli/main.py +5 -1
- {swiftgate_cli-1.0.2 → swiftgate_cli-1.0.4}/LICENSE +0 -0
- {swiftgate_cli-1.0.2 → swiftgate_cli-1.0.4}/README.md +0 -0
- {swiftgate_cli-1.0.2 → swiftgate_cli-1.0.4}/src/swiftgate_cli/__init__.py +0 -0
- {swiftgate_cli-1.0.2 → swiftgate_cli-1.0.4}/src/swiftgate_cli/__main__.py +0 -0
- {swiftgate_cli-1.0.2 → swiftgate_cli-1.0.4}/src/swiftgate_cli/api_client.py +0 -0
- {swiftgate_cli-1.0.2 → swiftgate_cli-1.0.4}/src/swiftgate_cli/sse_listener.py +0 -0
- {swiftgate_cli-1.0.2 → swiftgate_cli-1.0.4}/tests/test_agent_bridge.py +0 -0
- {swiftgate_cli-1.0.2 → swiftgate_cli-1.0.4}/tests/test_config.py +0 -0
- {swiftgate_cli-1.0.2 → swiftgate_cli-1.0.4}/tests/test_sse_listener.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__pycache__/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: swiftgate-cli
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.4
|
|
4
4
|
Summary: SwiftGate CLI — autonomous bidirectional agent bridge for SwiftGate OS
|
|
5
5
|
Project-URL: Homepage, https://swiftgate.ai
|
|
6
6
|
Project-URL: Repository, https://github.com/thetaroot/swiftgate
|
|
@@ -9,11 +9,13 @@ from __future__ import annotations
|
|
|
9
9
|
|
|
10
10
|
import asyncio
|
|
11
11
|
import errno
|
|
12
|
+
import fcntl
|
|
12
13
|
import json
|
|
13
14
|
import logging
|
|
14
15
|
import os
|
|
15
16
|
import pty
|
|
16
17
|
import signal
|
|
18
|
+
import struct
|
|
17
19
|
import sys
|
|
18
20
|
import tty
|
|
19
21
|
from pathlib import Path
|
|
@@ -90,6 +92,18 @@ class AgentBridge:
|
|
|
90
92
|
logger.error("Failed to open pty: %s", exc)
|
|
91
93
|
return False
|
|
92
94
|
|
|
95
|
+
# 2.5 Set pty window size to match parent terminal
|
|
96
|
+
try:
|
|
97
|
+
term_size = os.get_terminal_size()
|
|
98
|
+
winsize = struct.pack("HHHH", term_size.lines, term_size.columns, 0, 0)
|
|
99
|
+
fcntl.ioctl(master_fd, termios.TIOCSWINSZ, winsize)
|
|
100
|
+
os.environ["COLUMNS"] = str(term_size.columns)
|
|
101
|
+
os.environ["LINES"] = str(term_size.lines)
|
|
102
|
+
logger.debug("Pty window size set: %dx%d",
|
|
103
|
+
term_size.columns, term_size.lines)
|
|
104
|
+
except (OSError, AttributeError):
|
|
105
|
+
pass
|
|
106
|
+
|
|
93
107
|
# 3. Fork
|
|
94
108
|
pid = os.fork()
|
|
95
109
|
if pid == 0:
|
|
@@ -132,7 +146,7 @@ class AgentBridge:
|
|
|
132
146
|
if not self._running or self._master_fd is None:
|
|
133
147
|
return
|
|
134
148
|
|
|
135
|
-
msg = f"\
|
|
149
|
+
msg = f"\nSwiftGate: You have {count} pending tasks. Call swiftgate_agent_get_task\n"
|
|
136
150
|
try:
|
|
137
151
|
os.write(self._master_fd, msg.encode("utf-8"))
|
|
138
152
|
logger.debug("Wake injected for %s (%d pending)", self._slug, count)
|
|
@@ -165,6 +179,24 @@ class AgentBridge:
|
|
|
165
179
|
except (termios.error, OSError):
|
|
166
180
|
pass
|
|
167
181
|
|
|
182
|
+
# SIGWINCH handler: propagate terminal resize to pty
|
|
183
|
+
old_winch = signal.SIG_DFL
|
|
184
|
+
|
|
185
|
+
def _resize_pty(_sig: int, _frame) -> None:
|
|
186
|
+
try:
|
|
187
|
+
cols, rows = os.get_terminal_size()
|
|
188
|
+
winsize = struct.pack("HHHH", rows, cols, 0, 0)
|
|
189
|
+
fcntl.ioctl(master_fd, termios.TIOCSWINSZ, winsize)
|
|
190
|
+
os.environ["COLUMNS"] = str(cols)
|
|
191
|
+
os.environ["LINES"] = str(rows)
|
|
192
|
+
except OSError:
|
|
193
|
+
pass
|
|
194
|
+
|
|
195
|
+
try:
|
|
196
|
+
old_winch = signal.signal(signal.SIGWINCH, _resize_pty)
|
|
197
|
+
except OSError:
|
|
198
|
+
pass
|
|
199
|
+
|
|
168
200
|
stop_event = asyncio.Event()
|
|
169
201
|
|
|
170
202
|
def _stdin_to_pty():
|
|
@@ -215,6 +247,13 @@ class AgentBridge:
|
|
|
215
247
|
except (termios.error, OSError):
|
|
216
248
|
pass
|
|
217
249
|
|
|
250
|
+
# Restore SIGWINCH handler
|
|
251
|
+
if old_winch != signal.SIG_DFL:
|
|
252
|
+
try:
|
|
253
|
+
signal.signal(signal.SIGWINCH, old_winch)
|
|
254
|
+
except OSError:
|
|
255
|
+
pass
|
|
256
|
+
|
|
218
257
|
# ── Lifecycle ────────────────────────────────────────────────────────────
|
|
219
258
|
|
|
220
259
|
async def wait(self) -> int:
|
|
@@ -33,6 +33,12 @@ def _ensure_config_dir() -> None:
|
|
|
33
33
|
pass
|
|
34
34
|
|
|
35
35
|
|
|
36
|
+
def ensure_config_dir() -> Path:
|
|
37
|
+
"""Ensure ~/.swiftgate/ exists and return its path."""
|
|
38
|
+
_ensure_config_dir()
|
|
39
|
+
return _CONFIG_DIR
|
|
40
|
+
|
|
41
|
+
|
|
36
42
|
def _set_permissions(path: Path) -> None:
|
|
37
43
|
"""Set file permissions to 0600 (owner read/write only)."""
|
|
38
44
|
try:
|
|
@@ -18,6 +18,7 @@ from typing import Optional
|
|
|
18
18
|
import click
|
|
19
19
|
|
|
20
20
|
from swiftgate_cli.config import (
|
|
21
|
+
ensure_config_dir,
|
|
21
22
|
is_setup, set_setup, get_server, list_agents as cfg_list_agents,
|
|
22
23
|
add_agent as cfg_add_agent, remove_agent as cfg_remove_agent,
|
|
23
24
|
get_agent as cfg_get_agent,
|
|
@@ -26,16 +27,19 @@ from swiftgate_cli.api_client import APIClient
|
|
|
26
27
|
from swiftgate_cli.sse_listener import SSEWakeListener
|
|
27
28
|
from swiftgate_cli.agent_bridge import AgentBridge
|
|
28
29
|
|
|
30
|
+
_log_dir = ensure_config_dir()
|
|
29
31
|
logging.basicConfig(
|
|
30
32
|
level=logging.INFO,
|
|
31
33
|
format="%(asctime)s [%(name)s] %(levelname)s: %(message)s",
|
|
32
34
|
datefmt="%H:%M:%S",
|
|
35
|
+
filename=str(_log_dir / "swiftgate-cli.log"),
|
|
36
|
+
filemode="a",
|
|
33
37
|
)
|
|
34
38
|
logger = logging.getLogger("swiftgate")
|
|
35
39
|
|
|
36
40
|
|
|
37
41
|
@click.group()
|
|
38
|
-
@click.version_option(version="1.0.
|
|
42
|
+
@click.version_option(version="1.0.4", prog_name="swiftgate-cli")
|
|
39
43
|
def cli():
|
|
40
44
|
"""swiftgate-cli — Autonomous bidirectional agent bridge for SwiftGate OS.
|
|
41
45
|
|
|
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
|