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.
Files changed (80) hide show
  1. package/README.md +62 -0
  2. package/dist/ci/pipeline.d.ts +43 -0
  3. package/dist/ci/pipeline.d.ts.map +1 -0
  4. package/dist/ci/pipeline.js +107 -0
  5. package/dist/ci/pipeline.js.map +1 -0
  6. package/dist/ci/pr-creator.d.ts +17 -0
  7. package/dist/ci/pr-creator.d.ts.map +1 -0
  8. package/dist/ci/pr-creator.js +67 -0
  9. package/dist/ci/pr-creator.js.map +1 -0
  10. package/dist/ci/report.d.ts +14 -0
  11. package/dist/ci/report.d.ts.map +1 -0
  12. package/dist/ci/report.js +51 -0
  13. package/dist/ci/report.js.map +1 -0
  14. package/dist/ci/test-runner.d.ts +10 -0
  15. package/dist/ci/test-runner.d.ts.map +1 -0
  16. package/dist/ci/test-runner.js +111 -0
  17. package/dist/ci/test-runner.js.map +1 -0
  18. package/dist/config.d.ts +33 -0
  19. package/dist/config.d.ts.map +1 -0
  20. package/dist/config.js +67 -0
  21. package/dist/config.js.map +1 -0
  22. package/dist/deploy/canary-deploy.d.ts +80 -0
  23. package/dist/deploy/canary-deploy.d.ts.map +1 -0
  24. package/dist/deploy/canary-deploy.js +145 -0
  25. package/dist/deploy/canary-deploy.js.map +1 -0
  26. package/dist/deploy/landing-queue.d.ts +83 -0
  27. package/dist/deploy/landing-queue.d.ts.map +1 -0
  28. package/dist/deploy/landing-queue.js +172 -0
  29. package/dist/deploy/landing-queue.js.map +1 -0
  30. package/dist/headless/answer-injector.d.ts +27 -0
  31. package/dist/headless/answer-injector.d.ts.map +1 -0
  32. package/dist/headless/answer-injector.js +80 -0
  33. package/dist/headless/answer-injector.js.map +1 -0
  34. package/dist/headless/exit-codes.d.ts +13 -0
  35. package/dist/headless/exit-codes.d.ts.map +1 -0
  36. package/dist/headless/exit-codes.js +29 -0
  37. package/dist/headless/exit-codes.js.map +1 -0
  38. package/dist/headless/idle-detector.d.ts +32 -0
  39. package/dist/headless/idle-detector.d.ts.map +1 -0
  40. package/dist/headless/idle-detector.js +62 -0
  41. package/dist/headless/idle-detector.js.map +1 -0
  42. package/dist/headless/jsonl-stream.d.ts +28 -0
  43. package/dist/headless/jsonl-stream.d.ts.map +1 -0
  44. package/dist/headless/jsonl-stream.js +65 -0
  45. package/dist/headless/jsonl-stream.js.map +1 -0
  46. package/dist/headless/orchestrator.d.ts +63 -0
  47. package/dist/headless/orchestrator.d.ts.map +1 -0
  48. package/dist/headless/orchestrator.js +156 -0
  49. package/dist/headless/orchestrator.js.map +1 -0
  50. package/{index.ts → dist/index.d.ts} +4 -26
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +31 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/tools/ci_status.d.ts +40 -0
  55. package/dist/tools/ci_status.d.ts.map +1 -0
  56. package/dist/tools/ci_status.js +110 -0
  57. package/dist/tools/ci_status.js.map +1 -0
  58. package/dist/types.d.ts +93 -0
  59. package/dist/types.d.ts.map +1 -0
  60. package/dist/types.js +17 -0
  61. package/dist/types.js.map +1 -0
  62. package/dist/workflow/deployment-workflow.d.ts +56 -0
  63. package/dist/workflow/deployment-workflow.d.ts.map +1 -0
  64. package/dist/workflow/deployment-workflow.js +95 -0
  65. package/dist/workflow/deployment-workflow.js.map +1 -0
  66. package/package.json +26 -26
  67. package/AGENTS.md +0 -25
  68. package/src/ci/pipeline.ts +0 -130
  69. package/src/ci/pr-creator.ts +0 -74
  70. package/src/ci/report.ts +0 -65
  71. package/src/ci/test-runner.ts +0 -129
  72. package/src/config.ts +0 -99
  73. package/src/headless/answer-injector.ts +0 -98
  74. package/src/headless/exit-codes.ts +0 -32
  75. package/src/headless/idle-detector.ts +0 -76
  76. package/src/headless/jsonl-stream.ts +0 -90
  77. package/src/headless/orchestrator.ts +0 -206
  78. package/src/tools/ci_status.ts +0 -137
  79. package/src/types.ts +0 -149
  80. 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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"}
@@ -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.1.1",
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
- "keywords": [
9
- "pi-package",
10
- "pi",
11
- "pi-coding-agent",
12
- "ci",
13
- "headless",
14
- "automation"
15
- ],
16
- "files": [
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
- "check": "npm run typecheck && npm test",
16
+ "build": "tsc --noEmitOnError false",
25
17
  "typecheck": "tsc --noEmit",
26
- "test": "node --experimental-strip-types --test --test-concurrency=1 --test-timeout=30000 test/unit/*.test.ts"
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
- "@mariozechner/pi-coding-agent": "*"
36
+ "typescript": "^5.0.0"
35
37
  },
36
- "peerDependenciesMeta": {
37
- "@mariozechner/pi-coding-agent": {
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
@@ -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
- }