@gh-symphony/cli 0.4.5 → 0.4.7

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
@@ -8,6 +8,9 @@ The following tools must be installed before using the CLI:
8
8
 
9
9
  - **[Node.js](https://nodejs.org/)** (v24+) with npm
10
10
  - **[Git](https://git-scm.com/)**
11
+ - At least one AI agent runtime on `PATH` before `gh-symphony repo start`:
12
+ - **[Codex CLI](https://developers.openai.com/codex/cli/)** (`codex`) - install from the official Codex CLI guide, then authenticate with `codex login`.
13
+ - **[Claude Code](https://code.claude.com/docs/en/quickstart)** (`claude`) - install from the official Claude Code quickstart, then authenticate with `ANTHROPIC_API_KEY` or a local Claude login for non-bare runs.
11
14
  - One GitHub auth source with required scopes (`repo`, `read:org`, `project`):
12
15
  - **[GitHub CLI (`gh`)](https://cli.github.com/)**:
13
16
  ```bash
@@ -106,7 +109,7 @@ Examples of generated validation guidance include `make test`, `just build`, `uv
106
109
 
107
110
  You can further customize the agent's behavior by editing `WORKFLOW.md` — this is the policy layer that controls what the agent does at each workflow phase.
108
111
 
109
- > Currently supported runtimes: **Codex**, **Claude Code**
112
+ > Currently supported runtimes: **[Codex CLI](https://developers.openai.com/codex/cli/)** and **[Claude Code](https://code.claude.com/docs/en/quickstart)**. The selected runtime command must be installed and authenticated before `gh-symphony repo start` can dispatch worker runs.
110
113
 
111
114
  ### Explicit Priority Mapping
112
115
 
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  workflow_init_default
4
- } from "./chunk-4ZHWEQQL.js";
4
+ } from "./chunk-775A5LB5.js";
5
5
  import {
6
6
  fetchGithubProjectIssueByRepositoryAndNumber,
7
7
  inspectManagedProjectSelection,
8
8
  resolveTrackerAdapter
9
- } from "./chunk-HHBXGE23.js";
9
+ } from "./chunk-C4QCVQVY.js";
10
10
  import {
11
11
  GitHubApiError,
12
12
  createClient,
@@ -14,12 +14,12 @@ import {
14
14
  getGhTokenWithSource,
15
15
  getProjectDetail,
16
16
  validateGitHubToken
17
- } from "./chunk-SMNIGNS3.js";
17
+ } from "./chunk-FFY5VKNV.js";
18
18
  import {
19
19
  buildPromptVariables,
20
20
  parseWorkflowMarkdown,
21
21
  renderPrompt
22
- } from "./chunk-LJUEOVAQ.js";
22
+ } from "./chunk-RGCSM2KZ.js";
23
23
  import {
24
24
  loadActiveProjectConfig
25
25
  } from "./chunk-YZP5N5XP.js";
@@ -11,12 +11,12 @@ import {
11
11
  listUserProjects,
12
12
  resolveGitHubAuth,
13
13
  validateToken
14
- } from "./chunk-SMNIGNS3.js";
14
+ } from "./chunk-FFY5VKNV.js";
15
15
  import {
16
16
  formatClaudePreflightText,
17
17
  resolveClaudeCommandBinary,
18
18
  runClaudePreflight
19
- } from "./chunk-LJUEOVAQ.js";
19
+ } from "./chunk-RGCSM2KZ.js";
20
20
 
21
21
  // src/mapping/smart-defaults.ts
