chiefwiggum 1.3.41 → 1.3.43
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/cli.cjs +116 -9
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -1078,16 +1078,32 @@ async function setupProjectConfig() {
|
|
|
1078
1078
|
console.log("Make sure you're in a git repo with a GitHub remote.");
|
|
1079
1079
|
}
|
|
1080
1080
|
console.log();
|
|
1081
|
+
let exitHint = "Then run chiefwiggum new again";
|
|
1082
|
+
let exitCommand = "";
|
|
1083
|
+
if (ghCheck.reason === "not_installed") {
|
|
1084
|
+
exitHint = "brew install gh (macOS) or apt install gh (Linux)";
|
|
1085
|
+
exitCommand = "gh --version";
|
|
1086
|
+
} else if (ghCheck.reason === "not_authenticated") {
|
|
1087
|
+
exitHint = "gh auth login";
|
|
1088
|
+
exitCommand = "gh auth login";
|
|
1089
|
+
} else if (ghCheck.reason === "not_github_repo") {
|
|
1090
|
+
exitHint = "git remote add origin <url>";
|
|
1091
|
+
exitCommand = "git remote -v";
|
|
1092
|
+
}
|
|
1081
1093
|
const fallback = await select2({
|
|
1082
1094
|
message: "What would you like to do?",
|
|
1083
1095
|
options: [
|
|
1084
1096
|
{ value: "todo", label: "Use TODO.md instead", hint: "Track tasks locally" },
|
|
1085
|
-
{ value: "exit", label: "Exit and set up gh first", hint:
|
|
1097
|
+
{ value: "exit", label: "Exit and set up gh first", hint: exitHint }
|
|
1086
1098
|
]
|
|
1087
1099
|
});
|
|
1088
1100
|
if (fallback === "exit") {
|
|
1089
1101
|
console.log();
|
|
1090
|
-
|
|
1102
|
+
if (exitCommand) {
|
|
1103
|
+
console.log(import_picocolors7.default.cyan(` ${exitCommand}`));
|
|
1104
|
+
console.log();
|
|
1105
|
+
}
|
|
1106
|
+
console.log(import_picocolors7.default.dim("Then run 'chiefwiggum new' again."));
|
|
1091
1107
|
process.exit(0);
|
|
1092
1108
|
}
|
|
1093
1109
|
config2.projectTracker = "todo";
|
|
@@ -1402,12 +1418,42 @@ Create 5-15 issues.${projectName ? ` Add each to project "${projectName}".` : ""
|
|
|
1402
1418
|
}
|
|
1403
1419
|
if (!usedFallback) {
|
|
1404
1420
|
const total = issues.length;
|
|
1405
|
-
|
|
1421
|
+
const owner = repoName.split("/")[0];
|
|
1422
|
+
console.log(import_picocolors7.default.dim(" Creating epic from PRD..."));
|
|
1423
|
+
const prdTitleMatch = prdGenerated.match(/^#\s+(.+)$/m);
|
|
1424
|
+
const epicTitle = prdTitleMatch ? `Epic: ${prdTitleMatch[1]}` : "Epic: Project Implementation";
|
|
1425
|
+
const epicBodyInitial = `${prdGenerated}
|
|
1426
|
+
|
|
1427
|
+
---
|
|
1428
|
+
|
|
1429
|
+
## Tasks
|
|
1430
|
+
|
|
1431
|
+
_Creating issues..._
|
|
1432
|
+
`;
|
|
1433
|
+
let epicNumber = null;
|
|
1434
|
+
let epicUrl = null;
|
|
1435
|
+
try {
|
|
1436
|
+
const escapeForShell = (str) => {
|
|
1437
|
+
return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/`/g, "\\`").replace(/\$/g, "\\$").replace(/!/g, "\\!").replace(/\n/g, "\\n");
|
|
1438
|
+
};
|
|
1439
|
+
const epicCmd = `gh issue create --title "${escapeForShell(epicTitle)}" --body "${escapeForShell(epicBodyInitial)}" --label "epic,chiefwiggum"`;
|
|
1440
|
+
epicUrl = (0, import_node_child_process6.execSync)(epicCmd, {
|
|
1441
|
+
encoding: "utf-8",
|
|
1442
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
1443
|
+
}).trim();
|
|
1444
|
+
const epicNumMatch = epicUrl.match(/\/issues\/(\d+)$/);
|
|
1445
|
+
epicNumber = epicNumMatch ? parseInt(epicNumMatch[1], 10) : null;
|
|
1446
|
+
if (epicNumber) {
|
|
1447
|
+
console.log(import_picocolors7.default.green(` \u2713 Created epic #${epicNumber}`));
|
|
1448
|
+
}
|
|
1449
|
+
} catch {
|
|
1450
|
+
console.log(import_picocolors7.default.yellow(" Could not create epic issue. Continuing without parent tracking..."));
|
|
1451
|
+
}
|
|
1452
|
+
console.log(import_picocolors7.default.dim(` Creating ${total} child issues...`));
|
|
1406
1453
|
let projectNumber = null;
|
|
1407
1454
|
let projectId = null;
|
|
1408
1455
|
let statusFieldId = null;
|
|
1409
1456
|
let todoOptionId = null;
|
|
1410
|
-
const owner = repoName.split("/")[0];
|
|
1411
1457
|
if (projectName) {
|
|
1412
1458
|
try {
|
|
1413
1459
|
const projectsOutput = (0, import_node_child_process6.execSync)(
|
|
@@ -1453,6 +1499,15 @@ Create 5-15 issues.${projectName ? ` Add each to project "${projectName}".` : ""
|
|
|
1453
1499
|
} catch {
|
|
1454
1500
|
}
|
|
1455
1501
|
}
|
|
1502
|
+
if (epicUrl && projectNumber) {
|
|
1503
|
+
try {
|
|
1504
|
+
(0, import_node_child_process6.execSync)(
|
|
1505
|
+
`gh project item-add ${projectNumber} --owner ${owner} --url "${epicUrl}"`,
|
|
1506
|
+
{ stdio: ["pipe", "pipe", "pipe"] }
|
|
1507
|
+
);
|
|
1508
|
+
} catch {
|
|
1509
|
+
}
|
|
1510
|
+
}
|
|
1456
1511
|
let availableLabels = /* @__PURE__ */ new Set();
|
|
1457
1512
|
try {
|
|
1458
1513
|
const labelsOutput = (0, import_node_child_process6.execSync)("gh label list --json name --jq '.[].name'", {
|
|
@@ -1467,11 +1522,16 @@ Create 5-15 issues.${projectName ? ` Add each to project "${projectName}".` : ""
|
|
|
1467
1522
|
`gh label create chiefwiggum --description "Created by Chief Wiggum CLI" --color "FFA500" 2>/dev/null || true`,
|
|
1468
1523
|
{ stdio: ["pipe", "pipe", "pipe"] }
|
|
1469
1524
|
);
|
|
1525
|
+
(0, import_node_child_process6.execSync)(
|
|
1526
|
+
`gh label create epic --description "Parent tracking issue" --color "6366F1" 2>/dev/null || true`,
|
|
1527
|
+
{ stdio: ["pipe", "pipe", "pipe"] }
|
|
1528
|
+
);
|
|
1470
1529
|
} catch {
|
|
1471
1530
|
}
|
|
1472
1531
|
let created = 0;
|
|
1473
1532
|
let failed = 0;
|
|
1474
1533
|
const failedIssues = [];
|
|
1534
|
+
const createdIssueNumbers = [];
|
|
1475
1535
|
for (let i = 0; i < issues.length; i++) {
|
|
1476
1536
|
const issue = issues[i];
|
|
1477
1537
|
const progress = Math.round((i + 1) / total * 100);
|
|
@@ -1487,13 +1547,25 @@ Create 5-15 issues.${projectName ? ` Add each to project "${projectName}".` : ""
|
|
|
1487
1547
|
const escapeForShell = (str) => {
|
|
1488
1548
|
return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/`/g, "\\`").replace(/\$/g, "\\$").replace(/!/g, "\\!").replace(/\n/g, "\\n");
|
|
1489
1549
|
};
|
|
1490
|
-
|
|
1550
|
+
let bodyWithEpic = issue.body;
|
|
1551
|
+
if (epicNumber) {
|
|
1552
|
+
bodyWithEpic = `Part of #${epicNumber}
|
|
1553
|
+
|
|
1554
|
+
---
|
|
1555
|
+
|
|
1556
|
+
${issue.body}`;
|
|
1557
|
+
}
|
|
1558
|
+
const body = escapeForShell(bodyWithEpic);
|
|
1491
1559
|
const title = escapeForShell(issue.title);
|
|
1492
1560
|
const createCmd = `gh issue create --title "${title}" --body "${body}" ${labelsArg}`;
|
|
1493
1561
|
const issueUrl = (0, import_node_child_process6.execSync)(createCmd, {
|
|
1494
1562
|
encoding: "utf-8",
|
|
1495
1563
|
stdio: ["pipe", "pipe", "pipe"]
|
|
1496
1564
|
}).trim();
|
|
1565
|
+
const issueNumMatch = issueUrl.match(/\/issues\/(\d+)$/);
|
|
1566
|
+
if (issueNumMatch) {
|
|
1567
|
+
createdIssueNumbers.push(parseInt(issueNumMatch[1], 10));
|
|
1568
|
+
}
|
|
1497
1569
|
if (projectNumber && issueUrl) {
|
|
1498
1570
|
try {
|
|
1499
1571
|
const addOutput = (0, import_node_child_process6.execSync)(
|
|
@@ -1542,6 +1614,28 @@ Create 5-15 issues.${projectName ? ` Add each to project "${projectName}".` : ""
|
|
|
1542
1614
|
console.log(import_picocolors7.default.green(` \u2713 Added to board "${projectName}"`));
|
|
1543
1615
|
}
|
|
1544
1616
|
}
|
|
1617
|
+
if (epicNumber && createdIssueNumbers.length > 0) {
|
|
1618
|
+
const escapeForShell = (str) => {
|
|
1619
|
+
return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/`/g, "\\`").replace(/\$/g, "\\$").replace(/!/g, "\\!").replace(/\n/g, "\\n");
|
|
1620
|
+
};
|
|
1621
|
+
const tasklist = createdIssueNumbers.map((num) => `- [ ] #${num}`).join("\n");
|
|
1622
|
+
const updatedEpicBody = `${prdGenerated}
|
|
1623
|
+
|
|
1624
|
+
---
|
|
1625
|
+
|
|
1626
|
+
## Tasks
|
|
1627
|
+
|
|
1628
|
+
${tasklist}`;
|
|
1629
|
+
try {
|
|
1630
|
+
(0, import_node_child_process6.execSync)(
|
|
1631
|
+
`gh issue edit ${epicNumber} --body "${escapeForShell(updatedEpicBody)}"`,
|
|
1632
|
+
{ stdio: ["pipe", "pipe", "pipe"] }
|
|
1633
|
+
);
|
|
1634
|
+
console.log(import_picocolors7.default.green(` \u2713 Updated epic #${epicNumber} with tasklist`));
|
|
1635
|
+
} catch {
|
|
1636
|
+
console.log(import_picocolors7.default.yellow(` Could not update epic with tasklist`));
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1545
1639
|
} else {
|
|
1546
1640
|
console.log(import_picocolors7.default.green(" \u2713 GitHub Issues created"));
|
|
1547
1641
|
if (projectName) {
|
|
@@ -1801,7 +1895,7 @@ async function cleanGitHubIssues() {
|
|
|
1801
1895
|
let issues = [];
|
|
1802
1896
|
try {
|
|
1803
1897
|
const output = (0, import_node_child_process7.execSync)(
|
|
1804
|
-
`gh issue list --label chiefwiggum --state open --json number,title,createdAt --limit 100`,
|
|
1898
|
+
`gh issue list --label chiefwiggum --state open --json number,title,createdAt,labels --limit 100`,
|
|
1805
1899
|
{ encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
|
|
1806
1900
|
);
|
|
1807
1901
|
issues = JSON.parse(output);
|
|
@@ -1813,10 +1907,22 @@ async function cleanGitHubIssues() {
|
|
|
1813
1907
|
console.log(import_picocolors8.default.dim("No open issues with 'chiefwiggum' label found."));
|
|
1814
1908
|
return;
|
|
1815
1909
|
}
|
|
1910
|
+
const isEpic = (i) => i.labels.some((l) => l.name === "epic");
|
|
1911
|
+
const epics = issues.filter(isEpic);
|
|
1912
|
+
const childIssues = issues.filter((i) => !isEpic(i));
|
|
1816
1913
|
console.log();
|
|
1817
1914
|
console.log(`Found ${issues.length} issues with 'chiefwiggum' label:`);
|
|
1818
|
-
|
|
1819
|
-
console.log(
|
|
1915
|
+
if (epics.length > 0) {
|
|
1916
|
+
console.log(import_picocolors8.default.dim(" Epics:"));
|
|
1917
|
+
for (const issue of epics) {
|
|
1918
|
+
console.log(` ${import_picocolors8.default.magenta(`#${issue.number}`)} ${import_picocolors8.default.bold("\u{1F4CB}")} ${issue.title}`);
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1921
|
+
if (childIssues.length > 0) {
|
|
1922
|
+
console.log(import_picocolors8.default.dim(" Tasks:"));
|
|
1923
|
+
for (const issue of childIssues) {
|
|
1924
|
+
console.log(` ${import_picocolors8.default.cyan(`#${issue.number}`)} - ${issue.title}`);
|
|
1925
|
+
}
|
|
1820
1926
|
}
|
|
1821
1927
|
console.log();
|
|
1822
1928
|
const action = await select2({
|
|
@@ -1836,7 +1942,8 @@ async function cleanGitHubIssues() {
|
|
|
1836
1942
|
message: "Select issues to remove (space to toggle, enter to confirm)",
|
|
1837
1943
|
options: issues.map((i) => ({
|
|
1838
1944
|
value: String(i.number),
|
|
1839
|
-
label: `#${i.number} - ${i.title}
|
|
1945
|
+
label: isEpic(i) ? `\u{1F4CB} #${i.number} - ${i.title}` : `#${i.number} - ${i.title}`,
|
|
1946
|
+
hint: isEpic(i) ? "epic" : void 0
|
|
1840
1947
|
}))
|
|
1841
1948
|
});
|
|
1842
1949
|
if (selected.length === 0) {
|