@loopstack/cli 0.15.1 → 0.17.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 +62 -0
- package/dist/commands/create.d.ts +3 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/create.js +80 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/env.d.ts +3 -0
- package/dist/commands/env.d.ts.map +1 -0
- package/dist/commands/env.js +42 -0
- package/dist/commands/env.js.map +1 -0
- package/dist/commands/list.d.ts +3 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +119 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/login.d.ts +3 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +62 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/run.d.ts +3 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +94 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/runs.d.ts +3 -0
- package/dist/commands/runs.d.ts.map +1 -0
- package/dist/commands/runs.js +153 -0
- package/dist/commands/runs.js.map +1 -0
- package/dist/commands/watch.d.ts +3 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +48 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/config/config.d.ts +14 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +25 -0
- package/dist/config/config.js.map +1 -0
- package/dist/config/resolve.d.ts +18 -0
- package/dist/config/resolve.d.ts.map +1 -0
- package/dist/config/resolve.js +57 -0
- package/dist/config/resolve.js.map +1 -0
- package/dist/errors.d.ts +12 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +36 -0
- package/dist/errors.js.map +1 -0
- package/dist/hitl/discovery.d.ts +16 -0
- package/dist/hitl/discovery.d.ts.map +1 -0
- package/dist/hitl/discovery.js +67 -0
- package/dist/hitl/discovery.js.map +1 -0
- package/dist/hitl/editor.d.ts +4 -0
- package/dist/hitl/editor.d.ts.map +1 -0
- package/dist/hitl/editor.js +73 -0
- package/dist/hitl/editor.js.map +1 -0
- package/dist/hitl/idle-handler.d.ts +8 -0
- package/dist/hitl/idle-handler.d.ts.map +1 -0
- package/dist/hitl/idle-handler.js +71 -0
- package/dist/hitl/idle-handler.js.map +1 -0
- package/dist/hitl/prompt.d.ts +14 -0
- package/dist/hitl/prompt.d.ts.map +1 -0
- package/dist/hitl/prompt.js +127 -0
- package/dist/hitl/prompt.js.map +1 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +33 -0
- package/dist/main.js.map +1 -0
- package/dist/output/format.d.ts +7 -0
- package/dist/output/format.d.ts.map +1 -0
- package/dist/output/format.js +47 -0
- package/dist/output/format.js.map +1 -0
- package/dist/output/studio-link.d.ts +4 -0
- package/dist/output/studio-link.d.ts.map +1 -0
- package/dist/output/studio-link.js +17 -0
- package/dist/output/studio-link.js.map +1 -0
- package/dist/run/args.d.ts +2 -0
- package/dist/run/args.d.ts.map +1 -0
- package/dist/run/args.js +41 -0
- package/dist/run/args.js.map +1 -0
- package/dist/run/documents.d.ts +3 -0
- package/dist/run/documents.d.ts.map +1 -0
- package/dist/run/documents.js +40 -0
- package/dist/run/documents.js.map +1 -0
- package/dist/run/follow.d.ts +14 -0
- package/dist/run/follow.d.ts.map +1 -0
- package/dist/run/follow.js +148 -0
- package/dist/run/follow.js.map +1 -0
- package/dist/run/workspace.d.ts +3 -0
- package/dist/run/workspace.d.ts.map +1 -0
- package/dist/run/workspace.js +26 -0
- package/dist/run/workspace.js.map +1 -0
- package/fixtures/app/CLAUDE.md +40 -0
- package/fixtures/app/README.md +21 -0
- package/fixtures/app/docker-compose.yml +33 -0
- package/fixtures/app/env.example +16 -0
- package/fixtures/app/nest-cli.json +10 -0
- package/fixtures/app/src/app.module.ts +8 -0
- package/fixtures/app/src/hello/hello.module.ts +12 -0
- package/fixtures/app/src/hello/hello.workflow.ts +28 -0
- package/fixtures/app/src/main.ts +8 -0
- package/package.json +36 -10
- package/bin/loopstack.js +0 -33
package/README.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# @loopstack/cli
|
|
2
|
+
|
|
3
|
+
Scaffold, run, inspect, and watch [Loopstack](https://loopstack.ai) workflows from the terminal — live transition and LLM token streaming, human-in-the-loop prompts answered inline, and CI-ready JSON output with meaningful exit codes.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install -g @loopstack/cli
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Start a new app with a zero-config hello workflow:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
loopstack create my-app
|
|
13
|
+
cd my-app && docker compose up -d && npm run start:dev
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
$ loopstack run hello --arg name=Maya
|
|
18
|
+
|
|
19
|
+
▸ run 088cd19c… started
|
|
20
|
+
▸ start
|
|
21
|
+
✓ start (9ms)
|
|
22
|
+
Hello, Maya! 👋
|
|
23
|
+
result: {"greeting":"Hello, Maya! 👋"}
|
|
24
|
+
■ run completed in 96ms
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
When a run asks a question, answer it right there — or in Studio; whichever answers first wins, and the CLI keeps following either way. Field forms hand off to Studio via deep link (or open in `$EDITOR` with `--editor`):
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
⏸ waiting_for_answer
|
|
31
|
+
|
|
32
|
+
Which environment should we deploy to?
|
|
33
|
+
1. staging
|
|
34
|
+
2. production
|
|
35
|
+
answer: 2
|
|
36
|
+
■ run completed
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Commands
|
|
40
|
+
|
|
41
|
+
| Command | What it does |
|
|
42
|
+
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
|
|
43
|
+
| `loopstack create <dir>` | Scaffold a new Loopstack app (NestJS + LoopstackModule + hello workflow + docker-compose) |
|
|
44
|
+
| `loopstack list [workflow]` | Workflows you can run; with a name: its arguments and a ready-to-run example |
|
|
45
|
+
| `loopstack run <workflow>` | Start a run and follow it live; `--arg k=v`, `--arg k=@file.json`, `--arg k=@-` (stdin), `--detach`, `--quiet`, `--open`, `--json` |
|
|
46
|
+
| `loopstack runs [run-id]` | Recent runs (waiting-for-input first) or one run’s audit trail; `--follow` reattaches and answers prompts |
|
|
47
|
+
| `loopstack watch` | Live event stream; `--workflow`, `--type`, NDJSON with `--json` |
|
|
48
|
+
| `loopstack login` | Save a backend environment to `~/.loopstack/config.json` |
|
|
49
|
+
| `loopstack env list\|use` | Manage saved environments |
|
|
50
|
+
|
|
51
|
+
## CI
|
|
52
|
+
|
|
53
|
+
```yaml
|
|
54
|
+
- run: npx --yes @loopstack/cli run triage-ticket --arg ticket=@samples/ticket-042.json --json
|
|
55
|
+
env:
|
|
56
|
+
LOOPSTACK_URL: ${{ vars.LOOPSTACK_URL }}
|
|
57
|
+
LOOPSTACK_TOKEN: ${{ secrets.LOOPSTACK_TOKEN }}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Exit codes: `0` completed · `1` failed · `2` connection/config error · `3` waiting for input (non-interactive). `--json` prints one final object — `{ workflowId, status, result, errorMessage, durationMs }` — on a clean stdout.
|
|
61
|
+
|
|
62
|
+
Local backends with auth disabled need no login or token at all. When an environment has a Studio URL (saved via `login`, `LOOPSTACK_STUDIO_URL`, or the local default), run output includes deep links into Studio — and `--open` jumps straight there. Full documentation: [CLI Reference](https://loopstack.ai/docs/reference/cli).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2CzC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA4D5D"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import pc from 'picocolors';
|
|
6
|
+
import { CliError } from '../errors.js';
|
|
7
|
+
import { printData, printStatus } from '../output/format.js';
|
|
8
|
+
const FIXTURES_DIR = fileURLToPath(new URL('../../fixtures/app', import.meta.url));
|
|
9
|
+
const LOOPSTACK_DEPENDENCIES = ['@loopstack/loopstack-module', '@loopstack/common', 'zod'];
|
|
10
|
+
function run(label, command, args, cwd) {
|
|
11
|
+
printStatus(pc.dim(`▸ ${label}`));
|
|
12
|
+
const result = spawnSync(command, args, { cwd, stdio: ['ignore', 2, 2] });
|
|
13
|
+
if (result.error)
|
|
14
|
+
throw new CliError(`${label} failed: ${result.error.message}`);
|
|
15
|
+
if (result.status !== 0)
|
|
16
|
+
throw new CliError(`${label} failed (exit ${result.status ?? 'unknown'})`);
|
|
17
|
+
}
|
|
18
|
+
function overlayFixtures(targetDir) {
|
|
19
|
+
fs.cpSync(FIXTURES_DIR, targetDir, { recursive: true });
|
|
20
|
+
const example = path.join(targetDir, 'env.example');
|
|
21
|
+
fs.copyFileSync(example, path.join(targetDir, '.env'));
|
|
22
|
+
fs.renameSync(example, path.join(targetDir, '.env.example'));
|
|
23
|
+
}
|
|
24
|
+
function addDependencies(targetDir) {
|
|
25
|
+
const pkgPath = path.join(targetDir, 'package.json');
|
|
26
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
27
|
+
pkg.dependencies ??= {};
|
|
28
|
+
for (const name of LOOPSTACK_DEPENDENCIES) {
|
|
29
|
+
pkg.dependencies[name] = 'latest';
|
|
30
|
+
}
|
|
31
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
|
|
32
|
+
}
|
|
33
|
+
export function registerCreateCommand(program) {
|
|
34
|
+
program
|
|
35
|
+
.command('create')
|
|
36
|
+
.description('Scaffold a new Loopstack app (NestJS + LoopstackModule + a hello workflow)')
|
|
37
|
+
.argument('<dir>', 'target directory — its basename becomes the project name')
|
|
38
|
+
.option('--skip-install', 'skip npm install (dependencies are added to package.json)')
|
|
39
|
+
.option('--no-git', 'skip git init')
|
|
40
|
+
.action((dir, options) => {
|
|
41
|
+
const targetDir = path.resolve(dir);
|
|
42
|
+
const name = path.basename(targetDir);
|
|
43
|
+
const parentDir = path.dirname(targetDir);
|
|
44
|
+
if (!/^[a-z0-9][a-z0-9-]*$/.test(name)) {
|
|
45
|
+
throw new CliError(`Invalid project name "${name}" — use lowercase letters, digits, and hyphens.`);
|
|
46
|
+
}
|
|
47
|
+
if (fs.existsSync(targetDir) && fs.readdirSync(targetDir).length > 0) {
|
|
48
|
+
throw new CliError(`Directory ${targetDir} already exists and is not empty.`);
|
|
49
|
+
}
|
|
50
|
+
fs.mkdirSync(parentDir, { recursive: true });
|
|
51
|
+
run('Scaffolding NestJS app', 'npx', ['--yes', '@nestjs/cli@latest', 'new', name, '--skip-git', '--skip-install', '--package-manager', 'npm'], parentDir);
|
|
52
|
+
printStatus(pc.dim('▸ Applying Loopstack fixtures'));
|
|
53
|
+
overlayFixtures(targetDir);
|
|
54
|
+
addDependencies(targetDir);
|
|
55
|
+
if (!options.skipInstall) {
|
|
56
|
+
run('Installing dependencies', 'npm', ['install'], targetDir);
|
|
57
|
+
}
|
|
58
|
+
if (options.git !== false) {
|
|
59
|
+
run('Initializing git repository', 'git', ['init', '-b', 'main'], targetDir);
|
|
60
|
+
spawnSync('git', ['add', '-A'], { cwd: targetDir, stdio: 'ignore' });
|
|
61
|
+
spawnSync('git', ['commit', '-m', 'Initial commit'], { cwd: targetDir, stdio: 'ignore' });
|
|
62
|
+
}
|
|
63
|
+
printStatus(pc.green(`■ Created ${name}`));
|
|
64
|
+
printData([
|
|
65
|
+
'',
|
|
66
|
+
'Next steps:',
|
|
67
|
+
` cd ${path.relative(process.cwd(), targetDir) || '.'}`,
|
|
68
|
+
...(options.skipInstall ? [' npm install'] : []),
|
|
69
|
+
' docker compose up -d # Postgres, Redis, and Studio',
|
|
70
|
+
' npm run start:dev # backend on http://localhost:3000',
|
|
71
|
+
'',
|
|
72
|
+
' Studio: http://localhost:5173',
|
|
73
|
+
' Terminal: npx @loopstack/cli run hello --arg name=You',
|
|
74
|
+
'',
|
|
75
|
+
' CLAUDE.md primes coding agents with the conventions and the CLI feedback loop.',
|
|
76
|
+
'',
|
|
77
|
+
].join('\n'));
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=create.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/commands/env.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMzC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuCzD"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import pc from 'picocolors';
|
|
2
|
+
import { loadConfig, saveConfig } from '../config/config.js';
|
|
3
|
+
import { CliError } from '../errors.js';
|
|
4
|
+
import { printData, printStatus, renderTable } from '../output/format.js';
|
|
5
|
+
export function registerEnvCommand(program) {
|
|
6
|
+
const env = program.command('env').description('Manage saved backend environments');
|
|
7
|
+
env
|
|
8
|
+
.command('list')
|
|
9
|
+
.description('List saved environments')
|
|
10
|
+
.action((_options, cmd) => {
|
|
11
|
+
const config = loadConfig();
|
|
12
|
+
const names = Object.keys(config.environments);
|
|
13
|
+
const globals = cmd.optsWithGlobals();
|
|
14
|
+
if (globals.json) {
|
|
15
|
+
printData(JSON.stringify(config, null, 2));
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (names.length === 0) {
|
|
19
|
+
printStatus('No environments saved — run `loopstack login`.');
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const rows = names.map((name) => [
|
|
23
|
+
config.defaultEnvironment === name ? `${name} ${pc.dim('(default)')}` : name,
|
|
24
|
+
config.environments[name].url,
|
|
25
|
+
config.environments[name].token ? 'yes' : 'no',
|
|
26
|
+
]);
|
|
27
|
+
printData(renderTable(['NAME', 'URL', 'TOKEN'], rows));
|
|
28
|
+
});
|
|
29
|
+
env
|
|
30
|
+
.command('use <name>')
|
|
31
|
+
.description('Set the default environment')
|
|
32
|
+
.action((name) => {
|
|
33
|
+
const config = loadConfig();
|
|
34
|
+
if (!config.environments[name]) {
|
|
35
|
+
throw new CliError(`Unknown environment "${name}" — run \`loopstack env list\`.`);
|
|
36
|
+
}
|
|
37
|
+
config.defaultEnvironment = name;
|
|
38
|
+
saveConfig(config);
|
|
39
|
+
printStatus(pc.green(`✔ Default environment is now "${name}".`));
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/commands/env.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAE1E,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,mCAAmC,CAAC,CAAC;IAEpF,GAAG;SACA,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,yBAAyB,CAAC;SACtC,MAAM,CAAC,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE;QACxB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAC/C,MAAM,OAAO,GAAG,GAAG,CAAC,eAAe,EAAwB,CAAC;QAE5D,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC3C,OAAO;QACT,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,WAAW,CAAC,gDAAgD,CAAC,CAAC;YAC9D,OAAO;QACT,CAAC;QACD,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YAC/B,MAAM,CAAC,kBAAkB,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI;YAC5E,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,GAAG;YAC7B,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;SAC/C,CAAC,CAAC;QACH,SAAS,CAAC,WAAW,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEL,GAAG;SACA,OAAO,CAAC,YAAY,CAAC;SACrB,WAAW,CAAC,6BAA6B,CAAC;SAC1C,MAAM,CAAC,CAAC,IAAY,EAAE,EAAE;QACvB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,QAAQ,CAAC,wBAAwB,IAAI,iCAAiC,CAAC,CAAC;QACpF,CAAC;QACD,MAAM,CAAC,kBAAkB,GAAG,IAAI,CAAC;QACjC,UAAU,CAAC,MAAM,CAAC,CAAC;QACnB,WAAW,CAAC,EAAE,CAAC,KAAK,CAAC,iCAAiC,IAAI,IAAI,CAAC,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqBzC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAe1D"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import pc from 'picocolors';
|
|
2
|
+
import { createClientFor, resolveConnection } from '../config/resolve.js';
|
|
3
|
+
import { CliError } from '../errors.js';
|
|
4
|
+
import { printData, printStatus, renderTable } from '../output/format.js';
|
|
5
|
+
export function registerListCommand(program) {
|
|
6
|
+
program
|
|
7
|
+
.command('list [workflow]')
|
|
8
|
+
.description('List the workflows you can run, or show one workflow’s arguments')
|
|
9
|
+
.action(async (workflowName, _options, cmd) => {
|
|
10
|
+
const globals = cmd.optsWithGlobals();
|
|
11
|
+
const connection = resolveConnection(globals);
|
|
12
|
+
const client = createClientFor(connection);
|
|
13
|
+
if (workflowName) {
|
|
14
|
+
await describeWorkflow(client, workflowName, !!globals.json);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
await listWorkflows(client, connection, !!globals.json);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
async function listWorkflows(client, connection, json) {
|
|
21
|
+
const apps = await client.config.apps();
|
|
22
|
+
const workflows = apps.flatMap((app) => app.workflows.map((workflow) => ({
|
|
23
|
+
workflowName: workflow.workflowName,
|
|
24
|
+
title: workflow.title ?? '',
|
|
25
|
+
description: workflow.description ?? '',
|
|
26
|
+
appName: app.appName,
|
|
27
|
+
appTitle: app.title,
|
|
28
|
+
})));
|
|
29
|
+
if (json) {
|
|
30
|
+
printData(JSON.stringify(workflows, null, 2));
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (workflows.length === 0) {
|
|
34
|
+
printStatus(`No workflows on ${connection.url} — is a Loopstack app with @StudioApp modules running?`);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const rows = workflows.map((workflow) => [workflow.workflowName, workflow.title, workflow.appTitle]);
|
|
38
|
+
printData(renderTable(['WORKFLOW', 'TITLE', 'APP'], rows, [32, 42, 20]));
|
|
39
|
+
printStatus('');
|
|
40
|
+
printStatus(`${workflows.length} workflows in ${apps.length} apps (${connection.name}) — \`loopstack list <workflow>\` shows its arguments`);
|
|
41
|
+
}
|
|
42
|
+
async function describeWorkflow(client, workflowName, json) {
|
|
43
|
+
const apps = await client.config.apps();
|
|
44
|
+
let app;
|
|
45
|
+
let workflow;
|
|
46
|
+
for (const candidate of apps) {
|
|
47
|
+
workflow = candidate.workflows.find((entry) => entry.workflowName === workflowName);
|
|
48
|
+
if (workflow) {
|
|
49
|
+
app = candidate;
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (!workflow || !app) {
|
|
54
|
+
const available = apps.flatMap((entry) => entry.workflows.map((item) => item.workflowName)).sort();
|
|
55
|
+
throw new CliError(`Unknown workflow "${workflowName}". Available workflows: ${available.join(', ')}`);
|
|
56
|
+
}
|
|
57
|
+
const schema = (workflow.schema ?? {});
|
|
58
|
+
const properties = schema.type === 'object' ? (schema.properties ?? {}) : {};
|
|
59
|
+
const required = new Set(schema.required ?? []);
|
|
60
|
+
if (json) {
|
|
61
|
+
printData(JSON.stringify({
|
|
62
|
+
workflowName: workflow.workflowName,
|
|
63
|
+
title: workflow.title,
|
|
64
|
+
description: workflow.description,
|
|
65
|
+
appName: app.appName,
|
|
66
|
+
appTitle: app.title,
|
|
67
|
+
schema: workflow.schema ?? null,
|
|
68
|
+
}, null, 2));
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const title = workflow.title ? ` — ${workflow.title}` : '';
|
|
72
|
+
printData(`${pc.bold(workflow.workflowName)}${title}`);
|
|
73
|
+
if (workflow.description)
|
|
74
|
+
printData(workflow.description);
|
|
75
|
+
printData(pc.dim(`app: ${app.title} (${app.appName})`));
|
|
76
|
+
printData('');
|
|
77
|
+
const argNames = Object.keys(properties);
|
|
78
|
+
if (argNames.length === 0) {
|
|
79
|
+
printData(pc.dim('No arguments.'));
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
const rows = argNames.map((name) => {
|
|
83
|
+
const property = properties[name];
|
|
84
|
+
return [
|
|
85
|
+
name,
|
|
86
|
+
property.type ?? 'any',
|
|
87
|
+
required.has(name) && property.default === undefined ? 'yes' : 'no',
|
|
88
|
+
property.default !== undefined ? JSON.stringify(property.default) : '',
|
|
89
|
+
property.description ?? '',
|
|
90
|
+
];
|
|
91
|
+
});
|
|
92
|
+
printData(renderTable(['ARGUMENT', 'TYPE', 'REQUIRED', 'DEFAULT', 'DESCRIPTION'], rows));
|
|
93
|
+
}
|
|
94
|
+
printData('');
|
|
95
|
+
printData(`Run it: ${pc.bold(exampleInvocation(workflow.workflowName, properties, required))}`);
|
|
96
|
+
}
|
|
97
|
+
function exampleInvocation(workflowName, properties, required) {
|
|
98
|
+
const sample = (property) => {
|
|
99
|
+
if (property.default !== undefined)
|
|
100
|
+
return JSON.stringify(property.default);
|
|
101
|
+
switch (property.type) {
|
|
102
|
+
case 'number':
|
|
103
|
+
case 'integer':
|
|
104
|
+
return '42';
|
|
105
|
+
case 'boolean':
|
|
106
|
+
return 'true';
|
|
107
|
+
default:
|
|
108
|
+
return `<${property.type ?? 'value'}>`;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
const names = Object.keys(properties);
|
|
112
|
+
const shown = names.filter((name) => required.has(name));
|
|
113
|
+
const optional = names.filter((name) => !required.has(name));
|
|
114
|
+
if (shown.length === 0 || names.length <= 3)
|
|
115
|
+
shown.push(...optional.slice(0, 3 - shown.length));
|
|
116
|
+
const args = shown.map((name) => `--arg ${name}=${sample(properties[name])}`).join(' ');
|
|
117
|
+
return `loopstack run ${workflowName}${args ? ` ${args}` : ''}`;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAczC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAsD3D"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { stdin, stdout } from 'node:process';
|
|
2
|
+
import { createInterface } from 'node:readline/promises';
|
|
3
|
+
import pc from 'picocolors';
|
|
4
|
+
import { createClient } from '@loopstack/client';
|
|
5
|
+
import { configPath, loadConfig, saveConfig } from '../config/config.js';
|
|
6
|
+
import { CliError } from '../errors.js';
|
|
7
|
+
import { printStatus } from '../output/format.js';
|
|
8
|
+
function suggestName(url) {
|
|
9
|
+
const hostname = new URL(url).hostname;
|
|
10
|
+
return hostname === 'localhost' || hostname === '127.0.0.1' ? 'local' : hostname;
|
|
11
|
+
}
|
|
12
|
+
export function registerLoginCommand(program) {
|
|
13
|
+
program
|
|
14
|
+
.command('login')
|
|
15
|
+
.description('Save a backend environment to ~/.loopstack/config.json (pass --url/--token or answer the prompts)')
|
|
16
|
+
.option('--name <name>', 'environment name')
|
|
17
|
+
.option('--studio-url <url>', 'Studio frontend URL — enables deep links in run output')
|
|
18
|
+
.action(async (_options, cmd) => {
|
|
19
|
+
const merged = cmd.optsWithGlobals();
|
|
20
|
+
let { url, token, name, studioUrl } = merged;
|
|
21
|
+
token = token || undefined;
|
|
22
|
+
studioUrl = studioUrl || undefined;
|
|
23
|
+
if (!url && !stdin.isTTY) {
|
|
24
|
+
throw new CliError('Non-interactive shell — pass --url (and --token for authenticated backends).');
|
|
25
|
+
}
|
|
26
|
+
if (!url || (token === undefined && stdin.isTTY)) {
|
|
27
|
+
const rl = createInterface({ input: stdin, output: stdout });
|
|
28
|
+
try {
|
|
29
|
+
if (!url) {
|
|
30
|
+
url = (await rl.question('Backend URL [http://localhost:3000]: ')).trim() || 'http://localhost:3000';
|
|
31
|
+
}
|
|
32
|
+
if (token === undefined) {
|
|
33
|
+
token = (await rl.question('API token (lsk_…, empty for local no-auth): ')).trim() || undefined;
|
|
34
|
+
}
|
|
35
|
+
if (studioUrl === undefined) {
|
|
36
|
+
const isLocal = ['localhost', '127.0.0.1'].includes(new URL(url).hostname);
|
|
37
|
+
const suggestion = isLocal ? 'http://localhost:5173' : '';
|
|
38
|
+
const hint = suggestion ? ` [${suggestion}]` : ' (empty for none)';
|
|
39
|
+
studioUrl = (await rl.question(`Studio URL${hint}: `)).trim() || suggestion || undefined;
|
|
40
|
+
}
|
|
41
|
+
if (!name) {
|
|
42
|
+
const suggested = suggestName(url);
|
|
43
|
+
name = (await rl.question(`Environment name [${suggested}]: `)).trim() || suggested;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
rl.close();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
name ??= suggestName(url);
|
|
51
|
+
printStatus(pc.dim(`Probing ${url} …`));
|
|
52
|
+
const client = createClient({ url, token, envKey: name });
|
|
53
|
+
await client.workflows.list({ limit: 1 });
|
|
54
|
+
const config = loadConfig();
|
|
55
|
+
config.environments[name] = { ...config.environments[name], url, token, ...(studioUrl && { studioUrl }) };
|
|
56
|
+
config.defaultEnvironment ??= name;
|
|
57
|
+
saveConfig(config);
|
|
58
|
+
const isDefault = config.defaultEnvironment === name;
|
|
59
|
+
printStatus(pc.green(`✔ Environment "${name}" saved to ${configPath()}${isDefault ? ' (default)' : ''}.`));
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2BzC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgGzD"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Writable } from 'node:stream';
|
|
2
|
+
import pc from 'picocolors';
|
|
3
|
+
import { WorkflowState } from '@loopstack/contracts/enums';
|
|
4
|
+
import { createClientFor, resolveConnection } from '../config/resolve.js';
|
|
5
|
+
import { ExitCode } from '../errors.js';
|
|
6
|
+
import { createIdleHandler } from '../hitl/idle-handler.js';
|
|
7
|
+
import { formatDuration, printData, printStatus, renderResult } from '../output/format.js';
|
|
8
|
+
import { openInBrowser, studioRunUrl } from '../output/studio-link.js';
|
|
9
|
+
import { parseRunArgs } from '../run/args.js';
|
|
10
|
+
import { createDocumentRenderer } from '../run/documents.js';
|
|
11
|
+
import { followRun } from '../run/follow.js';
|
|
12
|
+
import { resolveWorkspaceId } from '../run/workspace.js';
|
|
13
|
+
const collect = (value, previous) => [...previous, value];
|
|
14
|
+
const discard = () => new Writable({ write: (_chunk, _encoding, callback) => callback() });
|
|
15
|
+
export function registerRunCommand(program) {
|
|
16
|
+
program
|
|
17
|
+
.command('run <workflow>')
|
|
18
|
+
.description('Start a workflow run and follow it live (exit 0 completed / 1 failed / 3 waiting for input)')
|
|
19
|
+
.option('--arg <key=value>', 'workflow argument, repeatable; key=@file.json reads a file, key=@- reads stdin', collect, [])
|
|
20
|
+
.option('--workspace <id>', 'workspace to run in (default: newest workspace of the workflow’s app)')
|
|
21
|
+
.option('--detach', 'start the run, print its id, exit immediately')
|
|
22
|
+
.option('--quiet', 'no progress — print only the final result')
|
|
23
|
+
.option('--open', 'open the run in Studio')
|
|
24
|
+
.option('--editor', 'answer field forms in $EDITOR instead of handing off to Studio')
|
|
25
|
+
.action(async (workflowName, options, cmd) => {
|
|
26
|
+
const globals = cmd.optsWithGlobals();
|
|
27
|
+
const connection = resolveConnection(globals);
|
|
28
|
+
const client = createClientFor(connection);
|
|
29
|
+
const json = !!globals.json;
|
|
30
|
+
const quiet = !!options.quiet;
|
|
31
|
+
const out = json ? process.stderr : quiet ? discard() : process.stdout;
|
|
32
|
+
const statusOut = json || quiet ? process.stderr : process.stdout;
|
|
33
|
+
const args = parseRunArgs(options.arg);
|
|
34
|
+
const workspaceId = await resolveWorkspaceId(client, workflowName, options.workspace, connection.workspaceId);
|
|
35
|
+
const events = options.detach ? undefined : client.stream.events();
|
|
36
|
+
const startedAt = Date.now();
|
|
37
|
+
const run = await client.processor.start({ workflowName, workspaceId, args });
|
|
38
|
+
out.write(pc.dim(`▸ run ${run.workflowId} started\n`));
|
|
39
|
+
const link = studioRunUrl(connection, run.workflowId);
|
|
40
|
+
if (link && events)
|
|
41
|
+
out.write(pc.dim(`⧉ ${link}\n`));
|
|
42
|
+
if (options.open) {
|
|
43
|
+
if (link)
|
|
44
|
+
openInBrowser(link);
|
|
45
|
+
else
|
|
46
|
+
printStatus('No Studio URL configured for this environment — set one with `loopstack login`.');
|
|
47
|
+
}
|
|
48
|
+
if (!events) {
|
|
49
|
+
if (link)
|
|
50
|
+
printStatus(pc.dim(`⧉ ${link}`));
|
|
51
|
+
printStatus(pc.dim(`resume with: loopstack runs ${run.workflowId} --follow`));
|
|
52
|
+
printData(json ? JSON.stringify({ workflowId: run.workflowId, ...(link && { studioUrl: link }) }) : run.workflowId);
|
|
53
|
+
process.exit(ExitCode.Success);
|
|
54
|
+
}
|
|
55
|
+
const outcome = await followRun(events, run.workflowId, out, {
|
|
56
|
+
onIdle: createIdleHandler(client, run.workflowId, statusOut, { studioUrl: link, editor: options.editor }),
|
|
57
|
+
onDocument: createDocumentRenderer(client, out),
|
|
58
|
+
});
|
|
59
|
+
client.stream.close();
|
|
60
|
+
const durationMs = Date.now() - startedAt;
|
|
61
|
+
const full = await client.workflows.get(run.workflowId);
|
|
62
|
+
if (json) {
|
|
63
|
+
printData(JSON.stringify({
|
|
64
|
+
workflowId: run.workflowId,
|
|
65
|
+
status: outcome.status,
|
|
66
|
+
result: full.result,
|
|
67
|
+
errorMessage: full.errorMessage,
|
|
68
|
+
durationMs,
|
|
69
|
+
...(link && { studioUrl: link }),
|
|
70
|
+
}, null, 2));
|
|
71
|
+
}
|
|
72
|
+
if (outcome.status === WorkflowState.Completed) {
|
|
73
|
+
if (!json && quiet) {
|
|
74
|
+
const result = full.result;
|
|
75
|
+
printData(typeof result === 'string' ? result : JSON.stringify(result ?? null, null, 2));
|
|
76
|
+
}
|
|
77
|
+
if (!json && !quiet)
|
|
78
|
+
renderResult(out, full.result);
|
|
79
|
+
statusOut.write(`${pc.green('■')} run completed in ${formatDuration(durationMs)}\n`);
|
|
80
|
+
process.exit(ExitCode.Success);
|
|
81
|
+
}
|
|
82
|
+
if (outcome.status === WorkflowState.Waiting || outcome.status === WorkflowState.Paused) {
|
|
83
|
+
statusOut.write(`${pc.yellow('⏸')} run is waiting for input — resume with \`loopstack runs ${run.workflowId} --follow\`\n`);
|
|
84
|
+
if (link)
|
|
85
|
+
statusOut.write(pc.dim(`⧉ answer in Studio: ${link}\n`));
|
|
86
|
+
process.exit(ExitCode.NeedsInput);
|
|
87
|
+
}
|
|
88
|
+
statusOut.write(`${pc.red('■')} run ${outcome.status}${full.errorMessage ? `: ${full.errorMessage}` : ''}\n`);
|
|
89
|
+
if (link)
|
|
90
|
+
statusOut.write(pc.dim(`⧉ inspect in Studio: ${link}\n`));
|
|
91
|
+
process.exit(ExitCode.RunFailed);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runs.d.ts","sourceRoot":"","sources":["../../src/commands/runs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsCzC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwB1D"}
|