@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.
Files changed (107) hide show
  1. package/dashboard/dist/assets/{index-CiIBsixF.js → index-CziHWiV5.js} +41 -41
  2. package/dashboard/dist/assets/index-CziHWiV5.js.map +1 -0
  3. package/dashboard/dist/index.html +1 -1
  4. package/dist/agent-farm/cli.d.ts.map +1 -1
  5. package/dist/agent-farm/cli.js +4 -0
  6. package/dist/agent-farm/cli.js.map +1 -1
  7. package/dist/agent-farm/commands/cleanup.d.ts.map +1 -1
  8. package/dist/agent-farm/commands/cleanup.js +10 -5
  9. package/dist/agent-farm/commands/cleanup.js.map +1 -1
  10. package/dist/agent-farm/commands/spawn-roles.d.ts +1 -0
  11. package/dist/agent-farm/commands/spawn-roles.d.ts.map +1 -1
  12. package/dist/agent-farm/commands/spawn-roles.js.map +1 -1
  13. package/dist/agent-farm/commands/spawn-worktree.d.ts +48 -9
  14. package/dist/agent-farm/commands/spawn-worktree.d.ts.map +1 -1
  15. package/dist/agent-farm/commands/spawn-worktree.js +261 -39
  16. package/dist/agent-farm/commands/spawn-worktree.js.map +1 -1
  17. package/dist/agent-farm/commands/spawn.d.ts.map +1 -1
  18. package/dist/agent-farm/commands/spawn.js +98 -27
  19. package/dist/agent-farm/commands/spawn.js.map +1 -1
  20. package/dist/agent-farm/commands/team-update.d.ts.map +1 -1
  21. package/dist/agent-farm/commands/team-update.js +7 -4
  22. package/dist/agent-farm/commands/team-update.js.map +1 -1
  23. package/dist/agent-farm/commands/team.d.ts.map +1 -1
  24. package/dist/agent-farm/commands/team.js +6 -2
  25. package/dist/agent-farm/commands/team.js.map +1 -1
  26. package/dist/agent-farm/servers/overview.d.ts +7 -7
  27. package/dist/agent-farm/servers/overview.d.ts.map +1 -1
  28. package/dist/agent-farm/servers/overview.js +35 -33
  29. package/dist/agent-farm/servers/overview.js.map +1 -1
  30. package/dist/agent-farm/types.d.ts +4 -0
  31. package/dist/agent-farm/types.d.ts.map +1 -1
  32. package/dist/commands/consult/index.d.ts.map +1 -1
  33. package/dist/commands/consult/index.js +86 -69
  34. package/dist/commands/consult/index.js.map +1 -1
  35. package/dist/commands/doctor.d.ts.map +1 -1
  36. package/dist/commands/doctor.js +67 -23
  37. package/dist/commands/doctor.js.map +1 -1
  38. package/dist/commands/porch/checks.d.ts +6 -2
  39. package/dist/commands/porch/checks.d.ts.map +1 -1
  40. package/dist/commands/porch/checks.js +52 -3
  41. package/dist/commands/porch/checks.js.map +1 -1
  42. package/dist/commands/porch/next.d.ts.map +1 -1
  43. package/dist/commands/porch/next.js +8 -1
  44. package/dist/commands/porch/next.js.map +1 -1
  45. package/dist/commands/porch/prompts.js +2 -2
  46. package/dist/commands/porch/prompts.js.map +1 -1
  47. package/dist/commands/porch/state.d.ts.map +1 -1
  48. package/dist/commands/porch/state.js +7 -3
  49. package/dist/commands/porch/state.js.map +1 -1
  50. package/dist/lib/forge-contracts.d.ts +94 -0
  51. package/dist/lib/forge-contracts.d.ts.map +1 -0
  52. package/dist/lib/forge-contracts.js +35 -0
  53. package/dist/lib/forge-contracts.js.map +1 -0
  54. package/dist/lib/forge.d.ts +102 -0
  55. package/dist/lib/forge.d.ts.map +1 -0
  56. package/dist/lib/forge.js +384 -0
  57. package/dist/lib/forge.js.map +1 -0
  58. package/dist/lib/github.d.ts +68 -60
  59. package/dist/lib/github.d.ts.map +1 -1
  60. package/dist/lib/github.js +160 -169
  61. package/dist/lib/github.js.map +1 -1
  62. package/dist/lib/team-github.d.ts +5 -3
  63. package/dist/lib/team-github.d.ts.map +1 -1
  64. package/dist/lib/team-github.js +25 -15
  65. package/dist/lib/team-github.js.map +1 -1
  66. package/package.json +3 -2
  67. package/scripts/forge/gitea/auth-status.sh +3 -0
  68. package/scripts/forge/gitea/issue-comment.sh +3 -0
  69. package/scripts/forge/gitea/issue-list.sh +3 -0
  70. package/scripts/forge/gitea/issue-view.sh +3 -0
  71. package/scripts/forge/gitea/pr-exists.sh +3 -0
  72. package/scripts/forge/gitea/pr-list.sh +3 -0
  73. package/scripts/forge/gitea/pr-merge.sh +3 -0
  74. package/scripts/forge/gitea/pr-view.sh +3 -0
  75. package/scripts/forge/gitea/recently-closed.sh +3 -0
  76. package/scripts/forge/gitea/recently-merged.sh +3 -0
  77. package/scripts/forge/gitea/user-identity.sh +3 -0
  78. package/scripts/forge/github/auth-status.sh +4 -0
  79. package/scripts/forge/github/issue-comment.sh +5 -0
  80. package/scripts/forge/github/issue-list.sh +4 -0
  81. package/scripts/forge/github/issue-view.sh +5 -0
  82. package/scripts/forge/github/on-it-timestamps.sh +8 -0
  83. package/scripts/forge/github/pr-diff.sh +10 -0
  84. package/scripts/forge/github/pr-exists.sh +5 -0
  85. package/scripts/forge/github/pr-list.sh +4 -0
  86. package/scripts/forge/github/pr-merge.sh +5 -0
  87. package/scripts/forge/github/pr-search.sh +5 -0
  88. package/scripts/forge/github/pr-view.sh +11 -0
  89. package/scripts/forge/github/recently-closed.sh +15 -0
  90. package/scripts/forge/github/recently-merged.sh +15 -0
  91. package/scripts/forge/github/team-activity.sh +5 -0
  92. package/scripts/forge/github/user-identity.sh +4 -0
  93. package/scripts/forge/gitlab/auth-status.sh +3 -0
  94. package/scripts/forge/gitlab/issue-comment.sh +3 -0
  95. package/scripts/forge/gitlab/issue-list.sh +3 -0
  96. package/scripts/forge/gitlab/issue-view.sh +3 -0
  97. package/scripts/forge/gitlab/pr-diff.sh +3 -0
  98. package/scripts/forge/gitlab/pr-exists.sh +3 -0
  99. package/scripts/forge/gitlab/pr-list.sh +3 -0
  100. package/scripts/forge/gitlab/pr-merge.sh +3 -0
  101. package/scripts/forge/gitlab/pr-search.sh +3 -0
  102. package/scripts/forge/gitlab/pr-view.sh +3 -0
  103. package/scripts/forge/gitlab/recently-closed.sh +3 -0
  104. package/scripts/forge/gitlab/recently-merged.sh +3 -0
  105. package/scripts/forge/gitlab/user-identity.sh +3 -0
  106. package/skeleton/roles/architect.md +18 -6
  107. package/dashboard/dist/assets/index-CiIBsixF.js.map +0 -1
