silicon-cli 1.0.0__py3-none-any.whl
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.
- silicon_cli/__init__.py +2 -0
- silicon_cli/cli.py +250 -0
- silicon_cli/config.py +29 -0
- silicon_cli/glassagent.py +66 -0
- silicon_cli/process.py +258 -0
- silicon_cli/registry.py +145 -0
- silicon_cli/stemcell.py +226 -0
- silicon_cli/sync.py +216 -0
- silicon_cli/ui.py +61 -0
- silicon_cli/update.py +80 -0
- silicon_cli-1.0.0.dist-info/METADATA +74 -0
- silicon_cli-1.0.0.dist-info/RECORD +16 -0
- silicon_cli-1.0.0.dist-info/WHEEL +5 -0
- silicon_cli-1.0.0.dist-info/entry_points.txt +2 -0
- silicon_cli-1.0.0.dist-info/licenses/LICENSE +21 -0
- silicon_cli-1.0.0.dist-info/top_level.txt +1 -0
silicon_cli/update.py
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""Update silicon instances from the stemcell, and self-update this CLI."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
import shutil
|
|
5
|
+
import subprocess
|
|
6
|
+
import sys
|
|
7
|
+
import tempfile
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
from . import process, registry, stemcell, ui
|
|
11
|
+
from .config import CLI_SOURCE_FILE
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def update_instance(target: str | None) -> None:
|
|
15
|
+
if shutil.which("git") is None:
|
|
16
|
+
ui.warn("git not found — some non-conflicting merges may be skipped.")
|
|
17
|
+
|
|
18
|
+
tmp_src = tempfile.mkdtemp(prefix="silicon-update-src-")
|
|
19
|
+
try:
|
|
20
|
+
ui.info("Downloading latest Silicon source...")
|
|
21
|
+
stemcell.download_stemcell(tmp_src)
|
|
22
|
+
updater = Path(tmp_src) / "scripts" / "silicon_update.py"
|
|
23
|
+
if not updater.exists():
|
|
24
|
+
ui.error("Downloaded source did not include the updater script.")
|
|
25
|
+
sys.exit(1)
|
|
26
|
+
|
|
27
|
+
if target and registry.is_multi_target(target):
|
|
28
|
+
names = registry.resolve_targets(target)
|
|
29
|
+
if not names:
|
|
30
|
+
ui.error("No matching installations")
|
|
31
|
+
sys.exit(1)
|
|
32
|
+
if target == "all" and not ui.confirm(f"Are you sure you want to update: {', '.join(names)}?"):
|
|
33
|
+
return
|
|
34
|
+
for n in names:
|
|
35
|
+
_update_one(n, tmp_src, str(updater), multi=True)
|
|
36
|
+
return
|
|
37
|
+
_update_one(target, tmp_src, str(updater), multi=False)
|
|
38
|
+
finally:
|
|
39
|
+
shutil.rmtree(tmp_src, ignore_errors=True)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _update_one(target: str | None, tmp_src: str, updater: str, multi: bool) -> None:
|
|
43
|
+
inst = registry.resolve_one(target)
|
|
44
|
+
if process.is_running(inst.pid_file):
|
|
45
|
+
msg = f"'{inst.name}' is running. Stop it first with: silicon stop {inst.name}"
|
|
46
|
+
if multi:
|
|
47
|
+
ui.warn(f"Skipping '{inst.name}' — it is running.")
|
|
48
|
+
return
|
|
49
|
+
ui.error(msg)
|
|
50
|
+
sys.exit(1)
|
|
51
|
+
|
|
52
|
+
ui.info(f"Updating '{inst.name}' safely...")
|
|
53
|
+
from .config import python_run_cmd
|
|
54
|
+
r = subprocess.run([python_run_cmd(), updater, "update", "--source", tmp_src, "--target", inst.path])
|
|
55
|
+
if r.returncode == 0:
|
|
56
|
+
ui.success(f"'{inst.name}' updated successfully")
|
|
57
|
+
elif r.returncode == 2:
|
|
58
|
+
ui.error(f"Update aborted — merge conflicts detected in '{inst.name}'. No files overwritten.")
|
|
59
|
+
if not multi:
|
|
60
|
+
sys.exit(2)
|
|
61
|
+
else:
|
|
62
|
+
ui.error(f"Update failed for '{inst.name}'.")
|
|
63
|
+
if not multi:
|
|
64
|
+
sys.exit(r.returncode)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def update_cli() -> None:
|
|
68
|
+
"""Reinstall/upgrade this CLI from its recorded source (pip into our venv)."""
|
|
69
|
+
ui.info("Updating silicon CLI...")
|
|
70
|
+
source = CLI_SOURCE_FILE.read_text().strip() if CLI_SOURCE_FILE.exists() else ""
|
|
71
|
+
if not source:
|
|
72
|
+
ui.warn("No install source recorded. Reinstall manually:")
|
|
73
|
+
ui.info(" pip install --upgrade <path-or-git-url-to-silicon-manager>")
|
|
74
|
+
return
|
|
75
|
+
r = subprocess.run([sys.executable, "-m", "pip", "install", "--upgrade", source])
|
|
76
|
+
if r.returncode == 0:
|
|
77
|
+
ui.success("CLI updated to latest version")
|
|
78
|
+
else:
|
|
79
|
+
ui.error("CLI update failed.")
|
|
80
|
+
sys.exit(r.returncode)
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: silicon-cli
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Silicon CLI — create, run, and manage your silicon instances.
|
|
5
|
+
Author: Saket
|
|
6
|
+
Project-URL: Homepage, https://github.com/saket1225/silicon-cli
|
|
7
|
+
Project-URL: Repository, https://github.com/saket1225/silicon-cli
|
|
8
|
+
Keywords: silicon,cli,agents
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Requires-Python: >=3.9
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Dynamic: license-file
|
|
16
|
+
|
|
17
|
+
# silicon-cli
|
|
18
|
+
|
|
19
|
+
Our own **`silicon`** CLI — a Python (pip-installable) port of the original bash
|
|
20
|
+
silicon manager. Manages silicon instances on a machine: create them from the
|
|
21
|
+
[silicon-stemcell](https://github.com/unlikefraction/silicon-stemcell) base,
|
|
22
|
+
start/stop them under an auto-restart watchdog, stream logs, and back them up to
|
|
23
|
+
Glass. It reads the same `~/.silicon/registry.json`, so existing installs carry
|
|
24
|
+
over unchanged.
|
|
25
|
+
|
|
26
|
+
## Install
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install silicon-cli
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
(Zero runtime dependencies — stdlib only.)
|
|
33
|
+
|
|
34
|
+
## Commands
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
silicon Show status or list instances
|
|
38
|
+
silicon new [dir] Create a new Silicon (hydrate from stemcell)
|
|
39
|
+
silicon new . Hydrate the current folder into a runnable silicon
|
|
40
|
+
silicon start <target> Start silicon(s). target = name, index, 1,2,4, or all
|
|
41
|
+
silicon stop [--full] <target> Stop silicon(s) (--full also stops the glass agent)
|
|
42
|
+
silicon restart <target> Restart silicon(s)
|
|
43
|
+
silicon agent <start|stop|status> [name] Manage the per-silicon glass agent
|
|
44
|
+
silicon status [name] Show instance status
|
|
45
|
+
silicon browser [name] Open a headed browser for login
|
|
46
|
+
silicon debug [name] Tail a running instance's logs
|
|
47
|
+
silicon attach [path] Register an existing silicon directory
|
|
48
|
+
silicon pull <username> Pull a silicon from Glass into a new folder
|
|
49
|
+
silicon push [name] [now|stop] Hourly backups to Glass (now = one-shot, stop = end loop)
|
|
50
|
+
silicon update <target> Update silicon(s) from the latest stemcell
|
|
51
|
+
silicon list List all instances
|
|
52
|
+
silicon script update Update this CLI itself
|
|
53
|
+
silicon help Show help
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Configuration (env vars)
|
|
57
|
+
|
|
58
|
+
| Var | Default | Purpose |
|
|
59
|
+
| --- | --- | --- |
|
|
60
|
+
| `SILICON_HOME` | `~/.silicon` | registry + CLI state |
|
|
61
|
+
| `GLASS_SERVER_URL` | `https://glass.unlikefraction.com` | Glass sync server (pull/push) |
|
|
62
|
+
| `SILICON_STEMCELL_REPO` | `unlikefraction/silicon-stemcell` | base for `new` |
|
|
63
|
+
| `SILICON_GLASS_CLI_REPO` | `unlikefraction/glass` | glass backup CLI |
|
|
64
|
+
| `SILICON_PYTHON` | `python3` | interpreter used to run a silicon's `main.py` |
|
|
65
|
+
|
|
66
|
+
## How it differs from the bash version
|
|
67
|
+
|
|
68
|
+
- Pure Python package with a `silicon` console entry point (installed in an
|
|
69
|
+
isolated venv), instead of a single bash script.
|
|
70
|
+
- The auto-restart watchdog runs as `silicon _watchdog` (a detached supervisor
|
|
71
|
+
process) rather than a backgrounded bash function — same crash-loop detection,
|
|
72
|
+
`.silicon.stop` sentinel, and `.silicon.pid`/`.silicon.log` behavior.
|
|
73
|
+
- `silicon script update` reinstalls the package via pip from its recorded source.
|
|
74
|
+
- Everything (server, stemcell repo) is env-overridable.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
silicon_cli/__init__.py,sha256=w6jDDC2G5ed0ZhQjAj7gbEFw7KbBuQxTuA1RUCwWN6k,112
|
|
2
|
+
silicon_cli/cli.py,sha256=JHcxRddYG_ruRisaYzWOK5etNVHppRmH__tX-0Qlkkc,9231
|
|
3
|
+
silicon_cli/config.py,sha256=8OrDPxX9XCQhcCUZPh6OwKAawRnSsIAROJM-2378jqs,1324
|
|
4
|
+
silicon_cli/glassagent.py,sha256=c2aSlIQxxQTZ0IVGb5ThhDGKsViKV_0wmoP3aNTlsZI,1643
|
|
5
|
+
silicon_cli/process.py,sha256=QiTE8FNALYNrMr7SQCwo_-qrTmXpoOYKehYHqVkAKoI,8176
|
|
6
|
+
silicon_cli/registry.py,sha256=VyLIa2wWQmamspJu9lwjBxZdWTgOeMpjlx4lYagVZ8Q,4110
|
|
7
|
+
silicon_cli/stemcell.py,sha256=fLcddmFBAkx-FBfeCmzcRVwNeQ9q0fqBgqnBogVIUXA,9358
|
|
8
|
+
silicon_cli/sync.py,sha256=EAxllc8hnbJE-Z67QW6wJvqtG1IinVX1LolkF1t9qXA,8630
|
|
9
|
+
silicon_cli/ui.py,sha256=zln50wsvOpG73YQMjGkQLPtvkLIhzA1aG7HFCTKOSPM,1875
|
|
10
|
+
silicon_cli/update.py,sha256=sHKg7GdEy8IaiEUXhcW27aVhRlUBIncVLixZu92CkVg,3051
|
|
11
|
+
silicon_cli-1.0.0.dist-info/licenses/LICENSE,sha256=lvCA4HhTS-7oF1EANeLwH4LaCsMc7rgsc7sJ-JLMdlI,1062
|
|
12
|
+
silicon_cli-1.0.0.dist-info/METADATA,sha256=so9sOM29ltK5kx18vFyXfnRyIltrZtgRUEDGavHB8Uc,3227
|
|
13
|
+
silicon_cli-1.0.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
14
|
+
silicon_cli-1.0.0.dist-info/entry_points.txt,sha256=di4YAM1gfOubdF4oRiw12NCNO-OHD_lyCTM-E6q3Wrc,49
|
|
15
|
+
silicon_cli-1.0.0.dist-info/top_level.txt,sha256=4vOt8z8yA3B9TkZHYfgMKtAanxnKL_XJOUCyY98Boi0,12
|
|
16
|
+
silicon_cli-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Saket
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
silicon_cli
|