@vitest-agent/cli 2.2.18 → 2.2.19

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
@@ -66,14 +66,14 @@ const mapDefectToExit = (cause) => {
66
66
  const message = defect instanceof Error ? defect.message : String(defect ?? "unknown defect");
67
67
  return writeStderrAndExit(5, "Defect", message);
68
68
  };
69
- const hostKindOpt = Flag.string("host-kind").pipe(Flag.withDescription("Host vendor identifier; e.g. 'claude-code', 'cursor', 'goose'"));
70
- const agentTypeOpt = Flag.string("agent-type").pipe(Flag.withDescription("Agent type, must begin with the host-kind prefix"));
71
- const hostSessionIdOpt = Flag.string("host-session-id").pipe(Flag.withDescription("Host's native session id (host chat UUID; `session_id` in the CC hook payload)"));
72
- const transcriptPathOpt = Flag.string("transcript-path").pipe(Flag.withDescription("Path to the host's transcript file (basename UUID is the conversation key)"));
73
- const cwdOpt = Flag.string("cwd").pipe(Flag.withDescription("Workspace root directory the agent is running in"));
74
- const parentAgentIdOpt = Flag.optional(Flag.string("parent-agent-id"));
75
- const clientNonceOpt = Flag.optional(Flag.string("client-nonce"));
76
- const projectKeyOverrideOpt = Flag.optional(Flag.string("project-key"));
69
+ const hostKindOpt = Flag.String("host-kind").pipe(Flag.withDescription("Host vendor identifier; e.g. 'claude-code', 'cursor', 'goose'"));
70
+ const agentTypeOpt = Flag.String("agent-type").pipe(Flag.withDescription("Agent type, must begin with the host-kind prefix"));
71
+ const hostSessionIdOpt = Flag.String("host-session-id").pipe(Flag.withDescription("Host's native session id (host chat UUID; `session_id` in the CC hook payload)"));
72
+ const transcriptPathOpt = Flag.String("transcript-path").pipe(Flag.withDescription("Path to the host's transcript file (basename UUID is the conversation key)"));
73
+ const cwdOpt = Flag.String("cwd").pipe(Flag.withDescription("Workspace root directory the agent is running in"));
74
+ const parentAgentIdOpt = Flag.optional(Flag.String("parent-agent-id"));
75
+ const clientNonceOpt = Flag.optional(Flag.String("client-nonce"));
76
+ const projectKeyOverrideOpt = Flag.optional(Flag.String("project-key"));
77
77
  const registerAgentSubcommand = Command.make("register-agent", {
78
78
  hostKind: hostKindOpt,
79
79
  agentType: agentTypeOpt,
@@ -111,11 +111,11 @@ const registerAgentSubcommand = Command.make("register-agent", {
111
111
  idempotencyHit: result.idempotencyHit
112
112
  }));
113
113
  }).pipe(Effect.provide(NodeServices.layer))).pipe(Command.withDescription("Register an agent invocation in the per-project store and the per-client session map"));
114
- const agentIdOpt = Flag.string("agent-id").pipe(Flag.withDescription("The agent_id (UUID) returned by an earlier register-agent call"));
115
- const endedAtOpt = Flag.optional(Flag.integer("ended-at"));
116
- const endHostSessionIdOpt = Flag.optional(Flag.string("host-session-id"));
117
- const endCwdOpt = Flag.string("cwd").pipe(Flag.withDefault(process.cwd()), Flag.withDescription("Workspace root, used to locate the per-project data.db"));
118
- const endProjectKeyOverrideOpt = Flag.optional(Flag.string("project-key"));
114
+ const agentIdOpt = Flag.String("agent-id").pipe(Flag.withDescription("The agent_id (UUID) returned by an earlier register-agent call"));
115
+ const endedAtOpt = Flag.optional(Flag.Int("ended-at"));
116
+ const endHostSessionIdOpt = Flag.optional(Flag.String("host-session-id"));
117
+ const endCwdOpt = Flag.String("cwd").pipe(Flag.withDefault(process.cwd()), Flag.withDescription("Workspace root, used to locate the per-project data.db"));
118
+ const endProjectKeyOverrideOpt = Flag.optional(Flag.String("project-key"));
119
119
  const endAgentSubcommand = Command.make("end-agent", {
120
120
  agentId: agentIdOpt,
121
121
  endedAt: endedAtOpt,
@@ -139,8 +139,8 @@ const endAgentSubcommand = Command.make("end-agent", {
139
139
  ...Option.isSome(opts.hostSessionId) && { hostSessionId: opts.hostSessionId.value }
140
140
  }).pipe(Effect.provide(sidecar), Effect.catchCause(mapDefectToExit));
141
141
  }).pipe(Effect.provide(NodeServices.layer))).pipe(Command.withDescription("Mark an agent (and optionally its session) as ended"));
