pi-cicd 0.1.1 → 0.3.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/README.md +62 -0
- package/dist/ci/pipeline.d.ts +43 -0
- package/dist/ci/pipeline.d.ts.map +1 -0
- package/dist/ci/pipeline.js +107 -0
- package/dist/ci/pipeline.js.map +1 -0
- package/dist/ci/pr-creator.d.ts +17 -0
- package/dist/ci/pr-creator.d.ts.map +1 -0
- package/dist/ci/pr-creator.js +67 -0
- package/dist/ci/pr-creator.js.map +1 -0
- package/dist/ci/report.d.ts +14 -0
- package/dist/ci/report.d.ts.map +1 -0
- package/dist/ci/report.js +51 -0
- package/dist/ci/report.js.map +1 -0
- package/dist/ci/test-runner.d.ts +10 -0
- package/dist/ci/test-runner.d.ts.map +1 -0
- package/dist/ci/test-runner.js +111 -0
- package/dist/ci/test-runner.js.map +1 -0
- package/dist/config.d.ts +33 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +67 -0
- package/dist/config.js.map +1 -0
- package/dist/deploy/canary-deploy.d.ts +80 -0
- package/dist/deploy/canary-deploy.d.ts.map +1 -0
- package/dist/deploy/canary-deploy.js +145 -0
- package/dist/deploy/canary-deploy.js.map +1 -0
- package/dist/deploy/landing-queue.d.ts +83 -0
- package/dist/deploy/landing-queue.d.ts.map +1 -0
- package/dist/deploy/landing-queue.js +172 -0
- package/dist/deploy/landing-queue.js.map +1 -0
- package/dist/headless/answer-injector.d.ts +27 -0
- package/dist/headless/answer-injector.d.ts.map +1 -0
- package/dist/headless/answer-injector.js +80 -0
- package/dist/headless/answer-injector.js.map +1 -0
- package/dist/headless/exit-codes.d.ts +13 -0
- package/dist/headless/exit-codes.d.ts.map +1 -0
- package/dist/headless/exit-codes.js +29 -0
- package/dist/headless/exit-codes.js.map +1 -0
- package/dist/headless/idle-detector.d.ts +32 -0
- package/dist/headless/idle-detector.d.ts.map +1 -0
- package/dist/headless/idle-detector.js +62 -0
- package/dist/headless/idle-detector.js.map +1 -0
- package/dist/headless/jsonl-stream.d.ts +28 -0
- package/dist/headless/jsonl-stream.d.ts.map +1 -0
- package/dist/headless/jsonl-stream.js +65 -0
- package/dist/headless/jsonl-stream.js.map +1 -0
- package/dist/headless/orchestrator.d.ts +63 -0
- package/dist/headless/orchestrator.d.ts.map +1 -0
- package/dist/headless/orchestrator.js +156 -0
- package/dist/headless/orchestrator.js.map +1 -0
- package/{index.ts → dist/index.d.ts} +4 -26
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/ci_status.d.ts +40 -0
- package/dist/tools/ci_status.d.ts.map +1 -0
- package/dist/tools/ci_status.js +110 -0
- package/dist/tools/ci_status.js.map +1 -0
- package/dist/types.d.ts +93 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +17 -0
- package/dist/types.js.map +1 -0
- package/dist/workflow/deployment-workflow.d.ts +56 -0
- package/dist/workflow/deployment-workflow.d.ts.map +1 -0
- package/dist/workflow/deployment-workflow.js +95 -0
- package/dist/workflow/deployment-workflow.js.map +1 -0
- package/package.json +26 -26
- package/AGENTS.md +0 -25
- package/src/ci/pipeline.ts +0 -130
- package/src/ci/pr-creator.ts +0 -74
- package/src/ci/report.ts +0 -65
- package/src/ci/test-runner.ts +0 -129
- package/src/config.ts +0 -99
- package/src/headless/answer-injector.ts +0 -98
- package/src/headless/exit-codes.ts +0 -32
- package/src/headless/idle-detector.ts +0 -76
- package/src/headless/jsonl-stream.ts +0 -90
- package/src/headless/orchestrator.ts +0 -206
- package/src/tools/ci_status.ts +0 -137
- package/src/types.ts +0 -149
- package/tsconfig.json +0 -19
package/README.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# pi-cicd
|
|
2
|
+
|
|
3
|
+
CI/CD workflow automation and deployment extension for coding agents.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Deployment Workflow** - Declarative deployment with stages
|
|
8
|
+
- **Canary Deployment** - Gradual rollout with traffic shifting
|
|
9
|
+
- **Landing Queue** - Managed deployment queue with backoff
|
|
10
|
+
- **Test Runner** - Automated test execution and reporting
|
|
11
|
+
- **PR Creator** - Automated pull request generation
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install pi-cicd
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
### Commands
|
|
22
|
+
|
|
23
|
+
- `/deploy [env]` - Deploy to specified environment
|
|
24
|
+
- `/canary [percentage]` - Start canary deployment
|
|
25
|
+
- `/rollback` - Rollback to previous version
|
|
26
|
+
- `/pr [type]` - Create pull request
|
|
27
|
+
|
|
28
|
+
### Deployment Workflow
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { createDeploymentWorkflow } from 'pi-cicd';
|
|
32
|
+
|
|
33
|
+
const workflow = createDeploymentWorkflow({
|
|
34
|
+
stages: ['build', 'test', 'staging', 'production'],
|
|
35
|
+
canary: { initial: 10, increment: 20, interval: 60000 },
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Architecture
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
src/
|
|
43
|
+
├── deploy/
|
|
44
|
+
│ ├── canary-deploy.ts # Canary deployment
|
|
45
|
+
│ └── landing-queue.ts # Deployment queue
|
|
46
|
+
├── workflow/
|
|
47
|
+
│ └── deployment-workflow.ts
|
|
48
|
+
├── automation/
|
|
49
|
+
│ ├── pr-creator.ts # PR generation
|
|
50
|
+
│ └── pipeline.ts # Pipeline automation
|
|
51
|
+
└── index.ts
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Patterns Applied
|
|
55
|
+
|
|
56
|
+
- DeploymentWorkflow from pi-crew
|
|
57
|
+
- LandingQueue from gstack
|
|
58
|
+
- Pipeline automation from vetc-dev-kit
|
|
59
|
+
|
|
60
|
+
## License
|
|
61
|
+
|
|
62
|
+
MIT
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pi-ci — CI pipeline wrapper.
|
|
3
|
+
*
|
|
4
|
+
* Provides single, plan, review, and supervised execution modes.
|
|
5
|
+
*/
|
|
6
|
+
import type { CIEvent, CIOptions, ExitCode, TestSummary } from "../types.ts";
|
|
7
|
+
import { type OrchestratorHooks } from "../headless/orchestrator.ts";
|
|
8
|
+
export interface PipelineResult {
|
|
9
|
+
exitCode: ExitCode;
|
|
10
|
+
events: CIEvent[];
|
|
11
|
+
report: string;
|
|
12
|
+
testSummary?: TestSummary;
|
|
13
|
+
}
|
|
14
|
+
export declare class CIPipeline {
|
|
15
|
+
private readonly options;
|
|
16
|
+
private readonly hooks;
|
|
17
|
+
constructor(options: CIOptions, hooks: OrchestratorHooks);
|
|
18
|
+
/**
|
|
19
|
+
* Execute the pipeline in the configured mode.
|
|
20
|
+
*/
|
|
21
|
+
execute(): Promise<PipelineResult>;
|
|
22
|
+
/**
|
|
23
|
+
* Single task mode — run one prompt to completion.
|
|
24
|
+
*/
|
|
25
|
+
private executeSingle;
|
|
26
|
+
/**
|
|
27
|
+
* Plan mode — execute steps from a plan file.
|
|
28
|
+
*
|
|
29
|
+
* Each step becomes a sequential orchestrator invocation. If any step fails,
|
|
30
|
+
* the pipeline stops.
|
|
31
|
+
*/
|
|
32
|
+
private executePlan;
|
|
33
|
+
/**
|
|
34
|
+
* PR review mode — review a PR by number.
|
|
35
|
+
*/
|
|
36
|
+
private executeReview;
|
|
37
|
+
/**
|
|
38
|
+
* Supervised mode — stdin/stdout forwarding for an external orchestrator.
|
|
39
|
+
*/
|
|
40
|
+
private executeSupervised;
|
|
41
|
+
private loadAnswers;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/ci/pipeline.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAkB,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE7F,OAAO,EAAwB,KAAK,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAK3F,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,OAAO,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAY;IACpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;gBAE9B,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,iBAAiB;IAKxD;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,cAAc,CAAC;IAexC;;OAEG;YACW,aAAa;IAY3B;;;;;OAKG;YACW,WAAW;IAsBzB;;OAEG;YACW,aAAa;IAe3B;;OAEG;YACW,iBAAiB;YAYjB,WAAW;CAM1B"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pi-ci — CI pipeline wrapper.
|
|
3
|
+
*
|
|
4
|
+
* Provides single, plan, review, and supervised execution modes.
|
|
5
|
+
*/
|
|
6
|
+
import { EXIT_CODES } from "../types.ts";
|
|
7
|
+
import { HeadlessOrchestrator } from "../headless/orchestrator.ts";
|
|
8
|
+
import { loadAnswers } from "../headless/answer-injector.ts";
|
|
9
|
+
import { generateReport } from "./report.ts";
|
|
10
|
+
export class CIPipeline {
|
|
11
|
+
options;
|
|
12
|
+
hooks;
|
|
13
|
+
constructor(options, hooks) {
|
|
14
|
+
this.options = options;
|
|
15
|
+
this.hooks = hooks;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Execute the pipeline in the configured mode.
|
|
19
|
+
*/
|
|
20
|
+
async execute() {
|
|
21
|
+
switch (this.options.mode) {
|
|
22
|
+
case "single":
|
|
23
|
+
return this.executeSingle();
|
|
24
|
+
case "plan":
|
|
25
|
+
return this.executePlan();
|
|
26
|
+
case "review":
|
|
27
|
+
return this.executeReview();
|
|
28
|
+
case "supervised":
|
|
29
|
+
return this.executeSupervised();
|
|
30
|
+
default:
|
|
31
|
+
throw new Error(`Unknown CI pipeline mode: ${this.options.mode}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Single task mode — run one prompt to completion.
|
|
36
|
+
*/
|
|
37
|
+
async executeSingle() {
|
|
38
|
+
const answers = await this.loadAnswers();
|
|
39
|
+
const orchestrator = new HeadlessOrchestrator(answers, this.options, this.hooks);
|
|
40
|
+
const result = await orchestrator.run(this.options.prompt, "single");
|
|
41
|
+
return {
|
|
42
|
+
exitCode: result.exitCode,
|
|
43
|
+
events: result.events,
|
|
44
|
+
report: generateReport(result.events),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Plan mode — execute steps from a plan file.
|
|
49
|
+
*
|
|
50
|
+
* Each step becomes a sequential orchestrator invocation. If any step fails,
|
|
51
|
+
* the pipeline stops.
|
|
52
|
+
*/
|
|
53
|
+
async executePlan() {
|
|
54
|
+
const allEvents = [];
|
|
55
|
+
let finalExitCode = EXIT_CODES.SUCCESS;
|
|
56
|
+
let totalDuration = 0;
|
|
57
|
+
// Plan steps are provided via the executeStep hook — the orchestrator
|
|
58
|
+
// iterates over steps internally.
|
|
59
|
+
const answers = await this.loadAnswers();
|
|
60
|
+
const orchestrator = new HeadlessOrchestrator(answers, this.options, this.hooks);
|
|
61
|
+
const result = await orchestrator.run(this.options.prompt, "plan");
|
|
62
|
+
allEvents.push(...result.events);
|
|
63
|
+
finalExitCode = result.exitCode;
|
|
64
|
+
totalDuration = result.durationMs;
|
|
65
|
+
return {
|
|
66
|
+
exitCode: finalExitCode,
|
|
67
|
+
events: allEvents,
|
|
68
|
+
report: generateReport(allEvents),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* PR review mode — review a PR by number.
|
|
73
|
+
*/
|
|
74
|
+
async executeReview() {
|
|
75
|
+
const answers = await this.loadAnswers();
|
|
76
|
+
const orchestrator = new HeadlessOrchestrator(answers, this.options, this.hooks);
|
|
77
|
+
const prompt = this.options.prNumber
|
|
78
|
+
? `Review PR #${this.options.prNumber}`
|
|
79
|
+
: this.options.prompt;
|
|
80
|
+
const result = await orchestrator.run(prompt, "single");
|
|
81
|
+
return {
|
|
82
|
+
exitCode: result.exitCode,
|
|
83
|
+
events: result.events,
|
|
84
|
+
report: generateReport(result.events),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Supervised mode — stdin/stdout forwarding for an external orchestrator.
|
|
89
|
+
*/
|
|
90
|
+
async executeSupervised() {
|
|
91
|
+
const answers = await this.loadAnswers();
|
|
92
|
+
const orchestrator = new HeadlessOrchestrator(answers, this.options, this.hooks);
|
|
93
|
+
const result = await orchestrator.run(this.options.prompt, "single");
|
|
94
|
+
return {
|
|
95
|
+
exitCode: result.exitCode,
|
|
96
|
+
events: result.events,
|
|
97
|
+
report: generateReport(result.events),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
async loadAnswers() {
|
|
101
|
+
if (this.options.answersFile) {
|
|
102
|
+
return loadAnswers(this.options.answersFile);
|
|
103
|
+
}
|
|
104
|
+
return [];
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/ci/pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pi-ci — PR creation via the GitHub CLI (`gh`).
|
|
3
|
+
*
|
|
4
|
+
* Wraps `gh pr create` with structured error handling.
|
|
5
|
+
*/
|
|
6
|
+
import type { PROptions, PRResult } from "../types.ts";
|
|
7
|
+
/**
|
|
8
|
+
* Create a pull request using the `gh` CLI.
|
|
9
|
+
*
|
|
10
|
+
* Throws if `gh` is not installed or the command fails.
|
|
11
|
+
*/
|
|
12
|
+
export declare function createPR(options: PROptions): Promise<PRResult>;
|
|
13
|
+
/**
|
|
14
|
+
* Detect the default (base) branch for the current repository.
|
|
15
|
+
*/
|
|
16
|
+
export declare function detectBaseBranch(): Promise<string>;
|
|
17
|
+
//# sourceMappingURL=pr-creator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr-creator.d.ts","sourceRoot":"","sources":["../../src/ci/pr-creator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvD;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,CA+BpE;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,CAGxD"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pi-ci — PR creation via the GitHub CLI (`gh`).
|
|
3
|
+
*
|
|
4
|
+
* Wraps `gh pr create` with structured error handling.
|
|
5
|
+
*/
|
|
6
|
+
import { execFile } from "node:child_process";
|
|
7
|
+
/**
|
|
8
|
+
* Create a pull request using the `gh` CLI.
|
|
9
|
+
*
|
|
10
|
+
* Throws if `gh` is not installed or the command fails.
|
|
11
|
+
*/
|
|
12
|
+
export async function createPR(options) {
|
|
13
|
+
const args = ["pr", "create", "--title", options.title];
|
|
14
|
+
if (options.body) {
|
|
15
|
+
args.push("--body", options.body);
|
|
16
|
+
}
|
|
17
|
+
if (options.base) {
|
|
18
|
+
args.push("--base", options.base);
|
|
19
|
+
}
|
|
20
|
+
if (options.head) {
|
|
21
|
+
args.push("--head", options.head);
|
|
22
|
+
}
|
|
23
|
+
if (options.draft) {
|
|
24
|
+
args.push("--draft");
|
|
25
|
+
}
|
|
26
|
+
for (const label of options.labels ?? []) {
|
|
27
|
+
args.push("--label", label);
|
|
28
|
+
}
|
|
29
|
+
const output = await runGh(args);
|
|
30
|
+
// Parse the PR URL from the output
|
|
31
|
+
const urlMatch = output.match(/https:\/\/github\.com\/[^\s]+\/pull\/(\d+)/);
|
|
32
|
+
if (!urlMatch) {
|
|
33
|
+
throw new Error(`Failed to parse PR URL from gh output: ${output}`);
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
url: urlMatch[0],
|
|
37
|
+
number: parseInt(urlMatch[1], 10),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Detect the default (base) branch for the current repository.
|
|
42
|
+
*/
|
|
43
|
+
export async function detectBaseBranch() {
|
|
44
|
+
const output = await runGh(["repo", "view", "--json", "defaultBranchRef", "--jq", ".defaultBranchRef.name"]);
|
|
45
|
+
return output.trim() || "main";
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Execute a `gh` command and return stdout.
|
|
49
|
+
*/
|
|
50
|
+
function runGh(args) {
|
|
51
|
+
return new Promise((resolve, reject) => {
|
|
52
|
+
execFile("gh", args, { timeout: 60_000 }, (err, stdout, stderr) => {
|
|
53
|
+
if (err) {
|
|
54
|
+
const message = stderr?.trim() || err.message;
|
|
55
|
+
if (err.code === "ENOENT") {
|
|
56
|
+
reject(new Error("gh CLI is not installed. Install it from https://cli.github.com"));
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
reject(new Error(`gh ${args.join(" ")} failed: ${message}`));
|
|
60
|
+
}
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
resolve(stdout);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=pr-creator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pr-creator.js","sourceRoot":"","sources":["../../src/ci/pr-creator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG9C;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,OAAkB;IAC/C,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAExD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACvB,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;IAEjC,mCAAmC;IACnC,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAC5E,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,0CAA0C,MAAM,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,OAAO;QACL,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;QAChB,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;KAClC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,EAAE,wBAAwB,CAAC,CAAC,CAAC;IAC7G,OAAO,MAAM,CAAC,IAAI,EAAE,IAAI,MAAM,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,SAAS,KAAK,CAAC,IAAc;IAC3B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YAChE,IAAI,GAAG,EAAE,CAAC;gBACR,MAAM,OAAO,GAAG,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,OAAO,CAAC;gBAC9C,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC1B,MAAM,CAAC,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC,CAAC;gBACvF,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,OAAO,EAAE,CAAC,CAAC,CAAC;gBAC/D,CAAC;gBACD,OAAO;YACT,CAAC;YACD,OAAO,CAAC,MAAM,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pi-ci — CI report generation.
|
|
3
|
+
*
|
|
4
|
+
* Produces JSONL or human-readable summary reports from collected CI events.
|
|
5
|
+
*/
|
|
6
|
+
import type { CIEvent } from "../types.ts";
|
|
7
|
+
export interface ReportOptions {
|
|
8
|
+
format: "jsonl" | "summary";
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Generate a report from a list of CI events.
|
|
12
|
+
*/
|
|
13
|
+
export declare function generateReport(events: CIEvent[], options?: ReportOptions): string;
|
|
14
|
+
//# sourceMappingURL=report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/ci/report.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAwC,MAAM,aAAa,CAAC;AAGjF,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM,CASjF"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pi-ci — CI report generation.
|
|
3
|
+
*
|
|
4
|
+
* Produces JSONL or human-readable summary reports from collected CI events.
|
|
5
|
+
*/
|
|
6
|
+
import { isCIEndEvent, isCICostEvent, isCITestEvent } from "../headless/jsonl-stream.ts";
|
|
7
|
+
/**
|
|
8
|
+
* Generate a report from a list of CI events.
|
|
9
|
+
*/
|
|
10
|
+
export function generateReport(events, options) {
|
|
11
|
+
const format = options?.format ?? "jsonl";
|
|
12
|
+
if (format === "summary") {
|
|
13
|
+
return generateSummary(events);
|
|
14
|
+
}
|
|
15
|
+
// JSONL: one event per line
|
|
16
|
+
return events.map((e) => JSON.stringify(e)).join("\n");
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Generate a human-readable summary.
|
|
20
|
+
*/
|
|
21
|
+
function generateSummary(events) {
|
|
22
|
+
const lines = ["=== CI Run Summary ===", ""];
|
|
23
|
+
let totalTestsPassed = 0;
|
|
24
|
+
let totalTestsFailed = 0;
|
|
25
|
+
let totalCostUsd = 0;
|
|
26
|
+
let exitCode = -1;
|
|
27
|
+
let durationMs = 0;
|
|
28
|
+
for (const event of events) {
|
|
29
|
+
if (isCITestEvent(event)) {
|
|
30
|
+
totalTestsPassed += event.passed;
|
|
31
|
+
totalTestsFailed += event.failed;
|
|
32
|
+
}
|
|
33
|
+
if (isCICostEvent(event)) {
|
|
34
|
+
totalCostUsd += event.cost_usd;
|
|
35
|
+
}
|
|
36
|
+
if (isCIEndEvent(event)) {
|
|
37
|
+
exitCode = event.exit_code;
|
|
38
|
+
durationMs = event.duration_ms;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
lines.push(`Exit Code: ${exitCode}`);
|
|
42
|
+
lines.push(`Duration: ${(durationMs / 1000).toFixed(1)}s`);
|
|
43
|
+
lines.push(`Tests: ${totalTestsPassed} passed, ${totalTestsFailed} failed`);
|
|
44
|
+
if (totalCostUsd > 0) {
|
|
45
|
+
lines.push(`Cost: $${totalCostUsd.toFixed(4)}`);
|
|
46
|
+
}
|
|
47
|
+
const status = exitCode === 0 ? "SUCCESS" : exitCode === 10 ? "BLOCKED" : exitCode === 11 ? "CANCELLED" : "ERROR";
|
|
48
|
+
lines.push(`Status: ${status}`);
|
|
49
|
+
return lines.join("\n");
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/ci/report.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAMzF;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,MAAiB,EAAE,OAAuB;IACvE,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,OAAO,CAAC;IAE1C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IAED,4BAA4B;IAC5B,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzD,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,MAAiB;IACxC,MAAM,KAAK,GAAa,CAAC,wBAAwB,EAAE,EAAE,CAAC,CAAC;IAEvD,IAAI,gBAAgB,GAAG,CAAC,CAAC;IACzB,IAAI,gBAAgB,GAAG,CAAC,CAAC;IACzB,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,IAAI,QAAQ,GAAG,CAAC,CAAC,CAAC;IAClB,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,gBAAgB,IAAI,KAAK,CAAC,MAAM,CAAC;YACjC,gBAAgB,IAAI,KAAK,CAAC,MAAM,CAAC;QACnC,CAAC;QACD,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,YAAY,IAAI,KAAK,CAAC,QAAQ,CAAC;QACjC,CAAC;QACD,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;YACxB,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC;YAC3B,UAAU,GAAG,KAAK,CAAC,WAAW,CAAC;QACjC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,cAAc,QAAQ,EAAE,CAAC,CAAC;IACrC,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC5D,KAAK,CAAC,IAAI,CAAC,cAAc,gBAAgB,YAAY,gBAAgB,SAAS,CAAC,CAAC;IAChF,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,eAAe,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,MAAM,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC;IAClH,KAAK,CAAC,IAAI,CAAC,cAAc,MAAM,EAAE,CAAC,CAAC;IAEnC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pi-ci — Test result parsing for TAP, Jest, and Vitest output formats.
|
|
3
|
+
*/
|
|
4
|
+
import type { TestSummary } from "../types.ts";
|
|
5
|
+
export type TestOutputFormat = "tap" | "jest" | "vitest";
|
|
6
|
+
/**
|
|
7
|
+
* Parse test output and return a summary.
|
|
8
|
+
*/
|
|
9
|
+
export declare function parseTestResults(output: string, format: TestOutputFormat): TestSummary;
|
|
10
|
+
//# sourceMappingURL=test-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-runner.d.ts","sourceRoot":"","sources":["../../src/ci/test-runner.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEzD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,WAAW,CAetF"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pi-ci — Test result parsing for TAP, Jest, and Vitest output formats.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Parse test output and return a summary.
|
|
6
|
+
*/
|
|
7
|
+
export function parseTestResults(output, format) {
|
|
8
|
+
if (!output || !output.trim()) {
|
|
9
|
+
return { passed: 0, failed: 0, total: 0, duration_ms: 0 };
|
|
10
|
+
}
|
|
11
|
+
switch (format) {
|
|
12
|
+
case "tap":
|
|
13
|
+
return parseTap(output);
|
|
14
|
+
case "jest":
|
|
15
|
+
return parseJest(output);
|
|
16
|
+
case "vitest":
|
|
17
|
+
return parseVitest(output);
|
|
18
|
+
default:
|
|
19
|
+
return { passed: 0, failed: 0, total: 0, duration_ms: 0 };
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Parse TAP (Test Anything Protocol) output.
|
|
24
|
+
*
|
|
25
|
+
* Example:
|
|
26
|
+
* 1..5
|
|
27
|
+
* ok 1 - first test
|
|
28
|
+
* not ok 2 - failing test
|
|
29
|
+
* ok 3 - third test
|
|
30
|
+
*/
|
|
31
|
+
function parseTap(output) {
|
|
32
|
+
let passed = 0;
|
|
33
|
+
let failed = 0;
|
|
34
|
+
const lines = output.split("\n");
|
|
35
|
+
for (const line of lines) {
|
|
36
|
+
const trimmed = line.trim();
|
|
37
|
+
if (trimmed.startsWith("ok ")) {
|
|
38
|
+
passed++;
|
|
39
|
+
}
|
|
40
|
+
else if (trimmed.startsWith("not ok ")) {
|
|
41
|
+
failed++;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
passed,
|
|
46
|
+
failed,
|
|
47
|
+
total: passed + failed,
|
|
48
|
+
duration_ms: 0, // TAP doesn't have standard duration
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Parse Jest-style test output.
|
|
53
|
+
*
|
|
54
|
+
* Looks for patterns like:
|
|
55
|
+
* Tests: 5 passed, 2 failed, 7 total
|
|
56
|
+
* Time: 3.456 s
|
|
57
|
+
*/
|
|
58
|
+
function parseJest(output) {
|
|
59
|
+
let passed = 0;
|
|
60
|
+
let failed = 0;
|
|
61
|
+
let total = 0;
|
|
62
|
+
let durationMs = 0;
|
|
63
|
+
// Match test summary line
|
|
64
|
+
const testMatch = output.match(/Tests:\s*(\d+)\s*passed(?:,\s*(\d+)\s*failed)?(?:,\s*(\d+)\s*total)?/);
|
|
65
|
+
if (testMatch) {
|
|
66
|
+
passed = parseInt(testMatch[1], 10);
|
|
67
|
+
failed = parseInt(testMatch[2] || "0", 10);
|
|
68
|
+
total = parseInt(testMatch[3] || String(passed + failed), 10);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// Fallback: count individual test lines
|
|
72
|
+
const passMatches = output.match(/✓|PASS/g);
|
|
73
|
+
const failMatches = output.match(/✕|FAIL/g);
|
|
74
|
+
passed = passMatches?.length ?? 0;
|
|
75
|
+
failed = failMatches?.length ?? 0;
|
|
76
|
+
total = passed + failed;
|
|
77
|
+
}
|
|
78
|
+
// Match time
|
|
79
|
+
const timeMatch = output.match(/Time:\s*([\d.]+)\s*s/);
|
|
80
|
+
if (timeMatch) {
|
|
81
|
+
durationMs = Math.round(parseFloat(timeMatch[1]) * 1000);
|
|
82
|
+
}
|
|
83
|
+
return { passed, failed, total, duration_ms: durationMs };
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Parse Vitest-style test output.
|
|
87
|
+
*
|
|
88
|
+
* Looks for patterns like:
|
|
89
|
+
* Tests 5 passed | 2 failed (7)
|
|
90
|
+
* Duration 3.45s
|
|
91
|
+
*/
|
|
92
|
+
function parseVitest(output) {
|
|
93
|
+
let passed = 0;
|
|
94
|
+
let failed = 0;
|
|
95
|
+
let total = 0;
|
|
96
|
+
let durationMs = 0;
|
|
97
|
+
// Match test summary line: "Tests 5 passed | 2 failed (7)"
|
|
98
|
+
const testMatch = output.match(/Tests\s+(\d+)\s+passed(?:\s*\|\s*(\d+)\s+failed)?(?:\s*\((\d+)\))?/);
|
|
99
|
+
if (testMatch) {
|
|
100
|
+
passed = parseInt(testMatch[1], 10);
|
|
101
|
+
failed = parseInt(testMatch[2] || "0", 10);
|
|
102
|
+
total = parseInt(testMatch[3] || String(passed + failed), 10);
|
|
103
|
+
}
|
|
104
|
+
// Match duration: "Duration 3.45s"
|
|
105
|
+
const durMatch = output.match(/Duration\s+([\d.]+)s/);
|
|
106
|
+
if (durMatch) {
|
|
107
|
+
durationMs = Math.round(parseFloat(durMatch[1]) * 1000);
|
|
108
|
+
}
|
|
109
|
+
return { passed, failed, total, duration_ms: durationMs };
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=test-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-runner.js","sourceRoot":"","sources":["../../src/ci/test-runner.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pi-ci — Configuration loading and defaults.
|
|
3
|
+
*
|
|
4
|
+
* Reads `.pi/pi-ci.json` from the given directory (or cwd) and merges with defaults.
|
|
5
|
+
*/
|
|
6
|
+
export interface PiCiReportConfig {
|
|
7
|
+
format: "jsonl" | "summary";
|
|
8
|
+
includeCost: boolean;
|
|
9
|
+
includeEdits: boolean;
|
|
10
|
+
includeTests: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface PiCiExitCodeConfig {
|
|
13
|
+
success: number;
|
|
14
|
+
error: number;
|
|
15
|
+
blocked: number;
|
|
16
|
+
cancelled: number;
|
|
17
|
+
needsInput: number;
|
|
18
|
+
}
|
|
19
|
+
export interface PiCiConfig {
|
|
20
|
+
enabled: boolean;
|
|
21
|
+
idleTimeoutMs: number;
|
|
22
|
+
maxRetries: number;
|
|
23
|
+
retryBackoffMaxMs: number;
|
|
24
|
+
exitCodes: PiCiExitCodeConfig;
|
|
25
|
+
report: PiCiReportConfig;
|
|
26
|
+
}
|
|
27
|
+
declare const DEFAULT_CONFIG: PiCiConfig;
|
|
28
|
+
/**
|
|
29
|
+
* Load pi-ci configuration from `.pi/pi-ci.json` (if present) merged with defaults.
|
|
30
|
+
*/
|
|
31
|
+
export declare function loadCiConfig(cwd?: string): Promise<PiCiConfig>;
|
|
32
|
+
export { DEFAULT_CONFIG };
|
|
33
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,kBAAkB,CAAC;IAC9B,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED,QAAA,MAAM,cAAc,EAAE,UAkBrB,CAAC;AAEF;;GAEG;AACH,wBAAsB,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAwCpE;AAED,OAAO,EAAE,cAAc,EAAE,CAAC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pi-ci — Configuration loading and defaults.
|
|
3
|
+
*
|
|
4
|
+
* Reads `.pi/pi-ci.json` from the given directory (or cwd) and merges with defaults.
|
|
5
|
+
*/
|
|
6
|
+
import { readFile } from "node:fs/promises";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
const DEFAULT_CONFIG = {
|
|
9
|
+
enabled: true,
|
|
10
|
+
idleTimeoutMs: 15_000,
|
|
11
|
+
maxRetries: 3,
|
|
12
|
+
retryBackoffMaxMs: 30_000,
|
|
13
|
+
exitCodes: {
|
|
14
|
+
success: 0,
|
|
15
|
+
error: 1,
|
|
16
|
+
blocked: 10,
|
|
17
|
+
cancelled: 11,
|
|
18
|
+
needsInput: 12,
|
|
19
|
+
},
|
|
20
|
+
report: {
|
|
21
|
+
format: "jsonl",
|
|
22
|
+
includeCost: true,
|
|
23
|
+
includeEdits: true,
|
|
24
|
+
includeTests: true,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Load pi-ci configuration from `.pi/pi-ci.json` (if present) merged with defaults.
|
|
29
|
+
*/
|
|
30
|
+
export async function loadCiConfig(cwd) {
|
|
31
|
+
const dir = cwd ?? process.cwd();
|
|
32
|
+
const configPath = join(dir, ".pi", "pi-ci.json");
|
|
33
|
+
let text;
|
|
34
|
+
try {
|
|
35
|
+
text = await readFile(configPath, "utf-8");
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return { ...DEFAULT_CONFIG };
|
|
39
|
+
}
|
|
40
|
+
const raw = JSON.parse(text);
|
|
41
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
42
|
+
return { ...DEFAULT_CONFIG };
|
|
43
|
+
}
|
|
44
|
+
const user = raw;
|
|
45
|
+
return {
|
|
46
|
+
enabled: typeof user.enabled === "boolean" ? user.enabled : DEFAULT_CONFIG.enabled,
|
|
47
|
+
idleTimeoutMs: typeof user.idleTimeoutMs === "number" ? user.idleTimeoutMs : DEFAULT_CONFIG.idleTimeoutMs,
|
|
48
|
+
maxRetries: typeof user.maxRetries === "number" ? user.maxRetries : DEFAULT_CONFIG.maxRetries,
|
|
49
|
+
retryBackoffMaxMs: typeof user.retryBackoffMaxMs === "number"
|
|
50
|
+
? user.retryBackoffMaxMs
|
|
51
|
+
: DEFAULT_CONFIG.retryBackoffMaxMs,
|
|
52
|
+
exitCodes: {
|
|
53
|
+
...DEFAULT_CONFIG.exitCodes,
|
|
54
|
+
...(typeof user.exitCodes === "object" && user.exitCodes !== null
|
|
55
|
+
? user.exitCodes
|
|
56
|
+
: {}),
|
|
57
|
+
},
|
|
58
|
+
report: {
|
|
59
|
+
...DEFAULT_CONFIG.report,
|
|
60
|
+
...(typeof user.report === "object" && user.report !== null
|
|
61
|
+
? user.report
|
|
62
|
+
: {}),
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
export { DEFAULT_CONFIG };
|
|
67
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AA0BjC,MAAM,cAAc,GAAe;IACjC,OAAO,EAAE,IAAI;IACb,aAAa,EAAE,MAAM;IACrB,UAAU,EAAE,CAAC;IACb,iBAAiB,EAAE,MAAM;IACzB,SAAS,EAAE;QACT,OAAO,EAAE,CAAC;QACV,KAAK,EAAE,CAAC;QACR,OAAO,EAAE,EAAE;QACX,SAAS,EAAE,EAAE;QACb,UAAU,EAAE,EAAE;KACf;IACD,MAAM,EAAE;QACN,MAAM,EAAE,OAAO;QACf,WAAW,EAAE,IAAI;QACjB,YAAY,EAAE,IAAI;QAClB,YAAY,EAAE,IAAI;KACnB;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAY;IAC7C,MAAM,GAAG,GAAG,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACjC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;IAElD,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAC/B,CAAC;IAED,MAAM,GAAG,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAClE,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAC/B,CAAC;IAED,MAAM,IAAI,GAAG,GAA8B,CAAC;IAC5C,OAAO;QACL,OAAO,EAAE,OAAO,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO;QAClF,aAAa,EACX,OAAO,IAAI,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,cAAc,CAAC,aAAa;QAC5F,UAAU,EACR,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC,UAAU;QACnF,iBAAiB,EACf,OAAO,IAAI,CAAC,iBAAiB,KAAK,QAAQ;YACxC,CAAC,CAAC,IAAI,CAAC,iBAAiB;YACxB,CAAC,CAAC,cAAc,CAAC,iBAAiB;QACtC,SAAS,EAAE;YACT,GAAG,cAAc,CAAC,SAAS;YAC3B,GAAG,CAAC,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI;gBAC/D,CAAC,CAAE,IAAI,CAAC,SAAyC;gBACjD,CAAC,CAAC,EAAE,CAAC;SACR;QACD,MAAM,EAAE;YACN,GAAG,cAAc,CAAC,MAAM;YACxB,GAAG,CAAC,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI;gBACzD,CAAC,CAAE,IAAI,CAAC,MAAoC;gBAC5C,CAAC,CAAC,EAAE,CAAC;SACR;KACF,CAAC;AACJ,CAAC;AAED,OAAO,EAAE,cAAc,EAAE,CAAC"}
|