@vitest-agent/cli 4.0.2 → 4.0.3
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 +2 -2
- package/commands/db.js +8 -4
- package/commands/doctor.js +3 -2
- package/commands/record.js +2 -1
- package/commands/triage.js +2 -1
- package/commands/wrapup.js +2 -1
- package/layers/project-data.js +26 -0
- package/main.d.ts +5 -4
- package/main.js +13 -12
- package/package.json +4 -4
- package/version.js +1 -1
package/commands/agent.js
CHANGED
|
@@ -68,7 +68,7 @@ const registerAgentSubcommand = Command.make("register-agent", {
|
|
|
68
68
|
projectKey,
|
|
69
69
|
...Option.isSome(opts.parentAgentId) && { parentAgentId: opts.parentAgentId.value },
|
|
70
70
|
...Option.isSome(opts.clientNonce) && { clientNonce: opts.clientNonce.value }
|
|
71
|
-
}).pipe(Effect.provide(sidecar), Effect.catchCause(mapDefectToExit));
|
|
71
|
+
}).pipe(Effect.provide(sidecar, { local: true }), Effect.catchCause(mapDefectToExit));
|
|
72
72
|
yield* writeStdout(JSON.stringify({
|
|
73
73
|
agentId: result.agentId,
|
|
74
74
|
conversationId: result.conversationId,
|
|
@@ -100,7 +100,7 @@ const endAgentSubcommand = Command.make("end-agent", {
|
|
|
100
100
|
agentId: opts.agentId,
|
|
101
101
|
endedAt,
|
|
102
102
|
...Option.isSome(opts.hostSessionId) && { hostSessionId: opts.hostSessionId.value }
|
|
103
|
-
}).pipe(Effect.provide(sidecar), Effect.catchCause(mapDefectToExit));
|
|
103
|
+
}).pipe(Effect.provide(sidecar, { local: true }), Effect.catchCause(mapDefectToExit));
|
|
104
104
|
}).pipe(Effect.provide(NodeServices.layer))).pipe(Command.withDescription("Mark an agent (and optionally its session) as ended"));
|
|
105
105
|
const commandOpt = Flag.String("command").pipe(Flag.withDescription("The Bash command to (possibly) rewrite with VITEST_AGENT_* env-prefix"));
|
|
106
106
|
const cwdInjectOpt = Flag.String("cwd").pipe(Flag.withDefault(process.cwd()), Flag.withDescription("Working directory; used to find package.json scripts"));
|
package/commands/db.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ProjectDataLive, ProjectDir } from "../layers/project-data.js";
|
|
1
2
|
import { formatDbQuery } from "../lib/format-db-query.js";
|
|
2
3
|
import { Cancelled, CliExit, CliInteractive } from "@effected/cli";
|
|
3
4
|
import { DataStore, resolveDataPath } from "@vitest-agent/engine";
|
|
@@ -8,14 +9,15 @@ import { SqlClient } from "effect/sql/SqlClient";
|
|
|
8
9
|
|
|
9
10
|
//#region src/commands/db.ts
|
|
10
11
|
const pathCommand = Command.make("path", {}, () => Effect.gen(function* () {
|
|
11
|
-
const
|
|
12
|
+
const { dir } = yield* ProjectDir;
|
|
13
|
+
const dbPath = yield* resolveDataPath(dir);
|
|
12
14
|
yield* Effect.sync(() => process.stdout.write(`${dbPath}\n`));
|
|
13
15
|
})).pipe(Command.withDescription("Print the resolved database path"));
|
|
14
16
|
const keepRecentOption = Flag.withDefault(Flag.Int("keep-recent"), 30).pipe(Flag.withDescription("Number of most-recent sessions to keep in full"));
|
|
15
17
|
const pruneCommand = Command.make("prune", { keepRecent: keepRecentOption }, ({ keepRecent }) => Effect.gen(function* () {
|
|
16
18
|
const result = yield* (yield* DataStore).pruneSessions(keepRecent);
|
|
17
19
|
yield* Effect.sync(() => process.stdout.write(`Pruned ${result.prunedTurns} turn row(s) across ${result.affectedSessions} session(s); session rows retained.\n`));
|
|
18
|
-
})).pipe(Command.withDescription("Drop old sessions' turn history (W1 retention; keeps the last N in full)"));
|
|
20
|
+
})).pipe(Command.withDescription("Drop old sessions' turn history (W1 retention; keeps the last N in full)"), Command.provide(ProjectDataLive));
|
|
19
21
|
const yesOption = Flag.Boolean("yes").pipe(Flag.withDefault(false), Flag.withDescription("Skip the interactive confirmation prompt"));
|
|
20
22
|
const resetCommand = Command.make("reset", { yes: yesOption }, ({ yes }) => Effect.gen(function* () {
|
|
21
23
|
const agentId = process.env.VITEST_AGENT_AGENT_ID;
|
|
@@ -23,7 +25,8 @@ const resetCommand = Command.make("reset", { yes: yesOption }, ({ yes }) => Effe
|
|
|
23
25
|
yield* Console.error("db reset is human-only; use db prune or run from a human terminal");
|
|
24
26
|
return yield* CliExit.set(4);
|
|
25
27
|
}
|
|
26
|
-
const
|
|
28
|
+
const { dir } = yield* ProjectDir;
|
|
29
|
+
const dbPath = yield* resolveDataPath(dir);
|
|
27
30
|
if (!yes && !(yield* CliInteractive)) {
|
|
28
31
|
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
32
|
return yield* CliExit.set(5);
|
|
@@ -73,7 +76,8 @@ const queryCommand = Command.make("query", {
|
|
|
73
76
|
});
|
|
74
77
|
return;
|
|
75
78
|
}
|
|
76
|
-
const
|
|
79
|
+
const { dir } = yield* ProjectDir;
|
|
80
|
+
const dbPath = yield* resolveDataPath(dir);
|
|
77
81
|
yield* Effect.gen(function* () {
|
|
78
82
|
const rows = yield* (yield* SqlClient).unsafe(sql);
|
|
79
83
|
yield* Effect.sync(() => {
|
package/commands/doctor.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ProjectDataLive, ProjectDir } from "../layers/project-data.js";
|
|
1
2
|
import { formatDoctor } from "../lib/format-doctor.js";
|
|
2
3
|
import { DataReader, resolveDataPath } from "@vitest-agent/engine";
|
|
3
4
|
import { Effect, Option } from "effect";
|
|
@@ -12,7 +13,7 @@ const writeOutput = (results, format) => Effect.sync(() => {
|
|
|
12
13
|
const doctorCommand = Command.make("doctor", { format: formatOption }, ({ format }) => Effect.gen(function* () {
|
|
13
14
|
const reader = yield* DataReader;
|
|
14
15
|
const results = [];
|
|
15
|
-
const dbPath = yield* resolveDataPath(
|
|
16
|
+
const dbPath = yield* resolveDataPath((yield* ProjectDir).dir);
|
|
16
17
|
results.push({
|
|
17
18
|
name: "Database path",
|
|
18
19
|
passed: true,
|
|
@@ -102,7 +103,7 @@ const doctorCommand = Command.make("doctor", { format: formatOption }, ({ format
|
|
|
102
103
|
}
|
|
103
104
|
yield* writeOutput(results, format);
|
|
104
105
|
if (results.some((r) => !r.passed)) yield* Effect.sync(() => process.exit(1));
|
|
105
|
-
}));
|
|
106
|
+
})).pipe(Command.provide(ProjectDataLive));
|
|
106
107
|
|
|
107
108
|
//#endregion
|
|
108
109
|
export { doctorCommand };
|
package/commands/record.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ProjectDataLive } from "../layers/project-data.js";
|
|
1
2
|
import { DataReader, DataStore, dispatchRecordTddArtifactEffect, recordRunWorkspaceChangesEffect, recordSessionEnd, recordSessionStart, recordTurnEffect } from "@vitest-agent/engine";
|
|
2
3
|
import { Effect, Option } from "effect";
|
|
3
4
|
import { Argument, Command, Flag } from "effect/cli";
|
|
@@ -192,7 +193,7 @@ const recordCommand = Command.make("record").pipe(Command.withSubcommands([
|
|
|
192
193
|
runWorkspaceChangesSubcommand,
|
|
193
194
|
runTriggerSubcommand,
|
|
194
195
|
testCaseTurnsSubcommand
|
|
195
|
-
]), Command.withDescription("Hook write surface (Decision D3): turn, session-start, session-end, tdd-artifact, run-workspace-changes"));
|
|
196
|
+
]), Command.withDescription("Hook write surface (Decision D3): turn, session-start, session-end, tdd-artifact, run-workspace-changes"), Command.provide(ProjectDataLive));
|
|
196
197
|
|
|
197
198
|
//#endregion
|
|
198
199
|
export { recordCommand };
|
package/commands/triage.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ProjectDataLive } from "../layers/project-data.js";
|
|
1
2
|
import { formatTriageEffect } from "@vitest-agent/engine";
|
|
2
3
|
import { Effect } from "effect";
|
|
3
4
|
import { Command, Flag } from "effect/cli";
|
|
@@ -25,7 +26,7 @@ const triageCommand = Command.make("triage", {
|
|
|
25
26
|
return;
|
|
26
27
|
}
|
|
27
28
|
yield* Effect.sync(() => process.stdout.write(md.length > 0 ? `${md}\n` : ""));
|
|
28
|
-
})).pipe(Command.withDescription("Emit the W3 orientation triage brief for SessionStart"));
|
|
29
|
+
})).pipe(Command.withDescription("Emit the W3 orientation triage brief for SessionStart"), Command.provide(ProjectDataLive));
|
|
29
30
|
|
|
30
31
|
//#endregion
|
|
31
32
|
export { triageCommand };
|
package/commands/wrapup.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ProjectDataLive } from "../layers/project-data.js";
|
|
1
2
|
import { formatWrapupEffect } from "@vitest-agent/engine";
|
|
2
3
|
import { Effect } from "effect";
|
|
3
4
|
import { Command, Flag } from "effect/cli";
|
|
@@ -32,7 +33,7 @@ const wrapupCommand = Command.make("wrapup", {
|
|
|
32
33
|
return;
|
|
33
34
|
}
|
|
34
35
|
yield* Effect.sync(() => process.stdout.write(md.length > 0 ? `${md}\n` : ""));
|
|
35
|
-
})).pipe(Command.withDescription("Emit the W5 wrap-up prompt for a session"));
|
|
36
|
+
})).pipe(Command.withDescription("Emit the W5 wrap-up prompt for a session"), Command.provide(ProjectDataLive));
|
|
36
37
|
|
|
37
38
|
//#endregion
|
|
38
39
|
export { wrapupCommand };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { PlatformLive, resolveDataPath } from "@vitest-agent/engine";
|
|
2
|
+
import { Context, Effect, Layer } from "effect";
|
|
3
|
+
|
|
4
|
+
//#region src/layers/project-data.ts
|
|
5
|
+
/**
|
|
6
|
+
* The resolved absolute project directory plus the environment it was
|
|
7
|
+
* resolved from. Provided once by `main.ts` from `resolveProjectDir`.
|
|
8
|
+
*/
|
|
9
|
+
var ProjectDir = class extends Context.Service()("vitest-agent/cli/ProjectDir") {};
|
|
10
|
+
/**
|
|
11
|
+
* The engine's `PlatformLive` over the project `data.db`, built only when a
|
|
12
|
+
* command that needs it runs. `logger: false`: the root `CliLog` layer is the
|
|
13
|
+
* one logger set, and the engine's `LoggerLive` would replace it.
|
|
14
|
+
*/
|
|
15
|
+
const ProjectDataLive = Layer.unwrap(Effect.gen(function* () {
|
|
16
|
+
const { dir, env } = yield* ProjectDir;
|
|
17
|
+
const dbPath = yield* resolveDataPath(dir);
|
|
18
|
+
return PlatformLive({
|
|
19
|
+
dbPath,
|
|
20
|
+
env,
|
|
21
|
+
logger: false
|
|
22
|
+
});
|
|
23
|
+
}));
|
|
24
|
+
|
|
25
|
+
//#endregion
|
|
26
|
+
export { ProjectDataLive, ProjectDir };
|
package/main.d.ts
CHANGED
|
@@ -39,10 +39,11 @@ export interface MainOptions {
|
|
|
39
39
|
* sink that is silent unless `VITEST_REPORTER_LOG_LEVEL` is set (then
|
|
40
40
|
* NDJSON on stderr for every audience), plus an
|
|
41
41
|
* async NDJSON file when `VITEST_REPORTER_LOG_FILE` is set. The platform
|
|
42
|
-
* therefore installs no logger of its own (`
|
|
43
|
-
* the engine's `LoggerLive` would
|
|
44
|
-
*
|
|
45
|
-
*
|
|
42
|
+
* therefore installs no logger of its own (`ProjectDataLive` builds
|
|
43
|
+
* `PlatformLive` with `logger: false`: the engine's `LoggerLive` would
|
|
44
|
+
* otherwise replace this set inside the program). The project database
|
|
45
|
+
* layer is built under that logger, so what it logs while building (the
|
|
46
|
+
* engine's migration records) reaches the same sink.
|
|
46
47
|
* `format: "auto"`: NDJSON for an agent or a CI, plain lines for a person.
|
|
47
48
|
* `argv` (`process.argv.slice(2)`) lets the build-time records follow the
|
|
48
49
|
* audience flags too, so `--agent` with no agent detected is all NDJSON and
|
package/main.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CURRENT_CLI_VERSION } from "./version.js";
|
|
2
|
+
import { ProjectDir } from "./layers/project-data.js";
|
|
2
3
|
import { agentCommand } from "./commands/agent.js";
|
|
3
4
|
import { dbCommand } from "./commands/db.js";
|
|
4
5
|
import { doctorCommand } from "./commands/doctor.js";
|
|
@@ -9,14 +10,14 @@ import * as NodeRuntime from "@effect/platform-node/NodeRuntime";
|
|
|
9
10
|
import * as NodeServices from "@effect/platform-node/NodeServices";
|
|
10
11
|
import { CliAudience, CliRuntime } from "@effected/cli";
|
|
11
12
|
import { CurrentDistribution } from "@effected/engine";
|
|
12
|
-
import { PathResolutionLive,
|
|
13
|
+
import { PathResolutionLive, resolveProjectDir } from "@vitest-agent/engine";
|
|
13
14
|
import { Effect, Layer, Option } from "effect";
|
|
14
15
|
import { Command } from "effect/cli";
|
|
15
16
|
|
|
16
17
|
//#region src/main.ts
|
|
17
18
|
/**
|
|
18
|
-
* Assembled CLI program. Owns the process: resolves the
|
|
19
|
-
*
|
|
19
|
+
* Assembled CLI program. Owns the process: resolves the project directory, wires the
|
|
20
|
+
* root platform (no database), and runs the root command through
|
|
20
21
|
* `@effected/cli`'s `CliRuntime.main` under `NodeRuntime.runMain`.
|
|
21
22
|
*
|
|
22
23
|
* `bin.ts` is the published bin shim (`#!/usr/bin/env node` +
|
|
@@ -66,10 +67,11 @@ const rootCommand = Command.make("vitest-agent").pipe(Command.withSharedFlags(Cl
|
|
|
66
67
|
* sink that is silent unless `VITEST_REPORTER_LOG_LEVEL` is set (then
|
|
67
68
|
* NDJSON on stderr for every audience), plus an
|
|
68
69
|
* async NDJSON file when `VITEST_REPORTER_LOG_FILE` is set. The platform
|
|
69
|
-
* therefore installs no logger of its own (`
|
|
70
|
-
* the engine's `LoggerLive` would
|
|
71
|
-
*
|
|
72
|
-
*
|
|
70
|
+
* therefore installs no logger of its own (`ProjectDataLive` builds
|
|
71
|
+
* `PlatformLive` with `logger: false`: the engine's `LoggerLive` would
|
|
72
|
+
* otherwise replace this set inside the program). The project database
|
|
73
|
+
* layer is built under that logger, so what it logs while building (the
|
|
74
|
+
* engine's migration records) reaches the same sink.
|
|
73
75
|
* `format: "auto"`: NDJSON for an agent or a CI, plain lines for a person.
|
|
74
76
|
* `argv` (`process.argv.slice(2)`) lets the build-time records follow the
|
|
75
77
|
* audience flags too, so `--agent` with no agent detected is all NDJSON and
|
|
@@ -96,11 +98,10 @@ const main = (options = {}) => {
|
|
|
96
98
|
env,
|
|
97
99
|
cwd: process.cwd()
|
|
98
100
|
});
|
|
99
|
-
const platform = Layer.
|
|
100
|
-
|
|
101
|
-
env
|
|
102
|
-
|
|
103
|
-
}))).pipe(Layer.provideMerge(PathResolutionLive(projectDir)), Layer.provideMerge(NodeServices.layer));
|
|
101
|
+
const platform = Layer.mergeAll(Layer.succeed(ProjectDir, {
|
|
102
|
+
dir: projectDir,
|
|
103
|
+
env
|
|
104
|
+
}), PathResolutionLive(projectDir)).pipe(Layer.provideMerge(NodeServices.layer));
|
|
104
105
|
const distribution = Option.fromNullishOr(options.distribution);
|
|
105
106
|
const displayPath = (absolute) => {
|
|
106
107
|
const rel = relative(projectDir, absolute);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vitest-agent/cli",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.3",
|
|
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": [
|
|
@@ -52,9 +52,9 @@
|
|
|
52
52
|
"@effected/glob": "^0.10.0",
|
|
53
53
|
"@effected/walker": "^0.15.0",
|
|
54
54
|
"@effected/workspaces": "^0.31.0",
|
|
55
|
-
"@vitest-agent/engine": "0.6.
|
|
56
|
-
"@vitest-agent/sdk": "6.
|
|
57
|
-
"@vitest-agent/sidecar": "2.2.
|
|
55
|
+
"@vitest-agent/engine": "0.6.1",
|
|
56
|
+
"@vitest-agent/sdk": "6.1.0",
|
|
57
|
+
"@vitest-agent/sidecar": "2.2.6",
|
|
58
58
|
"effect": "^4.0.0"
|
|
59
59
|
},
|
|
60
60
|
"engines": {
|