@ghx-dev/core 0.2.1 → 0.2.2

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 (29) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +68 -231
  3. package/dist/{chunk-HEHONZTO.js → chunk-C2KRRSSX.js} +1 -1
  4. package/dist/chunk-C2KRRSSX.js.map +1 -0
  5. package/dist/{chunk-M5PJLKL5.js → chunk-T3L2VDOS.js} +11 -11
  6. package/dist/chunk-T3L2VDOS.js.map +1 -0
  7. package/dist/cli/index.js +3 -3
  8. package/dist/cli/index.js.map +1 -1
  9. package/dist/index.d.ts +160 -0
  10. package/dist/index.js +2 -2
  11. package/dist/index.js.map +1 -1
  12. package/dist/{issue-mutations-OW464JP3.js → issue-mutations-DIWPF3JH.js} +2 -2
  13. package/dist/{issue-queries-ORG3VPK4.js → issue-queries-YQL65J7X.js} +2 -2
  14. package/dist/{pr-mutations-WOTG6FAB.js → pr-mutations-BVHDCAPR.js} +2 -2
  15. package/dist/{pr-queries-6CJJW7BT.js → pr-queries-NUL2UZJB.js} +2 -2
  16. package/dist/{project-QFSCYDDW.js → project-3ZSPVIOC.js} +2 -2
  17. package/dist/{release-33236BBA.js → release-IQCWD655.js} +2 -2
  18. package/dist/{repo-M6DKCWBG.js → repo-JF47JAZG.js} +2 -2
  19. package/package.json +5 -5
  20. package/skills/using-ghx/SKILL.md +2 -0
  21. package/dist/chunk-HEHONZTO.js.map +0 -1
  22. package/dist/chunk-M5PJLKL5.js.map +0 -1
  23. /package/dist/{issue-mutations-OW464JP3.js.map → issue-mutations-DIWPF3JH.js.map} +0 -0
  24. /package/dist/{issue-queries-ORG3VPK4.js.map → issue-queries-YQL65J7X.js.map} +0 -0
  25. /package/dist/{pr-mutations-WOTG6FAB.js.map → pr-mutations-BVHDCAPR.js.map} +0 -0
  26. /package/dist/{pr-queries-6CJJW7BT.js.map → pr-queries-NUL2UZJB.js.map} +0 -0
  27. /package/dist/{project-QFSCYDDW.js.map → project-3ZSPVIOC.js.map} +0 -0
  28. /package/dist/{release-33236BBA.js.map → release-IQCWD655.js.map} +0 -0
  29. /package/dist/{repo-M6DKCWBG.js.map → repo-JF47JAZG.js.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ghx",
3
3
  "description": "GitHub execution router for AI agents — 70 capabilities with deterministic routing and normalized output",
4
- "version": "0.2.1",
4
+ "version": "0.2.2",
5
5
  "author": {
6
6
  "name": "Arye Kogan"
7
7
  },
package/README.md CHANGED
@@ -1,283 +1,120 @@
1
- # @ghx-dev/core
1
+ <h1 align="center">@ghx-dev/core</h1>
2
2
 
3
3
  <p align="center">
4
4
  <img src="https://raw.githubusercontent.com/aryeko/ghx/main/assets/branding/social/ghx-social-dark-1280x640.png" alt="ghx social preview" width="480">
5
5
  </p>
6
6
 
7
+ <p align="center">
8
+ A typed GitHub execution router that gives AI agents deterministic, token-efficient access to the GitHub API.
9
+ </p>
10
+
7
11
  [![npm version](https://img.shields.io/npm/v/%40ghx-dev%2Fcore)](https://www.npmjs.com/package/@ghx-dev/core)
8
12
  [![npm downloads](https://img.shields.io/npm/dm/%40ghx-dev%2Fcore)](https://www.npmjs.com/package/@ghx-dev/core)
9
13
  [![CI (main)](https://github.com/aryeko/ghx/actions/workflows/ci-main.yml/badge.svg)](https://github.com/aryeko/ghx/actions/workflows/ci-main.yml)
10
14
  [![codecov](https://codecov.io/gh/aryeko/ghx/graph/badge.svg?token=KBIGR138V7)](https://codecov.io/gh/aryeko/ghx)
11
15
  [![License](https://img.shields.io/npm/l/%40ghx-dev%2Fcore)](https://github.com/aryeko/ghx/blob/main/LICENSE)
12
16
 
13
- Typed GitHub execution router for AI agents. Deterministic routing across CLI and GraphQL, runtime schema validation, and a stable result envelope -- so agents stop wasting tokens re-discovering GitHub API surfaces.
14
-
15
- ## Why ghx
16
-
17
- Agents instructed to "use `gh` CLI" for common PR and issue operations waste significant tokens on research, trial-and-error, and output parsing. Benchmarked across 40 runs on standard PR and issue workflows (MCP mode benchmark coming soon):
18
-
19
- | Metric | Improvement |
20
- |---|---|
21
- | Tool calls | **-55%** (PR review), **-47%** (issue triage) |
22
- | Active tokens | **-88%** (PR review), **-41%** (thread resolution) |
23
- | Latency | **-57%** (PR review), **-26%** (thread resolution) |
24
- | Success rate | **100%** both modes |
25
-
26
- Full report: [Codex 5.3 Benchmark](https://github.com/aryeko/ghx/blob/main/reports/codex-5.3-benchmark/README.md)
27
-
28
- ## Installation
29
-
30
- Requirements: Node.js `22+`, `gh` CLI authenticated (`gh auth status`).
31
-
32
- ```bash
33
- npm install @ghx-dev/core
34
- ```
35
-
36
- Alternative package managers:
37
-
38
- ```bash
39
- pnpm add @ghx-dev/core
40
- # or
41
- yarn add @ghx-dev/core
17
+ ## Why ghx?
18
+
19
+ When AI agents use the `gh` CLI directly, they waste thousands of tokens on research, trial-and-error formatting, and guessing JSON parsing paths. **ghx eliminates this waste** by providing a stable, structured execution layer.
20
+
21
+ > **100% success rate, 73% fewer tool calls, 18% fewer active tokens, 54% lower latency** compared to raw CLI usage ([measured across 30 runs](https://github.com/aryeko/ghx/blob/main/docs/eval-report.md) on standard PR workflows with Codex 5.3).
22
+
23
+ ```mermaid
24
+ sequenceDiagram
25
+ participant Agent
26
+ participant ghx as ghx
27
+ participant GH as GitHub API
28
+
29
+ %% Agent requests a typed execution
30
+ Agent->>ghx: executeTask("pr.view", { owner, name, prNumber })
31
+
32
+ %% ghx routing engine takes over
33
+ Note over ghx: 1. Validate input schema<br/>2. Select optimal route (GraphQL/CLI)<br/>3. Run preflight checks
34
+ ghx->>GH: typed GraphQL request
35
+ GH-->>ghx: response
36
+ Note over ghx: normalize errors & structure
37
+
38
+ %% Stable envelope returned
39
+ ghx-->>Agent: ResultEnvelope { ok: true, data: { ... } }
42
40
  ```
43
41
 
44
- Or run directly without installing:
42
+ ## Features
45
43
 
46
- ```bash
47
- npx @ghx-dev/core capabilities list
48
- ```
44
+ - **70+ Declarative Capabilities**: PRs, issues, labels, workflows, projects, releases — all defined by versioned YAML operation cards.
45
+ - **Deterministic Routing**: The agent doesn't choose CLI vs. GraphQL. ghx evaluates suitability rules and picks the optimal route automatically, with built-in fallbacks.
46
+ - **Stable Result Envelope**: No try/catch needed. Every execution returns `{ ok, data, error, meta }`. Errors are mapped to standard codes (`AUTH`, `RATE_LIMIT`, `NOT_FOUND`, etc.).
47
+ - **Chaining & Batching**: Execute multiple steps (`add label`, `add assignee`, `comment`) in one call. ghx resolves node IDs and batches them into a single network request.
48
+ - **Type Safety**: Full TypeScript schemas for inputs and outputs (via generated GraphQL types).
49
49
 
50
- Global CLI install:
51
-
52
- ```bash
53
- npm i -g @ghx-dev/core
54
- ```
55
-
56
- ## Quick Start (CLI)
57
-
58
- Set `GITHUB_TOKEN` or `GH_TOKEN` in your environment, then:
59
-
60
- ```bash
61
- npx @ghx-dev/core capabilities list
62
- npx @ghx-dev/core capabilities explain repo.view
63
- npx @ghx-dev/core run repo.view --input '{"owner":"aryeko","name":"ghx"}'
64
- ```
65
-
66
- If installed globally, replace `npx @ghx-dev/core` with `ghx`.
67
-
68
- Every capability returns a stable envelope:
50
+ ## Documentation
69
51
 
70
- ```json
71
- {
72
- "ok": true,
73
- "data": {
74
- "id": "R_kgDOOx...",
75
- "name": "ghx",
76
- "nameWithOwner": "aryeko/ghx"
77
- },
78
- "error": null,
79
- "meta": {
80
- "capability_id": "repo.view",
81
- "route_used": "cli",
82
- "reason": "CARD_PREFERRED"
83
- }
84
- }
85
- ```
52
+ Comprehensive documentation is available in the [`docs/`](./docs/) directory:
86
53
 
87
- ## Chain: Batch Operations
54
+ - **[Getting Started](./docs/getting-started/README.md)** — Installation, why ghx, and use case diagrams.
55
+ - [Library Quickstart](./docs/getting-started/library-quickstart.md)
56
+ - [CLI Quickstart](./docs/getting-started/cli-quickstart.md)
57
+ - [Agent Setup](./docs/getting-started/agent-setup.md)
58
+ - **[Concepts](./docs/concepts/README.md)** — How ghx works internally (Routing Engine, Operation Cards, Result Envelope, Chaining).
59
+ - **[Architecture](./docs/architecture/README.md)** — System design, execution pipeline, formatters, and GraphQL layer.
60
+ - **[Reference](./docs/reference/README.md)** — API exports, error codes, and a complete table of all 70+ capabilities.
88
61
 
89
- Batch multiple operations into a single tool call:
62
+ ## Quick Start (Library)
90
63
 
91
64
  ```bash
92
- ghx chain --steps - <<'EOF'
93
- [
94
- {"task":"issue.labels.remove","input":{"owner":"acme","name":"repo","issueNumber":42,"labels":["triage"]}},
95
- {"task":"issue.labels.add","input":{"owner":"acme","name":"repo","issueNumber":42,"labels":["enhancement"]}},
96
- {"task":"issue.comments.create","input":{"owner":"acme","name":"repo","issueNumber":42,"body":"Triaged."}}
97
- ]
98
- EOF
65
+ npm install @ghx-dev/core
99
66
  ```
100
67
 
101
- ## Quick Start (Library API)
102
-
103
68
  ```ts
104
69
  import { createGithubClientFromToken, executeTask } from "@ghx-dev/core"
105
70
 
106
71
  const token = process.env.GITHUB_TOKEN!
107
72
  const githubClient = createGithubClientFromToken(token)
108
73
 
74
+ // Execute a task: input is validated, optimal route is chosen
109
75
  const result = await executeTask(
110
76
  { task: "repo.view", input: { owner: "aryeko", name: "ghx" } },
111
77
  { githubClient, githubToken: token },
112
78
  )
113
79
 
114
80
  if (result.ok) {
115
- console.log(result.data)
81
+ console.log("Success:", result.data.nameWithOwner)
82
+ console.log("Route used:", result.meta.route_used) // e.g. "graphql"
116
83
  } else {
117
- console.error(result.error?.code, result.error?.message)
84
+ console.error("Failed:", result.error.code) // e.g. "NOT_FOUND"
85
+ console.error("Retryable?", result.error.retryable)
118
86
  }
119
87
  ```
120
88
 
121
- Need a custom GraphQL transport? See [Custom GraphQL Transport](#custom-graphql-transport).
122
-
123
- ## Agent Onboarding
89
+ ## Quick Start (CLI)
124
90
 
125
- <details>
126
- <summary>Install ghx as a project skill for Claude Code</summary>
91
+ Use ghx directly from your terminal or add it as an agent skill.
127
92
 
128
93
  ```bash
129
- npx @ghx-dev/core setup --scope project --yes
130
- npx @ghx-dev/core setup --scope project --verify
131
- ```
132
-
133
- The canonical setup skill content is stored in `skills/using-ghx/SKILL.md` (package root). During build/publish it is copied to `dist/skills/using-ghx/SKILL.md`. `ghx setup` writes this content to `.agents/skills/ghx/SKILL.md` in user or project scope.
134
-
135
- </details>
136
-
137
- ## Agent Tools
138
-
139
- ```ts
140
- import {
141
- createExecuteTool,
142
- createGithubClientFromToken,
143
- executeTask,
144
- explainCapability,
145
- listCapabilities,
146
- } from "@ghx-dev/core"
147
-
148
- // Wire the execute tool to the real engine
149
- const token = process.env.GITHUB_TOKEN!
150
- const githubClient = createGithubClientFromToken(token)
151
-
152
- const tool = createExecuteTool({
153
- executeTask: (request) => executeTask(request, { githubClient, githubToken: token }),
154
- })
155
-
156
- // Discover and execute capabilities
157
- console.log(listCapabilities())
158
- console.log(explainCapability("repo.view"))
159
- const result = await tool.execute("repo.view", { owner: "aryeko", name: "ghx" })
160
- ```
161
-
162
- ## 70 Capabilities
163
-
164
- | Domain | Count | Examples |
165
- |---|---|---|
166
- | Repository | 3 | `repo.view`, `repo.labels.list` |
167
- | Issues | 23 | create/update/close, labels, assignees, milestones, relations |
168
- | Pull Requests | 21 | diff, threads, reviews, checks, merge, branch update |
169
- | Workflows and CI | 11 | runs, jobs, logs, dispatch, rerun, cancel, artifacts |
170
- | Releases | 5 | view, list, create, update, publish |
171
- | Projects v2 | 7 | items, fields, add/remove issues |
172
-
173
- Full list: `ghx capabilities list` or [operation card registry](https://github.com/aryeko/ghx/tree/main/packages/core/src/core/registry/cards).
174
-
175
- ## Result Envelope
94
+ # List all 70+ capabilities
95
+ npx @ghx-dev/core capabilities list
176
96
 
177
- All execution paths resolve to:
97
+ # Run a capability
98
+ npx @ghx-dev/core run pr.view --input '{"owner":"aryeko","name":"ghx","number":42}'
178
99
 
179
- ```ts
180
- type ResultEnvelope<TData = unknown> = {
181
- ok: boolean
182
- data?: TData
183
- error?: {
184
- code: string // AUTH, NOT_FOUND, RATE_LIMIT, VALIDATION, ...
185
- message: string
186
- retryable: boolean
187
- details?: Record<string, unknown>
188
- }
189
- meta: {
190
- capability_id: string
191
- route_used?: "cli" | "graphql" | "rest"
192
- reason?: string
193
- attempts?: Array<{
194
- route: "cli" | "graphql" | "rest"
195
- status: "success" | "error" | "skipped"
196
- error_code?: string
197
- duration_ms?: number
198
- }>
199
- }
200
- }
100
+ # Output is a standard ResultEnvelope:
101
+ # {
102
+ # "ok": true,
103
+ # "data": { ... },
104
+ # "meta": { "capability_id": "pr.view", "route_used": "graphql", ... }
105
+ # }
201
106
  ```
202
107
 
203
- ## Environment Variables
204
-
205
- - `GITHUB_TOKEN` or `GH_TOKEN` (required)
206
- - `GITHUB_GRAPHQL_URL` (optional; override GraphQL endpoint)
207
- - `GH_HOST` (optional; derives enterprise GraphQL endpoint)
208
-
209
- ## Security and Permissions
210
-
211
- - Start with least privilege and grant only what your capability set needs.
212
- - For quick local testing, a classic PAT with `repo` scope is the simplest route.
213
- - For production agents, prefer fine-grained tokens with read permissions first (`Metadata`, `Contents`, `Pull requests`, `Issues`, `Actions`, `Projects`) and add writes only where needed.
108
+ ## Agent Integration
214
109
 
215
- ## Compatibility
110
+ To install the `ghx` skill for Claude Code:
216
111
 
217
- - Node.js `22+`
218
- - GitHub Cloud and GitHub Enterprise hosts (`GH_HOST` supported)
219
- - Route adapters: CLI and GraphQL
220
-
221
- <details>
222
- <summary>Public Exports</summary>
223
-
224
- Root (`@ghx-dev/core`):
225
-
226
- - `executeTask` -- run a capability
227
- - `createGithubClientFromToken` -- create a client from a token string
228
- - `createGithubClient`, `createGraphqlClient` -- create clients from a custom transport
229
- - `listOperationCards`, `getOperationCard` -- inspect capability registry
230
- - `createSafeCliCommandRunner` -- custom CLI execution
231
- - Types: `TaskRequest`, `ResultEnvelope`, `ResultError`, `ResultMeta`, `AttemptMeta`, `RouteSource`, `RouteReasonCode`, `TokenClientOptions`
232
-
233
- Subpaths:
234
-
235
- - `@ghx-dev/core/cli` -- CLI entrypoint
236
-
237
- </details>
238
-
239
- <details>
240
- <a id="custom-graphql-transport"></a>
241
- <summary>Custom GraphQL Transport</summary>
242
-
243
- For full control over the GraphQL layer, pass your own transport to `createGithubClient`:
244
-
245
- ```ts
246
- import { createGithubClient, executeTask } from "@ghx-dev/core"
247
-
248
- const githubClient = createGithubClient({
249
- async execute<TData>(query: string, variables?: Record<string, unknown>): Promise<TData> {
250
- const response = await fetch("https://api.github.com/graphql", {
251
- method: "POST",
252
- headers: {
253
- "content-type": "application/json",
254
- authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
255
- },
256
- body: JSON.stringify({ query, variables: variables ?? {} }),
257
- })
258
- const payload = (await response.json()) as { data?: TData; errors?: Array<{ message?: string }> }
259
- if (payload.errors?.length) throw new Error(payload.errors[0]?.message ?? "GraphQL error")
260
- if (payload.data === undefined) throw new Error("GraphQL response missing data")
261
- return payload.data
262
- },
263
- })
264
-
265
- const result = await executeTask(
266
- { task: "repo.view", input: { owner: "aryeko", name: "ghx" } },
267
- { githubClient, githubToken: process.env.GITHUB_TOKEN },
268
- )
112
+ ```bash
113
+ npx @ghx-dev/core setup --scope project --yes
269
114
  ```
270
115
 
271
- </details>
272
-
273
- ## Documentation
274
-
275
- - [Documentation Hub](https://github.com/aryeko/ghx/blob/main/docs/README.md)
276
- - [Architecture](https://github.com/aryeko/ghx/blob/main/docs/architecture/README.md)
277
- - [Capabilities Reference](https://github.com/aryeko/ghx/blob/main/docs/capabilities/README.md)
278
- - [Operation Cards](https://github.com/aryeko/ghx/blob/main/docs/architecture/operation-cards.md)
279
- - [Publishing Guide](https://github.com/aryeko/ghx/blob/main/docs/contributing/publishing.md)
116
+ This installs `.agents/skills/ghx/SKILL.md` which teaches Claude how to use `npx @ghx-dev/core` for reliable GitHub interactions.
280
117
 
281
118
  ## License
282
119
 
283
- MIT - https://github.com/aryeko/ghx/blob/main/LICENSE
120
+ MIT
@@ -118,4 +118,4 @@ export {
118
118
  resolveGraphqlUrl,
119
119
  createTokenTransport
120
120
  };
121
- //# sourceMappingURL=chunk-HEHONZTO.js.map
121
+ //# sourceMappingURL=chunk-C2KRRSSX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/gql/transport.ts"],"sourcesContent":["import { type DocumentNode, print } from \"graphql\"\nimport type { GraphQLClient, RequestDocument, RequestOptions } from \"graphql-request\"\n\nexport type GraphqlVariables = Record<string, unknown>\n\n/** A single error from a GraphQL response. */\nexport type GraphqlError = {\n message: string\n path?: ReadonlyArray<string | number>\n extensions?: Record<string, unknown>\n}\n\n/** Raw GraphQL response containing both `data` and `errors` fields. */\nexport type GraphqlRawResult<TData> = {\n data: TData | undefined\n errors: GraphqlError[] | undefined\n}\n\ntype GraphqlDocument = string | DocumentNode\ntype QueryLike = GraphqlDocument | RequestDocument\n\n/**\n * Low-level transport interface for sending GraphQL queries.\n *\n * Implement this to use a custom HTTP client, proxy, or mock.\n * Pass to {@link createGithubClient} or {@link createGraphqlClient}.\n */\nexport interface GraphqlTransport {\n execute<TData>(query: string, variables?: GraphqlVariables): Promise<TData>\n executeRaw?<TData>(query: string, variables?: GraphqlVariables): Promise<GraphqlRawResult<TData>>\n}\n\n/**\n * Higher-level GraphQL client with `query` and `queryRaw` methods.\n *\n * Created by {@link createGraphqlClient} from a {@link GraphqlTransport}.\n */\nexport interface GraphqlClient {\n query<TData, TVariables extends GraphqlVariables = GraphqlVariables>(\n query: GraphqlDocument,\n variables?: TVariables,\n ): Promise<TData>\n queryRaw<TData, TVariables extends GraphqlVariables = GraphqlVariables>(\n query: GraphqlDocument,\n variables?: TVariables,\n ): Promise<GraphqlRawResult<TData>>\n}\n\n/** Options for creating a token-based GraphQL transport. */\nexport type TokenClientOptions = {\n token: string\n graphqlUrl?: string\n}\n\nfunction queryToString(query: QueryLike): string {\n if (typeof query === \"string\") {\n return query\n }\n\n if (typeof query === \"object\" && query !== null && \"kind\" in query) {\n return print(query as DocumentNode)\n }\n\n return String(query)\n}\n\nfunction assertQuery(query: string): void {\n if (query.trim().length === 0) {\n throw new Error(\"GraphQL query must be non-empty\")\n }\n}\n\n/**\n * Create a {@link GraphqlClient} from a {@link GraphqlTransport}.\n *\n * Wraps the raw transport `execute` method with query string normalization\n * and a `queryRaw` method that returns settled results.\n */\nexport function createGraphqlClient(transport: GraphqlTransport): GraphqlClient {\n return {\n async query<TData, TVariables extends GraphqlVariables = GraphqlVariables>(\n query: GraphqlDocument,\n variables?: TVariables,\n ): Promise<TData> {\n const queryText = queryToString(query)\n assertQuery(queryText)\n return transport.execute<TData>(queryText, variables)\n },\n async queryRaw<TData, TVariables extends GraphqlVariables = GraphqlVariables>(\n query: GraphqlDocument,\n variables?: TVariables,\n ): Promise<GraphqlRawResult<TData>> {\n const queryText = queryToString(query)\n assertQuery(queryText)\n // Both paths normalize transport-level errors into settled results\n try {\n if (transport.executeRaw) {\n return await transport.executeRaw<TData>(queryText, variables)\n }\n const data = await transport.execute<TData>(queryText, variables)\n return { data, errors: undefined }\n } catch (err) {\n return {\n data: undefined,\n errors: [{ message: err instanceof Error ? err.message : String(err) }],\n }\n }\n },\n }\n}\n\nexport function createGraphqlRequestClient(transport: GraphqlTransport): GraphQLClient {\n const client: Pick<GraphQLClient, \"request\"> = {\n request<TData, TVariables extends object = object>(\n documentOrOptions: RequestDocument | RequestOptions<TVariables, TData>,\n ...variablesAndRequestHeaders: unknown[]\n ): Promise<TData> {\n const options =\n typeof documentOrOptions === \"object\" &&\n documentOrOptions !== null &&\n \"document\" in documentOrOptions\n ? documentOrOptions\n : {\n document: documentOrOptions,\n variables: variablesAndRequestHeaders[0] as TVariables | undefined,\n }\n\n const queryText = queryToString(options.document)\n assertQuery(queryText)\n return transport.execute<TData>(queryText, options.variables as GraphqlVariables)\n },\n }\n\n return client as GraphQLClient\n}\n\nconst DEFAULT_GRAPHQL_URL = \"https://api.github.com/graphql\"\n\nexport function resolveGraphqlUrl(): string {\n if (process.env.GITHUB_GRAPHQL_URL) {\n return process.env.GITHUB_GRAPHQL_URL\n }\n\n if (process.env.GH_HOST) {\n return `https://${process.env.GH_HOST}/api/graphql`\n }\n\n return DEFAULT_GRAPHQL_URL\n}\n\ntype JsonPayload<TData> = {\n data?: TData\n errors?: GraphqlError[]\n message?: string\n}\n\nasync function fetchGraphql<TData>(\n url: string,\n token: string,\n query: string,\n variables?: GraphqlVariables,\n): Promise<JsonPayload<TData>> {\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n authorization: `Bearer ${token}`,\n },\n body: JSON.stringify({ query, variables: variables ?? {} }),\n })\n\n if (!response.ok) {\n let message = `GraphQL request failed (${response.status})`\n try {\n const body = (await response.json()) as JsonPayload<TData>\n if (body.message) {\n message = body.message\n }\n } catch {\n // Non-JSON error body — use status-based message\n }\n throw new Error(message)\n }\n\n try {\n return (await response.json()) as JsonPayload<TData>\n } catch {\n throw new Error(`GraphQL response is not valid JSON (${response.status})`)\n }\n}\n\nexport function createTokenTransport(token: string, graphqlUrl?: string): GraphqlTransport {\n const url = graphqlUrl ?? resolveGraphqlUrl()\n\n return {\n async execute<TData>(query: string, variables?: GraphqlVariables): Promise<TData> {\n const payload = await fetchGraphql<TData>(url, token, query, variables)\n\n if (payload.errors?.length) {\n throw new Error(payload.errors[0]?.message ?? \"GraphQL returned errors\")\n }\n\n if (payload.data === undefined) {\n throw new Error(\"GraphQL response missing data\")\n }\n\n return payload.data\n },\n\n async executeRaw<TData>(\n query: string,\n variables?: GraphqlVariables,\n ): Promise<GraphqlRawResult<TData>> {\n const payload = await fetchGraphql<TData>(url, token, query, variables)\n return {\n data: payload.data,\n errors: payload.errors?.length ? payload.errors : undefined,\n }\n },\n }\n}\n"],"mappings":"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","names":[]}
@@ -76,7 +76,7 @@ import {
76
76
  import {
77
77
  createGraphqlClient,
78
78
  createTokenTransport
79
- } from "./chunk-HEHONZTO.js";
79
+ } from "./chunk-C2KRRSSX.js";
80
80
 
81
81
  // src/core/execution/cli/safe-runner.ts
82
82
  import { spawn } from "child_process";
@@ -745,7 +745,7 @@ function createLogger(config) {
745
745
  }
746
746
  function write(level, msg, ctx) {
747
747
  if (levelIndex(level) < minIndex) return;
748
- const version = true ? "0.2.1" : "unknown";
748
+ const version = true ? "0.2.2" : "unknown";
749
749
  const entry = {
750
750
  ts: (/* @__PURE__ */ new Date()).toISOString(),
751
751
  pid: config.pid,
@@ -856,7 +856,7 @@ function assembleChainResult(input) {
856
856
  };
857
857
  }
858
858
  if (alias in mutationRawResult) {
859
- return { task: req.task, ok: true, data: mutationRawResult[alias] };
859
+ return { task: req.task, ok: true };
860
860
  }
861
861
  if (alias in queryRawResult) {
862
862
  return { task: req.task, ok: true, data: queryRawResult[alias] };
@@ -6049,13 +6049,13 @@ function createGithubClient(transport) {
6049
6049
  let prMutations;
6050
6050
  let release;
6051
6051
  let project;
6052
- const loadRepo = async () => repo ??= await import("./repo-M6DKCWBG.js");
6053
- const loadIssueQueries = async () => issueQueries ??= await import("./issue-queries-ORG3VPK4.js");
6054
- const loadIssueMutations = async () => issueMutations ??= await import("./issue-mutations-OW464JP3.js");
6055
- const loadPrQueries = async () => prQueries ??= await import("./pr-queries-6CJJW7BT.js");
6056
- const loadPrMutations = async () => prMutations ??= await import("./pr-mutations-WOTG6FAB.js");
6057
- const loadRelease = async () => release ??= await import("./release-33236BBA.js");
6058
- const loadProject = async () => project ??= await import("./project-QFSCYDDW.js");
6052
+ const loadRepo = async () => repo ??= await import("./repo-JF47JAZG.js");
6053
+ const loadIssueQueries = async () => issueQueries ??= await import("./issue-queries-YQL65J7X.js");
6054
+ const loadIssueMutations = async () => issueMutations ??= await import("./issue-mutations-DIWPF3JH.js");
6055
+ const loadPrQueries = async () => prQueries ??= await import("./pr-queries-NUL2UZJB.js");
6056
+ const loadPrMutations = async () => prMutations ??= await import("./pr-mutations-BVHDCAPR.js");
6057
+ const loadRelease = async () => release ??= await import("./release-IQCWD655.js");
6058
+ const loadProject = async () => project ??= await import("./project-3ZSPVIOC.js");
6059
6059
  return {
6060
6060
  query: (query, variables) => graphqlClient.query(query, variables),
6061
6061
  queryRaw: (query, variables) => graphqlClient.queryRaw(query, variables),
@@ -6129,4 +6129,4 @@ export {
6129
6129
  createGithubClientFromToken,
6130
6130
  createGithubClient
6131
6131
  };
6132
- //# sourceMappingURL=chunk-M5PJLKL5.js.map
6132
+ //# sourceMappingURL=chunk-T3L2VDOS.js.map