@@ -0,0 +1,384 @@
1
+ /**
2
+ * Forge concept command dispatcher.
3
+ *
4
+ * Routes forge operations (issue fetch, PR list, etc.) through configurable
5
+ * external commands. Default commands wrap the `gh` CLI for GitHub repos.
6
+ * Projects override commands via the `forge` section in af-config.json.
7
+ *
8
+ * Concept commands are executed via shell (`sh -c`) to support pipes,
9
+ * redirects, and variable expansion in user-configured commands.
10
+ * Environment variables (CODEV_*) are set before invocation.
11
+ *
12
+ * @see codev/specs/589-non-github-repository-support.md
13
+ */
14
+ import { exec, execSync } from 'node:child_process';
15
+ import { promisify } from 'node:util';
16
+ import { existsSync, readFileSync } from 'node:fs';
17
+ import { resolve, dirname } from 'node:path';
18
+ import { fileURLToPath } from 'node:url';
19
+ const execAsync = promisify(exec);
20
+ const __filename = fileURLToPath(import.meta.url);
21
+ const __dirname = dirname(__filename);
22
+ /**
23
+ * Resolve the path to a provider's on-disk concept script.
24
+ * Scripts live at `scripts/forge/<provider>/<concept>.sh` relative to the package root.
25
+ * At runtime, __dirname is `dist/lib/` — the package root is two levels up.
26
+ */
27
+ function resolveScriptPath(provider, concept) {
28
+ return resolve(__dirname, '..', '..', 'scripts', 'forge', provider, `${concept}.sh`);
29
+ }
30
+ /** Default maxBuffer for forge commands (10MB). Prevents truncation for large diffs. */
31
+ const DEFAULT_MAX_BUFFER = 10 * 1024 * 1024;
32
+ // =============================================================================
33
+ // Known concept names
34
+ // =============================================================================
35
+ const KNOWN_CONCEPTS = [
36
+ 'issue-view', 'pr-list', 'issue-list', 'issue-comment', 'pr-exists',
37
+ 'recently-closed', 'recently-merged', 'user-identity', 'team-activity',
38
+ 'on-it-timestamps', 'pr-merge', 'pr-search', 'pr-view', 'pr-diff',
39
+ 'auth-status',
40
+ ];
41
+ // =============================================================================
42
+ // Default concept commands — resolved lazily from on-disk scripts
43
+ // =============================================================================
44
+ let _defaultCommands = null;
45
+ /**
46
+ * Build default commands from on-disk scripts (github provider).
47
+ * Each concept maps to `scripts/forge/github/<concept>.sh`.
48
+ * Lazily computed and cached.
49
+ */
50
+ function getDefaultCommands() {
51
+ if (_defaultCommands)
52
+ return _defaultCommands;
53
+ _defaultCommands = {};
54
+ for (const concept of KNOWN_CONCEPTS) {
55
+ _defaultCommands[concept] = resolveScriptPath('github', concept);
56
+ }
57
+ return _defaultCommands;
58
+ }
59
+ // =============================================================================
60
+ // Provider presets
61
+ // =============================================================================
62
+ /**
63
+ * Build a provider preset from on-disk scripts.
64
+ * Concepts without a script file are null (disabled).
65
+ */
66
+ function buildPresetFromScripts(provider, disabledConcepts = []) {
67
+ const preset = {};
68
+ for (const concept of KNOWN_CONCEPTS) {
69
+ if (disabledConcepts.includes(concept)) {
70
+ preset[concept] = null;
71
+ continue;
72
+ }
73
+ const scriptPath = resolveScriptPath(provider, concept);
74
+ if (existsSync(scriptPath)) {
75
+ preset[concept] = scriptPath;
76
+ }
77
+ else {
78
+ preset[concept] = null;
79
+ }
80
+ }
81
+ return preset;
82
+ }
83
+ let _providerPresets = null;
84
+ /**
85
+ * Built-in presets for common forges. Resolved lazily from on-disk scripts.
86
+ *
87
+ * NOTE: Non-GitHub presets are best-effort. Their output schemas may not conform
88
+ * to the contracts in forge-contracts.ts. Consumers must handle null returns
89
+ * gracefully since JSON parse failures now return null instead of raw strings.
90
+ */
91
+ function getProviderPresets() {
92
+ if (_providerPresets)
93
+ return _providerPresets;
94
+ _providerPresets = {
95
+ github: getDefaultCommands(),
96
+ gitlab: buildPresetFromScripts('gitlab', ['team-activity', 'on-it-timestamps']),
97
+ gitea: buildPresetFromScripts('gitea', ['team-activity', 'on-it-timestamps', 'pr-search', 'pr-diff']),
98
+ };
99
+ return _providerPresets;
100
+ }
101
+ /** Get known provider names. */
102
+ export function getKnownProviders() {
103
+ return Object.keys(getProviderPresets());
104
+ }
105
+ /**
106
+ * Resolve all 15 concepts with their source and executable.
107
+ * Used by `codev doctor` for full concept reporting.
108
+ */
109
+ export function resolveAllConcepts(forgeConfig) {
110
+ const concepts = Object.keys(getDefaultCommands());
111
+ return concepts.map((concept) => {
112
+ // Check manual override first
113
+ if (forgeConfig && concept !== 'provider' && concept in forgeConfig) {
114
+ const cmd = forgeConfig[concept];
115
+ if (cmd === null) {
116
+ return { concept, command: null, source: 'disabled', executable: null };
117
+ }
118
+ return { concept, command: cmd, source: 'override', executable: extractExecutable(cmd) };
119
+ }
120
+ // Check provider preset
121
+ if (forgeConfig?.provider) {
122
+ const preset = getProviderPresets()[forgeConfig.provider];
123
+ if (preset && concept in preset) {
124
+ const cmd = preset[concept];
125
+ if (cmd === null) {
126
+ return { concept, command: null, source: 'disabled', executable: null };
127
+ }
128
+ return { concept, command: cmd, source: 'preset', executable: extractExecutable(cmd) };
129
+ }
130
+ }
131
+ // Default
132
+ const cmd = getDefaultCommands()[concept] ?? null;
133
+ return { concept, command: cmd, source: 'default', executable: cmd ? extractExecutable(cmd) : null };
134
+ });
135
+ }
136
+ /**
137
+ * Extract the executable name from a command string or script path.
138
+ *
139
+ * For script paths (ending in .sh): reads the script and finds the first
140
+ * substantive command (after `exec`, or in `if/then` blocks).
141
+ *
142
+ * For inline commands: handles `if [ ... ]; then cmd ...` patterns and pipes.
143
+ */
144
+ function extractExecutable(command) {
145
+ const trimmed = command.trim();
146
+ // Script path: read and extract the underlying tool
147
+ if (trimmed.endsWith('.sh') && existsSync(trimmed)) {
148
+ try {
149
+ const content = readFileSync(trimmed, 'utf-8');
150
+ // Look for `exec <tool>` or first non-comment, non-shebang, non-blank line
151
+ for (const line of content.split('\n')) {
152
+ const l = line.trim();
153
+ if (!l || l.startsWith('#') || l.startsWith('if') || l.startsWith('else') || l.startsWith('fi'))
154
+ continue;
155
+ const execMatch = l.match(/^exec\s+(\S+)/);
156
+ if (execMatch)
157
+ return execMatch[1];
158
+ // First substantive command
159
+ const token = l.split(/\s+/)[0];
160
+ if (token && !['if', 'then', 'else', 'fi', 'test', '[', '[['].includes(token)) {
161
+ return token;
162
+ }
163
+ }
164
+ return null;
165
+ }
166
+ catch {
167
+ return null;
168
+ }
169
+ }
170
+ // Inline command: extract first real executable
171
+ // Shell conditional: extract first command after "then"
172
+ const thenMatch = trimmed.match(/then\s+(\S+)/);
173
+ if (thenMatch)
174
+ return thenMatch[1];
175
+ // Pipe: first command
176
+ const first = trimmed.split(/[|;]/).map(s => s.trim())[0];
177
+ // Skip shell builtins
178
+ const token = first.split(/\s+/)[0];
179
+ if (['if', 'test', '[', '[['].includes(token))
180
+ return null;
181
+ return token || null;
182
+ }
183
+ // =============================================================================
184
+ // Configuration loading
185
+ // =============================================================================
186
+ /**
187
+ * Load forge configuration from af-config.json.
188
+ * Returns the forge section or null if not configured.
189
+ *
190
+ * Prefer passing forge config directly via ForgeCommandOptions.forgeConfig
191
+ * when config is already loaded (e.g., from loadUserConfig in config.ts).
192
+ */
193
+ export function loadForgeConfig(workspaceRoot) {
194
+ const configPath = resolve(workspaceRoot, 'af-config.json');
195
+ if (!existsSync(configPath))
196
+ return null;
197
+ try {
198
+ const content = readFileSync(configPath, 'utf-8');
199
+ const config = JSON.parse(content);
200
+ return config.forge ?? null;
201
+ }
202
+ catch {
203
+ return null;
204
+ }
205
+ }
206
+ /** Resolve forge config from options: explicit > loaded from workspace > loaded from cwd > null. */
207
+ function resolveForgeConfig(options) {
208
+ if (options?.forgeConfig !== undefined)
209
+ return options.forgeConfig;
210
+ if (options?.workspaceRoot)
211
+ return loadForgeConfig(options.workspaceRoot);
212
+ if (options?.cwd)
213
+ return loadForgeConfig(options.cwd);
214
+ return null;
215
+ }
216
+ /**
217
+ * Get the command string for a concept.
218
+ * Resolution order: manual concept override > provider preset > default (github).
219
+ * Returns null if concept is explicitly disabled (set to null in config).
220
+ */
221
+ export function getForgeCommand(concept, forgeConfig) {
222
+ // Check manual concept overrides first (excluding 'provider' key)
223
+ if (forgeConfig && concept !== 'provider' && concept in forgeConfig) {
224
+ return forgeConfig[concept]; // null means explicitly disabled
225
+ }
226
+ // Check provider preset
227
+ if (forgeConfig?.provider) {
228
+ const preset = getProviderPresets()[forgeConfig.provider];
229
+ if (preset && concept in preset) {
230
+ return preset[concept]; // null means not supported by this provider
231
+ }
232
+ }
233
+ // Fall back to default (github)
234
+ return getDefaultCommands()[concept] ?? null;
235
+ }
236
+ /**
237
+ * Check if a concept is explicitly disabled (set to null in config).
238
+ */
239
+ export function isConceptDisabled(concept, forgeConfig) {
240
+ if (!forgeConfig)
241
+ return false;
242
+ return concept in forgeConfig && forgeConfig[concept] === null;
243
+ }
244
+ // =============================================================================
245
+ // Execution
246
+ // =============================================================================
247
+ /**
248
+ * Execute a forge concept command asynchronously.
249
+ *
250
+ * Sets CODEV_* environment variables, executes the configured command
251
+ * via shell, and parses stdout as JSON. Returns null on failure.
252
+ *
253
+ * @param concept - The concept name (e.g., 'issue-view', 'pr-list')
254
+ * @param env - Additional environment variables to set (CODEV_* prefix recommended)
255
+ * @param options - Execution options
256
+ * @returns Parsed JSON from stdout, raw string for non-JSON concepts, or null on failure
257
+ */
258
+ export async function executeForgeCommand(concept, env, options) {
259
+ const forgeConfig = resolveForgeConfig(options);
260
+ const command = getForgeCommand(concept, forgeConfig);
261
+ if (command === null) {
262
+ return null;
263
+ }
264
+ try {
265
+ const { stdout } = await execAsync(command, {
266
+ cwd: options?.cwd,
267
+ env: { ...process.env, ...env },
268
+ timeout: 30_000,
269
+ maxBuffer: options?.maxBuffer ?? DEFAULT_MAX_BUFFER,
270
+ });
271
+ return parseOutput(stdout, options?.raw);
272
+ }
273
+ catch (err) {
274
+ logDebug(concept, err);
275
+ return null;
276
+ }
277
+ }
278
+ /**
279
+ * Execute a forge concept command synchronously.
280
+ *
281
+ * Same as executeForgeCommand but blocks until completion.
282
+ * Use sparingly — prefer the async variant.
283
+ */
284
+ export function executeForgeCommandSync(concept, env, options) {
285
+ const forgeConfig = resolveForgeConfig(options);
286
+ const command = getForgeCommand(concept, forgeConfig);
287
+ if (command === null) {
288
+ return null;
289
+ }
290
+ try {
291
+ const stdout = execSync(command, {
292
+ cwd: options?.cwd,
293
+ env: { ...process.env, ...env },
294
+ encoding: 'utf-8',
295
+ timeout: 30_000,
296
+ maxBuffer: options?.maxBuffer ?? DEFAULT_MAX_BUFFER,
297
+ stdio: ['pipe', 'pipe', 'pipe'],
298
+ });
299
+ return parseOutput(stdout, options?.raw);
300
+ }
301
+ catch (err) {
302
+ logDebug(concept, err, true);
303
+ return null;
304
+ }
305
+ }
306
+ // =============================================================================
307
+ // Internal helpers
308
+ // =============================================================================
309
+ /** Parse command stdout: try JSON when raw=false (null on parse failure), raw string otherwise. */
310
+ function parseOutput(stdout, raw) {
311
+ const trimmed = stdout.trim();
312
+ if (!trimmed)
313
+ return null;
314
+ if (raw)
315
+ return trimmed;
316
+ try {
317
+ return JSON.parse(trimmed);
318
+ }
319
+ catch {
320
+ // Not valid JSON — return null so downstream code doesn't cast a raw
321
+ // string to typed objects (e.g. IssueViewResult, PrListItem[]).
322
+ return null;
323
+ }
324
+ }
325
+ /** Log concept failure at debug level. */
326
+ function logDebug(concept, err, sync = false) {
327
+ if (process.env.CODEV_DEBUG) {
328
+ const msg = err instanceof Error ? err.message : String(err);
329
+ const suffix = sync ? ' (sync)' : '';
330
+ console.warn(`[forge] concept '${concept}'${suffix} failed: ${msg}`);
331
+ }
332
+ }
333
+ // =============================================================================
334
+ // Convenience helpers
335
+ // =============================================================================
336
+ /**
337
+ * Get the list of all known concept names.
338
+ */
339
+ export function getKnownConcepts() {
340
+ return Object.keys(getDefaultCommands());
341
+ }
342
+ /**
343
+ * Get the default command for a concept (ignoring user config).
344
+ * Useful for documentation and doctor checks.
345
+ */
346
+ export function getDefaultCommand(concept) {
347
+ return getDefaultCommands()[concept] ?? null;
348
+ }
349
+ /**
350
+ * Validate forge configuration.
351
+ * Returns an array of diagnostic messages.
352
+ * Used by `codev doctor`.
353
+ */
354
+ export function validateForgeConfig(forgeConfig) {
355
+ const results = [];
356
+ // Report provider if set
357
+ if (forgeConfig.provider) {
358
+ const providerName = forgeConfig.provider;
359
+ if (getProviderPresets()[providerName]) {
360
+ results.push({ concept: 'provider', status: 'provider', message: `Provider: ${providerName}` });
361
+ }
362
+ else {
363
+ results.push({ concept: 'provider', status: 'unknown_concept', message: `Unknown provider '${providerName}' (known: ${Object.keys(getProviderPresets()).join(', ')})` });
364
+ }
365
+ }
366
+ for (const [concept, command] of Object.entries(forgeConfig)) {
367
+ if (concept === 'provider')
368
+ continue; // Already handled above
369
+ if (command === null) {
370
+ results.push({ concept, status: 'disabled', message: `Concept '${concept}' is explicitly disabled` });
371
+ }
372
+ else if (command === '') {
373
+ results.push({ concept, status: 'empty_command', message: `Concept '${concept}' has an empty command string` });
374
+ }
375
+ else if (!(concept in getDefaultCommands())) {
376
+ results.push({ concept, status: 'unknown_concept', message: `Concept '${concept}' is not a known forge concept` });
377
+ }
378
+ else {
379
+ results.push({ concept, status: 'ok', message: `Concept '${concept}' overridden: ${command}` });
380
+ }
381
+ }
382
+ return results;
383
+ }
384
+ //# sourceMappingURL=forge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forge.js","sourceRoot":"","sources":["../../src/lib/forge.ts"],"names":[],"mappings":"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"}
@@ -1,75 +1,78 @@
1
1
  /**
2
- * Shared GitHub utilities for Codev.
2
+ * Shared forge utilities for Codev.
3
3
  *
4
- * Provides non-fatal GitHub API access via the `gh` CLI.
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 GitHub is unavailable.
7
+ * enabling graceful degradation when forge is unavailable.
8
+ *
9
+ * @see codev/specs/589-non-github-repository-support.md
7
10
  */
