@vitest-agent/cli 3.1.6 → 3.2.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
@@ -14,34 +14,6 @@ import { exitCodeForTag, injectEnv } from "@vitest-agent/sdk/dispatch";
14
14
  import { resolveSidecarBinaryPath } from "@vitest-agent/sidecar";
15
15
 
16
16
  //#region src/commands/agent.ts
17
- /**
18
- * `agent` subcommand namespace.
19
- *
20
- * Commands intended for agents and hook scripts — humans typically do
21
- * not invoke these directly. The group composes the hook-driven
22
- * utilities (triage, wrapup, record) with the sidecar invocations
23
- * called by plugins/claude-code/hooks/*.sh scripts (register-agent, end-agent,
24
- * inject-env).
25
- *
26
- * The sidecar subcommands return plain text on stdout that the bash
27
- * hooks parse, and structured error info on stderr in the shape
28
- * `<exit_code> <error_tag>: <message>`.
29
- *
30
- * Exit codes follow the contract documented in the agent-agnostic
31
- * taxonomy plan:
32
- * 0 = success
33
- * 1 = registration conflict
34
- * 2 = sidecar timeout
35
- * 3 = database error
36
- * 4 = project identity not resolvable
37
- * 5 = other unexpected defect
38
- *
39
- * `check-test-path` is not part of that family and does not share the
40
- * taxonomy: it exits 1, with nothing on stdout, to mean "no verdict was
41
- * rendered — fail open."
42
- *
43
- * @packageDocumentation
44
- */
45
17
  const writeStdout = (line) => Effect.sync(() => {
46
18
  process.stdout.write(`${line}\n`);
47
19
  });
package/commands/db.js CHANGED
@@ -8,11 +8,6 @@ import { layer } from "@effect/sql-sqlite-node/SqliteClient";
8
8
  import { SqlClient } from "effect/unstable/sql/SqlClient";
9
9
 
10
10
  //#region src/commands/db.ts
