@gh-symphony/cli 0.0.17 → 0.0.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 (32) hide show
  1. package/README.md +105 -9
  2. package/dist/{chunk-EFMFGOWM.js → chunk-6CI3UUMH.js} +282 -57
  3. package/dist/chunk-C7G7RJ4G.js +146 -0
  4. package/dist/{chunk-MHIWAIVD.js → chunk-GKENCODJ.js} +141 -53
  5. package/dist/{project-557FE2GD.js → chunk-H2YXSYOZ.js} +108 -92
  6. package/dist/{chunk-TF3QNWNC.js → chunk-M3IFVLQS.js} +246 -212
  7. package/dist/{chunk-IWR4UQEJ.js → chunk-RN2PACNV.js} +350 -523
  8. package/dist/chunk-TILHWBP6.js +638 -0
  9. package/dist/{chunk-6HBZC3BE.js → chunk-XN5ABWZ6.js} +23 -5
  10. package/dist/{chunk-76QPITKI.js → chunk-Y6TYJMNT.js} +1 -1
  11. package/dist/{config-cmd-AZ7POMAA.js → config-cmd-DNXNL26Z.js} +3 -1
  12. package/dist/doctor-IYHCFXOZ.js +1126 -0
  13. package/dist/index.js +157 -19
  14. package/dist/init-KZT6YNOH.js +33 -0
  15. package/dist/{logs-6LNGT2GF.js → logs-6JKKYDGJ.js} +1 -1
  16. package/dist/project-DNALEWO3.js +22 -0
  17. package/dist/{recover-LVBI2TGH.js → recover-C3V2QAUB.js} +3 -3
  18. package/dist/repo-HDDE7OUI.js +321 -0
  19. package/dist/{run-WITYAYFZ.js → run-XI2S5Y4V.js} +3 -3
  20. package/dist/setup-K4CYYJBF.js +431 -0
  21. package/dist/{start-JUFKNL3N.js → start-M6IQGRFO.js} +5 -5
  22. package/dist/{status-3WK5BWRZ.js → status-QSCFVGRQ.js} +2 -2
  23. package/dist/{stop-AA3AP5M6.js → stop-7MFCBQVW.js} +2 -2
  24. package/dist/upgrade-F4VE4XBS.js +165 -0
  25. package/dist/{version-YVM2A25J.js → version-Y5RYNWMF.js} +1 -1
  26. package/dist/worker-entry.js +39 -11
  27. package/dist/workflow-TBIFY5MO.js +497 -0
  28. package/package.json +4 -4
  29. package/dist/chunk-JO3AXHQI.js +0 -130
  30. package/dist/chunk-TH5QPO3Y.js +0 -67
  31. package/dist/init-EZXQAXZM.js +0 -17
  32. package/dist/repo-R3XBIVAX.js +0 -121
@@ -1,38 +1,35 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- GitHubScopeError,
4
3
  abortIfCancelled,
5
- checkRequiredScopes,
6
- createClient,
7
4
  generateProjectId,
8
- getProjectDetail,
9
- listUserProjects,
10
- validateToken,
11
5
  writeConfig
12
- } from "./chunk-IWR4UQEJ.js";
6
+ } from "./chunk-RN2PACNV.js";
13
7
  import {
14
8
  start_default
15
- } from "./chunk-MHIWAIVD.js";
9
+ } from "./chunk-GKENCODJ.js";
16
10
  import {
17
11
  GhAuthError,
18
- ensureGhAuth,
19
- getGhToken
20
- } from "./chunk-JO3AXHQI.js";
21
- import {
22
- stop_default
23
- } from "./chunk-76QPITKI.js";
12
+ GitHubScopeError,
13
+ checkRequiredScopes,
14
+ createClient,
15
+ getGhTokenWithSource,
16
+ getProjectDetail,
17
+ listUserProjects,
18
+ resolveGitHubAuth,
19
+ validateToken
20
+ } from "./chunk-TILHWBP6.js";
24
21
  import {
25
22
  status_default
26
- } from "./chunk-6HBZC3BE.js";
23
+ } from "./chunk-XN5ABWZ6.js";
27
24
  import {
28
25
  stripAnsi
29
26
  } from "./chunk-MVRF7BES.js";
30
- import "./chunk-EFMFGOWM.js";
31
- import "./chunk-TF3QNWNC.js";
32
27
  import {
33
28
  resolveRuntimeRoot
34
29
  } from "./chunk-5NV3LSAJ.js";
35
- import "./chunk-TH5QPO3Y.js";
30
+ import {
31
+ stop_default
32
+ } from "./chunk-Y6TYJMNT.js";
36
33
  import {
37
34
  daemonPidPath,
38
35
  httpStatusPath,
@@ -66,7 +63,7 @@ Then re-run: ${retryCommand}`,
66
63
  );
67
64
  }
68
65
  function parseProjectAddFlags(args) {
69
- const flags = { nonInteractive: false, assignedOnly: false };
66
+ const flags = { nonInteractive: false };
70
67
  for (let i = 0; i < args.length; i += 1) {
71
68
  const arg = args[i];
72
69
  const next = args[i + 1];
@@ -306,12 +303,12 @@ async function projectAdd(args, options) {
306
303
  await projectAddNonInteractive(flags, options);
307
304
  return;
308
305
  }
309
- await projectAddInteractive(options);
306
+ await projectAddInteractive(flags, options);
310
307
  }
311
308
  async function projectAddNonInteractive(flags, options) {
312
309
  let token;
313
310
  try {
314
- token = getGhToken();
311
+ token = getGhTokenWithSource().token;
315
312
  } catch {
316
313
  process.stderr.write(
317
314
  "Error: GitHub token not found. Run 'gh auth login --scopes repo,read:org,project' or set GITHUB_GRAPHQL_TOKEN.\n"
@@ -379,7 +376,7 @@ async function projectAddNonInteractive(flags, options) {
379
376
  `);
380
377
  }
381
378
  }
382
- async function projectAddInteractive(options) {
379
+ async function projectAddInteractive(flags, options) {
383
380
  p.intro("gh-symphony - Project Setup");
384
381
  const defaultWorkspaceDir = join(options.configDir, "workspaces");
385
382
  const existingConfig = await loadGlobalConfig(options.configDir);
@@ -397,32 +394,19 @@ async function projectAddInteractive(options) {
397
394
  }
398
395
  }
399
396
  const s1 = p.spinner();
400
- s1.start("Checking gh CLI authentication...");
397
+ s1.start("Checking GitHub authentication...");
401
398
  let login;
402
399
  let client;
403
400
  try {
404
- const { login: ghLogin, token } = ensureGhAuth();
405
- login = ghLogin;
406
- client = createClient(token);
407
- s1.stop(`Authenticated as ${login}`);
401
+ const auth = await resolveGitHubAuth();
402
+ const sourceLabel = auth.source === "env" ? "GITHUB_GRAPHQL_TOKEN" : "gh CLI";
403
+ login = auth.login;
404
+ client = createClient(auth.token);
405
+ s1.stop(`Authenticated via ${sourceLabel} as ${login}`);
408
406
  } catch (error) {
409
407
  s1.stop("Authentication failed.");
410
408
  if (error instanceof GhAuthError) {
411
- if (error.code === "not_installed") {
412
- p.log.error(
413
- "gh CLI\uAC00 \uC124\uCE58\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. https://cli.github.com \uC5D0\uC11C \uC124\uCE58\uD558\uC138\uC694."
414
- );
415
- } else if (error.code === "not_authenticated") {
416
- p.log.error(
417
- "gh auth login --scopes repo,read:org,project \uB97C \uC2E4\uD589\uD558\uC138\uC694."
418
- );
419
- } else if (error.code === "missing_scopes") {
420
- p.log.error(
421
- "gh auth refresh --scopes repo,read:org,project \uB97C \uC2E4\uD589\uD558\uC138\uC694."
422
- );
423
- } else {
424
- p.log.error(error.message);
425
- }
409
+ p.log.error(error.message);
426
410
  } else {
427
411
  p.log.error(error instanceof Error ? error.message : "Unknown error");
428
412
  }
@@ -484,10 +468,64 @@ async function projectAddInteractive(options) {
484
468
  process.exitCode = 1;
485
469
  return;
486
470
  }
471
+ const {
472
+ assignedOnly: promptAssignedOnly,
473
+ selectedRepos,
474
+ workspaceDir
475
+ } = await promptProjectRegistrationOptions({
476
+ projectDetail,
477
+ defaultWorkspaceDir,
478
+ assignedOnlyMessage: "Step 2/2 - Only process issues assigned to the authenticated GitHub user?",
479
+ assignedOnlyInitialValue: flags.assignedOnly
480
+ });
481
+ const assignedOnly = flags.assignedOnly || promptAssignedOnly;
482
+ const repoSummary = selectedRepos.length === projectDetail.linkedRepositories.length ? `${selectedRepos.map((repo) => `${repo.owner}/${repo.name}`).join(", ")} (all ${selectedRepos.length} linked)` : `${selectedRepos.map((repo) => `${repo.owner}/${repo.name}`).join(", ")} (${selectedRepos.length} of ${projectDetail.linkedRepositories.length} linked)`;
483
+ p.note(
484
+ renderProjectRegistrationSummary({
485
+ login,
486
+ projectTitle: projectDetail.title,
487
+ repoSummary,
488
+ assignedOnly,
489
+ workspaceDir
490
+ }),
491
+ "Configuration Summary"
492
+ );
493
+ const confirmed = await abortIfCancelled(
494
+ p.confirm({ message: "Apply this configuration?" })
495
+ );
496
+ if (!confirmed) {
497
+ p.cancel("Setup cancelled.");
498
+ process.exitCode = 130;
499
+ return;
500
+ }
501
+ const projectId = generateProjectId(projectDetail.title, projectDetail.id);
502
+ const s6 = p.spinner();
503
+ s6.start("Writing configuration...");
504
+ try {
505
+ await writeConfig(options.configDir, {
506
+ projectId,
507
+ project: projectDetail,
508
+ repos: selectedRepos,
509
+ workspaceDir,
510
+ assignedOnly
511
+ });
512
+ s6.stop("Configuration saved.");
513
+ } catch (error) {
514
+ s6.stop("Failed to write configuration.");
515
+ p.log.error(error instanceof Error ? error.message : "Unknown error");
516
+ process.exitCode = 1;
517
+ return;
518
+ }
519
+ p.outro(
520
+ `Project "${projectId}" created.
521
+ Run 'gh-symphony start' to begin orchestration.`
522
+ );
523
+ }
524
+ async function promptProjectRegistrationOptions(input) {
487
525
  const assignedOnly = await abortIfCancelled(
488
526
  p.confirm({
489
- message: "Step 2/2 - Only process issues assigned to the authenticated GitHub user?",
490
- initialValue: false
527
+ message: input.assignedOnlyMessage ?? "Only process issues assigned to the authenticated GitHub user?",
528
+ initialValue: input.assignedOnlyInitialValue ?? false
491
529
  })
492
530
  );
493
531
  const customizeAdvancedOptions = await abortIfCancelled(
@@ -496,8 +534,8 @@ async function projectAddInteractive(options) {
496
534
  initialValue: false
497
535
  })
498
536
  );
499
- let selectedRepos = projectDetail.linkedRepositories;
500
- let workspaceDir = defaultWorkspaceDir;
537
+ let selectedRepos = input.projectDetail.linkedRepositories;
538
+ let workspaceDir = input.defaultWorkspaceDir;
501
539
  if (customizeAdvancedOptions) {
502
540
  const filterRepositories = await abortIfCancelled(
503
541
  p.confirm({
@@ -509,7 +547,7 @@ async function projectAddInteractive(options) {
509
547
  selectedRepos = await abortIfCancelled(
510
548
  p.multiselect({
511
549
  message: "Select repositories to orchestrate:",
512
- options: projectDetail.linkedRepositories.map((repo) => ({
550
+ options: input.projectDetail.linkedRepositories.map((repo) => ({
513
551
  value: repo,
514
552
  label: `${repo.owner}/${repo.name}`
515
553
  })),
@@ -520,55 +558,28 @@ async function projectAddInteractive(options) {
520
558
  workspaceDir = await abortIfCancelled(
521
559
  p.text({
522
560
  message: "Workspace root directory:",
523
- placeholder: defaultWorkspaceDir,
524
- defaultValue: defaultWorkspaceDir,
561
+ placeholder: input.defaultWorkspaceDir,
562
+ defaultValue: input.defaultWorkspaceDir,
525
563
  validate(value) {
526
564
  return value.trim().length > 0 ? void 0 : "Workspace directory is required.";
527
565
  }
528
566
  })
529
567
  );
530
568
  }
531
- const repoSummary = selectedRepos.length === projectDetail.linkedRepositories.length ? `${selectedRepos.map((repo) => `${repo.owner}/${repo.name}`).join(", ")} (all ${selectedRepos.length} linked)` : `${selectedRepos.map((repo) => `${repo.owner}/${repo.name}`).join(", ")} (${selectedRepos.length} of ${projectDetail.linkedRepositories.length} linked)`;
532
- p.note(
533
- [
534
- `User: ${login}`,
535
- `Project: ${projectDetail.title}`,
536
- `Repos: ${repoSummary}`,
537
- `Assigned: ${assignedOnly ? `Only issues assigned to ${login}` : "All project issues"}`,
538
- `Workspace: ${workspaceDir}`
539
- ].join("\n"),
540
- "Configuration Summary"
541
- );
542
- const confirmed = await abortIfCancelled(
543
- p.confirm({ message: "Apply this configuration?" })
544
- );
545
- if (!confirmed) {
546
- p.cancel("Setup cancelled.");
547
- process.exitCode = 130;
548
- return;
549
- }
550
- const projectId = generateProjectId(projectDetail.title, projectDetail.id);
551
- const s6 = p.spinner();
552
- s6.start("Writing configuration...");
553
- try {
554
- await writeConfig(options.configDir, {
555
- projectId,
556
- project: projectDetail,
557
- repos: selectedRepos,
558
- workspaceDir,
559
- assignedOnly
560
- });
561
- s6.stop("Configuration saved.");
562
- } catch (error) {
563
- s6.stop("Failed to write configuration.");
564
- p.log.error(error instanceof Error ? error.message : "Unknown error");
565
- process.exitCode = 1;
566
- return;
567
- }
568
- p.outro(
569
- `Project "${projectId}" created.
570
- Run 'gh-symphony start' to begin orchestration.`
571
- );
569
+ return {
570
+ assignedOnly,
571
+ selectedRepos,
572
+ workspaceDir
573
+ };
574
+ }
575
+ function renderProjectRegistrationSummary(input) {
576
+ return [
577
+ `User: ${input.login}`,
578
+ `Project: ${input.projectTitle}`,
579
+ `Repos: ${input.repoSummary}`,
580
+ `Assigned: ${input.assignedOnly ? `Only issues assigned to ${input.login}` : "All project issues"}`,
581
+ `Workspace: ${input.workspaceDir}`
582
+ ].join("\n");
572
583
  }
573
584
  async function projectList(options) {
574
585
  const global = await loadGlobalConfig(options.configDir);
@@ -648,7 +659,9 @@ async function projectRemove(args, options) {
648
659
  async function projectSwitch(options) {
649
660
  const global = await loadGlobalConfig(options.configDir);
650
661
  if (!global || global.projects.length === 0) {
651
- process.stderr.write("No projects configured. Run 'gh-symphony init'.\n");
662
+ process.stderr.write(
663
+ "No projects configured. Run 'gh-symphony workflow init'.\n"
664
+ );
652
665
  process.exitCode = 1;
653
666
  return;
654
667
  }
@@ -674,6 +687,9 @@ async function projectSwitch(options) {
674
687
  process.stdout.write(`Switched to project: ${selected}
675
688
  `);
676
689
  }
690
+
677
691
  export {
678
- project_default as default
692
+ project_default,
693
+ promptProjectRegistrationOptions,
694
+ renderProjectRegistrationSummary
679
695
  };