simplicio-loop 3.4.0__tar.gz → 3.9.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.
Files changed (51) hide show
  1. {simplicio_loop-3.4.0/simplicio_loop.egg-info → simplicio_loop-3.9.0}/PKG-INFO +1 -1
  2. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/README.md +53 -11
  3. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/pyproject.toml +1 -1
  4. simplicio_loop-3.9.0/simplicio_loop/__init__.py +18 -0
  5. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/hooks/simplicio_dashboard.py +11 -3
  6. simplicio_loop-3.9.0/simplicio_loop/cli.py +180 -0
  7. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0/simplicio_loop.egg-info}/PKG-INFO +1 -1
  8. simplicio_loop-3.4.0/simplicio_loop/__init__.py +0 -8
  9. simplicio_loop-3.4.0/simplicio_loop/cli.py +0 -76
  10. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/LICENSE +0 -0
  11. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/MANIFEST.in +0 -0
  12. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/PYPI.md +0 -0
  13. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/setup.cfg +0 -0
  14. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/hooks/README.md +0 -0
  15. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/hooks/action_gate.py +0 -0
  16. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/hooks/hooks.claude.json +0 -0
  17. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/hooks/hooks.json +0 -0
  18. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/hooks/learn_stop.py +0 -0
  19. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/hooks/loop_capture.py +0 -0
  20. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/hooks/loop_stop.py +0 -0
  21. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/hooks/orient_clamp.py +0 -0
  22. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/hooks/orient_rewrite.py +0 -0
  23. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/hooks/simplicio_watch.py +0 -0
  24. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/skills/simplicio-compress/SKILL.md +0 -0
  25. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/skills/simplicio-learn/SKILL.md +0 -0
  26. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/skills/simplicio-loop/SKILL.md +0 -0
  27. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/skills/simplicio-orient/SKILL.md +0 -0
  28. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/skills/simplicio-review/SKILL.md +0 -0
  29. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/skills/simplicio-tasks/SKILL.md +0 -0
  30. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/skills/simplicio-tasks/references/agentsview-adapter.md +0 -0
  31. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/skills/simplicio-tasks/references/azure-devops-adapter.md +0 -0
  32. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/skills/simplicio-tasks/references/extension-points.md +0 -0
  33. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/skills/simplicio-tasks/references/headroom-adapter.md +0 -0
  34. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/skills/simplicio-tasks/references/lmcache-adapter.md +0 -0
  35. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/skills/simplicio-tasks/references/orchestration.md +0 -0
  36. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/skills/simplicio-tasks/references/quality-safety-delivery.md +0 -0
  37. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/skills/simplicio-tasks/references/standing-loop-247.md +0 -0
  38. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/skills/simplicio-tasks/references/token-capture.md +0 -0
  39. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/skills/simplicio-tasks/references/token-economy.md +0 -0
  40. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/skills/simplicio-tasks/references/understand-anything-adapter.md +0 -0
  41. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/skills/simplicio-tasks/references/video-evidence.md +0 -0
  42. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop/_bundle/skills/simplicio-tasks/references/web-evidence.md +0 -0
  43. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop.egg-info/SOURCES.txt +0 -0
  44. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop.egg-info/dependency_links.txt +0 -0
  45. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop.egg-info/entry_points.txt +0 -0
  46. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop.egg-info/requires.txt +0 -0
  47. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/simplicio_loop.egg-info/top_level.txt +0 -0
  48. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/tests/test_action_gate.py +0 -0
  49. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/tests/test_loop_e2e.py +0 -0
  50. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/tests/test_worker_selftests.py +0 -0
  51. {simplicio_loop-3.4.0 → simplicio_loop-3.9.0}/tests/test_worker_smoke.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simplicio-loop
3
- Version: 3.4.0
3
+ Version: 3.9.0
4
4
  Summary: The Universal Looping AI Orchestrator — a runtime-agnostic super-plugin (6 skills) that drains any queue of work end-to-end on any LLM/runtime.
