@angli/unit-test-tool 0.1.0
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/.claude/settings.local.json +14 -0
- package/README.md +232 -0
- package/dist/src/cli/commands/analyze.js +20 -0
- package/dist/src/cli/commands/guard.js +26 -0
- package/dist/src/cli/commands/init.js +39 -0
- package/dist/src/cli/commands/run.js +72 -0
- package/dist/src/cli/commands/schedule.js +29 -0
- package/dist/src/cli/commands/start.js +102 -0
- package/dist/src/cli/commands/status.js +27 -0
- package/dist/src/cli/commands/verify.js +15 -0
- package/dist/src/cli/context/create-context.js +101 -0
- package/dist/src/cli/index.js +23 -0
- package/dist/src/cli/utils/scan-dir.js +6 -0
- package/dist/src/core/analyzers/coverage-analyzer.js +8 -0
- package/dist/src/core/analyzers/dependency-complexity-analyzer.js +19 -0
- package/dist/src/core/analyzers/existing-test-analyzer.js +66 -0
- package/dist/src/core/analyzers/failure-history-analyzer.js +9 -0
- package/dist/src/core/analyzers/file-classifier-analyzer.js +24 -0
- package/dist/src/core/analyzers/index.js +37 -0
- package/dist/src/core/analyzers/llm-semantic-analyzer.js +3 -0
- package/dist/src/core/analyzers/path-priority-analyzer.js +34 -0
- package/dist/src/core/coverage/read-coverage-summary.js +183 -0
- package/dist/src/core/executor/claude-cli-executor.js +91 -0
- package/dist/src/core/middleware/loop-detection.js +6 -0
- package/dist/src/core/middleware/pre-completion-checklist.js +27 -0
- package/dist/src/core/middleware/silent-success-post-check.js +13 -0
- package/dist/src/core/planner/rank-candidates.js +3 -0
- package/dist/src/core/planner/rule-planner.js +41 -0
- package/dist/src/core/planner/score-candidate.js +49 -0
- package/dist/src/core/prompts/case-library.js +35 -0
- package/dist/src/core/prompts/edit-boundary-prompt.js +24 -0
- package/dist/src/core/prompts/retry-prompt.js +18 -0
- package/dist/src/core/prompts/system-prompt.js +27 -0
- package/dist/src/core/prompts/task-prompt.js +22 -0
- package/dist/src/core/reporter/index.js +48 -0
- package/dist/src/core/state-machine/index.js +12 -0
- package/dist/src/core/storage/defaults.js +16 -0
- package/dist/src/core/storage/event-store.js +16 -0
- package/dist/src/core/storage/lifecycle-store.js +18 -0
- package/dist/src/core/storage/report-store.js +16 -0
- package/dist/src/core/storage/state-store.js +11 -0
- package/dist/src/core/strategies/classify-failure.js +14 -0
- package/dist/src/core/strategies/switch-mock-strategy.js +9 -0
- package/dist/src/core/tools/analyze-baseline.js +54 -0
- package/dist/src/core/tools/guard.js +68 -0
- package/dist/src/core/tools/run-loop.js +108 -0
- package/dist/src/core/tools/run-with-claude-cli.js +645 -0
- package/dist/src/core/tools/verify-all.js +75 -0
- package/dist/src/core/worktrees/is-git-repo.js +10 -0
- package/dist/src/types/index.js +1 -0
- package/dist/src/types/logger.js +1 -0
- package/dist/src/utils/clock.js +10 -0
- package/dist/src/utils/command-runner.js +18 -0
- package/dist/src/utils/commands.js +28 -0
- package/dist/src/utils/duration.js +22 -0
- package/dist/src/utils/fs.js +53 -0
- package/dist/src/utils/logger.js +10 -0
- package/dist/src/utils/paths.js +21 -0
- package/dist/src/utils/process-lifecycle.js +74 -0
- package/dist/src/utils/prompts.js +20 -0
- package/dist/tests/core/create-context.test.js +41 -0
- package/dist/tests/core/default-state.test.js +10 -0
- package/dist/tests/core/failure-classification.test.js +7 -0
- package/dist/tests/core/loop-detection.test.js +7 -0
- package/dist/tests/core/paths.test.js +11 -0
- package/dist/tests/core/prompt-builders.test.js +33 -0
- package/dist/tests/core/score-candidate.test.js +28 -0
- package/dist/tests/core/state-machine.test.js +12 -0
- package/dist/tests/integration/status-report.test.js +21 -0
- package/docs/architecture.md +20 -0
- package/docs/demo.sh +266 -0
- package/docs/skill-integration.md +15 -0
- package/docs/state-machine.md +15 -0
- package/package.json +31 -0
- package/src/cli/commands/analyze.ts +22 -0
- package/src/cli/commands/guard.ts +28 -0
- package/src/cli/commands/init.ts +41 -0
- package/src/cli/commands/run.ts +79 -0
- package/src/cli/commands/schedule.ts +32 -0
- package/src/cli/commands/start.ts +111 -0
- package/src/cli/commands/status.ts +30 -0
- package/src/cli/commands/verify.ts +17 -0
- package/src/cli/context/create-context.ts +142 -0
- package/src/cli/index.ts +27 -0
- package/src/cli/utils/scan-dir.ts +5 -0
- package/src/core/analyzers/coverage-analyzer.ts +10 -0
- package/src/core/analyzers/dependency-complexity-analyzer.ts +25 -0
- package/src/core/analyzers/existing-test-analyzer.ts +76 -0
- package/src/core/analyzers/failure-history-analyzer.ts +12 -0
- package/src/core/analyzers/file-classifier-analyzer.ts +25 -0
- package/src/core/analyzers/index.ts +51 -0
- package/src/core/analyzers/llm-semantic-analyzer.ts +6 -0
- package/src/core/analyzers/path-priority-analyzer.ts +41 -0
- package/src/core/coverage/read-coverage-summary.ts +224 -0
- package/src/core/executor/claude-cli-executor.ts +94 -0
- package/src/core/middleware/loop-detection.ts +8 -0
- package/src/core/middleware/pre-completion-checklist.ts +32 -0
- package/src/core/middleware/silent-success-post-check.ts +16 -0
- package/src/core/planner/rank-candidates.ts +5 -0
- package/src/core/planner/rule-planner.ts +65 -0
- package/src/core/planner/score-candidate.ts +60 -0
- package/src/core/prompts/case-library.ts +36 -0
- package/src/core/prompts/edit-boundary-prompt.ts +26 -0
- package/src/core/prompts/retry-prompt.ts +22 -0
- package/src/core/prompts/system-prompt.ts +32 -0
- package/src/core/prompts/task-prompt.ts +26 -0
- package/src/core/reporter/index.ts +56 -0
- package/src/core/state-machine/index.ts +14 -0
- package/src/core/storage/defaults.ts +18 -0
- package/src/core/storage/event-store.ts +18 -0
- package/src/core/storage/lifecycle-store.ts +20 -0
- package/src/core/storage/report-store.ts +19 -0
- package/src/core/storage/state-store.ts +18 -0
- package/src/core/strategies/classify-failure.ts +9 -0
- package/src/core/strategies/switch-mock-strategy.ts +12 -0
- package/src/core/tools/analyze-baseline.ts +61 -0
- package/src/core/tools/guard.ts +89 -0
- package/src/core/tools/run-loop.ts +142 -0
- package/src/core/tools/run-with-claude-cli.ts +926 -0
- package/src/core/tools/verify-all.ts +83 -0
- package/src/core/worktrees/is-git-repo.ts +10 -0
- package/src/types/index.ts +291 -0
- package/src/types/logger.ts +6 -0
- package/src/utils/clock.ts +10 -0
- package/src/utils/command-runner.ts +24 -0
- package/src/utils/commands.ts +42 -0
- package/src/utils/duration.ts +20 -0
- package/src/utils/fs.ts +50 -0
- package/src/utils/logger.ts +12 -0
- package/src/utils/paths.ts +24 -0
- package/src/utils/process-lifecycle.ts +92 -0
- package/src/utils/prompts.ts +22 -0
- package/tests/core/create-context.test.ts +45 -0
- package/tests/core/default-state.test.ts +11 -0
- package/tests/core/failure-classification.test.ts +8 -0
- package/tests/core/loop-detection.test.ts +8 -0
- package/tests/core/paths.test.ts +13 -0
- package/tests/core/prompt-builders.test.ts +38 -0
- package/tests/core/score-candidate.test.ts +30 -0
- package/tests/core/state-machine.test.ts +14 -0
- package/tests/fixtures/simple-project/.openclaw-testbot/logs/events.jsonl +10 -0
- package/tests/fixtures/simple-project/.openclaw-testbot/plan.json +75 -0
- package/tests/fixtures/simple-project/.openclaw-testbot/reports/coverage-summary.json +9 -0
- package/tests/fixtures/simple-project/.openclaw-testbot/reports/final-report.json +14 -0
- package/tests/fixtures/simple-project/.openclaw-testbot/state.json +18 -0
- package/tests/fixtures/simple-project/coverage-summary.json +1 -0
- package/tests/fixtures/simple-project/package.json +8 -0
- package/tests/fixtures/simple-project/src/add.js +3 -0
- package/tests/fixtures/simple-project/test-runner.js +18 -0
- package/tests/integration/status-report.test.ts +24 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
import os from 'node:os'
|
|
5
|
+
import { createContext } from '../../src/cli/context/create-context.js'
|
|
6
|
+
|
|
7
|
+
describe('createContext', () => {
|
|
8
|
+
it('passes promptOverrides into prompt builders', async () => {
|
|
9
|
+
const projectPath = mkdtempSync(path.join(os.tmpdir(), 'unit-test-tool-'))
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
writeFileSync(path.join(projectPath, 'package.json'), JSON.stringify({ scripts: {} }))
|
|
13
|
+
|
|
14
|
+
const ctx = await createContext({
|
|
15
|
+
projectPath,
|
|
16
|
+
coverageTarget: 80,
|
|
17
|
+
configOverrides: {
|
|
18
|
+
promptOverrides: {
|
|
19
|
+
systemAppend: 'system override',
|
|
20
|
+
taskAppend: 'task override',
|
|
21
|
+
retryAppend: 'retry override'
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
const task = {
|
|
27
|
+
taskId: 't1',
|
|
28
|
+
targetFile: 'src/foo.ts',
|
|
29
|
+
testFiles: [],
|
|
30
|
+
score: 1,
|
|
31
|
+
reasons: [],
|
|
32
|
+
estimatedDifficulty: 'low' as const,
|
|
33
|
+
strategy: '补测试',
|
|
34
|
+
status: 'pending' as const,
|
|
35
|
+
attemptCount: 0
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
expect(ctx.prompts.buildSystemPrompt()).toContain('system override')
|
|
39
|
+
expect(ctx.prompts.buildTaskPrompt(task)).toContain('task override')
|
|
40
|
+
expect(ctx.prompts.buildRetryPrompt(task, 'failed')).toContain('retry override')
|
|
41
|
+
} finally {
|
|
42
|
+
rmSync(projectPath, { recursive: true, force: true })
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
})
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { defaultState } from '../../src/core/storage/defaults.js'
|
|
3
|
+
|
|
4
|
+
describe('defaultState', () => {
|
|
5
|
+
it('provides baseline state', () => {
|
|
6
|
+
const state = defaultState()
|
|
7
|
+
expect(state.phase).toBe('INIT')
|
|
8
|
+
expect(state.status).toBe('idle')
|
|
9
|
+
expect(state.totals.pending).toBe(0)
|
|
10
|
+
})
|
|
11
|
+
})
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { classifyFailure } from '../../src/core/strategies/classify-failure.js'
|
|
3
|
+
|
|
4
|
+
describe('classifyFailure', () => {
|
|
5
|
+
it('classifies timeout messages', () => {
|
|
6
|
+
expect(classifyFailure('request timeout')).toBe('CLI_TIMEOUT')
|
|
7
|
+
})
|
|
8
|
+
})
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { loopDetection } from '../../src/core/middleware/loop-detection.js'
|
|
3
|
+
|
|
4
|
+
describe('loopDetection', () => {
|
|
5
|
+
it('detects when threshold exceeded', () => {
|
|
6
|
+
expect(loopDetection({ attemptCount: 3 } as any, 2).loopDetected).toBe(true)
|
|
7
|
+
})
|
|
8
|
+
})
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { buildPaths } from '../../src/utils/paths.js'
|
|
3
|
+
|
|
4
|
+
describe('buildPaths', () => {
|
|
5
|
+
it('builds runtime file paths', () => {
|
|
6
|
+
const paths = buildPaths('/tmp/demo-project')
|
|
7
|
+
|
|
8
|
+
expect(paths.runtimeDir).toBe('/tmp/demo-project/.unit_test_tool_workspace')
|
|
9
|
+
expect(paths.statePath).toBe('/tmp/demo-project/.unit_test_tool_workspace/state.json')
|
|
10
|
+
expect(paths.eventsPath).toBe('/tmp/demo-project/.unit_test_tool_workspace/logs/events.jsonl')
|
|
11
|
+
expect(paths.finalReportPath).toBe('/tmp/demo-project/.unit_test_tool_workspace/reports/final-report.json')
|
|
12
|
+
})
|
|
13
|
+
})
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { buildPromptBuilders } from '../../src/utils/prompts.js'
|
|
3
|
+
|
|
4
|
+
describe('buildPromptBuilders', () => {
|
|
5
|
+
it('includes default strategy and case library in system prompt', () => {
|
|
6
|
+
const prompts = buildPromptBuilders()
|
|
7
|
+
const systemPrompt = prompts.buildSystemPrompt()
|
|
8
|
+
|
|
9
|
+
expect(systemPrompt).toContain('通用单测策略:')
|
|
10
|
+
expect(systemPrompt).toContain('典型案例约束:')
|
|
11
|
+
expect(systemPrompt).toContain('render/HOC 包装组件')
|
|
12
|
+
expect(systemPrompt).toContain('强依赖上下文组件')
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
it('appends project prompt overrides', () => {
|
|
16
|
+
const prompts = buildPromptBuilders({
|
|
17
|
+
systemAppend: 'system rule',
|
|
18
|
+
taskAppend: 'task rule',
|
|
19
|
+
retryAppend: 'retry rule'
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
const task = {
|
|
23
|
+
taskId: 't1',
|
|
24
|
+
targetFile: 'src/foo.ts',
|
|
25
|
+
testFiles: [],
|
|
26
|
+
score: 1,
|
|
27
|
+
reasons: [],
|
|
28
|
+
estimatedDifficulty: 'low' as const,
|
|
29
|
+
strategy: '补测试',
|
|
30
|
+
status: 'pending' as const,
|
|
31
|
+
attemptCount: 0
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
expect(prompts.buildSystemPrompt()).toContain('system rule')
|
|
35
|
+
expect(prompts.buildTaskPrompt(task)).toContain('task rule')
|
|
36
|
+
expect(prompts.buildRetryPrompt(task, 'boom')).toContain('retry rule')
|
|
37
|
+
})
|
|
38
|
+
})
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { scoreCandidate } from '../../src/core/planner/score-candidate.js'
|
|
3
|
+
|
|
4
|
+
describe('scoreCandidate', () => {
|
|
5
|
+
it('scores priority and low complexity candidates higher', () => {
|
|
6
|
+
const result = scoreCandidate({
|
|
7
|
+
targetFile: 'src/a.ts',
|
|
8
|
+
coverage: { coverageGap: 20 },
|
|
9
|
+
pathPriority: { label: 'priority', score: 100 },
|
|
10
|
+
fileClassification: {},
|
|
11
|
+
dependencyComplexity: {
|
|
12
|
+
importCount: 1,
|
|
13
|
+
externalDependencyCount: 1,
|
|
14
|
+
complexityLevel: 'low'
|
|
15
|
+
},
|
|
16
|
+
existingTest: {
|
|
17
|
+
hasExistingTest: false,
|
|
18
|
+
testFilePaths: []
|
|
19
|
+
},
|
|
20
|
+
failureHistory: {
|
|
21
|
+
previousAttemptCount: 0,
|
|
22
|
+
loopDetected: false,
|
|
23
|
+
blockedBefore: false,
|
|
24
|
+
failurePenaltyScore: 0
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
expect(result.baseScore).toBeGreaterThan(100)
|
|
29
|
+
})
|
|
30
|
+
})
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { deriveStatusFromPhase } from '../../src/core/state-machine/index.js'
|
|
3
|
+
|
|
4
|
+
describe('deriveStatusFromPhase', () => {
|
|
5
|
+
it('maps blocked and done phases', () => {
|
|
6
|
+
expect(deriveStatusFromPhase('BLOCKED')).toBe('blocked')
|
|
7
|
+
expect(deriveStatusFromPhase('DONE')).toBe('done')
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
it('maps init to idle and active phases to running', () => {
|
|
11
|
+
expect(deriveStatusFromPhase('INIT')).toBe('idle')
|
|
12
|
+
expect(deriveStatusFromPhase('WRITING_TESTS')).toBe('running')
|
|
13
|
+
})
|
|
14
|
+
})
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{"eventType":"baseline_analyzed","phase":"ANALYZE_BASELINE","message":"analyzed 1 source files","data":{"framework":"unknown","sourceFiles":1,"testFiles":0},"timestamp":"2026-03-31T17:38:43.768Z"}
|
|
2
|
+
{"eventType":"plan_generated","phase":"PLANNING","message":"generated plan with 1 tasks","data":{"totalTasks":1},"timestamp":"2026-03-31T17:38:43.771Z"}
|
|
3
|
+
{"eventType":"baseline_analyzed","phase":"ANALYZE_BASELINE","message":"analyzed 1 source files","data":{"framework":"unknown","sourceFiles":1,"testFiles":0},"timestamp":"2026-03-31T17:55:30.031Z"}
|
|
4
|
+
{"eventType":"baseline_analyzed","phase":"ANALYZE_BASELINE","message":"analyzed 1 source files","data":{"framework":"unknown","sourceFiles":1,"testFiles":0},"timestamp":"2026-03-31T17:57:20.718Z"}
|
|
5
|
+
{"eventType":"plan_generated","phase":"PLANNING","message":"generated plan with 1 tasks","data":{"totalTasks":1},"timestamp":"2026-03-31T17:57:20.721Z"}
|
|
6
|
+
{"eventType":"baseline_analyzed","phase":"ANALYZE_BASELINE","message":"analyzed 1 source files","data":{"framework":"unknown","sourceFiles":1,"testFiles":0},"timestamp":"2026-03-31T23:53:44.984Z"}
|
|
7
|
+
{"eventType":"baseline_analyzed","phase":"ANALYZE_BASELINE","message":"analyzed 1 source files","data":{"framework":"unknown","sourceFiles":1,"testFiles":0},"timestamp":"2026-03-31T23:53:45.007Z"}
|
|
8
|
+
{"eventType":"plan_generated","phase":"PLANNING","message":"generated plan with 1 tasks","data":{"totalTasks":1},"timestamp":"2026-03-31T23:53:45.010Z"}
|
|
9
|
+
{"eventType":"plan_generated","phase":"PLANNING","message":"generated plan with 1 tasks","data":{"totalTasks":1},"timestamp":"2026-03-31T23:56:30.257Z"}
|
|
10
|
+
{"eventType":"task_started","phase":"WRITING_TESTS","taskId":"t-0001","message":"task started","data":{"targetFile":"src/add.js","attemptCount":1},"timestamp":"2026-03-31T23:56:40.567Z"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"planId": "plan-1775001390254",
|
|
3
|
+
"generatedAt": "2026-03-31T23:56:30.254Z",
|
|
4
|
+
"coverageBaseline": {
|
|
5
|
+
"lines": 0,
|
|
6
|
+
"rawSummary": "sourceFiles=1, testFiles=0"
|
|
7
|
+
},
|
|
8
|
+
"selectionStrategy": "rule-plus-llm",
|
|
9
|
+
"plannerMode": "rule-plus-llm",
|
|
10
|
+
"llmPlannerApplied": true,
|
|
11
|
+
"llmPlannerFallback": false,
|
|
12
|
+
"llmValidationWarnings": [],
|
|
13
|
+
"tasks": [
|
|
14
|
+
{
|
|
15
|
+
"taskId": "t-0001",
|
|
16
|
+
"targetFile": "src/add.js",
|
|
17
|
+
"testFiles": [],
|
|
18
|
+
"score": 12,
|
|
19
|
+
"reasons": [
|
|
20
|
+
"low-complexity"
|
|
21
|
+
],
|
|
22
|
+
"estimatedDifficulty": "low",
|
|
23
|
+
"strategy": "pure-logic",
|
|
24
|
+
"status": "failed",
|
|
25
|
+
"attemptCount": 1,
|
|
26
|
+
"priorityGroup": "P1",
|
|
27
|
+
"businessReason": "低复杂度逻辑文件,优先完成以快速提升覆盖率。",
|
|
28
|
+
"riskTag": "low",
|
|
29
|
+
"llmAdjustment": 2,
|
|
30
|
+
"analyzerFacts": {
|
|
31
|
+
"targetFile": "src/add.js",
|
|
32
|
+
"coverage": {
|
|
33
|
+
"lineRate": 0,
|
|
34
|
+
"coverageGap": 0
|
|
35
|
+
},
|
|
36
|
+
"pathPriority": {
|
|
37
|
+
"label": "normal",
|
|
38
|
+
"score": 0
|
|
39
|
+
},
|
|
40
|
+
"existingTest": {
|
|
41
|
+
"hasExistingTest": false,
|
|
42
|
+
"testFilePaths": [],
|
|
43
|
+
"partialCoverageLikely": false
|
|
44
|
+
},
|
|
45
|
+
"fileClassification": {
|
|
46
|
+
"ruleCategory": "unknown",
|
|
47
|
+
"semanticCategory": "unknown",
|
|
48
|
+
"uiSignal": false,
|
|
49
|
+
"domSignal": false,
|
|
50
|
+
"frameworkSignal": false
|
|
51
|
+
},
|
|
52
|
+
"dependencyComplexity": {
|
|
53
|
+
"importCount": 0,
|
|
54
|
+
"externalDependencyCount": 0,
|
|
55
|
+
"complexityLevel": "low"
|
|
56
|
+
},
|
|
57
|
+
"failureHistory": {
|
|
58
|
+
"previousAttemptCount": 0,
|
|
59
|
+
"loopDetected": false,
|
|
60
|
+
"blockedBefore": false,
|
|
61
|
+
"failurePenaltyScore": 0
|
|
62
|
+
},
|
|
63
|
+
"analyzerWarnings": []
|
|
64
|
+
},
|
|
65
|
+
"lastTriedAt": "2026-03-31T23:56:40.565Z",
|
|
66
|
+
"failureCategory": "RUNTIME_ENV_ERROR",
|
|
67
|
+
"lastError": "npm error Missing script: \"lint\"\nnpm error\nnpm error Did you mean this?\nnpm error npm link # Symlink a package folder\nnpm error\nnpm error To see a list of scripts, run:\nnpm error npm run\nnpm error A complete log of this run can be found in: /Users/starlee/.npm/_logs/2026-03-31T23_57_15_899Z-debug-0.log"
|
|
68
|
+
}
|
|
69
|
+
],
|
|
70
|
+
"groups": {
|
|
71
|
+
"P0": 0,
|
|
72
|
+
"P1": 1,
|
|
73
|
+
"P2": 0
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"generatedAt": "2026-03-31T23:53:44.985Z",
|
|
3
|
+
"totals": {
|
|
4
|
+
"pending": 1,
|
|
5
|
+
"running": 0,
|
|
6
|
+
"passed": 0,
|
|
7
|
+
"failed": 0,
|
|
8
|
+
"blocked": 0
|
|
9
|
+
},
|
|
10
|
+
"blockedTasks": [],
|
|
11
|
+
"failedTasks": [],
|
|
12
|
+
"coveragePassed": false,
|
|
13
|
+
"suggestedNextAction": "plan"
|
|
14
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"phase": "PLANNING",
|
|
3
|
+
"status": "running",
|
|
4
|
+
"totals": {
|
|
5
|
+
"pending": 1,
|
|
6
|
+
"running": 0,
|
|
7
|
+
"passed": 0,
|
|
8
|
+
"failed": 0,
|
|
9
|
+
"blocked": 0
|
|
10
|
+
},
|
|
11
|
+
"lastAction": "generate-plan",
|
|
12
|
+
"nextSuggestedAction": "run-once",
|
|
13
|
+
"updatedAt": "2026-03-31T23:56:30.256Z",
|
|
14
|
+
"coverageSnapshot": {
|
|
15
|
+
"lines": 0,
|
|
16
|
+
"rawSummary": "sourceFiles=1, testFiles=0"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"total":{"lines":{"pct":100},"statements":{"pct":100},"functions":{"pct":100},"branches":{"pct":100}}}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { writeFileSync } from 'node:fs'
|
|
2
|
+
import { add } from './src/add.js'
|
|
3
|
+
|
|
4
|
+
if (add(1, 2) !== 3) {
|
|
5
|
+
console.error('add failed')
|
|
6
|
+
process.exit(1)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
writeFileSync('coverage-summary.json', JSON.stringify({
|
|
10
|
+
total: {
|
|
11
|
+
lines: { pct: 100 },
|
|
12
|
+
statements: { pct: 100 },
|
|
13
|
+
functions: { pct: 100 },
|
|
14
|
+
branches: { pct: 100 }
|
|
15
|
+
}
|
|
16
|
+
}))
|
|
17
|
+
|
|
18
|
+
console.log('ok')
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { createContext } from '../../src/cli/context/create-context.js'
|
|
4
|
+
import { analyzeBaseline } from '../../src/core/tools/analyze-baseline.js'
|
|
5
|
+
import { buildFinalReport, reportStatus } from '../../src/core/reporter/index.js'
|
|
6
|
+
|
|
7
|
+
const fixture = path.resolve('tests/fixtures/simple-project')
|
|
8
|
+
|
|
9
|
+
describe('integration: status/report', () => {
|
|
10
|
+
it('builds status and report', async () => {
|
|
11
|
+
const ctx = await createContext({
|
|
12
|
+
projectPath: fixture,
|
|
13
|
+
coverageTarget: 80
|
|
14
|
+
})
|
|
15
|
+
await analyzeBaseline(ctx)
|
|
16
|
+
const status = await reportStatus(ctx)
|
|
17
|
+
expect(status.ok).toBe(true)
|
|
18
|
+
|
|
19
|
+
const report = await buildFinalReport(ctx)
|
|
20
|
+
await ctx.reportStore.saveFinalReport(report)
|
|
21
|
+
const loaded = await ctx.reportStore.loadFinalReport()
|
|
22
|
+
expect(loaded).toBeTruthy()
|
|
23
|
+
})
|
|
24
|
+
})
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ES2022",
|
|
5
|
+
"moduleResolution": "Bundler",
|
|
6
|
+
"lib": ["ES2022"],
|
|
7
|
+
"strict": true,
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"resolveJsonModule": true,
|
|
11
|
+
"outDir": "dist",
|
|
12
|
+
"rootDir": ".",
|
|
13
|
+
"types": ["node"],
|
|
14
|
+
"noEmitOnError": true
|
|
15
|
+
},
|
|
16
|
+
"include": ["src", "tests"],
|
|
17
|
+
"exclude": ["node_modules", "dist"]
|
|
18
|
+
}
|