142
- const commandOpt = Flag.string("command").pipe(Flag.withDescription("The Bash command to (possibly) rewrite with VITEST_AGENT_* env-prefix"));
143
- const cwdInjectOpt = Flag.string("cwd").pipe(Flag.withDefault(process.cwd()), Flag.withDescription("Working directory; used to find package.json scripts"));
142
+ const commandOpt = Flag.String("command").pipe(Flag.withDescription("The Bash command to (possibly) rewrite with VITEST_AGENT_* env-prefix"));
143
+ const cwdInjectOpt = Flag.String("cwd").pipe(Flag.withDefault(process.cwd()), Flag.withDescription("Working directory; used to find package.json scripts"));
144
144
  const injectEnvSubcommand = Command.make("inject-env", {
145
145
  command: commandOpt,
146
146
  cwd: cwdInjectOpt
@@ -157,7 +157,7 @@ const sidecarPathSubcommand = Command.make("sidecar-path", {}, () => Effect.sync
157
157
  if (path === null) process.exit(1);
158
158
  process.stdout.write(`${path}\n`);
159
159
  })).pipe(Command.withDescription("Print the absolute path of the platform sidecar binary resolved via require.resolve"));
160
- const testPathArg = Argument.string("path").pipe(Argument.withDescription("Path to classify against the workspace test layout; relative paths resolve against VITEST_AGENT_PROJECT_DIR, or cwd when that is unset"));
160
+ const testPathArg = Argument.String("path").pipe(Argument.withDescription("Path to classify against the workspace test layout; relative paths resolve against VITEST_AGENT_PROJECT_DIR, or cwd when that is unset"));
161
161
  /**
162
162
  * True when any directory between `ownerPath` and `filePath`'s own directory
163
163
  * declares its own `package.json`.
package/commands/db.js CHANGED
@@ -17,12 +17,12 @@ const pathCommand = Command.make("path", {}, () => Effect.gen(function* () {
17
17
  const dbPath = yield* resolveDataPath(process.env.VITEST_AGENT_PROJECT_DIR ?? process.cwd());
18
18
  yield* Effect.sync(() => process.stdout.write(`${dbPath}\n`));
19
19
  })).pipe(Command.withDescription("Print the resolved database path"));
20
- const keepRecentOption = Flag.withDefault(Flag.integer("keep-recent"), 30).pipe(Flag.withDescription("Number of most-recent sessions to keep in full"));
20
+ const keepRecentOption = Flag.withDefault(Flag.Int("keep-recent"), 30).pipe(Flag.withDescription("Number of most-recent sessions to keep in full"));
21
21
  const pruneCommand = Command.make("prune", { keepRecent: keepRecentOption }, ({ keepRecent }) => Effect.gen(function* () {
22
22
  const result = yield* (yield* DataStore).pruneSessions(keepRecent);
23
23
  yield* Effect.sync(() => process.stdout.write(`Pruned ${result.prunedTurns} turn row(s) across ${result.affectedSessions} session(s); session rows retained.\n`));
24
24
  })).pipe(Command.withDescription("Drop old sessions' turn history (W1 retention; keeps the last N in full)"));
25
- const yesOption = Flag.boolean("yes").pipe(Flag.withDefault(false), Flag.withDescription("Skip the interactive confirmation prompt"));
25
+ const yesOption = Flag.Boolean("yes").pipe(Flag.withDefault(false), Flag.withDescription("Skip the interactive confirmation prompt"));
26
26
  const resetCommand = Command.make("reset", { yes: yesOption }, ({ yes }) => Effect.gen(function* () {
27
27
  const agentId = process.env.VITEST_AGENT_AGENT_ID;
28
28
  if (agentId !== void 0 && agentId.length > 0) {
@@ -68,8 +68,8 @@ const resetCommand = Command.make("reset", { yes: yesOption }, ({ yes }) => Effe
68
68
  process.stdout.write(`Deleted database at ${dbPath}\n`);
69
69
  });
70
70
  }).pipe(Effect.provide(NodeServices.layer))).pipe(Command.withDescription("Wipe the database (human-only; blocked in agent contexts)"));
71
- const queryFormatOption = Flag.choice("format", ["table", "json"]).pipe(Flag.withDefault("table"), Flag.withDescription("Output format for query results"));
72
- const sqlArg = Argument.string("sql").pipe(Argument.withDescription("Read-only SQL statement to execute against data.db"));
71
+ const queryFormatOption = Flag.Literals("format", ["table", "json"]).pipe(Flag.withDefault("table"), Flag.withDescription("Output format for query results"));
72
+ const sqlArg = Argument.String("sql").pipe(Argument.withDescription("Read-only SQL statement to execute against data.db"));
73
73
  /**
74
74
  * Flatten an error and its cause chain into a single message so the
75
75
  * driver's `attempt to write a readonly database` text surfaces to
@@ -9,7 +9,7 @@ import { Command, Flag } from "effect/unstable/cli";
9
9
  *
10
10
  * @packageDocumentation
11
11
  */
