@vitest-agent/cli 3.2.7 → 4.0.1

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/commands/agent.js CHANGED
@@ -1,15 +1,15 @@
1
1
  import { recordCommand } from "./record.js";
2
2
  import { triageCommand } from "./triage.js";
3
3
  import { wrapupCommand } from "./wrapup.js";
4
+ import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
4
5
  import * as NodeServices from "@effect/platform-node/NodeServices";
5
6
  import { SidecarPlatformLive, endAgentEffect, registerAgentEffect, resolveHookPaths, resolveProjectKeyFromCwd } from "@vitest-agent/engine";
6
- import { classifyTestPath, detectNonDefaultDiscoverStrategy, findOwningWorkspace } from "@vitest-agent/sdk";
7
7
  import { Cause, Effect, Option } from "effect";
8
8
  import { Argument, Command, Flag } from "effect/cli";
9
9
  import { existsSync, readFileSync } from "node:fs";
10
- import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
11
10
  import { findWorkspaceRootSync, getWorkspacePackagesSync } from "@effected/workspaces";
12
11
  import { nodeSyncOps } from "@effected/workspaces/node-sync";
12
+ import { classifyTestPath, detectNonDefaultDiscoverStrategy, findOwningWorkspace } from "@vitest-agent/sdk";
13
13
  import { exitCodeForTag, injectEnv } from "@vitest-agent/sdk/dispatch";
14
14
  import { resolveSidecarBinaryPath } from "@vitest-agent/sidecar";
15
15
 
package/commands/db.js CHANGED
@@ -1,9 +1,8 @@
1
1
  import { formatDbQuery } from "../lib/format-db-query.js";
2
- import * as NodeServices from "@effect/platform-node/NodeServices";
2
+ import { Cancelled, CliExit, CliInteractive } from "@effected/cli";
3
3
  import { DataStore, resolveDataPath } from "@vitest-agent/engine";
4
- import { Effect, FileSystem } from "effect";
5
- import { Argument, Command, Flag } from "effect/cli";
6
- import * as readline from "node:readline";
4
+ import { Console, Effect, FileSystem } from "effect";
5
+ import { Argument, Command, Flag, Prompt } from "effect/cli";
7
6
  import { layer } from "@effect/sql-sqlite-node/SqliteClient";
8
7
  import { SqlClient } from "effect/sql/SqlClient";
9
8
 
