@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 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.
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env bun
2
+ export {};