chiefwiggum 1.3.38 → 1.3.41
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 +180 -19
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -95,6 +95,14 @@ async function multilineText(options) {
|
|
|
95
95
|
});
|
|
96
96
|
});
|
|
97
97
|
}
|
|
98
|
+
async function multiselect2(options) {
|
|
99
|
+
const result = await p.multiselect({
|
|
100
|
+
message: options.message,
|
|
101
|
+
options: options.options,
|
|
102
|
+
required: options.required ?? false
|
|
103
|
+
});
|
|
104
|
+
return handleCancel(result);
|
|
105
|
+
}
|
|
98
106
|
async function searchSelect(options) {
|
|
99
107
|
const { message, items, placeholder = "Type to filter...", maxVisible = 10 } = options;
|
|
100
108
|
const readline = await import("readline");
|
|
@@ -440,9 +448,10 @@ Then list open issues: gh issue list --state open
|
|
|
440
448
|
Use this to update issue status on the project board (replace <issue_number> and <status_name>):
|
|
441
449
|
|
|
442
450
|
\`\`\`bash
|
|
443
|
-
# Get repo owner and project
|
|
451
|
+
# Get repo owner, project number, and project ID
|
|
444
452
|
OWNER=$(gh repo view --json owner -q .owner.login)
|
|
445
453
|
PROJECT_NUM=$(gh repo view --json projectsV2 -q '.projectsV2.Nodes[0].number')
|
|
454
|
+
PROJECT_ID=$(gh repo view --json projectsV2 -q '.projectsV2.Nodes[0].id')
|
|
446
455
|
|
|
447
456
|
# Get the issue's item ID in the project
|
|
448
457
|
ITEM_ID=$(gh project item-list $PROJECT_NUM --owner $OWNER --format json | jq -r '.items[] | select(.content.number == <issue_number>) | .id')
|
|
@@ -452,7 +461,7 @@ FIELD_ID=$(gh project field-list $PROJECT_NUM --owner $OWNER --format json | jq
|
|
|
452
461
|
STATUS_ID=$(gh project field-list $PROJECT_NUM --owner $OWNER --format json | jq -r '.fields[] | select(.name == "Status") | .options[] | select(.name == "<status_name>") | .id')
|
|
453
462
|
|
|
454
463
|
# Update status (use "In Progress" when starting, "Done" when complete)
|
|
455
|
-
gh project item-edit --project-id $
|
|
464
|
+
gh project item-edit --project-id $PROJECT_ID --id $ITEM_ID --field-id $FIELD_ID --single-select-option-id $STATUS_ID
|
|
456
465
|
\`\`\`
|
|
457
466
|
|
|
458
467
|
If any step fails (no project linked, field not found), skip and continue.
|
|
@@ -1395,10 +1404,14 @@ Create 5-15 issues.${projectName ? ` Add each to project "${projectName}".` : ""
|
|
|
1395
1404
|
const total = issues.length;
|
|
1396
1405
|
console.log(import_picocolors7.default.dim(` Creating ${total} issues...`));
|
|
1397
1406
|
let projectNumber = null;
|
|
1407
|
+
let projectId = null;
|
|
1408
|
+
let statusFieldId = null;
|
|
1409
|
+
let todoOptionId = null;
|
|
1410
|
+
const owner = repoName.split("/")[0];
|
|
1398
1411
|
if (projectName) {
|
|
1399
1412
|
try {
|
|
1400
1413
|
const projectsOutput = (0, import_node_child_process6.execSync)(
|
|
1401
|
-
`gh project list --owner ${
|
|
1414
|
+
`gh project list --owner ${owner} --format json`,
|
|
1402
1415
|
{ encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
|
|
1403
1416
|
);
|
|
1404
1417
|
const projects = JSON.parse(projectsOutput);
|
|
@@ -1407,11 +1420,35 @@ Create 5-15 issues.${projectName ? ` Add each to project "${projectName}".` : ""
|
|
|
1407
1420
|
if (projectNumber) {
|
|
1408
1421
|
try {
|
|
1409
1422
|
(0, import_node_child_process6.execSync)(
|
|
1410
|
-
`gh project link ${projectNumber} --owner ${
|
|
1423
|
+
`gh project link ${projectNumber} --owner ${owner} --repo ${repoName}`,
|
|
1411
1424
|
{ stdio: ["pipe", "pipe", "pipe"] }
|
|
1412
1425
|
);
|
|
1413
1426
|
} catch {
|
|
1414
1427
|
}
|
|
1428
|
+
try {
|
|
1429
|
+
const repoProjectsOutput = (0, import_node_child_process6.execSync)(
|
|
1430
|
+
`gh repo view --json projectsV2 -q '.projectsV2.Nodes[] | select(.number == ${projectNumber}) | .id'`,
|
|
1431
|
+
{ encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
|
|
1432
|
+
);
|
|
1433
|
+
projectId = repoProjectsOutput.trim() || null;
|
|
1434
|
+
} catch {
|
|
1435
|
+
}
|
|
1436
|
+
if (projectId) {
|
|
1437
|
+
try {
|
|
1438
|
+
const fieldsOutput = (0, import_node_child_process6.execSync)(
|
|
1439
|
+
`gh project field-list ${projectNumber} --owner ${owner} --format json`,
|
|
1440
|
+
{ encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
|
|
1441
|
+
);
|
|
1442
|
+
const fields = JSON.parse(fieldsOutput);
|
|
1443
|
+
const statusField = fields.fields?.find((f) => f.name === "Status");
|
|
1444
|
+
if (statusField) {
|
|
1445
|
+
statusFieldId = statusField.id;
|
|
1446
|
+
const todoOption = statusField.options?.find((o) => o.name === "Todo");
|
|
1447
|
+
todoOptionId = todoOption?.id || null;
|
|
1448
|
+
}
|
|
1449
|
+
} catch {
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1415
1452
|
}
|
|
1416
1453
|
} catch {
|
|
1417
1454
|
}
|
|
@@ -1425,6 +1462,13 @@ Create 5-15 issues.${projectName ? ` Add each to project "${projectName}".` : ""
|
|
|
1425
1462
|
availableLabels = new Set(labelsOutput.trim().split("\n").filter(Boolean));
|
|
1426
1463
|
} catch {
|
|
1427
1464
|
}
|
|
1465
|
+
try {
|
|
1466
|
+
(0, import_node_child_process6.execSync)(
|
|
1467
|
+
`gh label create chiefwiggum --description "Created by Chief Wiggum CLI" --color "FFA500" 2>/dev/null || true`,
|
|
1468
|
+
{ stdio: ["pipe", "pipe", "pipe"] }
|
|
1469
|
+
);
|
|
1470
|
+
} catch {
|
|
1471
|
+
}
|
|
1428
1472
|
let created = 0;
|
|
1429
1473
|
let failed = 0;
|
|
1430
1474
|
const failedIssues = [];
|
|
@@ -1438,7 +1482,8 @@ Create 5-15 issues.${projectName ? ` Add each to project "${projectName}".` : ""
|
|
|
1438
1482
|
process.stdout.write(`\r ${bar} ${progress}% (${i + 1}/${total}) Creating: ${issue.title.slice(0, 40)}...`.padEnd(100));
|
|
1439
1483
|
try {
|
|
1440
1484
|
const validLabels = issue.labels.filter((label) => availableLabels.size === 0 || availableLabels.has(label));
|
|
1441
|
-
const
|
|
1485
|
+
const allLabels = ["chiefwiggum", ...validLabels];
|
|
1486
|
+
const labelsArg = `--label "${allLabels.join(",")}"`;
|
|
1442
1487
|
const escapeForShell = (str) => {
|
|
1443
1488
|
return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/`/g, "\\`").replace(/\$/g, "\\$").replace(/!/g, "\\!").replace(/\n/g, "\\n");
|
|
1444
1489
|
};
|
|
@@ -1451,10 +1496,23 @@ Create 5-15 issues.${projectName ? ` Add each to project "${projectName}".` : ""
|
|
|
1451
1496
|
}).trim();
|
|
1452
1497
|
if (projectNumber && issueUrl) {
|
|
1453
1498
|
try {
|
|
1454
|
-
(0, import_node_child_process6.execSync)(
|
|
1455
|
-
`gh project item-add ${projectNumber} --owner ${
|
|
1456
|
-
{ stdio: ["pipe", "pipe", "pipe"] }
|
|
1499
|
+
const addOutput = (0, import_node_child_process6.execSync)(
|
|
1500
|
+
`gh project item-add ${projectNumber} --owner ${owner} --url "${issueUrl}"`,
|
|
1501
|
+
{ encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
|
|
1457
1502
|
);
|
|
1503
|
+
if (projectId && statusFieldId && todoOptionId) {
|
|
1504
|
+
const itemIdMatch = addOutput.match(/Added item\s+(\S+)/i);
|
|
1505
|
+
const itemId = itemIdMatch?.[1];
|
|
1506
|
+
if (itemId) {
|
|
1507
|
+
try {
|
|
1508
|
+
(0, import_node_child_process6.execSync)(
|
|
1509
|
+
`gh project item-edit --project-id ${projectId} --id ${itemId} --field-id ${statusFieldId} --single-select-option-id ${todoOptionId}`,
|
|
1510
|
+
{ stdio: ["pipe", "pipe", "pipe"] }
|
|
1511
|
+
);
|
|
1512
|
+
} catch {
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1458
1516
|
} catch {
|
|
1459
1517
|
}
|
|
1460
1518
|
}
|
|
@@ -1478,7 +1536,11 @@ Create 5-15 issues.${projectName ? ` Add each to project "${projectName}".` : ""
|
|
|
1478
1536
|
}
|
|
1479
1537
|
}
|
|
1480
1538
|
if (projectName && projectNumber) {
|
|
1481
|
-
|
|
1539
|
+
if (todoOptionId) {
|
|
1540
|
+
console.log(import_picocolors7.default.green(` \u2713 Added to board "${projectName}" (Todo column)`));
|
|
1541
|
+
} else {
|
|
1542
|
+
console.log(import_picocolors7.default.green(` \u2713 Added to board "${projectName}"`));
|
|
1543
|
+
}
|
|
1482
1544
|
}
|
|
1483
1545
|
} else {
|
|
1484
1546
|
console.log(import_picocolors7.default.green(" \u2713 GitHub Issues created"));
|
|
@@ -1711,11 +1773,110 @@ init_loop();
|
|
|
1711
1773
|
// src/commands/clean.ts
|
|
1712
1774
|
init_cjs_shims();
|
|
1713
1775
|
var import_node_fs4 = require("fs");
|
|
1776
|
+
var import_node_child_process7 = require("child_process");
|
|
1714
1777
|
var import_picocolors8 = __toESM(require("picocolors"), 1);
|
|
1715
1778
|
init_prompts();
|
|
1779
|
+
init_new();
|
|
1780
|
+
async function removeIssues(numbers, action) {
|
|
1781
|
+
let success = 0;
|
|
1782
|
+
let failed = 0;
|
|
1783
|
+
for (const num of numbers) {
|
|
1784
|
+
try {
|
|
1785
|
+
if (action === "delete") {
|
|
1786
|
+
(0, import_node_child_process7.execSync)(`gh issue delete ${num} --yes`, { stdio: ["pipe", "pipe", "pipe"] });
|
|
1787
|
+
} else {
|
|
1788
|
+
(0, import_node_child_process7.execSync)(`gh issue close ${num}`, { stdio: ["pipe", "pipe", "pipe"] });
|
|
1789
|
+
}
|
|
1790
|
+
console.log(import_picocolors8.default.green(`\u2713 #${num} ${action === "delete" ? "deleted" : "closed"}`));
|
|
1791
|
+
success++;
|
|
1792
|
+
} catch {
|
|
1793
|
+
console.log(import_picocolors8.default.red(`\u2717 #${num} failed`));
|
|
1794
|
+
failed++;
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
console.log();
|
|
1798
|
+
console.log(`${action === "delete" ? "Deleted" : "Closed"}: ${success}, Failed: ${failed}`);
|
|
1799
|
+
}
|
|
1800
|
+
async function cleanGitHubIssues() {
|
|
1801
|
+
let issues = [];
|
|
1802
|
+
try {
|
|
1803
|
+
const output = (0, import_node_child_process7.execSync)(
|
|
1804
|
+
`gh issue list --label chiefwiggum --state open --json number,title,createdAt --limit 100`,
|
|
1805
|
+
{ encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
|
|
1806
|
+
);
|
|
1807
|
+
issues = JSON.parse(output);
|
|
1808
|
+
} catch {
|
|
1809
|
+
console.log(import_picocolors8.default.yellow("Could not fetch GitHub issues."));
|
|
1810
|
+
return;
|
|
1811
|
+
}
|
|
1812
|
+
if (issues.length === 0) {
|
|
1813
|
+
console.log(import_picocolors8.default.dim("No open issues with 'chiefwiggum' label found."));
|
|
1814
|
+
return;
|
|
1815
|
+
}
|
|
1816
|
+
console.log();
|
|
1817
|
+
console.log(`Found ${issues.length} issues with 'chiefwiggum' label:`);
|
|
1818
|
+
for (const issue of issues) {
|
|
1819
|
+
console.log(` ${import_picocolors8.default.cyan(`#${issue.number}`)} - ${issue.title}`);
|
|
1820
|
+
}
|
|
1821
|
+
console.log();
|
|
1822
|
+
const action = await select2({
|
|
1823
|
+
message: "What would you like to do with these issues?",
|
|
1824
|
+
options: [
|
|
1825
|
+
{ value: "close", label: "Close all", hint: "reversible" },
|
|
1826
|
+
{ value: "delete", label: "Delete all", hint: "permanent" },
|
|
1827
|
+
{ value: "pick", label: "Pick which to remove" },
|
|
1828
|
+
{ value: "cancel", label: "Cancel" }
|
|
1829
|
+
]
|
|
1830
|
+
});
|
|
1831
|
+
if (action === "cancel") {
|
|
1832
|
+
return;
|
|
1833
|
+
}
|
|
1834
|
+
if (action === "pick") {
|
|
1835
|
+
const selected = await multiselect2({
|
|
1836
|
+
message: "Select issues to remove (space to toggle, enter to confirm)",
|
|
1837
|
+
options: issues.map((i) => ({
|
|
1838
|
+
value: String(i.number),
|
|
1839
|
+
label: `#${i.number} - ${i.title}`
|
|
1840
|
+
}))
|
|
1841
|
+
});
|
|
1842
|
+
if (selected.length === 0) {
|
|
1843
|
+
console.log(import_picocolors8.default.yellow("No issues selected."));
|
|
1844
|
+
return;
|
|
1845
|
+
}
|
|
1846
|
+
const pickAction = await select2({
|
|
1847
|
+
message: `${selected.length} issues selected. Close or delete?`,
|
|
1848
|
+
options: [
|
|
1849
|
+
{ value: "close", label: "Close", hint: "reversible" },
|
|
1850
|
+
{ value: "delete", label: "Delete", hint: "permanent" }
|
|
1851
|
+
]
|
|
1852
|
+
});
|
|
1853
|
+
await removeIssues(selected, pickAction);
|
|
1854
|
+
} else {
|
|
1855
|
+
const issueNumbers = issues.map((i) => String(i.number));
|
|
1856
|
+
const confirmMsg = action === "delete" ? `DELETE ${issues.length} issues? This cannot be undone!` : `Close ${issues.length} issues?`;
|
|
1857
|
+
const confirmed = await confirm2({
|
|
1858
|
+
message: confirmMsg,
|
|
1859
|
+
initialValue: false
|
|
1860
|
+
});
|
|
1861
|
+
if (confirmed) {
|
|
1862
|
+
await removeIssues(issueNumbers, action);
|
|
1863
|
+
}
|
|
1864
|
+
}
|
|
1865
|
+
}
|
|
1716
1866
|
async function cmdClean() {
|
|
1717
1867
|
console.log(import_picocolors8.default.bold("Clean Project"));
|
|
1718
1868
|
console.log();
|
|
1869
|
+
const tracker = getProjectTracker();
|
|
1870
|
+
if (tracker === "github") {
|
|
1871
|
+
const cleanIssues = await confirm2({
|
|
1872
|
+
message: "Clean up GitHub Issues created by Chief Wiggum?",
|
|
1873
|
+
initialValue: false
|
|
1874
|
+
});
|
|
1875
|
+
if (cleanIssues) {
|
|
1876
|
+
await cleanGitHubIssues();
|
|
1877
|
+
}
|
|
1878
|
+
console.log();
|
|
1879
|
+
}
|
|
1719
1880
|
const filesToRemove = [];
|
|
1720
1881
|
if ((0, import_node_fs4.existsSync)(".chiefwiggum")) filesToRemove.push(".chiefwiggum/");
|
|
1721
1882
|
if ((0, import_node_fs4.existsSync)("specs")) filesToRemove.push("specs/");
|
|
@@ -1749,7 +1910,7 @@ async function cmdClean() {
|
|
|
1749
1910
|
// src/commands/config.ts
|
|
1750
1911
|
init_cjs_shims();
|
|
1751
1912
|
var import_node_fs5 = require("fs");
|
|
1752
|
-
var
|
|
1913
|
+
var import_node_child_process8 = require("child_process");
|
|
1753
1914
|
var import_picocolors9 = __toESM(require("picocolors"), 1);
|
|
1754
1915
|
init_prompts();
|
|
1755
1916
|
var CONFIG_FILE2 = ".chiefwiggum/CLAUDE.md";
|
|
@@ -1782,17 +1943,17 @@ function saveConfig2(config2) {
|
|
|
1782
1943
|
}
|
|
1783
1944
|
function checkGitHubCLI2() {
|
|
1784
1945
|
try {
|
|
1785
|
-
(0,
|
|
1946
|
+
(0, import_node_child_process8.execSync)("which gh", { stdio: ["pipe", "pipe", "pipe"] });
|
|
1786
1947
|
} catch {
|
|
1787
1948
|
return { ok: false, reason: "not_installed" };
|
|
1788
1949
|
}
|
|
1789
1950
|
try {
|
|
1790
|
-
(0,
|
|
1951
|
+
(0, import_node_child_process8.execSync)("gh auth status", { stdio: ["pipe", "pipe", "pipe"] });
|
|
1791
1952
|
} catch {
|
|
1792
1953
|
return { ok: false, reason: "not_authenticated" };
|
|
1793
1954
|
}
|
|
1794
1955
|
try {
|
|
1795
|
-
const repo = (0,
|
|
1956
|
+
const repo = (0, import_node_child_process8.execSync)("gh repo view --json nameWithOwner -q .nameWithOwner", {
|
|
1796
1957
|
encoding: "utf-8",
|
|
1797
1958
|
stdio: ["pipe", "pipe", "pipe"]
|
|
1798
1959
|
}).trim();
|
|
@@ -1882,7 +2043,7 @@ async function selectOrCreateProjectBoard2(knownRepo) {
|
|
|
1882
2043
|
let repoName = knownRepo || "";
|
|
1883
2044
|
if (!repoName) {
|
|
1884
2045
|
try {
|
|
1885
|
-
repoName = (0,
|
|
2046
|
+
repoName = (0, import_node_child_process8.execSync)("gh repo view --json nameWithOwner -q .nameWithOwner", {
|
|
1886
2047
|
encoding: "utf-8",
|
|
1887
2048
|
stdio: ["pipe", "pipe", "pipe"]
|
|
1888
2049
|
}).trim();
|
|
@@ -1893,7 +2054,7 @@ async function selectOrCreateProjectBoard2(knownRepo) {
|
|
|
1893
2054
|
}
|
|
1894
2055
|
let existingProjects = [];
|
|
1895
2056
|
try {
|
|
1896
|
-
const projectsOutput = (0,
|
|
2057
|
+
const projectsOutput = (0, import_node_child_process8.execSync)(`gh project list --owner ${repoName.split("/")[0]} --format json`, {
|
|
1897
2058
|
encoding: "utf-8",
|
|
1898
2059
|
stdio: ["pipe", "pipe", "pipe"]
|
|
1899
2060
|
});
|
|
@@ -1921,7 +2082,7 @@ async function selectOrCreateProjectBoard2(knownRepo) {
|
|
|
1921
2082
|
});
|
|
1922
2083
|
console.log(import_picocolors9.default.cyan(`Creating board "${projectName}"...`));
|
|
1923
2084
|
try {
|
|
1924
|
-
const createOutput = (0,
|
|
2085
|
+
const createOutput = (0, import_node_child_process8.execSync)(
|
|
1925
2086
|
`gh project create --owner ${repoName.split("/")[0]} --title "${projectName}"`,
|
|
1926
2087
|
{ encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
|
|
1927
2088
|
);
|
|
@@ -1930,7 +2091,7 @@ async function selectOrCreateProjectBoard2(knownRepo) {
|
|
|
1930
2091
|
console.log(import_picocolors9.default.green(`\u2713 Board "${projectName}" created`));
|
|
1931
2092
|
if (projectNumber) {
|
|
1932
2093
|
try {
|
|
1933
|
-
(0,
|
|
2094
|
+
(0, import_node_child_process8.execSync)(`gh project link ${projectNumber} --owner ${repoName.split("/")[0]} --repo ${repoName}`, {
|
|
1934
2095
|
stdio: ["pipe", "pipe", "pipe"]
|
|
1935
2096
|
});
|
|
1936
2097
|
console.log(import_picocolors9.default.green(`\u2713 Linked to ${repoName}`));
|
|
@@ -1945,14 +2106,14 @@ async function selectOrCreateProjectBoard2(knownRepo) {
|
|
|
1945
2106
|
}
|
|
1946
2107
|
} else if (selectedProject !== "__none__") {
|
|
1947
2108
|
try {
|
|
1948
|
-
const projectsOutput = (0,
|
|
2109
|
+
const projectsOutput = (0, import_node_child_process8.execSync)(
|
|
1949
2110
|
`gh project list --owner ${repoName.split("/")[0]} --format json`,
|
|
1950
2111
|
{ encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
|
|
1951
2112
|
);
|
|
1952
2113
|
const projects = JSON.parse(projectsOutput);
|
|
1953
2114
|
const project = projects.projects?.find((p2) => p2.title === selectedProject);
|
|
1954
2115
|
if (project?.number) {
|
|
1955
|
-
(0,
|
|
2116
|
+
(0, import_node_child_process8.execSync)(
|
|
1956
2117
|
`gh project link ${project.number} --owner ${repoName.split("/")[0]} --repo ${repoName}`,
|
|
1957
2118
|
{ stdio: ["pipe", "pipe", "pipe"] }
|
|
1958
2119
|
);
|