@staff0rd/assist 0.606.0 → 0.606.1

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/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.606.0",
9
+ version: "0.606.1",
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 }) {
@@ -21787,18 +21793,66 @@ function applyCreatedIssueMetadata(createOutput, metadata2) {
21787
21793
  }
21788
21794
  }
21789
21795
 
21790
- // src/commands/github/issue/buildIssuePreviewBody.ts
21791
- function buildIssuePreviewBody(metadata2, body) {
21792
- if (!metadata2) return body;
21793
- const lines2 = [`**Repository:** ${metadata2.repo}`];
21794
- if (metadata2.type) lines2.push(`**Type:** ${metadata2.type}`);
21795
- if (metadata2.project) lines2.push(`**Project:** ${metadata2.project}`);
21796
- if (metadata2.status) lines2.push(`**Status:** ${metadata2.status}`);
21797
- return `${lines2.join("\n")}
21798
-
21799
- ---
21796
+ // src/commands/github/issue/issuePreviewMetadata.ts
21797
+ function issuePreviewMetadata(resolved) {
21798
+ if (!resolved) return [];
21799
+ const { target, issueType, project, labels } = resolved;
21800
+ const items2 = [
21801
+ { label: "Repository", value: `${target.owner}/${target.repo}` }
21802
+ ];
21803
+ if (issueType) items2.push({ label: "Type", value: issueType.name });
21804
+ if (project)
21805
+ items2.push({
21806
+ label: "Project",
21807
+ value: `${project.number} (${project.title})`
21808
+ });
21809
+ if (project?.status)
21810
+ items2.push({ label: "Status", value: project.status.optionName });
21811
+ if (labels?.length) items2.push({ label: "Labels", value: labels.join(", ") });
21812
+ return items2;
21813
+ }
21800
21814
 
21801
- ${body}`;
21815
+ // src/commands/github/issue/resolveIssueLabels.ts
21816
+ var QUERY5 = `query($owner: String!, $repo: String!, $after: String) {
21817
+ repository(owner: $owner, name: $repo) {
21818
+ labels(first: 100, after: $after) {
21819
+ nodes { name }
21820
+ pageInfo { hasNextPage endCursor }
21821
+ }
21822
+ }
21823
+ }`;
21824
+ function readRepoLabels(target) {
21825
+ const names = [];
21826
+ let after;
21827
+ do {
21828
+ const page = JSON.parse(
21829
+ runGhGraphqlJson(QUERY5, { ...target, after })
21830
+ ).data?.repository?.labels;
21831
+ if (!page) {
21832
+ throw new Error(
21833
+ `No labels could be read for ${target.owner}/${target.repo}`
21834
+ );
21835
+ }
21836
+ for (const node of page.nodes ?? []) if (node?.name) names.push(node.name);
21837
+ after = page.pageInfo?.hasNextPage ? page.pageInfo.endCursor ?? void 0 : void 0;
21838
+ } while (after);
21839
+ return names;
21840
+ }
21841
+ function matchLabel(names, wanted) {
21842
+ const normalised = normaliseTypeName(wanted);
21843
+ return names.find((name) => name === wanted) ?? names.find((name) => name.toLowerCase() === wanted.toLowerCase()) ?? names.find((name) => normaliseTypeName(name) === normalised);
21844
+ }
21845
+ function resolveIssueLabels(target, wanted) {
21846
+ const names = readRepoLabels(target);
21847
+ return wanted.map((label2) => {
21848
+ const match = matchLabel(names, label2);
21849
+ if (!match) {
21850
+ throw new Error(
21851
+ `${target.owner}/${target.repo} has no ${label2} label. It has ${names.join(", ")}`
21852
+ );
21853
+ }
21854
+ return match;
21855
+ });
21802
21856
  }
21803
21857
 
21804
21858
  // src/commands/prs/shared.ts
@@ -22006,7 +22060,9 @@ function resolveCreateIssueProject(owner, projectNumber, statusName) {
22006
22060
 
22007
22061
  // src/commands/github/issue/resolveCreateIssueMetadata.ts
22008
22062
  function resolveCreateIssueMetadata(options2) {
22009
- if (!options2.type && !options2.project && !options2.status) return void 0;
22063
+ const labels = options2.label ?? [];
22064
+ if (!options2.type && !options2.project && !options2.status && !labels.length)
22065
+ return void 0;
22010
22066
  if (options2.status && !options2.project) {
22011
22067
  throw new Error(
22012
22068
  "--status is a field on a project board, so it needs --project <number>"
@@ -22016,13 +22072,14 @@ function resolveCreateIssueMetadata(options2) {
22016
22072
  return {
22017
22073
  target,
22018
22074
  issueType: options2.type ? resolveIssueType(resolveOrgIssueTypes(target.owner), options2.type) : void 0,
22019
- project: options2.project ? resolveCreateIssueProject(target.owner, options2.project, options2.status) : void 0
22075
+ project: options2.project ? resolveCreateIssueProject(target.owner, options2.project, options2.status) : void 0,
22076
+ labels: labels.length ? resolveIssueLabels(target, labels) : void 0
22020
22077
  };
22021
22078
  }
22022
22079
 
22023
22080
  // src/commands/github/issue/reviewProposedIssue.ts
22024
22081
  import { randomUUID as randomUUID8 } from "crypto";
22025
- async function reviewProposedIssue(title, body) {
22082
+ async function reviewProposedIssue(title, body, metadata2 = []) {
22026
22083
  const sessionId = process.env.ASSIST_SESSION_ID;
22027
22084
  if (process.env.ASSIST_SESSION !== "1" || !sessionId) return;
22028
22085
  await awaitPreviewApproval("GitHub issue preview", {
@@ -22031,15 +22088,17 @@ async function reviewProposedIssue(title, body) {
22031
22088
  title,
22032
22089
  body,
22033
22090
  prNumber: null,
22034
- kind: "github-issue"
22091
+ kind: "github-issue",
22092
+ metadata: metadata2.length ? metadata2 : void 0
22035
22093
  });
22036
22094
  }
22037
22095
 
22038
22096
  // src/commands/github/issue/runGhIssueCreate.ts
22039
22097
  import { execFileSync as execFileSync7 } from "child_process";
22040
- function runGhIssueCreate(title, body, repo) {
22098
+ function runGhIssueCreate(title, body, repo, labels) {
22041
22099
  const args = ["issue", "create", "--title", title, "--body", body];
22042
22100
  if (repo) args.push("--repo", repo);
22101
+ for (const label2 of labels ?? []) args.push("--label", label2);
22043
22102
  try {
22044
22103
  return execFileSync7("gh", args, {
22045
22104
  encoding: "utf8",
@@ -22051,7 +22110,7 @@ function runGhIssueCreate(title, body, repo) {
22051
22110
  }
22052
22111
 
22053
22112
  // 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>]";
22113
+ var USAGE2 = "Usage: assist github issue create --title <title> --body <body> [-R <owner>/<repo>] [--type <name>] [--project <number>] [--status <name>] [--label <name>]";
22055
22114
  function preflight(options2) {
22056
22115
  try {
22057
22116
  return resolveCreateIssueMetadata(options2);
@@ -22060,15 +22119,6 @@ function preflight(options2) {
22060
22119
  process.exit(1);
22061
22120
  }
22062
22121
  }
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
22122
  async function createIssue(options2) {
22073
22123
  if (!options2.title || !options2.body) {
22074
22124
  console.error(USAGE2);
@@ -22081,11 +22131,8 @@ async function createIssue(options2) {
22081
22131
  body
22082
22132
  );
22083
22133
  const resolved = preflight(options2);
22084
- await reviewProposedIssue(
22085
- title,
22086
- buildIssuePreviewBody(previewMetadata(resolved), body)
22087
- );
22088
- const output = runGhIssueCreate(title, body, options2.repo);
22134
+ await reviewProposedIssue(title, body, issuePreviewMetadata(resolved));
22135
+ const output = runGhIssueCreate(title, body, options2.repo, resolved?.labels);
22089
22136
  console.log(output.trim());
22090
22137
  if (resolved) applyCreatedIssueMetadata(output, resolved);
22091
22138
  }
@@ -22104,9 +22151,14 @@ function registerCreateIssue(issueCommand) {
22104
22151
  ).option(
22105
22152
  "--status <name>",
22106
22153
  "Status option to set on the project item (requires --project)"
22154
+ ).option(
22155
+ "--label <name>",
22156
+ "Label to apply (repeat the flag, or pass a comma-separated list)",
22157
+ collectLabels,
22158
+ []
22107
22159
  ).addHelpText(
22108
22160
  "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 --status are all resolved before the preview, so an unknown name, a missing project scope or --status without --project creates nothing.\nThe project scope is needed for --project: gh auth refresh -h github.com -s project"
22161
+ "\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, --status and --label are all resolved before the preview, so an unknown name, a missing project scope or --status without --project creates nothing.\nThe project scope is needed for --project: gh auth refresh -h github.com -s project"
22110
22162
  ).action(createIssue);
22111
22163
  }
22112
22164
 
@@ -35056,6 +35108,16 @@ function isPreviewKind(value) {
35056
35108
  return PREVIEW_KINDS.includes(value);
35057
35109
  }
35058
35110
 
35111
+ // src/commands/sessions/daemon/parsePreviewMetadata.ts
35112
+ function parsePreviewMetadata(value) {
35113
+ if (!Array.isArray(value)) return void 0;
35114
+ const items2 = value.flatMap((entry) => {
35115
+ const { label: label2, value: text18 } = entry ?? {};
35116
+ return typeof label2 === "string" && typeof text18 === "string" ? [{ label: label2, value: text18 }] : [];
35117
+ });
35118
+ return items2.length > 0 ? items2 : void 0;
35119
+ }
35120
+
35059
35121
  // src/commands/sessions/daemon/previewTargetLabel.ts
35060
35122
  function previewTargetLabel(kind, itemType, prNumber, draft) {
35061
35123
  if (kind === "backlog-comment") return "backlog comment";
@@ -35092,7 +35154,8 @@ function setPrPreview(sessions, waiters, notify2, client, d) {
35092
35154
  prNumber,
35093
35155
  kind,
35094
35156
  itemType: kind === "backlog-item" ? itemType : void 0,
35095
- draft: kind === "pr" && prNumber === null ? draft : void 0
35157
+ draft: kind === "pr" && prNumber === null ? draft : void 0,
35158
+ metadata: parsePreviewMetadata(d.metadata)
35096
35159
  };
35097
35160
  waiters.set(id, client);
35098
35161
  const target = previewTargetLabel(kind, itemType, prNumber, draft);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.606.0",
3
+ "version": "0.606.1",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {