chiefwiggum 1.3.17 → 1.3.19

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.
Files changed (2) hide show
  1. package/dist/cli.cjs +279 -55
  2. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -626,17 +626,26 @@ async function cmdLoop() {
626
626
  var __dirname = (0, import_node_path2.dirname)((0, import_node_url.fileURLToPath)(importMetaUrl));
627
627
  var LOCAL_TEMPLATES_DIR = ".chiefwiggum/templates";
628
628
  var CONFIG_FILE = ".chiefwiggum/CLAUDE.md";
629
- function getProjectTracker() {
629
+ function getConfig() {
630
630
  if (!(0, import_node_fs3.existsSync)(CONFIG_FILE)) {
631
- return "todo";
631
+ return { projectTracker: "todo" };
632
632
  }
633
633
  try {
634
- const config2 = JSON.parse((0, import_node_fs3.readFileSync)(CONFIG_FILE, "utf-8"));
635
- return config2.projectTracker || "todo";
634
+ return JSON.parse((0, import_node_fs3.readFileSync)(CONFIG_FILE, "utf-8"));
636
635
  } catch {
637
- return "todo";
636
+ return { projectTracker: "todo" };
638
637
  }
639
638
  }
639
+ function saveConfig(config2) {
640
+ (0, import_node_fs3.mkdirSync)((0, import_node_path2.dirname)(CONFIG_FILE), { recursive: true });
641
+ (0, import_node_fs3.writeFileSync)(CONFIG_FILE, JSON.stringify(config2, null, 2) + "\n");
642
+ }
643
+ function getProjectTracker() {
644
+ return getConfig().projectTracker || "todo";
645
+ }
646
+ function getGithubProject() {
647
+ return getConfig().githubProject;
648
+ }
640
649
  var BUNDLED_TEMPLATES_DIR = (0, import_node_path2.join)(__dirname, "..", "templates");
641
650
  var SKIP_DIRS = /* @__PURE__ */ new Set([
642
651
  "node_modules",
@@ -785,6 +794,27 @@ async function setupTemplates() {
785
794
  console.log(import_picocolors7.default.dim(" You can customize these templates to change how specs are generated."));
786
795
  console.log();
787
796
  }
797
+ function checkGitHubCLI() {
798
+ try {
799
+ (0, import_node_child_process6.execSync)("which gh", { stdio: ["pipe", "pipe", "pipe"] });
800
+ } catch {
801
+ return { ok: false, reason: "not_installed" };
802
+ }
803
+ try {
804
+ (0, import_node_child_process6.execSync)("gh auth status", { stdio: ["pipe", "pipe", "pipe"] });
805
+ } catch {
806
+ return { ok: false, reason: "not_authenticated" };
807
+ }
808
+ try {
809
+ const repo = (0, import_node_child_process6.execSync)("gh repo view --json nameWithOwner -q .nameWithOwner", {
810
+ encoding: "utf-8",
811
+ stdio: ["pipe", "pipe", "pipe"]
812
+ }).trim();
813
+ return { ok: true, repo };
814
+ } catch {
815
+ return { ok: false, reason: "not_github_repo" };
816
+ }
817
+ }
788
818
  async function setupProjectConfig() {
789
819
  if ((0, import_node_fs3.existsSync)(CONFIG_FILE)) {
790
820
  return;
@@ -797,13 +827,113 @@ async function setupProjectConfig() {
797
827
  const config2 = {
798
828
  projectTracker: useGitHub ? "github" : "todo"
799
829
  };
800
- (0, import_node_fs3.writeFileSync)(CONFIG_FILE, JSON.stringify(config2, null, 2) + "\n");
801
- console.log(import_picocolors7.default.green(`\u2713 Config saved to ${CONFIG_FILE}`));
802
830
  if (useGitHub) {
831
+ const ghCheck = checkGitHubCLI();
832
+ if (!ghCheck.ok) {
833
+ console.log();
834
+ if (ghCheck.reason === "not_installed") {
835
+ console.log(import_picocolors7.default.yellow("GitHub CLI (gh) is not installed."));
836
+ console.log();
837
+ console.log("To use GitHub Issues, install it first:");
838
+ console.log(import_picocolors7.default.cyan(" brew install gh # macOS"));
839
+ console.log(import_picocolors7.default.cyan(" sudo apt install gh # Ubuntu/Debian"));
840
+ console.log(import_picocolors7.default.dim(" https://cli.github.com for other platforms"));
841
+ } else if (ghCheck.reason === "not_authenticated") {
842
+ console.log(import_picocolors7.default.yellow("GitHub CLI is not authenticated."));
843
+ console.log();
844
+ console.log("Run this command to log in:");
845
+ console.log(import_picocolors7.default.cyan(" gh auth login"));
846
+ } else if (ghCheck.reason === "not_github_repo") {
847
+ console.log(import_picocolors7.default.yellow("This doesn't appear to be a GitHub repository."));
848
+ console.log();
849
+ console.log("Make sure you're in a git repo with a GitHub remote.");
850
+ }
851
+ console.log();
852
+ const fallback = await select2({
853
+ message: "What would you like to do?",
854
+ options: [
855
+ { value: "todo", label: "Use TODO.md instead", hint: "Track tasks locally" },
856
+ { value: "exit", label: "Exit and set up gh first", hint: "Then run chiefwiggum new again" }
857
+ ]
858
+ });
859
+ if (fallback === "exit") {
860
+ console.log();
861
+ console.log(import_picocolors7.default.dim("Run 'chiefwiggum new' again after setting up gh."));
862
+ process.exit(0);
863
+ }
864
+ config2.projectTracker = "todo";
865
+ } else {
866
+ const projectName = await selectOrCreateProjectBoard(ghCheck.repo);
867
+ config2.githubProject = projectName;
868
+ }
869
+ }
870
+ saveConfig(config2);
871
+ console.log(import_picocolors7.default.green(`\u2713 Config saved to ${CONFIG_FILE}`));
872
+ if (config2.projectTracker === "github") {
803
873
  console.log(import_picocolors7.default.dim(" Tasks will be created as GitHub Issues."));
874
+ if (config2.githubProject) {
875
+ console.log(import_picocolors7.default.dim(` Issues will be added to board: ${config2.githubProject}`));
876
+ }
804
877
  }
805
878
  console.log();
806
879
  }
880
+ async function selectOrCreateProjectBoard(knownRepo) {
881
+ let repoName = knownRepo || "";
882
+ if (!repoName) {
883
+ try {
884
+ repoName = (0, import_node_child_process6.execSync)("gh repo view --json nameWithOwner -q .nameWithOwner", {
885
+ encoding: "utf-8",
886
+ stdio: ["pipe", "pipe", "pipe"]
887
+ }).trim();
888
+ } catch {
889
+ console.log(import_picocolors7.default.yellow("Could not detect GitHub repo. Skipping project board setup."));
890
+ return null;
891
+ }
892
+ }
893
+ let existingProjects = [];
894
+ try {
895
+ const projectsOutput = (0, import_node_child_process6.execSync)(`gh project list --owner ${repoName.split("/")[0]} --format json`, {
896
+ encoding: "utf-8",
897
+ stdio: ["pipe", "pipe", "pipe"]
898
+ });
899
+ const projects = JSON.parse(projectsOutput);
900
+ existingProjects = projects.projects?.map((p2) => p2.title) || [];
901
+ } catch {
902
+ }
903
+ console.log();
904
+ console.log(import_picocolors7.default.bold(`GitHub Project Board`));
905
+ console.log(import_picocolors7.default.dim(`Organize issues in a Kanban-style board for ${repoName}`));
906
+ console.log();
907
+ const projectOptions = [
908
+ ...existingProjects.map((name) => ({ value: name, label: name })),
909
+ { value: "__new__", label: "Create new board..." },
910
+ { value: "__none__", label: "Skip (just create issues without a board)" }
911
+ ];
912
+ const selectedProject = await select2({
913
+ message: "Add issues to a project board?",
914
+ options: projectOptions
915
+ });
916
+ if (selectedProject === "__new__") {
917
+ const projectName = await text2({
918
+ message: "Board name",
919
+ placeholder: "e.g., SVG Icon Generator v2"
920
+ });
921
+ console.log(import_picocolors7.default.cyan(`Creating board "${projectName}"...`));
922
+ try {
923
+ (0, import_node_child_process6.execSync)(`gh project create --owner ${repoName.split("/")[0]} --title "${projectName}"`, {
924
+ stdio: "inherit"
925
+ });
926
+ console.log(import_picocolors7.default.green(`\u2713 Board "${projectName}" created`));
927
+ return projectName;
928
+ } catch {
929
+ console.log(import_picocolors7.default.yellow("Could not create board. Issues will be created without one."));
930
+ return null;
931
+ }
932
+ } else if (selectedProject !== "__none__") {
933
+ return selectedProject;
934
+ }
935
+ return null;
936
+ }
807
937
  async function interactiveDescribe() {
808
938
  console.log();
809
939
  console.log(import_picocolors7.default.bold("Tell me about your project"));
@@ -960,49 +1090,11 @@ Write directly to CLAUDE.md.`;
960
1090
  console.log(import_picocolors7.default.red("Could not detect GitHub repo. Make sure you're in a git repo with a GitHub remote."));
961
1091
  process.exit(1);
962
1092
  }
963
- let existingProjects = [];
964
- try {
965
- const projectsOutput = (0, import_node_child_process6.execSync)(`gh project list --owner ${repoName.split("/")[0]} --format json`, {
966
- encoding: "utf-8",
967
- stdio: ["pipe", "pipe", "pipe"]
968
- });
969
- const projects = JSON.parse(projectsOutput);
970
- existingProjects = projects.projects?.map((p2) => p2.title) || [];
971
- } catch {
972
- }
973
- console.log(import_picocolors7.default.bold(`GitHub Project Board`));
974
- console.log(import_picocolors7.default.dim(`Organize issues in a Kanban-style board for ${repoName}`));
975
- console.log();
976
- const projectOptions = [
977
- ...existingProjects.map((name) => ({ value: name, label: name })),
978
- { value: "__new__", label: "Create new board..." },
979
- { value: "__none__", label: "Skip (just create issues without a board)" }
980
- ];
981
- const selectedProject = await select2({
982
- message: "Add issues to a project board?",
983
- options: projectOptions
984
- });
985
- let projectName = null;
986
- if (selectedProject === "__new__") {
987
- projectName = await text2({
988
- message: "Board name",
989
- placeholder: "e.g., SVG Icon Generator v2"
990
- });
991
- console.log(import_picocolors7.default.cyan(`Creating board "${projectName}"...`));
992
- try {
993
- (0, import_node_child_process6.execSync)(`gh project create --owner ${repoName.split("/")[0]} --title "${projectName}"`, {
994
- stdio: "inherit"
995
- });
996
- console.log(import_picocolors7.default.green(`\u2713 Board "${projectName}" created`));
997
- } catch {
998
- console.log(import_picocolors7.default.yellow("Could not create board. Issues will be created without one."));
999
- projectName = null;
1000
- }
1001
- } else if (selectedProject !== "__none__") {
1002
- projectName = selectedProject;
1003
- }
1004
- console.log();
1093
+ const projectName = getGithubProject();
1005
1094
  console.log(import_picocolors7.default.yellow("[4/4] Creating GitHub Issues..."));
1095
+ if (projectName) {
1096
+ console.log(import_picocolors7.default.dim(` Issues will be added to board: ${projectName}`));
1097
+ }
1006
1098
  const projectInstruction = projectName ? `After creating each issue, add it to the project "${projectName}" using:
1007
1099
  gh project item-add <PROJECT_NUMBER> --owner ${repoName.split("/")[0]} --url <ISSUE_URL>` : "";
1008
1100
  const issuesPrompt = `You are creating GitHub Issues based on specs.
@@ -1126,9 +1218,10 @@ async function cmdClean() {
1126
1218
 
1127
1219
  // src/commands/config.ts
1128
1220
  var import_node_fs5 = require("fs");
1221
+ var import_node_child_process7 = require("child_process");
1129
1222
  var import_picocolors9 = __toESM(require("picocolors"), 1);
1130
1223
  var CONFIG_FILE2 = ".chiefwiggum/CLAUDE.md";
1131
- function getConfig() {
1224
+ function getConfig2() {
1132
1225
  if (!(0, import_node_fs5.existsSync)(CONFIG_FILE2)) {
1133
1226
  return { projectTracker: "todo" };
1134
1227
  }
@@ -1138,15 +1231,39 @@ function getConfig() {
1138
1231
  return { projectTracker: "todo" };
1139
1232
  }
1140
1233
  }
1141
- function saveConfig(config2) {
1234
+ function saveConfig2(config2) {
1142
1235
  (0, import_node_fs5.mkdirSync)(".chiefwiggum", { recursive: true });
1143
1236
  (0, import_node_fs5.writeFileSync)(CONFIG_FILE2, JSON.stringify(config2, null, 2) + "\n");
1144
1237
  }
1238
+ function checkGitHubCLI2() {
1239
+ try {
1240
+ (0, import_node_child_process7.execSync)("which gh", { stdio: ["pipe", "pipe", "pipe"] });
1241
+ } catch {
1242
+ return { ok: false, reason: "not_installed" };
1243
+ }
1244
+ try {
1245
+ (0, import_node_child_process7.execSync)("gh auth status", { stdio: ["pipe", "pipe", "pipe"] });
1246
+ } catch {
1247
+ return { ok: false, reason: "not_authenticated" };
1248
+ }
1249
+ try {
1250
+ const repo = (0, import_node_child_process7.execSync)("gh repo view --json nameWithOwner -q .nameWithOwner", {
1251
+ encoding: "utf-8",
1252
+ stdio: ["pipe", "pipe", "pipe"]
1253
+ }).trim();
1254
+ return { ok: true, repo };
1255
+ } catch {
1256
+ return { ok: false, reason: "not_github_repo" };
1257
+ }
1258
+ }
1145
1259
  async function cmdConfig() {
1146
1260
  console.log(import_picocolors9.default.bold("Configuration"));
1147
1261
  console.log();
1148
- const config2 = getConfig();
1262
+ const config2 = getConfig2();
1149
1263
  console.log(`Current tracker: ${import_picocolors9.default.cyan(config2.projectTracker)}`);
1264
+ if (config2.projectTracker === "github") {
1265
+ console.log(`GitHub Project Board: ${import_picocolors9.default.cyan(config2.githubProject || "(none)")}`);
1266
+ }
1150
1267
  console.log();
1151
1268
  const newTracker = await select2({
1152
1269
  message: "Project tracker",
@@ -1156,16 +1273,123 @@ async function cmdConfig() {
1156
1273
  ],
1157
1274
  initialValue: config2.projectTracker
1158
1275
  });
1159
- if (newTracker !== config2.projectTracker) {
1276
+ let changed = false;
1277
+ if (newTracker === "github" && config2.projectTracker !== "github") {
1278
+ const ghCheck = checkGitHubCLI2();
1279
+ if (!ghCheck.ok) {
1280
+ console.log();
1281
+ if (ghCheck.reason === "not_installed") {
1282
+ console.log(import_picocolors9.default.yellow("GitHub CLI (gh) is not installed."));
1283
+ console.log();
1284
+ console.log("To use GitHub Issues, install it first:");
1285
+ console.log(import_picocolors9.default.cyan(" brew install gh # macOS"));
1286
+ console.log(import_picocolors9.default.cyan(" sudo apt install gh # Ubuntu/Debian"));
1287
+ console.log(import_picocolors9.default.dim(" https://cli.github.com for other platforms"));
1288
+ } else if (ghCheck.reason === "not_authenticated") {
1289
+ console.log(import_picocolors9.default.yellow("GitHub CLI is not authenticated."));
1290
+ console.log();
1291
+ console.log("Run this command to log in:");
1292
+ console.log(import_picocolors9.default.cyan(" gh auth login"));
1293
+ } else if (ghCheck.reason === "not_github_repo") {
1294
+ console.log(import_picocolors9.default.yellow("This doesn't appear to be a GitHub repository."));
1295
+ console.log();
1296
+ console.log("Make sure you're in a git repo with a GitHub remote.");
1297
+ }
1298
+ console.log();
1299
+ console.log(import_picocolors9.default.dim("Cannot switch to GitHub Issues. Keeping current tracker."));
1300
+ return;
1301
+ }
1302
+ config2.projectTracker = "github";
1303
+ changed = true;
1304
+ const projectName = await selectOrCreateProjectBoard2(ghCheck.repo);
1305
+ config2.githubProject = projectName;
1306
+ } else if (newTracker !== config2.projectTracker) {
1160
1307
  config2.projectTracker = newTracker;
1161
- saveConfig(config2);
1308
+ changed = true;
1309
+ }
1310
+ if (newTracker === "github" && config2.projectTracker === "github" && !changed) {
1311
+ const changeBoard = await confirm2({
1312
+ message: config2.githubProject ? `Change project board? (current: ${config2.githubProject})` : "Set up a project board?",
1313
+ initialValue: !config2.githubProject
1314
+ });
1315
+ if (changeBoard) {
1316
+ const projectName = await selectOrCreateProjectBoard2();
1317
+ if (projectName !== config2.githubProject) {
1318
+ config2.githubProject = projectName;
1319
+ changed = true;
1320
+ }
1321
+ }
1322
+ }
1323
+ if (changed) {
1324
+ saveConfig2(config2);
1162
1325
  console.log();
1163
- console.log(import_picocolors9.default.green(`\u2713 Tracker changed to ${newTracker}`));
1326
+ console.log(import_picocolors9.default.green(`\u2713 Config updated`));
1327
+ console.log(import_picocolors9.default.dim(` Tracker: ${config2.projectTracker}`));
1328
+ if (config2.projectTracker === "github" && config2.githubProject) {
1329
+ console.log(import_picocolors9.default.dim(` Project board: ${config2.githubProject}`));
1330
+ }
1164
1331
  } else {
1165
1332
  console.log();
1166
1333
  console.log(import_picocolors9.default.dim("No changes made."));
1167
1334
  }
1168
1335
  }
1336
+ async function selectOrCreateProjectBoard2(knownRepo) {
1337
+ let repoName = knownRepo || "";
1338
+ if (!repoName) {
1339
+ try {
1340
+ repoName = (0, import_node_child_process7.execSync)("gh repo view --json nameWithOwner -q .nameWithOwner", {
1341
+ encoding: "utf-8",
1342
+ stdio: ["pipe", "pipe", "pipe"]
1343
+ }).trim();
1344
+ } catch {
1345
+ console.log(import_picocolors9.default.yellow("Could not detect GitHub repo. Skipping project board setup."));
1346
+ return null;
1347
+ }
1348
+ }
1349
+ let existingProjects = [];
1350
+ try {
1351
+ const projectsOutput = (0, import_node_child_process7.execSync)(`gh project list --owner ${repoName.split("/")[0]} --format json`, {
1352
+ encoding: "utf-8",
1353
+ stdio: ["pipe", "pipe", "pipe"]
1354
+ });
1355
+ const projects = JSON.parse(projectsOutput);
1356
+ existingProjects = projects.projects?.map((p2) => p2.title) || [];
1357
+ } catch {
1358
+ }
1359
+ console.log();
1360
+ console.log(import_picocolors9.default.bold(`GitHub Project Board`));
1361
+ console.log(import_picocolors9.default.dim(`Organize issues in a Kanban-style board for ${repoName}`));
1362
+ console.log();
1363
+ const projectOptions = [
1364
+ ...existingProjects.map((name) => ({ value: name, label: name })),
1365
+ { value: "__new__", label: "Create new board..." },
1366
+ { value: "__none__", label: "No board (just create issues)" }
1367
+ ];
1368
+ const selectedProject = await select2({
1369
+ message: "Select a project board",
1370
+ options: projectOptions
1371
+ });
1372
+ if (selectedProject === "__new__") {
1373
+ const projectName = await text2({
1374
+ message: "Board name",
1375
+ placeholder: "e.g., SVG Icon Generator v2"
1376
+ });
1377
+ console.log(import_picocolors9.default.cyan(`Creating board "${projectName}"...`));
1378
+ try {
1379
+ (0, import_node_child_process7.execSync)(`gh project create --owner ${repoName.split("/")[0]} --title "${projectName}"`, {
1380
+ stdio: "inherit"
1381
+ });
1382
+ console.log(import_picocolors9.default.green(`\u2713 Board "${projectName}" created`));
1383
+ return projectName;
1384
+ } catch {
1385
+ console.log(import_picocolors9.default.yellow("Could not create board."));
1386
+ return null;
1387
+ }
1388
+ } else if (selectedProject !== "__none__") {
1389
+ return selectedProject;
1390
+ }
1391
+ return null;
1392
+ }
1169
1393
 
1170
1394
  // src/cli.ts
1171
1395
  var __dirname2 = (0, import_node_path3.dirname)((0, import_node_url2.fileURLToPath)(importMetaUrl));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chiefwiggum",
3
- "version": "1.3.17",
3
+ "version": "1.3.19",
4
4
  "description": "Autonomous coding agent CLI. Point it at a plan, watch it build.",
5
5
  "type": "module",
6
6
  "bin": {