@vitest-agent/sdk 1.3.0 → 1.3.2

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/index.js CHANGED
@@ -115,7 +115,7 @@ import { requiredArtifactForTransition, transitionEnforcesBehaviorMatch, validat
115
115
  * substituted yet. Exported for version introspection by downstream tooling.
116
116
  * @public
117
117
  */
118
- const CURRENT_SDK_VERSION = "1.3.0";
118
+ const CURRENT_SDK_VERSION = "1.3.2";
119
119
 
120
120
  //#endregion
121
121
  export { ActionSeverity, ActorType, Agent, AgentConsoleMode, AgentContext, AgentId, AgentNotFoundError, AgentPluginOptions, AgentReport, AgentReporterOptions, BehaviorAbandonedEvent, BehaviorAddedEvent, BehaviorCompletedEvent, BehaviorDetail, BehaviorNotFoundError, BehaviorRow, BehaviorScopedEventTypes, BehaviorStartedEvent, BehaviorStatus, BehaviorsReadyEvent, BlockedEvent, CURRENT_SDK_VERSION, CacheManifest, CacheManifestEntry, ChannelEvent, ChatId, CiConsoleMode, ConfigLive, ConsoleLeakFile, ConsoleLeaks, ConsoleLogLevel, ConsoleMode, ConsoleOutputMode, ConsoleOutputs, ConversationId, ConversationNotFoundError, CoverageBaselines, FileCoverageReport as CoverageFile, CoverageGap, CoverageLevel, CoverageMetric, CoverageRenderState, CoverageReport, CoverageTargets, CoverageTargetsMetrics, CoverageTotals, DATABASE_FILENAME, DataReader, DataReaderLive, DataStore, DataStoreError, DataStoreLive, DetailLevel, DetailResolver, DetailResolverLive, DiscoveryError, DiscoveryRegistry, DiscoveryRegistryLive, Environment, EnvironmentDetector, EnvironmentDetectorLive, EnvironmentDetectorTest, Executor, ExecutorResolver, ExecutorResolverLive, FailureRecord, FileCoverageReport, FileEditPayload, FormatSelector, FormatSelectorLive, GfmFormatter, GitCommandError, GoalAbandonedEvent, GoalAddedEvent, GoalCompletedEvent, GoalDetail, GoalNotFoundError, GoalRow, GoalStartedEvent, GoalStatus, GoalsReadyEvent, HistoryRecord, HistoryTracker, HistoryTrackerLive, HistoryTrackerTest, HookFirePayload, HookStatus, HookType, HostKind, HostMetadataParseError, HumanConsoleMode, HypothesisPayload, IDEMPOTENCY_ROOT_SENTINEL, IdempotencyHit, IllegalStatusTransitionError, JsonFormatter, LoggerLive, MarkdownFormatter, MetricThresholds, ModuleRecord, ModuleReport, NotePayload, OutputFormat, OutputPipelineLive, OutputRenderer, OutputRendererLive, PackageManager, PathResolutionError, PathResolutionLive, PatternThresholds, PerClientSessionMapReader, PerClientSessionMapReaderLive, PerClientSessionMapWriter, PerClientSessionMapWriterLive, PhaseTransitionEvent, ProbeMissError, ProjectDiscovery, ProjectDiscoveryLive, ProjectDiscoveryTest, ProjectIdentity, ProjectIdentityLive, ProjectIdentityNotResolvableError, ProjectIdentityTest, ProjectKey, RegistrationConflictError, RenderState, RenderTotals, ReportError, ReportSummary, ResolvedThresholds, RunContext, RunContext$, RunContextLive, RunContextService, RunContextTest, RunEvent, SessionCompleteEvent, SessionNotFoundError, SessionOutcome, SidecarTimeoutError, SilentFormatter, SuggestedActionRecord, TagCountEntry, TddTaskAlreadyEndedError, TddTaskId, TddTaskNotFoundError, TerminalFormatter, TestClassification, TestHistory, TestRecord, TestReport, TestRun, TestRunReason, TestState, ToolCallPayload, ToolResultPayload, Transport, TrendEntry, TrendRecord, TurnPayload, UserPromptPayload, VitestAgentConfig, VitestAgentConfigFile, _resetMigrationCacheForTesting, ansi, assembleHistoryRecord, assembleManifest, buildAgentReport, buildConsoleLeaks, buildEnvPrefix, canonicalizeGitUrl, ciAnnotationsFormatter, classifyTest, collectConsoleLeakEntries, compressLines, computeFailureSignature, computeTrend, deriveIdempotencyKey, detectPackageManager, detectVitestScripts, determineTier, ensureMigrated, extractSqlReason, findFunctionBoundary, formatConsoleMarkdown, formatFatalError, formatGfm, formatTriageEffect, formatWrapupEffect, getRecentDirection, getRunCommand, getWorstMetric, gitUrlToProjectKey, hashTargets, historyKey, initialRenderState, isTimeoutError, isVitestInvocation, migration as migration0001, normalizeAssertionShape, normalizeWorkspaceKey, osc8, probeHostMetadataFromEnv, migration$1 as registryMigration0001, relativePath, requiredArtifactForTransition, resolveCoverageInput, resolveDataPath, resolveLogFile, resolveLogLevel, resolveProjectIdentityFromCandidates, resolveProjectKeyFromCwd, resolveWorkspaceKey, rewriteBashCommand, safeFilename, migration$2 as sessionMapMigration0001, stripAnsi, transitionEnforcesBehaviorMatch, validateCoverageConfig, validateCoverageTargetsShape, validatePhaseTransition };
@@ -422,9 +422,10 @@ const DataReaderLive = Layer.effect(DataReader, Effect.gen(function* () {
422
422
  WHERE project = ${project}
423
423
  ORDER BY timestamp DESC LIMIT 1`;
424
424
  if (runs.length === 0) return Option.none();
425
+ const runId = runs[0].id;
425
426
  const fileCoverageRows = yield* sql`SELECT f.path as file_path, fc.statements, fc.branches, fc.functions, fc.lines, fc.uncovered_lines
426
427
  FROM file_coverage fc JOIN files f ON f.id = fc.file_id
427
- WHERE fc.run_id = ${runs[0].id}`;
428
+ WHERE fc.run_id = ${runId}`;
428
429
  const trendRows = yield* sql`SELECT statements, branches, functions, lines
429
430
  FROM coverage_trends
430
431
  WHERE project = ${project}
@@ -687,11 +688,12 @@ const DataReaderLive = Layer.effect(DataReader, Effect.gen(function* () {
687
688
  WHERE project = ${project}
688
689
  ORDER BY timestamp DESC LIMIT 1`;
689
690
  if (runs.length === 0) return Option.none();
691
+ const runId = runs[0].id;
690
692
  const rows = yield* sql`SELECT tc.id, tc.full_name, tc.state, tc.duration, f.path as relative_module_id, tc.classification
691
693
  FROM test_cases tc
692
694
  JOIN test_modules tm ON tm.id = tc.module_id
693
695
  JOIN files f ON f.id = tm.file_id
694
- WHERE tm.run_id = ${runs[0].id} AND tc.full_name = ${fullName}
696
+ WHERE tm.run_id = ${runId} AND tc.full_name = ${fullName}
695
697
  LIMIT 1`;
696
698
  if (rows.length === 0) return Option.none();
697
699
  const r = rows[0];
@@ -757,12 +759,13 @@ const DataReaderLive = Layer.effect(DataReader, Effect.gen(function* () {
757
759
  WHERE project = ${project}
758
760
  ORDER BY timestamp DESC LIMIT 1`;
759
761
  if (runs.length === 0) return [];
762
+ const runId = runs[0].id;
760
763
  return (yield* sql`SELECT tm.id, f.path as file_path, tm.state,
761
764
  (SELECT COUNT(*) FROM test_cases tc WHERE tc.module_id = tm.id) as test_count,
762
765
  tm.duration
763
766
  FROM test_modules tm
764
767
  JOIN files f ON f.id = tm.file_id
765
- WHERE tm.run_id = ${runs[0].id}
768
+ WHERE tm.run_id = ${runId}
766
769
  ORDER BY f.path`).map((r) => ({
767
770
  id: r.id,
768
771
  file: r.file_path,
@@ -860,7 +863,8 @@ const DataReaderLive = Layer.effect(DataReader, Effect.gen(function* () {
860
863
  })));
861
864
  const findSessionsByChatPrefix = (prefix) => Effect.gen(function* () {
862
865
  yield* Effect.logDebug("findSessionsByChatPrefix").pipe(Effect.annotateLogs({ prefix }));
863
- return (yield* sql`SELECT id, chat_id, project, cwd, agent_kind, agent_type, parent_session_id, triage_was_non_empty, started_at, ended_at, end_reason FROM sessions WHERE chat_id LIKE ${`${prefix}%`} ESCAPE '\\' ORDER BY started_at DESC`).map(sessionRowToDetail);
866
+ const pattern = `${prefix}%`;
867
+ return (yield* sql`SELECT id, chat_id, project, cwd, agent_kind, agent_type, parent_session_id, triage_was_non_empty, started_at, ended_at, end_reason FROM sessions WHERE chat_id LIKE ${pattern} ESCAPE '\\' ORDER BY started_at DESC`).map(sessionRowToDetail);
864
868
  }).pipe(Effect.annotateLogs("service", "DataReader"), Effect.mapError((e) => new DataStoreError({
865
869
  operation: "read",
866
870
  table: "sessions",
@@ -879,7 +883,10 @@ const DataReaderLive = Layer.effect(DataReader, Effect.gen(function* () {
879
883
  const searchTurns = (options) => Effect.gen(function* () {
880
884
  yield* Effect.logDebug("searchTurns").pipe(Effect.annotateLogs({ ...options }));
881
885
  const limit = options.limit ?? 100;
882
- return (yield* sql`SELECT id, session_id, turn_no, type, payload, occurred_at FROM turns WHERE 1=1${options.sessionId !== void 0 ? sql` AND session_id = ${options.sessionId}` : sql``}${options.type !== void 0 ? sql` AND type = ${options.type}` : sql``}${options.since !== void 0 ? sql` AND occurred_at >= ${options.since}` : sql``} ORDER BY occurred_at DESC, turn_no DESC LIMIT ${limit}`).map((r) => ({
886
+ const sessionFilter = options.sessionId !== void 0 ? sql` AND session_id = ${options.sessionId}` : sql``;
887
+ const typeFilter = options.type !== void 0 ? sql` AND type = ${options.type}` : sql``;
888
+ const sinceFilter = options.since !== void 0 ? sql` AND occurred_at >= ${options.since}` : sql``;
889
+ return (yield* sql`SELECT id, session_id, turn_no, type, payload, occurred_at FROM turns WHERE 1=1${sessionFilter}${typeFilter}${sinceFilter} ORDER BY occurred_at DESC, turn_no DESC LIMIT ${limit}`).map((r) => ({
883
890
  id: r.id,
884
891
  sessionId: r.session_id,
885
892
  turnNo: r.turn_no,
@@ -1564,6 +1571,7 @@ const DataReaderLive = Layer.effect(DataReader, Effect.gen(function* () {
1564
1571
  WHERE project = ${options.project}
1565
1572
  ORDER BY timestamp DESC LIMIT 1`;
1566
1573
  if (runs.length === 0) return [];
1574
+ const runId = runs[0].id;
1567
1575
  return (yield* sql`
1568
1576
  SELECT tc.id, tc.full_name, tc.state, tc.duration, f.path AS file_path, tc.classification
1569
1577
  FROM test_cases tc
@@ -1571,7 +1579,7 @@ const DataReaderLive = Layer.effect(DataReader, Effect.gen(function* () {
1571
1579
  JOIN files f ON f.id = tm.file_id
1572
1580
  JOIN test_case_tags tct ON tct.test_case_id = tc.id
1573
1581
  JOIN tags t ON t.id = tct.tag_id
1574
- WHERE tm.run_id = ${runs[0].id} AND t.name = ${tag}
1582
+ WHERE tm.run_id = ${runId} AND t.name = ${tag}
1575
1583
  ORDER BY tc.full_name
1576
1584
  `).map(mapTestListRow);
1577
1585
  }
@@ -227,7 +227,8 @@ const DataStoreLive = Layer.effect(DataStore, Effect.gen(function* () {
227
227
  testModuleId,
228
228
  mappingType
229
229
  }));
230
- yield* sql`INSERT OR IGNORE INTO source_test_map (source_file_id, test_module_id, mapping_type) VALUES (${yield* ensureFile(sourceFilePath)}, ${testModuleId}, ${mappingType})`;
230
+ const sourceFileId = yield* ensureFile(sourceFilePath);
231
+ yield* sql`INSERT OR IGNORE INTO source_test_map (source_file_id, test_module_id, mapping_type) VALUES (${sourceFileId}, ${testModuleId}, ${mappingType})`;
231
232
  }).pipe(Effect.annotateLogs("service", "DataStore"), Effect.mapError((e) => new DataStoreError({
232
233
  operation: "write",
233
234
  table: "source_test_map",
@@ -343,11 +344,12 @@ const DataStoreLive = Layer.effect(DataStore, Effect.gen(function* () {
343
344
  if (input.type === "file_edit") {
344
345
  const filePath = payload.file_path;
345
346
  yield* sql`INSERT OR IGNORE INTO files (path) VALUES (${filePath})`;
347
+ const fileId = (yield* sql`SELECT id FROM files WHERE path = ${filePath}`)[0].id;
346
348
  yield* sql`
347
349
  INSERT INTO file_edits (turn_id, file_id, edit_kind, lines_added, lines_removed, diff)
348
350
  VALUES (
349
351
  ${turnId},
350
- ${(yield* sql`SELECT id FROM files WHERE path = ${filePath}`)[0].id},
352
+ ${fileId},
351
353
  ${payload.edit_kind},
352
354
  ${payload.lines_added ?? null},
353
355
  ${payload.lines_removed ?? null},
@@ -356,11 +358,12 @@ const DataStoreLive = Layer.effect(DataStore, Effect.gen(function* () {
356
358
  `;
357
359
  } else {
358
360
  const rawToolName = payload.tool_name;
361
+ const toolName = typeof rawToolName === "string" && rawToolName.startsWith("mcp__") ? rawToolName.split("__").at(-1) ?? rawToolName : rawToolName;
359
362
  yield* sql`
360
363
  INSERT INTO tool_invocations (turn_id, tool_name, params_hash, result_summary, duration_ms, success)
361
364
  VALUES (
362
365
  ${turnId},
363
- ${typeof rawToolName === "string" && rawToolName.startsWith("mcp__") ? rawToolName.split("__").at(-1) ?? rawToolName : rawToolName},
366
+ ${toolName},
364
367
  ${null},
365
368
  ${payload.result_summary ?? null},
366
369
  ${payload.duration_ms ?? null},
@@ -530,7 +533,7 @@ const DataStoreLive = Layer.effect(DataStore, Effect.gen(function* () {
530
533
  goal: input.goal
531
534
  }));
532
535
  yield* ensureTddTaskOpen(input.tddTaskId);
533
- return goalRowFromDb((yield* sql`
536
+ const rows = yield* sql`
534
537
  INSERT INTO tdd_session_goals (session_id, ordinal, goal)
535
538
  SELECT ${input.tddTaskId},
536
539
  COALESCE(MAX(ordinal), -1) + 1,
@@ -542,7 +545,8 @@ const DataStoreLive = Layer.effect(DataStore, Effect.gen(function* () {
542
545
  operation: "write",
543
546
  table: "tdd_session_goals",
544
547
  reason: extractSqlReason(e)
545
- }))))[0]);
548
+ })));
549
+ return goalRowFromDb(rows[0]);
546
550
  }).pipe(Effect.annotateLogs("service", "DataStore"));
547
551
  const getGoal = (id) => Effect.gen(function* () {
548
552
  const rows = yield* sql`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitest-agent/sdk",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "private": false,
5
5
  "description": "Shared Effect Schema, SQLite migrations, data layer, services, formatters, and utilities for vitest-agent packages.",
6
6
  "keywords": [
@@ -43,11 +43,13 @@
43
43
  },
44
44
  "dependencies": {
45
45
  "@effect/cluster": "^0.59.0",
46
+ "@effect/experimental": "^0.60.0",
46
47
  "@effect/platform": "^0.96.2",
47
48
  "@effect/platform-node": "^0.107.0",
48
49
  "@effect/rpc": "^0.75.1",
49
50
  "@effect/sql": "^0.51.1",
50
51
  "@effect/sql-sqlite-node": "^0.52.0",
52
+ "@effect/workflow": "^0.18.2",
51
53
  "@types/acorn": "^6.0.4",
52
54
  "acorn": "^8.17.0",
53
55
  "acorn-typescript": "^1.4.13",
@@ -55,7 +57,7 @@
55
57
  "config-file-effect": "^0.3.0",
56
58
  "effect": "^3.21.4",
57
59
  "std-env": "^4.1.0",
58
- "workspaces-effect": "^1.3.0",
60
+ "workspaces-effect": "^2.0.2",
59
61
  "xdg-effect": "^2.1.0"
60
62
  },
61
63
  "engines": {
@@ -25,7 +25,8 @@ const IDEMPOTENCY_ROOT_SENTINEL = "__ROOT__";
25
25
  const deriveIdempotencyKey = (input) => {
26
26
  const parent = input.parentAgentId ?? "__ROOT__";
27
27
  const message = `${input.agentType}|${parent}|${input.clientNonce}`;
28
- return base32Encode(createHash("sha256").update(message).digest()).slice(0, 26);
28
+ const digest = createHash("sha256").update(message).digest();
29
+ return base32Encode(digest).slice(0, 26);
29
30
  };
30
31
  const BASE32_ALPHABET = "abcdefghijklmnopqrstuvwxyz234567";
31
32
  /**