11
- /**
12
- * CLI db command -- manage the vitest-agent database.
13
- *
14
- * @packageDocumentation
15
- */
16
11
  const pathCommand = Command.make("path", {}, () => Effect.gen(function* () {
17
12
  const dbPath = yield* resolveDataPath(process.env.VITEST_AGENT_PROJECT_DIR ?? process.cwd());
18
13
  yield* Effect.sync(() => process.stdout.write(`${dbPath}\n`));
@@ -4,11 +4,6 @@ import { Effect, Option } from "effect";
4
4
  import { Command, Flag } from "effect/unstable/cli";
5
5
 
6
6
  //#region src/commands/doctor.ts
7
- /**
8
- * CLI doctor command -- diagnose database health.
9
- *
10
- * @packageDocumentation
11
- */
12
7
  const formatOption = Flag.withDefault(Flag.Literals("format", ["markdown", "json"]), "markdown");
13
8
  const writeOutput = (results, format) => Effect.sync(() => {
14
9
  if (format === "json") process.stdout.write(`${JSON.stringify(results, null, 2)}\n`);
@@ -3,15 +3,6 @@ import { Effect } from "effect";
3
3
  import { Command, Flag } from "effect/unstable/cli";
4
4
 
5
5
  //#region src/commands/triage.ts
6
- /**
7
- * CLI triage command -- emits the W3 orientation triage brief.
8
- *
9
- * Calls the shared formatTriageEffect generator, which the MCP
10
- * triage_brief tool also uses. The plugin's SessionStart hook runs
11
- * this and pipes the result into Claude Code's additionalContext.
12
- *
13
- * @packageDocumentation
14
- */
15
6
  const formatOption = Flag.withDefault(Flag.Literals("format", [
16
7
  "markdown",
17
8
  "json",
@@ -3,16 +3,6 @@ import { Effect } from "effect";
3
3
  import { Command, Flag } from "effect/unstable/cli";
4
4
 
5
5
  //#region src/commands/wrapup.ts
6
- /**
7
- * CLI wrapup command -- emits the W5 wrap-up prompt for a session.
8
- *
9
- * Drives the four interpretive hooks (Stop / SessionEnd / PreCompact /
10
- * UserPromptSubmit). Hooks invoke the bin with --kind set; humans on
11
- * the terminal can also run it on demand with --chat-id (host chat UUID)
12
- * or --row-id (internal integer FK, mostly for debugging).
13
- *
14
- * @packageDocumentation
15
- */
16
6
  const rowIdOption = Flag.optional(Flag.Int("row-id"));
17
7
  const chatIdOption = Flag.optional(Flag.String("chat-id"));
18
8
  const kindOption = Flag.withDefault(Flag.Literals("kind", [
@@ -0,0 +1,23 @@
1
+ import { CliColor } from "@effected/cli";
2
+ import { CurrentDistribution, distributionSuffix } from "@effected/engine";
3
+ import { Effect, Layer } from "effect";
4
+
5
+ //#region src/lib/version-formatter.ts
6
+ /**
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`
10
+ * 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.
13
+ *
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.
17
+ *
18
+ * @internal
19
+ */
20
+ const versionFormatterLayer = Layer.unwrap(Effect.map(CurrentDistribution, (distribution) => CliColor.formatterLayer({ formatVersion: (name, version) => `${name} ${version}${distributionSuffix(distribution)}` })));
21
+
22
+ //#endregion
23
+ export { versionFormatterLayer };
package/main.d.ts CHANGED
@@ -1,22 +1,48 @@
1
+ import { Distribution } from "@effected/engine";
1
2
  //#region src/main.d.ts
2
3
  /**
3
- * Assembled CLI program. Owns the process: resolves the data path, wires the
4
- * engine's platform layers, and runs the root command via
5
- * `NodeRuntime.runMain`.
4
+ * Options the carrier's bin shim passes to {@link main}.
6
5
  *
7
- * `bin.ts` is the published bin shim (`#!/usr/bin/env node` +
8
- * `main()`); this module is also published as the `./main` subpath so a
9
- * consumer can invoke the assembled program without going through the shim.
10
- *
11
- * @packageDocumentation
6
+ * @public
12
7
  */
8
+ export interface MainOptions {
9
+ /**
10
+ * The meta-package the bin was launched through (for example
11
+ * `@vitest-agent/plugin`), appended to `--version` as
12
+ * ` via <name> <version>`. Omitted for a direct install of this package.
13
+ */
14
+ readonly distribution?: Distribution | undefined;
15
+ }
13
16
  /**
14
17
  * Assembles and runs the CLI program, taking over the process. Not
15
18
  * re-exported from `index.ts` — a library consumer's import graph must not
16
19
  * pull in the process-owning module.
17
20
  *
21
+ * Output routing (hooks parse `agent *` stdout with jq, so stdout carries
22
+ * only what a command writes as its result):
23
+ *
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`.
33
+ * - 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.
39
+ *
40
+ * 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.
43
+ *
18
44
  * @public
19
45
  */
20
- export declare const main: () => void;
46
+ export declare const main: (options?: MainOptions) => void;
21
47
  //#endregion
22
48
  //# sourceMappingURL=main.d.ts.map
package/main.js CHANGED
@@ -2,22 +2,26 @@ 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
6
  import * as NodeRuntime from "@effect/platform-node/NodeRuntime";
6
7
  import * as NodeServices from "@effect/platform-node/NodeServices";
8
+ import { CliRuntime } from "@effected/cli";
9
+ import { CurrentDistribution } from "@effected/engine";
7
10
  import { PathResolutionLive, PlatformLive, resolveDataPath, resolveLogFile, resolveLogLevel, resolveProjectDir } from "@vitest-agent/engine";
8
11
  import { formatFatalError } from "@vitest-agent/sdk";
9
- import { Cause, Console, Effect } from "effect";
12
+ import { Effect, Layer, Option } from "effect";
10
13
  import { Command } from "effect/unstable/cli";
11
14
 
12
15
  //#region src/main.ts
13
16
  /**
14
17
  * Assembled CLI program. Owns the process: resolves the data path, wires the
15
- * engine's platform layers, and runs the root command via
16
- * `NodeRuntime.runMain`.
18
+ * engine's platform layers, and runs the root command through
19
+ * `@effected/cli`'s `CliRuntime.main` under `NodeRuntime.runMain`.
17
20
  *
18
21
  * `bin.ts` is the published bin shim (`#!/usr/bin/env node` +
19
- * `main()`); this module is also published as the `./main` subpath so a
20
- * consumer can invoke the assembled program without going through the shim.
22
+ * `main()`); this module is also published as the `./main` subpath so the
23
+ * carrier (`@vitest-agent/plugin`) can ship the same program behind its own
24
+ * bin, threading its identity in through {@link MainOptions.distribution}.
21
25
  *
22
26
  * @packageDocumentation
23
27
  */
@@ -27,13 +31,56 @@ const rootCommand = Command.make("vitest-agent").pipe(Command.withSubcommands([
27
31
  agentCommand
28
32
  ]));
29
33
  /**
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
+ /**
30
54
  * Assembles and runs the CLI program, taking over the process. Not
31
55
  * re-exported from `index.ts` — a library consumer's import graph must not
32
56
  * pull in the process-owning module.
33
57
  *
58
+ * Output routing (hooks parse `agent *` stdout with jq, so stdout carries
59
+ * only what a command writes as its result):
60
+ *
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`.
70
+ * - 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.
76
+ *
77
+ * 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.
80
+ *
34
81
  * @public
35
82
  */
36
- const main = () => {
83
+ const main = (options = {}) => {
37
84
  const env = process.env;
38
85
  const logLevel = resolveLogLevel(env);
39
86
  const logFile = resolveLogFile(env);
@@ -41,16 +88,18 @@ const main = () => {
41
88
  env,
42
89
  cwd: process.cwd()
43
90
  });
44
- const cli = Command.run(rootCommand, { version: CURRENT_CLI_VERSION });
45
- const program = resolveDataPath(projectDir).pipe(Effect.flatMap((dbPath) => cli.pipe(Effect.provide(PlatformLive({
91
+ const dataLayer = Layer.unwrap(Effect.map(resolveDataPath(projectDir), (dbPath) => PlatformLive({
46
92
  dbPath,
47
93
  env,
48
94
  logLevel,
49
95
  logFile
50
- })))), Effect.provide(PathResolutionLive(projectDir)), Effect.provide(NodeServices.layer), Effect.catchCause((cause) => {
51
- if (cause.reasons.filter(Cause.isDieReason).length > 0) return Console.error(`vitest-agent: ${formatFatalError(cause)}`).pipe(Effect.andThen(Effect.failCause(cause)));
52
- return Effect.failCause(cause);
53
- }));
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 }), {
99
+ platform,
100
+ render: renderFailure,
101
+ helpOnUsageError: "stderr"
102
+ }).pipe(Effect.provideService(CurrentDistribution, Option.fromNullishOr(options.distribution)));
54
103
  NodeRuntime.runMain(program);
55
104
  };
56
105
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitest-agent/cli",
3
- "version": "3.1.6",
3
+ "version": "3.2.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": [
@@ -45,8 +45,10 @@
45
45
  "dependencies": {
46
46
  "@effect/platform-node": "4.0.0-rc.117",
47
47
  "@effect/sql-sqlite-node": "4.0.0-rc.117",
48
- "@effected/workspaces": "^0.26.0",
49
- "@vitest-agent/engine": "0.2.6",
48
+ "@effected/cli": "^0.9.0",
49
+ "@effected/engine": "^0.1.0",
50
+ "@effected/workspaces": "^0.28.0",
51
+ "@vitest-agent/engine": "0.2.8",
50
52
  "@vitest-agent/sdk": "5.1.2",
51
53
  "@vitest-agent/sidecar": "2.2.2",
52
54
  "effect": "4.0.0-rc.117"
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.59.2"
8
+ "packageVersion": "7.59.1"
9
9
  }
10
10
  ]
11
11
  }
package/version.js CHANGED
@@ -7,7 +7,7 @@
7
7
  *
8
8
  * @public
9
9
  */
10
- const CURRENT_CLI_VERSION = "3.1.6";
10
+ const CURRENT_CLI_VERSION = "3.2.1";
11
11
 
12
12
  //#endregion
13
13
  export { CURRENT_CLI_VERSION };