5
5
  Author-email: Wesley Simplicio <wesleybob4@gmail.com>
6
6
  License: MIT
@@ -145,7 +145,7 @@ The orchestrator discovers work from any source via pluggable adapters. Each exp
145
145
 
146
146
  See each adapter's reference doc under `.claude/skills/simplicio-tasks/references/`.
147
147
 
148
- |---
148
+ ---
149
149
 
150
150
  ## 🌐 11 runtimes, one protocol
151
151
 
@@ -378,17 +378,25 @@ does this routing for OpenAI-compatible clients at install time.
378
378
 
379
379
  ### 📈 Simplicio Token Monitor
380
380
 
381
- A live, always-on view of the savings:
381
+ A view of the savings you open when you want — only the capture is always-on:
382
382
 
383
+ - **Capture proxy** — **always-on** (the one auto-started service; the wired clients need it
384
+ reachable). It silently captures + measures Claude + Codex + Hermes in the background.
383
385
  - **Web dashboard** — `http://127.0.0.1:9090` — real-time token chart, savings gauge, the LLMs/runtimes
384
- and **141/144 providers (98%)** we intercept, and a live proxy log.
386
+ and **141/144 providers (98%)** we intercept, a live proxy log. **Opens once on the first install**
387
+ so you see it works, then it's **on-demand** — re-open it any of these ways:
388
+ - `simplicio-loop dashboard` — works from anywhere after the pip install (no repo path needed);
389
+ `simplicio-loop dashboard --stop` to close, `--no-browser` to just start the server.
390
+ - `bash scripts/simplicio-economy.sh monitor` (repo checkout) · `… monitor stop` to close.
391
+ - just **ask the agent** — "open the token dashboard".
385
392
  - **Menu-bar / tray widget** — live tokens saved in the system tray (macOS rumps · Windows/Linux pystray).
386
- - **One module** — `scripts/simplicio-economy.sh {status|up|wire}` brings up the capture proxy + monitor +
387
- tray + the `simplicio-dev-cli` deterministic operator and reports the whole stack.
393
+ **On-demand:** `bash scripts/simplicio-economy.sh tray` · `… tray stop`.
388
394
 
389
- Install registers all three as auto-start services (macOS launchd · Linux systemd · Windows Startup) via
390
- `scripts/setup_simplicio.sh`, or the cross-platform `python3 scripts/install_services.py install`. After
391
- install the monitor + capture run **without invoking the loop**see `references/token-capture.md`.
395
+ Install auto-starts **only the capture proxy** (macOS launchd · Linux systemd · Windows Startup). The
396
+ dashboard opens **once** on a fresh install (marker-guarded a re-install/update never reopens it; opt
397
+ out with `SIMPLICIO_NO_DASHBOARD=1`), and the tray never opens by itselfnothing is forced to stay
398
+ open. Manage the stack: `scripts/simplicio-economy.sh {status|up|monitor|tray|wire}`. After install,
399
+ capture runs **without invoking the loop** — see `references/token-capture.md`.
392
400
 
393
401
  ### 🛠️ The capture engine — one native module, every command
394
402
 
@@ -431,7 +439,7 @@ Without the extra, the deterministic stdlib path covers everything; models downl
431
439
  (axum reverse proxy), `simplicio-parity` (Rust↔Python parity harness). Build with `maturin` — the Python
432
440
  engine works fully without them; the crates only add native speed.
433
441
 
434
- |---
442
+ ---
435
443
 
436
444
  ## 🏛️ Design pillars (in detail)
437
445
 
@@ -453,11 +461,45 @@ git clone https://github.com/wesleysimplicio/simplicio-loop
453
461
  cd simplicio-loop
454
462
 
455
463
  # install for your runtime (omit <runtime> to auto-detect)
