@mcpeak/cli 0.9.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/LICENSE +21 -0
- package/README.md +108 -0
- package/dist/cli.cjs +6 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +8 -0
- package/dist/commands.cjs +11 -0
- package/dist/commands.d.cts +67 -0
- package/dist/commands.d.mts +67 -0
- package/dist/commands.mjs +2 -0
- package/dist/index.cjs +6 -0
- package/dist/index.d.cts +27 -0
- package/dist/index.d.mts +27 -0
- package/dist/index.mjs +2 -0
- package/dist/replay-command-BAtSzf8R.d.mts +186 -0
- package/dist/replay-command-V0ZSJPiD.d.cts +186 -0
- package/dist/src-D1NW6ckv.mjs +459 -0
- package/dist/src-Df8147pD.cjs +482 -0
- package/dist/test-command-BZ_94UmI.cjs +4576 -0
- package/dist/test-command-CsJfojut.mjs +4493 -0
- package/package.json +61 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 OhMyMCP contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# MCPeak CLI
|
|
2
|
+
|
|
3
|
+
`mcpeak test`는 JSON 테스트 명세로 로컬 stdio MCP 서버를 직접 시작하고 종료합니다.
|
|
4
|
+
|
|
5
|
+
처음 실행하거나 사용 가능한 명령을 확인할 때는 전체 도움말을 표시합니다. 인자 없이 실행해도
|
|
6
|
+
같은 도움말을 stdout에 쓰고 종료 코드 0을 반환합니다.
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
mcpeak --help
|
|
10
|
+
mcpeak -h
|
|
11
|
+
mcpeak help
|
|
12
|
+
mcpeak --version
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
`mcpeak help test`와 `mcpeak test --help`는 `test` 도움말을, `mcpeak help generate`와
|
|
16
|
+
`mcpeak generate --help`는 `generate` 도움말을 표시합니다. 도움말과 버전은 오류가 아니므로
|
|
17
|
+
stderr가 아니라 stdout으로 출력하고 종료 코드 0을 반환합니다.
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
mcpeak test packages/cli/tests/fixtures/weather-suite.json \
|
|
21
|
+
--command node \
|
|
22
|
+
--arg examples/weather-server/server.mjs
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
문법은 `mcpeak test <suite.json> --command <executable> [--arg <value> ...] [--json] [--junit <path>] [--stderr-lines <N>]`입니다. 위 예시의 command와 arg는 `node examples/weather-server/server.mjs`로 실행됩니다. `--arg`는 반복할 수 있고, 하이픈으로 시작하는 값은 `--arg=-m`, 빈 값은 `--arg=`로 전달합니다.
|
|
26
|
+
|
|
27
|
+
stdout에는 보고서만 나갑니다. 기본은 사람이 읽는 보고서이고, `--json`을 주면 `RunnerReport` JSON이 나갑니다. CLI 오류와 서버 프로세스 진단은 stderr로만 나가므로 `--json > report.json`이 깨지지 않습니다. 모든 테스트가 통과하면 종료 코드 0을, failed 또는 aborted report와 입력, 연결, 종료 오류에는 1을 반환합니다.
|
|
28
|
+
|
|
29
|
+
`--junit <path>`는 CI 도구가 읽는 JUnit XML 리포트를 그 경로에 씁니다.
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
mcpeak test weather.json \
|
|
33
|
+
--command node --arg examples/weather-server/server.mjs \
|
|
34
|
+
--junit reports/junit.xml
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
stdout은 그대로 두고 파일만 더하므로 `--json`과 함께 쓸 수 있습니다. 둘의 역할이 다릅니다 — `--json`은 stdout 형식을, `--junit`은 별도 산출물을 정합니다. 경로의 디렉터리는 미리 있어야 하며, 파일을 쓰지 못하면 모든 테스트가 통과했더라도 `JUNIT_WRITE_FAILED`와 함께 종료 코드 1을 냅니다. 리포트 없이 CI가 초록이 되지 않게 하려는 것입니다. XML은 stdout보다 먼저 쓰므로 stdout이 파이프에서 끊겨도 파일은 남습니다.
|
|
38
|
+
|
|
39
|
+
XML을 만드는 단계에서 실패하면 `CLI_INTERNAL_ERROR`와 함께 종료 코드 1을 냅니다. 이때는 파일 쓰기에 도달하기 전이므로 **파일을 만들지도, 기존 파일을 덮어쓰지도 않습니다.** 직전 실행의 리포트가 그대로 남으므로, CI에서 이 경로를 읽는 도구가 낡은 리포트를 최신 결과로 오해할 수 있습니다. 종료 코드로 판정하세요.
|
|
40
|
+
|
|
41
|
+
`RunnerReport`에는 시간 정보가 없어 모든 `time` 속성은 `0`입니다. "0초 걸렸다"가 아니라 "시간 정보를 갖고 있지 않다"는 뜻입니다. 근거는 [ADR-0016](../../docs/adr/0016-junit-time-속성-고정.md), 플래그 설계는 [ADR-0019](../../docs/adr/0019-junit-리포터-cli-노출-방식.md)에 있습니다.
|
|
42
|
+
|
|
43
|
+
`--stderr-lines <N>`은 실패했거나 서버가 비정상 종료·중단했을 때, 진단 내용이 있으면 stderr에 붙는 서버 프로세스 진단 블록의 stderr 표시 줄 수입니다. 기본값은 20이고, `0`을 주면 블록을 완전히 끕니다(그때 출력 바이트는 이 기능이 없던 때와 같습니다). 블록에는 종료 코드와 시그널, 서버가 남긴 stderr의 마지막 N줄이 담기며 잘린 사실은 헤더에 적힙니다. 서버가 정상 종료했고 stderr도 비어 있으면 보여줄 근거가 없으므로 블록을 쓰지 않습니다.
|
|
44
|
+
|
|
45
|
+
### 승인 지문 대조
|
|
46
|
+
|
|
47
|
+
`test`는 실행할 명세의 승인 지문을 계산해 파일에 적힌 `approval.fingerprint`와 대조하고, 그 결과를 보고서에 적습니다. **판정은 바꾸지 않습니다.** 종료 코드는 케이스 결과로만 정해지므로 지문이 달라도 전부 통과하면 0입니다. 명세를 고치는 것은 정상 작업이고, 그때마다 테스트가 막히면 사용자는 확인 절차를 우회하는 방법부터 찾게 됩니다.
|
|
48
|
+
|
|
49
|
+
표시 여부는 다음과 같습니다. 매 실행 한 줄을 무조건 찍으면 손으로 명세를 쓰는 사용자에게는 영구적인 소음이고, 그러면 정작 필요할 때 그 줄을 읽지 않습니다.
|
|
50
|
+
|
|
51
|
+
| 지문 상태 | 전부 통과 | 실패·타임아웃 등이 있음 |
|
|
52
|
+
|---|---|---|
|
|
53
|
+
| 일치 | 침묵 | 표시 |
|
|
54
|
+
| 불일치 | **표시** | 표시 |
|
|
55
|
+
| 없음(미고정) | 침묵 | 표시 |
|
|
56
|
+
|
|
57
|
+
전부 통과인데 불일치일 때만 예외를 두는 이유는 승인받지 않은 명세로 초록불이 뜬 상태이기 때문입니다. 그 사실은 실패보다 오히려 조용히 지나가기 쉽습니다.
|
|
58
|
+
|
|
59
|
+
명세 줄은 보고서 본문 뒤에 빈 줄 하나를 두고 stdout으로 나갑니다. `--json`에는 위 억제 규칙을 적용하지 않고 `spec` 키를 항상 넣습니다(`approval`은 `matched` · `mismatched` · `absent` 중 하나, `fingerprint`는 실행 시점 계산값, `approvedFingerprint`는 파일에 적힌 값이며 `absent`면 키가 없습니다). 기계가 읽는 출력에서 키가 조건부로 사라지면 소비자가 분기를 하나 더 써야 합니다. 기존 보고서 키는 그대로이므로 기존 소비자는 깨지지 않습니다.
|
|
60
|
+
|
|
61
|
+
지문이 없는 명세도 정상입니다. 손으로 쓴 명세와 이 기능 이전에 만든 명세가 여기에 해당하며 실패로 취급하지 않습니다.
|
|
62
|
+
|
|
63
|
+
현재는 UTF-8 JSON 단일 명세와 stdio 서버만 지원합니다. shell 문법, 여러 명세, TypeScript 모듈 명세는 지원하지 않습니다. `record`, `replay`, `mock` 명령은 아직 구현되지 않았습니다.
|
|
64
|
+
|
|
65
|
+
## generate
|
|
66
|
+
|
|
67
|
+
`mcpeak generate`는 서버의 `tools/list` 결과에서 결정론적 baseline suite를 만듭니다.
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
mcpeak generate \
|
|
71
|
+
--suite-id weather \
|
|
72
|
+
--name "Weather server" \
|
|
73
|
+
--out weather.json \
|
|
74
|
+
--command node \
|
|
75
|
+
--arg examples/weather-server/server.mjs \
|
|
76
|
+
--baseline-only
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
문법은 다음과 같습니다.
|
|
80
|
+
|
|
81
|
+
```text
|
|
82
|
+
mcpeak generate --suite-id <id> --name <name> --out <suite.json> --command <executable> [--arg <value> ...] [--baseline-only] [--provider <codex|claude>] [--model <model>]
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`--baseline-only`는 AI를 호출하지 않는 명시적 비대화형 승인입니다. 생성기는 기존 출력 파일을 덮어쓰지 않으며, 같은 디렉터리의 임시 파일을 다시 읽어 suite와 fingerprint를 검증한 뒤 원자적으로 저장합니다. weather-server의 baseline은 `get_weather`에 `{ "city": "example" }`를 사용하므로, 이어서 `mcpeak test`를 실행하면 get_weather가 실패하고 add는 통과합니다. 이는 baseline이 스키마에서 얻은 출발점일 뿐 실행 성공을 보장하지 않는다는 신호입니다.
|
|
86
|
+
|
|
87
|
+
TTY에서 `--baseline-only`를 빼면 대화형 검토가 시작됩니다. Codex 또는 Claude provider와 model을 선택할 수 있습니다. 기본 model은 Codex `gpt-5.6-luna`, Claude `haiku`입니다. `--provider`와 `--model`을 함께 지정하면 그 정확한 선택을 사용합니다.
|
|
88
|
+
|
|
89
|
+
각 AI 요청 전에 provider, model, 정제된 요청의 크기, 결과 제한, timeout, fingerprint를 표시하고 전송 승인을 받습니다. 승인하지 않으면 provider를 호출하지 않습니다. 후보 결과는 전체 적용 또는 change ID 선택 적용으로 검토하며, 피드백을 입력해 새 요청을 보낼 수 있습니다. 질문 결과도 표시한 뒤 답변을 새 요청으로 보낼 수 있습니다. 직접 편집은 별도 JSON 파일 경로를 입력해 불러오며, 같은 diff와 승인 경계를 거칩니다.
|
|
90
|
+
|
|
91
|
+
저장한 명세에는 `approval` 블록이 함께 들어갑니다.
|
|
92
|
+
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"schemaVersion": 1,
|
|
96
|
+
"id": "weather",
|
|
97
|
+
"name": "Weather server",
|
|
98
|
+
"approval": {
|
|
99
|
+
"fingerprint": "9f2c1a3b4d5e6f708192a3b4c5d6e7f8091a2b3c4d5e6f708192a3b4c5d6e7f8"
|
|
100
|
+
},
|
|
101
|
+
"defaultTimeoutMs": 5000,
|
|
102
|
+
"cases": []
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
`fingerprint`는 승인한 시점의 명세를 요약한 소문자 hex 64자입니다. 계산 대상은 파일 바이트가 아니라 파싱된 명세 객체이므로 들여쓰기, 줄 끝 문자, 키 순서를 바꿔도 값이 그대로입니다. 답해야 하는 질문이 "바이트가 바뀌었나"가 아니라 "테스트의 의미가 바뀌었나"이기 때문입니다. `approval` 블록 자신은 계산에서 제외됩니다. 자기를 포함한 채로 자기를 요약할 수는 없습니다. 저장 직후에는 파일을 다시 읽어 계산값과 파일에 적힌 값이 모두 승인 시점의 지문과 같은지 확인한 뒤에만 커밋합니다.
|
|
107
|
+
|
|
108
|
+
마지막으로 승인된 draft의 fingerprint를 확인하고 저장을 다시 승인해야 JSON을 씁니다. 저장한 파일은 기존 `mcpeak test <suite.json> --command ...` 명령에 그대로 전달할 수 있습니다. 실제 Codex 또는 Claude 호출은 계정과 비용을 사용하는 작업이므로, 자동 테스트나 기본 검증에서는 실행하지 않습니다.
|
package/dist/cli.cjs
ADDED
package/dist/cli.d.cts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
package/dist/cli.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
package/dist/cli.mjs
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_test_command = require("./test-command-BZ_94UmI.cjs");
|
|
3
|
+
exports.nodeGenerateDependencies = require_test_command.nodeGenerateDependencies;
|
|
4
|
+
exports.nodeReviewIO = require_test_command.nodeReviewIO;
|
|
5
|
+
exports.parseRepairCommand = require_test_command.parseRepairCommand;
|
|
6
|
+
exports.parseReplayCommand = require_test_command.parseReplayCommand;
|
|
7
|
+
exports.parseTestCommand = require_test_command.parseTestCommand;
|
|
8
|
+
exports.runCli = require_test_command.runCli;
|
|
9
|
+
exports.runGenerateCommand = require_test_command.runGenerateCommand;
|
|
10
|
+
exports.runRepairCommand = require_test_command.runRepairCommand;
|
|
11
|
+
exports.runReplayCommand = require_test_command.runReplayCommand;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { a as RepairCommandDependencies, c as runRepairCommand, d as ReviewIO, f as nodeGenerateDependencies, i as runReplayCommand, l as GenerateCommandDependencies, m as runGenerateCommand, n as ReplayCommandInput, o as RepairCommandInput, p as nodeReviewIO, r as parseReplayCommand, s as parseRepairCommand, t as ReplayCommandDependencies, u as GenerateCommandInput } from "./replay-command-V0ZSJPiD.cjs";
|
|
2
|
+
import { McpStdioConnection } from "@mcpeak/core";
|
|
3
|
+
import { CheckDeterminismOptions, DeterminismResult, FinalizeRunnerExecutionOptions, InputContractOptions, RunSuiteOptions, RunnerExecution, RunnerReport, SpecFindingsResult, SuiteValidationIssue, SuiteValidationResult, TestSuiteSpec } from "@mcpeak/runner";
|
|
4
|
+
//#region src/test-command.d.ts
|
|
5
|
+
interface TestCommandInput {
|
|
6
|
+
readonly suitePath: string;
|
|
7
|
+
readonly command: string;
|
|
8
|
+
readonly args: readonly string[];
|
|
9
|
+
readonly json: boolean;
|
|
10
|
+
/** `--junit` 로 받은 XML 출력 경로. 지정하지 않으면 undefined 이고 XML 을 만들지 않는다. */
|
|
11
|
+
readonly junitPath: string | undefined;
|
|
12
|
+
/** `--repair-bundle` 로 받은 번들 출력 경로. 지정하지 않으면 undefined 이고 번들을 안 만든다. */
|
|
13
|
+
readonly repairBundlePath: string | undefined;
|
|
14
|
+
/** `--determinism`. 스위트를 2회 실행해 결과를 대조한다. 설계 문서 §5.2. */
|
|
15
|
+
readonly determinism: boolean;
|
|
16
|
+
/** `--reset-cmd` 로 받은 초기화 명령. 각 회차 전에 1번씩 실행한다. */
|
|
17
|
+
readonly resetCmd: string | undefined;
|
|
18
|
+
readonly stderrLines: number;
|
|
19
|
+
}
|
|
20
|
+
type CliErrorCode = "CLI_USAGE" | "COMMAND_NOT_IMPLEMENTED" | "SUITE_FORMAT_UNSUPPORTED" | "SUITE_READ_FAILED" | "SUITE_ENCODING_INVALID" | "SUITE_JSON_INVALID" | "SUITE_VALIDATION_FAILED" | "MCP_CONNECTION_FAILED" | "RUNNER_EXECUTION_FAILED" | "RUNNER_FINALIZATION_FAILED" | "JUNIT_WRITE_FAILED" | "REPAIR_BUNDLE_WRITE_FAILED" | "RESET_COMMAND_FAILED" | "CLI_INTERNAL_ERROR";
|
|
21
|
+
interface CliFailure {
|
|
22
|
+
readonly code: CliErrorCode;
|
|
23
|
+
readonly message: string;
|
|
24
|
+
readonly hint: string;
|
|
25
|
+
readonly coreCode?: string;
|
|
26
|
+
readonly issues?: readonly SuiteValidationIssue[];
|
|
27
|
+
}
|
|
28
|
+
interface TestCommandDependencies {
|
|
29
|
+
readFile(path: string): Promise<Uint8Array>;
|
|
30
|
+
validateSuite(input: unknown): SuiteValidationResult;
|
|
31
|
+
connect(options: {
|
|
32
|
+
command: string;
|
|
33
|
+
args: readonly string[];
|
|
34
|
+
}): Promise<McpStdioConnection>;
|
|
35
|
+
startRunner(options: RunSuiteOptions): RunnerExecution;
|
|
36
|
+
finalize(options: FinalizeRunnerExecutionOptions): Promise<RunnerReport>;
|
|
37
|
+
renderReport(report: RunnerReport, options?: {
|
|
38
|
+
color?: boolean;
|
|
39
|
+
}): string;
|
|
40
|
+
/**
|
|
41
|
+
* runner 의 `renderJUnit`. 두 번째 인자를 선언하지 않는다 — CLI 는 `suiteName` 을 넘길 이유가
|
|
42
|
+
* 없고(기본값이 `report.suite.name` 이다), 선택 인자를 가진 실제 함수는 이 시그니처에 그대로
|
|
43
|
+
* 할당된다. ADR-0016 이 예약한 `JUnitRenderOptions` 확장 경로도 막지 않는다.
|
|
44
|
+
*/
|
|
45
|
+
renderJUnit(report: RunnerReport): string;
|
|
46
|
+
writeFile(path: string, text: string): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* 비차단 진단의 주입 지점. 생략하면 `runner` 의 실제 함수를 쓴다. 필수로 두면 진입점의
|
|
49
|
+
* "런타임 의존성 없음" 경로가 이 두 필드를 채울 수 없다. 설계 문서 §7.
|
|
50
|
+
*/
|
|
51
|
+
checkInputContract?(options: InputContractOptions): SpecFindingsResult;
|
|
52
|
+
checkAssertionSubstance?(suite: TestSuiteSpec): SpecFindingsResult;
|
|
53
|
+
/**
|
|
54
|
+
* 결정론성 비교와 초기화 명령의 주입 지점. 위 두 필드와 같은 이유로 선택 사항이다.
|
|
55
|
+
* 생략하면 각각 `runner` 의 `checkDeterminism` 과 `reset-hook.ts` 의 `runResetCommand` 다.
|
|
56
|
+
* 캡처 래퍼는 CLI 내부 구현이라 주입 대상이 아니다(설계 문서 §5.2).
|
|
57
|
+
*/
|
|
58
|
+
checkDeterminism?(options: CheckDeterminismOptions): DeterminismResult;
|
|
59
|
+
runResetCommand?(command: string): Promise<void>;
|
|
60
|
+
colorEnabled: boolean;
|
|
61
|
+
writeStdout(text: string): void;
|
|
62
|
+
writeStderr(text: string): void;
|
|
63
|
+
}
|
|
64
|
+
declare function parseTestCommand(argv: readonly string[]): TestCommandInput;
|
|
65
|
+
declare function runCli(argv: readonly string[], dependencies: TestCommandDependencies): Promise<number>;
|
|
66
|
+
//#endregion
|
|
67
|
+
export { type CliErrorCode, type CliFailure, type GenerateCommandDependencies, type GenerateCommandInput, type RepairCommandDependencies, type RepairCommandInput, type ReplayCommandDependencies, type ReplayCommandInput, type ReviewIO, type TestCommandDependencies, type TestCommandInput, nodeGenerateDependencies, nodeReviewIO, parseRepairCommand, parseReplayCommand, parseTestCommand, runCli, runGenerateCommand, runRepairCommand, runReplayCommand };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { a as RepairCommandDependencies, c as runRepairCommand, d as ReviewIO, f as nodeGenerateDependencies, i as runReplayCommand, l as GenerateCommandDependencies, m as runGenerateCommand, n as ReplayCommandInput, o as RepairCommandInput, p as nodeReviewIO, r as parseReplayCommand, s as parseRepairCommand, t as ReplayCommandDependencies, u as GenerateCommandInput } from "./replay-command-BAtSzf8R.mjs";
|
|
2
|
+
import { CheckDeterminismOptions, DeterminismResult, FinalizeRunnerExecutionOptions, InputContractOptions, RunSuiteOptions, RunnerExecution, RunnerReport, SpecFindingsResult, SuiteValidationIssue, SuiteValidationResult, TestSuiteSpec } from "@mcpeak/runner";
|
|
3
|
+
import { McpStdioConnection } from "@mcpeak/core";
|
|
4
|
+
//#region src/test-command.d.ts
|
|
5
|
+
interface TestCommandInput {
|
|
6
|
+
readonly suitePath: string;
|
|
7
|
+
readonly command: string;
|
|
8
|
+
readonly args: readonly string[];
|
|
9
|
+
readonly json: boolean;
|
|
10
|
+
/** `--junit` 로 받은 XML 출력 경로. 지정하지 않으면 undefined 이고 XML 을 만들지 않는다. */
|
|
11
|
+
readonly junitPath: string | undefined;
|
|
12
|
+
/** `--repair-bundle` 로 받은 번들 출력 경로. 지정하지 않으면 undefined 이고 번들을 안 만든다. */
|
|
13
|
+
readonly repairBundlePath: string | undefined;
|
|
14
|
+
/** `--determinism`. 스위트를 2회 실행해 결과를 대조한다. 설계 문서 §5.2. */
|
|
15
|
+
readonly determinism: boolean;
|
|
16
|
+
/** `--reset-cmd` 로 받은 초기화 명령. 각 회차 전에 1번씩 실행한다. */
|
|
17
|
+
readonly resetCmd: string | undefined;
|
|
18
|
+
readonly stderrLines: number;
|
|
19
|
+
}
|
|
20
|
+
type CliErrorCode = "CLI_USAGE" | "COMMAND_NOT_IMPLEMENTED" | "SUITE_FORMAT_UNSUPPORTED" | "SUITE_READ_FAILED" | "SUITE_ENCODING_INVALID" | "SUITE_JSON_INVALID" | "SUITE_VALIDATION_FAILED" | "MCP_CONNECTION_FAILED" | "RUNNER_EXECUTION_FAILED" | "RUNNER_FINALIZATION_FAILED" | "JUNIT_WRITE_FAILED" | "REPAIR_BUNDLE_WRITE_FAILED" | "RESET_COMMAND_FAILED" | "CLI_INTERNAL_ERROR";
|
|
21
|
+
interface CliFailure {
|
|
22
|
+
readonly code: CliErrorCode;
|
|
23
|
+
readonly message: string;
|
|
24
|
+
readonly hint: string;
|
|
25
|
+
readonly coreCode?: string;
|
|
26
|
+
readonly issues?: readonly SuiteValidationIssue[];
|
|
27
|
+
}
|
|
28
|
+
interface TestCommandDependencies {
|
|
29
|
+
readFile(path: string): Promise<Uint8Array>;
|
|
30
|
+
validateSuite(input: unknown): SuiteValidationResult;
|
|
31
|
+
connect(options: {
|
|
32
|
+
command: string;
|
|
33
|
+
args: readonly string[];
|
|
34
|
+
}): Promise<McpStdioConnection>;
|
|
35
|
+
startRunner(options: RunSuiteOptions): RunnerExecution;
|
|
36
|
+
finalize(options: FinalizeRunnerExecutionOptions): Promise<RunnerReport>;
|
|
37
|
+
renderReport(report: RunnerReport, options?: {
|
|
38
|
+
color?: boolean;
|
|
39
|
+
}): string;
|
|
40
|
+
/**
|
|
41
|
+
* runner 의 `renderJUnit`. 두 번째 인자를 선언하지 않는다 — CLI 는 `suiteName` 을 넘길 이유가
|
|
42
|
+
* 없고(기본값이 `report.suite.name` 이다), 선택 인자를 가진 실제 함수는 이 시그니처에 그대로
|
|
43
|
+
* 할당된다. ADR-0016 이 예약한 `JUnitRenderOptions` 확장 경로도 막지 않는다.
|
|
44
|
+
*/
|
|
45
|
+
renderJUnit(report: RunnerReport): string;
|
|
46
|
+
writeFile(path: string, text: string): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* 비차단 진단의 주입 지점. 생략하면 `runner` 의 실제 함수를 쓴다. 필수로 두면 진입점의
|
|
49
|
+
* "런타임 의존성 없음" 경로가 이 두 필드를 채울 수 없다. 설계 문서 §7.
|
|
50
|
+
*/
|
|
51
|
+
checkInputContract?(options: InputContractOptions): SpecFindingsResult;
|
|
52
|
+
checkAssertionSubstance?(suite: TestSuiteSpec): SpecFindingsResult;
|
|
53
|
+
/**
|
|
54
|
+
* 결정론성 비교와 초기화 명령의 주입 지점. 위 두 필드와 같은 이유로 선택 사항이다.
|
|
55
|
+
* 생략하면 각각 `runner` 의 `checkDeterminism` 과 `reset-hook.ts` 의 `runResetCommand` 다.
|
|
56
|
+
* 캡처 래퍼는 CLI 내부 구현이라 주입 대상이 아니다(설계 문서 §5.2).
|
|
57
|
+
*/
|
|
58
|
+
checkDeterminism?(options: CheckDeterminismOptions): DeterminismResult;
|
|
59
|
+
runResetCommand?(command: string): Promise<void>;
|
|
60
|
+
colorEnabled: boolean;
|
|
61
|
+
writeStdout(text: string): void;
|
|
62
|
+
writeStderr(text: string): void;
|
|
63
|
+
}
|
|
64
|
+
declare function parseTestCommand(argv: readonly string[]): TestCommandInput;
|
|
65
|
+
declare function runCli(argv: readonly string[], dependencies: TestCommandDependencies): Promise<number>;
|
|
66
|
+
//#endregion
|
|
67
|
+
export { type CliErrorCode, type CliFailure, type GenerateCommandDependencies, type GenerateCommandInput, type RepairCommandDependencies, type RepairCommandInput, type ReplayCommandDependencies, type ReplayCommandInput, type ReviewIO, type TestCommandDependencies, type TestCommandInput, nodeGenerateDependencies, nodeReviewIO, parseRepairCommand, parseReplayCommand, parseTestCommand, runCli, runGenerateCommand, runRepairCommand, runReplayCommand };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as runReplayCommand, c as nodeGenerateDependencies, i as parseReplayCommand, l as nodeReviewIO, n as runCli, o as parseRepairCommand, s as runRepairCommand, t as parseTestCommand, u as runGenerateCommand } from "./test-command-CsJfojut.mjs";
|
|
2
|
+
export { nodeGenerateDependencies, nodeReviewIO, parseRepairCommand, parseReplayCommand, parseTestCommand, runCli, runGenerateCommand, runRepairCommand, runReplayCommand };
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_src = require("./src-Df8147pD.cjs");
|
|
3
|
+
exports.COMMANDS = require_src.COMMANDS;
|
|
4
|
+
exports.nodeRepairDependencies = require_src.nodeRepairDependencies;
|
|
5
|
+
exports.run = require_src.run;
|
|
6
|
+
exports.unavailableReplayDependencies = require_src.unavailableReplayDependencies;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { a as RepairCommandDependencies, t as ReplayCommandDependencies } from "./replay-command-V0ZSJPiD.cjs";
|
|
2
|
+
//#region src/index.d.ts
|
|
3
|
+
type Command = (argv: string[]) => Promise<number>;
|
|
4
|
+
declare const COMMANDS: readonly ["test", "generate", "repair", "record", "replay", "verify", "mock"];
|
|
5
|
+
/**
|
|
6
|
+
* `repair` 실행 의존성. 함수로 빼 둔 이유는 **주입 자체를 테스트가 단언할 수 있게** 하기
|
|
7
|
+
* 위해서다. 분기 안에 리터럴로 두면 `reviewIO` 를 빠뜨려도 아무 테스트도 안 깨진다.
|
|
8
|
+
* 실제로 그렇게 한 번 빠뜨렸다(T10 보고서).
|
|
9
|
+
*
|
|
10
|
+
* 대화형 판정은 `generate` 와 같은 기준이다. 같은 `nodeReviewIO()` 를 쓰고, 그 구현이
|
|
11
|
+
* stdin·stdout 이 둘 다 TTY 일 때만 `interactive` 를 참으로 만든다.
|
|
12
|
+
*/
|
|
13
|
+
declare function nodeRepairDependencies(generate: typeof import("@mcpeak/generate")): RepairCommandDependencies;
|
|
14
|
+
/**
|
|
15
|
+
* replay 는 `connect` 를 쓰지 않는다. 대신 카세트 로더가 필요하다. 런타임 의존성을 못 불러도
|
|
16
|
+
* 사용 오류는 정상적으로 내야 하므로, 실제로 쓰이기 전에 끝나는 경로를 위해 자리만 채운다.
|
|
17
|
+
*
|
|
18
|
+
* **테스트가 배선을 직접 단언할 수 있도록 내보낸다.** 여기서 평범한 Error 로 되돌아가면
|
|
19
|
+
* 사용자는 "이슈를 보고하세요" 를 보게 되는데, 모듈 모킹으로는 이 경로를 재현할 수 없다 —
|
|
20
|
+
* `record` 와 `runner` 가 `generate-command` 를 통해 정적 import 체인에 있어서, 그것을
|
|
21
|
+
* 모킹하면 `index.ts` 로드 자체가 깨진다. `nodeRepairDependencies` 를 함수로 뺀 것과 같은
|
|
22
|
+
* 이유다(주입을 빠뜨려도 아무 테스트가 안 깨지는 상황을 막는다).
|
|
23
|
+
*/
|
|
24
|
+
declare const unavailableReplayDependencies: ReplayCommandDependencies;
|
|
25
|
+
declare function run(argv: string[]): Promise<number>;
|
|
26
|
+
//#endregion
|
|
27
|
+
export { COMMANDS, Command, nodeRepairDependencies, run, unavailableReplayDependencies };
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { a as RepairCommandDependencies, t as ReplayCommandDependencies } from "./replay-command-BAtSzf8R.mjs";
|
|
2
|
+
//#region src/index.d.ts
|
|
3
|
+
type Command = (argv: string[]) => Promise<number>;
|
|
4
|
+
declare const COMMANDS: readonly ["test", "generate", "repair", "record", "replay", "verify", "mock"];
|
|
5
|
+
/**
|
|
6
|
+
* `repair` 실행 의존성. 함수로 빼 둔 이유는 **주입 자체를 테스트가 단언할 수 있게** 하기
|
|
7
|
+
* 위해서다. 분기 안에 리터럴로 두면 `reviewIO` 를 빠뜨려도 아무 테스트도 안 깨진다.
|
|
8
|
+
* 실제로 그렇게 한 번 빠뜨렸다(T10 보고서).
|
|
9
|
+
*
|
|
10
|
+
* 대화형 판정은 `generate` 와 같은 기준이다. 같은 `nodeReviewIO()` 를 쓰고, 그 구현이
|
|
11
|
+
* stdin·stdout 이 둘 다 TTY 일 때만 `interactive` 를 참으로 만든다.
|
|
12
|
+
*/
|
|
13
|
+
declare function nodeRepairDependencies(generate: typeof import("@mcpeak/generate")): RepairCommandDependencies;
|
|
14
|
+
/**
|
|
15
|
+
* replay 는 `connect` 를 쓰지 않는다. 대신 카세트 로더가 필요하다. 런타임 의존성을 못 불러도
|
|
16
|
+
* 사용 오류는 정상적으로 내야 하므로, 실제로 쓰이기 전에 끝나는 경로를 위해 자리만 채운다.
|
|
17
|
+
*
|
|
18
|
+
* **테스트가 배선을 직접 단언할 수 있도록 내보낸다.** 여기서 평범한 Error 로 되돌아가면
|
|
19
|
+
* 사용자는 "이슈를 보고하세요" 를 보게 되는데, 모듈 모킹으로는 이 경로를 재현할 수 없다 —
|
|
20
|
+
* `record` 와 `runner` 가 `generate-command` 를 통해 정적 import 체인에 있어서, 그것을
|
|
21
|
+
* 모킹하면 `index.ts` 로드 자체가 깨진다. `nodeRepairDependencies` 를 함수로 뺀 것과 같은
|
|
22
|
+
* 이유다(주입을 빠뜨려도 아무 테스트가 안 깨지는 상황을 막는다).
|
|
23
|
+
*/
|
|
24
|
+
declare const unavailableReplayDependencies: ReplayCommandDependencies;
|
|
25
|
+
declare function run(argv: string[]): Promise<number>;
|
|
26
|
+
//#endregion
|
|
27
|
+
export { COMMANDS, Command, nodeRepairDependencies, run, unavailableReplayDependencies };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { FinalizeRunnerExecutionOptions, RunSuiteOptions, RunnerExecution, RunnerReport, SuiteValidationIssue, SuiteValidationResult, TestSuiteSpec } from "@mcpeak/runner";
|
|
2
|
+
import { Cassette } from "@mcpeak/record";
|
|
3
|
+
import { McpStdioConnection, ToolDef } from "@mcpeak/core";
|
|
4
|
+
import { AuthoringExecutionSnapshot, AuthoringSessionView, BaselineGenerationResult, PreFillProvider } from "@mcpeak/generate";
|
|
5
|
+
//#region src/generate-command.d.ts
|
|
6
|
+
interface GenerateCommandInput {
|
|
7
|
+
readonly suiteId: string;
|
|
8
|
+
readonly name: string;
|
|
9
|
+
readonly outPath: string;
|
|
10
|
+
readonly command: string;
|
|
11
|
+
readonly args: readonly string[];
|
|
12
|
+
readonly baselineOnly: boolean;
|
|
13
|
+
readonly provider?: "codex" | "claude";
|
|
14
|
+
readonly model?: string;
|
|
15
|
+
/** 승인 전 시험 실행 여부. 기본은 실행이고 `--no-dry-run` 이 끈다. 설계 문서 §4.3. */
|
|
16
|
+
readonly dryRun: boolean;
|
|
17
|
+
/** `--cassette` 경로. 없으면 서버를 직접 부른다. */
|
|
18
|
+
readonly cassettePath?: string;
|
|
19
|
+
/** `--record`. 카세트 파일이 있어도 새로 녹화한다. */
|
|
20
|
+
readonly forceRecord: boolean;
|
|
21
|
+
/** `--force`. `--out` 에 파일이 있으면 지우고 새로 쓴다. 설계 문서 §5. */
|
|
22
|
+
readonly force: boolean;
|
|
23
|
+
/** `--reset-cmd`. 시험 실행 직전 1회 실행한다. */
|
|
24
|
+
readonly resetCmd?: string;
|
|
25
|
+
/** 입력값 교정 단계를 돌릴지 여부. 기본은 실행이고 `--no-repair` 가 끈다. 설계 문서 §7. */
|
|
26
|
+
readonly repair: boolean;
|
|
27
|
+
}
|
|
28
|
+
interface GenerateCommandDependencies {
|
|
29
|
+
connect(options: {
|
|
30
|
+
command: string;
|
|
31
|
+
args: readonly string[];
|
|
32
|
+
}): Promise<McpStdioConnection>;
|
|
33
|
+
createBaselineSuite(tools: readonly ToolDef[], options: {
|
|
34
|
+
suiteId: string;
|
|
35
|
+
suiteName: string;
|
|
36
|
+
}): BaselineGenerationResult;
|
|
37
|
+
createAuthoringSession(baseline: BaselineGenerationResult, options?: {
|
|
38
|
+
readonly preFilledCaseIds?: readonly string[];
|
|
39
|
+
}): AuthoringSessionView;
|
|
40
|
+
finalizeAuthoringDraft(options: {
|
|
41
|
+
session: AuthoringSessionView;
|
|
42
|
+
approval: {
|
|
43
|
+
approved: boolean;
|
|
44
|
+
fingerprint: string;
|
|
45
|
+
};
|
|
46
|
+
}): {
|
|
47
|
+
finalized: true;
|
|
48
|
+
snapshot: AuthoringExecutionSnapshot;
|
|
49
|
+
} | {
|
|
50
|
+
finalized: false;
|
|
51
|
+
};
|
|
52
|
+
getAuthoringExecutionSuite(snapshot: AuthoringExecutionSnapshot): TestSuiteSpec;
|
|
53
|
+
validateSuite(value: unknown): SuiteValidationResult;
|
|
54
|
+
exists(path: string): Promise<boolean>;
|
|
55
|
+
openTemp(path: string): Promise<{
|
|
56
|
+
writeFile(data: string, encoding: "utf8"): Promise<void>;
|
|
57
|
+
sync(): Promise<void>;
|
|
58
|
+
close(): Promise<void>;
|
|
59
|
+
}>;
|
|
60
|
+
readFile(path: string): Promise<Uint8Array>;
|
|
61
|
+
/**
|
|
62
|
+
* 임시 파일을 최종 경로에 커밋한다. `rename`이 아니라 `link`인 것이 요점이다.
|
|
63
|
+
* `rename`은 대상이 있으면 말없이 덮어쓴다. `link`는 EEXIST로 실패하므로
|
|
64
|
+
* 원자성과 no-clobber를 동시에 얻는다. 덮어쓸 수 있는 primitive를 아예 두지 않는다.
|
|
65
|
+
*/
|
|
66
|
+
link(from: string, to: string): Promise<void>;
|
|
67
|
+
unlink(path: string): Promise<void>;
|
|
68
|
+
writeStdout(text: string): void;
|
|
69
|
+
writeStderr(text: string): void;
|
|
70
|
+
reviewIO?: ReviewIO;
|
|
71
|
+
providers?: Partial<Record<"codex" | "claude", (model: string) => TestAuthoringProvider | undefined>>;
|
|
72
|
+
/**
|
|
73
|
+
* 거절 근거 진단 통로 (#89 · 설계 문서 §6). `providers` 와 **따로 둔다.** 그쪽은
|
|
74
|
+
* `TestAuthoringProvider`(`author`)이고 이쪽은 `diagnoseRejection` 이라 다른 계약이다.
|
|
75
|
+
* `preFillProviders` 와 같은 선례다. 없으면 진단을 아예 묻지 않는다.
|
|
76
|
+
*/
|
|
77
|
+
rejectionProviders?: Partial<Record<"codex" | "claude", (model: string) => import("@mcpeak/generate").RejectionDiagnosisProvider | undefined>>;
|
|
78
|
+
prepareRejectionDiagnosisRequests?: typeof import("@mcpeak/generate").prepareRejectionDiagnosisRequests;
|
|
79
|
+
dispatchRejectionDiagnosis?: typeof import("@mcpeak/generate").dispatchRejectionDiagnosis;
|
|
80
|
+
prepareAuthoringRequest?: typeof import("@mcpeak/generate").prepareAuthoringRequest;
|
|
81
|
+
dispatchAuthoringRequest?: typeof import("@mcpeak/generate").dispatchAuthoringRequest;
|
|
82
|
+
createAuthoringDiff?: typeof import("@mcpeak/generate").createAuthoringDiff;
|
|
83
|
+
applyAuthoringChanges?: typeof import("@mcpeak/generate").applyAuthoringChanges;
|
|
84
|
+
reviewLocalAuthoringCandidate?: typeof import("@mcpeak/generate").reviewLocalAuthoringCandidate;
|
|
85
|
+
computeCoverage?: typeof import("@mcpeak/generate").computeCoverage;
|
|
86
|
+
/**
|
|
87
|
+
* AI 사전보완 통로. 넷 다 주입돼야 사전보완이 돈다. 하나라도 없으면 건너뛴다.
|
|
88
|
+
* 위 authoring 통로와 같은 이유로 값 import 가 아니라 주입이다.
|
|
89
|
+
*/
|
|
90
|
+
preparePreFillRequest?: typeof import("@mcpeak/generate").preparePreFillRequest;
|
|
91
|
+
previewPreFillRequest?: typeof import("@mcpeak/generate").previewPreFillRequest;
|
|
92
|
+
dispatchPreFillRequest?: typeof import("@mcpeak/generate").dispatchPreFillRequest;
|
|
93
|
+
preFillProviders?: Partial<Record<"codex" | "claude", (model: string) => PreFillProvider | undefined>>;
|
|
94
|
+
/**
|
|
95
|
+
* `instanceof` 용 클래스. 값 import 가 아니라 주입인 것이 요점이다.
|
|
96
|
+
*
|
|
97
|
+
* 이 파일은 `@mcpeak/generate` 에서 타입만 가져온다(위 `import type`). 클래스를 값으로
|
|
98
|
+
* 가져오면 `index.ts` 가 정적으로 끌어와 `test` 경로까지 `generate` 를 로드한다.
|
|
99
|
+
* `typeof import(...)` 는 타입 위치라 런타임 import 가 생기지 않고, 주입하면 클래스
|
|
100
|
+
* 동일성도 보장된다. 위 6개 필드가 같은 방식이다.
|
|
101
|
+
*/
|
|
102
|
+
GenerateTestsError?: typeof import("@mcpeak/generate").GenerateTestsError;
|
|
103
|
+
/**
|
|
104
|
+
* 카세트 파일 입출력. 주입점을 여기 하나만 두는 이유는 시험 실행 경로에서 파일시스템을
|
|
105
|
+
* 만지는 곳이 이것뿐이기 때문이다. 나머지(`runDryRun`·`reviewDryRun`)는 주입한 client 와
|
|
106
|
+
* io 만 쓰므로 테스트가 실제 구현을 그대로 돌린다.
|
|
107
|
+
*/
|
|
108
|
+
cassetteIo?: {
|
|
109
|
+
load(path: string): Promise<Cassette | null>;
|
|
110
|
+
save(path: string, cassette: Cassette): Promise<void>;
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
interface ReviewIO {
|
|
114
|
+
input(message: string): Promise<string>;
|
|
115
|
+
choose(message: string, choices: readonly string[]): Promise<string>;
|
|
116
|
+
confirm(message: string): Promise<boolean>;
|
|
117
|
+
write(text: string): void;
|
|
118
|
+
readonly interactive: boolean;
|
|
119
|
+
close?(): void;
|
|
120
|
+
}
|
|
121
|
+
type TestAuthoringProvider = import("@mcpeak/generate").TestAuthoringProvider;
|
|
122
|
+
declare function runGenerateCommand(argv: readonly string[], deps: GenerateCommandDependencies): Promise<number>;
|
|
123
|
+
declare const nodeGenerateDependencies: () => Omit<GenerateCommandDependencies, "connect" | "createBaselineSuite" | "createAuthoringSession" | "finalizeAuthoringDraft" | "getAuthoringExecutionSuite" | "validateSuite">;
|
|
124
|
+
declare function nodeReviewIO(input?: NodeJS.ReadableStream, output?: NodeJS.WritableStream): ReviewIO;
|
|
125
|
+
//#endregion
|
|
126
|
+
//#region src/repair-command.d.ts
|
|
127
|
+
interface RepairCommandInput {
|
|
128
|
+
readonly bundlePath: string;
|
|
129
|
+
readonly providerId: "codex" | "claude";
|
|
130
|
+
readonly model: string;
|
|
131
|
+
readonly yes: boolean;
|
|
132
|
+
readonly includeStderr: boolean;
|
|
133
|
+
readonly maxCases: number;
|
|
134
|
+
}
|
|
135
|
+
interface RepairCommandDependencies {
|
|
136
|
+
readFile(path: string): Promise<string>;
|
|
137
|
+
writeStdout(text: string): void;
|
|
138
|
+
writeStderr(text: string): void;
|
|
139
|
+
/** 전송 확인 화면. 없으면 비대화형으로 본다. `generate` 가 쓰는 그 인터페이스다. */
|
|
140
|
+
readonly reviewIO?: ReviewIO;
|
|
141
|
+
/**
|
|
142
|
+
* 진단 통로. `@mcpeak/generate` 를 값으로 import 하지 않고 주입받는다. 정적으로 import 하면
|
|
143
|
+
* `test` 경로가 `generate` 를 함께 로드한다. 계획서 §8 위험표 첫 줄이다.
|
|
144
|
+
*/
|
|
145
|
+
readonly diagnosis?: {
|
|
146
|
+
readonly prepare: typeof import("@mcpeak/generate").prepareDiagnosisRequest;
|
|
147
|
+
readonly dispatch: typeof import("@mcpeak/generate").dispatchDiagnosisRequest;
|
|
148
|
+
readonly providers: {
|
|
149
|
+
readonly codex: (model: string) => import("@mcpeak/generate").ServerDiagnosisProvider;
|
|
150
|
+
readonly claude: (model: string) => import("@mcpeak/generate").ServerDiagnosisProvider;
|
|
151
|
+
};
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
declare function parseRepairCommand(argv: readonly string[]): RepairCommandInput;
|
|
155
|
+
/**
|
|
156
|
+
* `repair` 명령. 번들을 읽고, 전송 내용을 확인받고, provider 에게 진단을 물어 화면에 찍는다.
|
|
157
|
+
* 파일도 명세도 고치지 않는다. 종료 코드는 운영 실패에만 1 이다(설계서 §7.1).
|
|
158
|
+
*/
|
|
159
|
+
declare function runRepairCommand(argv: readonly string[], deps: RepairCommandDependencies): Promise<number>;
|
|
160
|
+
//#endregion
|
|
161
|
+
//#region src/replay-command.d.ts
|
|
162
|
+
interface ReplayCommandInput {
|
|
163
|
+
readonly suitePath: string;
|
|
164
|
+
readonly cassettePath: string;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* `connect` 가 없다. replay 가 서버를 띄우지 않는다는 것이 주석이 아니라 타입에 드러난다.
|
|
168
|
+
* ADR-0028.
|
|
169
|
+
*/
|
|
170
|
+
interface ReplayCommandDependencies {
|
|
171
|
+
readFile(path: string): Promise<Uint8Array>;
|
|
172
|
+
validateSuite(input: unknown): SuiteValidationResult;
|
|
173
|
+
loadCassette(path: string): Promise<Cassette | null>;
|
|
174
|
+
startRunner(options: RunSuiteOptions): RunnerExecution;
|
|
175
|
+
finalize(options: FinalizeRunnerExecutionOptions): Promise<RunnerReport>;
|
|
176
|
+
renderReport(report: RunnerReport, options?: {
|
|
177
|
+
color?: boolean;
|
|
178
|
+
}): string;
|
|
179
|
+
colorEnabled: boolean;
|
|
180
|
+
writeStdout(text: string): void;
|
|
181
|
+
writeStderr(text: string): void;
|
|
182
|
+
}
|
|
183
|
+
declare function parseReplayCommand(argv: readonly string[]): ReplayCommandInput;
|
|
184
|
+
declare function runReplayCommand(argv: readonly string[], dependencies: ReplayCommandDependencies): Promise<number>;
|
|
185
|
+
//#endregion
|
|
186
|
+
export { RepairCommandDependencies as a, runRepairCommand as c, ReviewIO as d, nodeGenerateDependencies as f, runReplayCommand as i, GenerateCommandDependencies as l, runGenerateCommand as m, ReplayCommandInput as n, RepairCommandInput as o, nodeReviewIO as p, parseReplayCommand as r, parseRepairCommand as s, ReplayCommandDependencies as t, GenerateCommandInput as u };
|