@cluesmith/codev 3.0.0-rc.1 → 3.0.0-rc.3
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/dashboard/dist/assets/{index-CiIBsixF.js → index-CziHWiV5.js} +41 -41
- package/dashboard/dist/assets/index-CziHWiV5.js.map +1 -0
- package/dashboard/dist/index.html +1 -1
- package/dist/agent-farm/cli.d.ts.map +1 -1
- package/dist/agent-farm/cli.js +4 -0
- package/dist/agent-farm/cli.js.map +1 -1
- package/dist/agent-farm/commands/cleanup.d.ts.map +1 -1
- package/dist/agent-farm/commands/cleanup.js +10 -5
- package/dist/agent-farm/commands/cleanup.js.map +1 -1
- package/dist/agent-farm/commands/spawn-roles.d.ts +1 -0
- package/dist/agent-farm/commands/spawn-roles.d.ts.map +1 -1
- package/dist/agent-farm/commands/spawn-roles.js.map +1 -1
- package/dist/agent-farm/commands/spawn-worktree.d.ts +48 -9
- package/dist/agent-farm/commands/spawn-worktree.d.ts.map +1 -1
- package/dist/agent-farm/commands/spawn-worktree.js +261 -39
- package/dist/agent-farm/commands/spawn-worktree.js.map +1 -1
- package/dist/agent-farm/commands/spawn.d.ts.map +1 -1
- package/dist/agent-farm/commands/spawn.js +98 -27
- package/dist/agent-farm/commands/spawn.js.map +1 -1
- package/dist/agent-farm/commands/team-update.d.ts.map +1 -1
- package/dist/agent-farm/commands/team-update.js +7 -4
- package/dist/agent-farm/commands/team-update.js.map +1 -1
- package/dist/agent-farm/commands/team.d.ts.map +1 -1
- package/dist/agent-farm/commands/team.js +6 -2
- package/dist/agent-farm/commands/team.js.map +1 -1
- package/dist/agent-farm/servers/overview.d.ts +7 -7
- package/dist/agent-farm/servers/overview.d.ts.map +1 -1
- package/dist/agent-farm/servers/overview.js +35 -33
- package/dist/agent-farm/servers/overview.js.map +1 -1
- package/dist/agent-farm/types.d.ts +4 -0
- package/dist/agent-farm/types.d.ts.map +1 -1
- package/dist/commands/consult/index.d.ts.map +1 -1
- package/dist/commands/consult/index.js +86 -69
- package/dist/commands/consult/index.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +67 -23
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/porch/checks.d.ts +6 -2
- package/dist/commands/porch/checks.d.ts.map +1 -1
- package/dist/commands/porch/checks.js +52 -3
- package/dist/commands/porch/checks.js.map +1 -1
- package/dist/commands/porch/next.d.ts.map +1 -1
- package/dist/commands/porch/next.js +8 -1
- package/dist/commands/porch/next.js.map +1 -1
- package/dist/commands/porch/prompts.js +2 -2
- package/dist/commands/porch/prompts.js.map +1 -1
- package/dist/commands/porch/state.d.ts.map +1 -1
- package/dist/commands/porch/state.js +7 -3
- package/dist/commands/porch/state.js.map +1 -1
- package/dist/lib/forge-contracts.d.ts +94 -0
- package/dist/lib/forge-contracts.d.ts.map +1 -0
- package/dist/lib/forge-contracts.js +35 -0
- package/dist/lib/forge-contracts.js.map +1 -0
- package/dist/lib/forge.d.ts +102 -0
- package/dist/lib/forge.d.ts.map +1 -0
- package/dist/lib/forge.js +384 -0
- package/dist/lib/forge.js.map +1 -0
- package/dist/lib/github.d.ts +68 -60
- package/dist/lib/github.d.ts.map +1 -1
- package/dist/lib/github.js +160 -169
- package/dist/lib/github.js.map +1 -1
- package/dist/lib/team-github.d.ts +5 -3
- package/dist/lib/team-github.d.ts.map +1 -1
- package/dist/lib/team-github.js +25 -15
- package/dist/lib/team-github.js.map +1 -1
- package/package.json +3 -2
- package/scripts/forge/gitea/auth-status.sh +3 -0
- package/scripts/forge/gitea/issue-comment.sh +3 -0
- package/scripts/forge/gitea/issue-list.sh +3 -0
- package/scripts/forge/gitea/issue-view.sh +3 -0
- package/scripts/forge/gitea/pr-exists.sh +3 -0
- package/scripts/forge/gitea/pr-list.sh +3 -0
- package/scripts/forge/gitea/pr-merge.sh +3 -0
- package/scripts/forge/gitea/pr-view.sh +3 -0
- package/scripts/forge/gitea/recently-closed.sh +3 -0
- package/scripts/forge/gitea/recently-merged.sh +3 -0
- package/scripts/forge/gitea/user-identity.sh +3 -0
- package/scripts/forge/github/auth-status.sh +4 -0
- package/scripts/forge/github/issue-comment.sh +5 -0
- package/scripts/forge/github/issue-list.sh +4 -0
- package/scripts/forge/github/issue-view.sh +5 -0
- package/scripts/forge/github/on-it-timestamps.sh +8 -0
- package/scripts/forge/github/pr-diff.sh +10 -0
- package/scripts/forge/github/pr-exists.sh +5 -0
- package/scripts/forge/github/pr-list.sh +4 -0
- package/scripts/forge/github/pr-merge.sh +5 -0
- package/scripts/forge/github/pr-search.sh +5 -0
- package/scripts/forge/github/pr-view.sh +11 -0
- package/scripts/forge/github/recently-closed.sh +15 -0
- package/scripts/forge/github/recently-merged.sh +15 -0
- package/scripts/forge/github/team-activity.sh +5 -0
- package/scripts/forge/github/user-identity.sh +4 -0
- package/scripts/forge/gitlab/auth-status.sh +3 -0
- package/scripts/forge/gitlab/issue-comment.sh +3 -0
- package/scripts/forge/gitlab/issue-list.sh +3 -0
- package/scripts/forge/gitlab/issue-view.sh +3 -0
- package/scripts/forge/gitlab/pr-diff.sh +3 -0
- package/scripts/forge/gitlab/pr-exists.sh +3 -0
- package/scripts/forge/gitlab/pr-list.sh +3 -0
- package/scripts/forge/gitlab/pr-merge.sh +3 -0
- package/scripts/forge/gitlab/pr-search.sh +3 -0
- package/scripts/forge/gitlab/pr-view.sh +3 -0
- package/scripts/forge/gitlab/recently-closed.sh +3 -0
- package/scripts/forge/gitlab/recently-merged.sh +3 -0
- package/scripts/forge/gitlab/user-identity.sh +3 -0
- package/skeleton/roles/architect.md +18 -6
- package/dashboard/dist/assets/index-CiIBsixF.js.map +0 -1
package/dist/lib/github.js
CHANGED
|
@@ -1,239 +1,230 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Shared
|
|
2
|
+
* Shared forge utilities for Codev.
|
|
3
3
|
*
|
|
4
|
-
* Provides non-fatal
|
|
4
|
+
* Provides non-fatal forge API access via configurable concept commands.
|
|
5
|
+
* Default commands wrap the `gh` CLI. Projects can override via af-config.json.
|
|
5
6
|
* All functions return `null` on failure instead of throwing,
|
|
6
|
-
* enabling graceful degradation when
|
|
7
|
+
* enabling graceful degradation when forge is unavailable.
|
|
8
|
+
*
|
|
9
|
+
* @see codev/specs/589-non-github-repository-support.md
|
|
7
10
|
*/
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
const execFileAsync = promisify(execFile);
|
|
11
|
+
import { executeForgeCommand } from './forge.js';
|
|
12
|
+
import { getRepoInfo } from './team-github.js';
|
|
11
13
|
// =============================================================================
|
|
12
|
-
// Core
|
|
14
|
+
// Core forge API functions (non-fatal, via concept commands)
|
|
13
15
|
// =============================================================================
|
|
14
16
|
/**
|
|
15
|
-
* Fetch a single
|
|
16
|
-
*
|
|
17
|
+
* Fetch a single issue by ID.
|
|
18
|
+
* Routes through the `issue-view` concept command.
|
|
19
|
+
* Returns null if the concept command fails.
|
|
20
|
+
*
|
|
21
|
+
* @param issueId - Issue identifier (number or string)
|
|
22
|
+
* @param options - Optional forge config and cwd
|
|
17
23
|
*/
|
|
18
|
-
export async function
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
catch {
|
|
27
|
-
return null;
|
|
28
|
-
}
|
|
24
|
+
export async function fetchIssue(issueId, options) {
|
|
25
|
+
const result = await executeForgeCommand('issue-view', {
|
|
26
|
+
CODEV_ISSUE_ID: String(issueId),
|
|
27
|
+
}, {
|
|
28
|
+
cwd: options?.cwd,
|
|
29
|
+
forgeConfig: options?.forgeConfig,
|
|
30
|
+
});
|
|
31
|
+
return result;
|
|
29
32
|
}
|
|
30
33
|
/**
|
|
31
|
-
* Fetch a single
|
|
34
|
+
* Fetch a single issue by ID.
|
|
32
35
|
* Throws on failure (for use in spawn where failure is fatal).
|
|
36
|
+
*
|
|
37
|
+
* @param issueId - Issue identifier (number or string)
|
|
38
|
+
* @param options - Optional forge config and cwd
|
|
33
39
|
*/
|
|
34
|
-
export async function
|
|
35
|
-
const issue = await
|
|
40
|
+
export async function fetchIssueOrThrow(issueId, options) {
|
|
41
|
+
const issue = await fetchIssue(issueId, options);
|
|
36
42
|
if (!issue) {
|
|
37
|
-
throw new Error(`Failed to fetch issue #${
|
|
43
|
+
throw new Error(`Failed to fetch issue #${issueId}. Ensure the 'issue-view' forge concept command is configured ` +
|
|
44
|
+
`(default: 'gh' CLI must be installed and authenticated). ` +
|
|
45
|
+
`Configure forge commands in af-config.json if using a non-GitHub forge.`);
|
|
38
46
|
}
|
|
39
47
|
return issue;
|
|
40
48
|
}
|
|
49
|
+
/** @deprecated Use fetchIssue instead. */
|
|
50
|
+
export const fetchGitHubIssue = fetchIssue;
|
|
51
|
+
/** @deprecated Use fetchIssueOrThrow instead. */
|
|
52
|
+
export const fetchGitHubIssueOrThrow = fetchIssueOrThrow;
|
|
41
53
|
/**
|
|
42
54
|
* Fetch open PRs for the current repo.
|
|
55
|
+
* Routes through the `pr-list` concept command.
|
|
43
56
|
* Returns null on failure.
|
|
44
|
-
* @param cwd - Working directory for `gh` CLI (determines which repo is queried).
|
|
45
57
|
*/
|
|
46
|
-
export async function fetchPRList(cwd) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return JSON.parse(stdout);
|
|
53
|
-
}
|
|
54
|
-
catch (err) {
|
|
55
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
56
|
-
console.warn(`[github] fetchPRList failed (cwd=${cwd ?? 'none'}): ${msg}`);
|
|
57
|
-
return null;
|
|
58
|
-
}
|
|
58
|
+
export async function fetchPRList(cwd, forgeConfig) {
|
|
59
|
+
const result = await executeForgeCommand('pr-list', {}, {
|
|
60
|
+
cwd,
|
|
61
|
+
forgeConfig,
|
|
62
|
+
});
|
|
63
|
+
return result;
|
|
59
64
|
}
|
|
60
65
|
/**
|
|
61
66
|
* Fetch open issues for the current repo.
|
|
67
|
+
* Routes through the `issue-list` concept command.
|
|
62
68
|
* Returns null on failure.
|
|
63
|
-
* @param cwd - Working directory for `gh` CLI (determines which repo is queried).
|
|
64
69
|
*/
|
|
65
|
-
export async function fetchIssueList(cwd) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
], { cwd });
|
|
72
|
-
return JSON.parse(stdout);
|
|
73
|
-
}
|
|
74
|
-
catch (err) {
|
|
75
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
76
|
-
console.warn(`[github] fetchIssueList failed (cwd=${cwd ?? 'none'}): ${msg}`);
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
70
|
+
export async function fetchIssueList(cwd, forgeConfig) {
|
|
71
|
+
const result = await executeForgeCommand('issue-list', {}, {
|
|
72
|
+
cwd,
|
|
73
|
+
forgeConfig,
|
|
74
|
+
});
|
|
75
|
+
return result;
|
|
79
76
|
}
|
|
80
77
|
/**
|
|
81
78
|
* Fetch recently closed issues (last 24 hours).
|
|
79
|
+
* Routes through the `recently-closed` concept command.
|
|
82
80
|
* Returns null on failure.
|
|
83
|
-
* @param cwd - Working directory for `gh` CLI (determines which repo is queried).
|
|
84
81
|
*/
|
|
85
|
-
export async function fetchRecentlyClosed(cwd) {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
catch (err) {
|
|
99
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
100
|
-
console.warn(`[github] fetchRecentlyClosed failed (cwd=${cwd ?? 'none'}): ${msg}`);
|
|
101
|
-
return null;
|
|
102
|
-
}
|
|
82
|
+
export async function fetchRecentlyClosed(cwd, forgeConfig) {
|
|
83
|
+
const since = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString().split('T')[0];
|
|
84
|
+
const result = await executeForgeCommand('recently-closed', {
|
|
85
|
+
CODEV_SINCE_DATE: since,
|
|
86
|
+
}, {
|
|
87
|
+
cwd,
|
|
88
|
+
forgeConfig,
|
|
89
|
+
});
|
|
90
|
+
if (!result || !Array.isArray(result))
|
|
91
|
+
return result;
|
|
92
|
+
// Filter to last 24 hours (concept command may return more)
|
|
93
|
+
const cutoff = Date.now() - 24 * 60 * 60 * 1000;
|
|
94
|
+
return result.filter(i => i.closedAt && new Date(i.closedAt).getTime() >= cutoff);
|
|
103
95
|
}
|
|
104
96
|
/**
|
|
105
97
|
* Fetch recently merged PRs (last 24 hours).
|
|
98
|
+
* Routes through the `recently-merged` concept command.
|
|
106
99
|
* Returns null on failure.
|
|
107
|
-
* @param cwd - Working directory for `gh` CLI (determines which repo is queried).
|
|
108
100
|
*/
|
|
109
|
-
export async function fetchRecentMergedPRs(cwd) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
catch (err) {
|
|
123
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
124
|
-
console.warn(`[github] fetchMergedPRs failed (cwd=${cwd ?? 'none'}): ${msg}`);
|
|
125
|
-
return null;
|
|
126
|
-
}
|
|
101
|
+
export async function fetchRecentMergedPRs(cwd, forgeConfig) {
|
|
102
|
+
const since = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString().split('T')[0];
|
|
103
|
+
const result = await executeForgeCommand('recently-merged', {
|
|
104
|
+
CODEV_SINCE_DATE: since,
|
|
105
|
+
}, {
|
|
106
|
+
cwd,
|
|
107
|
+
forgeConfig,
|
|
108
|
+
});
|
|
109
|
+
if (!result || !Array.isArray(result))
|
|
110
|
+
return result;
|
|
111
|
+
// Filter to last 24 hours (concept command may return more)
|
|
112
|
+
const cutoff = Date.now() - 24 * 60 * 60 * 1000;
|
|
113
|
+
return result.filter(pr => pr.mergedAt && new Date(pr.mergedAt).getTime() >= cutoff);
|
|
127
114
|
}
|
|
128
115
|
/**
|
|
129
116
|
* Fetch merged PRs, optionally filtered to those merged since a given date.
|
|
130
|
-
*
|
|
117
|
+
* Routes through the `recently-merged` concept command.
|
|
131
118
|
* Returns null on failure.
|
|
132
119
|
*/
|
|
133
|
-
export async function fetchMergedPRs(since, cwd) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
'--state', 'merged',
|
|
138
|
-
'--json', 'number,title,createdAt,mergedAt,body,headRefName',
|
|
139
|
-
'--limit', '1000',
|
|
140
|
-
];
|
|
141
|
-
if (since) {
|
|
142
|
-
args.push('--search', `merged:>=${since}`);
|
|
143
|
-
}
|
|
144
|
-
const { stdout } = await execFileAsync('gh', args, { cwd });
|
|
145
|
-
return JSON.parse(stdout);
|
|
146
|
-
}
|
|
147
|
-
catch (err) {
|
|
148
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
149
|
-
console.warn(`[github] fetchMergedPRs failed (cwd=${cwd ?? 'none'}): ${msg}`);
|
|
150
|
-
return null;
|
|
120
|
+
export async function fetchMergedPRs(since, cwd, forgeConfig) {
|
|
121
|
+
const env = {};
|
|
122
|
+
if (since) {
|
|
123
|
+
env.CODEV_SINCE_DATE = since;
|
|
151
124
|
}
|
|
125
|
+
const result = await executeForgeCommand('recently-merged', env, {
|
|
126
|
+
cwd,
|
|
127
|
+
forgeConfig,
|
|
128
|
+
});
|
|
129
|
+
return result;
|
|
152
130
|
}
|
|
153
131
|
/**
|
|
154
132
|
* Fetch closed issues, optionally filtered to those closed since a given date.
|
|
155
|
-
*
|
|
133
|
+
* Routes through the `recently-closed` concept command.
|
|
156
134
|
* Returns null on failure.
|
|
157
135
|
*/
|
|
158
|
-
export async function fetchClosedIssues(since, cwd) {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
'--state', 'closed',
|
|
163
|
-
'--json', 'number,title,createdAt,closedAt,labels',
|
|
164
|
-
'--limit', '1000',
|
|
165
|
-
];
|
|
166
|
-
if (since) {
|
|
167
|
-
args.push('--search', `closed:>=${since}`);
|
|
168
|
-
}
|
|
169
|
-
const { stdout } = await execFileAsync('gh', args, { cwd });
|
|
170
|
-
return JSON.parse(stdout);
|
|
171
|
-
}
|
|
172
|
-
catch (err) {
|
|
173
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
174
|
-
console.warn(`[github] fetchClosedIssues failed (cwd=${cwd ?? 'none'}): ${msg}`);
|
|
175
|
-
return null;
|
|
136
|
+
export async function fetchClosedIssues(since, cwd, forgeConfig) {
|
|
137
|
+
const env = {};
|
|
138
|
+
if (since) {
|
|
139
|
+
env.CODEV_SINCE_DATE = since;
|
|
176
140
|
}
|
|
141
|
+
const result = await executeForgeCommand('recently-closed', env, {
|
|
142
|
+
cwd,
|
|
143
|
+
forgeConfig,
|
|
144
|
+
});
|
|
145
|
+
return result;
|
|
177
146
|
}
|
|
178
147
|
/**
|
|
179
|
-
* Fetch the "On it!" comment timestamp for multiple issues
|
|
148
|
+
* Fetch the "On it!" comment timestamp for multiple issues.
|
|
180
149
|
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
150
|
+
* Routes through the `on-it-timestamps` concept command. The default command
|
|
151
|
+
* uses `gh api graphql` with a batched query. Non-GitHub forges can provide
|
|
152
|
+
* a simpler command that accepts CODEV_ISSUE_NUMBERS (comma-separated) and
|
|
153
|
+
* returns a JSON map of issue number → ISO timestamp.
|
|
154
|
+
*
|
|
155
|
+
* For the default GitHub implementation, this function builds the GraphQL
|
|
156
|
+
* query internally and passes it via CODEV_GRAPHQL_QUERY. It also needs
|
|
157
|
+
* repo owner/name which it fetches via a separate gh call.
|
|
185
158
|
*
|
|
186
159
|
* Batches in groups of 50 to stay within GraphQL complexity limits.
|
|
187
|
-
*
|
|
160
|
+
* Returns empty map on failure (graceful degradation — analytics falls
|
|
161
|
+
* back to PR createdAt for wall-clock time).
|
|
188
162
|
*/
|
|
189
|
-
export async function fetchOnItTimestamps(
|
|
163
|
+
export async function fetchOnItTimestamps(issueIds, cwd, forgeConfig) {
|
|
190
164
|
const result = new Map();
|
|
191
|
-
if (
|
|
165
|
+
if (issueIds.length === 0)
|
|
166
|
+
return result;
|
|
167
|
+
const unique = [...new Set(issueIds)];
|
|
168
|
+
// Check if a custom (non-default) on-it-timestamps command is configured.
|
|
169
|
+
// Custom commands receive CODEV_ISSUE_NUMBERS and return a simple JSON map.
|
|
170
|
+
const customCmd = forgeConfig?.['on-it-timestamps'];
|
|
171
|
+
if (customCmd !== undefined) {
|
|
172
|
+
// Custom command or explicitly disabled (null)
|
|
173
|
+
if (customCmd === null)
|
|
174
|
+
return result;
|
|
175
|
+
const cmdResult = await executeForgeCommand('on-it-timestamps', {
|
|
176
|
+
CODEV_ISSUE_NUMBERS: unique.join(','),
|
|
177
|
+
}, { cwd, forgeConfig });
|
|
178
|
+
if (cmdResult && typeof cmdResult === 'object' && !Array.isArray(cmdResult)) {
|
|
179
|
+
for (const [key, value] of Object.entries(cmdResult)) {
|
|
180
|
+
if (typeof value === 'string') {
|
|
181
|
+
result.set(key, value);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
192
185
|
return result;
|
|
193
|
-
const unique = [...new Set(issueNumbers)];
|
|
194
|
-
// Get repo owner/name for GraphQL query
|
|
195
|
-
let owner;
|
|
196
|
-
let repoName;
|
|
197
|
-
try {
|
|
198
|
-
const { stdout } = await execFileAsync('gh', [
|
|
199
|
-
'repo', 'view', '--json', 'owner,name',
|
|
200
|
-
], { cwd });
|
|
201
|
-
const repo = JSON.parse(stdout);
|
|
202
|
-
owner = repo.owner.login;
|
|
203
|
-
repoName = repo.name;
|
|
204
186
|
}
|
|
205
|
-
|
|
187
|
+
// Default path: build GraphQL query for gh api graphql
|
|
188
|
+
// Get repo owner/name from git remote
|
|
189
|
+
const repo = await getRepoInfo(cwd);
|
|
190
|
+
if (!repo) {
|
|
206
191
|
return result; // Can't determine repo, skip gracefully
|
|
207
192
|
}
|
|
193
|
+
const { owner, name: repoName } = repo;
|
|
208
194
|
const BATCH_SIZE = 50;
|
|
209
195
|
for (let i = 0; i < unique.length; i += BATCH_SIZE) {
|
|
210
196
|
const batch = unique.slice(i, i + BATCH_SIZE);
|
|
211
197
|
// Build aliased GraphQL query — one field per issue
|
|
212
|
-
|
|
198
|
+
// GraphQL requires numeric issue numbers; skip non-numeric IDs (non-GitHub forges)
|
|
199
|
+
const numericBatch = batch.filter(id => /^\d+$/.test(id));
|
|
200
|
+
if (numericBatch.length === 0)
|
|
201
|
+
continue;
|
|
202
|
+
const issueFragments = numericBatch.map((id) => `issue${id}: issue(number: ${id}) { comments(first: 50) { nodes { body createdAt } } }`).join('\n ');
|
|
213
203
|
const query = `query($owner: String!, $name: String!) {
|
|
214
204
|
repository(owner: $owner, name: $name) {
|
|
215
205
|
${issueFragments}
|
|
216
206
|
}
|
|
217
207
|
}`;
|
|
218
208
|
try {
|
|
219
|
-
const
|
|
220
|
-
'
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
const
|
|
209
|
+
const cmdResult = await executeForgeCommand('on-it-timestamps', {
|
|
210
|
+
CODEV_ISSUE_NUMBERS: batch.join(','),
|
|
211
|
+
CODEV_GRAPHQL_QUERY: query,
|
|
212
|
+
CODEV_REPO_OWNER: owner,
|
|
213
|
+
CODEV_REPO_NAME: repoName,
|
|
214
|
+
}, { cwd, forgeConfig });
|
|
215
|
+
// Default gh command returns GraphQL response structure
|
|
216
|
+
const data = cmdResult;
|
|
217
|
+
const repoData = data?.data?.repository;
|
|
227
218
|
if (!repoData)
|
|
228
219
|
continue;
|
|
229
|
-
for (const
|
|
230
|
-
const issueData = repoData[`issue${
|
|
220
|
+
for (const id of numericBatch) {
|
|
221
|
+
const issueData = repoData[`issue${id}`];
|
|
231
222
|
if (!issueData?.comments?.nodes)
|
|
232
223
|
continue;
|
|
233
224
|
const onItComment = issueData.comments.nodes
|
|
234
225
|
.find((c) => c.body.includes('On it!'));
|
|
235
226
|
if (onItComment) {
|
|
236
|
-
result.set(
|
|
227
|
+
result.set(id, onItComment.createdAt);
|
|
237
228
|
}
|
|
238
229
|
}
|
|
239
230
|
}
|
|
@@ -260,27 +251,27 @@ export function parseLinkedIssue(prBody, prTitle) {
|
|
|
260
251
|
const closingKeywordPattern = /(?:fix(?:es)?|close[sd]?|resolve[sd]?)\s+#(\d+)/i;
|
|
261
252
|
const bodyMatch = prBody.match(closingKeywordPattern);
|
|
262
253
|
if (bodyMatch) {
|
|
263
|
-
return
|
|
254
|
+
return String(Number(bodyMatch[1]));
|
|
264
255
|
}
|
|
265
256
|
// Check PR title for [Spec N] or [Bugfix #N] patterns
|
|
266
257
|
const specPattern = /\[Spec\s+#?(\d+)\]/i;
|
|
267
258
|
const bugfixPattern = /\[Bugfix\s+#?(\d+)\]/i;
|
|
268
259
|
const titleSpecMatch = prTitle.match(specPattern);
|
|
269
260
|
if (titleSpecMatch) {
|
|
270
|
-
return
|
|
261
|
+
return String(Number(titleSpecMatch[1]));
|
|
271
262
|
}
|
|
272
263
|
const titleBugfixMatch = prTitle.match(bugfixPattern);
|
|
273
264
|
if (titleBugfixMatch) {
|
|
274
|
-
return
|
|
265
|
+
return String(Number(titleBugfixMatch[1]));
|
|
275
266
|
}
|
|
276
267
|
// Also check body for same patterns
|
|
277
268
|
const bodySpecMatch = prBody.match(specPattern);
|
|
278
269
|
if (bodySpecMatch) {
|
|
279
|
-
return
|
|
270
|
+
return String(Number(bodySpecMatch[1]));
|
|
280
271
|
}
|
|
281
272
|
const bodyBugfixMatch = prBody.match(bugfixPattern);
|
|
282
273
|
if (bodyBugfixMatch) {
|
|
283
|
-
return
|
|
274
|
+
return String(Number(bodyBugfixMatch[1]));
|
|
284
275
|
}
|
|
285
276
|
return null;
|
|
286
277
|
}
|
|
@@ -300,16 +291,16 @@ export function parseAllLinkedIssues(prBody, prTitle) {
|
|
|
300
291
|
// GitHub closing keywords (global)
|
|
301
292
|
const closingPattern = /(?:fix(?:es)?|close[sd]?|resolve[sd]?)\s+#(\d+)/gi;
|
|
302
293
|
for (const m of combined.matchAll(closingPattern)) {
|
|
303
|
-
issues.add(
|
|
294
|
+
issues.add(String(Number(m[1])));
|
|
304
295
|
}
|
|
305
296
|
// [Spec N] or [Bugfix #N] patterns (global)
|
|
306
297
|
const specPattern = /\[Spec\s+#?(\d+)\]/gi;
|
|
307
298
|
for (const m of combined.matchAll(specPattern)) {
|
|
308
|
-
issues.add(
|
|
299
|
+
issues.add(String(Number(m[1])));
|
|
309
300
|
}
|
|
310
301
|
const bugfixPattern = /\[Bugfix\s+#?(\d+)\]/gi;
|
|
311
302
|
for (const m of combined.matchAll(bugfixPattern)) {
|
|
312
|
-
issues.add(
|
|
303
|
+
issues.add(String(Number(m[1])));
|
|
313
304
|
}
|
|
314
305
|
return [...issues];
|
|
315
306
|
}
|
package/dist/lib/github.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/lib/github.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/lib/github.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,mBAAmB,EAAoB,MAAM,YAAY,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAqB/C,gFAAgF;AAChF,6DAA6D;AAC7D,gFAAgF;AAEhF;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,OAAwB,EACxB,OAA4D;IAE5D,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,YAAY,EAAE;QACrD,cAAc,EAAE,MAAM,CAAC,OAAO,CAAC;KAChC,EAAE;QACD,GAAG,EAAE,OAAO,EAAE,GAAG;QACjB,WAAW,EAAE,OAAO,EAAE,WAAW;KAClC,CAAC,CAAC;IACH,OAAO,MAA2B,CAAC;AACrC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAwB,EACxB,OAA4D;IAE5D,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACjD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,0BAA0B,OAAO,gEAAgE;YACjG,2DAA2D;YAC3D,yEAAyE,CAC1E,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,0CAA0C;AAC1C,MAAM,CAAC,MAAM,gBAAgB,GAAG,UAAU,CAAC;AAC3C,iDAAiD;AACjD,MAAM,CAAC,MAAM,uBAAuB,GAAG,iBAAiB,CAAC;AAEzD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,GAAY,EACZ,WAAgC;IAEhC,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,SAAS,EAAE,EAAE,EAAE;QACtD,GAAG;QACH,WAAW;KACZ,CAAC,CAAC;IACH,OAAO,MAA0B,CAAC;AACpC,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,GAAY,EACZ,WAAgC;IAEhC,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,YAAY,EAAE,EAAE,EAAE;QACzD,GAAG;QACH,WAAW;KACZ,CAAC,CAAC;IACH,OAAO,MAAqC,CAAC;AAC/C,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,GAAY,EACZ,WAAgC;IAEhC,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACrF,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,iBAAiB,EAAE;QAC1D,gBAAgB,EAAE,KAAK;KACxB,EAAE;QACD,GAAG;QACH,WAAW;KACZ,CAAC,CAAC;IACH,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,MAAqC,CAAC;IAEpF,4DAA4D;IAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAChD,OAAQ,MAA+B,CAAC,MAAM,CAC5C,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,IAAI,MAAM,CAC5D,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,GAAY,EACZ,WAAgC;IAEhC,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACrF,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,iBAAiB,EAAE;QAC1D,gBAAgB,EAAE,KAAK;KACxB,EAAE;QACD,GAAG;QACH,WAAW;KACZ,CAAC,CAAC;IACH,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,MAA0B,CAAC;IAEzE,4DAA4D;IAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAChD,OAAQ,MAAoB,CAAC,MAAM,CACjC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,IAAI,MAAM,CAC/D,CAAC;AACJ,CAAC;AAuBD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,KAAoB,EACpB,GAAY,EACZ,WAAgC;IAEhC,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,IAAI,KAAK,EAAE,CAAC;QACV,GAAG,CAAC,gBAAgB,GAAG,KAAK,CAAC;IAC/B,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/D,GAAG;QACH,WAAW;KACZ,CAAC,CAAC;IACH,OAAO,MAA2B,CAAC;AACrC,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,KAAoB,EACpB,GAAY,EACZ,WAAgC;IAEhC,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,IAAI,KAAK,EAAE,CAAC;QACV,GAAG,CAAC,gBAAgB,GAAG,KAAK,CAAC;IAC/B,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/D,GAAG;QACH,WAAW;KACZ,CAAC,CAAC;IACH,OAAO,MAA8B,CAAC;AACxC,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,QAAkB,EAClB,GAAY,EACZ,WAAgC;IAEhC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IAEzC,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEtC,0EAA0E;IAC1E,4EAA4E;IAC5E,MAAM,SAAS,GAAG,WAAW,EAAE,CAAC,kBAAkB,CAAC,CAAC;IACpD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,+CAA+C;QAC/C,IAAI,SAAS,KAAK,IAAI;YAAE,OAAO,MAAM,CAAC;QAEtC,MAAM,SAAS,GAAG,MAAM,mBAAmB,CAAC,kBAAkB,EAAE;YAC9D,mBAAmB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;SACtC,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;QAEzB,IAAI,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5E,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAmC,CAAC,EAAE,CAAC;gBAC/E,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;oBAC9B,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;gBACzB,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,uDAAuD;IACvD,sCAAsC;IACtC,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,MAAM,CAAC,CAAC,wCAAwC;IACzD,CAAC;IACD,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IAEvC,MAAM,UAAU,GAAG,EAAE,CAAC;IAEtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,UAAU,EAAE,CAAC;QACnD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC;QAE9C,oDAAoD;QACpD,mFAAmF;QACnF,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAC1D,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QACxC,MAAM,cAAc,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAC7C,QAAQ,EAAE,mBAAmB,EAAE,wDAAwD,CACxF,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEjB,MAAM,KAAK,GAAG;;MAEZ,cAAc;;EAElB,CAAC;QAEC,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,mBAAmB,CAAC,kBAAkB,EAAE;gBAC9D,mBAAmB,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;gBACpC,mBAAmB,EAAE,KAAK;gBAC1B,gBAAgB,EAAE,KAAK;gBACvB,eAAe,EAAE,QAAQ;aAC1B,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAC;YAEzB,wDAAwD;YACxD,MAAM,IAAI,GAAG,SAAqI,CAAC;YACnJ,MAAM,QAAQ,GAAG,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC;YACxC,IAAI,CAAC,QAAQ;gBAAE,SAAS;YAExB,KAAK,MAAM,EAAE,IAAI,YAAY,EAAE,CAAC;gBAC9B,MAAM,SAAS,GAAG,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;gBACzC,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,KAAK;oBAAE,SAAS;gBAE1C,MAAM,WAAW,GAAG,SAAS,CAAC,QAAQ,CAAC,KAAK;qBACzC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAC1C,IAAI,WAAW,EAAE,CAAC;oBAChB,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;gBACxC,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,8DAA8D;QAChE,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,gFAAgF;AAChF,oBAAoB;AACpB,gFAAgF;AAEhF;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAc,EAAE,OAAe;IAC9D,4CAA4C;IAC5C,MAAM,qBAAqB,GAAG,kDAAkD,CAAC;IACjF,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACtD,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;IAED,sDAAsD;IACtD,MAAM,WAAW,GAAG,qBAAqB,CAAC;IAC1C,MAAM,aAAa,GAAG,uBAAuB,CAAC;IAE9C,MAAM,cAAc,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAClD,IAAI,cAAc,EAAE,CAAC;QACnB,OAAO,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,gBAAgB,GAAG,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IACtD,IAAI,gBAAgB,EAAE,CAAC;QACrB,OAAO,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC;IAED,oCAAoC;IACpC,MAAM,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAChD,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IACpD,IAAI,eAAe,EAAE,CAAC;QACpB,OAAO,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAE,OAAe;IAClE,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IACjC,MAAM,QAAQ,GAAG,GAAG,OAAO,KAAK,MAAM,EAAE,CAAC;IAEzC,mCAAmC;IACnC,MAAM,cAAc,GAAG,mDAAmD,CAAC;IAC3E,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;QAClD,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC;IAED,4CAA4C;IAC5C,MAAM,WAAW,GAAG,sBAAsB,CAAC;IAC3C,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/C,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC;IAED,MAAM,aAAa,GAAG,wBAAwB,CAAC;IAC/C,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QACjD,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC;AACrB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,qEAAqE;AACrE,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;AAE9D,iGAAiG;AACjG,MAAM,kBAAkB,GAAG,mEAAmE,CAAC;AAE/F,MAAM,UAAU,kBAAkB,CAChC,MAA+B,EAC/B,KAAc;IAKd,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAEtC,MAAM,UAAU,GAAG,KAAK;SACrB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;SAClC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SACpB,IAAI,EAAE,CAAC;IAEV,iFAAiF;IACjF,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/D,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,CAAC;IAED,8CAA8C;IAC9C,IAAI,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;IACzB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,IAAI,GAAG,KAAK,IAAI,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IACrE,CAAC;IAED,MAAM,cAAc,GAAG,KAAK;SACzB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;SACtC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SACpB,IAAI,EAAE,CAAC;IAEV,OAAO;QACL,IAAI;QACJ,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,IAAI,QAAQ;KACxC,CAAC;AACJ,CAAC"}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* Spec 587: Team Tab in Tower Right Panel.
|
|
8
8
|
*/
|
|
9
9
|
import type { TeamMember } from './team.js';
|
|
10
|
+
import { type ForgeConfig } from './forge.js';
|
|
10
11
|
export interface TeamMemberGitHubData {
|
|
11
12
|
assignedIssues: {
|
|
12
13
|
number: number;
|
|
@@ -48,10 +49,11 @@ export declare function buildTeamGraphQLQuery(members: TeamMember[], owner: stri
|
|
|
48
49
|
*/
|
|
49
50
|
export declare function parseTeamGraphQLResponse(data: Record<string, unknown>, members: TeamMember[]): Map<string, TeamMemberGitHubData>;
|
|
50
51
|
/**
|
|
51
|
-
* Fetch
|
|
52
|
-
*
|
|
52
|
+
* Fetch forge data for all team members.
|
|
53
|
+
* Routes through the `team-activity` concept command with a batched GraphQL query.
|
|
54
|
+
* Returns empty data with error message on failure (graceful degradation).
|
|
53
55
|
*/
|
|
54
|
-
export declare function fetchTeamGitHubData(members: TeamMember[], cwd?: string): Promise<{
|
|
56
|
+
export declare function fetchTeamGitHubData(members: TeamMember[], cwd?: string, forgeConfig?: ForgeConfig | null): Promise<{
|
|
55
57
|
data: Map<string, TeamMemberGitHubData>;
|
|
56
58
|
error?: string;
|
|
57
59
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"team-github.d.ts","sourceRoot":"","sources":["../../src/lib/team-github.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"team-github.d.ts","sourceRoot":"","sources":["../../src/lib/team-github.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAQnE,MAAM,WAAW,oBAAoB;IACnC,cAAc,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACjE,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1D,cAAc,EAAE;QACd,SAAS,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QACjE,YAAY,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;KACrE,CAAC;CACH;AAMD,wBAAsB,WAAW,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAgB/F;AAqBD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CA2BhG;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,UAAU,EAAE,GACpB,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAuBnC;AAMD;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,UAAU,EAAE,EACrB,GAAG,CAAC,EAAE,MAAM,EACZ,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,GAC/B,OAAO,CAAC;IAAE,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAgCtE"}
|
package/dist/lib/team-github.js
CHANGED
|
@@ -9,17 +9,24 @@
|
|
|
9
9
|
import { execFile } from 'node:child_process';
|
|
10
10
|
import { promisify } from 'node:util';
|
|
11
11
|
import { isValidGitHubHandle } from './team.js';
|
|
12
|
+
import { executeForgeCommand } from './forge.js';
|
|
12
13
|
const execFileAsync = promisify(execFile);
|
|
13
14
|
// =============================================================================
|
|
14
15
|
// Repo Detection
|
|
15
16
|
// =============================================================================
|
|
16
17
|
export async function getRepoInfo(cwd) {
|
|
17
18
|
try {
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
// Derive owner/name from git remote URL instead of calling gh directly
|
|
20
|
+
const { stdout } = await execFileAsync('git', [
|
|
21
|
+
'remote', 'get-url', 'origin',
|
|
20
22
|
], { cwd });
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
+
const url = stdout.trim();
|
|
24
|
+
// Match SSH (git@github.com:owner/repo.git) or HTTPS (https://github.com/owner/repo.git)
|
|
25
|
+
const match = url.match(/[:/]([^/]+)\/([^/]+?)(?:\.git)?$/);
|
|
26
|
+
if (match) {
|
|
27
|
+
return { owner: match[1], name: match[2] };
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
23
30
|
}
|
|
24
31
|
catch {
|
|
25
32
|
return null;
|
|
@@ -102,33 +109,36 @@ export function parseTeamGraphQLResponse(data, members) {
|
|
|
102
109
|
// Main Fetch Function
|
|
103
110
|
// =============================================================================
|
|
104
111
|
/**
|
|
105
|
-
* Fetch
|
|
106
|
-
*
|
|
112
|
+
* Fetch forge data for all team members.
|
|
113
|
+
* Routes through the `team-activity` concept command with a batched GraphQL query.
|
|
114
|
+
* Returns empty data with error message on failure (graceful degradation).
|
|
107
115
|
*/
|
|
108
|
-
export async function fetchTeamGitHubData(members, cwd) {
|
|
116
|
+
export async function fetchTeamGitHubData(members, cwd, forgeConfig) {
|
|
109
117
|
const validMembers = members.filter(m => isValidGitHubHandle(m.github));
|
|
110
118
|
if (validMembers.length === 0) {
|
|
111
119
|
return { data: new Map() };
|
|
112
120
|
}
|
|
113
121
|
const repo = await getRepoInfo(cwd);
|
|
114
122
|
if (!repo) {
|
|
115
|
-
return { data: new Map(), error: 'Could not determine repository
|
|
123
|
+
return { data: new Map(), error: 'Could not determine repository. Configure forge concepts in af-config.json.' };
|
|
116
124
|
}
|
|
117
125
|
const query = buildTeamGraphQLQuery(validMembers, repo.owner, repo.name);
|
|
118
126
|
try {
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
127
|
+
const result = await executeForgeCommand('team-activity', {
|
|
128
|
+
CODEV_GRAPHQL_QUERY: query,
|
|
129
|
+
}, { cwd, forgeConfig });
|
|
130
|
+
if (!result || typeof result !== 'object') {
|
|
131
|
+
return { data: new Map(), error: 'team-activity concept returned no data' };
|
|
132
|
+
}
|
|
133
|
+
const response = result;
|
|
124
134
|
if (!response.data) {
|
|
125
|
-
return { data: new Map(), error: '
|
|
135
|
+
return { data: new Map(), error: 'team-activity concept returned no data' };
|
|
126
136
|
}
|
|
127
137
|
return { data: parseTeamGraphQLResponse(response.data, validMembers) };
|
|
128
138
|
}
|
|
129
139
|
catch (err) {
|
|
130
140
|
const message = err instanceof Error ? err.message : String(err);
|
|
131
|
-
return { data: new Map(), error: `
|
|
141
|
+
return { data: new Map(), error: `Forge API request failed: ${message}` };
|
|
132
142
|
}
|
|
133
143
|
}
|
|
134
144
|
//# sourceMappingURL=team-github.js.map
|