@generacy-ai/generacy 0.3.3 → 0.4.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/README.md +153 -0
- package/dist/cli/commands/cluster/scaffolder.d.ts.map +1 -1
- package/dist/cli/commands/cluster/scaffolder.js +2 -0
- package/dist/cli/commands/cluster/scaffolder.js.map +1 -1
- package/dist/cli/commands/cockpit/advance.d.ts +42 -0
- package/dist/cli/commands/cockpit/advance.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/advance.js +136 -0
- package/dist/cli/commands/cockpit/advance.js.map +1 -0
- package/dist/cli/commands/cockpit/clarification-comment-finder.d.ts +13 -0
- package/dist/cli/commands/cockpit/clarification-comment-finder.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/clarification-comment-finder.js +31 -0
- package/dist/cli/commands/cockpit/clarification-comment-finder.js.map +1 -0
- package/dist/cli/commands/cockpit/code-references.d.ts +27 -0
- package/dist/cli/commands/cockpit/code-references.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/code-references.js +48 -0
- package/dist/cli/commands/cockpit/code-references.js.map +1 -0
- package/dist/cli/commands/cockpit/context.d.ts +90 -0
- package/dist/cli/commands/cockpit/context.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/context.js +280 -0
- package/dist/cli/commands/cockpit/context.js.map +1 -0
- package/dist/cli/commands/cockpit/exit.d.ts +12 -0
- package/dist/cli/commands/cockpit/exit.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/exit.js +18 -0
- package/dist/cli/commands/cockpit/exit.js.map +1 -0
- package/dist/cli/commands/cockpit/gate-vocabulary.d.ts +48 -0
- package/dist/cli/commands/cockpit/gate-vocabulary.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/gate-vocabulary.js +96 -0
- package/dist/cli/commands/cockpit/gate-vocabulary.js.map +1 -0
- package/dist/cli/commands/cockpit/index.d.ts +20 -0
- package/dist/cli/commands/cockpit/index.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/index.js +40 -0
- package/dist/cli/commands/cockpit/index.js.map +1 -0
- package/dist/cli/commands/cockpit/manual-advance-marker.d.ts +18 -0
- package/dist/cli/commands/cockpit/manual-advance-marker.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/manual-advance-marker.js +43 -0
- package/dist/cli/commands/cockpit/manual-advance-marker.js.map +1 -0
- package/dist/cli/commands/cockpit/mcp/errors.d.ts +54 -0
- package/dist/cli/commands/cockpit/mcp/errors.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/mcp/errors.js +190 -0
- package/dist/cli/commands/cockpit/mcp/errors.js.map +1 -0
- package/dist/cli/commands/cockpit/mcp/event-bus-registry.d.ts +59 -0
- package/dist/cli/commands/cockpit/mcp/event-bus-registry.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/mcp/event-bus-registry.js +305 -0
- package/dist/cli/commands/cockpit/mcp/event-bus-registry.js.map +1 -0
- package/dist/cli/commands/cockpit/mcp/event-bus.d.ts +82 -0
- package/dist/cli/commands/cockpit/mcp/event-bus.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/mcp/event-bus.js +230 -0
- package/dist/cli/commands/cockpit/mcp/event-bus.js.map +1 -0
- package/dist/cli/commands/cockpit/mcp/index.d.ts +17 -0
- package/dist/cli/commands/cockpit/mcp/index.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/mcp/index.js +37 -0
- package/dist/cli/commands/cockpit/mcp/index.js.map +1 -0
- package/dist/cli/commands/cockpit/mcp/ref-input.d.ts +52 -0
- package/dist/cli/commands/cockpit/mcp/ref-input.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/mcp/ref-input.js +132 -0
- package/dist/cli/commands/cockpit/mcp/ref-input.js.map +1 -0
- package/dist/cli/commands/cockpit/mcp/schemas.d.ts +287 -0
- package/dist/cli/commands/cockpit/mcp/schemas.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/mcp/schemas.js +84 -0
- package/dist/cli/commands/cockpit/mcp/schemas.js.map +1 -0
- package/dist/cli/commands/cockpit/mcp/server.d.ts +17 -0
- package/dist/cli/commands/cockpit/mcp/server.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/mcp/server.js +62 -0
- package/dist/cli/commands/cockpit/mcp/server.js.map +1 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_advance.d.ts +42 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_advance.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_advance.js +73 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_advance.js.map +1 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_await_events.d.ts +34 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_await_events.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_await_events.js +115 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_await_events.js.map +1 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_context.d.ts +21 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_context.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_context.js +35 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_context.js.map +1 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_merge.d.ts +43 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_merge.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_merge.js +99 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_merge.js.map +1 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_queue.d.ts +43 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_queue.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_queue.js +68 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_queue.js.map +1 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_resume.d.ts +38 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_resume.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_resume.js +79 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_resume.js.map +1 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_status.d.ts +21 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_status.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_status.js +59 -0
- package/dist/cli/commands/cockpit/mcp/tools/cockpit_status.js.map +1 -0
- package/dist/cli/commands/cockpit/merge.d.ts +42 -0
- package/dist/cli/commands/cockpit/merge.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/merge.js +360 -0
- package/dist/cli/commands/cockpit/merge.js.map +1 -0
- package/dist/cli/commands/cockpit/plan-dependency-extractor.d.ts +30 -0
- package/dist/cli/commands/cockpit/plan-dependency-extractor.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/plan-dependency-extractor.js +135 -0
- package/dist/cli/commands/cockpit/plan-dependency-extractor.js.map +1 -0
- package/dist/cli/commands/cockpit/queue.d.ts +85 -0
- package/dist/cli/commands/cockpit/queue.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/queue.js +438 -0
- package/dist/cli/commands/cockpit/queue.js.map +1 -0
- package/dist/cli/commands/cockpit/resolver.d.ts +70 -0
- package/dist/cli/commands/cockpit/resolver.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/resolver.js +117 -0
- package/dist/cli/commands/cockpit/resolver.js.map +1 -0
- package/dist/cli/commands/cockpit/resume.d.ts +38 -0
- package/dist/cli/commands/cockpit/resume.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/resume.js +167 -0
- package/dist/cli/commands/cockpit/resume.js.map +1 -0
- package/dist/cli/commands/cockpit/shared/classify-issue.d.ts +12 -0
- package/dist/cli/commands/cockpit/shared/classify-issue.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/shared/classify-issue.js +10 -0
- package/dist/cli/commands/cockpit/shared/classify-issue.js.map +1 -0
- package/dist/cli/commands/cockpit/shared/failing-check-json.d.ts +53 -0
- package/dist/cli/commands/cockpit/shared/failing-check-json.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/shared/failing-check-json.js +170 -0
- package/dist/cli/commands/cockpit/shared/failing-check-json.js.map +1 -0
- package/dist/cli/commands/cockpit/shared/identity.d.ts +54 -0
- package/dist/cli/commands/cockpit/shared/identity.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/shared/identity.js +65 -0
- package/dist/cli/commands/cockpit/shared/identity.js.map +1 -0
- package/dist/cli/commands/cockpit/shared/is-done-snapshot.d.ts +16 -0
- package/dist/cli/commands/cockpit/shared/is-done-snapshot.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/shared/is-done-snapshot.js +17 -0
- package/dist/cli/commands/cockpit/shared/is-done-snapshot.js.map +1 -0
- package/dist/cli/commands/cockpit/shared/pagination.d.ts +17 -0
- package/dist/cli/commands/cockpit/shared/pagination.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/shared/pagination.js +50 -0
- package/dist/cli/commands/cockpit/shared/pagination.js.map +1 -0
- package/dist/cli/commands/cockpit/shared/pr-link.d.ts +8 -0
- package/dist/cli/commands/cockpit/shared/pr-link.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/shared/pr-link.js +15 -0
- package/dist/cli/commands/cockpit/shared/pr-link.js.map +1 -0
- package/dist/cli/commands/cockpit/shared/required-checks.d.ts +17 -0
- package/dist/cli/commands/cockpit/shared/required-checks.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/shared/required-checks.js +38 -0
- package/dist/cli/commands/cockpit/shared/required-checks.js.map +1 -0
- package/dist/cli/commands/cockpit/shared/review-context-json.d.ts +29 -0
- package/dist/cli/commands/cockpit/shared/review-context-json.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/shared/review-context-json.js +28 -0
- package/dist/cli/commands/cockpit/shared/review-context-json.js.map +1 -0
- package/dist/cli/commands/cockpit/status/color.d.ts +11 -0
- package/dist/cli/commands/cockpit/status/color.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/status/color.js +33 -0
- package/dist/cli/commands/cockpit/status/color.js.map +1 -0
- package/dist/cli/commands/cockpit/status/group.d.ts +8 -0
- package/dist/cli/commands/cockpit/status/group.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/status/group.js +35 -0
- package/dist/cli/commands/cockpit/status/group.js.map +1 -0
- package/dist/cli/commands/cockpit/status/render-table.d.ts +24 -0
- package/dist/cli/commands/cockpit/status/render-table.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/status/render-table.js +71 -0
- package/dist/cli/commands/cockpit/status/render-table.js.map +1 -0
- package/dist/cli/commands/cockpit/status/row.d.ts +18 -0
- package/dist/cli/commands/cockpit/status/row.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/status/row.js +17 -0
- package/dist/cli/commands/cockpit/status/row.js.map +1 -0
- package/dist/cli/commands/cockpit/status.d.ts +18 -0
- package/dist/cli/commands/cockpit/status.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/status.js +138 -0
- package/dist/cli/commands/cockpit/status.js.map +1 -0
- package/dist/cli/commands/cockpit/watch/actionable.d.ts +15 -0
- package/dist/cli/commands/cockpit/watch/actionable.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/watch/actionable.js +32 -0
- package/dist/cli/commands/cockpit/watch/actionable.js.map +1 -0
- package/dist/cli/commands/cockpit/watch/aggregate-emit.d.ts +107 -0
- package/dist/cli/commands/cockpit/watch/aggregate-emit.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/watch/aggregate-emit.js +41 -0
- package/dist/cli/commands/cockpit/watch/aggregate-emit.js.map +1 -0
- package/dist/cli/commands/cockpit/watch/aggregate.d.ts +25 -0
- package/dist/cli/commands/cockpit/watch/aggregate.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/watch/aggregate.js +67 -0
- package/dist/cli/commands/cockpit/watch/aggregate.js.map +1 -0
- package/dist/cli/commands/cockpit/watch/check-rollup.d.ts +9 -0
- package/dist/cli/commands/cockpit/watch/check-rollup.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/watch/check-rollup.js +22 -0
- package/dist/cli/commands/cockpit/watch/check-rollup.js.map +1 -0
- package/dist/cli/commands/cockpit/watch/diff.d.ts +29 -0
- package/dist/cli/commands/cockpit/watch/diff.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/watch/diff.js +85 -0
- package/dist/cli/commands/cockpit/watch/diff.js.map +1 -0
- package/dist/cli/commands/cockpit/watch/emit.d.ts +58 -0
- package/dist/cli/commands/cockpit/watch/emit.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/watch/emit.js +30 -0
- package/dist/cli/commands/cockpit/watch/emit.js.map +1 -0
- package/dist/cli/commands/cockpit/watch/poll-loop.d.ts +29 -0
- package/dist/cli/commands/cockpit/watch/poll-loop.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/watch/poll-loop.js +81 -0
- package/dist/cli/commands/cockpit/watch/poll-loop.js.map +1 -0
- package/dist/cli/commands/cockpit/watch/pr-state.d.ts +17 -0
- package/dist/cli/commands/cockpit/watch/pr-state.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/watch/pr-state.js +33 -0
- package/dist/cli/commands/cockpit/watch/pr-state.js.map +1 -0
- package/dist/cli/commands/cockpit/watch/snapshot.d.ts +33 -0
- package/dist/cli/commands/cockpit/watch/snapshot.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/watch/snapshot.js +30 -0
- package/dist/cli/commands/cockpit/watch/snapshot.js.map +1 -0
- package/dist/cli/commands/cockpit/watch/stream-event.d.ts +82 -0
- package/dist/cli/commands/cockpit/watch/stream-event.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/watch/stream-event.js +9 -0
- package/dist/cli/commands/cockpit/watch/stream-event.js.map +1 -0
- package/dist/cli/commands/cockpit/watch.d.ts +22 -0
- package/dist/cli/commands/cockpit/watch.d.ts.map +1 -0
- package/dist/cli/commands/cockpit/watch.js +186 -0
- package/dist/cli/commands/cockpit/watch.js.map +1 -0
- package/dist/cli/commands/setup/build.d.ts.map +1 -1
- package/dist/cli/commands/setup/build.js +59 -0
- package/dist/cli/commands/setup/build.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +11 -5
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `generacy cockpit queue <epic-ref> <phase>` — enqueue every eligible ref
|
|
3
|
+
* listed under the matched `### <phase>` heading in the epic body.
|
|
4
|
+
*
|
|
5
|
+
* Pipeline:
|
|
6
|
+
* 1. resolveEpic(epicRef) → matchPhaseHeading(phase).
|
|
7
|
+
* 2. Per ref in the matched phase: gh issue view → classifyRow → eligible or [SKIP: …].
|
|
8
|
+
* 3. Print preview; if !--yes, prompt; on confirm, assign + label best-effort.
|
|
9
|
+
*/
|
|
10
|
+
import { Command, Option } from 'commander';
|
|
11
|
+
import * as p from '@clack/prompts';
|
|
12
|
+
import { GhCliWrapper, LoudResolverError, loadCockpitConfig, nodeChildProcessRunner, resolveEpic, matchPhaseHeading, } from '@generacy-ai/cockpit';
|
|
13
|
+
import { getLogger } from '../../utils/logger.js';
|
|
14
|
+
import { resolveIssueContext } from './resolver.js';
|
|
15
|
+
import { CockpitExit, isCockpitExit } from './exit.js';
|
|
16
|
+
import { LoudIdentityError, resolveCockpitIdentity } from './shared/identity.js';
|
|
17
|
+
import { extractPlanDependencies, } from './plan-dependency-extractor.js';
|
|
18
|
+
const DEFAULT_LABEL = 'process:speckit-feature';
|
|
19
|
+
const OWNER_REPO_REGEX = /^[^/]+\/[^/]+$/;
|
|
20
|
+
const LOGIN_REGEX = /^[A-Za-z0-9-]+$/;
|
|
21
|
+
// GitHub allows most characters in label names, but we validate the small
|
|
22
|
+
// subset the workflow ever uses to guard against typos.
|
|
23
|
+
const LABEL_REGEX = /^[A-Za-z0-9_:./-]{1,50}$/;
|
|
24
|
+
/**
|
|
25
|
+
* Default plan.md fetcher. Uses `gh api` via the provided CommandRunner to fetch the
|
|
26
|
+
* spec directory contents for an issue's feature branch and returns the decoded plan.md
|
|
27
|
+
* body. Returns null when the PR (and thus the branch, and thus the spec dir) does not
|
|
28
|
+
* exist yet, or when plan.md is not present.
|
|
29
|
+
*/
|
|
30
|
+
function makeDefaultPlanFetcher(runner, gh) {
|
|
31
|
+
return async (ref) => {
|
|
32
|
+
let resolution;
|
|
33
|
+
try {
|
|
34
|
+
resolution = await gh.resolveIssueToPRRef(ref.repo, ref.number);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
if (resolution.kind !== 'resolved')
|
|
40
|
+
return null;
|
|
41
|
+
const branch = resolution.ref.headRefName;
|
|
42
|
+
const specDir = `specs/${branch}/plan.md`;
|
|
43
|
+
const apiPath = `repos/${ref.repo}/contents/${encodeURIComponent(specDir).replace(/%2F/g, '/')}?ref=${encodeURIComponent(branch)}`;
|
|
44
|
+
const result = await runner('gh', ['api', apiPath, '--jq', '.content']);
|
|
45
|
+
if (result.exitCode !== 0)
|
|
46
|
+
return null;
|
|
47
|
+
// gh returns base64 content (from GitHub API `.content` field) with newlines.
|
|
48
|
+
const b64 = result.stdout.trim().replace(/\n/g, '');
|
|
49
|
+
if (!b64)
|
|
50
|
+
return null;
|
|
51
|
+
try {
|
|
52
|
+
return Buffer.from(b64, 'base64').toString('utf-8');
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Classify a dependency's state at queue time. Returns null when the dep is fine
|
|
61
|
+
* (merged or already closed with an associated merged PR).
|
|
62
|
+
*/
|
|
63
|
+
async function classifyDependency(dep, gh) {
|
|
64
|
+
const nwo = `${dep.owner}/${dep.repo}`;
|
|
65
|
+
let resolution;
|
|
66
|
+
try {
|
|
67
|
+
resolution = await gh.resolveIssueToPRRef(nwo, dep.number);
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return 'unresolved';
|
|
71
|
+
}
|
|
72
|
+
// Resolver returns only OPEN, non-draft PRs, so a resolved/ambiguous/pr-is-draft
|
|
73
|
+
// result means the dep is still in flight. MERGED/CLOSED PRs are surfaced via
|
|
74
|
+
// the issue's stateReason below.
|
|
75
|
+
if (resolution.kind !== 'unresolved') {
|
|
76
|
+
return 'unresolved';
|
|
77
|
+
}
|
|
78
|
+
// No open PR linked — fall back to the issue's state. `stateReason` disambiguates
|
|
79
|
+
// merged deps (COMPLETED — no warning) from truly closed-unmerged ones.
|
|
80
|
+
let issueState = null;
|
|
81
|
+
try {
|
|
82
|
+
issueState = await gh.fetchIssueState(nwo, dep.number);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return 'unresolved';
|
|
86
|
+
}
|
|
87
|
+
if (issueState == null)
|
|
88
|
+
return 'unresolved';
|
|
89
|
+
if (issueState.state === 'CLOSED') {
|
|
90
|
+
return issueState.stateReason === 'COMPLETED' ? null : 'closed-unmerged';
|
|
91
|
+
}
|
|
92
|
+
return 'unresolved';
|
|
93
|
+
}
|
|
94
|
+
async function annotateRowsWithDependencyWarnings(rows, fetchPlan, gh) {
|
|
95
|
+
for (const row of rows) {
|
|
96
|
+
if (row.eligibility.kind !== 'eligible')
|
|
97
|
+
continue;
|
|
98
|
+
let planMd;
|
|
99
|
+
try {
|
|
100
|
+
planMd = await fetchPlan(row.ref);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
continue; // treat any fetch error as "no plan.md — skip"
|
|
104
|
+
}
|
|
105
|
+
if (planMd == null)
|
|
106
|
+
continue;
|
|
107
|
+
// IssueRef.repo is the full owner/repo string; split for the extractor's defaults.
|
|
108
|
+
const [defaultOwner = '', defaultRepo = ''] = row.ref.repo.split('/');
|
|
109
|
+
const deps = extractPlanDependencies(planMd, defaultOwner, defaultRepo);
|
|
110
|
+
const warnings = [];
|
|
111
|
+
for (const dep of deps) {
|
|
112
|
+
const state = await classifyDependency(dep, gh);
|
|
113
|
+
if (state != null)
|
|
114
|
+
warnings.push({ ref: dep, state });
|
|
115
|
+
}
|
|
116
|
+
if (warnings.length > 0) {
|
|
117
|
+
row.dependencyWarnings = warnings;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function classifyRow(ref, targetRepo, workflowLabel, viewResult) {
|
|
122
|
+
if (ref.repo !== targetRepo)
|
|
123
|
+
return { kind: 'skip', reason: 'cross-repo' };
|
|
124
|
+
if (viewResult == null)
|
|
125
|
+
return { kind: 'skip', reason: 'not-found' };
|
|
126
|
+
if (viewResult.state === 'CLOSED')
|
|
127
|
+
return { kind: 'skip', reason: 'closed' };
|
|
128
|
+
if (viewResult.labels.includes(workflowLabel)) {
|
|
129
|
+
return { kind: 'skip', reason: 'already-labeled' };
|
|
130
|
+
}
|
|
131
|
+
return { kind: 'eligible', workflowLabel };
|
|
132
|
+
}
|
|
133
|
+
function sortRows(rows) {
|
|
134
|
+
const eligible = [];
|
|
135
|
+
const skipped = [];
|
|
136
|
+
for (const r of rows) {
|
|
137
|
+
if (r.eligibility.kind === 'eligible')
|
|
138
|
+
eligible.push(r);
|
|
139
|
+
else
|
|
140
|
+
skipped.push(r);
|
|
141
|
+
}
|
|
142
|
+
const byRepoThenNumber = (a, b) => a.ref.repo === b.ref.repo ? a.ref.number - b.ref.number : a.ref.repo.localeCompare(b.ref.repo);
|
|
143
|
+
eligible.sort(byRepoThenNumber);
|
|
144
|
+
skipped.sort(byRepoThenNumber);
|
|
145
|
+
return { eligible, skipped };
|
|
146
|
+
}
|
|
147
|
+
export function renderPreview(epic, phase, targetRepo, workflowLabel, assignee, rows) {
|
|
148
|
+
const { eligible, skipped } = sortRows(rows);
|
|
149
|
+
const lines = [];
|
|
150
|
+
lines.push(`cockpit queue: epic ${epic.epic.repo}#${epic.epic.number} / phase '${phase.heading}' → ` +
|
|
151
|
+
`${eligible.length} eligible, ${skipped.length} skipped in ${targetRepo}`);
|
|
152
|
+
for (const row of eligible) {
|
|
153
|
+
if (row.eligibility.kind !== 'eligible')
|
|
154
|
+
continue;
|
|
155
|
+
lines.push(` ${row.ref.repo}#${row.ref.number} ${row.title} ` +
|
|
156
|
+
`(${row.eligibility.workflowLabel}, assignee: ${assignee})`);
|
|
157
|
+
if (row.dependencyWarnings) {
|
|
158
|
+
for (const warning of row.dependencyWarnings) {
|
|
159
|
+
const depRef = `${warning.ref.owner}/${warning.ref.repo}#${warning.ref.number}`;
|
|
160
|
+
lines.push(` [WARN: depends-on ${depRef} not yet merged]`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
for (const row of skipped) {
|
|
165
|
+
if (row.eligibility.kind !== 'skip')
|
|
166
|
+
continue;
|
|
167
|
+
const tag = `[SKIP: ${row.eligibility.reason}]`;
|
|
168
|
+
const title = row.title ? ` ${row.title}` : '';
|
|
169
|
+
lines.push(` ${tag} ${row.ref.repo}#${row.ref.number}${title}`);
|
|
170
|
+
}
|
|
171
|
+
return lines;
|
|
172
|
+
}
|
|
173
|
+
function mutationField(o) {
|
|
174
|
+
if (o == null)
|
|
175
|
+
return 'skipped';
|
|
176
|
+
if (o.kind === 'ok')
|
|
177
|
+
return 'ok';
|
|
178
|
+
if (o.kind === 'already')
|
|
179
|
+
return 'already';
|
|
180
|
+
return `error: ${o.reason}`;
|
|
181
|
+
}
|
|
182
|
+
export function renderSummary(rows) {
|
|
183
|
+
const { eligible } = sortRows(rows);
|
|
184
|
+
const lines = [];
|
|
185
|
+
for (const row of eligible) {
|
|
186
|
+
const assignField = mutationField(row.assignResult);
|
|
187
|
+
const labelField = mutationField(row.labelResult);
|
|
188
|
+
const isErr = row.assignResult?.kind === 'error' || row.labelResult?.kind === 'error';
|
|
189
|
+
const prefix = isErr ? 'FAILED' : 'Queued';
|
|
190
|
+
lines.push(`${prefix} ${row.ref.repo}#${row.ref.number} assignee=${assignField} label=${labelField}`);
|
|
191
|
+
}
|
|
192
|
+
return lines;
|
|
193
|
+
}
|
|
194
|
+
async function defaultPrompt(message) {
|
|
195
|
+
const answer = await p.confirm({ message });
|
|
196
|
+
if (p.isCancel(answer))
|
|
197
|
+
return false;
|
|
198
|
+
return Boolean(answer);
|
|
199
|
+
}
|
|
200
|
+
function pickTargetRepo(refs, repoFlag) {
|
|
201
|
+
const seen = new Set();
|
|
202
|
+
for (const r of refs)
|
|
203
|
+
seen.add(r.repo);
|
|
204
|
+
const repos = [...seen].sort();
|
|
205
|
+
if (repoFlag != null) {
|
|
206
|
+
if (!repos.includes(repoFlag))
|
|
207
|
+
return { kind: 'flag-not-in-repos', repos };
|
|
208
|
+
return repoFlag;
|
|
209
|
+
}
|
|
210
|
+
if (repos.length === 1)
|
|
211
|
+
return repos[0];
|
|
212
|
+
return { kind: 'multi-repo-no-flag', repos };
|
|
213
|
+
}
|
|
214
|
+
export async function runQueue(epicRef, phaseArg, opts, deps) {
|
|
215
|
+
const print = deps.stdout ?? ((line) => process.stdout.write(`${line}\n`));
|
|
216
|
+
if (epicRef == null || epicRef.trim() === '') {
|
|
217
|
+
throw new CockpitExit(2, 'Error: cockpit queue: missing required argument <epic-ref>');
|
|
218
|
+
}
|
|
219
|
+
if (phaseArg == null || phaseArg.trim() === '') {
|
|
220
|
+
throw new CockpitExit(2, 'Error: cockpit queue: missing required argument <phase>');
|
|
221
|
+
}
|
|
222
|
+
const workflowLabel = opts.label ?? DEFAULT_LABEL;
|
|
223
|
+
if (!LABEL_REGEX.test(workflowLabel)) {
|
|
224
|
+
throw new CockpitExit(2, `Error: cockpit queue: invalid --label "${workflowLabel}"`);
|
|
225
|
+
}
|
|
226
|
+
if (opts.repo != null && !OWNER_REPO_REGEX.test(opts.repo)) {
|
|
227
|
+
throw new CockpitExit(2, `Error: cockpit queue: invalid --repo "${opts.repo}" (expected owner/repo)`);
|
|
228
|
+
}
|
|
229
|
+
if (opts.assignee != null && !LOGIN_REGEX.test(opts.assignee)) {
|
|
230
|
+
throw new CockpitExit(2, `Error: cockpit queue: invalid --assignee "${opts.assignee}" (expected GitHub login)`);
|
|
231
|
+
}
|
|
232
|
+
const gh = deps.gh ?? new GhCliWrapper();
|
|
233
|
+
const cockpitGh = deps.cockpitGh ?? new GhCliWrapper(deps.runner ?? nodeChildProcessRunner);
|
|
234
|
+
const loadedConfig = await (deps.loadConfig ?? loadCockpitConfig)({});
|
|
235
|
+
const log = getLogger();
|
|
236
|
+
for (const w of loadedConfig.warnings)
|
|
237
|
+
log.warn(w);
|
|
238
|
+
let expandedEpicRef;
|
|
239
|
+
try {
|
|
240
|
+
const resolvedCtx = await resolveIssueContext({ issue: epicRef, runner: deps.runner });
|
|
241
|
+
expandedEpicRef = `${resolvedCtx.ref.nwo}#${resolvedCtx.ref.number}`;
|
|
242
|
+
}
|
|
243
|
+
catch (err) {
|
|
244
|
+
throw new CockpitExit(2, `Error: cockpit queue: ${err instanceof Error ? err.message : String(err)}`);
|
|
245
|
+
}
|
|
246
|
+
let epic;
|
|
247
|
+
try {
|
|
248
|
+
epic = await resolveEpic({ epicRef: expandedEpicRef, gh });
|
|
249
|
+
}
|
|
250
|
+
catch (err) {
|
|
251
|
+
if (err instanceof LoudResolverError) {
|
|
252
|
+
throw new CockpitExit(2, `Error: cockpit queue: ${err.message}`);
|
|
253
|
+
}
|
|
254
|
+
throw err;
|
|
255
|
+
}
|
|
256
|
+
let phase;
|
|
257
|
+
try {
|
|
258
|
+
phase = matchPhaseHeading(epic.parsed, phaseArg);
|
|
259
|
+
}
|
|
260
|
+
catch (err) {
|
|
261
|
+
if (err instanceof LoudResolverError) {
|
|
262
|
+
throw new CockpitExit(2, `Error: cockpit queue: ${err.message}`);
|
|
263
|
+
}
|
|
264
|
+
throw err;
|
|
265
|
+
}
|
|
266
|
+
const target = pickTargetRepo(phase.refs, opts.repo);
|
|
267
|
+
if (typeof target !== 'string') {
|
|
268
|
+
if (target.kind === 'multi-repo-no-flag') {
|
|
269
|
+
throw new CockpitExit(2, `Error: cockpit queue: phase '${phase.heading}' spans repos [${target.repos.join(', ')}]. ` +
|
|
270
|
+
'Pass --repo <owner/repo> to scope this invocation.');
|
|
271
|
+
}
|
|
272
|
+
throw new CockpitExit(2, `Error: cockpit queue: --repo ${opts.repo} not in phase repos [${target.repos.join(', ')}].`);
|
|
273
|
+
}
|
|
274
|
+
const targetRepo = target;
|
|
275
|
+
const rows = [];
|
|
276
|
+
for (const ref of phase.refs) {
|
|
277
|
+
if (ref.repo !== targetRepo) {
|
|
278
|
+
rows.push({
|
|
279
|
+
ref,
|
|
280
|
+
title: '',
|
|
281
|
+
labels: [],
|
|
282
|
+
assignees: [],
|
|
283
|
+
eligibility: { kind: 'skip', reason: 'cross-repo' },
|
|
284
|
+
});
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
let view;
|
|
288
|
+
try {
|
|
289
|
+
view = await cockpitGh.fetchIssueState(ref.repo, ref.number);
|
|
290
|
+
}
|
|
291
|
+
catch {
|
|
292
|
+
view = null;
|
|
293
|
+
}
|
|
294
|
+
const eligibility = classifyRow(ref, targetRepo, workflowLabel, view);
|
|
295
|
+
rows.push({
|
|
296
|
+
ref,
|
|
297
|
+
title: view?.title ?? '',
|
|
298
|
+
labels: view?.labels ?? [],
|
|
299
|
+
assignees: view?.assignees ?? [],
|
|
300
|
+
eligibility,
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
// Warning-only dependency check for the implement phase (#864).
|
|
304
|
+
if (/implement/i.test(phase.heading)) {
|
|
305
|
+
const fetchPlan = deps.fetchPlan ?? makeDefaultPlanFetcher(deps.runner ?? nodeChildProcessRunner, cockpitGh);
|
|
306
|
+
try {
|
|
307
|
+
await annotateRowsWithDependencyWarnings(rows, fetchPlan, cockpitGh);
|
|
308
|
+
}
|
|
309
|
+
catch (err) {
|
|
310
|
+
log.warn(`cockpit queue: dependency warning check failed — ${String(err)}`);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
let assignee;
|
|
314
|
+
try {
|
|
315
|
+
const resolved = await resolveCockpitIdentity({
|
|
316
|
+
flag: opts.assignee,
|
|
317
|
+
configAssignee: loadedConfig.config.assignee,
|
|
318
|
+
gh: cockpitGh,
|
|
319
|
+
logger: log,
|
|
320
|
+
verb: 'queue',
|
|
321
|
+
mode: 'required',
|
|
322
|
+
env: deps.env,
|
|
323
|
+
});
|
|
324
|
+
assignee = resolved.login;
|
|
325
|
+
}
|
|
326
|
+
catch (err) {
|
|
327
|
+
if (err instanceof LoudIdentityError) {
|
|
328
|
+
throw new CockpitExit(1, `Error: ${err.message}`);
|
|
329
|
+
}
|
|
330
|
+
throw err;
|
|
331
|
+
}
|
|
332
|
+
for (const line of renderPreview(epic, phase, targetRepo, workflowLabel, assignee, rows)) {
|
|
333
|
+
print(line);
|
|
334
|
+
}
|
|
335
|
+
const eligibleCount = rows.filter((r) => r.eligibility.kind === 'eligible').length;
|
|
336
|
+
if (eligibleCount === 0) {
|
|
337
|
+
print('cockpit queue: no eligible issues — nothing to do.');
|
|
338
|
+
return {
|
|
339
|
+
epic,
|
|
340
|
+
phase,
|
|
341
|
+
targetRepo,
|
|
342
|
+
workflowLabel,
|
|
343
|
+
assignee,
|
|
344
|
+
rows,
|
|
345
|
+
confirmed: false,
|
|
346
|
+
exitCode: 0,
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
let confirmed = Boolean(opts.yes);
|
|
350
|
+
if (!confirmed) {
|
|
351
|
+
const prompt = deps.prompt ?? defaultPrompt;
|
|
352
|
+
const answer = await prompt('Proceed?');
|
|
353
|
+
confirmed = answer === true;
|
|
354
|
+
if (!confirmed) {
|
|
355
|
+
print('Cancelled. No mutations made.');
|
|
356
|
+
return {
|
|
357
|
+
epic,
|
|
358
|
+
phase,
|
|
359
|
+
targetRepo,
|
|
360
|
+
workflowLabel,
|
|
361
|
+
assignee,
|
|
362
|
+
rows,
|
|
363
|
+
confirmed: false,
|
|
364
|
+
exitCode: 0,
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
const { eligible } = sortRows(rows);
|
|
369
|
+
for (const row of eligible) {
|
|
370
|
+
if (row.eligibility.kind !== 'eligible')
|
|
371
|
+
continue;
|
|
372
|
+
if (row.assignees.includes(assignee)) {
|
|
373
|
+
row.assignResult = { kind: 'already' };
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
376
|
+
try {
|
|
377
|
+
await cockpitGh.addAssignees(row.ref.repo, row.ref.number, [assignee]);
|
|
378
|
+
row.assignResult = { kind: 'ok' };
|
|
379
|
+
}
|
|
380
|
+
catch (err) {
|
|
381
|
+
row.assignResult = { kind: 'error', reason: err.message };
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
if (row.labels.includes(row.eligibility.workflowLabel)) {
|
|
385
|
+
row.labelResult = { kind: 'already' };
|
|
386
|
+
}
|
|
387
|
+
else {
|
|
388
|
+
try {
|
|
389
|
+
await cockpitGh.addLabel(row.ref.repo, row.ref.number, row.eligibility.workflowLabel);
|
|
390
|
+
row.labelResult = { kind: 'ok' };
|
|
391
|
+
}
|
|
392
|
+
catch (err) {
|
|
393
|
+
row.labelResult = { kind: 'error', reason: err.message };
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
for (const line of renderSummary(rows))
|
|
398
|
+
print(line);
|
|
399
|
+
const anyError = rows.some((r) => r.eligibility.kind === 'eligible' &&
|
|
400
|
+
(r.assignResult?.kind === 'error' || r.labelResult?.kind === 'error'));
|
|
401
|
+
return {
|
|
402
|
+
epic,
|
|
403
|
+
phase,
|
|
404
|
+
targetRepo,
|
|
405
|
+
workflowLabel,
|
|
406
|
+
assignee,
|
|
407
|
+
rows,
|
|
408
|
+
confirmed: true,
|
|
409
|
+
exitCode: anyError ? 1 : 0,
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
export function queueCommand(deps = {}) {
|
|
413
|
+
const cmd = new Command('queue');
|
|
414
|
+
cmd
|
|
415
|
+
.description('Queue every eligible ref under a phase heading to the cluster pipeline.')
|
|
416
|
+
.argument('<epic-ref>', 'Epic ref (owner/repo#N).')
|
|
417
|
+
.argument('<phase>', 'Phase token — matched case-insensitively against the first token of a ### heading.')
|
|
418
|
+
.addOption(new Option('--label <name>', `Workflow label (default: ${DEFAULT_LABEL}).`))
|
|
419
|
+
.addOption(new Option('--repo <owner/repo>', 'Restrict the invocation to a single repo.'))
|
|
420
|
+
.addOption(new Option('--assignee <login>', 'Override the default cluster-account assignee.'))
|
|
421
|
+
.addOption(new Option('--yes', 'Skip the interactive confirmation prompt.'))
|
|
422
|
+
.action(async (epicRef, phaseArg, opts) => {
|
|
423
|
+
try {
|
|
424
|
+
const result = await runQueue(epicRef, phaseArg, opts, deps);
|
|
425
|
+
process.exit(result.exitCode);
|
|
426
|
+
}
|
|
427
|
+
catch (err) {
|
|
428
|
+
if (isCockpitExit(err)) {
|
|
429
|
+
const stderr = deps.stderr ?? ((line) => process.stderr.write(`${line}\n`));
|
|
430
|
+
stderr(err.message);
|
|
431
|
+
process.exit(err.code);
|
|
432
|
+
}
|
|
433
|
+
throw err;
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
return cmd;
|
|
437
|
+
}
|
|
438
|
+
//# sourceMappingURL=queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.js","sourceRoot":"","sources":["../../../../src/cli/commands/cockpit/queue.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cockpit resolver — parses issue arguments and resolves them to a live
|
|
3
|
+
* `{ ref, repo, gh }` bundle:
|
|
4
|
+
*
|
|
5
|
+
* - `IssueRef` — owner/repo/number/nwo
|
|
6
|
+
* - `parseIssueRef(input)` — @internal; strict qualified-forms parser
|
|
7
|
+
* (owner/repo#N and URL only). Cockpit callers
|
|
8
|
+
* MUST go through `resolveIssueContext`.
|
|
9
|
+
* - `resolveIssueContext(x)` — gates bare numbers via cwd-origin inference,
|
|
10
|
+
* delegates qualified forms to `parseIssueRef`,
|
|
11
|
+
* and returns a live `{ ref, repo, gh }` bundle.
|
|
12
|
+
*
|
|
13
|
+
* Errors are loud (`parse issue: <reason>`) so callers can prefix
|
|
14
|
+
* `Error: cockpit <verb>: ` per cli-surface.md.
|
|
15
|
+
*/
|
|
16
|
+
import { type CommandRunner, type GhWrapper } from '@generacy-ai/cockpit';
|
|
17
|
+
export interface IssueRef {
|
|
18
|
+
/** GitHub owner login (e.g. "generacy-ai") */
|
|
19
|
+
owner: string;
|
|
20
|
+
/** GitHub repo name (e.g. "generacy") */
|
|
21
|
+
repo: string;
|
|
22
|
+
/** GitHub issue/PR number */
|
|
23
|
+
number: number;
|
|
24
|
+
/** "owner/repo" — convenience for gh CLI calls */
|
|
25
|
+
nwo: string;
|
|
26
|
+
}
|
|
27
|
+
export interface ResolveIssueContextInput {
|
|
28
|
+
/** The `<issue>` argument as typed by the caller. */
|
|
29
|
+
issue: string;
|
|
30
|
+
/** Optional programmatic override — never exposed as a CLI flag on `context`. */
|
|
31
|
+
repo?: string;
|
|
32
|
+
/** Working directory; defaults to `process.cwd()` for git-origin inference. */
|
|
33
|
+
cwd?: string;
|
|
34
|
+
/** Injected runner (tests only). */
|
|
35
|
+
runner?: CommandRunner;
|
|
36
|
+
}
|
|
37
|
+
export interface ResolvedIssueContext {
|
|
38
|
+
ref: IssueRef;
|
|
39
|
+
/** Same as `ref.nwo` — retained for legacy call-site compatibility. */
|
|
40
|
+
repo: string;
|
|
41
|
+
gh: GhWrapper;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* @internal — cockpit callers MUST use `resolveIssueContext` instead. This
|
|
45
|
+
* function is exported only for its unit tests. Enforced by ESLint
|
|
46
|
+
* `no-restricted-imports` (see `.eslintrc.json`). See #850.
|
|
47
|
+
*
|
|
48
|
+
* Strict qualified-forms parser. Accepts:
|
|
49
|
+
* - `owner/repo#123`
|
|
50
|
+
* - `https://github.com/owner/repo/issues/123`
|
|
51
|
+
* - `https://github.com/owner/repo/pull/123`
|
|
52
|
+
*
|
|
53
|
+
* Bare numbers ("123") fall through to the `unrecognized issue ref` throw —
|
|
54
|
+
* they are NOT a special case here. The bare-number remedy (cwd-origin
|
|
55
|
+
* inference) lives in `resolveIssueContext`.
|
|
56
|
+
*/
|
|
57
|
+
export declare function parseIssueRef(input: string): IssueRef;
|
|
58
|
+
/**
|
|
59
|
+
* Resolve an issue argument to a full `{ ref, repo, gh }` bundle.
|
|
60
|
+
*
|
|
61
|
+
* Strategy:
|
|
62
|
+
* 1. Bare numbers ("123"): resolve owner/repo from `input.repo` or cwd git
|
|
63
|
+
* origin inference, then build the ref directly via `makeRef`.
|
|
64
|
+
* 2. Qualified forms (`owner/repo#N`, URLs): delegate to `parseIssueRef`.
|
|
65
|
+
*
|
|
66
|
+
* The `input.repo` override exists for programmatic callers; the `context`
|
|
67
|
+
* verb intentionally does not expose it as a CLI flag (spec Q5 → A).
|
|
68
|
+
*/
|
|
69
|
+
export declare function resolveIssueContext(input: ResolveIssueContextInput): Promise<ResolvedIssueContext>;
|
|
70
|
+
//# sourceMappingURL=resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/cockpit/resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,SAAS,EACf,MAAM,sBAAsB,CAAC;AAE9B,MAAM,WAAW,QAAQ;IACvB,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,wBAAwB;IACvC,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,QAAQ,CAAC;IACd,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,SAAS,CAAC;CACf;AAuBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAsBrD;AAqBD;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,wBAAwB,GAC9B,OAAO,CAAC,oBAAoB,CAAC,CA4B/B"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cockpit resolver — parses issue arguments and resolves them to a live
|
|
3
|
+
* `{ ref, repo, gh }` bundle:
|
|
4
|
+
*
|
|
5
|
+
* - `IssueRef` — owner/repo/number/nwo
|
|
6
|
+
* - `parseIssueRef(input)` — @internal; strict qualified-forms parser
|
|
7
|
+
* (owner/repo#N and URL only). Cockpit callers
|
|
8
|
+
* MUST go through `resolveIssueContext`.
|
|
9
|
+
* - `resolveIssueContext(x)` — gates bare numbers via cwd-origin inference,
|
|
10
|
+
* delegates qualified forms to `parseIssueRef`,
|
|
11
|
+
* and returns a live `{ ref, repo, gh }` bundle.
|
|
12
|
+
*
|
|
13
|
+
* Errors are loud (`parse issue: <reason>`) so callers can prefix
|
|
14
|
+
* `Error: cockpit <verb>: ` per cli-surface.md.
|
|
15
|
+
*/
|
|
16
|
+
import { GhCliWrapper, nodeChildProcessRunner, } from '@generacy-ai/cockpit';
|
|
17
|
+
const OWNER_REPO_HASH = /^([^/\s]+)\/([^/\s#]+)#(\d+)$/;
|
|
18
|
+
const ISSUE_URL = /^https?:\/\/github\.com\/([^/\s]+)\/([^/\s]+)\/(?:issues|pull)\/(\d+)(?:[/?#].*)?$/;
|
|
19
|
+
const BARE_NUMBER = /^\d+$/;
|
|
20
|
+
function fail(reason) {
|
|
21
|
+
throw new Error(`parse issue: ${reason}`);
|
|
22
|
+
}
|
|
23
|
+
function makeRef(owner, repo, number) {
|
|
24
|
+
if (!owner || owner.includes('/') || /\s/.test(owner)) {
|
|
25
|
+
fail(`invalid owner "${owner}"`);
|
|
26
|
+
}
|
|
27
|
+
if (!repo || repo.includes('/') || /\s/.test(repo)) {
|
|
28
|
+
fail(`invalid repo "${repo}"`);
|
|
29
|
+
}
|
|
30
|
+
if (!Number.isInteger(number) || number <= 0) {
|
|
31
|
+
fail(`issue number must be a positive integer, got "${number}"`);
|
|
32
|
+
}
|
|
33
|
+
return { owner, repo, number, nwo: `${owner}/${repo}` };
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* @internal — cockpit callers MUST use `resolveIssueContext` instead. This
|
|
37
|
+
* function is exported only for its unit tests. Enforced by ESLint
|
|
38
|
+
* `no-restricted-imports` (see `.eslintrc.json`). See #850.
|
|
39
|
+
*
|
|
40
|
+
* Strict qualified-forms parser. Accepts:
|
|
41
|
+
* - `owner/repo#123`
|
|
42
|
+
* - `https://github.com/owner/repo/issues/123`
|
|
43
|
+
* - `https://github.com/owner/repo/pull/123`
|
|
44
|
+
*
|
|
45
|
+
* Bare numbers ("123") fall through to the `unrecognized issue ref` throw —
|
|
46
|
+
* they are NOT a special case here. The bare-number remedy (cwd-origin
|
|
47
|
+
* inference) lives in `resolveIssueContext`.
|
|
48
|
+
*/
|
|
49
|
+
export function parseIssueRef(input) {
|
|
50
|
+
const trimmed = input.trim();
|
|
51
|
+
if (trimmed === '') {
|
|
52
|
+
fail('issue argument is required');
|
|
53
|
+
}
|
|
54
|
+
const ownerRepoHash = OWNER_REPO_HASH.exec(trimmed);
|
|
55
|
+
if (ownerRepoHash) {
|
|
56
|
+
const [, owner, repo, num] = ownerRepoHash;
|
|
57
|
+
return makeRef(owner, repo, Number.parseInt(num, 10));
|
|
58
|
+
}
|
|
59
|
+
const url = ISSUE_URL.exec(trimmed);
|
|
60
|
+
if (url) {
|
|
61
|
+
const [, owner, repo, num] = url;
|
|
62
|
+
return makeRef(owner, repo, Number.parseInt(num, 10));
|
|
63
|
+
}
|
|
64
|
+
fail(`unrecognized issue ref "${input}". ` +
|
|
65
|
+
`Use <n>, <owner>/<repo>#<n>, or https://github.com/<owner>/<repo>/issues/<n>.`);
|
|
66
|
+
}
|
|
67
|
+
async function inferRepoFromGitOrigin(runner, cwd) {
|
|
68
|
+
const result = await runner('git', ['remote', 'get-url', 'origin'], cwd != null ? { cwd } : {});
|
|
69
|
+
if (result.exitCode !== 0) {
|
|
70
|
+
fail(`could not infer owner/repo: 'git remote get-url origin' failed ` +
|
|
71
|
+
`(exit ${result.exitCode}): ${result.stderr.trim()}`);
|
|
72
|
+
}
|
|
73
|
+
const url = result.stdout.trim();
|
|
74
|
+
const match = /github\.com[/:]([^/]+)\/([^/.]+?)(?:\.git)?\/?$/.exec(url);
|
|
75
|
+
if (!match || !match[1] || !match[2]) {
|
|
76
|
+
fail(`could not infer owner/repo from git origin URL: ${url}`);
|
|
77
|
+
}
|
|
78
|
+
return `${match[1]}/${match[2]}`;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Resolve an issue argument to a full `{ ref, repo, gh }` bundle.
|
|
82
|
+
*
|
|
83
|
+
* Strategy:
|
|
84
|
+
* 1. Bare numbers ("123"): resolve owner/repo from `input.repo` or cwd git
|
|
85
|
+
* origin inference, then build the ref directly via `makeRef`.
|
|
86
|
+
* 2. Qualified forms (`owner/repo#N`, URLs): delegate to `parseIssueRef`.
|
|
87
|
+
*
|
|
88
|
+
* The `input.repo` override exists for programmatic callers; the `context`
|
|
89
|
+
* verb intentionally does not expose it as a CLI flag (spec Q5 → A).
|
|
90
|
+
*/
|
|
91
|
+
export async function resolveIssueContext(input) {
|
|
92
|
+
const runner = input.runner ?? nodeChildProcessRunner;
|
|
93
|
+
const trimmed = input.issue.trim();
|
|
94
|
+
if (BARE_NUMBER.test(trimmed)) {
|
|
95
|
+
const number = Number.parseInt(trimmed, 10);
|
|
96
|
+
let repoNwo;
|
|
97
|
+
try {
|
|
98
|
+
repoNwo = input.repo ?? (await inferRepoFromGitOrigin(runner, input.cwd));
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
const innerReason = err.message.replace(/^parse issue: /, '');
|
|
102
|
+
throw new Error(`parse issue: bare issue number "${trimmed}" is not accepted here. ` +
|
|
103
|
+
`Accepted: <owner>/<repo>#${trimmed}, a full issue URL, or a bare number inside a ` +
|
|
104
|
+
`checkout with a resolvable GitHub origin. ` +
|
|
105
|
+
`(cwd-origin inference failed: ${innerReason})`);
|
|
106
|
+
}
|
|
107
|
+
const parts = repoNwo.split('/');
|
|
108
|
+
if (parts.length !== 2 || !parts[0] || !parts[1]) {
|
|
109
|
+
fail(`inferred repo "${repoNwo}" is not in <owner>/<repo> form`);
|
|
110
|
+
}
|
|
111
|
+
const ref = makeRef(parts[0], parts[1], number);
|
|
112
|
+
return { ref, repo: ref.nwo, gh: new GhCliWrapper(runner) };
|
|
113
|
+
}
|
|
114
|
+
const ref = parseIssueRef(input.issue);
|
|
115
|
+
return { ref, repo: ref.nwo, gh: new GhCliWrapper(runner) };
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../../../src/cli/commands/cockpit/resolver.ts"],"names":[],"mappings":"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"}
|