8
- export interface GitHubIssue {
9
- title: string;
10
- body: string;
11
- state: string;
12
- comments: Array<{
13
- body: string;
14
- createdAt: string;
15
- author: {
16
- login: string;
17
- };
18
- }>;
19
- }
20
- export interface GitHubPR {
21
- number: number;
22
- title: string;
23
- url: string;
24
- reviewDecision: string;
25
- body: string;
26
- createdAt: string;
27
- mergedAt?: string;
28
- }
29
- export interface GitHubIssueListItem {
30
- number: number;
31
- title: string;
32
- url: string;
33
- labels: Array<{
34
- name: string;
35
- }>;
36
- createdAt: string;
37
- closedAt?: string;
38
- }
11
+ import { type ForgeConfig } from './forge.js';
12
+ import type { IssueViewResult, PrListItem, IssueListItem } from './forge-contracts.js';
13
+ /** A single issue as returned by the `issue-view` concept command. */
14
+ export type ForgeIssue = IssueViewResult;
15
+ /** A single PR/MR item as returned by the `pr-list` concept command. */
16
+ export type ForgePR = PrListItem;
17
+ /** A single issue item as returned by the `issue-list` concept command. */
18
+ export type ForgeIssueListItem = IssueListItem;
19
+ /** @deprecated Use ForgeIssue instead. */
20
+ export type GitHubIssue = ForgeIssue;
21
+ /** @deprecated Use ForgePR instead. */
22
+ export type GitHubPR = ForgePR;
23
+ /** @deprecated Use ForgeIssueListItem instead. */
24
+ export type GitHubIssueListItem = ForgeIssueListItem;
39
25
  /**
40
- * Fetch a single GitHub issue by number.
41
- * Returns null if gh CLI fails (not authenticated, network down, etc.).
26
+ * Fetch a single issue by ID.
27
+ * Routes through the `issue-view` concept command.
28
+ * Returns null if the concept command fails.
29
+ *
30
+ * @param issueId - Issue identifier (number or string)
31
+ * @param options - Optional forge config and cwd
42
32
  */
