@loopstack/cli 0.17.0 → 0.19.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/README.md +14 -10
- package/dist/commands/answer.d.ts +3 -0
- package/dist/commands/answer.d.ts.map +1 -0
- package/dist/commands/answer.js +82 -0
- package/dist/commands/answer.js.map +1 -0
- package/dist/commands/attach.d.ts +3 -0
- package/dist/commands/attach.d.ts.map +1 -0
- package/dist/commands/attach.js +103 -0
- package/dist/commands/attach.js.map +1 -0
- package/dist/commands/create.js +3 -3
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +38 -13
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/runs.d.ts.map +1 -1
- package/dist/commands/runs.js +67 -69
- package/dist/commands/runs.js.map +1 -1
- package/dist/commands/watch.d.ts.map +1 -1
- package/dist/commands/watch.js +3 -1
- package/dist/commands/watch.js.map +1 -1
- package/dist/hitl/discovery.d.ts +15 -7
- package/dist/hitl/discovery.d.ts.map +1 -1
- package/dist/hitl/discovery.js +85 -28
- package/dist/hitl/discovery.js.map +1 -1
- package/dist/hitl/idle-handler.d.ts +0 -1
- package/dist/hitl/idle-handler.d.ts.map +1 -1
- package/dist/hitl/idle-handler.js +49 -17
- package/dist/hitl/idle-handler.js.map +1 -1
- package/dist/hitl/pending.d.ts +16 -0
- package/dist/hitl/pending.d.ts.map +1 -0
- package/dist/hitl/pending.js +45 -0
- package/dist/hitl/pending.js.map +1 -0
- package/dist/hitl/prompt.d.ts +5 -8
- package/dist/hitl/prompt.d.ts.map +1 -1
- package/dist/hitl/prompt.js +47 -105
- package/dist/hitl/prompt.js.map +1 -1
- package/dist/main.js +4 -0
- package/dist/main.js.map +1 -1
- package/dist/output/format.d.ts +1 -1
- package/dist/output/format.d.ts.map +1 -1
- package/dist/output/format.js +16 -5
- package/dist/output/format.js.map +1 -1
- package/dist/run/documents.d.ts +13 -1
- package/dist/run/documents.d.ts.map +1 -1
- package/dist/run/documents.js +82 -22
- package/dist/run/documents.js.map +1 -1
- package/dist/run/follow.d.ts +6 -2
- package/dist/run/follow.d.ts.map +1 -1
- package/dist/run/follow.js +61 -9
- package/dist/run/follow.js.map +1 -1
- package/dist/run/retry.d.ts +5 -0
- package/dist/run/retry.d.ts.map +1 -0
- package/dist/run/retry.js +59 -0
- package/dist/run/retry.js.map +1 -0
- package/dist/run/trail.d.ts +17 -0
- package/dist/run/trail.d.ts.map +1 -0
- package/dist/run/trail.js +42 -0
- package/dist/run/trail.js.map +1 -0
- package/dist/widgets/collect/form.collect.d.ts +7 -0
- package/dist/widgets/collect/form.collect.d.ts.map +1 -0
- package/dist/widgets/collect/form.collect.js +71 -0
- package/dist/widgets/collect/form.collect.js.map +1 -0
- package/dist/widgets/collect/prompts.collect.d.ts +5 -0
- package/dist/widgets/collect/prompts.collect.d.ts.map +1 -0
- package/dist/widgets/collect/prompts.collect.js +38 -0
- package/dist/widgets/collect/prompts.collect.js.map +1 -0
- package/dist/widgets/collect/secret-input.collect.d.ts +3 -0
- package/dist/widgets/collect/secret-input.collect.d.ts.map +1 -0
- package/dist/widgets/collect/secret-input.collect.js +47 -0
- package/dist/widgets/collect/secret-input.collect.js.map +1 -0
- package/dist/widgets/collect/transition.d.ts +3 -0
- package/dist/widgets/collect/transition.d.ts.map +1 -0
- package/dist/widgets/collect/transition.js +5 -0
- package/dist/widgets/collect/transition.js.map +1 -0
- package/dist/widgets/collect/workflow.collect.d.ts +4 -0
- package/dist/widgets/collect/workflow.collect.d.ts.map +1 -0
- package/dist/widgets/collect/workflow.collect.js +24 -0
- package/dist/widgets/collect/workflow.collect.js.map +1 -0
- package/dist/widgets/document/form.widget.d.ts +3 -0
- package/dist/widgets/document/form.widget.d.ts.map +1 -0
- package/dist/widgets/document/form.widget.js +34 -0
- package/dist/widgets/document/form.widget.js.map +1 -0
- package/dist/widgets/document/json.widget.d.ts +3 -0
- package/dist/widgets/document/json.widget.d.ts.map +1 -0
- package/dist/widgets/document/json.widget.js +17 -0
- package/dist/widgets/document/json.widget.js.map +1 -0
- package/dist/widgets/document/link.widget.d.ts +3 -0
- package/dist/widgets/document/link.widget.d.ts.map +1 -0
- package/dist/widgets/document/link.widget.js +9 -0
- package/dist/widgets/document/link.widget.js.map +1 -0
- package/dist/widgets/document/llm-message.widget.d.ts +3 -0
- package/dist/widgets/document/llm-message.widget.d.ts.map +1 -0
- package/dist/widgets/document/llm-message.widget.js +97 -0
- package/dist/widgets/document/llm-message.widget.js.map +1 -0
- package/dist/widgets/document/message.widget.d.ts +5 -0
- package/dist/widgets/document/message.widget.d.ts.map +1 -0
- package/dist/widgets/document/message.widget.js +35 -0
- package/dist/widgets/document/message.widget.js.map +1 -0
- package/dist/widgets/document/oauth-prompt.widget.d.ts +4 -0
- package/dist/widgets/document/oauth-prompt.widget.d.ts.map +1 -0
- package/dist/widgets/document/oauth-prompt.widget.js +22 -0
- package/dist/widgets/document/oauth-prompt.widget.js.map +1 -0
- package/dist/widgets/document/secret-request.widget.d.ts +3 -0
- package/dist/widgets/document/secret-request.widget.d.ts.map +1 -0
- package/dist/widgets/document/secret-request.widget.js +9 -0
- package/dist/widgets/document/secret-request.widget.js.map +1 -0
- package/dist/{hitl → widgets}/editor.d.ts +0 -1
- package/dist/widgets/editor.d.ts.map +1 -0
- package/dist/{hitl → widgets}/editor.js +0 -13
- package/dist/widgets/editor.js.map +1 -0
- package/dist/widgets/field/field-widgets.d.ts +6 -0
- package/dist/widgets/field/field-widgets.d.ts.map +1 -0
- package/dist/widgets/field/field-widgets.js +64 -0
- package/dist/widgets/field/field-widgets.js.map +1 -0
- package/dist/widgets/registry.d.ts +6 -0
- package/dist/widgets/registry.d.ts.map +1 -0
- package/dist/widgets/registry.js +45 -0
- package/dist/widgets/registry.js.map +1 -0
- package/dist/widgets/types.d.ts +44 -0
- package/dist/widgets/types.d.ts.map +1 -0
- package/dist/widgets/types.js +2 -0
- package/dist/widgets/types.js.map +1 -0
- package/fixtures/app/CLAUDE.md +16 -2
- package/fixtures/app/README.md +8 -2
- package/fixtures/app/docker-compose.studio.yml +10 -0
- package/fixtures/app/docker-compose.yml +0 -8
- package/fixtures/app/env.example +5 -0
- package/fixtures/app/src/main.ts +3 -0
- package/package.json +3 -3
- package/dist/hitl/editor.d.ts.map +0 -1
- package/dist/hitl/editor.js.map +0 -1
package/fixtures/app/CLAUDE.md
CHANGED
|
@@ -6,7 +6,7 @@ This is a [Loopstack](https://loopstack.ai) app — a NestJS backend where AI wo
|
|
|
6
6
|
|
|
7
7
|
- `src/app.module.ts` — mounts `LoopstackModule.forRoot()` plus your app modules
|
|
8
8
|
- `src/hello/` — a complete example: `hello.module.ts` (`@StudioApp` groups workflows into an app) and `hello.workflow.ts` (a minimal workflow)
|
|
9
|
-
- `docker-compose.yml` — Postgres
|
|
9
|
+
- `docker-compose.yml` — Postgres + Redis (Studio is a separate, optional `docker-compose.studio.yml` on http://localhost:5173; you don't need it — use the CLI below)
|
|
10
10
|
- `.env` — configuration; add API keys here when a module needs them
|
|
11
11
|
|
|
12
12
|
## The feedback loop — use the CLI, not guesswork
|
|
@@ -17,12 +17,16 @@ The `loopstack` CLI talks to the running backend (`npm run start:dev`, http://lo
|
|
|
17
17
|
loopstack list # what can be run right now
|
|
18
18
|
loopstack run <workflow> --arg k=v # run it, streamed live; --json for machine-readable output
|
|
19
19
|
loopstack runs # recent runs, waiting-for-input first
|
|
20
|
-
loopstack runs <run-id>
|
|
20
|
+
loopstack runs <run-id> # one run's audit trail (+ pendingPrompt under --json)
|
|
21
|
+
loopstack answer <run-id> --arg k=v # answer a waiting run's prompt non-interactively
|
|
22
|
+
loopstack attach <run-id> # rejoin a run live and answer its prompts interactively
|
|
21
23
|
loopstack watch --json # NDJSON event firehose while you develop
|
|
22
24
|
```
|
|
23
25
|
|
|
24
26
|
Exit codes: `0` completed, `1` failed, `2` connection/config error, `3` waiting for input in a non-interactive shell. After changing code, the dev server reloads automatically — rerun the workflow to verify.
|
|
25
27
|
|
|
28
|
+
When a run exits `3`, it parked on a human question. Close the loop instead of stopping: read the question with `loopstack runs <run-id> --json` (the `pendingPrompt` field carries the description, the expected answer schema, and the transition), ask the human for their answer, submit it with `loopstack answer <run-id> --arg key=value`, then re-check `loopstack runs <run-id>` for the outcome. Never invent an answer to a human question yourself.
|
|
29
|
+
|
|
26
30
|
## Writing workflows
|
|
27
31
|
|
|
28
32
|
Follow `src/hello/hello.workflow.ts` as the canonical example:
|
|
@@ -33,6 +37,16 @@ Follow `src/hello/hello.workflow.ts` as the canonical example:
|
|
|
33
37
|
- Documents are classes with `@Document({ schema })` (zod) saved via `this.documentStore.save(SomeDocument, data)` — they are what Studio renders.
|
|
34
38
|
- Tools are NestJS providers with `@Tool({ name })`, implementing `protected async handle(args, ctx, options?): Promise<ToolEnvelope>`.
|
|
35
39
|
|
|
40
|
+
## Testing
|
|
41
|
+
|
|
42
|
+
Tests are ordinary vitest tests that run the real engine in-process — no backend, no database:
|
|
43
|
+
|
|
44
|
+
- `runWorkflow(MyWorkflow, args, { providers, answers })` from `@loopstack/testing` executes the workflow and returns `{ status, path, result, documents, document(key) }` for assertions. Script HITL input with `answers: { waitTransitionName: payload }`; sub-workflows run inline.
|
|
45
|
+
- `testTool().forTool(MyTool)` unit-tests a tool's `handle()` in isolation.
|
|
46
|
+
- For deterministic LLM/tool regression tests, record a live run (`loopstack run <workflow> --trace`, then `loopstack runs <run-id> --record fixture.json`) and pass `replay: replay('fixture.json')` to `runWorkflow`. Omit `replay` to test against real providers — keep those assertions structural and run them on demand, not in CI.
|
|
47
|
+
|
|
48
|
+
Write workflow tests for every non-trivial workflow you build. Guide: https://loopstack.ai/docs/build/testing
|
|
49
|
+
|
|
36
50
|
## Learning more
|
|
37
51
|
|
|
38
52
|
- Docs: https://loopstack.ai/docs — for agents, the full corpus is at https://loopstack.ai/llms.txt (route via titles, fetch what you need)
|
package/fixtures/app/README.md
CHANGED
|
@@ -5,16 +5,22 @@ Scaffolded with `loopstack create`.
|
|
|
5
5
|
## Quickstart
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
docker compose up -d # Postgres
|
|
8
|
+
docker compose up -d # Postgres + Redis
|
|
9
9
|
npm run start:dev # the backend on http://localhost:3000
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Run the hello workflow from the terminal:
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
15
|
npx @loopstack/cli run hello --arg name=You
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
+
Prefer a visual UI? Start Studio (optional) and open [http://localhost:5173](http://localhost:5173):
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
docker compose -f docker-compose.studio.yml up -d
|
|
22
|
+
```
|
|
23
|
+
|
|
18
24
|
## Next steps
|
|
19
25
|
|
|
20
26
|
- Build your first workflow: https://loopstack.ai/docs
|
|
@@ -20,14 +20,6 @@ services:
|
|
|
20
20
|
volumes:
|
|
21
21
|
- redis_data:/data
|
|
22
22
|
|
|
23
|
-
studio:
|
|
24
|
-
image: ghcr.io/loopstack-ai/loopstack-studio:latest
|
|
25
|
-
pull_policy: always
|
|
26
|
-
ports:
|
|
27
|
-
- '5173:3000'
|
|
28
|
-
environment:
|
|
29
|
-
VITE_API_URL: ${VITE_API_URL:-http://localhost:3000}
|
|
30
|
-
|
|
31
23
|
volumes:
|
|
32
24
|
postgres_data:
|
|
33
25
|
redis_data:
|
package/fixtures/app/env.example
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
# PORT=3000
|
|
4
4
|
|
|
5
|
+
# Point at any Postgres / Redis with a single URL (managed, hosted, or your own),
|
|
6
|
+
# or use the discrete vars below. A URL, when set, takes precedence.
|
|
7
|
+
# DATABASE_URL=postgres://postgres:admin@localhost:5432/postgres
|
|
8
|
+
# REDIS_URL=redis://localhost:6379
|
|
9
|
+
|
|
5
10
|
# DATABASE_HOST=localhost
|
|
6
11
|
# DATABASE_PORT=5432
|
|
7
12
|
# DATABASE_USERNAME=postgres
|
package/fixtures/app/src/main.ts
CHANGED
|
@@ -3,6 +3,9 @@ import { AppModule } from './app.module';
|
|
|
3
3
|
|
|
4
4
|
async function bootstrap() {
|
|
5
5
|
const app = await NestFactory.create(AppModule);
|
|
6
|
+
// Graceful shutdown: on SIGTERM/SIGINT the BullMQ worker finishes in-flight
|
|
7
|
+
// transitions before the process exits, instead of stalling them.
|
|
8
|
+
app.enableShutdownHooks();
|
|
6
9
|
await app.listen(process.env.PORT ?? 3000);
|
|
7
10
|
}
|
|
8
11
|
void bootstrap();
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@loopstack/cli",
|
|
3
3
|
"displayName": "Loopstack CLI",
|
|
4
4
|
"description": "Run, trace, and watch Loopstack workflows from the terminal",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.19.0",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Jakob Klippel",
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"watch": "tsc -p tsconfig.build.json --watch"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@loopstack/client": "^0.
|
|
30
|
-
"@loopstack/contracts": "^0.
|
|
29
|
+
"@loopstack/client": "^0.39.0",
|
|
30
|
+
"@loopstack/contracts": "^0.39.0",
|
|
31
31
|
"commander": "^15.0.0",
|
|
32
32
|
"picocolors": "^1.1.1"
|
|
33
33
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../src/hitl/editor.ts"],"names":[],"mappings":"AAiCA,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAS7G;AAGD,wBAAgB,kBAAkB,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,EAAE,CAU7E;AAQD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,cAAc,GAAG,OAAO,CAqBzG"}
|
package/dist/hitl/editor.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"editor.js","sourceRoot":"","sources":["../../src/hitl/editor.ts"],"names":[],"mappings":"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"}
|