12
- const formatOption = Flag.withDefault(Flag.choice("format", ["markdown", "json"]), "markdown");
12
+ const formatOption = Flag.withDefault(Flag.Literals("format", ["markdown", "json"]), "markdown");
13
13
  const writeOutput = (results, format) => Effect.sync(() => {
14
14
  if (format === "json") process.stdout.write(`${JSON.stringify(results, null, 2)}\n`);
15
15
  else process.stdout.write(`${formatDoctor(results)}\n`);
@@ -7,13 +7,13 @@ import { Effect, Option } from "effect";
7
7
  import { Argument, Command, Flag } from "effect/unstable/cli";
8
8
 
9
9
  //#region src/commands/record.ts
10
- const chatId = Flag.string("chat-id").pipe(Flag.withDescription("Host chat id (`session_id` in the Claude Code hook envelope; equivalent in other clients)"));
11
- const occurredAt = Flag.string("occurred-at").pipe(Flag.withDefault((/* @__PURE__ */ new Date()).toISOString()), Flag.withDescription("ISO 8601 timestamp; defaults to now"));
12
- const payloadArg = Argument.string("payload-json").pipe(Argument.withDescription("Stringified JSON payload (validated against TurnPayload)"));
13
- const project = Flag.string("project");
14
- const cwd = Flag.string("cwd");
15
- const projectOptional = Flag.optional(Flag.string("project"));
16
- const cwdOptional = Flag.optional(Flag.string("cwd"));
10
+ const chatId = Flag.String("chat-id").pipe(Flag.withDescription("Host chat id (`session_id` in the Claude Code hook envelope; equivalent in other clients)"));
11
+ const occurredAt = Flag.String("occurred-at").pipe(Flag.withDefault((/* @__PURE__ */ new Date()).toISOString()), Flag.withDescription("ISO 8601 timestamp; defaults to now"));
12
+ const payloadArg = Argument.String("payload-json").pipe(Argument.withDescription("Stringified JSON payload (validated against TurnPayload)"));
13
+ const project = Flag.String("project");
14
+ const cwd = Flag.String("cwd");
15
+ const projectOptional = Flag.optional(Flag.String("project"));
16
+ const cwdOptional = Flag.optional(Flag.String("cwd"));
17
17
  const turnSubcommand = Command.make("turn", {
18
18
  chatId,
19
19
  occurredAt,
@@ -30,11 +30,11 @@ const turnSubcommand = Command.make("turn", {
30
30
  process.stderr.write(`record turn: ${err instanceof Error ? err.message : String(err)}\n`);
31
31
  process.exit(1);
32
32
  })))).pipe(Command.withDescription("Validate a TurnPayload JSON and write a turn row"));
33
- const agentKind = Flag.choice("agent-kind", ["main", "subagent"]).pipe(Flag.withDefault("main"));
34
- const agentType = Flag.optional(Flag.string("agent-type"));
35
- const parentChatId = Flag.optional(Flag.string("parent-chat-id"));
36
- const triageWasNonEmpty = Flag.boolean("triage-was-non-empty").pipe(Flag.withDefault(false));
37
- const startedAt = Flag.string("started-at").pipe(Flag.withDefault((/* @__PURE__ */ new Date()).toISOString()));
33
+ const agentKind = Flag.Literals("agent-kind", ["main", "subagent"]).pipe(Flag.withDefault("main"));
34
+ const agentType = Flag.optional(Flag.String("agent-type"));
35
+ const parentChatId = Flag.optional(Flag.String("parent-chat-id"));
36
+ const triageWasNonEmpty = Flag.Boolean("triage-was-non-empty").pipe(Flag.withDefault(false));
37
+ const startedAt = Flag.String("started-at").pipe(Flag.withDefault((/* @__PURE__ */ new Date()).toISOString()));
38
38
  const sessionStartSubcommand = Command.make("session-start", {
39
39
  chatId,
40
40
  project,
@@ -57,8 +57,8 @@ const sessionStartSubcommand = Command.make("session-start", {
57
57
  process.stderr.write(`record session-start: ${err instanceof Error ? err.message : String(err)}\n`);
58
58
  process.exit(1);
59
59
  })))).pipe(Command.withDescription("Insert a new sessions row"));
