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,80 @@
1
+ /**
2
+ * Canary Deployment with Monitoring
3
+ * Gradual rollout with automatic rollback
4
+ * Based on gstack /canary pattern
5
+ */
6
+ export interface CanaryConfig {
7
+ /** Initial traffic percentage for canary */
8
+ initialPercentage: number;
9
+ /** Increment per step */
10
+ incrementPercentage: number;
11
+ /** Time between increments (ms) */
12
+ stepInterval: number;
13
+ /** Total duration before full rollout (ms) */
14
+ totalDuration: number;
15
+ /** Metrics to monitor */
16
+ metrics: {
17
+ successRate: {
18
+ min: number;
19
+ };
20
+ latency: {
21
+ max: number;
22
+ };
23
+ errorRate: {
24
+ max: number;
25
+ };
26
+ };
27
+ }
28
+ export interface CanaryMetrics {
29
+ timestamp: number;
30
+ successRate: number;
31
+ latency: number;
32
+ errorRate: number;
33
+ requests: number;
34
+ }
35
+ export interface CanaryResult {
36
+ success: boolean;
37
+ finalPercentage: number;
38
+ metrics: CanaryMetrics[];
39
+ issues: string[];
40
+ rolledBack: boolean;
41
+ }
42
+ export interface DeployTarget {
43
+ name: string;
44
+ url: string;
45
+ healthy: boolean;
46
+ }
47
+ /**
48
+ * Canary Deployment Manager
49
+ */
50
+ export declare class CanaryDeploy {
51
+ private config;
52
+ private metricsHistory;
53
+ constructor(config?: Partial<CanaryConfig>);
54
+ /**
55
+ * Execute canary deployment
56
+ */
57
+ deploy(target: DeployTarget): Promise<CanaryResult>;
58
+ /**
59
+ * Get current metrics from target
60
+ */
61
+ private getMetrics;
62
+ /**
63
+ * Check metrics against thresholds
64
+ */
65
+ private checkMetrics;
66
+ /**
67
+ * Rollback deployment
68
+ */
69
+ rollback(target: DeployTarget): Promise<void>;
70
+ /**
71
+ * Get deployment history
72
+ */
73
+ getHistory(): CanaryMetrics[];
74
+ /**
75
+ * Generate deployment report
76
+ */
77
+ formatReport(result: CanaryResult): string;
78
+ private delay;
79
+ }
80
+ //# sourceMappingURL=canary-deploy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canary-deploy.d.ts","sourceRoot":"","sources":["../../src/deploy/canary-deploy.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,YAAY;IAC3B,4CAA4C;IAC5C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,yBAAyB;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mCAAmC;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,aAAa,EAAE,MAAM,CAAC;IACtB,yBAAyB;IACzB,OAAO,EAAE;QACP,WAAW,EAAE;YAAE,GAAG,EAAE,MAAM,CAAA;SAAE,CAAC;QAC7B,OAAO,EAAE;YAAE,GAAG,EAAE,MAAM,CAAA;SAAE,CAAC;QACzB,SAAS,EAAE;YAAE,GAAG,EAAE,MAAM,CAAA;SAAE,CAAC;KAC5B,CAAC;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,cAAc,CAAuB;gBAEjC,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC;IAc1C;;OAEG;IACG,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAmDzD;;OAEG;YACW,UAAU;IAaxB;;OAEG;IACH,OAAO,CAAC,YAAY;IAkBpB;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAOnD;;OAEG;IACH,UAAU,IAAI,aAAa,EAAE;IAI7B;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM;IA8B1C,OAAO,CAAC,KAAK;CAGd"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Canary Deployment with Monitoring
3
+ * Gradual rollout with automatic rollback
4
+ * Based on gstack /canary pattern
5
+ */
6
+ /**
7
+ * Canary Deployment Manager
8
+ */
9
+ export class CanaryDeploy {
10
+ config;
11
+ metricsHistory = [];
12
+ constructor(config) {
13
+ this.config = {
14
+ initialPercentage: config?.initialPercentage ?? 10,
15
+ incrementPercentage: config?.incrementPercentage ?? 10,
16
+ stepInterval: config?.stepInterval ?? 60000, // 1 minute
17
+ totalDuration: config?.totalDuration ?? 300000, // 5 minutes
18
+ metrics: config?.metrics ?? {
19
+ successRate: { min: 95 },
20
+ latency: { max: 500 },
21
+ errorRate: { max: 5 },
22
+ },
23
+ };
24
+ }
25
+ /**
26
+ * Execute canary deployment
27
+ */
28
+ async deploy(target) {
29
+ console.log(`Starting canary deployment to ${target.name}`);
30
+ console.log(`Initial: ${this.config.initialPercentage}% traffic`);
31
+ const issues = [];
32
+ let currentPercentage = this.config.initialPercentage;
33
+ let rolledBack = false;
34
+ const startTime = Date.now();
35
+ while (Date.now() - startTime < this.config.totalDuration) {
36
+ // Get current metrics
37
+ const metrics = await this.getMetrics(target);
38
+ this.metricsHistory.push(metrics);
39
+ // Check for issues
40
+ const detectedIssues = this.checkMetrics(metrics);
41
+ if (detectedIssues.length > 0) {
42
+ issues.push(...detectedIssues);
43
+ console.log(`⚠️ Issues detected: ${detectedIssues.join(', ')}`);
44
+ // Auto-rollback on critical issues
45
+ if (metrics.successRate < 90 || metrics.errorRate > 10) {
46
+ console.log('🔴 Critical issues - rolling back!');
47
+ rolledBack = true;
48
+ break;
49
+ }
50
+ }
51
+ // Print status
52
+ console.log(`[${Math.round((Date.now() - startTime) / 1000)}s] ` +
53
+ `Traffic: ${currentPercentage}% | ` +
54
+ `Success: ${metrics.successRate.toFixed(1)}% | ` +
55
+ `Latency: ${metrics.latency.toFixed(0)}ms`);
56
+ // Wait for next step
57
+ await this.delay(this.config.stepInterval);
58
+ // Increment traffic
59
+ currentPercentage = Math.min(100, currentPercentage + this.config.incrementPercentage);
60
+ }
61
+ return {
62
+ success: !rolledBack,
63
+ finalPercentage: rolledBack ? 0 : currentPercentage,
64
+ metrics: this.metricsHistory,
65
+ issues,
66
+ rolledBack,
67
+ };
68
+ }
69
+ /**
70
+ * Get current metrics from target
71
+ */
72
+ async getMetrics(target) {
73
+ // Simulate metrics collection
74
+ // In production: call monitoring API
75
+ return {
76
+ timestamp: Date.now(),
77
+ successRate: 95 + Math.random() * 5,
78
+ latency: 50 + Math.random() * 100,
79
+ errorRate: Math.random() * 3,
80
+ requests: Math.floor(100 + Math.random() * 900),
81
+ };
82
+ }
83
+ /**
84
+ * Check metrics against thresholds
85
+ */
86
+ checkMetrics(metrics) {
87
+ const issues = [];
88
+ if (metrics.successRate < this.config.metrics.successRate.min) {
89
+ issues.push(`Low success rate: ${metrics.successRate.toFixed(1)}%`);
90
+ }
91
+ if (metrics.latency > this.config.metrics.latency.max) {
92
+ issues.push(`High latency: ${metrics.latency.toFixed(0)}ms`);
93
+ }
94
+ if (metrics.errorRate > this.config.metrics.errorRate.max) {
95
+ issues.push(`High error rate: ${metrics.errorRate.toFixed(1)}%`);
96
+ }
97
+ return issues;
98
+ }
99
+ /**
100
+ * Rollback deployment
101
+ */
102
+ async rollback(target) {
103
+ console.log(`Rolling back ${target.name}`);
104
+ // In production: call rollback API
105
+ await this.delay(1000);
106
+ console.log('Rollback complete');
107
+ }
108
+ /**
109
+ * Get deployment history
110
+ */
111
+ getHistory() {
112
+ return [...this.metricsHistory];
113
+ }
114
+ /**
115
+ * Generate deployment report
116
+ */
117
+ formatReport(result) {
118
+ const lines = [];
119
+ lines.push('## Canary Deployment Report\n');
120
+ lines.push(`**Status:** ${result.success ? '✅ SUCCESS' : '❌ FAILED'}`);
121
+ lines.push(`**Final Traffic:** ${result.finalPercentage}%`);
122
+ lines.push(`**Rolled Back:** ${result.rolledBack ? 'Yes' : 'No'}\n`);
123
+ if (result.metrics.length > 0) {
124
+ lines.push('### Metrics History\n');
125
+ lines.push('| Time | Success | Latency | Error Rate |');
126
+ lines.push('|------|---------|---------|------------|');
127
+ result.metrics.forEach((m, i) => {
128
+ lines.push(`| ${i * 1}min | ${m.successRate.toFixed(1)}% | ${m.latency.toFixed(0)}ms | ${m.errorRate.toFixed(1)}% |`);
129
+ });
130
+ lines.push('');
131
+ }
132
+ if (result.issues.length > 0) {
133
+ lines.push('### Issues Detected\n');
134
+ for (const issue of result.issues) {
135
+ lines.push(`- ${issue}`);
136
+ }
137
+ lines.push('');
138
+ }
139
+ return lines.join('\n');
140
+ }
141
+ delay(ms) {
142
+ return new Promise((resolve) => setTimeout(resolve, ms));
143
+ }
144
+ }
145
+ //# sourceMappingURL=canary-deploy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canary-deploy.js","sourceRoot":"","sources":["../../src/deploy/canary-deploy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Landing Queue - Process deployments in order
3
+ * Based on gstack /landing-report pattern
4
+ */
5
+ export type DeployStatus = 'pending' | 'deploying' | 'deployed' | 'failed' | 'cancelled';
6
+ export type DeployEnvironment = 'staging' | 'production';
7
+ export interface QueuedDeploy {
8
+ id: string;
9
+ version: string;
10
+ environment: DeployEnvironment;
11
+ status: DeployStatus;
12
+ createdAt: number;
13
+ deployedAt?: number;
14
+ message?: string;
15
+ logs: string[];
16
+ }
17
+ export interface LandingQueueStats {
18
+ total: number;
19
+ pending: number;
20
+ deploying: number;
21
+ deployed: number;
22
+ failed: number;
23
+ }
24
+ /**
25
+ * Landing Queue Manager
26
+ */
27
+ export declare class LandingQueue {
28
+ private queue;
29
+ private current;
30
+ /**
31
+ * Add deployment to queue
32
+ */
33
+ enqueue(version: string, environment: DeployEnvironment, message?: string): QueuedDeploy;
34
+ /**
35
+ * Get next pending deployment
36
+ */
37
+ peek(): QueuedDeploy | undefined;
38
+ /**
39
+ * Start deploying next item
40
+ */
41
+ startNext(): Promise<QueuedDeploy | null>;
42
+ /**
43
+ * Mark deployment as complete
44
+ */
45
+ complete(id: string, success: boolean): void;
46
+ /**
47
+ * Cancel a deployment
48
+ */
49
+ cancel(id: string): void;
50
+ /**
51
+ * Get deployment by ID
52
+ */
53
+ get(id: string): QueuedDeploy | undefined;
54
+ /**
55
+ * Get queue status
56
+ */
57
+ getStats(): LandingQueueStats;
58
+ /**
59
+ * Get all deployments
60
+ */
61
+ getAll(): QueuedDeploy[];
62
+ /**
63
+ * Get pending deployments
64
+ */
65
+ getPending(): QueuedDeploy[];
66
+ /**
67
+ * Get current deploying
68
+ */
69
+ getCurrent(): QueuedDeploy | null;
70
+ /**
71
+ * Add log entry
72
+ */
73
+ private log;
74
+ /**
75
+ * Clear completed deployments
76
+ */
77
+ clearCompleted(): void;
78
+ /**
79
+ * Format queue as markdown report
80
+ */
81
+ formatReport(): string;
82
+ }
83
+ //# sourceMappingURL=landing-queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"landing-queue.d.ts","sourceRoot":"","sources":["../../src/deploy/landing-queue.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG,WAAW,CAAC;AACzF,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,YAAY,CAAC;AAEzD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,iBAAiB,CAAC;IAC/B,MAAM,EAAE,YAAY,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,OAAO,CAA6B;IAE5C;;OAEG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,iBAAiB,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY;IAiBxF;;OAEG;IACH,IAAI,IAAI,YAAY,GAAG,SAAS;IAIhC;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAY/C;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAa5C;;OAEG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAaxB;;OAEG;IACH,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAIzC;;OAEG;IACH,QAAQ,IAAI,iBAAiB;IAU7B;;OAEG;IACH,MAAM,IAAI,YAAY,EAAE;IAIxB;;OAEG;IACH,UAAU,IAAI,YAAY,EAAE;IAM5B;;OAEG;IACH,UAAU,IAAI,YAAY,GAAG,IAAI;IAIjC;;OAEG;IACH,OAAO,CAAC,GAAG;IAOX;;OAEG;IACH,cAAc,IAAI,IAAI;IAMtB;;OAEG;IACH,YAAY,IAAI,MAAM;CAgDvB"}
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Landing Queue - Process deployments in order
3
+ * Based on gstack /landing-report pattern
4
+ */
5
+ /**
6
+ * Landing Queue Manager
7
+ */
8
+ export class LandingQueue {
9
+ queue = [];
10
+ current = null;
11
+ /**
12
+ * Add deployment to queue
13
+ */
14
+ enqueue(version, environment, message) {
15
+ const deploy = {
16
+ id: `deploy-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
17
+ version,
18
+ environment,
19
+ status: 'pending',
20
+ createdAt: Date.now(),
21
+ message,
22
+ logs: [],
23
+ };
24
+ this.queue.push(deploy);
25
+ this.log(deploy.id, `Added to queue: ${version} -> ${environment}`);
26
+ return deploy;
27
+ }
28
+ /**
29
+ * Get next pending deployment
30
+ */
31
+ peek() {
32
+ return this.queue.find((d) => d.status === 'pending');
33
+ }
34
+ /**
35
+ * Start deploying next item
36
+ */
37
+ async startNext() {
38
+ const next = this.peek();
39
+ if (!next)
40
+ return null;
41
+ // Mark as deploying
42
+ next.status = 'deploying';
43
+ this.current = next;
44
+ this.log(next.id, 'Starting deployment');
45
+ return next;
46
+ }
47
+ /**
48
+ * Mark deployment as complete
49
+ */
50
+ complete(id, success) {
51
+ const deploy = this.queue.find((d) => d.id === id);
52
+ if (!deploy)
53
+ return;
54
+ deploy.status = success ? 'deployed' : 'failed';
55
+ deploy.deployedAt = Date.now();
56
+ this.log(id, success ? 'Deployment successful' : 'Deployment failed');
57
+ if (this.current?.id === id) {
58
+ this.current = null;
59
+ }
60
+ }
61
+ /**
62
+ * Cancel a deployment
63
+ */
64
+ cancel(id) {
65
+ const deploy = this.queue.find((d) => d.id === id);
66
+ if (!deploy)
67
+ return;
68
+ if (deploy.status === 'deploying') {
69
+ this.log(id, 'Cannot cancel - deployment in progress');
70
+ return;
71
+ }
72
+ deploy.status = 'cancelled';
73
+ this.log(id, 'Cancelled');
74
+ }
75
+ /**
76
+ * Get deployment by ID
77
+ */
78
+ get(id) {
79
+ return this.queue.find((d) => d.id === id);
80
+ }
81
+ /**
82
+ * Get queue status
83
+ */
84
+ getStats() {
85
+ return {
86
+ total: this.queue.length,
87
+ pending: this.queue.filter((d) => d.status === 'pending').length,
88
+ deploying: this.queue.filter((d) => d.status === 'deploying').length,
89
+ deployed: this.queue.filter((d) => d.status === 'deployed').length,
90
+ failed: this.queue.filter((d) => d.status === 'failed').length,
91
+ };
92
+ }
93
+ /**
94
+ * Get all deployments
95
+ */
96
+ getAll() {
97
+ return [...this.queue].sort((a, b) => b.createdAt - a.createdAt);
98
+ }
99
+ /**
100
+ * Get pending deployments
101
+ */
102
+ getPending() {
103
+ return this.queue
104
+ .filter((d) => d.status === 'pending')
105
+ .sort((a, b) => a.createdAt - b.createdAt);
106
+ }
107
+ /**
108
+ * Get current deploying
109
+ */
110
+ getCurrent() {
111
+ return this.current;
112
+ }
113
+ /**
114
+ * Add log entry
115
+ */
116
+ log(id, message) {
117
+ const deploy = this.queue.find((d) => d.id === id);
118
+ if (deploy) {
119
+ deploy.logs.push(`[${new Date().toISOString()}] ${message}`);
120
+ }
121
+ }
122
+ /**
123
+ * Clear completed deployments
124
+ */
125
+ clearCompleted() {
126
+ this.queue = this.queue.filter((d) => d.status === 'pending' || d.status === 'deploying');
127
+ }
128
+ /**
129
+ * Format queue as markdown report
130
+ */
131
+ formatReport() {
132
+ const stats = this.getStats();
133
+ const lines = [];
134
+ lines.push('## Landing Queue Report\n');
135
+ lines.push(`**Total:** ${stats.total} | **Pending:** ${stats.pending} | **Deploying:** ${stats.deploying} | **Deployed:** ${stats.deployed} | **Failed:** ${stats.failed}\n`);
136
+ const current = this.getCurrent();
137
+ if (current) {
138
+ lines.push('### Currently Deploying\n');
139
+ lines.push(`**${current.version}** -> ${current.environment}`);
140
+ lines.push(`Status: ${current.status}`);
141
+ lines.push('');
142
+ }
143
+ const pending = this.getPending();
144
+ if (pending.length > 0) {
145
+ lines.push('### Queue\n');
146
+ lines.push('| # | Version | Environment | Message |');
147
+ lines.push('|---|--------|------------|---------|');
148
+ pending.forEach((d, i) => {
149
+ lines.push(`| ${i + 1} | ${d.version} | ${d.environment} | ${d.message || '-'} |`);
150
+ });
151
+ lines.push('');
152
+ }
153
+ const recent = this.queue
154
+ .filter((d) => d.status === 'deployed' || d.status === 'failed')
155
+ .slice(0, 5);
156
+ if (recent.length > 0) {
157
+ lines.push('### Recent\n');
158
+ lines.push('| Version | Environment | Status | Time |');
159
+ lines.push('|---------|------------|--------|------|');
160
+ for (const d of recent) {
161
+ const icon = d.status === 'deployed' ? '✅' : '❌';
162
+ const time = d.deployedAt
163
+ ? new Date(d.deployedAt).toLocaleTimeString()
164
+ : '-';
165
+ lines.push(`| ${d.version} | ${d.environment} | ${icon} ${d.status} | ${time} |`);
166
+ }
167
+ lines.push('');
168
+ }
169
+ return lines.join('\n');
170
+ }
171
+ }
172
+ //# sourceMappingURL=landing-queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"landing-queue.js","sourceRoot":"","sources":["../../src/deploy/landing-queue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * pi-ci — Answer injection from a JSON file.
3
+ *
4
+ * When Pi encounters an interactive prompt in CI mode, it consults an
5
+ * answers file for a pre-supplied response.
6
+ */
7
+ import type { AnswerEntry } from "../types.ts";
8
+ /**
9
+ * Read and validate an answers JSON file.
10
+ *
11
+ * - Returns an empty array if the file cannot be read.
12
+ * - Skips entries that are missing `match` or `answer` fields.
13
+ * - Throws on invalid JSON.
14
+ */
15
+ export declare function loadAnswers(filePath: string): Promise<AnswerEntry[]>;
16
+ /**
17
+ * Synchronous variant that reads from a string (useful for testing).
18
+ */
19
+ export declare function parseAnswers(jsonText: string): AnswerEntry[];
20
+ /**
21
+ * Find a matching answer for the given prompt using substring matching.
22
+ *
23
+ * Returns the first answer whose `match` is found as a substring of `prompt`,
24
+ * or `undefined` if no match is found.
25
+ */
26
+ export declare function matchAnswer(entries: AnswerEntry[], prompt: string): string | undefined;
27
+ //# sourceMappingURL=answer-injector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"answer-injector.d.ts","sourceRoot":"","sources":["../../src/headless/answer-injector.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAc,MAAM,aAAa,CAAC;AAG3D;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAiC1E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,EAAE,CAyB5D;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,WAAW,EAAE,EACtB,MAAM,EAAE,MAAM,GACb,MAAM,GAAG,SAAS,CAOpB"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * pi-ci — Answer injection from a JSON file.
3
+ *
4
+ * When Pi encounters an interactive prompt in CI mode, it consults an
5
+ * answers file for a pre-supplied response.
6
+ */
7
+ import * as fs from "fs";
8
+ /**
9
+ * Read and validate an answers JSON file.
10
+ *
11
+ * - Returns an empty array if the file cannot be read.
12
+ * - Skips entries that are missing `match` or `answer` fields.
13
+ * - Throws on invalid JSON.
14
+ */
15
+ export async function loadAnswers(filePath) {
16
+ let text;
17
+ try {
18
+ text = fs.readFileSync(filePath, "utf-8");
19
+ }
20
+ catch {
21
+ return [];
22
+ }
23
+ const raw = JSON.parse(text);
24
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
25
+ throw new Error(`Answers file must contain a JSON object with an "answers" array`);
26
+ }
27
+ const obj = raw;
28
+ if (!Array.isArray(obj.answers)) {
29
+ throw new Error(`Answers file must contain an "answers" array`);
30
+ }
31
+ const entries = [];
32
+ for (const item of obj.answers) {
33
+ if (typeof item === "object" &&
34
+ item !== null &&
35
+ typeof item.match === "string" &&
36
+ typeof item.answer === "string") {
37
+ entries.push(item);
38
+ }
39
+ // Silently skip malformed entries
40
+ }
41
+ return entries;
42
+ }
43
+ /**
44
+ * Synchronous variant that reads from a string (useful for testing).
45
+ */
46
+ export function parseAnswers(jsonText) {
47
+ const raw = JSON.parse(jsonText);
48
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
49
+ throw new Error(`Answers file must contain a JSON object with an "answers" array`);
50
+ }
51
+ const obj = raw;
52
+ if (!Array.isArray(obj.answers)) {
53
+ throw new Error(`Answers file must contain an "answers" array`);
54
+ }
55
+ const entries = [];
56
+ for (const item of obj.answers) {
57
+ if (typeof item === "object" &&
58
+ item !== null &&
59
+ typeof item.match === "string" &&
60
+ typeof item.answer === "string") {
61
+ entries.push(item);
62
+ }
63
+ }
64
+ return entries;
65
+ }
66
+ /**
67
+ * Find a matching answer for the given prompt using substring matching.
68
+ *
69
+ * Returns the first answer whose `match` is found as a substring of `prompt`,
70
+ * or `undefined` if no match is found.
71
+ */
72
+ export function matchAnswer(entries, prompt) {
73
+ for (const entry of entries) {
74
+ if (prompt.includes(entry.match)) {
75
+ return entry.answer;
76
+ }
77
+ }
78
+ return undefined;
79
+ }
80
+ //# sourceMappingURL=answer-injector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"answer-injector.js","sourceRoot":"","sources":["../../src/headless/answer-injector.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAEzB;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,QAAgB;IAChD,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,GAAG,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEtC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;IACrF,CAAC;IAED,MAAM,GAAG,GAAG,GAA8B,CAAC;IAC3C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QAC/B,IACE,OAAO,IAAI,KAAK,QAAQ;YACxB,IAAI,KAAK,IAAI;YACb,OAAQ,IAAgC,CAAC,KAAK,KAAK,QAAQ;YAC3D,OAAQ,IAAgC,CAAC,MAAM,KAAK,QAAQ,EAC5D,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,IAAmB,CAAC,CAAC;QACpC,CAAC;QACD,kCAAkC;IACpC,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,MAAM,GAAG,GAAY,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAE1C,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;IACrF,CAAC;IAED,MAAM,GAAG,GAAG,GAA8B,CAAC;IAC3C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QAC/B,IACE,OAAO,IAAI,KAAK,QAAQ;YACxB,IAAI,KAAK,IAAI;YACb,OAAQ,IAAgC,CAAC,KAAK,KAAK,QAAQ;YAC3D,OAAQ,IAAgC,CAAC,MAAM,KAAK,QAAQ,EAC5D,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,IAAmB,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CACzB,OAAsB,EACtB,MAAc;IAEd,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACjC,OAAO,KAAK,CAAC,MAAM,CAAC;QACtB,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * pi-ci — Exit code resolution helpers.
3
+ */
4
+ import { EXIT_CODES, type ExitCode } from "../types.ts";
5
+ /**
6
+ * Map a symbolic status string to a numeric exit code.
7
+ *
8
+ * Unknown / unexpected statuses resolve to ERROR (1).
9
+ */
10
+ export declare function resolveExitCode(status: string): ExitCode;
11
+ export { EXIT_CODES };
12
+ export type { ExitCode };
13
+ //# sourceMappingURL=exit-codes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exit-codes.d.ts","sourceRoot":"","sources":["../../src/headless/exit-codes.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAExD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAiBxD;AAED,OAAO,EAAE,UAAU,EAAE,CAAC;AACtB,YAAY,EAAE,QAAQ,EAAE,CAAC"}