swiftgate-cli 1.0.4__tar.gz → 1.0.5__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: swiftgate-cli
3
- Version: 1.0.4
3
+ Version: 1.0.5
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
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "swiftgate-cli"
7
- version = "1.0.4"
7
+ version = "1.0.5"
8
8
  description = "SwiftGate CLI — autonomous bidirectional agent bridge for SwiftGate OS"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -146,7 +146,7 @@ class AgentBridge:
146
146
  if not self._running or self._master_fd is None:
147
147
  return
148
148
 
149
- msg = f"\nSwiftGate: You have {count} pending tasks. Call swiftgate_agent_get_task\n"
149
+ msg = f"\r\nSwiftGate: You have {count} pending tasks. Call swiftgate_agent_get_task\r\n"
150
150
  try:
151
151
  os.write(self._master_fd, msg.encode("utf-8"))
152
152
  logger.debug("Wake injected for %s (%d pending)", self._slug, count)
@@ -74,6 +74,26 @@ class APIClient:
74
74
  except Exception:
75
75
  return False
76
76
 
77
+ async def fetch_agent_token(self, workspace_slug: str) -> dict | None:
78
+ """Fetch MCP token + agent config from SwiftGate.
79
+
80
+ Authenticated via account token. Returns dict with
81
+ mcp_token, agent_type, server_url or None on failure.
82
+ """
83
+ url = self._cli_url("start-agent")
84
+ try:
85
+ async with aiohttp.ClientSession() as session:
86
+ async with session.post(
87
+ url, json={"workspace_slug": workspace_slug},
88
+ headers=self._headers(),
89
+ timeout=aiohttp.ClientTimeout(total=10),
90
+ ) as resp:
91
+ if resp.status != 200:
92
+ return None
93
+ return await resp.json()
94
+ except Exception:
95
+ return None
96
+
77
97
  def get_sse_url(self) -> str:
78
98
  """URL for the CLI SSE wake stream."""
79
99
  return self._cli_url("listen")
@@ -39,7 +39,7 @@ logger = logging.getLogger("swiftgate")
39
39
 
40
40
 
41
41
  @click.group()
42
- @click.version_option(version="1.0.4", prog_name="swiftgate-cli")
42
+ @click.version_option(version="1.0.5", prog_name="swiftgate-cli")
43
43
  def cli():
44
44
  """swiftgate-cli — Autonomous bidirectional agent bridge for SwiftGate OS.
45
45
 
@@ -84,16 +84,12 @@ def setup(token: str, server: str):
84
84
 
85
85
  @cli.command()
86
86
  @click.option("--agent", required=True, help="Agent workspace slug")
87
- @click.option("--mcp-token", default="", help="MCP token from agent registration (sg_ea_...)")
87
+ @click.option("--mcp-token", default="", help="MCP token (optional auto-fetched if not provided)")
88
88
  def start(agent: str, mcp_token: str):
89
89
  """Start an agent and bridge it to SwiftGate.
90
90
 
91
- Fetches agent config from SwiftGate, writes MCP configuration,
92
- spawns the agent process, and starts the SSE wake listener.
93
- stdin/stdout is forwarded transparently.
94
-
95
- The MCP token is required on first start. It is stored in
96
- ~/.swiftgate/config.json for subsequent starts.
91
+ MCP token is auto-fetched from SwiftGate using the account token.
92
+ No copy-paste needed just run: swiftgate-cli start --agent my-agent
97
93
  """
98
94
  asyncio.run(_start_async(agent, mcp_token))
99
95
 
@@ -103,18 +99,28 @@ async def _start_async(agent: str, mcp_token: str) -> None:
103
99
  click.echo(click.style("Not set up. Run: swiftgate-cli setup --token sg_acc_...", fg="red"))
104
100
  sys.exit(1)
105
101
 
102
+ client = APIClient()
103
+
106
104
  token = mcp_token or _get_stored_token(agent)
105
+ agent_type = _get_stored_type(agent) or "opencode"
106
+
107
107
  if not token:
108
- click.echo(click.style(
109
- "MCP token required. Copy the full command from the agent creation screen.",
110
- fg="yellow"))
111
- click.echo(f"Usage: swiftgate-cli start --agent {agent} --mcp-token sg_ea_...")
112
- sys.exit(1)
108
+ click.echo("Fetching agent config from SwiftGate...")
109
+ config = await client.fetch_agent_token(agent)
110
+ if config and config.get("mcp_token"):
111
+ token = config["mcp_token"]
112
+ agent_type = config.get("agent_type") or agent_type
113
+ _store_token(agent, token)
114
+ _store_type(agent, agent_type)
115
+ else:
116
+ click.echo(click.style(
117
+ "Could not fetch agent config. Provide MCP token manually:",
118
+ fg="yellow"))
119
+ click.echo(f"Usage: swiftgate-cli start --agent {agent} --mcp-token sg_ea_...")
120
+ sys.exit(1)
113
121
 
114
122
  if mcp_token and mcp_token.startswith("sg_ea_"):
115
123
  _store_token(agent, mcp_token)
116
-
117
- agent_type = _get_stored_type(agent) or "opencode"
118
124
  command = _agent_command(agent_type)
119
125
  if not command:
120
126
  click.echo(click.style(f"Unknown agent type: {agent_type}", fg="red"))
@@ -224,6 +230,14 @@ def _store_token(slug: str, token: str) -> None:
224
230
  save(cfg)
225
231
 
226
232
 
233
+ def _store_type(slug: str, agent_type: str) -> None:
234
+ """Save agent type to local config."""
235
+ from swiftgate_cli.config import load, save
236
+ cfg = load()
237
+ cfg.setdefault("agents", {}).setdefault(slug, {})["type"] = agent_type
238
+ save(cfg)
239
+
240
+
227
241
  def _get_stored_type(slug: str) -> str:
228
242
  """Get saved agent type from local config."""
229
243
  from swiftgate_cli.config import load
File without changes
File without changes
File without changes