456
- bash scripts/install.sh <runtime> [--global] # macOS / Linux
457
- pwsh scripts/install.ps1 <runtime> [-Global] # Windows
464
+ bash scripts/install.sh <runtime> [--global] [--minimal] # macOS / Linux
465
+ pwsh scripts/install.ps1 <runtime> [-Global] # Windows
458
466
  # <runtime> ∈ claude codex vscode cursor antigravity kiro opencode gemini aider hermes openclaw
459
467
  ```
460
468
 
469
+ **Install is complete by default — it installs everything.** One command sets up the whole stack:
470
+ the two loop operators (`simplicio-mapper` + `simplicio-cli`, auto-handling PEP 668 / externally-managed
471
+ Python and symlinking the binaries onto `PATH`), the **full Python stack** (the package + the `[onnx]`
472
+ models backend: onnxruntime + huggingface_hub + tokenizers + pillow, so `simplicio kompress/router/embed/image`
473
+ work), the **6 skills + hooks** with the loop's Stop hook wired, and the **always-on capture proxy**
474
+ with Claude + Codex + Hermes **routed and measured** in the background. The **dashboard opens once** on a
475
+ fresh install, then it's on-demand (`simplicio-loop dashboard` / `simplicio-economy.sh monitor`); the
476
+ **menu-bar tray never opens by itself** — nothing is forced to stay open.
477
+ Pass **`--minimal`** only for headless/CI to skip the heavy deps + the machine services. Verify any time:
478
+ `bash scripts/simplicio-economy.sh status`.
479
+
480
+ ### Update
481
+
482
+ ```bash
483
+ bash scripts/update.sh [<runtime>] # git pull → reinstall skills/hooks/operators → restart services
484
+ ```
485
+
486
+ `update.sh` stashes local edits, fast-forwards `main`, reinstalls from the fresh source, restarts the
487
+ launchd/systemd services so they run the new code, and prints the live stack + savings.
488
+
489
+ ### Doctor — verify + repair
490
+
491
+ ```bash
492
+ python3 scripts/doctor.py # report the whole stack (REQUIRED vs OPTIONAL)
493
+ python3 scripts/doctor.py --repair # install/wire what's fixable; make everything operational
494
+ # also: bash scripts/simplicio-economy.sh doctor [--repair]
495
+ ```
496
+
497
+ `doctor` separates **REQUIRED** (python3, the two loop operators, the 6 skills, the loop hooks, the
498
+ capture proxy — `--repair` installs/wires them) from **OPTIONAL** accelerators (the ONNX models
499
+ backend, the native **Rust** core, the tray dep). **Missing an optional piece is never a failure and
500
+ never blocks** — the Python engine + the deterministic path cover everything; the exit code is 0 as
501
+ long as every REQUIRED item is healthy.
502
+
461
503
  Or, on Claude Code / Cursor, add it as a marketplace plugin:
462
504
 
463
505
  ```
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "simplicio-loop"
7
- version = "3.4.0"
7
+ version = "3.9.0"
8
8
  description = "The Universal Looping AI Orchestrator — a runtime-agnostic super-plugin (6 skills) that drains any queue of work end-to-end on any LLM/runtime."
9
9
  readme = "PYPI.md"
10
10
  requires-python = ">=3.8"
@@ -0,0 +1,18 @@
1
+ """simplicio-loop — The Universal Looping AI Orchestrator.
2
+
3
+ A runtime-agnostic super-plugin (6 skills + loop/token hooks) that drains any
4
+ queue of work end-to-end on any LLM/runtime. This package ships the skills and
5
+ hooks and installs them into a runtime's skills location.
6
+ """
7
+
8
+ # Single source of truth = the package metadata (pyproject `version`); the literal is only a
9
+ # fallback for an editable/source checkout that was never installed. No more version drift.
10
+ try:
11
+ from importlib.metadata import version as _v, PackageNotFoundError
12
+
13
+ try:
14
+ __version__ = _v("simplicio-loop")
15
+ except PackageNotFoundError:
16
+ __version__ = "3.9.0"
17
+ except Exception: # pragma: no cover
18
+ __version__ = "3.9.0"
@@ -21,6 +21,7 @@ import re
21
21
  import socket
