@staff0rd/assist 0.606.0 → 0.607.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 +1 -1
- package/dist/commands/sessions/web/bundle.js +376 -376
- package/dist/index.js +146 -45
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Command } from "commander";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "@staff0rd/assist",
|
|
9
|
-
version: "0.
|
|
9
|
+
version: "0.607.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -21693,6 +21693,12 @@ function registerCommentIssue(issueCommand) {
|
|
|
21693
21693
|
);
|
|
21694
21694
|
}
|
|
21695
21695
|
|
|
21696
|
+
// src/commands/github/issue/collectLabels.ts
|
|
21697
|
+
function collectLabels(value, previous) {
|
|
21698
|
+
const added = value.split(",").map((label2) => label2.trim()).filter((label2) => label2.length > 0);
|
|
21699
|
+
return [...previous, ...added];
|
|
21700
|
+
}
|
|
21701
|
+
|
|
21696
21702
|
// src/commands/github/issue/addIssueToProject.ts
|
|
21697
21703
|
var MUTATION3 = `mutation($projectId: ID!, $contentId: ID!) {
|
|
21698
21704
|
addProjectV2ItemById(input: { projectId: $projectId, contentId: $contentId }) {
|
|
@@ -21706,6 +21712,16 @@ function addIssueToProject(projectId, contentId) {
|
|
|
21706
21712
|
return id;
|
|
21707
21713
|
}
|
|
21708
21714
|
|
|
21715
|
+
// src/commands/github/issue/addSubIssue.ts
|
|
21716
|
+
var MUTATION4 = `mutation($issueId: ID!, $subIssueId: ID!) {
|
|
21717
|
+
addSubIssue(input: { issueId: $issueId, subIssueId: $subIssueId }) {
|
|
21718
|
+
subIssue { id }
|
|
21719
|
+
}
|
|
21720
|
+
}`;
|
|
21721
|
+
function addSubIssue(parentId, childId) {
|
|
21722
|
+
runGhGraphqlJson(MUTATION4, { issueId: parentId, subIssueId: childId });
|
|
21723
|
+
}
|
|
21724
|
+
|
|
21709
21725
|
// src/commands/github/issue/fetchIssueNodeId.ts
|
|
21710
21726
|
var QUERY4 = `query($owner: String!, $repo: String!, $number: Int!) {
|
|
21711
21727
|
repository(owner: $owner, name: $repo) {
|
|
@@ -21741,7 +21757,7 @@ function parseCreatedIssueUrl(output) {
|
|
|
21741
21757
|
}
|
|
21742
21758
|
|
|
21743
21759
|
// src/commands/github/issue/setProjectItemStatus.ts
|
|
21744
|
-
var
|
|
21760
|
+
var MUTATION5 = `mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $optionId: String!) {
|
|
21745
21761
|
updateProjectV2ItemFieldValue(input: {
|
|
21746
21762
|
projectId: $projectId
|
|
21747
21763
|
itemId: $itemId
|
|
@@ -21752,7 +21768,7 @@ var MUTATION4 = `mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $optionI
|
|
|
21752
21768
|
}
|
|
21753
21769
|
}`;
|
|
21754
21770
|
function setProjectItemStatus(input) {
|
|
21755
|
-
runGhGraphqlJson(
|
|
21771
|
+
runGhGraphqlJson(MUTATION5, input);
|
|
21756
21772
|
}
|
|
21757
21773
|
|
|
21758
21774
|
// src/commands/github/issue/applyCreatedIssueMetadata.ts
|
|
@@ -21760,11 +21776,15 @@ function applyCreatedIssueMetadata(createOutput, metadata2) {
|
|
|
21760
21776
|
let step2 = "identifying the created issue";
|
|
21761
21777
|
try {
|
|
21762
21778
|
const issueId = fetchIssueNodeId(parseCreatedIssueUrl(createOutput));
|
|
21763
|
-
const { issueType, project } = metadata2;
|
|
21779
|
+
const { issueType, parent, project } = metadata2;
|
|
21764
21780
|
if (issueType) {
|
|
21765
21781
|
step2 = `setting its issue type to ${issueType.name}`;
|
|
21766
21782
|
updateIssueType(issueId, issueType.id);
|
|
21767
21783
|
}
|
|
21784
|
+
if (parent) {
|
|
21785
|
+
step2 = `adding it as a sub-issue of ${parent.owner}/${parent.repo}#${parent.number}`;
|
|
21786
|
+
addSubIssue(parent.id, issueId);
|
|
21787
|
+
}
|
|
21768
21788
|
if (project) {
|
|
21769
21789
|
step2 = `adding it to project ${project.number} (${project.title})`;
|
|
21770
21790
|
const itemId2 = addIssueToProject(project.id, issueId);
|
|
@@ -21787,18 +21807,83 @@ function applyCreatedIssueMetadata(createOutput, metadata2) {
|
|
|
21787
21807
|
}
|
|
21788
21808
|
}
|
|
21789
21809
|
|
|
21790
|
-
// src/commands/github/issue/
|
|
21791
|
-
function
|
|
21792
|
-
if (!
|
|
21793
|
-
const
|
|
21794
|
-
|
|
21795
|
-
|
|
21796
|
-
|
|
21797
|
-
|
|
21810
|
+
// src/commands/github/issue/issuePreviewMetadata.ts
|
|
21811
|
+
function issuePreviewMetadata(resolved) {
|
|
21812
|
+
if (!resolved) return [];
|
|
21813
|
+
const { target, issueType, parent, project, labels } = resolved;
|
|
21814
|
+
const items2 = [
|
|
21815
|
+
{ label: "Repository", value: `${target.owner}/${target.repo}` }
|
|
21816
|
+
];
|
|
21817
|
+
if (issueType) items2.push({ label: "Type", value: issueType.name });
|
|
21818
|
+
if (parent)
|
|
21819
|
+
items2.push({
|
|
21820
|
+
label: "Parent",
|
|
21821
|
+
value: `${parent.owner}/${parent.repo}#${parent.number}`
|
|
21822
|
+
});
|
|
21823
|
+
if (project)
|
|
21824
|
+
items2.push({
|
|
21825
|
+
label: "Project",
|
|
21826
|
+
value: `${project.number} (${project.title})`
|
|
21827
|
+
});
|
|
21828
|
+
if (project?.status)
|
|
21829
|
+
items2.push({ label: "Status", value: project.status.optionName });
|
|
21830
|
+
if (labels?.length) items2.push({ label: "Labels", value: labels.join(", ") });
|
|
21831
|
+
return items2;
|
|
21832
|
+
}
|
|
21798
21833
|
|
|
21799
|
-
|
|
21834
|
+
// src/commands/github/issue/hasCreateIssueMetadataOptions.ts
|
|
21835
|
+
function hasCreateIssueMetadataOptions(options2) {
|
|
21836
|
+
if (options2.status && !options2.project) {
|
|
21837
|
+
throw new Error(
|
|
21838
|
+
"--status is a field on a project board, so it needs --project <number>"
|
|
21839
|
+
);
|
|
21840
|
+
}
|
|
21841
|
+
return Boolean(
|
|
21842
|
+
options2.type || options2.parent || options2.project || options2.label?.length
|
|
21843
|
+
);
|
|
21844
|
+
}
|
|
21800
21845
|
|
|
21801
|
-
|
|
21846
|
+
// src/commands/github/issue/resolveIssueLabels.ts
|
|
21847
|
+
var QUERY5 = `query($owner: String!, $repo: String!, $after: String) {
|
|
21848
|
+
repository(owner: $owner, name: $repo) {
|
|
21849
|
+
labels(first: 100, after: $after) {
|
|
21850
|
+
nodes { name }
|
|
21851
|
+
pageInfo { hasNextPage endCursor }
|
|
21852
|
+
}
|
|
21853
|
+
}
|
|
21854
|
+
}`;
|
|
21855
|
+
function readRepoLabels(target) {
|
|
21856
|
+
const names = [];
|
|
21857
|
+
let after;
|
|
21858
|
+
do {
|
|
21859
|
+
const page = JSON.parse(
|
|
21860
|
+
runGhGraphqlJson(QUERY5, { ...target, after })
|
|
21861
|
+
).data?.repository?.labels;
|
|
21862
|
+
if (!page) {
|
|
21863
|
+
throw new Error(
|
|
21864
|
+
`No labels could be read for ${target.owner}/${target.repo}`
|
|
21865
|
+
);
|
|
21866
|
+
}
|
|
21867
|
+
for (const node of page.nodes ?? []) if (node?.name) names.push(node.name);
|
|
21868
|
+
after = page.pageInfo?.hasNextPage ? page.pageInfo.endCursor ?? void 0 : void 0;
|
|
21869
|
+
} while (after);
|
|
21870
|
+
return names;
|
|
21871
|
+
}
|
|
21872
|
+
function matchLabel(names, wanted) {
|
|
21873
|
+
const normalised = normaliseTypeName(wanted);
|
|
21874
|
+
return names.find((name) => name === wanted) ?? names.find((name) => name.toLowerCase() === wanted.toLowerCase()) ?? names.find((name) => normaliseTypeName(name) === normalised);
|
|
21875
|
+
}
|
|
21876
|
+
function resolveIssueLabels(target, wanted) {
|
|
21877
|
+
const names = readRepoLabels(target);
|
|
21878
|
+
return wanted.map((label2) => {
|
|
21879
|
+
const match = matchLabel(names, label2);
|
|
21880
|
+
if (!match) {
|
|
21881
|
+
throw new Error(
|
|
21882
|
+
`${target.owner}/${target.repo} has no ${label2} label. It has ${names.join(", ")}`
|
|
21883
|
+
);
|
|
21884
|
+
}
|
|
21885
|
+
return match;
|
|
21886
|
+
});
|
|
21802
21887
|
}
|
|
21803
21888
|
|
|
21804
21889
|
// src/commands/prs/shared.ts
|
|
@@ -21893,6 +21978,15 @@ function resolveIssueRepoTarget(repo) {
|
|
|
21893
21978
|
return parseRepoSlug(repo);
|
|
21894
21979
|
}
|
|
21895
21980
|
|
|
21981
|
+
// src/commands/github/issue/resolveCreateIssueParent.ts
|
|
21982
|
+
function resolveCreateIssueParent(target, parent) {
|
|
21983
|
+
const reference = resolveFixStructureTarget(
|
|
21984
|
+
parent,
|
|
21985
|
+
`${target.owner}/${target.repo}`
|
|
21986
|
+
);
|
|
21987
|
+
return { ...reference, id: fetchIssueNodeId(reference) };
|
|
21988
|
+
}
|
|
21989
|
+
|
|
21896
21990
|
// src/commands/github/issue/readGhTokenScopes.ts
|
|
21897
21991
|
import { spawnSync as spawnSync6 } from "child_process";
|
|
21898
21992
|
var SCOPES_LINE = /Token scopes:\s*(.*)/;
|
|
@@ -22006,23 +22100,21 @@ function resolveCreateIssueProject(owner, projectNumber, statusName) {
|
|
|
22006
22100
|
|
|
22007
22101
|
// src/commands/github/issue/resolveCreateIssueMetadata.ts
|
|
22008
22102
|
function resolveCreateIssueMetadata(options2) {
|
|
22009
|
-
if (!options2
|
|
22010
|
-
|
|
22011
|
-
throw new Error(
|
|
22012
|
-
"--status is a field on a project board, so it needs --project <number>"
|
|
22013
|
-
);
|
|
22014
|
-
}
|
|
22103
|
+
if (!hasCreateIssueMetadataOptions(options2)) return void 0;
|
|
22104
|
+
const labels = options2.label ?? [];
|
|
22015
22105
|
const target = resolveIssueRepoTarget(options2.repo);
|
|
22016
22106
|
return {
|
|
22017
22107
|
target,
|
|
22018
22108
|
issueType: options2.type ? resolveIssueType(resolveOrgIssueTypes(target.owner), options2.type) : void 0,
|
|
22019
|
-
|
|
22109
|
+
parent: options2.parent ? resolveCreateIssueParent(target, options2.parent) : void 0,
|
|
22110
|
+
project: options2.project ? resolveCreateIssueProject(target.owner, options2.project, options2.status) : void 0,
|
|
22111
|
+
labels: labels.length ? resolveIssueLabels(target, labels) : void 0
|
|
22020
22112
|
};
|
|
22021
22113
|
}
|
|
22022
22114
|
|
|
22023
22115
|
// src/commands/github/issue/reviewProposedIssue.ts
|
|
22024
22116
|
import { randomUUID as randomUUID8 } from "crypto";
|
|
22025
|
-
async function reviewProposedIssue(title, body) {
|
|
22117
|
+
async function reviewProposedIssue(title, body, metadata2 = []) {
|
|
22026
22118
|
const sessionId = process.env.ASSIST_SESSION_ID;
|
|
22027
22119
|
if (process.env.ASSIST_SESSION !== "1" || !sessionId) return;
|
|
22028
22120
|
await awaitPreviewApproval("GitHub issue preview", {
|
|
@@ -22031,15 +22123,17 @@ async function reviewProposedIssue(title, body) {
|
|
|
22031
22123
|
title,
|
|
22032
22124
|
body,
|
|
22033
22125
|
prNumber: null,
|
|
22034
|
-
kind: "github-issue"
|
|
22126
|
+
kind: "github-issue",
|
|
22127
|
+
metadata: metadata2.length ? metadata2 : void 0
|
|
22035
22128
|
});
|
|
22036
22129
|
}
|
|
22037
22130
|
|
|
22038
22131
|
// src/commands/github/issue/runGhIssueCreate.ts
|
|
22039
22132
|
import { execFileSync as execFileSync7 } from "child_process";
|
|
22040
|
-
function runGhIssueCreate(title, body, repo) {
|
|
22133
|
+
function runGhIssueCreate(title, body, repo, labels) {
|
|
22041
22134
|
const args = ["issue", "create", "--title", title, "--body", body];
|
|
22042
22135
|
if (repo) args.push("--repo", repo);
|
|
22136
|
+
for (const label2 of labels ?? []) args.push("--label", label2);
|
|
22043
22137
|
try {
|
|
22044
22138
|
return execFileSync7("gh", args, {
|
|
22045
22139
|
encoding: "utf8",
|
|
@@ -22051,7 +22145,7 @@ function runGhIssueCreate(title, body, repo) {
|
|
|
22051
22145
|
}
|
|
22052
22146
|
|
|
22053
22147
|
// src/commands/github/issue/createIssue.ts
|
|
22054
|
-
var USAGE2 = "Usage: assist github issue create --title <title> --body <body> [-R <owner>/<repo>] [--type <name>] [--project <number>] [--status <name>]";
|
|
22148
|
+
var USAGE2 = "Usage: assist github issue create --title <title> --body <body> [-R <owner>/<repo>] [--type <name>] [--parent <issue>] [--project <number>] [--status <name>] [--label <name>]";
|
|
22055
22149
|
function preflight(options2) {
|
|
22056
22150
|
try {
|
|
22057
22151
|
return resolveCreateIssueMetadata(options2);
|
|
@@ -22060,15 +22154,6 @@ function preflight(options2) {
|
|
|
22060
22154
|
process.exit(1);
|
|
22061
22155
|
}
|
|
22062
22156
|
}
|
|
22063
|
-
function previewMetadata(resolved) {
|
|
22064
|
-
if (!resolved) return void 0;
|
|
22065
|
-
return {
|
|
22066
|
-
repo: `${resolved.target.owner}/${resolved.target.repo}`,
|
|
22067
|
-
type: resolved.issueType?.name,
|
|
22068
|
-
project: resolved.project && `${resolved.project.number} (${resolved.project.title})`,
|
|
22069
|
-
status: resolved.project?.status?.optionName
|
|
22070
|
-
};
|
|
22071
|
-
}
|
|
22072
22157
|
async function createIssue(options2) {
|
|
22073
22158
|
if (!options2.title || !options2.body) {
|
|
22074
22159
|
console.error(USAGE2);
|
|
@@ -22081,11 +22166,8 @@ async function createIssue(options2) {
|
|
|
22081
22166
|
body
|
|
22082
22167
|
);
|
|
22083
22168
|
const resolved = preflight(options2);
|
|
22084
|
-
await reviewProposedIssue(
|
|
22085
|
-
|
|
22086
|
-
buildIssuePreviewBody(previewMetadata(resolved), body)
|
|
22087
|
-
);
|
|
22088
|
-
const output = runGhIssueCreate(title, body, options2.repo);
|
|
22169
|
+
await reviewProposedIssue(title, body, issuePreviewMetadata(resolved));
|
|
22170
|
+
const output = runGhIssueCreate(title, body, options2.repo, resolved?.labels);
|
|
22089
22171
|
console.log(output.trim());
|
|
22090
22172
|
if (resolved) applyCreatedIssueMetadata(output, resolved);
|
|
22091
22173
|
}
|
|
@@ -22098,15 +22180,23 @@ function registerCreateIssue(issueCommand) {
|
|
|
22098
22180
|
).option(
|
|
22099
22181
|
"--type <name>",
|
|
22100
22182
|
"Native issue type to set on the new issue (e.g. Epic)"
|
|
22183
|
+
).option(
|
|
22184
|
+
"--parent <issue>",
|
|
22185
|
+
"Parent issue to file the new issue under, as owner/repo#number, a github.com issue URL, or a bare number"
|
|
22101
22186
|
).option(
|
|
22102
22187
|
"--project <number>",
|
|
22103
22188
|
"Number of the repo owner's GitHub Project to add the new issue to"
|
|
22104
22189
|
).option(
|
|
22105
22190
|
"--status <name>",
|
|
22106
22191
|
"Status option to set on the project item (requires --project)"
|
|
22192
|
+
).option(
|
|
22193
|
+
"--label <name>",
|
|
22194
|
+
"Label to apply (repeat the flag, or pass a comma-separated list)",
|
|
22195
|
+
collectLabels,
|
|
22196
|
+
[]
|
|
22107
22197
|
).addHelpText(
|
|
22108
22198
|
"after",
|
|
22109
|
-
"\nThere is no What/Why/How template: an issue reports a problem, and the target repo's own issue template is unknowable from here. Write the body as the repo's maintainers would expect.\nIn an assist web session the title and body are previewed for approve/reject first (with inline comments); nothing is created until it is approved.\n--type, --project and --
|
|
22199
|
+
"\nThere is no What/Why/How template: an issue reports a problem, and the target repo's own issue template is unknowable from here. Write the body as the repo's maintainers would expect.\nIn an assist web session the title and body are previewed for approve/reject first (with inline comments); nothing is created until it is approved.\n--type, --parent, --project, --status and --label are all resolved before the preview, so an unknown name, an unreadable parent, a missing project scope or --status without --project creates nothing.\nA bare --parent number is read against --repo, or the current repo; a parent in another repository is allowed.\nThe project scope is needed for --project: gh auth refresh -h github.com -s project"
|
|
22110
22200
|
).action(createIssue);
|
|
22111
22201
|
}
|
|
22112
22202
|
|
|
@@ -29024,15 +29114,15 @@ function runReviewSubmission(mutation, body) {
|
|
|
29024
29114
|
}
|
|
29025
29115
|
|
|
29026
29116
|
// src/commands/review/submitBodyOnlyReview.ts
|
|
29027
|
-
var
|
|
29117
|
+
var MUTATION6 = `mutation($prId: ID!, $body: String) { addPullRequestReview(input: { pullRequestId: $prId, event: COMMENT, body: $body }) { pullRequestReview { id } } }`;
|
|
29028
29118
|
function submitBodyOnlyReview(body) {
|
|
29029
|
-
runReviewSubmission(
|
|
29119
|
+
runReviewSubmission(MUTATION6, body);
|
|
29030
29120
|
}
|
|
29031
29121
|
|
|
29032
29122
|
// src/commands/review/submitPendingReview.ts
|
|
29033
|
-
var
|
|
29123
|
+
var MUTATION7 = `mutation($prId: ID!, $body: String) { submitPullRequestReview(input: { pullRequestId: $prId, event: COMMENT, body: $body }) { pullRequestReview { id } } }`;
|
|
29034
29124
|
function submitPendingReview(body) {
|
|
29035
|
-
runReviewSubmission(
|
|
29125
|
+
runReviewSubmission(MUTATION7, body);
|
|
29036
29126
|
}
|
|
29037
29127
|
|
|
29038
29128
|
// src/commands/review/postAndMaybeSubmit.ts
|
|
@@ -35056,6 +35146,16 @@ function isPreviewKind(value) {
|
|
|
35056
35146
|
return PREVIEW_KINDS.includes(value);
|
|
35057
35147
|
}
|
|
35058
35148
|
|
|
35149
|
+
// src/commands/sessions/daemon/parsePreviewMetadata.ts
|
|
35150
|
+
function parsePreviewMetadata(value) {
|
|
35151
|
+
if (!Array.isArray(value)) return void 0;
|
|
35152
|
+
const items2 = value.flatMap((entry) => {
|
|
35153
|
+
const { label: label2, value: text18 } = entry ?? {};
|
|
35154
|
+
return typeof label2 === "string" && typeof text18 === "string" ? [{ label: label2, value: text18 }] : [];
|
|
35155
|
+
});
|
|
35156
|
+
return items2.length > 0 ? items2 : void 0;
|
|
35157
|
+
}
|
|
35158
|
+
|
|
35059
35159
|
// src/commands/sessions/daemon/previewTargetLabel.ts
|
|
35060
35160
|
function previewTargetLabel(kind, itemType, prNumber, draft) {
|
|
35061
35161
|
if (kind === "backlog-comment") return "backlog comment";
|
|
@@ -35092,7 +35192,8 @@ function setPrPreview(sessions, waiters, notify2, client, d) {
|
|
|
35092
35192
|
prNumber,
|
|
35093
35193
|
kind,
|
|
35094
35194
|
itemType: kind === "backlog-item" ? itemType : void 0,
|
|
35095
|
-
draft: kind === "pr" && prNumber === null ? draft : void 0
|
|
35195
|
+
draft: kind === "pr" && prNumber === null ? draft : void 0,
|
|
35196
|
+
metadata: parsePreviewMetadata(d.metadata)
|
|
35096
35197
|
};
|
|
35097
35198
|
waiters.set(id, client);
|
|
35098
35199
|
const target = previewTargetLabel(kind, itemType, prNumber, draft);
|