loopsmith-cli 0.3.1__tar.gz → 1.0.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.
- loopsmith_cli-1.0.0/PKG-INFO +135 -0
- loopsmith_cli-1.0.0/README.md +113 -0
- {loopsmith_cli-0.3.1 → loopsmith_cli-1.0.0}/pyproject.toml +1 -1
- {loopsmith_cli-0.3.1 → loopsmith_cli-1.0.0}/src/loopsmith_cli/__init__.py +20 -2
- loopsmith_cli-1.0.0/src/loopsmith_cli.egg-info/PKG-INFO +135 -0
- loopsmith_cli-0.3.1/PKG-INFO +0 -340
- loopsmith_cli-0.3.1/README.md +0 -318
- loopsmith_cli-0.3.1/src/loopsmith_cli.egg-info/PKG-INFO +0 -340
- {loopsmith_cli-0.3.1 → loopsmith_cli-1.0.0}/setup.cfg +0 -0
- {loopsmith_cli-0.3.1 → loopsmith_cli-1.0.0}/src/loopsmith_cli/__main__.py +0 -0
- {loopsmith_cli-0.3.1 → loopsmith_cli-1.0.0}/src/loopsmith_cli.egg-info/SOURCES.txt +0 -0
- {loopsmith_cli-0.3.1 → loopsmith_cli-1.0.0}/src/loopsmith_cli.egg-info/dependency_links.txt +0 -0
- {loopsmith_cli-0.3.1 → loopsmith_cli-1.0.0}/src/loopsmith_cli.egg-info/entry_points.txt +0 -0
- {loopsmith_cli-0.3.1 → loopsmith_cli-1.0.0}/src/loopsmith_cli.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: loopsmith-cli
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Self-evolving agent loops behind a deterministic verification gate. Installs the prebuilt Rust binary as `loopsmith`.
|
|
5
|
+
Author-email: Vaibhav Agarwal <bitphill@duck.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/bitphill/loopsmith
|
|
8
|
+
Project-URL: Repository, https://github.com/bitphill/loopsmith
|
|
9
|
+
Project-URL: Changelog, https://github.com/bitphill/loopsmith/blob/main/CHANGELOG.md
|
|
10
|
+
Project-URL: Issues, https://github.com/bitphill/loopsmith/issues
|
|
11
|
+
Keywords: agent,loop,llm,orchestration,cli,rust
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
16
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
17
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
18
|
+
Classifier: Programming Language :: Rust
|
|
19
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
20
|
+
Requires-Python: >=3.8
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
23
|
+
<div align="center">
|
|
24
|
+
<img src="https://raw.githubusercontent.com/bitphill/loopsmith/main/assets/loopsmith-logo-256.png" alt="loopsmith" width="180" />
|
|
25
|
+
<h1>loopsmith</h1>
|
|
26
|
+
<p><em>Hand a repeating job to an AI. A checker you wrote — not the AI — decides when it is done.</em></p>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
[](https://pypi.org/project/loopsmith-cli/)
|
|
30
|
+
[](https://github.com/bitphill/loopsmith/blob/main/LICENSE)
|
|
31
|
+

|
|
32
|
+

|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pipx install loopsmith-cli # or: pip install loopsmith-cli
|
|
36
|
+
loopsmith doctor
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
> **The distribution is `loopsmith-cli`; the command is `loopsmith`.** The
|
|
40
|
+
> shorter name was taken on PyPI. This package is a Rust binary with a thin
|
|
41
|
+
> Python launcher — there is nothing to `import`. The binary for your platform
|
|
42
|
+
> is downloaded on first run, so there is no Rust toolchain involved.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## What it is
|
|
47
|
+
|
|
48
|
+
You have a job you redo every week and are fussy about — a competitor roundup,
|
|
49
|
+
a lead list, a landing page, a research brief. You describe it once. loopsmith
|
|
50
|
+
runs it over and over on its own, and stops when a check **you** wrote says it
|
|
51
|
+
is done, or a limit **you** set says enough.
|
|
52
|
+
|
|
53
|
+
The part that makes it worth running unattended: whether a goal is done is
|
|
54
|
+
decided by compiled Rust, never by a model. The model does the work; a gate
|
|
55
|
+
that cannot be argued with decides whether the work counts. That gate can also
|
|
56
|
+
take "done" back — delete a required file and a satisfied goal flips straight
|
|
57
|
+
back to unsatisfied.
|
|
58
|
+
|
|
59
|
+
## Sixty seconds
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
loopsmith doctor # what this machine can and cannot do
|
|
63
|
+
loopsmith --web # build a loop in your browser
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Not a browser person? `loopsmith --guided` asks the same questions in the
|
|
67
|
+
terminal. Either way, nothing runs and nothing is spent while you answer.
|
|
68
|
+
|
|
69
|
+
To go straight to a file instead:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
loopsmith loop new --path ~/loops/my-loop --purpose "keep the roundup current"
|
|
73
|
+
loopsmith loop validate ~/loops/my-loop/loop.yaml # refuses, on purpose
|
|
74
|
+
loopsmith loop plan ~/loops/my-loop/loop.yaml # what it would do, and how fast
|
|
75
|
+
loopsmith run start ~/loops/my-loop/loop.yaml
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**That refusal is the point.** A fresh loop will not run until you tick the
|
|
79
|
+
steps saying you have done the job by hand at least once. Automating a process
|
|
80
|
+
nobody has performed produces the wrong answer faster, and at a scale that is
|
|
81
|
+
harder to undo.
|
|
82
|
+
|
|
83
|
+
## Fifteen worked loops to start from
|
|
84
|
+
|
|
85
|
+
Research, refactoring, traffic, trend tracking, landing pages, lead lists,
|
|
86
|
+
marketing, blogging, cold outreach, agent payments, a small game, idea
|
|
87
|
+
discovery, account watching, a container-isolated refactor, and one that
|
|
88
|
+
proposes improvements to itself. All fifteen are compiled into the binary and
|
|
89
|
+
load with one click in `--web`, or copy one from
|
|
90
|
+
[`config/examples/`](https://github.com/bitphill/loopsmith/tree/main/config/examples).
|
|
91
|
+
|
|
92
|
+
## Bring your own model
|
|
93
|
+
|
|
94
|
+
Every provider is a command template, so anything you can run from a shell can
|
|
95
|
+
serve a loop: Claude Code, Ollama, a Grok CLI, an OpenAI-compatible endpoint
|
|
96
|
+
driven by `curl`, an MCP server over stdio. Adding one is a config edit, never
|
|
97
|
+
a rebuild. Keys are named, never read — `requires_env` says a key must be
|
|
98
|
+
present, and the value goes from your environment to the command without
|
|
99
|
+
passing through loopsmith or its ledger.
|
|
100
|
+
|
|
101
|
+
Cheap models carry the mechanical work; strong models carry judgment. And a
|
|
102
|
+
judge is refused outright if it would run on the same provider as the work it
|
|
103
|
+
is grading, because a model marking its own homework is not a check.
|
|
104
|
+
|
|
105
|
+
## Keeping it alive
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
loopsmith run watch loop.yaml # stay resident, run on every trigger
|
|
109
|
+
loopsmith run schedule loop.yaml --install # hand it to launchd, cron, or Task Scheduler
|
|
110
|
+
loopsmith run status loop.yaml <run-id> # what the gate has ruled so far
|
|
111
|
+
loopsmith run ledger loop.yaml <run-id> # everything that happened, including why it stopped
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
A run survives a crash: state is a real store on disk, and `loopsmith run
|
|
115
|
+
resume` picks up from the last checkpoint.
|
|
116
|
+
|
|
117
|
+
## Where the rest of it is
|
|
118
|
+
|
|
119
|
+
- [**README-FOR-DUMMIES.md**](https://github.com/bitphill/loopsmith/blob/main/README-FOR-DUMMIES.md)
|
|
120
|
+
— the same thing with no jargon, if this page assumed too much
|
|
121
|
+
- [**README.md**](https://github.com/bitphill/loopsmith/blob/main/README.md)
|
|
122
|
+
— the full version
|
|
123
|
+
- [**HOW-TO-USE.md**](https://github.com/bitphill/loopsmith/blob/main/HOW-TO-USE.md)
|
|
124
|
+
— every config section, one at a time, with what goes wrong if you skip it
|
|
125
|
+
- [**LOOP-TEMPLATE.md**](https://github.com/bitphill/loopsmith/blob/main/LOOP-TEMPLATE.md)
|
|
126
|
+
— a blank loop with a note on every field
|
|
127
|
+
- [**Concepts**](https://github.com/bitphill/loopsmith/wiki/Concepts)
|
|
128
|
+
— every word the config and the error messages use, defined once
|
|
129
|
+
- [**Architecture**](https://github.com/bitphill/loopsmith/wiki/Architecture)
|
|
130
|
+
· [**Commands**](https://github.com/bitphill/loopsmith/wiki/Commands)
|
|
131
|
+
· [**Migration 0.3 → 1.0**](https://github.com/bitphill/loopsmith/wiki/Migration-0-3-To-1-0)
|
|
132
|
+
- [**Code wiki**](https://bitphill.github.io/loopsmith/wiki/#overview)
|
|
133
|
+
— a page per subsystem, generated from the code
|
|
134
|
+
|
|
135
|
+
Runs on Linux, macOS, and Windows. MIT licensed.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/bitphill/loopsmith/main/assets/loopsmith-logo-256.png" alt="loopsmith" width="180" />
|
|
3
|
+
<h1>loopsmith</h1>
|
|
4
|
+
<p><em>Hand a repeating job to an AI. A checker you wrote — not the AI — decides when it is done.</em></p>
|
|
5
|
+
</div>
|
|
6
|
+
|
|
7
|
+
[](https://pypi.org/project/loopsmith-cli/)
|
|
8
|
+
[](https://github.com/bitphill/loopsmith/blob/main/LICENSE)
|
|
9
|
+

|
|
10
|
+

|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pipx install loopsmith-cli # or: pip install loopsmith-cli
|
|
14
|
+
loopsmith doctor
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
> **The distribution is `loopsmith-cli`; the command is `loopsmith`.** The
|
|
18
|
+
> shorter name was taken on PyPI. This package is a Rust binary with a thin
|
|
19
|
+
> Python launcher — there is nothing to `import`. The binary for your platform
|
|
20
|
+
> is downloaded on first run, so there is no Rust toolchain involved.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## What it is
|
|
25
|
+
|
|
26
|
+
You have a job you redo every week and are fussy about — a competitor roundup,
|
|
27
|
+
a lead list, a landing page, a research brief. You describe it once. loopsmith
|
|
28
|
+
runs it over and over on its own, and stops when a check **you** wrote says it
|
|
29
|
+
is done, or a limit **you** set says enough.
|
|
30
|
+
|
|
31
|
+
The part that makes it worth running unattended: whether a goal is done is
|
|
32
|
+
decided by compiled Rust, never by a model. The model does the work; a gate
|
|
33
|
+
that cannot be argued with decides whether the work counts. That gate can also
|
|
34
|
+
take "done" back — delete a required file and a satisfied goal flips straight
|
|
35
|
+
back to unsatisfied.
|
|
36
|
+
|
|
37
|
+
## Sixty seconds
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
loopsmith doctor # what this machine can and cannot do
|
|
41
|
+
loopsmith --web # build a loop in your browser
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Not a browser person? `loopsmith --guided` asks the same questions in the
|
|
45
|
+
terminal. Either way, nothing runs and nothing is spent while you answer.
|
|
46
|
+
|
|
47
|
+
To go straight to a file instead:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
loopsmith loop new --path ~/loops/my-loop --purpose "keep the roundup current"
|
|
51
|
+
loopsmith loop validate ~/loops/my-loop/loop.yaml # refuses, on purpose
|
|
52
|
+
loopsmith loop plan ~/loops/my-loop/loop.yaml # what it would do, and how fast
|
|
53
|
+
loopsmith run start ~/loops/my-loop/loop.yaml
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**That refusal is the point.** A fresh loop will not run until you tick the
|
|
57
|
+
steps saying you have done the job by hand at least once. Automating a process
|
|
58
|
+
nobody has performed produces the wrong answer faster, and at a scale that is
|
|
59
|
+
harder to undo.
|
|
60
|
+
|
|
61
|
+
## Fifteen worked loops to start from
|
|
62
|
+
|
|
63
|
+
Research, refactoring, traffic, trend tracking, landing pages, lead lists,
|
|
64
|
+
marketing, blogging, cold outreach, agent payments, a small game, idea
|
|
65
|
+
discovery, account watching, a container-isolated refactor, and one that
|
|
66
|
+
proposes improvements to itself. All fifteen are compiled into the binary and
|
|
67
|
+
load with one click in `--web`, or copy one from
|
|
68
|
+
[`config/examples/`](https://github.com/bitphill/loopsmith/tree/main/config/examples).
|
|
69
|
+
|
|
70
|
+
## Bring your own model
|
|
71
|
+
|
|
72
|
+
Every provider is a command template, so anything you can run from a shell can
|
|
73
|
+
serve a loop: Claude Code, Ollama, a Grok CLI, an OpenAI-compatible endpoint
|
|
74
|
+
driven by `curl`, an MCP server over stdio. Adding one is a config edit, never
|
|
75
|
+
a rebuild. Keys are named, never read — `requires_env` says a key must be
|
|
76
|
+
present, and the value goes from your environment to the command without
|
|
77
|
+
passing through loopsmith or its ledger.
|
|
78
|
+
|
|
79
|
+
Cheap models carry the mechanical work; strong models carry judgment. And a
|
|
80
|
+
judge is refused outright if it would run on the same provider as the work it
|
|
81
|
+
is grading, because a model marking its own homework is not a check.
|
|
82
|
+
|
|
83
|
+
## Keeping it alive
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
loopsmith run watch loop.yaml # stay resident, run on every trigger
|
|
87
|
+
loopsmith run schedule loop.yaml --install # hand it to launchd, cron, or Task Scheduler
|
|
88
|
+
loopsmith run status loop.yaml <run-id> # what the gate has ruled so far
|
|
89
|
+
loopsmith run ledger loop.yaml <run-id> # everything that happened, including why it stopped
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
A run survives a crash: state is a real store on disk, and `loopsmith run
|
|
93
|
+
resume` picks up from the last checkpoint.
|
|
94
|
+
|
|
95
|
+
## Where the rest of it is
|
|
96
|
+
|
|
97
|
+
- [**README-FOR-DUMMIES.md**](https://github.com/bitphill/loopsmith/blob/main/README-FOR-DUMMIES.md)
|
|
98
|
+
— the same thing with no jargon, if this page assumed too much
|
|
99
|
+
- [**README.md**](https://github.com/bitphill/loopsmith/blob/main/README.md)
|
|
100
|
+
— the full version
|
|
101
|
+
- [**HOW-TO-USE.md**](https://github.com/bitphill/loopsmith/blob/main/HOW-TO-USE.md)
|
|
102
|
+
— every config section, one at a time, with what goes wrong if you skip it
|
|
103
|
+
- [**LOOP-TEMPLATE.md**](https://github.com/bitphill/loopsmith/blob/main/LOOP-TEMPLATE.md)
|
|
104
|
+
— a blank loop with a note on every field
|
|
105
|
+
- [**Concepts**](https://github.com/bitphill/loopsmith/wiki/Concepts)
|
|
106
|
+
— every word the config and the error messages use, defined once
|
|
107
|
+
- [**Architecture**](https://github.com/bitphill/loopsmith/wiki/Architecture)
|
|
108
|
+
· [**Commands**](https://github.com/bitphill/loopsmith/wiki/Commands)
|
|
109
|
+
· [**Migration 0.3 → 1.0**](https://github.com/bitphill/loopsmith/wiki/Migration-0-3-To-1-0)
|
|
110
|
+
- [**Code wiki**](https://bitphill.github.io/loopsmith/wiki/#overview)
|
|
111
|
+
— a page per subsystem, generated from the code
|
|
112
|
+
|
|
113
|
+
Runs on Linux, macOS, and Windows. MIT licensed.
|
|
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
|
|
|
6
6
|
# `loopsmith` on PyPI was already registered by an unrelated project, so the
|
|
7
7
|
# distribution is `loopsmith-cli`. The installed command is `loopsmith`.
|
|
8
8
|
name = "loopsmith-cli"
|
|
9
|
-
version = "0.
|
|
9
|
+
version = "1.0.0"
|
|
10
10
|
description = "Self-evolving agent loops behind a deterministic verification gate. Installs the prebuilt Rust binary as `loopsmith`."
|
|
11
11
|
readme = "README.md"
|
|
12
12
|
license = "MIT"
|
|
@@ -25,11 +25,21 @@ import urllib.request
|
|
|
25
25
|
import zipfile
|
|
26
26
|
from pathlib import Path
|
|
27
27
|
|
|
28
|
-
__version__ = "0.
|
|
28
|
+
__version__ = "1.0.0"
|
|
29
29
|
|
|
30
30
|
REPO = "bitphill/loopsmith"
|
|
31
31
|
_RELEASE_BASE = f"https://github.com/{REPO}/releases/download/v{__version__}"
|
|
32
32
|
|
|
33
|
+
# Seconds for each blocking step of a download: connecting to one address, or
|
|
34
|
+
# one read. `urllib` tries a host's addresses one after another and spends the
|
|
35
|
+
# whole of this on each address that does not answer, so it is the cost of every
|
|
36
|
+
# unreachable CDN node, paid in silence. GitHub serves release assets from four
|
|
37
|
+
# anycast addresses, and a network that cannot reach one of them made the first
|
|
38
|
+
# run sit for two minutes per download — with 120 here, and two downloads —
|
|
39
|
+
# looking exactly like the hang this launcher's other comments warn about.
|
|
40
|
+
# Twenty keeps a genuinely slow link working and makes a dead node a pause.
|
|
41
|
+
_TIMEOUT = 20
|
|
42
|
+
|
|
33
43
|
|
|
34
44
|
class ResolveError(RuntimeError):
|
|
35
45
|
"""This host has no prebuilt binary, or one could not be verified."""
|
|
@@ -77,7 +87,7 @@ def cache_dir() -> Path:
|
|
|
77
87
|
|
|
78
88
|
|
|
79
89
|
def _read(url: str) -> bytes:
|
|
80
|
-
with urllib.request.urlopen(url, timeout=
|
|
90
|
+
with urllib.request.urlopen(url, timeout=_TIMEOUT) as response: # noqa: S310
|
|
81
91
|
return response.read()
|
|
82
92
|
|
|
83
93
|
|
|
@@ -125,6 +135,14 @@ def ensure_binary() -> Path:
|
|
|
125
135
|
# happens once per version. Not worth the failure mode.
|
|
126
136
|
target = _target()
|
|
127
137
|
asset = f"loopsmith-v{__version__}-{target}.{'zip' if windows else 'tar.gz'}"
|
|
138
|
+
# Said before the download, not after it. This runs once per version, it can
|
|
139
|
+
# take a while on a slow or partly broken network, and a first run that
|
|
140
|
+
# prints nothing until it is done is indistinguishable from a hang.
|
|
141
|
+
print(
|
|
142
|
+
f"[loopsmith] first run of {__version__}: fetching the {target} binary "
|
|
143
|
+
"from the GitHub release",
|
|
144
|
+
file=sys.stderr,
|
|
145
|
+
)
|
|
128
146
|
want = _expected_digest(asset)
|
|
129
147
|
payload = _read(f"{_RELEASE_BASE}/{asset}")
|
|
130
148
|
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: loopsmith-cli
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Self-evolving agent loops behind a deterministic verification gate. Installs the prebuilt Rust binary as `loopsmith`.
|
|
5
|
+
Author-email: Vaibhav Agarwal <bitphill@duck.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/bitphill/loopsmith
|
|
8
|
+
Project-URL: Repository, https://github.com/bitphill/loopsmith
|
|
9
|
+
Project-URL: Changelog, https://github.com/bitphill/loopsmith/blob/main/CHANGELOG.md
|
|
10
|
+
Project-URL: Issues, https://github.com/bitphill/loopsmith/issues
|
|
11
|
+
Keywords: agent,loop,llm,orchestration,cli,rust
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
16
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
17
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
18
|
+
Classifier: Programming Language :: Rust
|
|
19
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
20
|
+
Requires-Python: >=3.8
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
23
|
+
<div align="center">
|
|
24
|
+
<img src="https://raw.githubusercontent.com/bitphill/loopsmith/main/assets/loopsmith-logo-256.png" alt="loopsmith" width="180" />
|
|
25
|
+
<h1>loopsmith</h1>
|
|
26
|
+
<p><em>Hand a repeating job to an AI. A checker you wrote — not the AI — decides when it is done.</em></p>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
[](https://pypi.org/project/loopsmith-cli/)
|
|
30
|
+
[](https://github.com/bitphill/loopsmith/blob/main/LICENSE)
|
|
31
|
+

|
|
32
|
+

|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pipx install loopsmith-cli # or: pip install loopsmith-cli
|
|
36
|
+
loopsmith doctor
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
> **The distribution is `loopsmith-cli`; the command is `loopsmith`.** The
|
|
40
|
+
> shorter name was taken on PyPI. This package is a Rust binary with a thin
|
|
41
|
+
> Python launcher — there is nothing to `import`. The binary for your platform
|
|
42
|
+
> is downloaded on first run, so there is no Rust toolchain involved.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## What it is
|
|
47
|
+
|
|
48
|
+
You have a job you redo every week and are fussy about — a competitor roundup,
|
|
49
|
+
a lead list, a landing page, a research brief. You describe it once. loopsmith
|
|
50
|
+
runs it over and over on its own, and stops when a check **you** wrote says it
|
|
51
|
+
is done, or a limit **you** set says enough.
|
|
52
|
+
|
|
53
|
+
The part that makes it worth running unattended: whether a goal is done is
|
|
54
|
+
decided by compiled Rust, never by a model. The model does the work; a gate
|
|
55
|
+
that cannot be argued with decides whether the work counts. That gate can also
|
|
56
|
+
take "done" back — delete a required file and a satisfied goal flips straight
|
|
57
|
+
back to unsatisfied.
|
|
58
|
+
|
|
59
|
+
## Sixty seconds
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
loopsmith doctor # what this machine can and cannot do
|
|
63
|
+
loopsmith --web # build a loop in your browser
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Not a browser person? `loopsmith --guided` asks the same questions in the
|
|
67
|
+
terminal. Either way, nothing runs and nothing is spent while you answer.
|
|
68
|
+
|
|
69
|
+
To go straight to a file instead:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
loopsmith loop new --path ~/loops/my-loop --purpose "keep the roundup current"
|
|
73
|
+
loopsmith loop validate ~/loops/my-loop/loop.yaml # refuses, on purpose
|
|
74
|
+
loopsmith loop plan ~/loops/my-loop/loop.yaml # what it would do, and how fast
|
|
75
|
+
loopsmith run start ~/loops/my-loop/loop.yaml
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**That refusal is the point.** A fresh loop will not run until you tick the
|
|
79
|
+
steps saying you have done the job by hand at least once. Automating a process
|
|
80
|
+
nobody has performed produces the wrong answer faster, and at a scale that is
|
|
81
|
+
harder to undo.
|
|
82
|
+
|
|
83
|
+
## Fifteen worked loops to start from
|
|
84
|
+
|
|
85
|
+
Research, refactoring, traffic, trend tracking, landing pages, lead lists,
|
|
86
|
+
marketing, blogging, cold outreach, agent payments, a small game, idea
|
|
87
|
+
discovery, account watching, a container-isolated refactor, and one that
|
|
88
|
+
proposes improvements to itself. All fifteen are compiled into the binary and
|
|
89
|
+
load with one click in `--web`, or copy one from
|
|
90
|
+
[`config/examples/`](https://github.com/bitphill/loopsmith/tree/main/config/examples).
|
|
91
|
+
|
|
92
|
+
## Bring your own model
|
|
93
|
+
|
|
94
|
+
Every provider is a command template, so anything you can run from a shell can
|
|
95
|
+
serve a loop: Claude Code, Ollama, a Grok CLI, an OpenAI-compatible endpoint
|
|
96
|
+
driven by `curl`, an MCP server over stdio. Adding one is a config edit, never
|
|
97
|
+
a rebuild. Keys are named, never read — `requires_env` says a key must be
|
|
98
|
+
present, and the value goes from your environment to the command without
|
|
99
|
+
passing through loopsmith or its ledger.
|
|
100
|
+
|
|
101
|
+
Cheap models carry the mechanical work; strong models carry judgment. And a
|
|
102
|
+
judge is refused outright if it would run on the same provider as the work it
|
|
103
|
+
is grading, because a model marking its own homework is not a check.
|
|
104
|
+
|
|
105
|
+
## Keeping it alive
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
loopsmith run watch loop.yaml # stay resident, run on every trigger
|
|
109
|
+
loopsmith run schedule loop.yaml --install # hand it to launchd, cron, or Task Scheduler
|
|
110
|
+
loopsmith run status loop.yaml <run-id> # what the gate has ruled so far
|
|
111
|
+
loopsmith run ledger loop.yaml <run-id> # everything that happened, including why it stopped
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
A run survives a crash: state is a real store on disk, and `loopsmith run
|
|
115
|
+
resume` picks up from the last checkpoint.
|
|
116
|
+
|
|
117
|
+
## Where the rest of it is
|
|
118
|
+
|
|
119
|
+
- [**README-FOR-DUMMIES.md**](https://github.com/bitphill/loopsmith/blob/main/README-FOR-DUMMIES.md)
|
|
120
|
+
— the same thing with no jargon, if this page assumed too much
|
|
121
|
+
- [**README.md**](https://github.com/bitphill/loopsmith/blob/main/README.md)
|
|
122
|
+
— the full version
|
|
123
|
+
- [**HOW-TO-USE.md**](https://github.com/bitphill/loopsmith/blob/main/HOW-TO-USE.md)
|
|
124
|
+
— every config section, one at a time, with what goes wrong if you skip it
|
|
125
|
+
- [**LOOP-TEMPLATE.md**](https://github.com/bitphill/loopsmith/blob/main/LOOP-TEMPLATE.md)
|
|
126
|
+
— a blank loop with a note on every field
|
|
127
|
+
- [**Concepts**](https://github.com/bitphill/loopsmith/wiki/Concepts)
|
|
128
|
+
— every word the config and the error messages use, defined once
|
|
129
|
+
- [**Architecture**](https://github.com/bitphill/loopsmith/wiki/Architecture)
|
|
130
|
+
· [**Commands**](https://github.com/bitphill/loopsmith/wiki/Commands)
|
|
131
|
+
· [**Migration 0.3 → 1.0**](https://github.com/bitphill/loopsmith/wiki/Migration-0-3-To-1-0)
|
|
132
|
+
- [**Code wiki**](https://bitphill.github.io/loopsmith/wiki/#overview)
|
|
133
|
+
— a page per subsystem, generated from the code
|
|
134
|
+
|
|
135
|
+
Runs on Linux, macOS, and Windows. MIT licensed.
|