22
22
  var ROLE_PATTERNS = [
@@ -30,7 +30,7 @@ import {
30
30
  resolveWorkflowRuntimeTimeouts,
31
31
  safeReadDir,
32
32
  scheduleRetryAt
33
- } from "./chunk-LJUEOVAQ.js";
33
+ } from "./chunk-RGCSM2KZ.js";
34
34
  import {
35
35
  loadGlobalConfig,
36
36
  loadProjectConfig
@@ -1470,8 +1470,10 @@ var githubProjectTrackerAdapter = {
1470
1470
  return fetchProjectIssueStatesByIds(project, issueIds, dependencies);
1471
1471
  },
1472
1472
  buildWorkerEnvironment(project) {
1473
+ const apiUrl = project.tracker.apiUrl?.trim();
1473
1474
  return {
1474
- GITHUB_PROJECT_ID: requireTrackerSetting(project.tracker, "projectId")
1475
+ GITHUB_PROJECT_ID: requireTrackerSetting(project.tracker, "projectId"),
1476
+ ...apiUrl ? { GITHUB_GRAPHQL_API_URL: apiUrl } : {}
1475
1477
  };
1476
1478
  },
1477
1479
  reviveIssue(project, run) {
@@ -1564,10 +1566,7 @@ function resolveAssignedOnly(tracker, dependencies) {
1564
1566
  if (dependencies.assignedOnly !== void 0) {
1565
1567
  return dependencies.assignedOnly;
1566
1568
  }
1567
- const legacyAssignedOnly = readBooleanTrackerSetting(
1568
- tracker,
1569
- "assignedOnly"
1570
- );
1569
+ const legacyAssignedOnly = readBooleanTrackerSetting(tracker, "assignedOnly");
1571
1570
  if (legacyAssignedOnly) {
1572
1571
  const warningKey = `${tracker.adapter}:${tracker.bindingId}`;
1573
1572
  if (!warnedLegacyAssignedOnlyProjectIds.has(warningKey)) {
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-3IRPSPAF.js";
5
5
  import {
6
6
  parseWorkflowMarkdown
7
- } from "./chunk-LJUEOVAQ.js";
7
+ } from "./chunk-RGCSM2KZ.js";
8
8
  import {
9
9
  saveGlobalConfig,
10
10
  saveProjectConfig
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/github/client.ts
4
- var DEFAULT_API_URL = "https://api.github.com/graphql";
4
+ var DEFAULT_GITHUB_GRAPHQL_API_URL = "https://api.github.com/graphql";
5
5
  var REST_API_URL = "https://api.github.com";
6
6
  function findLinkedRepository(project, owner, name) {
7
7
  const normalizedOwner = owner.trim().toLowerCase();
@@ -28,13 +28,35 @@ var GitHubScopeError = class extends GitHubApiError {
28
28
  function createClient(token, options) {
29
29
  return {
30
30
  token,
31
- apiUrl: options?.apiUrl ?? DEFAULT_API_URL,
31
+ apiUrl: options?.apiUrl ?? DEFAULT_GITHUB_GRAPHQL_API_URL,
32
32
  fetchImpl: options?.fetchImpl ?? fetch
33
33
  };
34
34
  }
35
+ function deriveGitHubRestApiUrl(graphqlApiUrl) {
36
+ try {
37
+ const url = new URL(graphqlApiUrl);
38
+ const normalizedPath = url.pathname.replace(/\/+$/, "");
39
+ if (url.hostname.toLowerCase() === "api.github.com") {
40
+ return REST_API_URL;
41
+ }
42
+ if (normalizedPath === "/api/graphql") {
43
+ url.pathname = "/api/v3";
44
+ url.search = "";
45
+ url.hash = "";
46
+ return url.toString().replace(/\/$/, "");
47
+ }
48
+ if (normalizedPath.endsWith("/graphql")) {
49
+ url.pathname = normalizedPath.slice(0, -"/graphql".length) || "/";
50
+ url.search = "";
51
+ url.hash = "";
52
+ return url.toString().replace(/\/$/, "");
53
+ }
54
+ } catch {
55
+ }
56
+ return REST_API_URL;
57
+ }
35
58
  async function listRepositoryLabels(client, owner, name) {
36
- const restUrl = client.apiUrl.replace("/graphql", "");
37
- const baseUrl = restUrl === client.apiUrl ? REST_API_URL : restUrl;
59
+ const baseUrl = deriveGitHubRestApiUrl(client.apiUrl);
38
60
  const labels = [];
39
61
  let page = 1;
40
62
  while (true) {
@@ -75,8 +97,7 @@ async function listRepositoryLabels(client, owner, name) {
75
97
  return labels;
76
98
  }
77
99
  async function validateToken(client) {
78
- const restUrl = client.apiUrl.replace("/graphql", "");
79
- const baseUrl = restUrl === client.apiUrl ? REST_API_URL : restUrl;
100
+ const baseUrl = deriveGitHubRestApiUrl(client.apiUrl);
80
101
  const response = await client.fetchImpl(`${baseUrl}/user`, {
81
102
  headers: {
82
103
  authorization: `Bearer ${client.token}`,
@@ -646,12 +667,20 @@ function checkGhInstalled(opts) {
646
667
  throw error;
647
668
  }
648
669
  }
670
+ function ghAuthHostArgs(hostname) {
671
+ const trimmed = hostname?.trim();
672
+ return trimmed ? ["--hostname", trimmed] : [];
673
+ }
649
674
  function checkGhAuthenticated(opts) {
650
675
  const spawnImpl = opts?.spawnImpl ?? spawnSync;
651
- const result = spawnImpl("gh", ["auth", "status"], {
652
- encoding: "utf8",
653
- stdio: ["pipe", "pipe", "pipe"]
654
- });
676
+ const result = spawnImpl(
677
+ "gh",
678
+ ["auth", "status", ...ghAuthHostArgs(opts?.hostname)],
679
+ {
680
+ encoding: "utf8",
681
+ stdio: ["pipe", "pipe", "pipe"]
682
+ }
683
+ );
655
684
  if ((result.status ?? 1) !== 0) {
656
685
  return { authenticated: false };
657
686
  }
@@ -660,10 +689,14 @@ function checkGhAuthenticated(opts) {
660
689
  }
661
690
  function checkGhScopes(opts) {
662
691
  const spawnImpl = opts?.spawnImpl ?? spawnSync;
663
- const result = spawnImpl("gh", ["auth", "status"], {
664
- encoding: "utf8",
665
- stdio: ["pipe", "pipe", "pipe"]
666
- });
692
+ const result = spawnImpl(
693
+ "gh",
694
+ ["auth", "status", ...ghAuthHostArgs(opts?.hostname)],
695
+ {
696
+ encoding: "utf8",
697
+ stdio: ["pipe", "pipe", "pipe"]
698
+ }
699
+ );
667
700
  const output = (result.stdout ?? "").toString();
668
701
  const scopes = parseScopes(output);
669
702
  if (scopes.length === 0) {
@@ -686,7 +719,8 @@ function getGhToken(opts) {
686
719
  }
687
720
  return getGhTokenWithSource({
688
721
  execImpl: opts?.execImpl,
689
- envToken: void 0
722
+ envToken: void 0,
723
+ hostname: opts?.hostname
690
724
  }).token;
691
725
  }
692
726
  function getGhTokenWithSource(opts) {
@@ -697,10 +731,14 @@ function getGhTokenWithSource(opts) {
697
731
  }
698
732
  const execImpl = opts?.execImpl ?? execFileSync;
699
733
  try {
700
- const token = execImpl("gh", ["auth", "token"], {
701
- encoding: "utf8",
702
- stdio: ["pipe", "pipe", "pipe"]
703
- }).toString().trim();
734
+ const token = execImpl(
735
+ "gh",
736
+ ["auth", "token", ...ghAuthHostArgs(opts?.hostname)],
737
+ {
738
+ encoding: "utf8",
739
+ stdio: ["pipe", "pipe", "pipe"]
740
+ }
741
+ ).toString().trim();
704
742
  if (!token) {
705
743
  throw new GhAuthError("token_failed", ghTokenReadErrorMessage());
706
744
  }
@@ -718,7 +756,9 @@ async function validateGitHubToken(token, source, opts) {
718
756
  const checkRequiredScopesImpl = opts?.checkRequiredScopesImpl ?? checkRequiredScopes;
719
757
  let viewer;
720
758
  try {
721
- const client = createClientImpl(token);
759
+ const client = createClientImpl(token, {
760
+ apiUrl: opts?.apiUrl
761
+ });
722
762
  viewer = await validateTokenImpl(client);
723
763
  } catch (error) {
724
764
  throw classifyTokenValidationError(error, source);
@@ -787,7 +827,7 @@ function ensureGhAuth(opts) {
787
827
  { source: "gh" }
788
828
  );
789
829
  }
790
- const auth = checkGhAuthenticated({ spawnImpl });
830
+ const auth = checkGhAuthenticated({ spawnImpl, hostname: opts?.hostname });
791
831
  if (!auth.authenticated) {
792
832
  throw new GhAuthError(
793
833
  "not_authenticated",
@@ -795,7 +835,7 @@ function ensureGhAuth(opts) {
795
835
  { source: "gh" }
796
836
  );
797
837
  }
798
- const scopeCheck = checkGhScopes({ spawnImpl });
838
+ const scopeCheck = checkGhScopes({ spawnImpl, hostname: opts?.hostname });
799
839
  if (!scopeCheck.valid) {
800
840
  throw new GhAuthError(
801
841
  "missing_scopes",
@@ -809,7 +849,8 @@ function ensureGhAuth(opts) {
809
849
  }
810
850
  const { token } = getGhTokenWithSource({
811
851
  execImpl,
812
- envToken: void 0
852
+ envToken: void 0,
853
+ hostname: opts?.hostname
813
854
  });
814
855
  return { login: auth.login ?? "unknown", token, source: "gh" };
815
856
  }
@@ -858,7 +899,7 @@ function runGhAuthRefresh(opts) {
858
899
  }
859
900
  function parseLogin(output) {
860
901
  const matched = output.match(
861
- /Logged in to github\.com account\s+\*?\*?([A-Za-z0-9_-]+)\*?\*?/i
902
+ /Logged in to \S+ account\s+\*?\*?([A-Za-z0-9_-]+)\*?\*?/i
862
903
  );
863
904
  return matched?.[1];
864
905
  }
@@ -871,6 +912,7 @@ function parseScopes(output) {
871
912
  }
872
913
 
873
914
  export {
915
+ DEFAULT_GITHUB_GRAPHQL_API_URL,
874
916
  findLinkedRepository,
875
917
  GitHubApiError,
876
918
  GitHubScopeError,
@@ -6619,6 +6619,7 @@ export {
6619
6619
  readJsonFile,
6620
6620
  safeReadDir,
6621
6621
  isFileMissing,
6622
+ formatEventMessage,
6622
6623
  parseRecentEvents,
6623
6624
  redactObservabilitySecrets,
6624
6625
  redactObservabilityDiagnosticsWithStats,
@@ -10,7 +10,7 @@ import {
10
10
  resolveGitHubGraphQLToken,
11
11
  shouldReuseAgentCredentialCache,
12
12
  writeAgentCredentialCache
13
- } from "./chunk-LJUEOVAQ.js";
13
+ } from "./chunk-RGCSM2KZ.js";
14
14
 
15
15
  // ../runtime-codex/src/runtime.ts
16
16
  import { spawn } from "child_process";
@@ -5,18 +5,19 @@ import {
5
5
  parseIssueReference,
6
6
  readGitHubProjectBinding,
7
7
  renderIssueWorkflowPreview
8
- } from "./chunk-I3CZXKS5.js";
9
- import "./chunk-4ZHWEQQL.js";
8
+ } from "./chunk-3ACU7O47.js";
9
+ import "./chunk-775A5LB5.js";
10
10
  import {
11
11
  fetchGithubProjectIssueByRepositoryAndNumber,
12
12
  fetchGithubProjectIssues,
13
13
  inspectManagedProjectSelection
14
- } from "./chunk-HHBXGE23.js";
15
- import "./chunk-7KFCWMMW.js";
14
+ } from "./chunk-C4QCVQVY.js";
15
+ import "./chunk-XLDJTMW5.js";
16
16
  import {
17
17
  resolveRuntimeRoot
18
18
  } from "./chunk-3IRPSPAF.js";
19
19
  import {
20
+ DEFAULT_GITHUB_GRAPHQL_API_URL,
20
21
  GitHubApiError,
21
22
  REQUIRED_GH_SCOPES,
22
23
  checkGhAuthenticated,
@@ -31,7 +32,7 @@ import {
31
32
  runGhAuthLogin,
32
33
  runGhAuthRefresh,
33
34
  validateGitHubToken
34
- } from "./chunk-SMNIGNS3.js";
35
+ } from "./chunk-FFY5VKNV.js";
35
36
  import {
36
37
  isClaudeRuntimeCommand,
37
38
  parseWorkflowMarkdown,
@@ -40,7 +41,7 @@ import {
40
41
  resolveClaudeCommandBinary,
41
42
  resolveRuntimeCommandBinary,
42
43
  runClaudePreflight
43
- } from "./chunk-LJUEOVAQ.js";
44
+ } from "./chunk-RGCSM2KZ.js";
44
45
  import {
45
46
  configFilePath,
46
47
  orchestratorLogPath,
@@ -537,6 +538,67 @@ function warnCheck(id, title, summary, remediation, details) {
537
538
  function formatAuthSource(source) {
538
539
  return source === "env" ? "GITHUB_GRAPHQL_TOKEN" : "gh CLI";
539
540
  }
541
+ function normalizeGitHubGraphqlEndpoint(value) {
542
+ const trimmed = value?.trim();
543
+ if (!trimmed) {
544
+ return null;
545
+ }
546
+ try {
547
+ const url = new URL(trimmed);
548
+ url.hostname = url.hostname.toLowerCase();
549
+ url.pathname = url.pathname.replace(/\/+$/, "") || "/";
550
+ url.search = "";
551
+ url.hash = "";
552
+ return url.toString().replace(/\/$/, "");
553
+ } catch {
554
+ return trimmed.replace(/\/+$/, "");
555
+ }
556
+ }
557
+ function deriveGhHostnameFromGraphqlEndpoint(endpoint) {
558
+ try {
559
+ const hostname = new URL(endpoint).hostname.toLowerCase();
560
+ return hostname === "api.github.com" ? "github.com" : hostname;
561
+ } catch {
562
+ return void 0;
563
+ }
564
+ }
565
+ function resolveGitHubGraphqlEndpoint(input) {
566
+ const trackerApiUrl = normalizeGitHubGraphqlEndpoint(input.trackerApiUrl);
567
+ const envApiUrl = normalizeGitHubGraphqlEndpoint(input.envApiUrl);
568
+ const resolvedEndpoint = trackerApiUrl ?? envApiUrl ?? DEFAULT_GITHUB_GRAPHQL_API_URL;
569
+ return {
570
+ resolvedEndpoint,
571
+ source: trackerApiUrl ? "tracker" : envApiUrl ? "env" : "default",
572
+ trackerApiUrl,
573
+ envApiUrl,
574
+ mismatch: trackerApiUrl !== null && envApiUrl !== null && trackerApiUrl !== envApiUrl,
575
+ ghHostname: deriveGhHostnameFromGraphqlEndpoint(resolvedEndpoint)
576
+ };
577
+ }
578
+ function buildGitHubGraphqlEndpointCheck(input) {
579
+ const details = {
580
+ resolvedEndpoint: input.resolvedEndpoint,
581
+ source: input.source,
582
+ trackerApiUrl: input.trackerApiUrl,
583
+ envApiUrl: input.envApiUrl,
584
+ ghHostname: input.ghHostname
585
+ };
586
+ if (input.mismatch) {
587
+ return warnCheck(
588
+ "github_graphql_endpoint",
589
+ "GitHub GraphQL endpoint",
590
+ `Resolved GitHub GraphQL endpoint is ${input.resolvedEndpoint}, but GITHUB_GRAPHQL_API_URL is ${input.envApiUrl}.`,
591
+ "Keep WORKFLOW.md tracker.endpoint/tracker.apiUrl and GITHUB_GRAPHQL_API_URL aligned, or unset GITHUB_GRAPHQL_API_URL so the workflow endpoint is authoritative.",
592
+ details
593
+ );
594
+ }
595
+ return passCheck(
596
+ "github_graphql_endpoint",
597
+ "GitHub GraphQL endpoint",
598
+ `Resolved GitHub GraphQL endpoint: ${input.resolvedEndpoint}.`,
599
+ details
600
+ );
601
+ }
540
602
  function remediationStep(id, checkId, title, status, summary, command, details) {
541
603
  return { id, checkId, title, status, summary, command, details };
542
604
  }
@@ -768,7 +830,10 @@ function buildGithubTrackerConfig(input) {
768
830
  }
769
831
  async function checkLinearTrackerResolution(input) {
770
832
  const tracker = input.projectConfig.projectConfig.tracker;
771
- const projectSlug = readStringSetting(tracker.settings, "projectSlug")?.trim();
833
+ const projectSlug = readStringSetting(
834
+ tracker.settings,
835
+ "projectSlug"
836
+ )?.trim();
772
837
  const activeStates = readLinearActiveStates(tracker.settings);
773
838
  const pickupLabels = readLinearPickupLabels(tracker.settings);
774
839
  if (!projectSlug) {
@@ -915,7 +980,9 @@ async function fetchLinearProjectBySlug(input) {
915
980
  })
916
981
  });
917
982
  if (!response.ok) {
918
- throw new Error(`Linear GraphQL request failed with HTTP ${response.status}.`);
983
+ throw new Error(
984
+ `Linear GraphQL request failed with HTTP ${response.status}.`
985
+ );
919
986
  }
920
987
  const payload = await response.json();
921
988
  if (payload.errors?.length) {
@@ -1453,6 +1520,7 @@ ${DOCTOR_USAGE}`);
1453
1520
  let resolvedProjectConfig = null;
1454
1521
  let resolvedGithubProjectDetail = null;
1455
1522
  let resolvedGithubProjectBindingId = null;
1523
+ let githubGraphqlEndpoint = null;
1456
1524
  const envToken = deps.getEnvGitHubToken();
1457
1525
  const currentNodeVersion = deps.processVersion;
1458
1526
  const currentNodeMajor = parseMajorNodeVersion(currentNodeVersion);
@@ -1531,19 +1599,68 @@ ${DOCTOR_USAGE}`);
1531
1599
  )
1532
1600
  );
1533
1601
  }
1534
- const ghAuth = ghInstalled ? deps.checkGhAuthenticated() : { authenticated: false };
1535
- const ghScopes = ghInstalled && ghAuth.authenticated ? deps.checkGhScopes() : { valid: false, missing: [...REQUIRED_GH_SCOPES], scopes: [] };
1602
+ resolvedProjectConfig = await deps.inspectManagedProjectSelection({
1603
+ configDir: options.configDir,
1604
+ requestedProjectId: parsedArgs.projectId
1605
+ });
1606
+ if (resolvedProjectConfig.kind === "resolved") {
1607
+ resolvedProjectId = resolvedProjectConfig.projectId;
1608
+ checks.push(
1609
+ passCheck(
1610
+ "managed_project",
1611
+ "Managed project selection",
1612
+ `Resolved managed project "${resolvedProjectConfig.projectId}".`,
1613
+ {
1614
+ projectId: resolvedProjectConfig.projectId,
1615
+ workspaceDir: resolvedProjectConfig.projectConfig.workspaceDir
1616
+ }
1617
+ )
1618
+ );
1619
+ if (resolvedProjectConfig.projectConfig.tracker.adapter !== "linear") {
1620
+ githubGraphqlEndpoint = resolveGitHubGraphqlEndpoint({
1621
+ trackerApiUrl: resolvedProjectConfig.projectConfig.tracker.apiUrl,
1622
+ envApiUrl: process.env.GITHUB_GRAPHQL_API_URL
1623
+ });
1624
+ checks.push(buildGitHubGraphqlEndpointCheck(githubGraphqlEndpoint));
1625
+ }
1626
+ } else {
1627
+ checks.push(
1628
+ failCheck(
1629
+ "managed_project",
1630
+ "Managed project selection",
1631
+ resolvedProjectConfig.message,
1632
+ "Run 'gh-symphony repo init' from the target repository.",
1633
+ {
1634
+ reason: resolvedProjectConfig.kind,
1635
+ ...resolvedProjectConfig.projectId ? { projectId: resolvedProjectConfig.projectId } : {}
1636
+ }
1637
+ )
1638
+ );
1639
+ }
1640
+ const ghHostname = githubGraphqlEndpoint?.ghHostname;
1641
+ const ghAuth = ghInstalled ? deps.checkGhAuthenticated({ hostname: ghHostname }) : { authenticated: false };
1642
+ const ghScopes = ghInstalled && ghAuth.authenticated ? deps.checkGhScopes({ hostname: ghHostname }) : { valid: false, missing: [...REQUIRED_GH_SCOPES], scopes: [] };
1643
+ const ghHostnameArg = ghHostname ? ` --hostname ${ghHostname}` : "";
1644
+ const ghLoginCommand = `gh auth login --scopes ${REQUIRED_GH_SCOPES.join(",")}${ghHostnameArg}`;
1645
+ const ghRefreshCommand = `gh auth refresh --scopes ${REQUIRED_GH_SCOPES.join(",")}${ghHostnameArg}`;
1536
1646
  if (envToken) {
1537
1647
  try {
1538
- auth = await deps.validateGitHubToken(envToken, "env");
1648
+ auth = await deps.validateGitHubToken(envToken, "env", {
1649
+ apiUrl: githubGraphqlEndpoint?.resolvedEndpoint
1650
+ });
1539
1651
  } catch (error) {
1540
1652
  envTokenError = error instanceof Error ? error.message : "Unknown token validation error.";
1541
1653
  }
1542
1654
  }
1543
1655
  if (!auth && ghInstalled && ghAuth.authenticated && ghScopes.valid) {
1544
1656
  try {
1545
- const ghToken = deps.getGhToken({ allowEnv: false });
1546
- auth = await deps.validateGitHubToken(ghToken, "gh");
1657
+ const ghToken = deps.getGhToken({
1658
+ allowEnv: false,
1659
+ hostname: ghHostname
1660
+ });
1661
+ auth = await deps.validateGitHubToken(ghToken, "gh", {
1662
+ apiUrl: githubGraphqlEndpoint?.resolvedEndpoint
1663
+ });
1547
1664
  } catch (error) {
1548
1665
  tokenError = error instanceof Error ? error.message : "Unknown token retrieval error.";
1549
1666
  }
@@ -1575,7 +1692,7 @@ ${DOCTOR_USAGE}`);
1575
1692
  "gh_authentication",
1576
1693
  "GitHub authentication",
1577
1694
  "gh auth status failed or no GitHub login is configured.",
1578
- `Run 'gh auth login --scopes ${REQUIRED_GH_SCOPES.join(",")}' and re-run the doctor command.`
1695
+ `Run '${ghLoginCommand}' and re-run the doctor command.`
1579
1696
  )
1580
1697
  );
1581
1698
  }
@@ -1605,42 +1722,11 @@ ${DOCTOR_USAGE}`);
1605
1722
  "gh_scopes",
1606
1723
  "GitHub token scopes",
1607
1724
  `Missing required scopes: ${missingScopes.join(", ")}.`,
1608
- `Run 'gh auth refresh --scopes ${REQUIRED_GH_SCOPES.join(",")}' and confirm 'gh auth status' shows the updated scopes.`,
1725
+ `Run '${ghRefreshCommand}' and confirm 'gh auth status${ghHostnameArg}' shows the updated scopes.`,
1609
1726
  { missing: missingScopes, scopes: ghScopes.scopes }
1610
1727
  )
1611
1728
  );
1612
1729
  }
1613
- resolvedProjectConfig = await deps.inspectManagedProjectSelection({
1614
- configDir: options.configDir,
1615
- requestedProjectId: parsedArgs.projectId
1616
- });
1617
- if (resolvedProjectConfig.kind === "resolved") {
1618
- resolvedProjectId = resolvedProjectConfig.projectId;
1619
- checks.push(
1620
- passCheck(
1621
- "managed_project",
1622
- "Managed project selection",
1623
- `Resolved managed project "${resolvedProjectConfig.projectId}".`,
1624
- {
1625
- projectId: resolvedProjectConfig.projectId,
1626
- workspaceDir: resolvedProjectConfig.projectConfig.workspaceDir
1627
- }
1628
- )
1629
- );
1630
- } else {
1631
- checks.push(
1632
- failCheck(
1633
- "managed_project",
1634
- "Managed project selection",
1635
- resolvedProjectConfig.message,
1636
- "Run 'gh-symphony repo init' from the target repository.",
1637
- {
1638
- reason: resolvedProjectConfig.kind,
1639
- ...resolvedProjectConfig.projectId ? { projectId: resolvedProjectConfig.projectId } : {}
1640
- }
1641
- )
1642
- );
1643
- }
1644
1730
  if (resolvedProjectConfig.kind === "resolved" && resolvedProjectConfig.projectConfig.tracker.adapter === "linear") {
1645
1731
  checks.push(
1646
1732
  await checkLinearTrackerResolution({
@@ -1683,7 +1769,9 @@ ${DOCTOR_USAGE}`);
1683
1769
  throw new Error("Managed project is not bound to a GitHub Project.");
1684
1770
  }
1685
1771
  resolvedGithubProjectBindingId = bindingId;
1686
- const client = deps.createClient(auth.token);
1772
+ const client = deps.createClient(auth.token, {
1773
+ apiUrl: githubGraphqlEndpoint?.resolvedEndpoint
1774
+ });
1687
1775
  const detail = await deps.getProjectDetail(client, bindingId);
1688
1776
  resolvedGithubProjectDetail = detail;
1689
1777
  checks.push(
@@ -1886,10 +1974,18 @@ ${DOCTOR_USAGE}`);
1886
1974
  }
1887
1975
  function buildRuntimeInstallGuidance(binary, platform) {
1888
1976
  if (binary === "codex") {
1889
- return "Install Codex CLI using its official installation instructions and ensure 'codex' is on PATH.";
1977
+ return [
1978
+ "Install Codex CLI from https://developers.openai.com/codex/cli/",
1979
+ "and ensure 'codex' is on PATH.",
1980
+ "Then authenticate with 'codex login'."
1981
+ ].join(" ");
1890
1982
  }
1891
1983
  if (binary === "claude" || binary === "claude-code") {
1892
- return "Install Claude Code using its official installation instructions and ensure the runtime binary is on PATH.";
1984
+ return [
1985
+ "Install Claude Code from https://code.claude.com/docs/en/quickstart",
1986
+ "and ensure the runtime binary is on PATH.",
1987
+ "Then set ANTHROPIC_API_KEY or complete a local Claude login for non-bare runs."
1988
+ ].join(" ");
1893
1989
  }
1894
1990
  if (platform === "win32" && binary) {
1895
1991
  return `Install '${binary}' using its official installation instructions and ensure the directory containing '${binary}.exe' is on PATH.`;
package/dist/index.d.ts CHANGED
@@ -1,10 +1,49 @@
1
1
  type GlobalOptions = {
2
2
  configDir: string;
3
+ configDirOverride?: boolean;
4
+ configDirSource?: "cli" | "env" | "default";
3
5
  verbose: boolean;
4
6
  json: boolean;
5
7
  noColor: boolean;
6
8
  };
7
9
  type CommandHandler = (args: string[], options: GlobalOptions) => Promise<void>;
10
+ type CliOptionValues = Partial<GlobalOptions & {
11
+ assignedOnly?: boolean;
12
+ config?: string;
13
+ daemon?: boolean;
14
+ dryRun?: boolean;
15
+ file?: string;
16
+ fix?: boolean;
17
+ follow?: boolean;
18
+ force?: boolean;
19
+ http?: string | boolean;
20
+ issue?: string;
21
+ level?: string;
22
+ logLevel?: string;
23
+ linearProjectSlug?: string;
24
+ nonInteractive?: boolean;
25
+ once?: boolean;
26
+ output?: string;
27
+ project?: string;
28
+ projectId?: string;
29
+ prune?: boolean;
30
+ run?: string;
31
+ runtime?: string;
32
+ skipContext?: boolean;
33
+ skipSkills?: boolean;
34
+ version?: boolean;
35
+ web?: string | boolean;
36
+ repoDir?: string;
37
+ workflowFile?: string;
38
+ workflow?: string;
39
+ watch?: boolean;
40
+ sample?: string;
41
+ smoke?: boolean;
42
+ bundle?: string | boolean;
43
+ attempt?: string;
44
+ tracker?: string;
45
+ }>;
46
+ declare function resolveGlobalOptions(values: CliOptionValues): GlobalOptions;
8
47
  declare function runCli(argv: string[]): Promise<void>;
9
48
 
10
- export { type CommandHandler, type GlobalOptions, runCli };
49
+ export { type CommandHandler, type GlobalOptions, resolveGlobalOptions, runCli };
package/dist/index.js CHANGED
@@ -417,21 +417,25 @@ function createRemovedCommandHandler(message) {
417
417
 
418
418
  // src/index.ts
419
419
  var COMMANDS = {
420
- workflow: () => import("./workflow-L5UEE7JH.js"),
421
- setup: () => import("./setup-DMYXHOCB.js"),
422
- doctor: () => import("./doctor-GHKE7TRO.js"),
423
- upgrade: () => import("./upgrade-UZAGYCRJ.js"),
424
- repo: () => import("./repo-V72OM7JL.js"),
420
+ workflow: () => import("./workflow-JQNOLYAM.js"),
421
+ setup: () => import("./setup-KCBVNMUJ.js"),
422
+ doctor: () => import("./doctor-TFKCAGZF.js"),
423
+ upgrade: () => import("./upgrade-YOYZAIIY.js"),
424
+ repo: () => import("./repo-7UOBO3QG.js"),
425
425
  config: () => import("./config-cmd-OIVIUKG7.js"),
426
- version: () => import("./version-UUVKCGQA.js")
426
+ version: () => import("./version-ZTY3SPRG.js")
427
427
  };
428
428
  function addGlobalOptions(command) {
429
429
  return command.option("--config <dir>", "Config directory").addOption(new Option("--config-dir <dir>").hideHelp()).option("-v, --verbose", "Enable verbose output").option("--json", "Output in JSON format").option("--no-color", "Disable color output");
430
430
  }
431
431
  function resolveGlobalOptions(values) {
432
432
  const configInput = typeof values.config === "string" ? values.config : typeof values.configDir === "string" ? values.configDir : void 0;
433
+ const configDirSource = configInput !== void 0 ? "cli" : typeof process.env.GH_SYMPHONY_CONFIG_DIR === "string" ? "env" : "default";
434
+ const hasConfigOverride = configDirSource === "cli" || hasExplicitConfigEnvOverride();
433
435
  const options = {
434
436
  configDir: resolveConfigDir(configInput),
437
+ configDirOverride: hasConfigOverride,
438
+ configDirSource,
435
439
  verbose: Boolean(values.verbose),
436
440
  json: Boolean(values.json),
437
441
  noColor: Boolean(values.noColor)
@@ -442,6 +446,13 @@ function resolveGlobalOptions(values) {
442
446
  setNoColor(options.noColor);
443
447
  return options;
444
448
  }
449
+ function hasExplicitConfigEnvOverride() {
450
+ const envConfigDir = process.env.GH_SYMPHONY_CONFIG_DIR;
451
+ if (!envConfigDir) {
452
+ return false;
453
+ }
454
+ return envConfigDir !== "/var/lib/gh-symphony";
455
+ }
445
456
  function resolveProjectId(values) {
446
457
  return values.projectId ?? values.project;
447
458
  }
@@ -706,7 +717,7 @@ function createProgram() {
706
717
  addGlobalOptions(
707
718
  repo.command("start").description("Start the orchestrator for the current repository").option("-d, --daemon", "Start in daemon mode").option("--once", "Run a single orchestration tick and exit").option("--assigned-only", "Limit this run to assigned issues").option(
708
719
  "--http [port]",
709
- "Expose dashboard and refresh endpoints over HTTP"
720
+ "Expose the JSON status API and refresh endpoints over HTTP"
710
721
  ).option(
711
722
  "--web [port]",
712
723
  "Expose the control plane web dashboard and API over HTTP"
@@ -872,5 +883,6 @@ if (process.argv[1] && import.meta.url === pathToFileURL(realpathSync(process.ar
872
883
  });
873
884
  }
874
885
  export {
886
+ resolveGlobalOptions,
875
887
  runCli
876
888
  };
@@ -17,7 +17,7 @@ import {
17
17
  import {
18
18
  initRepoRuntime,
19
19
  parseRepoRuntimeFlags
20
- } from "./chunk-34YCGQD2.js";
20
+ } from "./chunk-EILO332E.js";
21
21
  import {
22
22
  OrchestratorService,
23
23
  acquireProjectLock,
@@ -33,8 +33,8 @@ import {
33
33
  resolveOrchestratorLogLevel,
34
34
  resolveTrackerAdapter,
35
35
  runCli
36
- } from "./chunk-HHBXGE23.js";
37
- import "./chunk-7KFCWMMW.js";
36
+ } from "./chunk-C4QCVQVY.js";
37
+ import "./chunk-XLDJTMW5.js";
38
38
  import {
39
39
  resolveRepoRuntimeRoot,
40
40
  resolveRuntimeRoot
@@ -48,18 +48,20 @@ import {
48
48
  resolveGitHubAuth,
49
49
  runGhAuthLogin,
50
50
  runGhAuthRefresh
51
- } from "./chunk-SMNIGNS3.js";
51
+ } from "./chunk-FFY5VKNV.js";
52
52
  import {
53
53
  WorkflowConfigStore,
54
54
  deriveIssueWorkspaceKeyFromIdentifier,
55
+ formatEventMessage,
55
56
  isFileMissing,
56
57
  isMatchingIssueRun,
57
58
  mapIssueOrchestrationStateToStatus,
58
59
  parseRecentEvents,
59
60
  readJsonFile,
60
61
  safeReadDir
61
- } from "./chunk-LJUEOVAQ.js";
62
+ } from "./chunk-RGCSM2KZ.js";
62
63
  import {
64
+ configFilePath,
63
65
  daemonPidPath,
64
66
  httpStatusPath,
65
67
  loadActiveProjectConfig,
@@ -67,11 +69,15 @@ import {
67
69
  writeJsonFile
68
70
  } from "./chunk-YZP5N5XP.js";
69
71
 
72
+ // src/commands/repo.ts
73
+ import { existsSync } from "fs";
74
+
70
75
  // src/commands/logs.ts
71
76
  import { readFile, readdir, stat } from "fs/promises";
72
77
  import { join, resolve } from "path";
73
78
  import { createReadStream } from "fs";
74
79
  import { createInterface } from "readline";
80
+ var LOG_LEVELS = ["error", "warn", "info"];
75
81
  function parseLogsArgs(args) {
76
82
  const parsed = { follow: false };
77
83
  for (let i = 0; i < args.length; i += 1) {
@@ -100,6 +106,17 @@ function parseLogsArgs(args) {
100
106
  }
101
107
  var handler = async (args, options) => {
102
108
  const parsed = parseLogsArgs(args);
109
+ const level = parseLogLevel(parsed.level);
110
+ if (parsed.level && !level) {
111
+ process.stderr.write(
112
+ `Unknown --level "${parsed.level}". Valid values: ${LOG_LEVELS.join(
113
+ ", "
114
+ )}.
115
+ `
116
+ );
117
+ process.exitCode = 1;
118
+ return;
119
+ }
103
120
  const runtimeRoot = resolve(options.configDir);
104
121
  if (parsed.run) {
105
122
  const eventsPath = parsed.projectId ? join(
@@ -119,12 +136,19 @@ var handler = async (args, options) => {
119
136
  try {
120
137
  const content = await readFile(eventsPath, "utf8");
121
138
  const lines = content.trim().split("\n").filter(Boolean);
139
+ let matchedEvents2 = 0;
122
140
  for (const line of lines) {
123
141
  const event = JSON.parse(line);
124
- if (parsed.projectId && event.projectId !== parsed.projectId) continue;
125
- if (parsed.level && event.level !== parsed.level) continue;
126
- if (parsed.issue && event.issueIdentifier !== parsed.issue) continue;
142
+ if (parsed.projectId && getProjectId(event) !== parsed.projectId)
143
+ continue;
144
+ if (level && getLevel(event) !== level) continue;
145
+ if (parsed.issue && getIssueIdentifier(event) !== parsed.issue)
146
+ continue;
127
147
  process.stdout.write(formatEvent(event) + "\n");
148
+ matchedEvents2 += 1;
149
+ }
150
+ if (level && matchedEvents2 === 0) {
151
+ process.stderr.write(noMatchedEventsMessage(level));
128
152
  }
129
153
  } catch {
130
154
  process.stderr.write(`No events found for run: ${parsed.run}
@@ -177,6 +201,8 @@ var handler = async (args, options) => {
177
201
  }
178
202
  const runRoots = parsed.projectId ? [join(runtimeRoot, "projects", parsed.projectId, "runs")] : await listProjectRunRoots(runtimeRoot);
179
203
  let foundRuns = false;
204
+ let matchedEvents = 0;
205
+ const events = [];
180
206
  try {
181
207
  for (const runsDir of runRoots) {
182
208
  const entries = await safeReadDir2(runsDir);
@@ -191,11 +217,13 @@ var handler = async (args, options) => {
191
217
  const lines = content.trim().split("\n").filter(Boolean);
192
218
  for (const line of lines) {
193
219
  const event = JSON.parse(line);
194
- if (parsed.projectId && event.projectId !== parsed.projectId)
220
+ if (parsed.projectId && getProjectId(event) !== parsed.projectId)
195
221
  continue;
196
- if (parsed.level && event.level !== parsed.level) continue;
197
- if (parsed.issue && event.issueIdentifier !== parsed.issue) continue;
198
- process.stdout.write(formatEvent(event) + "\n");
222
+ if (level && getLevel(event) !== level) continue;
223
+ if (parsed.issue && getIssueIdentifier(event) !== parsed.issue)
224
+ continue;
225
+ events.push(event);
226
+ matchedEvents += 1;
199
227
  }
200
228
  } catch {
201
229
  }
@@ -205,15 +233,58 @@ var handler = async (args, options) => {
205
233
  }
206
234
  if (!foundRuns) {
207
235
  process.stderr.write("No runs found. Start the orchestrator first.\n");
236
+ return;
237
+ }
238
+ if (level && matchedEvents === 0) {
239
+ process.stderr.write(noMatchedEventsMessage(level));
240
+ return;
241
+ }
242
+ events.sort(
243
+ (left, right) => String(left.at ?? "").localeCompare(String(right.at ?? ""))
244
+ );
245
+ for (const event of events) {
246
+ process.stdout.write(formatEvent(event) + "\n");
208
247
  }
209
248
  };
210
249
  var logs_default = handler;
211
250
  function formatEvent(event) {
212
251
  const at = event.at ?? "";
213
252
  const eventType = event.event ?? "unknown";
214
- const issue = event.issueIdentifier ?? "";
215
- const extra = event.error ? ` error=${event.error}` : "";
216
- return `[${at}] ${eventType} ${issue}${extra}`;
253
+ const issue = getIssueIdentifier(event);
254
+ const message = formatEventMessage(event);
255
+ const subject = issue ? ` ${issue}` : "";
256
+ const extra = message ? ` ${message}` : "";
257
+ return `[${at}] ${eventType}${subject}${extra}`;
258
+ }
259
+ function getProjectId(event) {
260
+ return typeof event.projectId === "string" ? event.projectId : void 0;
261
+ }
262
+ function getLevel(event) {
263
+ switch (event.event) {
264
+ case "run-failed":
265
+ case "turn_failed":
266
+ case "worker-error":
267
+ case "hook-failed":
268
+ return "error";
269
+ case "run-suppressed":
270
+ case "run-retried":
271
+ return "warn";
272
+ default:
273
+ return "info";
274
+ }
275
+ }
276
+ function parseLogLevel(level) {
277
+ if (!level) {
278
+ return void 0;
279
+ }
280
+ return LOG_LEVELS.includes(level) ? level : void 0;
281
+ }
282
+ function noMatchedEventsMessage(level) {
283
+ return `No events matched the provided filters (--level ${level}).
284
+ `;
285
+ }
286
+ function getIssueIdentifier(event) {
287
+ return typeof event.issueIdentifier === "string" ? event.issueIdentifier : "";
217
288
  }
218
289
  async function listProjectRunRoots(runtimeRoot) {
219
290
  const roots = [join(runtimeRoot, "runs")];
@@ -2066,7 +2137,7 @@ var handler5 = async (args, options) => {
2066
2137
  if (httpServer) {
2067
2138
  logLine(
2068
2139
  cyan("\u25A1"),
2069
- parsed.webPort !== void 0 ? `Web dashboard listening on ${httpServer.url}` : `HTTP dashboard listening on ${httpServer.url}`
2140
+ parsed.webPort !== void 0 ? `Web dashboard listening on ${httpServer.url}` : `HTTP status API listening on ${httpServer.url}`
2070
2141
  );
2071
2142
  }
2072
2143
  logLine(
@@ -2085,7 +2156,7 @@ var handler5 = async (args, options) => {
2085
2156
  if (httpServer) {
2086
2157
  logLine(
2087
2158
  cyan("\u25A1"),
2088
- parsed.webPort !== void 0 ? "One-shot tick completed; web dashboard remains available until Ctrl+C" : "One-shot tick completed; HTTP dashboard remains available until Ctrl+C"
2159
+ parsed.webPort !== void 0 ? "One-shot tick completed; web dashboard remains available until Ctrl+C" : "One-shot tick completed; HTTP status API remains available until Ctrl+C"
2089
2160
  );
2090
2161
  if (shuttingDown) {
2091
2162
  break;
@@ -2807,6 +2878,7 @@ var handler7 = async (args, options) => {
2807
2878
  var stop_default = handler7;
2808
2879
 
2809
2880
  // src/commands/repo.ts
2881
+ var DOCKER_DEFAULT_CONFIG_DIR = "/var/lib/gh-symphony";
2810
2882
  var handler8 = async (args, options) => {
2811
2883
  const [subcommand, ...rest] = args;
2812
2884
  switch (subcommand) {
@@ -2850,11 +2922,21 @@ var handler8 = async (args, options) => {
2850
2922
  };
2851
2923
  var repo_default = handler8;
2852
2924
  function repoOptions(options) {
2925
+ const repoRuntimeRoot = resolveRepoRuntimeRoot();
2853
2926
  return {
2854
2927
  ...options,
2855
- configDir: resolveRepoRuntimeRoot()
2928
+ configDir: shouldUseConfigDirOverride(options, repoRuntimeRoot) ? options.configDir : repoRuntimeRoot
2856
2929
  };
2857
2930
  }
2931
+ function shouldUseConfigDirOverride(options, repoRuntimeRoot) {
2932
+ if (!options.configDirOverride) {
2933
+ return false;
2934
+ }
2935
+ if (options.configDirSource === "env" && options.configDir === DOCKER_DEFAULT_CONFIG_DIR && existsSync(configFilePath(repoRuntimeRoot))) {
2936
+ return false;
2937
+ }
2938
+ return true;
2939
+ }
2858
2940
  async function repoInit(args, options) {
2859
2941
  if (rejectRemovedProjectId(args)) {
2860
2942
  return;
@@ -2898,5 +2980,6 @@ function formatRepoSpec(repo) {
2898
2980
  return `${repo.owner}/${repo.name}`;
2899
2981
  }
2900
2982
  export {
2901
- repo_default as default
2983
+ repo_default as default,
2984
+ repoOptions
2902
2985
  };
@@ -16,10 +16,10 @@ import {
16
16
  warnDeprecatedSkipContext,
17
17
  writeEcosystem,
18
18
  writeWorkflowPlan
19
- } from "./chunk-4ZHWEQQL.js";
19
+ } from "./chunk-775A5LB5.js";
20
20
  import {
21
21
  initRepoRuntime
22
- } from "./chunk-34YCGQD2.js";
22
+ } from "./chunk-EILO332E.js";
23
23
  import "./chunk-3IRPSPAF.js";
24
24
  import {
25
25
  GhAuthError,
@@ -32,8 +32,8 @@ import {
32
32
  getProjectDetail,
33
33
  listUserProjects,
34
34
  validateToken
35
- } from "./chunk-SMNIGNS3.js";
36
- import "./chunk-LJUEOVAQ.js";
35
+ } from "./chunk-FFY5VKNV.js";
36
+ import "./chunk-RGCSM2KZ.js";
37
37
  import "./chunk-YZP5N5XP.js";
38
38
 
39
39
  // src/commands/setup.ts
@@ -16,8 +16,8 @@ function execFileAsync(file, args, execFileImpl = execFileCallback) {
16
16
  });
17
17
  }
18
18
  function resolveCurrentCliVersion() {
19
- if ("0.4.5".length > 0) {
20
- return "0.4.5";
19
+ if ("0.4.7".length > 0) {
20
+ return "0.4.7";
21
21
  }
22
22
  const pkg = JSON.parse(
23
23
  readFileSync(new URL("../../package.json", import.meta.url), "utf8")
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/commands/version.ts
4
4
  var handler = async (_args, options) => {
5
- const version = "0.4.5";
5
+ const version = "0.4.7";
6
6
  if (options.json) {
7
7
  process.stdout.write(JSON.stringify({ version }) + "\n");
8
8
  } else {
@@ -6,7 +6,7 @@ import {
6
6
  normalizeCodexRuntimeEvents,
7
7
  prepareCodexRuntimePlan,
8
8
  resolveLocalRuntimeLaunchConfig
9
- } from "./chunk-7KFCWMMW.js";
9
+ } from "./chunk-XLDJTMW5.js";
10
10
  import {
11
11
  DEFAULT_AGENT_INPUT_REQUIRED_REASON,
12
12
  classifySessionExit,
@@ -17,7 +17,7 @@ import {
17
17
  resolveClaudeCommandBinary,
18
18
  resolveWorkflowRuntimeCommand,
19
19
  runClaudePreflight
20
- } from "./chunk-LJUEOVAQ.js";
20
+ } from "./chunk-RGCSM2KZ.js";
21
21
 
22
22
  // ../worker/src/index.ts
23
23
  import { spawn as spawn2 } from "child_process";
@@ -6,12 +6,12 @@ import {
6
6
  resetWorkflowCommandDependenciesForTest,
7
7
  setWorkflowCommandDependenciesForTest,
8
8
  workflow_default
9
- } from "./chunk-I3CZXKS5.js";
10
- import "./chunk-4ZHWEQQL.js";
11
- import "./chunk-HHBXGE23.js";
12
- import "./chunk-7KFCWMMW.js";
13
- import "./chunk-SMNIGNS3.js";
14
- import "./chunk-LJUEOVAQ.js";
9
+ } from "./chunk-3ACU7O47.js";
10
+ import "./chunk-775A5LB5.js";
11
+ import "./chunk-C4QCVQVY.js";
12
+ import "./chunk-XLDJTMW5.js";
13
+ import "./chunk-FFY5VKNV.js";
14
+ import "./chunk-RGCSM2KZ.js";
15
15
  import "./chunk-YZP5N5XP.js";
16
16
  export {
17
17
  workflow_default as default,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gh-symphony/cli",
3
- "version": "0.4.5",
3
+ "version": "0.4.7",
4
4
  "license": "MIT",
5
5
  "author": "hojinzs",
6
6
  "description": "Interactive CLI for GitHub Symphony orchestration",
@@ -43,10 +43,10 @@
43
43
  "tsup": "^8.5.1",
44
44
  "@gh-symphony/core": "0.0.14",
45
45
  "@gh-symphony/control-plane": "0.0.15",
46
- "@gh-symphony/dashboard": "0.0.14",
47
46
  "@gh-symphony/orchestrator": "0.0.14",
48
47
  "@gh-symphony/runtime-claude": "0.0.14",
49
48
  "@gh-symphony/tracker-github": "0.0.14",
49
+ "@gh-symphony/dashboard": "0.0.14",
50
50
  "@gh-symphony/worker": "0.0.14"
51
51
  },
52
52
  "scripts": {