@hasna/loops 0.3.5 → 0.3.7
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/README.md +60 -0
- package/dist/cli/index.js +1054 -22
- package/dist/daemon/index.js +974 -19
- package/dist/index.d.ts +3 -0
- package/dist/index.js +985 -18
- package/dist/lib/executor.d.ts +3 -0
- package/dist/lib/format.d.ts +3 -1
- package/dist/lib/goal/model-factory.d.ts +9 -0
- package/dist/lib/goal/prompts.d.ts +4 -0
- package/dist/lib/goal/runner.d.ts +3 -0
- package/dist/lib/goal/status.d.ts +9 -0
- package/dist/lib/goal/types.d.ts +120 -0
- package/dist/lib/store.d.ts +58 -1
- package/dist/lib/store.js +544 -5
- package/dist/lib/workflow-spec.d.ts +2 -1
- package/dist/sdk/index.d.ts +6 -1
- package/dist/sdk/index.js +981 -18
- package/dist/types.d.ts +10 -0
- package/docs/TRANSCRIPT_LOOP_PATTERNS.md +95 -0
- package/docs/USAGE.md +17 -0
- package/docs/workflows/transcript-feedback-to-loops.json +80 -0
- package/package.json +5 -2
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { GoalSpec } from "./lib/goal/types.js";
|
|
2
|
+
export type { Goal, GoalAutoExecute, GoalExecutorResult, GoalPlan, GoalPlanNode, GoalPlanNodeStatus, GoalPlanStatus, GoalRollup, GoalRun, GoalSpec, GoalStatus, } from "./lib/goal/types.js";
|
|
1
3
|
export type LoopStatus = "active" | "paused" | "stopped" | "expired";
|
|
2
4
|
export type RunStatus = "running" | "succeeded" | "failed" | "timed_out" | "abandoned" | "skipped";
|
|
3
5
|
export type CatchUpPolicy = "none" | "latest" | "all";
|
|
@@ -79,6 +81,7 @@ export interface WorkflowStep {
|
|
|
79
81
|
name?: string;
|
|
80
82
|
description?: string;
|
|
81
83
|
target: ExecutableTarget;
|
|
84
|
+
goal?: GoalSpec;
|
|
82
85
|
dependsOn?: string[];
|
|
83
86
|
continueOnFailure?: boolean;
|
|
84
87
|
timeoutMs?: number;
|
|
@@ -90,6 +93,7 @@ export interface WorkflowSpec {
|
|
|
90
93
|
description?: string;
|
|
91
94
|
version: number;
|
|
92
95
|
status: WorkflowStatus;
|
|
96
|
+
goal?: GoalSpec;
|
|
93
97
|
steps: WorkflowStep[];
|
|
94
98
|
createdAt: string;
|
|
95
99
|
updatedAt: string;
|
|
@@ -97,6 +101,7 @@ export interface WorkflowSpec {
|
|
|
97
101
|
export interface CreateWorkflowInput {
|
|
98
102
|
name: string;
|
|
99
103
|
description?: string;
|
|
104
|
+
goal?: GoalSpec;
|
|
100
105
|
steps: WorkflowStep[];
|
|
101
106
|
version?: number;
|
|
102
107
|
}
|
|
@@ -108,6 +113,7 @@ export interface WorkflowRun {
|
|
|
108
113
|
loopRunId?: string;
|
|
109
114
|
scheduledFor?: string;
|
|
110
115
|
idempotencyKey?: string;
|
|
116
|
+
goalRunId?: string;
|
|
111
117
|
status: WorkflowRunStatus;
|
|
112
118
|
startedAt?: string;
|
|
113
119
|
finishedAt?: string;
|
|
@@ -132,6 +138,7 @@ export interface WorkflowStepRun {
|
|
|
132
138
|
error?: string;
|
|
133
139
|
accountProfile?: string;
|
|
134
140
|
accountTool?: string;
|
|
141
|
+
goalRunId?: string;
|
|
135
142
|
createdAt: string;
|
|
136
143
|
updatedAt: string;
|
|
137
144
|
}
|
|
@@ -151,6 +158,7 @@ export interface Loop {
|
|
|
151
158
|
status: LoopStatus;
|
|
152
159
|
schedule: ScheduleSpec;
|
|
153
160
|
target: LoopTarget;
|
|
161
|
+
goal?: GoalSpec;
|
|
154
162
|
machine?: LoopMachineRef;
|
|
155
163
|
nextRunAt?: string;
|
|
156
164
|
retryScheduledFor?: string;
|
|
@@ -181,6 +189,7 @@ export interface LoopRun {
|
|
|
181
189
|
stdout?: string;
|
|
182
190
|
stderr?: string;
|
|
183
191
|
error?: string;
|
|
192
|
+
goalRunId?: string;
|
|
184
193
|
createdAt: string;
|
|
185
194
|
updatedAt: string;
|
|
186
195
|
}
|
|
@@ -189,6 +198,7 @@ export interface CreateLoopInput {
|
|
|
189
198
|
description?: string;
|
|
190
199
|
schedule: ScheduleSpec;
|
|
191
200
|
target: LoopTarget;
|
|
201
|
+
goal?: GoalSpec;
|
|
192
202
|
machine?: LoopMachineRef;
|
|
193
203
|
catchUp?: CatchUpPolicy;
|
|
194
204
|
catchUpLimit?: number;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Transcript-Driven Loop Patterns
|
|
2
|
+
|
|
3
|
+
This guide turns long-form transcripts, meeting recordings, interviews, and product feedback videos into durable OpenLoops work. It pairs `iapp-transcriber` for media ingestion with OpenLoops workflows for recurring review, implementation, and verification.
|
|
4
|
+
|
|
5
|
+
The pattern came from reviewing a Claude Code fireside chat transcript. The useful operational takeaway was not just "use agents more"; it was that recurring agents need narrow scope, evidence, review gates, and clear ROI. In OpenLoops terms, that means using workflows and goals to move from transcript insight to scheduled loop safely.
|
|
6
|
+
|
|
7
|
+
## Baseline Workflow
|
|
8
|
+
|
|
9
|
+
Start with the checked-in workflow template. Copy it into the target repo, replace `/path/to/repo` with that repo's absolute path, and provide `TRANSCRIBER_SOURCE_URL` through the runner environment or a private, uncommitted workflow copy before storing or scheduling it. Do not commit private or signed media URLs.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
mkdir -p /path/to/repo/.openloops
|
|
13
|
+
cp /path/to/open-loops/docs/workflows/transcript-feedback-to-loops.json /path/to/repo/.openloops/transcript-feedback-to-loops.json
|
|
14
|
+
loops workflows validate /path/to/repo/.openloops/transcript-feedback-to-loops.json --preflight
|
|
15
|
+
loops workflows create /path/to/repo/.openloops/transcript-feedback-to-loops.json
|
|
16
|
+
loops workflows run transcript-feedback-to-loops --show-output
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The transcribe step writes `.openloops/transcripts/latest-transcript.json`. The transcript path is fixed so later agent steps read the same artifact the command step produced. Edit the copied workflow if you need a different artifact path. Set `TRANSCRIBER_PROVIDER` in the `transcribe-media` target env to choose another provider. For multi-speaker recordings, update the transcriber command to request diarization when the selected provider supports it. If no recurring loop candidates are generated, the validation step exits successfully after recording that there is nothing to validate.
|
|
20
|
+
|
|
21
|
+
The workflow includes non-shell `check-transcriber` and `check-loops` command steps so `loops workflows validate --preflight` can catch those missing CLIs. Shell command bodies, provider credentials, and media access are still checked by the transcriber step at runtime.
|
|
22
|
+
|
|
23
|
+
The ingestion template intentionally does not wrap the whole workflow in an OpenLoops goal. Goal wrappers execute the underlying target for each ready goal-plan node, which is useful for implementation workflows but too surprising for media ingestion. Use goals in the generated follow-up workflows after the transcript has been converted into a concrete backlog.
|
|
24
|
+
|
|
25
|
+
Schedule the workflow only after a manual run produces useful backlog items:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
loops create workflow transcript-feedback-weekly \
|
|
29
|
+
--workflow transcript-feedback-to-loops \
|
|
30
|
+
--cron "0 9 * * 1" \
|
|
31
|
+
--attempts 2 \
|
|
32
|
+
--retry-delay 10m \
|
|
33
|
+
--lease 2h
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Loop Candidates
|
|
37
|
+
|
|
38
|
+
Transcript and feedback sources usually produce recurring work in a few durable categories:
|
|
39
|
+
|
|
40
|
+
- Code review and security: scan recent changes, identify risky diffs, and open focused remediation PRs.
|
|
41
|
+
- Customer or community feedback: summarize new feedback, cluster issues, and create small implementation tasks.
|
|
42
|
+
- Maintenance PRs: remove stale tests, reduce duplication, update docs, and fix flaky workflows.
|
|
43
|
+
- CI optimization: inspect slow jobs, propose changes, and validate runtime improvements with before/after evidence.
|
|
44
|
+
- Knowledge capture: turn important discussions into reusable docs, prompts, or skills.
|
|
45
|
+
|
|
46
|
+
Use an agent loop when judgment is needed. Use a command loop when the task is deterministic. Use a workflow when the loop needs ordered steps, separate accounts, or a validation gate.
|
|
47
|
+
|
|
48
|
+
## Guardrails
|
|
49
|
+
|
|
50
|
+
Only transcribe media you are authorized to access. Keep source metadata with transcript artifacts so reviewers can trace where an insight came from.
|
|
51
|
+
|
|
52
|
+
Every loop candidate should name:
|
|
53
|
+
|
|
54
|
+
- Cadence and trigger.
|
|
55
|
+
- Allowed repository paths and whether writes are permitted.
|
|
56
|
+
- Agent provider and account profile, if needed.
|
|
57
|
+
- Verification command or evidence artifact.
|
|
58
|
+
- Stop condition or archive condition.
|
|
59
|
+
- Human review point before scheduling or merging changes.
|
|
60
|
+
|
|
61
|
+
For loops that can mutate code, prefer a disposable worktree and prompts that explicitly limit write scope. Start with a one-shot smoke schedule before switching to a recurring cadence.
|
|
62
|
+
|
|
63
|
+
## Example Follow-Up Loops
|
|
64
|
+
|
|
65
|
+
Review and security loop:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
loops create agent repo-review-daily \
|
|
69
|
+
--provider codewith \
|
|
70
|
+
--cron "0 8 * * 1-5" \
|
|
71
|
+
--cwd /path/to/repo \
|
|
72
|
+
--prompt "Review recent changes for correctness, security, and missing tests. Report concrete findings first. Do not modify files."
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Maintenance PR loop:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
loops create agent maintenance-pr-weekly \
|
|
79
|
+
--provider codewith \
|
|
80
|
+
--cron "0 10 * * 2" \
|
|
81
|
+
--cwd /path/to/repo \
|
|
82
|
+
--prompt "Find one small maintenance improvement, implement it, and run targeted verification. Keep changes scoped and reviewable."
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
CI optimization workflow loop:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
loops workflows validate docs/workflows/generated/ci-optimization.json --preflight
|
|
89
|
+
loops workflows create docs/workflows/generated/ci-optimization.json
|
|
90
|
+
loops create workflow ci-optimization-monthly \
|
|
91
|
+
--workflow ci-optimization \
|
|
92
|
+
--cron "0 11 1 * *" \
|
|
93
|
+
--attempts 2 \
|
|
94
|
+
--retry-delay 15m
|
|
95
|
+
```
|
package/docs/USAGE.md
CHANGED
|
@@ -24,8 +24,13 @@ Update:
|
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
26
|
npm update -g @hasna/loops
|
|
27
|
+
loops daemon stop
|
|
28
|
+
loops daemon start
|
|
29
|
+
loops daemon status
|
|
27
30
|
```
|
|
28
31
|
|
|
32
|
+
Restart the daemon on every machine that runs scheduled loops; already-running daemon processes keep using the old package until restarted.
|
|
33
|
+
|
|
29
34
|
From source:
|
|
30
35
|
|
|
31
36
|
```bash
|
|
@@ -155,6 +160,18 @@ Use `shell: true` only when you intentionally want shell parsing:
|
|
|
155
160
|
{ "type": "command", "command": "git status --short", "shell": true }
|
|
156
161
|
```
|
|
157
162
|
|
|
163
|
+
## Transcript-Driven Loops
|
|
164
|
+
|
|
165
|
+
OpenLoops can turn long-form media or meeting transcripts into recurring workflow work when paired with `iapp-transcriber`. The template at `docs/workflows/transcript-feedback-to-loops.json` transcribes an authorized media URL, asks an agent to extract recurring loop candidates, authors workflow specs, and validates generated workflows before scheduling. Copy it into the target repo, replace `/path/to/repo` with that repo's absolute path, and provide `TRANSCRIBER_SOURCE_URL` through the runner environment or a private, uncommitted workflow copy before storing or scheduling it. Do not commit private or signed media URLs.
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
loops workflows validate /path/to/repo/.openloops/transcript-feedback-to-loops.json --preflight
|
|
169
|
+
loops workflows create /path/to/repo/.openloops/transcript-feedback-to-loops.json
|
|
170
|
+
loops workflows run transcript-feedback-to-loops --show-output
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
See `docs/TRANSCRIPT_LOOP_PATTERNS.md` for transcript-to-loop guardrails and example schedules for review, maintenance, CI optimization, feedback triage, and knowledge-capture loops.
|
|
174
|
+
|
|
158
175
|
## Manage
|
|
159
176
|
|
|
160
177
|
```bash
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "transcript-feedback-to-loops",
|
|
3
|
+
"description": "Turn an authorized media transcript into a reviewable backlog of recurring OpenLoops workflows.",
|
|
4
|
+
"version": 1,
|
|
5
|
+
"steps": [
|
|
6
|
+
{
|
|
7
|
+
"id": "check-transcriber",
|
|
8
|
+
"description": "Fail early if the transcriber CLI is unavailable to the workflow runner.",
|
|
9
|
+
"target": {
|
|
10
|
+
"type": "command",
|
|
11
|
+
"command": "transcriber",
|
|
12
|
+
"args": ["--version"],
|
|
13
|
+
"cwd": "/path/to/repo",
|
|
14
|
+
"timeoutMs": 30000
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"id": "check-loops",
|
|
19
|
+
"description": "Fail early if the loops CLI is unavailable for generated workflow validation.",
|
|
20
|
+
"target": {
|
|
21
|
+
"type": "command",
|
|
22
|
+
"command": "loops",
|
|
23
|
+
"args": ["--version"],
|
|
24
|
+
"cwd": "/path/to/repo",
|
|
25
|
+
"timeoutMs": 30000
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "transcribe-media",
|
|
30
|
+
"description": "Use iapp-transcriber to download authorized media and write a structured transcript artifact.",
|
|
31
|
+
"dependsOn": ["check-transcriber"],
|
|
32
|
+
"target": {
|
|
33
|
+
"type": "command",
|
|
34
|
+
"command": "mkdir -p .openloops/transcripts && transcriber transcribe \"${TRANSCRIBER_SOURCE_URL:?set TRANSCRIBER_SOURCE_URL in workflow target.env}\" --provider \"${TRANSCRIBER_PROVIDER:-openai}\" --json > .openloops/transcripts/latest-transcript.json",
|
|
35
|
+
"shell": true,
|
|
36
|
+
"cwd": "/path/to/repo",
|
|
37
|
+
"env": {
|
|
38
|
+
"TRANSCRIBER_PROVIDER": "openai"
|
|
39
|
+
},
|
|
40
|
+
"timeoutMs": 3600000
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"id": "extract-loop-backlog",
|
|
45
|
+
"description": "Extract recurring engineering loop candidates from the transcript.",
|
|
46
|
+
"dependsOn": ["transcribe-media"],
|
|
47
|
+
"target": {
|
|
48
|
+
"type": "agent",
|
|
49
|
+
"provider": "codewith",
|
|
50
|
+
"cwd": "/path/to/repo",
|
|
51
|
+
"timeoutMs": 1800000,
|
|
52
|
+
"prompt": "Read .openloops/transcripts/latest-transcript.json and create or update docs/loop-backlog.md. Extract only recurring work that is useful enough to schedule through OpenLoops. For each candidate include cadence, target provider, allowed write scope, expected artifacts, verification command, stop condition, and the specific transcript insight that justifies it. Prefer loops for code review/security, customer feedback triage, maintenance PRs, CI optimization, knowledge capture, and workflow hygiene."
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"id": "author-loop-workflows",
|
|
57
|
+
"description": "Turn approved backlog items into workflow specs.",
|
|
58
|
+
"dependsOn": ["extract-loop-backlog"],
|
|
59
|
+
"target": {
|
|
60
|
+
"type": "agent",
|
|
61
|
+
"provider": "codewith",
|
|
62
|
+
"cwd": "/path/to/repo",
|
|
63
|
+
"timeoutMs": 1800000,
|
|
64
|
+
"prompt": "Use docs/loop-backlog.md to author or update workflow JSON specs under docs/workflows/generated. Each workflow must use deterministic command steps for checks, agent steps for judgment or code changes, and workflow or step goals only when the outcome needs planning. Keep prompts scoped to the target repo, name allowed paths, and include validation evidence."
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"id": "validate-loop-workflows",
|
|
69
|
+
"description": "Validate generated workflow specs before scheduling.",
|
|
70
|
+
"dependsOn": ["author-loop-workflows", "check-loops"],
|
|
71
|
+
"target": {
|
|
72
|
+
"type": "command",
|
|
73
|
+
"command": "set -- docs/workflows/generated/*.json; [ -e \"$1\" ] || { echo \"no generated workflow specs found; nothing to validate\"; exit 0; }; for file do loops workflows validate \"$file\" --preflight; done",
|
|
74
|
+
"shell": true,
|
|
75
|
+
"cwd": "/path/to/repo",
|
|
76
|
+
"timeoutMs": 300000
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/loops",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.7",
|
|
4
4
|
"description": "Persistent local loop and workflow runner for deterministic commands and headless AI coding agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -65,7 +65,10 @@
|
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
67
|
"@hasna/machines": "0.0.49",
|
|
68
|
-
"
|
|
68
|
+
"@openrouter/ai-sdk-provider": "2.9.1",
|
|
69
|
+
"ai": "6.0.204",
|
|
70
|
+
"commander": "^13.1.0",
|
|
71
|
+
"zod": "4.4.3"
|
|
69
72
|
},
|
|
70
73
|
"devDependencies": {
|
|
71
74
|
"@types/bun": "latest",
|