43
- export declare function fetchGitHubIssue(issueNumber: number): Promise<GitHubIssue | null>;
33
+ export declare function fetchIssue(issueId: string | number, options?: {
34
+ cwd?: string;
35
+ forgeConfig?: ForgeConfig | null;
36
+ }): Promise<ForgeIssue | null>;
44
37
  /**
45
- * Fetch a single GitHub issue by number.
38
+ * Fetch a single issue by ID.
46
39
  * Throws on failure (for use in spawn where failure is fatal).
40
+ *
41
+ * @param issueId - Issue identifier (number or string)
42
+ * @param options - Optional forge config and cwd
47
43
  */
48
- export declare function fetchGitHubIssueOrThrow(issueNumber: number): Promise<GitHubIssue>;
44
+ export declare function fetchIssueOrThrow(issueId: string | number, options?: {
45
+ cwd?: string;
46
+ forgeConfig?: ForgeConfig | null;
47
+ }): Promise<ForgeIssue>;
48
+ /** @deprecated Use fetchIssue instead. */
49
+ export declare const fetchGitHubIssue: typeof fetchIssue;
50
+ /** @deprecated Use fetchIssueOrThrow instead. */
51
+ export declare const fetchGitHubIssueOrThrow: typeof fetchIssueOrThrow;
49
52
  /**
50
53
  * Fetch open PRs for the current repo.
54
+ * Routes through the `pr-list` concept command.
51
55
  * Returns null on failure.
52
- * @param cwd - Working directory for `gh` CLI (determines which repo is queried).
53
56
  */