@@ -21,37 +20,20 @@ const yesOption = Flag.Boolean("yes").pipe(Flag.withDefault(false), Flag.withDes
21
20
  const resetCommand = Command.make("reset", { yes: yesOption }, ({ yes }) => Effect.gen(function* () {
22
21
  const agentId = process.env.VITEST_AGENT_AGENT_ID;
23
22
  if (agentId !== void 0 && agentId.length > 0) {
24
- yield* Effect.sync(() => {
25
- process.stderr.write("db reset is human-only; use db prune or run from a human terminal\n");
26
- process.exit(4);
27
- });
28
- return;
23
+ yield* Console.error("db reset is human-only; use db prune or run from a human terminal");
24
+ return yield* CliExit.set(4);
29
25
  }
30
26
  const dbPath = yield* resolveDataPath(process.env.VITEST_AGENT_PROJECT_DIR ?? process.cwd());
31
- if (!process.stdout.isTTY && !yes) {
32
- yield* Effect.sync(() => {
33
- process.stderr.write("db reset requires --yes when stdout is not a TTY\n");
34
- process.exit(5);
35
- });
36
- return;
27
+ if (!yes && !(yield* CliInteractive)) {
28
+ yield* Console.error("db reset requires --yes when the run is not interactive (stdout or stdin is not a TTY, or the audience is not human)");
29
+ return yield* CliExit.set(5);
37
30
  }
38
- if (process.stdout.isTTY && !yes) {
39
- if (!(yield* Effect.promise(() => {
40
- return new Promise((resolve) => {
41
- const rl = readline.createInterface({
42
- input: process.stdin,
43
- output: process.stdout
44
- });
45
- rl.question(`Wipe ${dbPath}? [y/N]: `, (answer) => {
46
- rl.close();
47
- resolve(answer === "y" || answer === "Y");
48
- });
49
- });
50
- }))) {
51
- yield* Effect.sync(() => {
52
- process.stdout.write("aborted\n");
53
- process.exit(0);
54
- });
31
+ if (!yes) {
32
+ if (!(yield* Prompt.run(Prompt.Confirm({
33
+ message: `Wipe ${dbPath}?`,
34
+ initial: false
35
+ })).pipe(Effect.catchTag("QuitError", () => Effect.fail(Cancelled.make({ reason: "interrupt" })))))) {
36
+ yield* Console.log("aborted");
55
37
  return;
56
38
  }
57
39
  }
@@ -59,10 +41,8 @@ const resetCommand = Command.make("reset", { yes: yesOption }, ({ yes }) => Effe
59
41
  yield* fs.remove(dbPath).pipe(Effect.catch(() => Effect.void));
60
42
  yield* fs.remove(`${dbPath}-shm`).pipe(Effect.catch(() => Effect.void));
61
43
  yield* fs.remove(`${dbPath}-wal`).pipe(Effect.catch(() => Effect.void));
62
- yield* Effect.sync(() => {
63
- process.stdout.write(`Deleted database at ${dbPath}\n`);
64
- });
65
- }).pipe(Effect.provide(NodeServices.layer))).pipe(Command.withDescription("Wipe the database (human-only; blocked in agent contexts)"));
44
+ yield* Console.log(`Deleted database at ${dbPath}`);
45
+ })).pipe(Command.withDescription("Wipe the database (human-only; blocked in agent contexts)"));
66
46
  const queryFormatOption = Flag.Literals("format", ["table", "json"]).pipe(Flag.withDefault("table"), Flag.withDescription("Output format for query results"));
67
47
  const sqlArg = Argument.String("sql").pipe(Argument.withDescription("Read-only SQL statement to execute against data.db"));
68
48
  /**
@@ -0,0 +1,59 @@
1
+ import { Cancelled, Fmt, NotInteractive } from "@effected/cli";
2
+ import { Schema } from "effect";
3
+
4
+ //#region src/lib/render-failure.ts
5
+ /**
6
+ * The one-line name of a typed failure: its `_tag` when it carries one (a
7
+ * `PlatformError`, `SqlError`, `MigrationError`), else its `Error` name.
8
+ */
9
+ const failureName = (error) => {
10
+ if (typeof error === "object" && error !== null && "_tag" in error && typeof error._tag === "string") return error._tag;
11
+ return error instanceof Error ? error.name : "Error";
12
+ };
13
+ /** Where a defect's report sends the reader: a defect is a bug in this program. */
14
+ const ISSUE_URL = "https://github.com/spencerbeggs/vitest-agent/issues";
15
+ /**
16
+ * Failures the kit renders better than one `<Tag>: <message>` line: its own
17
+ * `Cancelled` / `NotInteractive` fixed lines, and a `SchemaError` as a tree of
18
+ * the rejected values.
19
+ */
20
+ const isKitRendered = (error) => error instanceof Cancelled || error instanceof NotInteractive || Schema.isSchemaError(error);
21
+ /** One line of text we did not write, made safe to print: controls stripped, line breaks folded to spaces. */
22
+ const oneLine = (text) => Fmt.sanitize(text).replace(/\s*[\r\n]+\s*/g, " ").trim();
23
+ /**
24
+ * One rendering for every failure `CliRuntime.main` reports, its first line
25
+ * led by `vitest-agent: `. The kit says which kind it is
26
+ * (`details.isDefect`, exact: the cause carries no typed failure).
27
+ *
28
+ * - A typed failure from the error channel (a `PlatformError`, `SqlError`,
29
+ * `MigrationError`) is the one line we own: `vitest-agent: <Tag>: <message>`,
30
+ * the message passed through `Fmt.sanitize` (it can carry a path or SQL text).
31
+ * - Everything else is delegated to `details.lines({ status: false })`, the
32
+ * kit's report for this run (its colour, links, and `displayPath`) with the
33
+ * status glyph / `[FAIL]` tag left off, so our prefix replaces the marker
34
+ * rather than doubling it: `Cancelled` / `NotInteractive` keep their fixed
35
+ * line (`vitest-agent: cancelled; nothing written`), a `SchemaError` is a
36
+ * tree, and a defect is its message plus a `stack` of the program's own
37
+ * frames (`node_modules`, Node, and Effect frames hidden and counted), then
38
+ * the issue link.
39
+ *
40
+ * `ShowHelp` and runWith-rendered `UserError`s never reach here (the kit skips
41
+ * them).
42
+ *
43
+ * @internal
44
+ */
45
+ const renderFailure = (error, details) => {
46
+ if (!details.isDefect && !isKitRendered(error)) {
47
+ const message = oneLine(error instanceof Error ? error.message : typeof error === "string" ? error : "");
48
+ return [`vitest-agent: ${oneLine(failureName(error))}${message ? `: ${message}` : ""}`];
49
+ }
50
+ const [first = failureName(error), ...rest] = details.lines({ status: false });
51
+ return [
52
+ `vitest-agent: ${first}`,
53
+ ...rest,
54
+ ...details.isDefect ? [`Please report at ${ISSUE_URL}`] : []
55
+ ];
56
+ };
57
+
58
+ //#endregion
59
+ export { renderFailure };
@@ -1,23 +1,28 @@
1
- import { CliColor } from "@effected/cli";
2
- import { CurrentDistribution, distributionSuffix } from "@effected/engine";
3
- import { Effect, Layer } from "effect";
1
+ import { distributionSuffix } from "@effected/engine";
4
2
 
5
3
  //#region src/lib/version-formatter.ts
6
4
  /**
7
- * The program's one `CliOutput.Formatter` layer: `CliColor.formatterLayer`
8
- * (the kit's single colour decision — stdout is a TTY and `NO_COLOR` is
9
- * unset or empty) with only `formatVersion` overridden, so `--version`
5
+ * The `CliOutput.Formatter` methods `main.ts` replaces through
6
+ * `CliRuntime.main`'s `env.formatter`: only `formatVersion`, so `--version`
10
7
  * prints `vitest-agent <cli version>` plus ` via <name> <version>` when a
11
- * carrier (`@vitest-agent/plugin`'s bin shim) threaded its identity down.
12
- * Help and parse-error rendering stay `CliColor`'s own.
8
+ * carrier (`@vitest-agent/plugin`'s bin shim) passed its identity to `main`.
13
9
  *
14
- * `Layer.unwrap` reads `CurrentDistribution` once, at layer build time, from
15
- * the ambient context `main.ts` provides — so `main.ts` must provide
16
- * `CurrentDistribution` OUTSIDE the layer, not inside it.
10
+ * `env.formatter` is the kit's one way to keep a formatter method of our own:
11
+ * `main` installs its coloured default formatter inside the platform, which
12
+ * shadows any formatter the platform sets. Every method left out keeps the
13
+ * kit's coloured default, and `helpOnUsageError: "stderr"` still wraps the
14
+ * result, so usage-error help keeps going to stderr.
15
+ *
16
+ * `distribution` is the same value `main.ts` provides as `CurrentDistribution`;
17
+ * it is known when `main` is called, so it is read here directly rather than
18
+ * from the context when `--version` runs.
17
19
  *
18
20
  * @internal
19
21
  */
20
- const versionFormatterLayer = Layer.unwrap(Effect.map(CurrentDistribution, (distribution) => CliColor.formatterLayer({ formatVersion: (name, version) => `${name} ${version}${distributionSuffix(distribution)}` })));
22
+ const carrierVersionFormatter = (distribution) => {
23
+ const suffix = distributionSuffix(distribution);
24
+ return { formatVersion: (name, version) => `${name} ${version}${suffix}` };
25
+ };
21
26
 
22
27
  //#endregion
23
- export { versionFormatterLayer };
28
+ export { carrierVersionFormatter };
package/main.d.ts CHANGED
@@ -18,28 +18,48 @@ export interface MainOptions {
18
18
  * re-exported from `index.ts` — a library consumer's import graph must not
19
19
  * pull in the process-owning module.
20
20
  *
21
+ * The one `@effected/cli` wiring: the root carries `CliAudience.flags()`
22
+ * (`--audience <human|agent|ci>`, `--human`, `--agent`, `--ci`), runs through
23
+ * `CliAudience.run`, and `CliRuntime.main`'s `env` option builds the
24
+ * `@effected/env` services (`Audience` with the `VITEST_AGENT_AUDIENCE`
25
+ * override, `TerminalEnv`, `CliTheme`, `CliInteractive`, the gated `Terminal`)
26
+ * plus the kit's colour-decided help formatter, inside failure reporting.
27
+ * `env.formatter` replaces only that formatter's `formatVersion`, so
28
+ * `--version` names the carrier (`via @vitest-agent/plugin <version>`) when
29
+ * `options.distribution` is given; the same value is provided as
30
+ * `CurrentDistribution`. An audience flag recomputes `CliInteractive` from the
31
+ * TTY facts, so `--human` in an agent-detected shell (Claude Code's terminal)
32
+ * at a real terminal may prompt.
33
+ *
21
34
  * Output routing (hooks parse `agent *` stdout with jq, so stdout carries
22
35
  * only what a command writes as its result):
23
36
  *
24
- * - Inside the platform, the engine's `LoggerLive` (installed by
25
- * `PlatformLive`) is the active logger: silent unless
26
- * `VITEST_REPORTER_LOG_LEVEL` is set, then NDJSON on stderr (plus
27
- * `VITEST_REPORTER_LOG_FILE`). Every `Effect.log*` a command or engine
28
- * service emits goes there.
29
- * - Outside the platform, `CliRuntime.main`'s default `CliLogger` is
30
- * outermost and sends every level to stderr. It is what renders reported
31
- * failures (a layer-build failure, a typed command failure, a defect)
32
- * through `renderFailure`.
37
+ * - `env.log` makes `CliLog.layer` the one logger set, outermost: a
38
+ * `CliLogger` for ordinary lines and failure reports, plus a diagnostics
39
+ * sink that is silent unless `VITEST_REPORTER_LOG_LEVEL` is set (then
40
+ * NDJSON on stderr for every audience), plus an
41
+ * async NDJSON file when `VITEST_REPORTER_LOG_FILE` is set. The platform
42
+ * therefore installs no logger of its own (`PlatformLive`'s `logger: false`:
43
+ * the engine's `LoggerLive` would otherwise replace this set inside the
44
+ * program). The platform is built under that logger, so what it logs
45
+ * while building (the engine's migration records) reaches the same sink.
46
+ * `format: "auto"`: NDJSON for an agent or a CI, plain lines for a person.
47
+ * `argv` (`process.argv.slice(2)`) lets the build-time records follow the
48
+ * audience flags too, so `--agent` with no agent detected is all NDJSON and
49
+ * `--human` in an agent shell is all plain, migration records included.
50
+ * - Failures render through `renderFailure` on stderr, first line led by
51
+ * `vitest-agent: `. `env.displayPath` shows a defect's stack frames
52
+ * relative to the project directory (absolute when outside it).
33
53
  * - An explicit `--help` (or a bare group invocation) prints help on
34
- * stdout. A usage error (unknown flag, bad value, unknown subcommand)
35
- * prints help AND the parse errors on stderr (`helpOnUsageError: "stderr"`),
36
- * so stdout stays empty for a jq-piping hook. Both render via
37
- * the `CliOutput` formatter (`versionFormatterLayer`), which must come
38
- * through `platform` for the kit to reroute it.
54
+ * stdout. A usage error (unknown flag, bad value, unknown subcommand,
55
+ * conflicting audience flags) prints help AND the parse errors on stderr
56
+ * (`helpOnUsageError: "stderr"`), so stdout stays empty for a jq-piping
57
+ * hook.
39
58
  *
40
59
  * Exit codes are the kit's: `0` success (including bare `--help`), `64` a
41
- * usage error (parse error, unknown subcommand), `1` any other reported
42
- * failure. Commands that `process.exit` with their own code still do so.
60
+ * usage error, `130` a cancelled prompt, `1` any other reported failure.
61
+ * Commands that record their own code through `CliExit` (`db reset`) or
62
+ * `process.exit` with it still exit with it.
43
63
  *
44
64
  * @public
45
65
  */
package/main.js CHANGED
@@ -2,13 +2,14 @@ import { CURRENT_CLI_VERSION } from "./version.js";
2
2
  import { agentCommand } from "./commands/agent.js";
3
3
  import { dbCommand } from "./commands/db.js";
4
4
  import { doctorCommand } from "./commands/doctor.js";
5
- import { versionFormatterLayer } from "./lib/version-formatter.js";
5
+ import { renderFailure } from "./lib/render-failure.js";
6
+ import { carrierVersionFormatter } from "./lib/version-formatter.js";
7
+ import { isAbsolute, relative } from "node:path";
6
8
  import * as NodeRuntime from "@effect/platform-node/NodeRuntime";
7
9
  import * as NodeServices from "@effect/platform-node/NodeServices";
8
- import { CliRuntime } from "@effected/cli";
10
+ import { CliAudience, CliRuntime } from "@effected/cli";
9
11
  import { CurrentDistribution } from "@effected/engine";
10
- import { PathResolutionLive, PlatformLive, resolveDataPath, resolveLogFile, resolveLogLevel, resolveProjectDir } from "@vitest-agent/engine";
11
- import { formatFatalError } from "@vitest-agent/sdk";
12
+ import { PathResolutionLive, PlatformLive, resolveDataPath, resolveProjectDir } from "@vitest-agent/engine";
12
13
  import { Effect, Layer, Option } from "effect";
13
14
  import { Command } from "effect/cli";
14
15
 
@@ -25,81 +26,102 @@ import { Command } from "effect/cli";
25
26
  *
26
27
  * @packageDocumentation
27
28
  */
28
- const rootCommand = Command.make("vitest-agent").pipe(Command.withSubcommands([
29
+ /**
30
+ * The environment variable that overrides the detected audience
31
+ * (`human` | `agent` | `ci`), read by `@effected/env`'s `Audience` through
32
+ * `Config`. The `VITEST_AGENT_` prefix is the family's runtime-override
33
+ * namespace (`VITEST_AGENT_CONSOLE`, `VITEST_AGENT_PROJECT_DIR`,
34
+ * `VITEST_AGENT_CLI_CMD`); the `VITEST_REPORTER_` prefix survives only on the
35
+ * two legacy logging variables.
36
+ */
37
+ const AUDIENCE_ENV_VAR = "VITEST_AGENT_AUDIENCE";
38
+ const rootCommand = Command.make("vitest-agent").pipe(Command.withSharedFlags(CliAudience.flags()), Command.withSubcommands([
29
39
  dbCommand,
30
40
  doctorCommand,
31
41
  agentCommand
32
42
  ]));
33
43
  /**
34
- * The one-line name of a typed failure: its `_tag` when it carries one (a
35
- * `PlatformError`, `SqlError`, `MigrationError`), else its `Error` name.
36
- */
37
- const failureName = (error) => {
38
- if (typeof error === "object" && error !== null && "_tag" in error && typeof error._tag === "string") return error._tag;
39
- return error instanceof Error ? error.name : "Error";
40
- };
41
- /**
42
- * One rendering for every failure `CliRuntime.main` reports. The kit says
43
- * which kind it is (`details.isDefect`, exact: the cause carries no typed
44
- * failure): a typed failure from the error channel is one line, a defect
45
- * keeps the issue-report rendering `formatFatalError` gives it. `ShowHelp`
46
- * and runWith-rendered `UserError`s never reach here (the kit skips them).
47
- */
48
- const renderFailure = (error, details) => {
49
- if (details.isDefect) return `vitest-agent: ${formatFatalError(error)}`;
50
- const message = error instanceof Error ? error.message : typeof error === "string" ? error : "";
51
- return `vitest-agent: ${failureName(error)}${message ? `: ${message}` : ""}`;
52
- };
53
- /**
54
44
  * Assembles and runs the CLI program, taking over the process. Not
55
45
  * re-exported from `index.ts` — a library consumer's import graph must not
56
46
  * pull in the process-owning module.
57
47
  *
48
+ * The one `@effected/cli` wiring: the root carries `CliAudience.flags()`
49
+ * (`--audience <human|agent|ci>`, `--human`, `--agent`, `--ci`), runs through
50
+ * `CliAudience.run`, and `CliRuntime.main`'s `env` option builds the
51
+ * `@effected/env` services (`Audience` with the `VITEST_AGENT_AUDIENCE`
52
+ * override, `TerminalEnv`, `CliTheme`, `CliInteractive`, the gated `Terminal`)
53
+ * plus the kit's colour-decided help formatter, inside failure reporting.
54
+ * `env.formatter` replaces only that formatter's `formatVersion`, so
55
+ * `--version` names the carrier (`via @vitest-agent/plugin <version>`) when
56
+ * `options.distribution` is given; the same value is provided as
57
+ * `CurrentDistribution`. An audience flag recomputes `CliInteractive` from the
58
+ * TTY facts, so `--human` in an agent-detected shell (Claude Code's terminal)
59
+ * at a real terminal may prompt.
60
+ *
58
61
  * Output routing (hooks parse `agent *` stdout with jq, so stdout carries
59
62
  * only what a command writes as its result):
60
63
  *
61
- * - Inside the platform, the engine's `LoggerLive` (installed by
62
- * `PlatformLive`) is the active logger: silent unless
63
- * `VITEST_REPORTER_LOG_LEVEL` is set, then NDJSON on stderr (plus
64
- * `VITEST_REPORTER_LOG_FILE`). Every `Effect.log*` a command or engine
65
- * service emits goes there.
66
- * - Outside the platform, `CliRuntime.main`'s default `CliLogger` is
67
- * outermost and sends every level to stderr. It is what renders reported
68
- * failures (a layer-build failure, a typed command failure, a defect)
69
- * through `renderFailure`.
64
+ * - `env.log` makes `CliLog.layer` the one logger set, outermost: a
65
+ * `CliLogger` for ordinary lines and failure reports, plus a diagnostics
66
+ * sink that is silent unless `VITEST_REPORTER_LOG_LEVEL` is set (then
67
+ * NDJSON on stderr for every audience), plus an
68
+ * async NDJSON file when `VITEST_REPORTER_LOG_FILE` is set. The platform
69
+ * therefore installs no logger of its own (`PlatformLive`'s `logger: false`:
70
+ * the engine's `LoggerLive` would otherwise replace this set inside the
71
+ * program). The platform is built under that logger, so what it logs
72
+ * while building (the engine's migration records) reaches the same sink.
73
+ * `format: "auto"`: NDJSON for an agent or a CI, plain lines for a person.
74
+ * `argv` (`process.argv.slice(2)`) lets the build-time records follow the
75
+ * audience flags too, so `--agent` with no agent detected is all NDJSON and
76
+ * `--human` in an agent shell is all plain, migration records included.
77
+ * - Failures render through `renderFailure` on stderr, first line led by
78
+ * `vitest-agent: `. `env.displayPath` shows a defect's stack frames
79
+ * relative to the project directory (absolute when outside it).
70
80
  * - An explicit `--help` (or a bare group invocation) prints help on
71
- * stdout. A usage error (unknown flag, bad value, unknown subcommand)
72
- * prints help AND the parse errors on stderr (`helpOnUsageError: "stderr"`),
73
- * so stdout stays empty for a jq-piping hook. Both render via
74
- * the `CliOutput` formatter (`versionFormatterLayer`), which must come
75
- * through `platform` for the kit to reroute it.
81
+ * stdout. A usage error (unknown flag, bad value, unknown subcommand,
82
+ * conflicting audience flags) prints help AND the parse errors on stderr
83
+ * (`helpOnUsageError: "stderr"`), so stdout stays empty for a jq-piping
84
+ * hook.
76
85
  *
77
86
  * Exit codes are the kit's: `0` success (including bare `--help`), `64` a
78
- * usage error (parse error, unknown subcommand), `1` any other reported
79
- * failure. Commands that `process.exit` with their own code still do so.
87
+ * usage error, `130` a cancelled prompt, `1` any other reported failure.
88
+ * Commands that record their own code through `CliExit` (`db reset`) or
89
+ * `process.exit` with it still exit with it.
80
90
  *
81
91
  * @public
82
92
  */
83
93
  const main = (options = {}) => {
84
94
  const env = process.env;
85
- const logLevel = resolveLogLevel(env);
86
- const logFile = resolveLogFile(env);
87
95
  const projectDir = resolveProjectDir({
88
96
  env,
89
97
  cwd: process.cwd()
90
98
  });
91
- const dataLayer = Layer.unwrap(Effect.map(resolveDataPath(projectDir), (dbPath) => PlatformLive({
99
+ const platform = Layer.unwrap(Effect.map(resolveDataPath(projectDir), (dbPath) => PlatformLive({
92
100
  dbPath,
93
101
  env,
94
- logLevel,
95
- logFile
96
- })));
97
- const platform = Layer.mergeAll(dataLayer, versionFormatterLayer).pipe(Layer.provideMerge(PathResolutionLive(projectDir)), Layer.provideMerge(NodeServices.layer));
98
- const program = CliRuntime.main(Command.run(rootCommand, { version: CURRENT_CLI_VERSION }), {
102
+ logger: false
103
+ }))).pipe(Layer.provideMerge(PathResolutionLive(projectDir)), Layer.provideMerge(NodeServices.layer));
104
+ const distribution = Option.fromNullishOr(options.distribution);
105
+ const displayPath = (absolute) => {
106
+ const rel = relative(projectDir, absolute);
107
+ return rel === "" || rel.startsWith("..") || isAbsolute(rel) ? absolute : rel;
108
+ };
109
+ const program = CliRuntime.main(CliAudience.run(rootCommand, { version: CURRENT_CLI_VERSION }), {
99
110
  platform,
100
111
  render: renderFailure,
101
- helpOnUsageError: "stderr"
102
- }).pipe(Effect.provideService(CurrentDistribution, Option.fromNullishOr(options.distribution)));
112
+ helpOnUsageError: "stderr",
113
+ env: {
114
+ audienceEnvVar: AUDIENCE_ENV_VAR,
115
+ formatter: carrierVersionFormatter(distribution),
116
+ displayPath,
117
+ log: {
118
+ envVar: "VITEST_REPORTER_LOG_LEVEL",
119
+ format: "auto",
120
+ argv: process.argv.slice(2),
121
+ file: { envVar: "VITEST_REPORTER_LOG_FILE" }
122
+ }
123
+ }
124
+ }).pipe(Effect.provideService(CurrentDistribution, distribution));
103
125
  NodeRuntime.runMain(program);
104
126
  };
105
127
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitest-agent/cli",
3
- "version": "3.2.7",
3
+ "version": "4.0.1",
4
4
  "private": false,
5
5
  "description": "On-demand CLI for vitest-agent. Reads cached test data and reports status, overview, coverage, history, trends, and cache health.",
6
6
  "keywords": [
@@ -43,17 +43,19 @@
43
43
  "vitest-agent": "bin/vitest-agent.js"
44
44
  },
45
45
  "dependencies": {
46
- "@effect/platform-node": "4.0.0-rc.118",
47
- "@effect/sql-sqlite-node": "4.0.0-rc.118",
48
- "@effected/cli": "^0.10.0",
49
- "@effected/config-file": "^0.13.1",
50
- "@effected/engine": "^0.2.0",
51
- "@effected/walker": "^0.14.0",
52
- "@effected/workspaces": "^0.30.3",
53
- "@vitest-agent/engine": "0.3.2",
54
- "@vitest-agent/sdk": "5.1.3",
55
- "@vitest-agent/sidecar": "2.2.3",
56
- "effect": "4.0.0-rc.118"
46
+ "@effect/platform-node": "^4.0.0",
47
+ "@effect/sql-sqlite-node": "^4.0.0",
48
+ "@effected/cli": "^0.11.0",
49
+ "@effected/config-file": "^0.14.0",
50
+ "@effected/engine": "^0.3.0",
51
+ "@effected/env": "^0.1.0",
52
+ "@effected/glob": "^0.10.0",
53
+ "@effected/walker": "^0.15.0",
54
+ "@effected/workspaces": "^0.31.0",
55
+ "@vitest-agent/engine": "0.5.0",
56
+ "@vitest-agent/sdk": "6.0.0",
57
+ "@vitest-agent/sidecar": "2.2.5",
58
+ "effect": "^4.0.0"
57
59
  },
58
60
  "engines": {
59
61
  "node": ">=24.11.0"
package/version.js CHANGED
@@ -7,7 +7,7 @@
7
7
  *
8
8
  * @public
9
9
  */
10
- const CURRENT_CLI_VERSION = "3.2.7";
10
+ const CURRENT_CLI_VERSION = "4.0.1";
11
11
 
12
12
  //#endregion
13
13
  export { CURRENT_CLI_VERSION };