@ondrej-svec/hog 1.14.1 → 1.15.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 CHANGED
@@ -88,7 +88,9 @@ Labels are abbreviated automatically: `size:M` → `[M]`, `priority:high` → `[
88
88
  | Key | Action |
89
89
  |-----|--------|
90
90
  | `p` | Pick up issue — assign to yourself + optional TickTick task |
91
- | `a` / `u` | Assign / unassign collaborator |
91
+ | `a` | Assign issue to yourself (no-op if already assigned to anyone) |
92
+ | `u` | Undo last reversible action |
93
+ | `e` | Edit issue in `$EDITOR` — change assignee, title, status, labels, body |
92
94
  | `m` | Change project status |
93
95
  | `l` | Add / remove labels |
94
96
  | `c` | Add comment |
package/dist/cli.js CHANGED
@@ -694,6 +694,18 @@ function fetchProjectFields(repo, issueNumber, projectNumber) {
694
694
  field { ... on ProjectV2SingleSelectField { name } }
695
695
  name
696
696
  }
697
+ ... on ProjectV2ItemFieldTextValue {
698
+ field { ... on ProjectV2Field { name } }
699
+ text
700
+ }
701
+ ... on ProjectV2ItemFieldNumberValue {
702
+ field { ... on ProjectV2Field { name } }
703
+ number
704
+ }
705
+ ... on ProjectV2ItemFieldIterationValue {
706
+ field { ... on ProjectV2IterationField { name } }
707
+ title
708
+ }
697
709
  }
698
710
  }
699
711
  }
@@ -724,11 +736,17 @@ function fetchProjectFields(repo, issueNumber, projectNumber) {
724
736
  const fieldValues = projectItem.fieldValues?.nodes ?? [];
725
737
  for (const fv of fieldValues) {
726
738
  if (!fv) continue;
727
- if ("date" in fv && DATE_FIELD_NAME_RE2.test(fv.field?.name ?? "")) {
739
+ const fieldName = fv.field?.name ?? "";
740
+ if ("date" in fv && DATE_FIELD_NAME_RE2.test(fieldName)) {
728
741
  fields.targetDate = fv.date;
729
- }
730
- if ("name" in fv && fv.field?.name === "Status") {
742
+ } else if ("name" in fv && fieldName === "Status") {
731
743
  fields.status = fv.name;
744
+ } else if (fieldName) {
745
+ const value = "text" in fv && fv.text != null ? fv.text : "number" in fv && fv.number != null ? String(fv.number) : "name" in fv && fv.name != null ? fv.name : "title" in fv && fv.title != null ? fv.title : null;
746
+ if (value != null) {
747
+ if (!fields.customFields) fields.customFields = {};
748
+ fields.customFields[fieldName] = value;
749
+ }
732
750
  }
733
751
  }
734
752
  return fields;
@@ -761,6 +779,18 @@ function fetchProjectEnrichment(repo, projectNumber) {
761
779
  field { ... on ProjectV2SingleSelectField { name } }
762
780
  name
763
781
  }
782
+ ... on ProjectV2ItemFieldTextValue {
783
+ field { ... on ProjectV2Field { name } }
784
+ text
785
+ }
786
+ ... on ProjectV2ItemFieldNumberValue {
787
+ field { ... on ProjectV2Field { name } }
788
+ number
789
+ }
790
+ ... on ProjectV2ItemFieldIterationValue {
791
+ field { ... on ProjectV2IterationField { name } }
792
+ title
793
+ }
764
794
  }
765
795
  }
766
796
  }
@@ -793,11 +823,17 @@ function fetchProjectEnrichment(repo, projectNumber) {
793
823
  const fieldValues = item.fieldValues?.nodes ?? [];
794
824
  for (const fv of fieldValues) {
795
825
  if (!fv) continue;
796
- if ("date" in fv && fv.date && DATE_FIELD_NAME_RE2.test(fv.field?.name ?? "")) {
826
+ const fieldName = fv.field?.name ?? "";
827
+ if ("date" in fv && fv.date && DATE_FIELD_NAME_RE2.test(fieldName)) {
797
828
  enrichment.targetDate = fv.date;
798
- }
799
- if ("name" in fv && fv.field?.name === "Status" && fv.name) {
829
+ } else if ("name" in fv && fieldName === "Status" && fv.name) {
800
830
  enrichment.projectStatus = fv.name;
831
+ } else if (fieldName) {
832
+ const value = "text" in fv && fv.text != null ? fv.text : "number" in fv && fv.number != null ? String(fv.number) : "name" in fv && fv.name != null ? fv.name : "title" in fv && fv.title != null ? fv.title : null;
833
+ if (value != null) {
834
+ if (!enrichment.customFields) enrichment.customFields = {};
835
+ enrichment.customFields[fieldName] = value;
836
+ }
801
837
  }
802
838
  }
803
839
  enrichMap.set(item.content.number, enrichment);
@@ -4192,8 +4228,9 @@ var init_help_overlay = __esm({
4192
4228
  category: "Actions",
4193
4229
  items: [
4194
4230
  { key: "p", desc: "Pick issue (assign + TickTick)" },
4195
- { key: "a", desc: "Assign to self" },
4231
+ { key: "a", desc: "Assign to self (no-op if already assigned)" },
4196
4232
  { key: "u", desc: "Undo last reversible action" },
4233
+ { key: "e", desc: "Edit issue in $EDITOR (title, assignee, status, labels)" },
4197
4234
  { key: "c", desc: "Comment on issue" },
4198
4235
  { key: "m", desc: "Move status" },
4199
4236
  { key: "e", desc: "Edit issue in $EDITOR" },
@@ -4469,7 +4506,7 @@ function SearchBar({ defaultValue, onChange, onSubmit }) {
4469
4506
  TextInput5,
4470
4507
  {
4471
4508
  defaultValue,
4472
- placeholder: "search...",
4509
+ placeholder: "title, label, status, @user, #123, unassigned\u2026",
4473
4510
  onChange,
4474
4511
  onSubmit
4475
4512
  }
@@ -5315,6 +5352,31 @@ function RefreshAge({ lastRefresh }) {
5315
5352
  timeAgo(lastRefresh)
5316
5353
  ] });
5317
5354
  }
5355
+ function matchesSearch(issue, query) {
5356
+ if (!query.trim()) return true;
5357
+ const tokens = query.toLowerCase().trim().split(/\s+/);
5358
+ const labels = issue.labels ?? [];
5359
+ const assignees = issue.assignees ?? [];
5360
+ return tokens.every((token) => {
5361
+ if (token.startsWith("#")) {
5362
+ const num = parseInt(token.slice(1), 10);
5363
+ return !Number.isNaN(num) && issue.number === num;
5364
+ }
5365
+ if (token.startsWith("@")) {
5366
+ const login = token.slice(1);
5367
+ return assignees.some((a) => a.login.toLowerCase().includes(login));
5368
+ }
5369
+ if (token === "unassigned") return assignees.length === 0;
5370
+ if (token === "assigned") return assignees.length > 0;
5371
+ if (issue.title.toLowerCase().includes(token)) return true;
5372
+ if (labels.some((l) => l.name.toLowerCase().includes(token))) return true;
5373
+ if (issue.projectStatus?.toLowerCase().includes(token)) return true;
5374
+ if (issue.customFields && Object.values(issue.customFields).some((v) => v.toLowerCase().includes(token)))
5375
+ return true;
5376
+ if (assignees.some((a) => a.login.toLowerCase().includes(token))) return true;
5377
+ return false;
5378
+ });
5379
+ }
5318
5380
  function Dashboard({ config: config2, options, activeProfile }) {
5319
5381
  const { exit } = useApp();
5320
5382
  const refreshMs = config2.board.refreshInterval * 1e3;
@@ -5364,8 +5426,7 @@ function Dashboard({ config: config2, options, activeProfile }) {
5364
5426
  })).filter((rd) => rd.issues.length > 0);
5365
5427
  }
5366
5428
  if (!searchQuery) return filtered;
5367
- const q = searchQuery.toLowerCase();
5368
- return filtered.map((rd) => ({ ...rd, issues: rd.issues.filter((i) => i.title.toLowerCase().includes(q)) })).filter((rd) => rd.issues.length > 0);
5429
+ return filtered.map((rd) => ({ ...rd, issues: rd.issues.filter((i) => matchesSearch(i, searchQuery)) })).filter((rd) => rd.issues.length > 0);
5369
5430
  }, [allRepos, searchQuery, mineOnly, config2.board.assignee]);
5370
5431
  const boardTree = useMemo3(() => buildBoardTree(repos, allActivity), [repos, allActivity]);
5371
5432
  const [selectedRepoIdx, setSelectedRepoIdx] = useState16(0);
@@ -6165,6 +6226,7 @@ async function fetchDashboard(config2, options = {}) {
6165
6226
  ...issue,
6166
6227
  ...e?.targetDate !== void 0 ? { targetDate: e.targetDate } : {},
6167
6228
  ...e?.projectStatus !== void 0 ? { projectStatus: e.projectStatus } : {},
6229
+ ...e?.customFields !== void 0 ? { customFields: e.customFields } : {},
6168
6230
  ...slackUrl ? { slackThreadUrl: slackUrl } : {}
6169
6231
  };
6170
6232
  });
@@ -7211,7 +7273,7 @@ function resolveProjectId(projectId) {
7211
7273
  process.exit(1);
7212
7274
  }
7213
7275
  var program = new Command();
7214
- program.name("hog").description("Personal command deck \u2014 unified task dashboard for GitHub Projects + TickTick").version("1.14.1").option("--json", "Force JSON output").option("--human", "Force human-readable output").hook("preAction", (thisCommand) => {
7276
+ program.name("hog").description("Personal command deck \u2014 unified task dashboard for GitHub Projects + TickTick").version("1.15.0").option("--json", "Force JSON output").option("--human", "Force human-readable output").hook("preAction", (thisCommand) => {
7215
7277
  const opts = thisCommand.opts();
7216
7278
  if (opts.json) setFormat("json");
7217
7279
  if (opts.human) setFormat("human");