60
- const endedAt = Flag.string("ended-at").pipe(Flag.withDefault((/* @__PURE__ */ new Date()).toISOString()));
61
- const endReason = Flag.optional(Flag.string("end-reason"));
60
+ const endedAt = Flag.String("ended-at").pipe(Flag.withDefault((/* @__PURE__ */ new Date()).toISOString()));
61
+ const endReason = Flag.optional(Flag.String("end-reason"));
62
62
  const sessionEndSubcommand = Command.make("session-end", {
63
63
  chatId,
64
64
  endedAt,
@@ -71,7 +71,7 @@ const sessionEndSubcommand = Command.make("session-end", {
71
71
  process.stderr.write(`record session-end: ${err instanceof Error ? err.message : String(err)}\n`);
72
72
  process.exit(1);
73
73
  })))).pipe(Command.withDescription("Update sessions.ended_at + end_reason"));
74
- const artifactKindOpt = Flag.choice("artifact-kind", [
74
+ const artifactKindOpt = Flag.Literals("artifact-kind", [
75
75
  "test_written",
76
76
  "test_failed_run",
77
77
  "code_written",
@@ -79,15 +79,15 @@ const artifactKindOpt = Flag.choice("artifact-kind", [
79
79
  "refactor",
80
80
  "test_weakened"
81
81
  ]);
82
- const filePathOpt = Flag.optional(Flag.string("file-path"));
83
- const testCaseIdOpt = Flag.optional(Flag.integer("test-case-id"));
84
- const testRunIdOpt = Flag.optional(Flag.integer("test-run-id"));
85
- const testFirstFailureRunIdOpt = Flag.optional(Flag.integer("test-first-failure-run-id"));
86
- const diffExcerptOpt = Flag.optional(Flag.string("diff-excerpt"));
87
- const recordedAtOpt = Flag.string("recorded-at").pipe(Flag.withDefault((/* @__PURE__ */ new Date()).toISOString()));
88
- const chatIdOptional = Flag.optional(Flag.string("chat-id")).pipe(Flag.withDescription("Host chat id; omit when --tdd-task-id is supplied instead"));
89
- const tddTaskIdOpt = Flag.optional(Flag.integer("tdd-task-id")).pipe(Flag.withDescription("Explicit TDD task id escape hatch (issue #144): bypasses chat-id -> session -> task resolution entirely"));
90
- const suiteOpt = Flag.choice("suite", ["vitest", "bats"]).pipe(Flag.withDefault("vitest"), Flag.withDescription("Explicit test-runner marker (issue #363): 'vitest' (default) or 'bats'. Distinguishes a bats run-level artifact (no test_case_id) from a vitest one for the D2 phase-transition validator."));
82
+ const filePathOpt = Flag.optional(Flag.String("file-path"));
83
+ const testCaseIdOpt = Flag.optional(Flag.Int("test-case-id"));
84
+ const testRunIdOpt = Flag.optional(Flag.Int("test-run-id"));
85
+ const testFirstFailureRunIdOpt = Flag.optional(Flag.Int("test-first-failure-run-id"));
86
+ const diffExcerptOpt = Flag.optional(Flag.String("diff-excerpt"));
87
+ const recordedAtOpt = Flag.String("recorded-at").pipe(Flag.withDefault((/* @__PURE__ */ new Date()).toISOString()));
88
+ const chatIdOptional = Flag.optional(Flag.String("chat-id")).pipe(Flag.withDescription("Host chat id; omit when --tdd-task-id is supplied instead"));
89
+ const tddTaskIdOpt = Flag.optional(Flag.Int("tdd-task-id")).pipe(Flag.withDescription("Explicit TDD task id escape hatch (issue #144): bypasses chat-id -> session -> task resolution entirely"));
90
+ const suiteOpt = Flag.Literals("suite", ["vitest", "bats"]).pipe(Flag.withDefault("vitest"), Flag.withDescription("Explicit test-runner marker (issue #363): 'vitest' (default) or 'bats'. Distinguishes a bats run-level artifact (no test_case_id) from a vitest one for the D2 phase-transition validator."));
91
91
  const tddArtifactSubcommand = Command.make("tdd-artifact", {
92
92
  chatId: chatIdOptional,
93
93
  tddTaskId: tddTaskIdOpt,
@@ -135,7 +135,7 @@ const testCaseTurnsSubcommand = Command.make("test-case-turns", { chatId }, ({ c
135
135
  process.stderr.write(`record test-case-turns: ${err instanceof Error ? err.message : String(err)}\n`);
136
136
  process.exit(1);
137
137
  })))).pipe(Command.withDescription("Backfill test_cases.created_turn_id from file_edits in the current session (BUG-2 fix)"));
138
- const invocationMethodOpt = Flag.choice("invocation-method", [
138
+ const invocationMethodOpt = Flag.Literals("invocation-method", [
139
139
  "bash",
140
140
  "mcp",
141
141
  "cli"
@@ -152,14 +152,14 @@ const runTriggerSubcommand = Command.make("run-trigger", {
152
152
  process.stderr.write(`record run-trigger: ${err instanceof Error ? err.message : String(err)}\n`);
153
153
  process.exit(1);
154
154
  })))).pipe(Command.withDescription("Associate the latest test run with the current Claude Code session"));
155
- const shaOpt = Flag.string("sha");
156
- const parentShaOpt = Flag.optional(Flag.string("parent-sha"));
157
- const messageOpt = Flag.optional(Flag.string("message"));
158
- const authorOpt = Flag.optional(Flag.string("author"));
159
- const committedAtOpt = Flag.optional(Flag.string("committed-at"));
160
- const branchOpt = Flag.optional(Flag.string("branch"));
161
- const projectOpt = Flag.optional(Flag.string("project"));
162
- const filesArg = Argument.string("files-json").pipe(Argument.withDescription("JSON array of {\"filePath\",\"changeKind\"} objects"));
155
+ const shaOpt = Flag.String("sha");
156
+ const parentShaOpt = Flag.optional(Flag.String("parent-sha"));
157
+ const messageOpt = Flag.optional(Flag.String("message"));
158
+ const authorOpt = Flag.optional(Flag.String("author"));
159
+ const committedAtOpt = Flag.optional(Flag.String("committed-at"));
160
+ const branchOpt = Flag.optional(Flag.String("branch"));
161
+ const projectOpt = Flag.optional(Flag.String("project"));
162
+ const filesArg = Argument.String("files-json").pipe(Argument.withDescription("JSON array of {\"filePath\",\"changeKind\"} objects"));
163
163
  const runWorkspaceChangesSubcommand = Command.make("run-workspace-changes", {
164
164
  sha: shaOpt,
165
165
  parentSha: parentShaOpt,
@@ -12,13 +12,13 @@ import { Command, Flag } from "effect/unstable/cli";
12
12
  *
13
13
  * @packageDocumentation
14
14
  */
15
- const formatOption = Flag.withDefault(Flag.choice("format", [
15
+ const formatOption = Flag.withDefault(Flag.Literals("format", [
16
16
  "markdown",
17
17
  "json",
18
18
  "silent"
19
19
  ]), "markdown");
20
- const projectOption = Flag.optional(Flag.string("project"));
21
- const maxLinesOption = Flag.optional(Flag.integer("max-lines"));
20
+ const projectOption = Flag.optional(Flag.String("project"));
21
+ const maxLinesOption = Flag.optional(Flag.Int("max-lines"));
22
22
  const triageCommand = Command.make("triage", {
23
23
  format: formatOption,
24
24
  project: projectOption,
@@ -13,17 +13,17 @@ import { Command, Flag } from "effect/unstable/cli";
13
13
  *
14
14
  * @packageDocumentation
15
15
  */
16
- const rowIdOption = Flag.optional(Flag.integer("row-id"));
17
- const chatIdOption = Flag.optional(Flag.string("chat-id"));
18
- const kindOption = Flag.withDefault(Flag.choice("kind", [
16
+ const rowIdOption = Flag.optional(Flag.Int("row-id"));
17
+ const chatIdOption = Flag.optional(Flag.String("chat-id"));
18
+ const kindOption = Flag.withDefault(Flag.Literals("kind", [
19
19
  "stop",
20
20
  "session_end",
21
21
  "pre_compact",
22
22
  "tdd_handoff",
23
23
  "user_prompt_nudge"
24
24
  ]), "session_end");
25
- const userPromptHintOption = Flag.optional(Flag.string("user-prompt-hint"));
26
- const formatOption = Flag.withDefault(Flag.choice("format", ["markdown", "json"]), "markdown");
25
+ const userPromptHintOption = Flag.optional(Flag.String("user-prompt-hint"));
26
+ const formatOption = Flag.withDefault(Flag.Literals("format", ["markdown", "json"]), "markdown");
27
27
  const wrapupCommand = Command.make("wrapup", {
28
28
  rowId: rowIdOption,
29
29
  chatId: chatIdOption,
package/index.js CHANGED
@@ -11,7 +11,7 @@ import { DATA_DB_FILENAME, REGISTRY_DB_FILENAME, SESSIONS_DB_FILENAME, resolvePr
11
11
  *
12
12
  * @public
13
13
  */
14
- const CURRENT_CLI_VERSION = "2.2.18";
14
+ const CURRENT_CLI_VERSION = "2.2.19";
15
15
 
16
16
  //#endregion
17
17
  export { CURRENT_CLI_VERSION, CliLive, DATA_DB_FILENAME, REGISTRY_DB_FILENAME, SESSIONS_DB_FILENAME, SidecarLive, registerAgentEffect, resolveProjectDataDir, resolveRegistryDir, resolveSessionMapPath };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitest-agent/cli",
3
- "version": "2.2.18",
3
+ "version": "2.2.19",
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": [
@@ -38,12 +38,12 @@
38
38
  "vitest-agent": "bin/vitest-agent.js"
39
39
  },
40
40
  "dependencies": {
41
- "@effect/platform-node": "4.0.0-rc.112",
42
- "@effect/sql-sqlite-node": "4.0.0-rc.112",
43
- "@effected/workspaces": "^0.20.3",
44
- "@vitest-agent/sdk": "3.1.1",
45
- "@vitest-agent/sidecar": "2.1.18",
46
- "effect": "4.0.0-rc.112"
41
+ "@effect/platform-node": "4.0.0-rc.115",
42
+ "@effect/sql-sqlite-node": "4.0.0-rc.115",
43
+ "@effected/workspaces": "^0.21.0",
44
+ "@vitest-agent/sdk": "3.1.2",
45
+ "@vitest-agent/sidecar": "2.1.19",
46
+ "effect": "4.0.0-rc.115"
47
47
  },
48
48
  "engines": {
49
49
  "node": ">=24.11.0"