@supaku/agentfactory 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/src/deployment/deployment-checker.d.ts +110 -0
- package/dist/src/deployment/deployment-checker.d.ts.map +1 -0
- package/dist/src/deployment/deployment-checker.js +242 -0
- package/dist/src/deployment/index.d.ts +3 -0
- package/dist/src/deployment/index.d.ts.map +1 -0
- package/dist/src/deployment/index.js +2 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +4 -0
- package/dist/src/logger.d.ts +117 -0
- package/dist/src/logger.d.ts.map +1 -0
- package/dist/src/logger.js +430 -0
- package/dist/src/orchestrator/activity-emitter.d.ts +128 -0
- package/dist/src/orchestrator/activity-emitter.d.ts.map +1 -0
- package/dist/src/orchestrator/activity-emitter.js +406 -0
- package/dist/src/orchestrator/api-activity-emitter.d.ts +167 -0
- package/dist/src/orchestrator/api-activity-emitter.d.ts.map +1 -0
- package/dist/src/orchestrator/api-activity-emitter.js +469 -0
- package/dist/src/orchestrator/heartbeat-writer.d.ts +57 -0
- package/dist/src/orchestrator/heartbeat-writer.d.ts.map +1 -0
- package/dist/src/orchestrator/heartbeat-writer.js +137 -0
- package/dist/src/orchestrator/index.d.ts +20 -0
- package/dist/src/orchestrator/index.d.ts.map +1 -0
- package/dist/src/orchestrator/index.js +22 -0
- package/dist/src/orchestrator/log-analyzer.d.ts +160 -0
- package/dist/src/orchestrator/log-analyzer.d.ts.map +1 -0
- package/dist/src/orchestrator/log-analyzer.js +572 -0
- package/dist/src/orchestrator/log-config.d.ts +39 -0
- package/dist/src/orchestrator/log-config.d.ts.map +1 -0
- package/dist/src/orchestrator/log-config.js +45 -0
- package/dist/src/orchestrator/orchestrator.d.ts +246 -0
- package/dist/src/orchestrator/orchestrator.d.ts.map +1 -0
- package/dist/src/orchestrator/orchestrator.js +2525 -0
- package/dist/src/orchestrator/parse-work-result.d.ts +16 -0
- package/dist/src/orchestrator/parse-work-result.d.ts.map +1 -0
- package/dist/src/orchestrator/parse-work-result.js +73 -0
- package/dist/src/orchestrator/progress-logger.d.ts +72 -0
- package/dist/src/orchestrator/progress-logger.d.ts.map +1 -0
- package/dist/src/orchestrator/progress-logger.js +135 -0
- package/dist/src/orchestrator/session-logger.d.ts +159 -0
- package/dist/src/orchestrator/session-logger.d.ts.map +1 -0
- package/dist/src/orchestrator/session-logger.js +275 -0
- package/dist/src/orchestrator/state-recovery.d.ts +96 -0
- package/dist/src/orchestrator/state-recovery.d.ts.map +1 -0
- package/dist/src/orchestrator/state-recovery.js +301 -0
- package/dist/src/orchestrator/state-types.d.ts +165 -0
- package/dist/src/orchestrator/state-types.d.ts.map +1 -0
- package/dist/src/orchestrator/state-types.js +7 -0
- package/dist/src/orchestrator/stream-parser.d.ts +145 -0
- package/dist/src/orchestrator/stream-parser.d.ts.map +1 -0
- package/dist/src/orchestrator/stream-parser.js +131 -0
- package/dist/src/orchestrator/types.d.ts +205 -0
- package/dist/src/orchestrator/types.d.ts.map +1 -0
- package/dist/src/orchestrator/types.js +4 -0
- package/dist/src/providers/amp-provider.d.ts +20 -0
- package/dist/src/providers/amp-provider.d.ts.map +1 -0
- package/dist/src/providers/amp-provider.js +24 -0
- package/dist/src/providers/claude-provider.d.ts +18 -0
- package/dist/src/providers/claude-provider.d.ts.map +1 -0
- package/dist/src/providers/claude-provider.js +267 -0
- package/dist/src/providers/codex-provider.d.ts +21 -0
- package/dist/src/providers/codex-provider.d.ts.map +1 -0
- package/dist/src/providers/codex-provider.js +25 -0
- package/dist/src/providers/index.d.ts +42 -0
- package/dist/src/providers/index.d.ts.map +1 -0
- package/dist/src/providers/index.js +77 -0
- package/dist/src/providers/types.d.ts +147 -0
- package/dist/src/providers/types.d.ts.map +1 -0
- package/dist/src/providers/types.js +13 -0
- package/package.json +63 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Supaku
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deployment Status Checker
|
|
3
|
+
*
|
|
4
|
+
* Queries GitHub commit status API for Vercel deployment state.
|
|
5
|
+
* Used to verify deployments before QA/acceptance work can proceed.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Individual deployment status for a Vercel app
|
|
9
|
+
*/
|
|
10
|
+
export interface DeploymentStatus {
|
|
11
|
+
/** The app name (e.g., "supaku-social") */
|
|
12
|
+
app: string;
|
|
13
|
+
/** Deployment state */
|
|
14
|
+
state: 'success' | 'pending' | 'error' | 'failure';
|
|
15
|
+
/** Status description (e.g., "Deployment has completed") */
|
|
16
|
+
description: string;
|
|
17
|
+
/** Vercel preview URL if available */
|
|
18
|
+
targetUrl: string | null;
|
|
19
|
+
/** Full context string from GitHub */
|
|
20
|
+
context: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Result of checking deployment status for a commit
|
|
24
|
+
*/
|
|
25
|
+
export interface DeploymentCheckResult {
|
|
26
|
+
/** Whether all deployments succeeded */
|
|
27
|
+
allSucceeded: boolean;
|
|
28
|
+
/** Whether any deployment failed */
|
|
29
|
+
anyFailed: boolean;
|
|
30
|
+
/** Whether any deployment is still pending */
|
|
31
|
+
anyPending: boolean;
|
|
32
|
+
/** Individual deployment statuses */
|
|
33
|
+
statuses: DeploymentStatus[];
|
|
34
|
+
/** The commit SHA that was checked */
|
|
35
|
+
commitSha: string;
|
|
36
|
+
/** Overall state from GitHub */
|
|
37
|
+
overallState: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Options for checking deployment status
|
|
41
|
+
*/
|
|
42
|
+
export interface DeploymentCheckOptions {
|
|
43
|
+
/** GitHub repository owner */
|
|
44
|
+
owner?: string;
|
|
45
|
+
/** GitHub repository name */
|
|
46
|
+
repo?: string;
|
|
47
|
+
/** Timeout for GitHub API call in milliseconds */
|
|
48
|
+
timeout?: number;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get the PR number for the current branch using gh CLI
|
|
52
|
+
*/
|
|
53
|
+
export declare function getPRNumber(timeout?: number): Promise<number | null>;
|
|
54
|
+
/**
|
|
55
|
+
* Get the head commit SHA for a PR
|
|
56
|
+
*/
|
|
57
|
+
export declare function getPRHeadSha(prNumber: number, options?: DeploymentCheckOptions): Promise<string | null>;
|
|
58
|
+
/**
|
|
59
|
+
* Check deployment status for a specific commit SHA
|
|
60
|
+
*/
|
|
61
|
+
export declare function checkDeploymentStatus(commitSha: string, options?: DeploymentCheckOptions): Promise<DeploymentCheckResult>;
|
|
62
|
+
/**
|
|
63
|
+
* Check deployment status for a PR number
|
|
64
|
+
* Convenience function that gets the commit SHA and checks status
|
|
65
|
+
*/
|
|
66
|
+
export declare function checkPRDeploymentStatus(prNumber: number, options?: DeploymentCheckOptions): Promise<DeploymentCheckResult | null>;
|
|
67
|
+
/**
|
|
68
|
+
* Format deployment check result for display
|
|
69
|
+
*/
|
|
70
|
+
export declare function formatDeploymentStatus(result: DeploymentCheckResult): string;
|
|
71
|
+
/**
|
|
72
|
+
* Format failed deployments for a comment
|
|
73
|
+
*/
|
|
74
|
+
export declare function formatFailedDeployments(result: DeploymentCheckResult): string;
|
|
75
|
+
/**
|
|
76
|
+
* PR information found for an issue
|
|
77
|
+
*/
|
|
78
|
+
export interface IssuePRInfo {
|
|
79
|
+
/** PR number */
|
|
80
|
+
number: number;
|
|
81
|
+
/** Head commit SHA */
|
|
82
|
+
headSha: string;
|
|
83
|
+
/** Branch name */
|
|
84
|
+
branch: string;
|
|
85
|
+
/** PR title */
|
|
86
|
+
title: string;
|
|
87
|
+
/** PR URL */
|
|
88
|
+
url: string;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Find open PRs associated with a Linear issue identifier
|
|
92
|
+
* Searches for PRs with the issue identifier in the branch name or title
|
|
93
|
+
*
|
|
94
|
+
* @param issueIdentifier - The Linear issue identifier (e.g., "SUP-123")
|
|
95
|
+
* @param options - Options for the search
|
|
96
|
+
* @returns Array of matching PRs
|
|
97
|
+
*/
|
|
98
|
+
export declare function findPRsForIssue(issueIdentifier: string, options?: DeploymentCheckOptions): Promise<IssuePRInfo[]>;
|
|
99
|
+
/**
|
|
100
|
+
* Check deployment status for an issue by finding associated PRs
|
|
101
|
+
* Returns the first PR's deployment status, or null if no PRs found
|
|
102
|
+
*
|
|
103
|
+
* @param issueIdentifier - The Linear issue identifier (e.g., "SUP-123")
|
|
104
|
+
* @param options - Options for the search and check
|
|
105
|
+
* @returns Deployment check result with PR info, or null if no PR found
|
|
106
|
+
*/
|
|
107
|
+
export declare function checkIssueDeploymentStatus(issueIdentifier: string, options?: DeploymentCheckOptions): Promise<(DeploymentCheckResult & {
|
|
108
|
+
pr: IssuePRInfo;
|
|
109
|
+
}) | null>;
|
|
110
|
+
//# sourceMappingURL=deployment-checker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deployment-checker.d.ts","sourceRoot":"","sources":["../../../src/deployment/deployment-checker.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,2CAA2C;IAC3C,GAAG,EAAE,MAAM,CAAA;IACX,uBAAuB;IACvB,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAA;IAClD,4DAA4D;IAC5D,WAAW,EAAE,MAAM,CAAA;IACnB,sCAAsC;IACtC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,wCAAwC;IACxC,YAAY,EAAE,OAAO,CAAA;IACrB,oCAAoC;IACpC,SAAS,EAAE,OAAO,CAAA;IAClB,8CAA8C;IAC9C,UAAU,EAAE,OAAO,CAAA;IACnB,qCAAqC;IACrC,QAAQ,EAAE,gBAAgB,EAAE,CAAA;IAC5B,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAA;IACjB,gCAAgC;IAChC,YAAY,EAAE,MAAM,CAAA;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,6BAA6B;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,kDAAkD;IAClD,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAyDD;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,GAAE,MAAc,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWjF;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAYxB;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,qBAAqB,CAAC,CA+ChC;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAMvC;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,CAmD5E;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,CAmB7E;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,gBAAgB;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,kBAAkB;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,eAAe;IACf,KAAK,EAAE,MAAM,CAAA;IACb,aAAa;IACb,GAAG,EAAE,MAAM,CAAA;CACZ;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,eAAe,EAAE,MAAM,EACvB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,WAAW,EAAE,CAAC,CAsCxB;AAED;;;;;;;GAOG;AACH,wBAAsB,0BAA0B,CAC9C,eAAe,EAAE,MAAM,EACvB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,CAAC,qBAAqB,GAAG;IAAE,EAAE,EAAE,WAAW,CAAA;CAAE,CAAC,GAAG,IAAI,CAAC,CAe/D"}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deployment Status Checker
|
|
3
|
+
*
|
|
4
|
+
* Queries GitHub commit status API for Vercel deployment state.
|
|
5
|
+
* Used to verify deployments before QA/acceptance work can proceed.
|
|
6
|
+
*/
|
|
7
|
+
import { exec } from 'child_process';
|
|
8
|
+
import { promisify } from 'util';
|
|
9
|
+
const execAsync = promisify(exec);
|
|
10
|
+
const DEFAULT_OPTIONS = {
|
|
11
|
+
owner: 'supaku',
|
|
12
|
+
repo: 'agentfactory',
|
|
13
|
+
timeout: 30000,
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Parse Vercel app name from GitHub status context
|
|
17
|
+
* Contexts look like: "Vercel – supaku-social" or "Vercel"
|
|
18
|
+
*/
|
|
19
|
+
function parseAppName(context) {
|
|
20
|
+
// Extract app name after "Vercel – " or "Vercel - "
|
|
21
|
+
const match = context.match(/Vercel\s*[–-]\s*(.+)/);
|
|
22
|
+
if (match) {
|
|
23
|
+
return match[1].trim();
|
|
24
|
+
}
|
|
25
|
+
// Fallback to just "Vercel" if no app name
|
|
26
|
+
return context;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Check if a status description indicates a successful skip (monorepo optimization)
|
|
30
|
+
* Vercel skips deployments for unchanged apps, which is treated as success
|
|
31
|
+
*/
|
|
32
|
+
function isSuccessfulSkip(description) {
|
|
33
|
+
return description.toLowerCase().includes('skipped') &&
|
|
34
|
+
description.toLowerCase().includes('not affected');
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Map GitHub status state to our normalized state
|
|
38
|
+
*/
|
|
39
|
+
function normalizeState(state, description) {
|
|
40
|
+
// Handle successful skips as success
|
|
41
|
+
if (isSuccessfulSkip(description)) {
|
|
42
|
+
return 'success';
|
|
43
|
+
}
|
|
44
|
+
switch (state.toLowerCase()) {
|
|
45
|
+
case 'success':
|
|
46
|
+
return 'success';
|
|
47
|
+
case 'pending':
|
|
48
|
+
return 'pending';
|
|
49
|
+
case 'failure':
|
|
50
|
+
return 'failure';
|
|
51
|
+
case 'error':
|
|
52
|
+
return 'error';
|
|
53
|
+
default:
|
|
54
|
+
return 'pending';
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get the PR number for the current branch using gh CLI
|
|
59
|
+
*/
|
|
60
|
+
export async function getPRNumber(timeout = 30000) {
|
|
61
|
+
try {
|
|
62
|
+
const { stdout } = await execAsync('gh pr list --head "$(git branch --show-current)" --json number -q ".[0].number"', { timeout });
|
|
63
|
+
const prNumber = parseInt(stdout.trim(), 10);
|
|
64
|
+
return isNaN(prNumber) ? null : prNumber;
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get the head commit SHA for a PR
|
|
72
|
+
*/
|
|
73
|
+
export async function getPRHeadSha(prNumber, options = {}) {
|
|
74
|
+
const { owner, repo, timeout } = { ...DEFAULT_OPTIONS, ...options };
|
|
75
|
+
try {
|
|
76
|
+
const { stdout } = await execAsync(`gh api repos/${owner}/${repo}/pulls/${prNumber} --jq '.head.sha'`, { timeout });
|
|
77
|
+
return stdout.trim() || null;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Check deployment status for a specific commit SHA
|
|
85
|
+
*/
|
|
86
|
+
export async function checkDeploymentStatus(commitSha, options = {}) {
|
|
87
|
+
const { owner, repo, timeout } = { ...DEFAULT_OPTIONS, ...options };
|
|
88
|
+
const { stdout } = await execAsync(`gh api repos/${owner}/${repo}/commits/${commitSha}/status`, { timeout });
|
|
89
|
+
const response = JSON.parse(stdout);
|
|
90
|
+
// Extract Vercel-related statuses
|
|
91
|
+
const allStatuses = response.statuses || [];
|
|
92
|
+
// Filter to only Vercel statuses
|
|
93
|
+
const vercelStatuses = allStatuses.filter((s) => s.context.toLowerCase().includes('vercel'));
|
|
94
|
+
const deploymentStatuses = vercelStatuses.map((s) => ({
|
|
95
|
+
app: parseAppName(s.context),
|
|
96
|
+
state: normalizeState(s.state, s.description || ''),
|
|
97
|
+
description: s.description || '',
|
|
98
|
+
targetUrl: s.target_url,
|
|
99
|
+
context: s.context,
|
|
100
|
+
}));
|
|
101
|
+
// Calculate aggregate states
|
|
102
|
+
const allSucceeded = deploymentStatuses.length > 0 &&
|
|
103
|
+
deploymentStatuses.every((s) => s.state === 'success');
|
|
104
|
+
const anyFailed = deploymentStatuses.some((s) => s.state === 'failure' || s.state === 'error');
|
|
105
|
+
const anyPending = deploymentStatuses.some((s) => s.state === 'pending');
|
|
106
|
+
return {
|
|
107
|
+
allSucceeded,
|
|
108
|
+
anyFailed,
|
|
109
|
+
anyPending,
|
|
110
|
+
statuses: deploymentStatuses,
|
|
111
|
+
commitSha,
|
|
112
|
+
overallState: response.state || 'unknown',
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Check deployment status for a PR number
|
|
117
|
+
* Convenience function that gets the commit SHA and checks status
|
|
118
|
+
*/
|
|
119
|
+
export async function checkPRDeploymentStatus(prNumber, options = {}) {
|
|
120
|
+
const commitSha = await getPRHeadSha(prNumber, options);
|
|
121
|
+
if (!commitSha) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
return checkDeploymentStatus(commitSha, options);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Format deployment check result for display
|
|
128
|
+
*/
|
|
129
|
+
export function formatDeploymentStatus(result) {
|
|
130
|
+
const lines = [];
|
|
131
|
+
lines.push(`## Deployment Status Check`);
|
|
132
|
+
lines.push(``);
|
|
133
|
+
lines.push(`**Commit:** \`${result.commitSha.slice(0, 7)}\``);
|
|
134
|
+
lines.push(`**Overall State:** ${result.overallState}`);
|
|
135
|
+
lines.push(``);
|
|
136
|
+
if (result.statuses.length === 0) {
|
|
137
|
+
lines.push(`No Vercel deployments found for this commit.`);
|
|
138
|
+
return lines.join('\n');
|
|
139
|
+
}
|
|
140
|
+
lines.push(`| App | State | Description |`);
|
|
141
|
+
lines.push(`|-----|-------|-------------|`);
|
|
142
|
+
for (const status of result.statuses) {
|
|
143
|
+
const stateEmoji = {
|
|
144
|
+
success: '✅',
|
|
145
|
+
pending: '⏳',
|
|
146
|
+
failure: '❌',
|
|
147
|
+
error: '❌',
|
|
148
|
+
}[status.state];
|
|
149
|
+
const url = status.targetUrl
|
|
150
|
+
? `[${status.app}](${status.targetUrl})`
|
|
151
|
+
: status.app;
|
|
152
|
+
lines.push(`| ${url} | ${stateEmoji} ${status.state} | ${status.description} |`);
|
|
153
|
+
}
|
|
154
|
+
lines.push(``);
|
|
155
|
+
if (result.anyFailed) {
|
|
156
|
+
lines.push(`### ❌ Deployment Failed`);
|
|
157
|
+
lines.push(``);
|
|
158
|
+
lines.push(`One or more Vercel deployments failed. QA/acceptance cannot proceed until deployments succeed.`);
|
|
159
|
+
}
|
|
160
|
+
else if (result.anyPending) {
|
|
161
|
+
lines.push(`### ⏳ Deployment Pending`);
|
|
162
|
+
lines.push(``);
|
|
163
|
+
lines.push(`One or more Vercel deployments are still in progress.`);
|
|
164
|
+
}
|
|
165
|
+
else if (result.allSucceeded) {
|
|
166
|
+
lines.push(`### ✅ All Deployments Succeeded`);
|
|
167
|
+
lines.push(``);
|
|
168
|
+
lines.push(`All Vercel deployments have completed successfully.`);
|
|
169
|
+
}
|
|
170
|
+
return lines.join('\n');
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Format failed deployments for a comment
|
|
174
|
+
*/
|
|
175
|
+
export function formatFailedDeployments(result) {
|
|
176
|
+
const failed = result.statuses.filter((s) => s.state === 'failure' || s.state === 'error');
|
|
177
|
+
if (failed.length === 0) {
|
|
178
|
+
return 'No failed deployments.';
|
|
179
|
+
}
|
|
180
|
+
const lines = ['**Failed Deployments:**', ''];
|
|
181
|
+
for (const status of failed) {
|
|
182
|
+
const url = status.targetUrl
|
|
183
|
+
? ` - [View logs](${status.targetUrl})`
|
|
184
|
+
: '';
|
|
185
|
+
lines.push(`- **${status.app}**: ${status.description}${url}`);
|
|
186
|
+
}
|
|
187
|
+
return lines.join('\n');
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Find open PRs associated with a Linear issue identifier
|
|
191
|
+
* Searches for PRs with the issue identifier in the branch name or title
|
|
192
|
+
*
|
|
193
|
+
* @param issueIdentifier - The Linear issue identifier (e.g., "SUP-123")
|
|
194
|
+
* @param options - Options for the search
|
|
195
|
+
* @returns Array of matching PRs
|
|
196
|
+
*/
|
|
197
|
+
export async function findPRsForIssue(issueIdentifier, options = {}) {
|
|
198
|
+
const { owner, repo, timeout } = { ...DEFAULT_OPTIONS, ...options };
|
|
199
|
+
try {
|
|
200
|
+
// Search for PRs with the issue identifier in branch name or title
|
|
201
|
+
const { stdout } = await execAsync(`gh pr list --repo ${owner}/${repo} --state open --json number,headRefName,headRefOid,title,url --search "${issueIdentifier}"`, { timeout });
|
|
202
|
+
const prs = JSON.parse(stdout || '[]');
|
|
203
|
+
// Filter to PRs that actually match the issue identifier
|
|
204
|
+
const lowerIdentifier = issueIdentifier.toLowerCase();
|
|
205
|
+
const matchingPRs = prs.filter((pr) => {
|
|
206
|
+
const branchMatch = pr.headRefName.toLowerCase().includes(lowerIdentifier);
|
|
207
|
+
const titleMatch = pr.title.toLowerCase().includes(lowerIdentifier);
|
|
208
|
+
return branchMatch || titleMatch;
|
|
209
|
+
});
|
|
210
|
+
return matchingPRs.map((pr) => ({
|
|
211
|
+
number: pr.number,
|
|
212
|
+
headSha: pr.headRefOid,
|
|
213
|
+
branch: pr.headRefName,
|
|
214
|
+
title: pr.title,
|
|
215
|
+
url: pr.url,
|
|
216
|
+
}));
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
return [];
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Check deployment status for an issue by finding associated PRs
|
|
224
|
+
* Returns the first PR's deployment status, or null if no PRs found
|
|
225
|
+
*
|
|
226
|
+
* @param issueIdentifier - The Linear issue identifier (e.g., "SUP-123")
|
|
227
|
+
* @param options - Options for the search and check
|
|
228
|
+
* @returns Deployment check result with PR info, or null if no PR found
|
|
229
|
+
*/
|
|
230
|
+
export async function checkIssueDeploymentStatus(issueIdentifier, options = {}) {
|
|
231
|
+
const prs = await findPRsForIssue(issueIdentifier, options);
|
|
232
|
+
if (prs.length === 0) {
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
// Use the first matching PR (most recent PRs are returned first by gh)
|
|
236
|
+
const pr = prs[0];
|
|
237
|
+
const result = await checkDeploymentStatus(pr.headSha, options);
|
|
238
|
+
return {
|
|
239
|
+
...result,
|
|
240
|
+
pr,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { checkDeploymentStatus, checkPRDeploymentStatus, checkIssueDeploymentStatus, findPRsForIssue, getPRNumber, getPRHeadSha, formatDeploymentStatus, formatFailedDeployments, } from './deployment-checker';
|
|
2
|
+
export type { DeploymentStatus, DeploymentCheckResult, DeploymentCheckOptions, IssuePRInfo, } from './deployment-checker';
|
|
3
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/deployment/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,0BAA0B,EAC1B,eAAe,EACf,WAAW,EACX,YAAY,EACZ,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,sBAAsB,CAAA;AAE7B,YAAY,EACV,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,EACtB,WAAW,GACZ,MAAM,sBAAsB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,UAAU,CAAA;AACxB,cAAc,cAAc,CAAA"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logger utility for worker and orchestrator output
|
|
3
|
+
*
|
|
4
|
+
* Provides colorized, structured logging with worker/agent context.
|
|
5
|
+
* Uses ANSI escape codes directly to avoid external dependencies.
|
|
6
|
+
*/
|
|
7
|
+
declare const colors: {
|
|
8
|
+
readonly reset: "\u001B[0m";
|
|
9
|
+
readonly bold: "\u001B[1m";
|
|
10
|
+
readonly dim: "\u001B[2m";
|
|
11
|
+
readonly black: "\u001B[30m";
|
|
12
|
+
readonly red: "\u001B[31m";
|
|
13
|
+
readonly green: "\u001B[32m";
|
|
14
|
+
readonly yellow: "\u001B[33m";
|
|
15
|
+
readonly blue: "\u001B[34m";
|
|
16
|
+
readonly magenta: "\u001B[35m";
|
|
17
|
+
readonly cyan: "\u001B[36m";
|
|
18
|
+
readonly white: "\u001B[37m";
|
|
19
|
+
readonly brightBlack: "\u001B[90m";
|
|
20
|
+
readonly brightRed: "\u001B[91m";
|
|
21
|
+
readonly brightGreen: "\u001B[92m";
|
|
22
|
+
readonly brightYellow: "\u001B[93m";
|
|
23
|
+
readonly brightBlue: "\u001B[94m";
|
|
24
|
+
readonly brightMagenta: "\u001B[95m";
|
|
25
|
+
readonly brightCyan: "\u001B[96m";
|
|
26
|
+
readonly brightWhite: "\u001B[97m";
|
|
27
|
+
readonly bgBlack: "\u001B[40m";
|
|
28
|
+
readonly bgRed: "\u001B[41m";
|
|
29
|
+
readonly bgGreen: "\u001B[42m";
|
|
30
|
+
readonly bgYellow: "\u001B[43m";
|
|
31
|
+
readonly bgBlue: "\u001B[44m";
|
|
32
|
+
readonly bgMagenta: "\u001B[45m";
|
|
33
|
+
readonly bgCyan: "\u001B[46m";
|
|
34
|
+
readonly bgWhite: "\u001B[47m";
|
|
35
|
+
};
|
|
36
|
+
type ColorName = keyof typeof colors;
|
|
37
|
+
declare const LEVEL_STYLES: Record<string, {
|
|
38
|
+
color: ColorName;
|
|
39
|
+
label: string;
|
|
40
|
+
}>;
|
|
41
|
+
export type LogLevel = keyof typeof LEVEL_STYLES;
|
|
42
|
+
export interface LoggerContext {
|
|
43
|
+
workerId?: string;
|
|
44
|
+
workerShortId?: string;
|
|
45
|
+
issueIdentifier?: string;
|
|
46
|
+
sessionId?: string;
|
|
47
|
+
}
|
|
48
|
+
export interface LoggerOptions {
|
|
49
|
+
showTimestamp?: boolean;
|
|
50
|
+
showLevel?: boolean;
|
|
51
|
+
colorEnabled?: boolean;
|
|
52
|
+
minLevel?: LogLevel;
|
|
53
|
+
}
|
|
54
|
+
export declare class Logger {
|
|
55
|
+
private context;
|
|
56
|
+
private options;
|
|
57
|
+
constructor(context?: LoggerContext, options?: LoggerOptions);
|
|
58
|
+
/**
|
|
59
|
+
* Create a child logger with additional context
|
|
60
|
+
*/
|
|
61
|
+
child(additionalContext: LoggerContext): Logger;
|
|
62
|
+
/**
|
|
63
|
+
* Format the context prefix (worker ID, issue identifier)
|
|
64
|
+
*/
|
|
65
|
+
private formatPrefix;
|
|
66
|
+
/**
|
|
67
|
+
* Format a log line
|
|
68
|
+
*/
|
|
69
|
+
private formatLine;
|
|
70
|
+
/**
|
|
71
|
+
* Format data object for display
|
|
72
|
+
*/
|
|
73
|
+
private formatData;
|
|
74
|
+
/**
|
|
75
|
+
* Check if a log level should be output
|
|
76
|
+
*/
|
|
77
|
+
private shouldLog;
|
|
78
|
+
/**
|
|
79
|
+
* Core log method
|
|
80
|
+
*/
|
|
81
|
+
private log;
|
|
82
|
+
debug(message: string, data?: Record<string, unknown>): void;
|
|
83
|
+
info(message: string, data?: Record<string, unknown>): void;
|
|
84
|
+
success(message: string, data?: Record<string, unknown>): void;
|
|
85
|
+
warn(message: string, data?: Record<string, unknown>): void;
|
|
86
|
+
error(message: string, data?: Record<string, unknown>): void;
|
|
87
|
+
/**
|
|
88
|
+
* Log an activity (thought, action, response) with appropriate styling
|
|
89
|
+
*/
|
|
90
|
+
activity(type: string, content: string, maxLength?: number): void;
|
|
91
|
+
/**
|
|
92
|
+
* Log a section header/divider
|
|
93
|
+
*/
|
|
94
|
+
section(title: string): void;
|
|
95
|
+
/**
|
|
96
|
+
* Log a status change with visual indicator
|
|
97
|
+
*/
|
|
98
|
+
status(status: string, details?: string): void;
|
|
99
|
+
/**
|
|
100
|
+
* Log a tool call with formatted input
|
|
101
|
+
*/
|
|
102
|
+
toolCall(toolName: string, input?: Record<string, unknown>): void;
|
|
103
|
+
/**
|
|
104
|
+
* Format tool input for display (show relevant params based on tool type)
|
|
105
|
+
*/
|
|
106
|
+
private formatToolInput;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Create a logger instance
|
|
110
|
+
*/
|
|
111
|
+
export declare function createLogger(context?: LoggerContext, options?: LoggerOptions): Logger;
|
|
112
|
+
/**
|
|
113
|
+
* Default logger for quick use
|
|
114
|
+
*/
|
|
115
|
+
export declare const logger: Logger;
|
|
116
|
+
export {};
|
|
117
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/logger.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkCF,CAAA;AAEV,KAAK,SAAS,GAAG,MAAM,OAAO,MAAM,CAAA;AAepC,QAAA,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAMrE,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,YAAY,CAAA;AAEhD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,EAAE,QAAQ,CAAA;CACpB;AAwCD,qBAAa,MAAM;IACjB,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,OAAO,CAAyB;gBAE5B,OAAO,GAAE,aAAkB,EAAE,OAAO,GAAE,aAAkB;IAUpE;;OAEG;IACH,KAAK,CAAC,iBAAiB,EAAE,aAAa,GAAG,MAAM;IAO/C;;OAEG;IACH,OAAO,CAAC,YAAY;IA2BpB;;OAEG;IACH,OAAO,CAAC,UAAU;IA6ClB;;OAEG;IACH,OAAO,CAAC,UAAU;IAiBlB;;OAEG;IACH,OAAO,CAAC,SAAS;IAIjB;;OAEG;IACH,OAAO,CAAC,GAAG;IAcX,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI5D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI3D,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI9D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI3D,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI5D;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,SAAK,GAAG,IAAI;IAqC7D;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAa5B;;OAEG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAoD9C;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAkDjE;;OAEG;IACH,OAAO,CAAC,eAAe;CA0BxB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM,CAErF;AAED;;GAEG;AACH,eAAO,MAAM,MAAM,QAAiB,CAAA"}
|