22
22
  import subprocess
23
23
  import sys
24
+ import tempfile
24
25
  import time
25
26
  from pathlib import Path
26
27
 
@@ -42,7 +43,8 @@ LOGO_CANDIDATES = [
42
43
  REPO_ROOT / "assets" / "simplicio-loop-logo.png",
43
44
  Path(HOME) / "Projetos" / "ai" / "simplicio-runtime" / "site" / "assets" / "img" / "simplicio-logo.png",
44
45
  ]
45
- PID_FILE = Path("/tmp") / "simplicio-token-monitor.pid"
46
+ # Cross-platform temp dir (Windows has no /tmp) — must match simplicio_loop/cli.py PID_FILE.
47
+ PID_FILE = Path(tempfile.gettempdir()) / "simplicio-token-monitor.pid"
46
48
  PROXY_PORT = os.environ.get("SIMPLICIO_PROXY_PORT", os.environ.get("HEADROOM_PORT", "8788"))
47
49
  # Engine call: the native Simplicio engine module, invoked cross-platform via this interpreter.
48
50
  ENGINE_CMD = [sys.executable or "python3", str(REPO_ROOT / "engine" / "simplicio_engine.py")]
@@ -60,6 +62,9 @@ RUNTIMES = [
60
62
  {"name": "Hermes", "load": "native recall", "loop": "native loop", "state": "native", "intercept": "baseurl", "logo": "hermes", "proc": r"hermes", "families": ["deepseek", "openai"]},
61
63
  {"name": "Cursor", "load": ".cursor-plugin", "loop": "Stop hook", "state": "full", "intercept": "baseurl", "logo": "cursor", "proc": r"Cursor\.app|Cursor Helper", "families": ["openai", "anthropic"]},
62
64
  {"name": "OpenCode", "load": "AGENTS.md", "loop": "self-paced", "state": "partial", "intercept": "baseurl", "logo": "opencode", "proc": r"opencode", "families": ["openai", "anthropic"]},
65
+ {"name": "Gemini", "load": "GEMINI.md", "loop": "self-paced", "state": "partial", "intercept": "none", "logo": "gemini", "proc": r"\bgemini\b", "families": []},
66
+ {"name": "Kiro", "load": ".kiro/steering", "loop": "spec tick", "state": "partial", "intercept": "none", "logo": "kiro", "proc": r"\bkiro\b", "families": []},
67
+ {"name": "Antigravity", "load": "rules", "loop": "self-paced", "state": "partial", "intercept": "none", "logo": "antigravity", "proc": r"antigravity", "families": []},
63
68
  ]
64
69
 
65
70
  # ── Brand badge: faithful inline vector of the Simplicio hexagon-S mark ───────
@@ -854,8 +859,11 @@ class Handler(http.server.BaseHTTPRequestHandler):
854
859
  def main():
855
860
  port = int(os.environ.get("PORT", "9090"))
856
861
  srv = http.server.HTTPServer(("127.0.0.1", port), Handler)
857
- with open(PID_FILE, "w") as f:
858
- f.write(str(os.getpid()))
862
+ try: # the PID file lets `simplicio-loop dashboard --stop` find us; never fatal if it can't be written
863
+ PID_FILE.parent.mkdir(parents=True, exist_ok=True)
864
+ PID_FILE.write_text(str(os.getpid()))
865
+ except OSError:
866
+ pass
859
867
  print(f"⬡ Simplicio Token Monitor · http://127.0.0.1:{port}")
860
868
  print(f" api: /api/status · refresh: 3s")
861
869
  try:
