raillog-cli 0.1.0__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.
- raillog_cli-0.1.0/PKG-INFO +87 -0
- raillog_cli-0.1.0/README.md +62 -0
- raillog_cli-0.1.0/pyproject.toml +46 -0
- raillog_cli-0.1.0/raillog/__init__.py +1 -0
- raillog_cli-0.1.0/raillog/cli.py +54 -0
- raillog_cli-0.1.0/raillog/client.py +36 -0
- raillog_cli-0.1.0/raillog/cmd_auth.py +92 -0
- raillog_cli-0.1.0/raillog/cmd_bauzuege.py +834 -0
- raillog_cli-0.1.0/raillog/cmd_context.py +68 -0
- raillog_cli-0.1.0/raillog/cmd_install.py +100 -0
- raillog_cli-0.1.0/raillog/cmd_projects.py +114 -0
- raillog_cli-0.1.0/raillog/cmd_queries.py +244 -0
- raillog_cli-0.1.0/raillog/cmd_restrictions.py +188 -0
- raillog_cli-0.1.0/raillog/cmd_stations.py +209 -0
- raillog_cli-0.1.0/raillog/cmd_tracks.py +231 -0
- raillog_cli-0.1.0/raillog/cmd_travels.py +573 -0
- raillog_cli-0.1.0/raillog/cmd_waggons.py +777 -0
- raillog_cli-0.1.0/raillog/data/AGENTS.md +681 -0
- raillog_cli-0.1.0/raillog/guard.py +231 -0
- raillog_cli-0.1.0/raillog/session.py +114 -0
- raillog_cli-0.1.0/raillog_cli.egg-info/PKG-INFO +87 -0
- raillog_cli-0.1.0/raillog_cli.egg-info/SOURCES.txt +25 -0
- raillog_cli-0.1.0/raillog_cli.egg-info/dependency_links.txt +1 -0
- raillog_cli-0.1.0/raillog_cli.egg-info/entry_points.txt +2 -0
- raillog_cli-0.1.0/raillog_cli.egg-info/requires.txt +5 -0
- raillog_cli-0.1.0/raillog_cli.egg-info/top_level.txt +1 -0
- raillog_cli-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: raillog-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: CLI for Raillog V2.0 — railway construction logistics planning
|
|
5
|
+
Author-email: Boschetti Engineering <info@boschetti-engineering.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/boschetti-engineering/raillog
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/boschetti-engineering/raillog/issues
|
|
9
|
+
Keywords: railway,logistics,planning,cli,construction
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Topic :: Utilities
|
|
18
|
+
Requires-Python: >=3.11
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
Requires-Dist: click>=8.1
|
|
21
|
+
Requires-Dist: httpx>=0.27
|
|
22
|
+
Requires-Dist: supabase>=2.7
|
|
23
|
+
Requires-Dist: rich>=13.7
|
|
24
|
+
Requires-Dist: python-dateutil>=2.9
|
|
25
|
+
|
|
26
|
+
# raillog-cli
|
|
27
|
+
|
|
28
|
+
Command-line interface for **Raillog V2.0** — a spatiotemporal logistics planning system for railway construction sites.
|
|
29
|
+
|
|
30
|
+
Manages waggons, Bauzüge (construction train groups), stations, tracks, and Fahrten (trips) within a time-bounded project. The core question the system answers: *"Where is waggon X at time T, and on which track?"*
|
|
31
|
+
|
|
32
|
+
## Install
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pip install raillog-cli
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Requires Python 3.11+. Connects to a Supabase backend — you need a Raillog project URL and credentials.
|
|
39
|
+
|
|
40
|
+
## Quick start
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
raillog auth login
|
|
44
|
+
raillog project list
|
|
45
|
+
raillog project select <n>
|
|
46
|
+
raillog context
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Agent integration (Claude Code, Cursor, Codex, Gemini, opencode)
|
|
50
|
+
|
|
51
|
+
After install, run once in your project directory:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
raillog install-skill
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
This writes:
|
|
58
|
+
- `~/.claude/skills/raillog.md` — Claude Code skill (auto-loaded)
|
|
59
|
+
- `~/.claude/CLAUDE.md` — trigger phrase added
|
|
60
|
+
- `./AGENTS.md` — skill file for Cursor, Codex, Gemini CLI, opencode
|
|
61
|
+
|
|
62
|
+
For Cursor specifically, copy `AGENTS.md` to `.cursor/rules/raillog.mdc`.
|
|
63
|
+
|
|
64
|
+
## Commands
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
raillog auth login, status, refresh, logout
|
|
68
|
+
raillog project list, select, show, create
|
|
69
|
+
raillog station list, show, create, update, delete, impact
|
|
70
|
+
raillog track list, show, create, update, delete, impact, occupation
|
|
71
|
+
raillog waggon list, show, create, update, delete, impact, types,
|
|
72
|
+
position, history, set-zustand, zustand
|
|
73
|
+
raillog bauzug list, show, create, update, compose, delete, impact,
|
|
74
|
+
check-departure, history
|
|
75
|
+
raillog travel list, show, create, update, delete, impact, validate
|
|
76
|
+
raillog restriction list, show, create, delete
|
|
77
|
+
raillog query suggest-track, track-occupation, track-capacity,
|
|
78
|
+
waggon-availability, conflicts
|
|
79
|
+
raillog install-skill
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
All write commands support `--dry-run` and `--yes`.
|
|
83
|
+
All list/query commands support `--json` for agent consumption.
|
|
84
|
+
|
|
85
|
+
## License
|
|
86
|
+
|
|
87
|
+
MIT
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# raillog-cli
|
|
2
|
+
|
|
3
|
+
Command-line interface for **Raillog V2.0** — a spatiotemporal logistics planning system for railway construction sites.
|
|
4
|
+
|
|
5
|
+
Manages waggons, Bauzüge (construction train groups), stations, tracks, and Fahrten (trips) within a time-bounded project. The core question the system answers: *"Where is waggon X at time T, and on which track?"*
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install raillog-cli
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Requires Python 3.11+. Connects to a Supabase backend — you need a Raillog project URL and credentials.
|
|
14
|
+
|
|
15
|
+
## Quick start
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
raillog auth login
|
|
19
|
+
raillog project list
|
|
20
|
+
raillog project select <n>
|
|
21
|
+
raillog context
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Agent integration (Claude Code, Cursor, Codex, Gemini, opencode)
|
|
25
|
+
|
|
26
|
+
After install, run once in your project directory:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
raillog install-skill
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
This writes:
|
|
33
|
+
- `~/.claude/skills/raillog.md` — Claude Code skill (auto-loaded)
|
|
34
|
+
- `~/.claude/CLAUDE.md` — trigger phrase added
|
|
35
|
+
- `./AGENTS.md` — skill file for Cursor, Codex, Gemini CLI, opencode
|
|
36
|
+
|
|
37
|
+
For Cursor specifically, copy `AGENTS.md` to `.cursor/rules/raillog.mdc`.
|
|
38
|
+
|
|
39
|
+
## Commands
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
raillog auth login, status, refresh, logout
|
|
43
|
+
raillog project list, select, show, create
|
|
44
|
+
raillog station list, show, create, update, delete, impact
|
|
45
|
+
raillog track list, show, create, update, delete, impact, occupation
|
|
46
|
+
raillog waggon list, show, create, update, delete, impact, types,
|
|
47
|
+
position, history, set-zustand, zustand
|
|
48
|
+
raillog bauzug list, show, create, update, compose, delete, impact,
|
|
49
|
+
check-departure, history
|
|
50
|
+
raillog travel list, show, create, update, delete, impact, validate
|
|
51
|
+
raillog restriction list, show, create, delete
|
|
52
|
+
raillog query suggest-track, track-occupation, track-capacity,
|
|
53
|
+
waggon-availability, conflicts
|
|
54
|
+
raillog install-skill
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
All write commands support `--dry-run` and `--yes`.
|
|
58
|
+
All list/query commands support `--json` for agent consumption.
|
|
59
|
+
|
|
60
|
+
## License
|
|
61
|
+
|
|
62
|
+
MIT
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "raillog-cli"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "CLI for Raillog V2.0 — railway construction logistics planning"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
authors = [
|
|
12
|
+
{ name = "Boschetti Engineering", email = "info@boschetti-engineering.com" }
|
|
13
|
+
]
|
|
14
|
+
keywords = ["railway", "logistics", "planning", "cli", "construction"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 4 - Beta",
|
|
17
|
+
"Environment :: Console",
|
|
18
|
+
"Intended Audience :: End Users/Desktop",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.11",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
22
|
+
"Programming Language :: Python :: 3.13",
|
|
23
|
+
"Topic :: Utilities",
|
|
24
|
+
]
|
|
25
|
+
requires-python = ">=3.11"
|
|
26
|
+
dependencies = [
|
|
27
|
+
"click>=8.1",
|
|
28
|
+
"httpx>=0.27",
|
|
29
|
+
"supabase>=2.7",
|
|
30
|
+
"rich>=13.7",
|
|
31
|
+
"python-dateutil>=2.9",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
[project.urls]
|
|
35
|
+
Homepage = "https://github.com/boschetti-engineering/raillog"
|
|
36
|
+
"Bug Tracker" = "https://github.com/boschetti-engineering/raillog/issues"
|
|
37
|
+
|
|
38
|
+
[project.scripts]
|
|
39
|
+
raillog = "raillog.cli:cli"
|
|
40
|
+
|
|
41
|
+
[tool.setuptools.packages.find]
|
|
42
|
+
where = ["."]
|
|
43
|
+
include = ["raillog*"]
|
|
44
|
+
|
|
45
|
+
[tool.setuptools.package-data]
|
|
46
|
+
raillog = ["data/AGENTS.md"]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.0"
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""
|
|
2
|
+
raillog — main CLI entry point.
|
|
3
|
+
|
|
4
|
+
Registers all command groups. This is the `raillog` command installed by pip.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import click
|
|
10
|
+
from rich.console import Console
|
|
11
|
+
|
|
12
|
+
from raillog import __version__
|
|
13
|
+
from raillog.cmd_auth import auth_group
|
|
14
|
+
from raillog.cmd_projects import project_group
|
|
15
|
+
from raillog.cmd_context import context_cmd
|
|
16
|
+
from raillog.cmd_stations import station_group
|
|
17
|
+
from raillog.cmd_tracks import track_group
|
|
18
|
+
from raillog.cmd_bauzuege import bauzug_group
|
|
19
|
+
from raillog.cmd_waggons import waggon_group
|
|
20
|
+
from raillog.cmd_travels import travel_group
|
|
21
|
+
from raillog.cmd_restrictions import restriction_group
|
|
22
|
+
from raillog.cmd_queries import query_group
|
|
23
|
+
from raillog.cmd_install import install_skill
|
|
24
|
+
|
|
25
|
+
console = Console()
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@click.group()
|
|
29
|
+
@click.version_option(__version__, prog_name="raillog")
|
|
30
|
+
def cli() -> None:
|
|
31
|
+
"""
|
|
32
|
+
Raillog V2.0 — railway construction logistics CLI.
|
|
33
|
+
|
|
34
|
+
\b
|
|
35
|
+
Quick start:
|
|
36
|
+
raillog auth login
|
|
37
|
+
raillog project list
|
|
38
|
+
raillog project select <n>
|
|
39
|
+
raillog context
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
# ── Register all command groups ───────────────────────────────────────────────
|
|
44
|
+
cli.add_command(auth_group)
|
|
45
|
+
cli.add_command(project_group)
|
|
46
|
+
cli.add_command(context_cmd)
|
|
47
|
+
cli.add_command(station_group)
|
|
48
|
+
cli.add_command(track_group)
|
|
49
|
+
cli.add_command(bauzug_group)
|
|
50
|
+
cli.add_command(waggon_group)
|
|
51
|
+
cli.add_command(travel_group)
|
|
52
|
+
cli.add_command(restriction_group)
|
|
53
|
+
cli.add_command(query_group)
|
|
54
|
+
cli.add_command(install_skill)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Supabase client factory.
|
|
3
|
+
|
|
4
|
+
Builds a supabase-py client and injects the stored JWT so every
|
|
5
|
+
request is authenticated as the logged-in user (respecting RLS).
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from supabase import Client, create_client
|
|
11
|
+
|
|
12
|
+
SUPABASE_URL = "https://ouilcwrgxsirpvkzsdkq.supabase.co"
|
|
13
|
+
SUPABASE_ANON_KEY = (
|
|
14
|
+
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"
|
|
15
|
+
".eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im91aWxjd3JneHNpcnB2a3pzZGtxIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjU4MzMzNzYsImV4cCI6MjA4MTQwOTM3Nn0"
|
|
16
|
+
".WRR4puUXDvS46w7rsc1sHT6cz8_A1pL-1yzK47v7aqI"
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def get_client(access_token: str | None = None) -> Client:
|
|
21
|
+
"""
|
|
22
|
+
Return a Supabase client.
|
|
23
|
+
If access_token is provided, set it on the client so RLS applies.
|
|
24
|
+
"""
|
|
25
|
+
sb = create_client(SUPABASE_URL, SUPABASE_ANON_KEY)
|
|
26
|
+
if access_token:
|
|
27
|
+
# Inject user JWT — required for RLS to work correctly
|
|
28
|
+
sb.postgrest.auth(access_token)
|
|
29
|
+
return sb
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def authed_client() -> Client:
|
|
33
|
+
"""Shortcut: load session and return authenticated client."""
|
|
34
|
+
from raillog import session as sess
|
|
35
|
+
s = sess.require_auth()
|
|
36
|
+
return get_client(s["access_token"])
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"""raillog auth {login,status,logout}"""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import time
|
|
6
|
+
|
|
7
|
+
import click
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
|
|
10
|
+
from raillog import session as sess
|
|
11
|
+
from raillog.client import get_client, SUPABASE_URL
|
|
12
|
+
|
|
13
|
+
console = Console()
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@click.group("auth")
|
|
17
|
+
def auth_group() -> None:
|
|
18
|
+
"""Authenticate with Raillog (Supabase)."""
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@auth_group.command("login")
|
|
22
|
+
def auth_login() -> None:
|
|
23
|
+
"""Log in with email and password."""
|
|
24
|
+
console.print("[bold]Raillog Login[/bold]")
|
|
25
|
+
email = click.prompt("Email")
|
|
26
|
+
password = click.prompt("Password", hide_input=True)
|
|
27
|
+
|
|
28
|
+
sb = get_client()
|
|
29
|
+
try:
|
|
30
|
+
result = sb.auth.sign_in_with_password({"email": email, "password": password})
|
|
31
|
+
except Exception as e:
|
|
32
|
+
raise SystemExit(f"Login failed: {e}") from e
|
|
33
|
+
|
|
34
|
+
if not result.session:
|
|
35
|
+
raise SystemExit("Login failed: no session returned.")
|
|
36
|
+
|
|
37
|
+
s = result.session
|
|
38
|
+
user = result.user
|
|
39
|
+
|
|
40
|
+
sess.save({
|
|
41
|
+
"access_token": s.access_token,
|
|
42
|
+
"refresh_token": s.refresh_token,
|
|
43
|
+
"expires_at": s.expires_at or int(time.time()) + 3600,
|
|
44
|
+
"user_id": str(user.id) if user else "",
|
|
45
|
+
"user_email": user.email or email,
|
|
46
|
+
"project_id": None,
|
|
47
|
+
"project_name": None,
|
|
48
|
+
"access_level": None,
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
console.print(f"[green]Logged in as[/green] [bold]{user.email}[/bold]")
|
|
52
|
+
console.print("Run [cyan]raillog project list[/cyan] to select a project.")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@auth_group.command("status")
|
|
56
|
+
def auth_status() -> None:
|
|
57
|
+
"""Show current authentication status."""
|
|
58
|
+
s = sess.load()
|
|
59
|
+
if not s:
|
|
60
|
+
console.print("[red]Not authenticated.[/red] Run: raillog auth login")
|
|
61
|
+
return
|
|
62
|
+
|
|
63
|
+
if not sess.is_valid(s):
|
|
64
|
+
console.print("[yellow]Session expired.[/yellow] Run: raillog auth login")
|
|
65
|
+
return
|
|
66
|
+
|
|
67
|
+
remaining = s.get("expires_at", 0) - int(time.time())
|
|
68
|
+
hours = remaining // 3600
|
|
69
|
+
console.print(f"[green]Authenticated[/green] as [bold]{s.get('user_email')}[/bold]")
|
|
70
|
+
console.print(f"Session expires in ~{hours}h")
|
|
71
|
+
if s.get("project_id"):
|
|
72
|
+
console.print(f"Active project: [bold]{s.get('project_name')}[/bold] ({s.get('project_id')})")
|
|
73
|
+
else:
|
|
74
|
+
console.print("[dim]No project selected.[/dim]")
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@auth_group.command("refresh")
|
|
78
|
+
def auth_refresh() -> None:
|
|
79
|
+
"""Silently renew the session using the stored refresh token."""
|
|
80
|
+
if sess._try_refresh():
|
|
81
|
+
s = sess.load()
|
|
82
|
+
remaining = ((s or {}).get("expires_at", 0) - int(time.time())) // 3600
|
|
83
|
+
console.print(f"[green]Session refreshed.[/green] Expires in ~{remaining}h")
|
|
84
|
+
else:
|
|
85
|
+
raise SystemExit("Refresh failed — run: raillog auth login")
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@auth_group.command("logout")
|
|
89
|
+
def auth_logout() -> None:
|
|
90
|
+
"""Clear the local session."""
|
|
91
|
+
sess.clear()
|
|
92
|
+
console.print("[green]Logged out.[/green]")
|