54
- export declare function fetchPRList(cwd?: string): Promise<GitHubPR[] | null>;
57
+ export declare function fetchPRList(cwd?: string, forgeConfig?: ForgeConfig | null): Promise<ForgePR[] | null>;
55
58
  /**
56
59
  * Fetch open issues for the current repo.
60
+ * Routes through the `issue-list` concept command.
57
61
  * Returns null on failure.
58
- * @param cwd - Working directory for `gh` CLI (determines which repo is queried).
59
62
  */
60
- export declare function fetchIssueList(cwd?: string): Promise<GitHubIssueListItem[] | null>;
63
+ export declare function fetchIssueList(cwd?: string, forgeConfig?: ForgeConfig | null): Promise<ForgeIssueListItem[] | null>;
61
64
  /**
62
65
  * Fetch recently closed issues (last 24 hours).
66
+ * Routes through the `recently-closed` concept command.
63
67
  * Returns null on failure.
64
- * @param cwd - Working directory for `gh` CLI (determines which repo is queried).
65
68
  */
66
- export declare function fetchRecentlyClosed(cwd?: string): Promise<GitHubIssueListItem[] | null>;
69
+ export declare function fetchRecentlyClosed(cwd?: string, forgeConfig?: ForgeConfig | null): Promise<ForgeIssueListItem[] | null>;
67
70
  /**
68
71
  * Fetch recently merged PRs (last 24 hours).
72
+ * Routes through the `recently-merged` concept command.
69
73
  * Returns null on failure.
70
- * @param cwd - Working directory for `gh` CLI (determines which repo is queried).
71
74
  */
