@hasna/loops 0.1.0
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.
- package/LICENSE +17 -0
- package/README.md +127 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +1586 -0
- package/dist/daemon/control.d.ts +41 -0
- package/dist/daemon/daemon.d.ts +23 -0
- package/dist/daemon/index.d.ts +2 -0
- package/dist/daemon/index.js +1331 -0
- package/dist/daemon/install.d.ts +6 -0
- package/dist/daemon/loop.d.ts +10 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +1067 -0
- package/dist/lib/executor.d.ts +7 -0
- package/dist/lib/format.d.ts +4 -0
- package/dist/lib/ids.d.ts +2 -0
- package/dist/lib/paths.d.ts +7 -0
- package/dist/lib/schedule.d.ts +21 -0
- package/dist/lib/scheduler.d.ts +18 -0
- package/dist/lib/store.d.ts +56 -0
- package/dist/lib/store.js +685 -0
- package/dist/sdk/index.d.ts +25 -0
- package/dist/sdk/index.js +1059 -0
- package/dist/types.d.ts +109 -0
- package/docs/USAGE.md +127 -0
- package/package.json +77 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
https://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
Copyright 2026 Hasna
|
|
6
|
+
|
|
7
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
you may not use this file except in compliance with the License.
|
|
9
|
+
You may obtain a copy of the License at
|
|
10
|
+
|
|
11
|
+
https://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
|
|
13
|
+
Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
See the License for the specific language governing permissions and
|
|
17
|
+
limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# OpenLoops
|
|
2
|
+
|
|
3
|
+
OpenLoops is a local CLI and daemon for persistent loops: scheduled or recurring work that survives process restarts and records every run.
|
|
4
|
+
|
|
5
|
+
It supports deterministic command loops today and guarded CLI adapters for headless coding agents:
|
|
6
|
+
|
|
7
|
+
- `claude`
|
|
8
|
+
- `cursor-agent`
|
|
9
|
+
- `codewith exec`
|
|
10
|
+
- `aicopilot run`
|
|
11
|
+
- `opencode run`
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
From npm:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install -g @hasna/loops
|
|
19
|
+
loops --version
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Update:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm update -g @hasna/loops
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
From source:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
bun install
|
|
32
|
+
bun run build
|
|
33
|
+
bun link
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The CLI stores state in `~/.hasna/loops` by default. Set `LOOPS_DATA_DIR` to isolate state for tests or another profile.
|
|
37
|
+
|
|
38
|
+
## Create Loops
|
|
39
|
+
|
|
40
|
+
Run a deterministic command every minute:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
loops create command repo-status --every 1m --cmd "git status --short" --cwd /path/to/repo
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Run a Claude loop every morning:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
loops create agent morning-check \
|
|
50
|
+
--provider claude \
|
|
51
|
+
--cron "0 8 * * *" \
|
|
52
|
+
--cwd /path/to/repo \
|
|
53
|
+
--prompt "Check whether this repo is healthy and summarize required action."
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Run a Codewith loop every 15 minutes:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
loops create agent supply-chain-watch \
|
|
60
|
+
--provider codewith \
|
|
61
|
+
--every 15m \
|
|
62
|
+
--cwd /path/to/repo \
|
|
63
|
+
--prompt "Check for suspicious dependency or supply-chain changes. Report only concrete findings."
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Manage
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
loops list
|
|
70
|
+
loops show <id-or-name>
|
|
71
|
+
loops runs <id-or-name>
|
|
72
|
+
loops pause <id-or-name>
|
|
73
|
+
loops resume <id-or-name>
|
|
74
|
+
loops stop <id-or-name>
|
|
75
|
+
loops remove <id-or-name>
|
|
76
|
+
loops run-now <id-or-name>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Use `--json` for machine-readable output. Prompt bodies and run stdout/stderr are redacted by default in status output.
|
|
80
|
+
|
|
81
|
+
## Daemon
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
loops daemon start
|
|
85
|
+
loops daemon status
|
|
86
|
+
loops daemon logs
|
|
87
|
+
loops daemon stop
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Run in the foreground for supervised environments:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
loops daemon run
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Install startup integration:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
loops daemon install
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
On Linux this writes a user systemd service. On macOS it writes a LaunchAgent plist. The command prints the exact enable/load commands to run.
|
|
103
|
+
|
|
104
|
+
## Scheduling Contract
|
|
105
|
+
|
|
106
|
+
- `once`: one run at an absolute date/time.
|
|
107
|
+
- `interval`: fixed-rate by default. The next slot is based on the scheduled slot, then advanced past the completion time to avoid hot-looping after downtime.
|
|
108
|
+
- `cron`: five-field cron expression using the host local timezone.
|
|
109
|
+
- `dynamic`: one-minute cadence by default and no backfill.
|
|
110
|
+
- `catch_up=latest` by default: downtime coalesces missed interval/cron slots to the latest eligible slot.
|
|
111
|
+
- `catch_up=all`: runs up to `catch_up_limit` missed slots.
|
|
112
|
+
- `catch_up=none`: runs only the persisted next slot.
|
|
113
|
+
- `overlap=skip` by default: a due slot records a skipped run if a previous run is still active.
|
|
114
|
+
- Each run is keyed by `(loop_id, scheduled_for)` so a slot is claimed once.
|
|
115
|
+
- Failed slots retry only when `--attempts` is greater than `1`; retries keep the original `scheduled_for` value.
|
|
116
|
+
- Running rows have leases. If a daemon dies, a later daemon marks expired running rows as `abandoned`.
|
|
117
|
+
|
|
118
|
+
## Agent Adapter Notes
|
|
119
|
+
|
|
120
|
+
The adapters intentionally use provider command surfaces instead of pretending every agent has one SDK:
|
|
121
|
+
|
|
122
|
+
- Claude uses `claude -p --output-format json` and safe-mode/local setting sources by default.
|
|
123
|
+
- Codewith uses `codewith exec --json --ephemeral --ask-for-approval never`.
|
|
124
|
+
- AI Copilot and OpenCode use `run --format json --pure`.
|
|
125
|
+
- Cursor is CLI-first for now via `cursor-agent -p`; treat output as less stable until a stronger public SDK contract is selected.
|
|
126
|
+
|
|
127
|
+
For production loops that can mutate repos, prefer disposable worktrees and explicit prompts that name allowed write scope.
|