@t4h.framework/cli 0.0.0-experimental-20261007204009 → 0.0.0-experimental-20261008135920

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/CHANGELOG.md CHANGED
@@ -1,11 +1,63 @@
1
1
  # @t4h.framework/cli
2
2
 
3
- ## 0.0.0-experimental-20261007204009
3
+ ## 0.0.0-experimental-20261008135920
4
+
5
+ ### Minor Changes
6
+
7
+ - [#216](https://github.com/tech4humans-brasil/framework/pull/216) [`3d2ea34`](https://github.com/tech4humans-brasil/framework/commit/3d2ea3406e857ccaa5b50f26dddf6892d415e239) Thanks [@tony-tsx](https://github.com/tony-tsx)! - The CLI runs the `@t4h.framework/dev` installed in the project instead of its
8
+ own copy, so the project picks the dev server version — a pinned or
9
+ experimental one included. `dev`, `build`, `workflows` and `runtime` resolve it
10
+ from the project's `node_modules` (or a parent workspace) when they run, and
11
+ `build` takes `@t4h.framework/core` from the project too. `@t4h.framework/dev`
12
+ moves to an optional peer dependency: add it to the project
13
+ (`yarn add -D @t4h.framework/dev`). When it is missing, or too old for a
14
+ command, the command prints the version it found and exits with `1`; the other
15
+ commands no longer need it.
16
+
17
+ - [#208](https://github.com/tech4humans-brasil/framework/pull/208) [`c312bfb`](https://github.com/tech4humans-brasil/framework/commit/c312bfb0f1b1ddbc40d8ac0ede113c5614aa9df8) Thanks [@tony-tsx](https://github.com/tony-tsx)! - `framework workflows` lists, describes and runs the workflows of the app from
18
+ the terminal, without the dev server: `framework workflows <workflow> run
19
+ --input '<json>'` builds the project, runs the workflow, waits for it
20
+ (`--timeout`) and prints the run as JSON — with the activities, logs and child
21
+ runs under `--trace`. It exits with `0` when the run fulfills, `1` when it is
22
+ rejected or the command fails, and `2` on timeout, so scripts and AI agents can
23
+ test workflows headlessly.
24
+
25
+ `@t4h.framework/dev` exports `HeadlessApp`, the API behind it, and the app
26
+ process resolves its bundle root from `file:` URLs.
27
+
28
+ - [#210](https://github.com/tech4humans-brasil/framework/pull/210) [`990c074`](https://github.com/tech4humans-brasil/framework/commit/990c074af498cb7610d310e295ad613dce7a9b52) Thanks [@tony-tsx](https://github.com/tony-tsx)! - The dev runtime publishes what it runs: jobs queued, started and finished
29
+ (with the queue counts), runs created and settled, activities started, waiting
30
+ and settled (with the error of a rejected one), timeouts and lost workers.
31
+ - `--debug` on `framework dev` and `framework workflows <workflow> run` prints
32
+ those events on stderr; `--debug-log <file>` appends them to a file as NDJSON.
33
+ - Every app process registers itself and listens on a local socket (named pipe
34
+ on Windows). `framework runtime ls` lists them, `framework runtime status`
35
+ prints the queue, the jobs running and waiting and the runs in progress, and
36
+ `framework runtime watch` follows the events live (`--json` for NDJSON),
37
+ reconnecting across `dev` rebuilds.
38
+
39
+ `@t4h.framework/dev` exports `listRuntimes`, `requestRuntimeStatus`,
40
+ `watchRuntime` and `formatRuntimeEvent`, and takes `debugLog` on `Server` and
41
+ `HeadlessApp.up`.
42
+
43
+ ### Patch Changes
44
+
45
+ - Updated dependencies [[`c312bfb`](https://github.com/tech4humans-brasil/framework/commit/c312bfb0f1b1ddbc40d8ac0ede113c5614aa9df8), [`a93218a`](https://github.com/tech4humans-brasil/framework/commit/a93218ae284d91de7d94a65e8f306ace0db2d733), [`92db468`](https://github.com/tech4humans-brasil/framework/commit/92db468f819d3c7d01884526598acd5fbef9b4ef), [`990c074`](https://github.com/tech4humans-brasil/framework/commit/990c074af498cb7610d310e295ad613dce7a9b52)]:
46
+ - @t4h.framework/dev@0.0.0-experimental-20261008135920
47
+
48
+ ## 0.16.17
49
+
50
+ ### Patch Changes
51
+
52
+ - Updated dependencies [[`fc4db5f`](https://github.com/tech4humans-brasil/framework/commit/fc4db5fa01454a45a3727b76dbacc215aa6b3ab7)]:
53
+ - @t4h.framework/dev@0.22.6
54
+
55
+ ## 0.16.16
4
56
 
5
57
  ### Patch Changes
6
58
 
7
59
  - Updated dependencies []:
8
- - @t4h.framework/dev@0.0.0-experimental-20261007204009
60
+ - @t4h.framework/dev@0.22.5
9
61
 
10
62
  ## 0.16.15
11
63
 
package/dist/bin/bin.js CHANGED
@@ -5,12 +5,25 @@ import { buildCommand } from '../commands/build/build.js';
5
5
  import { devCommand } from '../commands/dev/dev.js';
6
6
  import { harnessCommand } from '../commands/harness/harness.js';
7
7
  import { publishCommand } from '../commands/publish/publish.js';
8
+ import { runtimeCommand } from '../commands/runtime/runtime.js';
9
+ import { workflowsCommand } from '../commands/workflows/workflows.js';
10
+ import { ProjectPackageError } from '../tools/project-package.js';
8
11
  program.addCommand(devCommand);
9
12
  program.addCommand(publishCommand);
10
13
  program.addCommand(buildCommand);
11
14
  program.addCommand(AIBootstrapCommand);
12
15
  program.addCommand(harnessCommand);
13
- await program.parseAsync(process.argv);
16
+ program.addCommand(workflowsCommand);
17
+ program.addCommand(runtimeCommand);
18
+ try {
19
+ await program.parseAsync(process.argv);
20
+ }
21
+ catch (error) {
22
+ if (!(error instanceof ProjectPackageError))
23
+ throw error;
24
+ process.stderr.write(`${error.message}\n`);
25
+ process.exit(1);
26
+ }
14
27
  process.on('uncaughtException', error => {
15
28
  const isExitPromptError = error instanceof Error && error.name === 'ExitPromptError';
16
29
  if (isExitPromptError)
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","sourceRoot":"","sources":["../../src/bin/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAA;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAE/D,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAA;AAC9B,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAA;AAClC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAA;AAChC,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAA;AACtC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAA;AAElC,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;AAEtC,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,KAAK,CAAC,EAAE;IACtC,MAAM,iBAAiB,GACrB,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,CAAA;IAE5D,IAAI,iBAAiB;QAAE,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAE7C,MAAM,KAAK,CAAA;AACb,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../../src/bin/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAA;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAA;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AAEjE,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAA;AAC9B,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAA;AAClC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAA;AAChC,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAA;AACtC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAA;AAClC,OAAO,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAA;AACpC,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAA;AAElC,IAAI,CAAC;IACH,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;AACxC,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACf,IAAI,CAAC,CAAC,KAAK,YAAY,mBAAmB,CAAC;QAAE,MAAM,KAAK,CAAA;IAExD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,OAAO,IAAI,CAAC,CAAA;IAC1C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC;AAED,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,KAAK,CAAC,EAAE;IACtC,MAAM,iBAAiB,GACrB,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,CAAA;IAE5D,IAAI,iBAAiB;QAAE,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAE7C,MAAM,KAAK,CAAA;AACb,CAAC,CAAC,CAAA"}
@@ -1,7 +1,8 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
- import { mkdirOutDirProjectFromTsConfigPathAndJsonPackagePath, resolvePackageJsonPath, resolveTsconfigFromPackageJsonPath, tsBuild, upApp, } from '@t4h.framework/dev/build';
4
3
  import { Command, Option } from 'commander';
4
+ import { loadDevBuild, toProjectDir } from '../../tools/load-dev.js';
5
+ import { importProjectPackage } from '../../tools/project-package.js';
5
6
  export const buildCommand = new Command('build')
6
7
  .option('--entrypoint <entrypoint path>', 'The entrypoint package json path', './package.json')
7
8
  .addOption(new Option('-e, --env <envs..>', 'The env secrets')
@@ -18,6 +19,8 @@ export const buildCommand = new Command('build')
18
19
  })
19
20
  .default({}))
20
21
  .action(async (options) => {
22
+ const projectDir = toProjectDir(options.entrypoint);
23
+ const { mkdirOutDirProjectFromTsConfigPathAndJsonPackagePath, resolvePackageJsonPath, resolveTsconfigFromPackageJsonPath, tsBuild, upApp, } = await loadDevBuild(projectDir);
21
24
  const entrypointPackageJsonPath = await resolvePackageJsonPath(options.entrypoint);
22
25
  const entrypointTsConfigPath = await resolveTsconfigFromPackageJsonPath(entrypointPackageJsonPath);
23
26
  const { outDir } = await mkdirOutDirProjectFromTsConfigPathAndJsonPackagePath(entrypointTsConfigPath, entrypointPackageJsonPath);
@@ -29,7 +32,8 @@ export const buildCommand = new Command('build')
29
32
  });
30
33
  if (!compileResult.ok)
31
34
  throw new Error(compileResult.diagnostics.join('\n'));
32
- const { Env } = await import('@t4h.framework/core');
35
+ // The core the app imports, so `Env.run` reaches it.
36
+ const { Env } = await importProjectPackage('@t4h.framework/core', projectDir);
33
37
  await Env.run(options.env, async () => {
34
38
  const { default: packageJson } = await import(entrypointPackageJsonPath, {
35
39
  with: { type: 'json' },
@@ -1 +1 @@
1
- {"version":3,"file":"build.js","sourceRoot":"","sources":["../../../src/commands/build/build.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../../../src/commands/build/build.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,9 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { parseEnv } from 'node:util';
4
- import { Server } from '@t4h.framework/dev';
5
4
  import { Command, Option } from 'commander';
5
+ import { debugLogOption, debugOption, toDebugLog, } from '../../tools/debug-log-option.js';
6
+ import { loadDev, toProjectDir } from '../../tools/load-dev.js';
6
7
  export const devCommand = new Command('dev')
7
8
  .description('Start the development server')
8
9
  .option('--entrypoint <entrypoint path>', 'The entrypoint package json path', './package.json')
@@ -25,14 +26,20 @@ export const devCommand = new Command('dev')
25
26
  .default(3000)
26
27
  .argParser(value => Number.parseInt(value, 10)))
27
28
  .addOption(new Option('--host <host>', 'The HTTP host').default('localhost'))
29
+ .addOption(debugOption())
30
+ .addOption(debugLogOption())
28
31
  .action(async (options) => {
29
32
  if (options.envFileIfExists && fs.existsSync(options.envFileIfExists))
30
33
  Object.assign(options.env, parseEnv(fs.readFileSync(options.envFileIfExists, 'utf8')));
34
+ const { Server } = await loadDev(toProjectDir(options.entrypoint), [
35
+ 'Server',
36
+ ]);
31
37
  const server = new Server({
32
38
  entrypoint: options.entrypoint,
33
39
  env: options.env,
34
40
  port: options.port,
35
41
  host: options.host,
42
+ debugLog: toDebugLog(options),
36
43
  });
37
44
  const shutdown = (code) => {
38
45
  server.down().finally(() => process.exit(code));
@@ -1 +1 @@
1
- {"version":3,"file":"dev.js","sourceRoot":"","sources":["../../../src/commands/dev/dev.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dev.js","sourceRoot":"","sources":["../../../src/commands/dev/dev.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,143 @@
1
+ import path from 'node:path';
2
+ import { setTimeout as sleep } from 'node:timers/promises';
3
+ import { Argument, Command, Option } from 'commander';
4
+ import { loadDev } from '../../tools/load-dev.js';
5
+ const NEXT_RUNTIME_POLL_IN_MS = 500;
6
+ /** Prints the message of an expected failure instead of a stack trace. */
7
+ const failing = (action) => async (...args) => {
8
+ exitWhenStdoutCloses();
9
+ try {
10
+ await action(...args);
11
+ }
12
+ catch (error) {
13
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
14
+ process.exit(1);
15
+ }
16
+ };
17
+ const print = (value) => process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
18
+ const line = (value) => process.stdout.write(`${value}\n`);
19
+ /** `framework runtime watch | head` closes stdout: stop quietly. */
20
+ function exitWhenStdoutCloses() {
21
+ process.stdout.on('error', error => {
22
+ if (error.code === 'EPIPE')
23
+ process.exit(0);
24
+ throw error;
25
+ });
26
+ }
27
+ /**
28
+ * Picks the runtime of `pid`, else the one serving `projectDir`, else the only
29
+ * one running. Throws with the candidates when that is ambiguous.
30
+ */
31
+ export function selectRuntime(runtimes, { pid, projectDir }) {
32
+ if (pid !== undefined) {
33
+ const runtime = runtimes.find(candidate => candidate.pid === pid);
34
+ if (!runtime)
35
+ throw new Error(`No runtime is running with pid ${pid}`);
36
+ return runtime;
37
+ }
38
+ const ofProject = runtimes.filter(candidate => candidate.projectDir === projectDir);
39
+ const candidates = ofProject.length ? ofProject : runtimes;
40
+ if (candidates.length === 0)
41
+ throw new Error('No runtime is running; start one with `framework dev` or `framework workflows <workflow> run`');
42
+ if (candidates.length > 1)
43
+ throw new Error(`${candidates.length} runtimes are running; pass a pid: ${candidates
44
+ .map(({ pid, kind, projectDir }) => `${pid} (${kind}, ${projectDir})`)
45
+ .join(', ')}`);
46
+ return candidates[0];
47
+ }
48
+ export function formatRuntimeStatus({ runtime, queue, runs, }) {
49
+ return [
50
+ `runtime ${runtime.pid} (${runtime.kind}) ${runtime.projectDir ?? runtime.entrypoint}`,
51
+ `workers=${queue.workers} concurrency=${queue.concurrency}`,
52
+ `queue=${queue.queued} (urgent ${queue.urgent})`,
53
+ `running=${queue.inFlight}/${queue.capacity}`,
54
+ `runs running=${runs.running}`,
55
+ ].join(' | ');
56
+ }
57
+ const pidArgument = () => new Argument('[pid]', 'Runtime pid (see `framework runtime ls`)').argParser(value => {
58
+ const pid = Number.parseInt(value, 10);
59
+ if (!Number.isInteger(pid))
60
+ throw new Error('Invalid pid');
61
+ return pid;
62
+ });
63
+ const projectOption = () => new Option('--project <dir>', 'Pick the runtime of this project when no pid is given')
64
+ .default(process.cwd(), 'the current directory')
65
+ .argParser(value => path.resolve(process.cwd(), value));
66
+ const RUNTIME_EXPORTS = [
67
+ 'formatRuntimeEvent',
68
+ 'listRuntimes',
69
+ 'requestRuntimeStatus',
70
+ 'watchRuntime',
71
+ ];
72
+ /** The runtime commands talk to runtimes through the project's dev package. */
73
+ const loadRuntimeDev = (projectDir) => loadDev(projectDir, RUNTIME_EXPORTS);
74
+ async function waitForNextRuntime({ listRuntimes }, previous) {
75
+ while (true) {
76
+ const next = (await listRuntimes()).find(runtime => runtime.pid !== previous.pid &&
77
+ runtime.projectDir === previous.projectDir &&
78
+ runtime.parentPid === previous.parentPid);
79
+ if (next)
80
+ return next;
81
+ await sleep(NEXT_RUNTIME_POLL_IN_MS);
82
+ }
83
+ }
84
+ const lsCommand = new Command('ls')
85
+ .description('List the runtimes running on this machine (JSON)')
86
+ .action(async () => {
87
+ const { listRuntimes } = await loadRuntimeDev(process.cwd());
88
+ print({ runtimes: await listRuntimes() });
89
+ });
90
+ const statusCommand = new Command('status')
91
+ .description('Print the queue, the jobs running and the runs of a runtime (JSON)')
92
+ .addArgument(pidArgument())
93
+ .addOption(projectOption())
94
+ .action(failing(async (pid, options) => {
95
+ const { listRuntimes, requestRuntimeStatus } = await loadRuntimeDev(options.project);
96
+ const runtime = selectRuntime(await listRuntimes(), {
97
+ pid,
98
+ projectDir: options.project,
99
+ });
100
+ print(await requestRuntimeStatus(runtime));
101
+ }));
102
+ const watchCommand = new Command('watch')
103
+ .description('Follow what a runtime runs: jobs, queue size, runs, activities, timeouts')
104
+ .addArgument(pidArgument())
105
+ .addOption(projectOption())
106
+ .option('--json', 'Print NDJSON instead of readable lines', false)
107
+ .option('--no-follow', 'Stop when the runtime exits instead of waiting for the next one (dev rebuilds)')
108
+ .action(failing(async (pid, options) => {
109
+ const dev = await loadRuntimeDev(options.project);
110
+ const { formatRuntimeEvent, listRuntimes, watchRuntime } = dev;
111
+ let runtime = selectRuntime(await listRuntimes(), {
112
+ pid,
113
+ projectDir: options.project,
114
+ });
115
+ const onStatus = (status) => options.json
116
+ ? line(JSON.stringify({ type: 'status', ...status }))
117
+ : line(formatRuntimeStatus(status));
118
+ let watcher = null;
119
+ process.once('SIGINT', () => {
120
+ watcher?.close();
121
+ process.exit(0);
122
+ });
123
+ while (true) {
124
+ watcher = watchRuntime(runtime, {
125
+ onStatus,
126
+ onEvent: event => line(options.json
127
+ ? JSON.stringify({ type: 'event', event })
128
+ : formatRuntimeEvent(event)),
129
+ });
130
+ await watcher.closed.catch(() => { });
131
+ if (!options.follow)
132
+ return;
133
+ if (!options.json)
134
+ line(`runtime ${runtime.pid} exited; waiting for the next one…`);
135
+ runtime = await waitForNextRuntime(dev, runtime);
136
+ }
137
+ }));
138
+ export const runtimeCommand = new Command('runtime')
139
+ .description('Inspect the runtimes started by `framework dev` and `framework workflows`')
140
+ .addCommand(lsCommand)
141
+ .addCommand(statusCommand)
142
+ .addCommand(watchCommand);
143
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../../src/commands/runtime/runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,132 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { parseEnv } from 'node:util';
4
+ import { Argument, Command, Option } from 'commander';
5
+ import { debugLogOption, debugOption, toDebugLog, } from '../../tools/debug-log-option.js';
6
+ import { loadDev, toProjectDir } from '../../tools/load-dev.js';
7
+ /** `DEFAULT_HEADLESS_RUN_TIMEOUT_IN_MS` of the dev package. */
8
+ export const DEFAULT_WORKFLOW_RUN_TIMEOUT_IN_MS = 60_000;
9
+ /** Exit codes of `framework workflows`, for scripts and agents. */
10
+ export const WORKFLOWS_EXIT_CODE = {
11
+ ok: 0,
12
+ rejected: 1,
13
+ error: 1,
14
+ timedOut: 2,
15
+ };
16
+ export function toWorkflowRunExitCode(result) {
17
+ if (result.timedOut)
18
+ return WORKFLOWS_EXIT_CODE.timedOut;
19
+ return result.run.status === 'fulfilled'
20
+ ? WORKFLOWS_EXIT_CODE.ok
21
+ : WORKFLOWS_EXIT_CODE.rejected;
22
+ }
23
+ export function readWorkflowInput({ input, inputFile, }) {
24
+ if (input !== undefined && inputFile !== undefined)
25
+ throw new Error('Pass either --input or --input-file, not both');
26
+ const text = inputFile !== undefined ? fs.readFileSync(inputFile, 'utf8') : input;
27
+ if (text === undefined)
28
+ return undefined;
29
+ try {
30
+ return JSON.parse(text);
31
+ }
32
+ catch (error) {
33
+ throw new Error(`The workflow input is not valid JSON: ${error.message}`, { cause: error });
34
+ }
35
+ }
36
+ /** By name: the error class belongs to the project's dev package. */
37
+ const isHeadlessAppError = (error) => error instanceof Error && error.name === 'HeadlessAppError';
38
+ function toErrorOutput(error) {
39
+ if (isHeadlessAppError(error))
40
+ return {
41
+ error: {
42
+ message: error.message,
43
+ status: error.status ?? null,
44
+ details: error.details ?? null,
45
+ },
46
+ };
47
+ return {
48
+ error: { message: error instanceof Error ? error.message : String(error) },
49
+ };
50
+ }
51
+ const print = (value) => process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
52
+ async function execute({ HeadlessAppError }, app, workflowId, action, options) {
53
+ if (workflowId === undefined) {
54
+ print({ workflows: app.workflows });
55
+ return WORKFLOWS_EXIT_CODE.ok;
56
+ }
57
+ const workflow = app.workflows.find(({ id }) => id === workflowId);
58
+ if (!workflow)
59
+ throw new HeadlessAppError(`Workflow not found: ${workflowId}`, 404, {
60
+ workflows: app.workflows.map(({ id }) => id),
61
+ });
62
+ if (action !== 'run') {
63
+ print({ workflow });
64
+ return WORKFLOWS_EXIT_CODE.ok;
65
+ }
66
+ const result = await app.run(workflowId, readWorkflowInput(options), {
67
+ timeoutInMs: options.timeout,
68
+ trace: options.trace,
69
+ });
70
+ print(result);
71
+ return toWorkflowRunExitCode(result);
72
+ }
73
+ export const workflowsCommand = new Command('workflows')
74
+ .description('List, describe or run the workflows of the app without the dev server; prints JSON')
75
+ .addArgument(new Argument('[workflow]', 'Workflow id; omit it to list the workflows'))
76
+ .addArgument(new Argument('[action]', 'What to do with the workflow')
77
+ .choices(['describe', 'run'])
78
+ .default('describe'))
79
+ .option('--entrypoint <entrypoint path>', 'The entrypoint package json path', './package.json')
80
+ .addOption(new Option('-e, --env <envs..>', 'The env secrets (NAME=value)')
81
+ .argParser((value, previous) => {
82
+ const index = value.indexOf('=');
83
+ if (index < 1)
84
+ throw new Error('Invalid secret format');
85
+ return { ...previous, [value.slice(0, index)]: value.slice(index + 1) };
86
+ })
87
+ .default({}))
88
+ .addOption(new Option('--env-file-if-exists <file-path>', 'Load variables from a .env file if it exists').argParser(value => path.resolve(process.cwd(), value)))
89
+ .option('-i, --input <json>', 'Workflow input as JSON (run)')
90
+ .addOption(new Option('--input-file <file-path>', 'Read the workflow input JSON from a file (run)').argParser(value => path.resolve(process.cwd(), value)))
91
+ .addOption(new Option('-t, --timeout <ms>', 'Stop waiting for the run after this many milliseconds (run)')
92
+ .default(DEFAULT_WORKFLOW_RUN_TIMEOUT_IN_MS)
93
+ .argParser(value => {
94
+ const timeout = Number.parseInt(value, 10);
95
+ if (!Number.isInteger(timeout) || timeout < 0)
96
+ throw new Error('Invalid timeout');
97
+ return timeout;
98
+ }))
99
+ .addOption(debugOption())
100
+ .addOption(debugLogOption())
101
+ .option('--trace', 'Include the activities, logs and child runs in the output (run)', false)
102
+ .action(async (workflowId, action, options) => {
103
+ if (options.envFileIfExists && fs.existsSync(options.envFileIfExists))
104
+ Object.assign(options.env, parseEnv(fs.readFileSync(options.envFileIfExists, 'utf8')));
105
+ let app = null;
106
+ let exitCode = WORKFLOWS_EXIT_CODE.error;
107
+ const shutdown = async (code) => {
108
+ await app?.down().catch(() => { });
109
+ process.exit(code);
110
+ };
111
+ process.once('SIGINT', () => void shutdown(130));
112
+ process.once('SIGTERM', () => void shutdown(143));
113
+ try {
114
+ if (action === 'run')
115
+ readWorkflowInput(options);
116
+ const dev = await loadDev(toProjectDir(options.entrypoint), [
117
+ 'HeadlessApp',
118
+ 'HeadlessAppError',
119
+ ]);
120
+ app = await dev.HeadlessApp.up({
121
+ entrypoint: options.entrypoint,
122
+ env: options.env,
123
+ debugLog: toDebugLog(options),
124
+ });
125
+ exitCode = await execute(dev, app, workflowId, action, options);
126
+ }
127
+ catch (error) {
128
+ print(toErrorOutput(error));
129
+ }
130
+ await shutdown(exitCode);
131
+ });
132
+ //# sourceMappingURL=workflows.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflows.js","sourceRoot":"","sources":["../../../src/commands/workflows/workflows.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import path from 'node:path';
2
+ import { Option } from 'commander';
3
+ /** `DEBUG_LOG_STDERR` of the dev package: the events go to stderr. */
4
+ export const DEBUG_LOG_STDERR = '-';
5
+ export const debugOption = () => new Option('--debug', 'Log what the runtime runs (jobs, runs, activities, queue) to stderr');
6
+ export const debugLogOption = () => new Option('--debug-log <file-path>', 'Append the runtime events to this file as NDJSON instead of stderr').argParser(value => path.resolve(process.cwd(), value));
7
+ /** The `debugLog` the dev package takes, or undefined when debugging is off. */
8
+ export function toDebugLog({ debug, debugLog, }) {
9
+ if (debugLog)
10
+ return debugLog;
11
+ return debug ? DEBUG_LOG_STDERR : undefined;
12
+ }
13
+ //# sourceMappingURL=debug-log-option.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug-log-option.js","sourceRoot":"","sources":["../../src/tools/debug-log-option.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAElC,sEAAsE;AACtE,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,CAAA;AAOnC,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,EAAE,CAC9B,IAAI,MAAM,CACR,SAAS,EACT,qEAAqE,CACtE,CAAA;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,EAAE,CACjC,IAAI,MAAM,CACR,yBAAyB,EACzB,oEAAoE,CACrE,CAAC,SAAS,CAAS,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC,CAAA;AAElE,gFAAgF;AAChF,MAAM,UAAU,UAAU,CAAC,EACzB,KAAK,EACL,QAAQ,GACQ;IAChB,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAA;IAE7B,OAAO,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAA;AAC7C,CAAC"}
@@ -0,0 +1,23 @@
1
+ import path from 'node:path';
2
+ import { DEV_PACKAGE_NAME, importProjectPackage, ProjectPackageError, } from './project-package.js';
3
+ /** The directory of a `--entrypoint` package json path. */
4
+ export const toProjectDir = (entrypoint) => path.dirname(path.resolve(process.cwd(), entrypoint));
5
+ /**
6
+ * Fails with the installed version when the project's dev package is older
7
+ * than the command needs, instead of a `x is not a function` later on.
8
+ */
9
+ function requireExports(module, names) {
10
+ const missing = names.filter(name => module[name] === undefined);
11
+ if (missing.length)
12
+ throw new ProjectPackageError(`${DEV_PACKAGE_NAME}@${module.package.version} (${module.package.dir}) does not provide ${missing.join(', ')}; upgrade it in the project`);
13
+ return module;
14
+ }
15
+ /** The `@t4h.framework/dev` installed in the project, not the CLI's. */
16
+ export async function loadDev(projectDir, required = []) {
17
+ return requireExports(await importProjectPackage(DEV_PACKAGE_NAME, projectDir), required);
18
+ }
19
+ /** `@t4h.framework/dev/build` of the project, see `loadDev`. */
20
+ export async function loadDevBuild(projectDir, required = []) {
21
+ return requireExports(await importProjectPackage(DEV_PACKAGE_NAME, projectDir, './build'), required);
22
+ }
23
+ //# sourceMappingURL=load-dev.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-dev.js","sourceRoot":"","sources":["../../src/tools/load-dev.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAK5B,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,GAEpB,MAAM,sBAAsB,CAAA;AAM7B,2DAA2D;AAC3D,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,UAAkB,EAAE,EAAE,CACjD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC,CAAC,CAAA;AAEvD;;;GAGG;AACH,SAAS,cAAc,CACrB,MAAe,EACf,KAA0C;IAE1C,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,SAAS,CAAC,CAAA;IAEhE,IAAI,OAAO,CAAC,MAAM;QAChB,MAAM,IAAI,mBAAmB,CAC3B,GAAG,gBAAgB,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,KAAK,MAAM,CAAC,OAAO,CAAC,GAAG,sBAAsB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,6BAA6B,CAC1I,CAAA;IAEH,OAAO,MAAM,CAAA;AACf,CAAC;AAED,wEAAwE;AACxE,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,UAAkB,EAClB,WAAmD,EAAE;IAErD,OAAO,cAAc,CACnB,MAAM,oBAAoB,CAAa,gBAAgB,EAAE,UAAU,CAAC,EACpE,QAAQ,CACT,CAAA;AACH,CAAC;AAED,gEAAgE;AAChE,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,UAAkB,EAClB,WAAwD,EAAE;IAE1D,OAAO,cAAc,CACnB,MAAM,oBAAoB,CACxB,gBAAgB,EAChB,UAAU,EACV,SAAS,CACV,EACD,QAAQ,CACT,CAAA;AACH,CAAC"}
@@ -0,0 +1,67 @@
1
+ import fs from 'node:fs';
2
+ import { createRequire } from 'node:module';
3
+ import path from 'node:path';
4
+ import { pathToFileURL } from 'node:url';
5
+ export const DEV_PACKAGE_NAME = '@t4h.framework/dev';
6
+ /** The project lacks a package the command needs; the CLI prints the message only. */
7
+ export class ProjectPackageError extends Error {
8
+ name = 'ProjectPackageError';
9
+ }
10
+ export class ProjectPackageNotFoundError extends ProjectPackageError {
11
+ packageName;
12
+ projectDir;
13
+ name = 'ProjectPackageNotFoundError';
14
+ constructor(packageName, projectDir) {
15
+ super(`${packageName} is not installed in ${projectDir}; add it to the project (e.g. \`yarn add -D ${packageName}\`)`);
16
+ this.packageName = packageName;
17
+ this.projectDir = projectDir;
18
+ }
19
+ }
20
+ /** The file `exports[subpath]` points to for `import`, as Node would pick it. */
21
+ function toImportTarget(exports) {
22
+ if (exports === undefined)
23
+ return null;
24
+ if (typeof exports === 'string')
25
+ return exports;
26
+ for (const condition of ['import', 'node', 'default'])
27
+ if (condition in exports)
28
+ return toImportTarget(exports[condition]);
29
+ return null;
30
+ }
31
+ /** Resolves `subpath` against `main` / `exports` of a package json. */
32
+ function toExportTarget({ main, exports }, subpath) {
33
+ if (exports === undefined)
34
+ return subpath === '.' ? (main ?? 'index.js') : subpath;
35
+ const isSubpathMap = typeof exports === 'object' &&
36
+ Object.keys(exports).some(key => key.startsWith('.'));
37
+ if (!isSubpathMap)
38
+ return subpath === '.' ? toImportTarget(exports) : null;
39
+ return toImportTarget(exports[subpath]);
40
+ }
41
+ /**
42
+ * Finds `packageName` the way the project itself would: in the `node_modules`
43
+ * of `projectDir` and its parents, never next to the CLI. That is what lets the
44
+ * project pin the version the CLI runs.
45
+ */
46
+ export function findProjectPackage(packageName, projectDir) {
47
+ const lookupPaths = createRequire(path.join(projectDir, 'package.json')).resolve.paths(packageName) ?? [];
48
+ for (const lookupPath of lookupPaths) {
49
+ const dir = path.join(lookupPath, packageName);
50
+ const packageJsonPath = path.join(dir, 'package.json');
51
+ if (!fs.existsSync(packageJsonPath))
52
+ continue;
53
+ const { version } = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
54
+ return { name: packageName, version, dir: fs.realpathSync(dir) };
55
+ }
56
+ throw new ProjectPackageNotFoundError(packageName, projectDir);
57
+ }
58
+ /** Imports `packageName[/subpath]` from the project, see `findProjectPackage`. */
59
+ export async function importProjectPackage(packageName, projectDir, subpath = '.') {
60
+ const projectPackage = findProjectPackage(packageName, projectDir);
61
+ const target = toExportTarget(JSON.parse(fs.readFileSync(path.join(projectPackage.dir, 'package.json'), 'utf8')), subpath);
62
+ if (!target)
63
+ throw new ProjectPackageError(`${packageName}@${projectPackage.version} does not export "${subpath}"; upgrade it in ${projectDir}`);
64
+ const module = await import(pathToFileURL(path.join(projectPackage.dir, target)).href);
65
+ return { ...module, package: projectPackage };
66
+ }
67
+ //# sourceMappingURL=project-package.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-package.js","sourceRoot":"","sources":["../../src/tools/project-package.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@t4h.framework/cli",
3
- "version": "0.0.0-experimental-20261007204009",
3
+ "version": "0.0.0-experimental-20261008135920",
4
4
  "description": "CLI tools for the T4H Framework",
5
5
  "homepage": "https://github.com/tech4humans-brasil/framework/tree/main/packages/cli",
6
6
  "bugs": "https://github.com/tech4humans-brasil/framework/issues",
@@ -29,18 +29,27 @@
29
29
  },
30
30
  "dependencies": {
31
31
  "@inquirer/prompts": "^8.3.0",
32
- "@t4h.framework/dev": "^0.0.0-experimental-20261007204009",
33
32
  "@t4h.framework/harness": "^0.3.2",
34
33
  "commander": "^14.0.3",
35
34
  "form-data": "^4.0.5",
36
35
  "tar": "^7.5.10"
37
36
  },
38
37
  "devDependencies": {
38
+ "@t4h.framework/core": "^0.19.0",
39
+ "@t4h.framework/dev": "^0.0.0-experimental-20261008135920",
39
40
  "@types/node": "^25.3.5",
40
41
  "@types/ssh2-sftp-client": "^9.0.6",
41
42
  "typescript": "^5.9.3",
42
43
  "vitest": "^4.0.18"
43
44
  },
45
+ "peerDependencies": {
46
+ "@t4h.framework/dev": "0.0.0-experimental-20261008135920"
47
+ },
48
+ "peerDependenciesMeta": {
49
+ "@t4h.framework/dev": {
50
+ "optional": true
51
+ }
52
+ },
44
53
  "packageManager": "yarn@4.12.0",
45
54
  "engines": {
46
55
  "node": ">=22"