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
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pi-ci — /ci status command handler.
|
|
3
|
+
*
|
|
4
|
+
* Shows the status of the current or last CI run.
|
|
5
|
+
*/
|
|
6
|
+
import { CIEventCollector } from "../headless/jsonl-stream.ts";
|
|
7
|
+
import { isCIEndEvent } from "../headless/jsonl-stream.ts";
|
|
8
|
+
/**
|
|
9
|
+
* Simple in-memory registry of CI runs (for the status command).
|
|
10
|
+
*/
|
|
11
|
+
const runRegistry = new Map();
|
|
12
|
+
/**
|
|
13
|
+
* Register a CI run for status lookups.
|
|
14
|
+
*/
|
|
15
|
+
export function registerRun(record) {
|
|
16
|
+
runRegistry.set(record.id, record);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Clear all registered runs (useful for testing).
|
|
20
|
+
*/
|
|
21
|
+
export function clearRuns() {
|
|
22
|
+
runRegistry.clear();
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get a specific run by ID (prefix match supported).
|
|
26
|
+
*/
|
|
27
|
+
export function getRun(id) {
|
|
28
|
+
// Exact match first
|
|
29
|
+
if (runRegistry.has(id)) {
|
|
30
|
+
return runRegistry.get(id);
|
|
31
|
+
}
|
|
32
|
+
// Prefix match
|
|
33
|
+
for (const [key, value] of runRegistry) {
|
|
34
|
+
if (key.startsWith(id)) {
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Handle the /ci status command.
|
|
42
|
+
*
|
|
43
|
+
* Returns a human-readable status string.
|
|
44
|
+
*/
|
|
45
|
+
export function ciStatusHandler(args) {
|
|
46
|
+
const runId = typeof args === "string" ? args : undefined;
|
|
47
|
+
if (runId) {
|
|
48
|
+
const run = getRun(runId);
|
|
49
|
+
if (!run) {
|
|
50
|
+
return `No CI run found matching: ${runId}`;
|
|
51
|
+
}
|
|
52
|
+
return formatRunStatus(run);
|
|
53
|
+
}
|
|
54
|
+
// Show all runs
|
|
55
|
+
if (runRegistry.size === 0) {
|
|
56
|
+
return "No CI runs found.";
|
|
57
|
+
}
|
|
58
|
+
const lines = [];
|
|
59
|
+
for (const run of runRegistry.values()) {
|
|
60
|
+
lines.push(formatRunStatus(run));
|
|
61
|
+
lines.push("");
|
|
62
|
+
}
|
|
63
|
+
return lines.join("\n").trimEnd();
|
|
64
|
+
}
|
|
65
|
+
function formatRunStatus(run) {
|
|
66
|
+
const lines = [];
|
|
67
|
+
lines.push(`Run: ${run.id}`);
|
|
68
|
+
lines.push(`Started: ${run.startTime}`);
|
|
69
|
+
const endEvent = run.events.find((e) => isCIEndEvent(e));
|
|
70
|
+
if (endEvent) {
|
|
71
|
+
lines.push(`Exit Code: ${endEvent.exit_code}`);
|
|
72
|
+
lines.push(`Duration: ${(endEvent.duration_ms / 1000).toFixed(1)}s`);
|
|
73
|
+
const status = endEvent.exit_code === 0
|
|
74
|
+
? "SUCCESS"
|
|
75
|
+
: endEvent.exit_code === 10
|
|
76
|
+
? "BLOCKED"
|
|
77
|
+
: endEvent.exit_code === 11
|
|
78
|
+
? "CANCELLED"
|
|
79
|
+
: "ERROR";
|
|
80
|
+
lines.push(`Status: ${status}`);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
lines.push("Status: RUNNING");
|
|
84
|
+
}
|
|
85
|
+
return lines.join("\n");
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Create a CI run tracker that collects events and registers the run.
|
|
89
|
+
*/
|
|
90
|
+
export function createRunTracker(runId) {
|
|
91
|
+
const collector = new CIEventCollector();
|
|
92
|
+
const startTime = new Date().toISOString();
|
|
93
|
+
return {
|
|
94
|
+
collector,
|
|
95
|
+
finalize() {
|
|
96
|
+
const events = collector.all();
|
|
97
|
+
const endEvent = events.find((e) => isCIEndEvent(e));
|
|
98
|
+
const record = {
|
|
99
|
+
id: runId,
|
|
100
|
+
startTime,
|
|
101
|
+
events,
|
|
102
|
+
exitCode: endEvent?.exit_code,
|
|
103
|
+
durationMs: endEvent?.duration_ms,
|
|
104
|
+
};
|
|
105
|
+
registerRun(record);
|
|
106
|
+
return record;
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=ci_status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ci_status.js","sourceRoot":"","sources":["../../src/tools/ci_status.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pi-ci — Shared types for headless CI mode.
|
|
3
|
+
*
|
|
4
|
+
* Exit code contract and CI event types per SPEC.md §2.1 and §5.
|
|
5
|
+
*/
|
|
6
|
+
export declare const EXIT_CODES: {
|
|
7
|
+
readonly SUCCESS: 0;
|
|
8
|
+
readonly ERROR: 1;
|
|
9
|
+
readonly TIMEOUT: 1;
|
|
10
|
+
readonly BLOCKED: 10;
|
|
11
|
+
readonly CANCELLED: 11;
|
|
12
|
+
readonly NEEDS_INPUT: 12;
|
|
13
|
+
};
|
|
14
|
+
export type ExitCode = (typeof EXIT_CODES)[keyof typeof EXIT_CODES];
|
|
15
|
+
export type CIEventType = "ci_start" | "ci_progress" | "ci_edit" | "ci_test" | "ci_cost" | "ci_end";
|
|
16
|
+
export interface CIEventBase {
|
|
17
|
+
type: CIEventType;
|
|
18
|
+
timestamp: string;
|
|
19
|
+
}
|
|
20
|
+
export interface CIStartEvent extends CIEventBase {
|
|
21
|
+
type: "ci_start";
|
|
22
|
+
task: string;
|
|
23
|
+
mode: "single" | "plan";
|
|
24
|
+
}
|
|
25
|
+
export type CIRunPhase = "exploring" | "planning" | "implementing" | "verifying" | "reviewing";
|
|
26
|
+
export interface CIProgressEvent extends CIEventBase {
|
|
27
|
+
type: "ci_progress";
|
|
28
|
+
phase: CIRunPhase;
|
|
29
|
+
files?: string[];
|
|
30
|
+
}
|
|
31
|
+
export interface CIEditEvent extends CIEventBase {
|
|
32
|
+
type: "ci_edit";
|
|
33
|
+
file: string;
|
|
34
|
+
lines_added: number;
|
|
35
|
+
lines_removed: number;
|
|
36
|
+
}
|
|
37
|
+
export interface CITestEvent extends CIEventBase {
|
|
38
|
+
type: "ci_test";
|
|
39
|
+
command: string;
|
|
40
|
+
passed: number;
|
|
41
|
+
failed: number;
|
|
42
|
+
}
|
|
43
|
+
export interface CICostEvent extends CIEventBase {
|
|
44
|
+
type: "ci_cost";
|
|
45
|
+
tokens: {
|
|
46
|
+
input: number;
|
|
47
|
+
output: number;
|
|
48
|
+
};
|
|
49
|
+
cost_usd: number;
|
|
50
|
+
}
|
|
51
|
+
export interface CIEndEvent extends CIEventBase {
|
|
52
|
+
type: "ci_end";
|
|
53
|
+
exit_code: ExitCode;
|
|
54
|
+
duration_ms: number;
|
|
55
|
+
}
|
|
56
|
+
export type CIEvent = CIStartEvent | CIProgressEvent | CIEditEvent | CITestEvent | CICostEvent | CIEndEvent;
|
|
57
|
+
export interface AnswerEntry {
|
|
58
|
+
match: string;
|
|
59
|
+
answer: string;
|
|
60
|
+
}
|
|
61
|
+
export interface AnswerFile {
|
|
62
|
+
answers: AnswerEntry[];
|
|
63
|
+
}
|
|
64
|
+
export interface TestSummary {
|
|
65
|
+
passed: number;
|
|
66
|
+
failed: number;
|
|
67
|
+
total: number;
|
|
68
|
+
duration_ms: number;
|
|
69
|
+
}
|
|
70
|
+
export interface PROptions {
|
|
71
|
+
title: string;
|
|
72
|
+
body?: string;
|
|
73
|
+
base?: string;
|
|
74
|
+
head?: string;
|
|
75
|
+
draft?: boolean;
|
|
76
|
+
labels?: string[];
|
|
77
|
+
}
|
|
78
|
+
export interface PRResult {
|
|
79
|
+
url: string;
|
|
80
|
+
number: number;
|
|
81
|
+
}
|
|
82
|
+
export type CIPipelineMode = "single" | "plan" | "review" | "supervised";
|
|
83
|
+
export interface CIOptions {
|
|
84
|
+
prompt: string;
|
|
85
|
+
mode: CIPipelineMode;
|
|
86
|
+
answersFile?: string;
|
|
87
|
+
planFile?: string;
|
|
88
|
+
prNumber?: number;
|
|
89
|
+
resume?: string;
|
|
90
|
+
idleTimeoutMs?: number;
|
|
91
|
+
maxRetries?: number;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pi-ci — Shared types for headless CI mode.
|
|
3
|
+
*
|
|
4
|
+
* Exit code contract and CI event types per SPEC.md §2.1 and §5.
|
|
5
|
+
*/
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// Exit codes
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
export const EXIT_CODES = {
|
|
10
|
+
SUCCESS: 0,
|
|
11
|
+
ERROR: 1,
|
|
12
|
+
TIMEOUT: 1,
|
|
13
|
+
BLOCKED: 10,
|
|
14
|
+
CANCELLED: 11,
|
|
15
|
+
NEEDS_INPUT: 12,
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,OAAO,EAAE,CAAC;IACV,KAAK,EAAE,CAAC;IACR,OAAO,EAAE,CAAC;IACV,OAAO,EAAE,EAAE;IACX,SAAS,EAAE,EAAE;IACb,WAAW,EAAE,EAAE;CACP,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deployment Workflow - Pattern from pi-crew workflow-config.ts
|
|
3
|
+
*
|
|
4
|
+
* Declarative deployment workflow definition.
|
|
5
|
+
*/
|
|
6
|
+
export interface DeploymentStep {
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
action: "validate" | "build" | "test" | "deploy" | "verify" | "rollback";
|
|
10
|
+
environment: "staging" | "production" | "preview";
|
|
11
|
+
dependsOn?: string[];
|
|
12
|
+
parallelGroup?: string;
|
|
13
|
+
timeout?: number;
|
|
14
|
+
retry?: {
|
|
15
|
+
maxAttempts: number;
|
|
16
|
+
backoffMs: number;
|
|
17
|
+
};
|
|
18
|
+
conditions?: {
|
|
19
|
+
onlyIf?: string;
|
|
20
|
+
skipIf?: string;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export interface DeploymentWorkflow {
|
|
24
|
+
name: string;
|
|
25
|
+
description: string;
|
|
26
|
+
version: string;
|
|
27
|
+
steps: DeploymentStep[];
|
|
28
|
+
maxConcurrency?: number;
|
|
29
|
+
rollbackOnFailure?: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface DeploymentState {
|
|
32
|
+
workflowId: string;
|
|
33
|
+
runId: string;
|
|
34
|
+
status: "pending" | "running" | "completed" | "failed" | "rolled_back";
|
|
35
|
+
currentStep?: string;
|
|
36
|
+
completedSteps: string[];
|
|
37
|
+
failedSteps: string[];
|
|
38
|
+
startedAt: string;
|
|
39
|
+
finishedAt?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Create a standard deployment workflow
|
|
43
|
+
*/
|
|
44
|
+
export declare function createDeploymentWorkflow(options: {
|
|
45
|
+
name: string;
|
|
46
|
+
environments?: string[];
|
|
47
|
+
includeStaging?: boolean;
|
|
48
|
+
}): DeploymentWorkflow;
|
|
49
|
+
/**
|
|
50
|
+
* Execute a deployment workflow
|
|
51
|
+
*/
|
|
52
|
+
export declare function executeDeploymentWorkflow(workflow: DeploymentWorkflow, executor: (step: DeploymentStep) => Promise<{
|
|
53
|
+
success: boolean;
|
|
54
|
+
error?: string;
|
|
55
|
+
}>): AsyncGenerator<DeploymentState>;
|
|
56
|
+
//# sourceMappingURL=deployment-workflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deployment-workflow.d.ts","sourceRoot":"","sources":["../../src/workflow/deployment-workflow.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC;IACzE,WAAW,EAAE,SAAS,GAAG,YAAY,GAAG,SAAS,CAAC;IAClD,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE;QACN,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,UAAU,CAAC,EAAE;QACX,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,aAAa,CAAC;IACvE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE;IACP,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,GACA,kBAAkB,CAiDpB;AAED;;GAEG;AACH,wBAAuB,yBAAyB,CAC9C,QAAQ,EAAE,kBAAkB,EAC5B,QAAQ,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAChF,cAAc,CAAC,eAAe,CAAC,CA0CjC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deployment Workflow - Pattern from pi-crew workflow-config.ts
|
|
3
|
+
*
|
|
4
|
+
* Declarative deployment workflow definition.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Create a standard deployment workflow
|
|
8
|
+
*/
|
|
9
|
+
export function createDeploymentWorkflow(options) {
|
|
10
|
+
const envs = options.environments ?? ["staging", "production"];
|
|
11
|
+
const steps = [
|
|
12
|
+
{ id: "validate", name: "Validate", action: "validate", environment: "staging" },
|
|
13
|
+
{ id: "build", name: "Build", action: "build", environment: "staging", dependsOn: ["validate"] },
|
|
14
|
+
{ id: "test", name: "Test", action: "test", environment: "staging", dependsOn: ["build"] },
|
|
15
|
+
];
|
|
16
|
+
if (options.includeStaging !== false) {
|
|
17
|
+
steps.push({
|
|
18
|
+
id: "deploy-staging",
|
|
19
|
+
name: "Deploy to Staging",
|
|
20
|
+
action: "deploy",
|
|
21
|
+
environment: "staging",
|
|
22
|
+
dependsOn: ["test"],
|
|
23
|
+
retry: { maxAttempts: 3, backoffMs: 5000 },
|
|
24
|
+
});
|
|
25
|
+
steps.push({
|
|
26
|
+
id: "verify-staging",
|
|
27
|
+
name: "Verify Staging",
|
|
28
|
+
action: "verify",
|
|
29
|
+
environment: "staging",
|
|
30
|
+
dependsOn: ["deploy-staging"],
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
if (envs.includes("production")) {
|
|
34
|
+
steps.push({
|
|
35
|
+
id: "deploy-production",
|
|
36
|
+
name: "Deploy to Production",
|
|
37
|
+
action: "deploy",
|
|
38
|
+
environment: "production",
|
|
39
|
+
dependsOn: options.includeStaging !== false ? ["verify-staging"] : ["test"],
|
|
40
|
+
retry: { maxAttempts: 3, backoffMs: 10000 },
|
|
41
|
+
conditions: {
|
|
42
|
+
onlyIf: "BRANCH=main",
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
name: options.name,
|
|
48
|
+
description: `Deployment workflow for ${options.name}`,
|
|
49
|
+
version: "1.0.0",
|
|
50
|
+
steps,
|
|
51
|
+
maxConcurrency: 1,
|
|
52
|
+
rollbackOnFailure: true,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Execute a deployment workflow
|
|
57
|
+
*/
|
|
58
|
+
export async function* executeDeploymentWorkflow(workflow, executor) {
|
|
59
|
+
const state = {
|
|
60
|
+
workflowId: workflow.name,
|
|
61
|
+
runId: `deploy-${Date.now()}`,
|
|
62
|
+
status: "pending",
|
|
63
|
+
completedSteps: [],
|
|
64
|
+
failedSteps: [],
|
|
65
|
+
startedAt: new Date().toISOString(),
|
|
66
|
+
};
|
|
67
|
+
yield state;
|
|
68
|
+
const stepMap = new Map(workflow.steps.map(s => [s.id, s]));
|
|
69
|
+
const completed = new Set();
|
|
70
|
+
for (const step of workflow.steps) {
|
|
71
|
+
// Check dependencies
|
|
72
|
+
if (step.dependsOn?.some(dep => !completed.has(dep))) {
|
|
73
|
+
continue; // Dependencies not met
|
|
74
|
+
}
|
|
75
|
+
state.status = "running";
|
|
76
|
+
state.currentStep = step.id;
|
|
77
|
+
yield state;
|
|
78
|
+
const result = await executor(step);
|
|
79
|
+
if (result.success) {
|
|
80
|
+
completed.add(step.id);
|
|
81
|
+
state.completedSteps.push(step.id);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
state.failedSteps.push(step.id);
|
|
85
|
+
state.status = "failed";
|
|
86
|
+
state.finishedAt = new Date().toISOString();
|
|
87
|
+
yield state;
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
state.status = "completed";
|
|
92
|
+
state.finishedAt = new Date().toISOString();
|
|
93
|
+
yield state;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=deployment-workflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deployment-workflow.js","sourceRoot":"","sources":["../../src/workflow/deployment-workflow.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,41 +1,41 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-cicd",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Pi extension for headless CI mode with structured exit codes, answer injection, and pipeline automation",
|
|
5
|
-
"author": "baphuongna",
|
|
6
|
-
"license": "MIT",
|
|
7
5
|
"type": "module",
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"*.ts",
|
|
18
|
-
"src/**/*.ts",
|
|
19
|
-
"README.md",
|
|
20
|
-
"AGENTS.md",
|
|
21
|
-
"tsconfig.json"
|
|
22
|
-
],
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
23
15
|
"scripts": {
|
|
24
|
-
"
|
|
16
|
+
"build": "tsc --noEmitOnError false",
|
|
25
17
|
"typecheck": "tsc --noEmit",
|
|
26
|
-
"test": "
|
|
18
|
+
"test": "npx tsx --test --test-concurrency=1 --test-timeout=30000 test/unit/*.test.ts"
|
|
27
19
|
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"keywords": [
|
|
24
|
+
"pi",
|
|
25
|
+
"coding-agent",
|
|
26
|
+
"extension"
|
|
27
|
+
],
|
|
28
|
+
"author": "BaphuongNA",
|
|
29
|
+
"license": "MIT",
|
|
28
30
|
"pi": {
|
|
29
31
|
"extensions": [
|
|
30
32
|
"./index.ts"
|
|
31
33
|
]
|
|
32
34
|
},
|
|
33
35
|
"peerDependencies": {
|
|
34
|
-
"
|
|
36
|
+
"typescript": "^5.0.0"
|
|
35
37
|
},
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"optional": true
|
|
39
|
-
}
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"tsx": "^4.19.0"
|
|
40
40
|
}
|
|
41
|
-
}
|
|
41
|
+
}
|
package/AGENTS.md
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
# pi-ci Development Notes
|
|
2
|
-
|
|
3
|
-
Pi extension for headless CI mode.
|
|
4
|
-
|
|
5
|
-
## Rules
|
|
6
|
-
|
|
7
|
-
- Keep `index.ts` minimal; re-export from `src/` modules.
|
|
8
|
-
- Avoid `any`; use `unknown` plus validation.
|
|
9
|
-
- After code changes, run `npm test` from `pi-ci/` unless explicitly told not to.
|
|
10
|
-
|
|
11
|
-
## Important commands
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
npm test
|
|
15
|
-
npm run typecheck
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## Important paths
|
|
19
|
-
|
|
20
|
-
- `index.ts` — extension entry point
|
|
21
|
-
- `src/headless/` — core headless mode (exit codes, answers, idle, JSONL, orchestrator)
|
|
22
|
-
- `src/ci/` — CI pipeline, PR creation, test runner, reports
|
|
23
|
-
- `src/tools/` — /ci status command
|
|
24
|
-
- `src/config.ts` — configuration loading
|
|
25
|
-
- `test/unit/` — unit tests
|
package/src/ci/pipeline.ts
DELETED
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* pi-ci — CI pipeline wrapper.
|
|
3
|
-
*
|
|
4
|
-
* Provides single, plan, review, and supervised execution modes.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { CIEvent, CIOptions, CIPipelineMode, ExitCode, TestSummary } from "../types.ts";
|
|
8
|
-
import { EXIT_CODES } from "../types.ts";
|
|
9
|
-
import { HeadlessOrchestrator, type OrchestratorHooks } from "../headless/orchestrator.ts";
|
|
10
|
-
import { loadAnswers } from "../headless/answer-injector.ts";
|
|
11
|
-
import { parseTestResults } from "./test-runner.ts";
|
|
12
|
-
import { generateReport } from "./report.ts";
|
|
13
|
-
|
|
14
|
-
export interface PipelineResult {
|
|
15
|
-
exitCode: ExitCode;
|
|
16
|
-
events: CIEvent[];
|
|
17
|
-
report: string;
|
|
18
|
-
testSummary?: TestSummary;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export class CIPipeline {
|
|
22
|
-
private readonly options: CIOptions;
|
|
23
|
-
private readonly hooks: OrchestratorHooks;
|
|
24
|
-
|
|
25
|
-
constructor(options: CIOptions, hooks: OrchestratorHooks) {
|
|
26
|
-
this.options = options;
|
|
27
|
-
this.hooks = hooks;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Execute the pipeline in the configured mode.
|
|
32
|
-
*/
|
|
33
|
-
async execute(): Promise<PipelineResult> {
|
|
34
|
-
switch (this.options.mode) {
|
|
35
|
-
case "single":
|
|
36
|
-
return this.executeSingle();
|
|
37
|
-
case "plan":
|
|
38
|
-
return this.executePlan();
|
|
39
|
-
case "review":
|
|
40
|
-
return this.executeReview();
|
|
41
|
-
case "supervised":
|
|
42
|
-
return this.executeSupervised();
|
|
43
|
-
default:
|
|
44
|
-
throw new Error(`Unknown CI pipeline mode: ${this.options.mode as string}`);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Single task mode — run one prompt to completion.
|
|
50
|
-
*/
|
|
51
|
-
private async executeSingle(): Promise<PipelineResult> {
|
|
52
|
-
const answers = await this.loadAnswers();
|
|
53
|
-
const orchestrator = new HeadlessOrchestrator(answers, this.options, this.hooks);
|
|
54
|
-
const result = await orchestrator.run(this.options.prompt, "single");
|
|
55
|
-
|
|
56
|
-
return {
|
|
57
|
-
exitCode: result.exitCode,
|
|
58
|
-
events: result.events,
|
|
59
|
-
report: generateReport(result.events),
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Plan mode — execute steps from a plan file.
|
|
65
|
-
*
|
|
66
|
-
* Each step becomes a sequential orchestrator invocation. If any step fails,
|
|
67
|
-
* the pipeline stops.
|
|
68
|
-
*/
|
|
69
|
-
private async executePlan(): Promise<PipelineResult> {
|
|
70
|
-
const allEvents: CIEvent[] = [];
|
|
71
|
-
let finalExitCode: ExitCode = EXIT_CODES.SUCCESS;
|
|
72
|
-
let totalDuration = 0;
|
|
73
|
-
|
|
74
|
-
// Plan steps are provided via the executeStep hook — the orchestrator
|
|
75
|
-
// iterates over steps internally.
|
|
76
|
-
const answers = await this.loadAnswers();
|
|
77
|
-
const orchestrator = new HeadlessOrchestrator(answers, this.options, this.hooks);
|
|
78
|
-
const result = await orchestrator.run(this.options.prompt, "plan");
|
|
79
|
-
|
|
80
|
-
allEvents.push(...result.events);
|
|
81
|
-
finalExitCode = result.exitCode;
|
|
82
|
-
totalDuration = result.durationMs;
|
|
83
|
-
|
|
84
|
-
return {
|
|
85
|
-
exitCode: finalExitCode,
|
|
86
|
-
events: allEvents,
|
|
87
|
-
report: generateReport(allEvents),
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* PR review mode — review a PR by number.
|
|
93
|
-
*/
|
|
94
|
-
private async executeReview(): Promise<PipelineResult> {
|
|
95
|
-
const answers = await this.loadAnswers();
|
|
96
|
-
const orchestrator = new HeadlessOrchestrator(answers, this.options, this.hooks);
|
|
97
|
-
const prompt = this.options.prNumber
|
|
98
|
-
? `Review PR #${this.options.prNumber}`
|
|
99
|
-
: this.options.prompt;
|
|
100
|
-
const result = await orchestrator.run(prompt, "single");
|
|
101
|
-
|
|
102
|
-
return {
|
|
103
|
-
exitCode: result.exitCode,
|
|
104
|
-
events: result.events,
|
|
105
|
-
report: generateReport(result.events),
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Supervised mode — stdin/stdout forwarding for an external orchestrator.
|
|
111
|
-
*/
|
|
112
|
-
private async executeSupervised(): Promise<PipelineResult> {
|
|
113
|
-
const answers = await this.loadAnswers();
|
|
114
|
-
const orchestrator = new HeadlessOrchestrator(answers, this.options, this.hooks);
|
|
115
|
-
const result = await orchestrator.run(this.options.prompt, "single");
|
|
116
|
-
|
|
117
|
-
return {
|
|
118
|
-
exitCode: result.exitCode,
|
|
119
|
-
events: result.events,
|
|
120
|
-
report: generateReport(result.events),
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
private async loadAnswers() {
|
|
125
|
-
if (this.options.answersFile) {
|
|
126
|
-
return loadAnswers(this.options.answersFile);
|
|
127
|
-
}
|
|
128
|
-
return [];
|
|
129
|
-
}
|
|
130
|
-
}
|