72
- export declare function fetchRecentMergedPRs(cwd?: string): Promise<GitHubPR[] | null>;
75
+ export declare function fetchRecentMergedPRs(cwd?: string, forgeConfig?: ForgeConfig | null): Promise<ForgePR[] | null>;
73
76
  export interface MergedPR {
74
77
  number: number;
75
78
  title: string;
@@ -89,28 +92,33 @@ export interface ClosedIssue {
89
92
  }
90
93
  /**
91
94
  * Fetch merged PRs, optionally filtered to those merged since a given date.
92
- * Uses `gh pr list --state merged --search "merged:>=DATE"` which provides `mergedAt`.
95
+ * Routes through the `recently-merged` concept command.
93
96
  * Returns null on failure.
94
97
  */
95
- export declare function fetchMergedPRs(since: string | null, cwd?: string): Promise<MergedPR[] | null>;
98
+ export declare function fetchMergedPRs(since: string | null, cwd?: string, forgeConfig?: ForgeConfig | null): Promise<MergedPR[] | null>;
96
99
  /**
97
100
  * Fetch closed issues, optionally filtered to those closed since a given date.
98
- * Uses `gh issue list --state closed --search "closed:>=DATE"` which provides `closedAt`.
101
+ * Routes through the `recently-closed` concept command.
99
102
  * Returns null on failure.
100
103
  */
101
- export declare function fetchClosedIssues(since: string | null, cwd?: string): Promise<ClosedIssue[] | null>;
104
+ export declare function fetchClosedIssues(since: string | null, cwd?: string, forgeConfig?: ForgeConfig | null): Promise<ClosedIssue[] | null>;
102
105
  /**
103
- * Fetch the "On it!" comment timestamp for multiple issues using GraphQL.
106
+ * Fetch the "On it!" comment timestamp for multiple issues.
107
+ *
108
+ * Routes through the `on-it-timestamps` concept command. The default command
109
+ * uses `gh api graphql` with a batched query. Non-GitHub forges can provide
110
+ * a simpler command that accepts CODEV_ISSUE_NUMBERS (comma-separated) and
111
+ * returns a JSON map of issue number → ISO timestamp.
104
112
  *
105
- * Uses a batched GraphQL query via `gh api graphql` to fetch comments for
106
- * many issues in a single API call. Finds the first comment containing
107
- * "On it!" (posted by `af spawn`). Returns a map of issue number → ISO timestamp.
108
- * Issues without an "On it!" comment are omitted from the result.
113
+ * For the default GitHub implementation, this function builds the GraphQL
114
+ * query internally and passes it via CODEV_GRAPHQL_QUERY. It also needs
115
+ * repo owner/name which it fetches via a separate gh call.
109
116
  *
110
117
  * Batches in groups of 50 to stay within GraphQL complexity limits.
111
- * For 100 issues, this makes 2 API calls instead of 100.
118
+ * Returns empty map on failure (graceful degradation analytics falls
119
+ * back to PR createdAt for wall-clock time).
112
120
  */
113
- export declare function fetchOnItTimestamps(issueNumbers: number[], cwd?: string): Promise<Map<number, string>>;
121
+ export declare function fetchOnItTimestamps(issueIds: string[], cwd?: string, forgeConfig?: ForgeConfig | null): Promise<Map<string, string>>;
114
122
  /**
115
123
  * Parse a linked issue number from a PR body and title.
116
124
  *
@@ -120,7 +128,7 @@ export declare function fetchOnItTimestamps(issueNumbers: number[], cwd?: string
120
128
  *
121
129
  * Returns the first matched issue number, or null if none found.
122
130
  */
123
- export declare function parseLinkedIssue(prBody: string, prTitle: string): number | null;
131
+ export declare function parseLinkedIssue(prBody: string, prTitle: string): string | null;
124
132
  /**
125
133
  * Parse ALL linked issue numbers from a PR body and title.
126
134
  *
@@ -131,7 +139,7 @@ export declare function parseLinkedIssue(prBody: string, prTitle: string): numbe
131
139
  *
132
140
  * Returns a deduplicated array of issue numbers (may be empty).
133
141
  */
134
- export declare function parseAllLinkedIssues(prBody: string, prTitle: string): number[];
142
+ export declare function parseAllLinkedIssues(prBody: string, prTitle: string): string[];
135
143
  export declare function parseLabelDefaults(labels: Array<{
136
144
  name: string;
137
145
  }>, title?: string): {
@@ -1 +1 @@
1
- {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/lib/github.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/lib/github.ts"],"names":[],"mappings":"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"}