@@ -0,0 +1,180 @@
1
+ """CLI for simplicio-loop: install the bundled skills + hooks into a runtime."""
2
+ from __future__ import annotations
3
+
4
+ import argparse
5
+ import os
6
+ import shutil
7
+ import socket
8
+ import subprocess
9
+ import sys
10
+ import tempfile
11
+ import time
12
+ import webbrowser
13
+ from pathlib import Path
14
+
15
+ from . import __version__
16
+
17
+ BUNDLE = Path(__file__).resolve().parent / "_bundle"
18
+ DASHBOARD = BUNDLE / "hooks" / "simplicio_dashboard.py"
19
+ # Cross-platform temp dir (Windows has no /tmp) — must match hooks/simplicio_dashboard.py.
20
+ PID_FILE = Path(tempfile.gettempdir()) / "simplicio-token-monitor.pid"
21
+ DEFAULT_DASH_PORT = int(os.environ.get("SIMPLICIO_MONITOR_PORT", "9090"))
22
+
23
+
24
+ def _gui_available() -> bool:
25
+ """True only when opening a browser is safe + non-blocking. On headless Linux (no DISPLAY),
26
+ webbrowser.open() may launch a text browser that inherits stdin and blocks forever — and a
27
+ blocking wait() is NOT caught by try/except — so we must skip it there."""
28
+ if sys.platform == "darwin" or os.name == "nt":
29
+ return True
30
+ return bool(os.environ.get("DISPLAY") or os.environ.get("WAYLAND_DISPLAY"))
31
+
32
+
33
+ def _copy_tree(src: Path, dst: Path) -> int:
34
+ """Copy every file under src into dst, preserving structure. Returns file count."""
35
+ count = 0
36
+ for item in src.rglob("*"):
37
+ if item.is_file():
38
+ out = dst / item.relative_to(src)
39
+ out.parent.mkdir(parents=True, exist_ok=True)
40
+ shutil.copy2(item, out)
41
+ count += 1
42
+ return count
43
+
44
+
45
+ def install(target: Path, globally: bool) -> int:
46
+ base = (Path.home() / ".claude") if globally else (target / ".claude")
47
+ skills_dst = base / "skills"
48
+ hooks_dst = (base / "hooks") if globally else (target / "hooks")
49
+
50
+ if not (BUNDLE / "skills").is_dir():
51
+ print("error: bundled skills not found in the installed package.", flush=True)
52
+ return 1
53
+
54
+ n_skills = _copy_tree(BUNDLE / "skills", skills_dst)
55
+ n_hooks = _copy_tree(BUNDLE / "hooks", hooks_dst)
56
+
57
+ print(f"simplicio-loop {__version__} installed:")
58
+ print(f" skills -> {skills_dst} ({n_skills} files)")
59
+ print(f" hooks -> {hooks_dst} ({n_hooks} files)")
60
+ print("")
61
+ print("Use it in your agent runtime (Claude Code, Cursor, ...):")
62
+ print(" /simplicio-tasks finish all the open issues")
63
+ return 0
64
+
65
+
66
+ def _port_up(port: int) -> bool:
67
+ try:
68
+ with socket.create_connection(("127.0.0.1", port), 0.5):
69
+ return True
70
+ except OSError:
71
+ return False
72
+
73
+
74
+ def _stop_dashboard() -> int:
75
+ """Best-effort stop: kill the PID the dashboard recorded, then any stray server."""
76
+ killed = False
77
+ try:
78
+ pid = int(PID_FILE.read_text().strip())
79
+ os.kill(pid, 15)
80
+ killed = True
81
+ except (OSError, ValueError):
82
+ pass
83
+ if os.name != "nt": # pkill catches a server started outside this CLI
84
+ try:
85
+ subprocess.run(["pkill", "-f", "simplicio_dashboard.py"], check=False)
86
+ killed = True
87
+ except OSError:
88
+ pass
89
+ try:
90
+ PID_FILE.unlink()
91
+ except OSError:
92
+ pass
93
+ print("⬡ Token Monitor stopped." if killed else "⬡ dashboard was not running.")
94
+ return 0
95
+
96
+
97
+ def dashboard(port: int, open_browser: bool, stop: bool) -> int:
98
+ """Open (or stop) the Simplicio Token Monitor dashboard — works from anywhere after a pip
99
+ install, no repo checkout needed. Starts the bundled server detached if it's not already up,
100
+ then opens the browser. The dashboard is on-demand: nothing keeps it open, close it freely."""
101
+ if stop:
102
+ return _stop_dashboard()
103
+ url = f"http://127.0.0.1:{port}"
104
+ if not DASHBOARD.is_file():
105
+ print("error: bundled dashboard not found in the installed package.", flush=True)
106
+ return 1
107
+ if not _port_up(port):
108
+ logdir = Path.home() / ".simplicio" / "logs"
109
+ logdir.mkdir(parents=True, exist_ok=True)
110
+ env = {**os.environ, "PORT": str(port)}
111
+ # Detach so the server outlives this CLI process (own session / no console window).
112
+ kw = {"start_new_session": True} if os.name != "nt" else {
113
+ "creationflags": 0x00000008 | 0x00000200} # DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP
114
+ with open(logdir / "token-monitor.log", "ab") as logf:
115
+ try:
116
+ subprocess.Popen([sys.executable or "python3", str(DASHBOARD)],
117
+ env=env, stdout=logf, stderr=logf, stdin=subprocess.DEVNULL, **kw)
118
+ except OSError as e:
119
+ print(f"error: could not start the dashboard ({e}).", flush=True)
120
+ return 1
121
+ for _ in range(25): # wait up to ~5s for the port to come up
122
+ if _port_up(port):
123
+ break
124
+ time.sleep(0.2)
125
+ if not _port_up(port):
126
+ print(f"⬡ failed to start the dashboard — see ~/.simplicio/logs/token-monitor.log", flush=True)
127
+ return 1
128
+ print(f"⬡ Simplicio Token Monitor → {url}")
129
+ if open_browser and _gui_available():
130
+ try:
131
+ webbrowser.open(url)
132
+ except Exception:
133
+ pass
134
+ print(" stop it any time: simplicio-loop dashboard --stop")
135
+ return 0
136
+
137
+
138
+ def main(argv=None) -> int:
139
+ parser = argparse.ArgumentParser(
140
+ prog="simplicio-loop",
141
+ description=(
142
+ "Install the simplicio-loop super-plugin (6 AI-orchestration skills + "
143
+ "loop/token-economy hooks) into a runtime's skills location, or open the "
144
+ "Token Monitor dashboard."
145
+ ),
146
+ )
147
+ parser.add_argument(
148
+ "command", nargs="?", default="install", choices=["install", "dashboard"],
149
+ help="action to run: install (default) or dashboard (open the Token Monitor)",
150
+ )
151
+ parser.add_argument(
152
+ "--target", default=".",
153
+ help="project directory to install into (default: current directory)",
154
+ )
155
+ parser.add_argument(
156
+ "--global", dest="globally", action="store_true",
157
+ help="install into ~/.claude instead of the project",
158
+ )
159
+ parser.add_argument(
160
+ "--port", type=int, default=DEFAULT_DASH_PORT,
161
+ help="dashboard port (default: %(default)s)",
162
+ )
163
+ parser.add_argument(
164
+ "--no-browser", dest="no_browser", action="store_true",
165
+ help="dashboard: start the server but do not open a browser",
166
+ )
167
+ parser.add_argument(
168
+ "--stop", action="store_true", help="dashboard: stop a running Token Monitor",
169
+ )
170
+ parser.add_argument(
171
+ "-V", "--version", action="version", version=f"simplicio-loop {__version__}",
172
+ )
173
+ args = parser.parse_args(argv)
174
+ if args.command == "dashboard":
175
+ return dashboard(args.port, not args.no_browser, args.stop)
176
+ return install(Path(args.target).resolve(), args.globally)
177
+
178
+
179
+ if __name__ == "__main__":
180
+ raise SystemExit(main())
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simplicio-loop
3
- Version: 3.4.0
3
+ Version: 3.9.0
4
4
  Summary: The Universal Looping AI Orchestrator — a runtime-agnostic super-plugin (6 skills) that drains any queue of work end-to-end on any LLM/runtime.
5
5
  Author-email: Wesley Simplicio <wesleybob4@gmail.com>
6
6
  License: MIT
@@ -1,8 +0,0 @@
1
- """simplicio-loop — The Universal Looping AI Orchestrator.
2
-
3
- A runtime-agnostic super-plugin (6 skills + loop/token hooks) that drains any
4
- queue of work end-to-end on any LLM/runtime. This package ships the skills and
5
- hooks and installs them into a runtime's skills location.
6
- """
7
-
8
- __version__ = "1.0.3"
@@ -1,76 +0,0 @@
1
- """CLI for simplicio-loop: install the bundled skills + hooks into a runtime."""
2
- from __future__ import annotations
3
-
4
- import argparse
5
- import shutil
6
- from pathlib import Path
7
-
8
- from . import __version__
9
-
10
- BUNDLE = Path(__file__).resolve().parent / "_bundle"
11
-
12
-
13
- def _copy_tree(src: Path, dst: Path) -> int:
14
- """Copy every file under src into dst, preserving structure. Returns file count."""
15
- count = 0
16
- for item in src.rglob("*"):
17
- if item.is_file():
18
- out = dst / item.relative_to(src)
19
- out.parent.mkdir(parents=True, exist_ok=True)
20
- shutil.copy2(item, out)
21
- count += 1
22
- return count
23
-
24
-
25
- def install(target: Path, globally: bool) -> int:
26
- base = (Path.home() / ".claude") if globally else (target / ".claude")
27
- skills_dst = base / "skills"
28
- hooks_dst = (base / "hooks") if globally else (target / "hooks")
29
-
30
- if not (BUNDLE / "skills").is_dir():
31
- print("error: bundled skills not found in the installed package.", flush=True)
32
- return 1
33
-
34
- n_skills = _copy_tree(BUNDLE / "skills", skills_dst)
35
- n_hooks = _copy_tree(BUNDLE / "hooks", hooks_dst)
36
-
37
- print(f"simplicio-loop {__version__} installed:")
38
- print(f" skills -> {skills_dst} ({n_skills} files)")
39
- print(f" hooks -> {hooks_dst} ({n_hooks} files)")
40
- print("")
41
- print("Use it in your agent runtime (Claude Code, Cursor, ...):")
42
- print(" /simplicio-tasks finish all the open issues")
43
- return 0
44
-
45
-
46
- def main(argv=None) -> int:
47
- parser = argparse.ArgumentParser(
48
- prog="simplicio-loop",
49
- description=(
50
- "Install the simplicio-loop super-plugin (6 AI-orchestration skills + "
51
- "loop/token-economy hooks) into a runtime's skills location."
52
- ),
53
- )
54
- parser.add_argument(
55
- "command", nargs="?", default="install", choices=["install"],
56
- help="action to run (default: install)",
57
- )
58
- parser.add_argument(
59
- "--target", default=".",
60
- help="project directory to install into (default: current directory)",
61
- )
62
- parser.add_argument(
63
- "--global", dest="globally", action="store_true",
64
- help="install into ~/.claude instead of the project",
65
- )
66
- parser.add_argument(
67
- "-V", "--version", action="version", version=f"simplicio-loop {__version__}",
68
- )
69
- args = parser.parse_args(argv)
70
- if args.command == "install":
71
- return install(Path(args.target).resolve(), args.globally)
72
- return 0
73
-
74
-
75
- if __name__ == "__main__":
76
- raise SystemExit(main())
File without changes
File without changes
File without changes