ask-github 0.1.4 → 0.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6ae01ffdb62eea1500c1e9544915704dbcc34d18f27124a82f3a3ee59c93e92b
4
- data.tar.gz: 03a155f16c3e4409ea7383b7b071f0c55d7bd729ec553c70d8e92020e9b72d8f
3
+ metadata.gz: bd64129291b95815da38080f42a150a158ce4f9bfc154b243ad237c209bcd21c
4
+ data.tar.gz: 9a61c3deae1d9e1902e3c8cb379f1c17c44c6c58ddf9bed24fab10ad7da907bc
5
5
  SHA512:
6
- metadata.gz: d40f074e53dd7d58e15dce513200921f23ac344fd2f1b505efb36a9d871b407993920dcfe39cf6ee925b7b67465aba444c24a156722bc2226614cd7e241df817
7
- data.tar.gz: 03210c203eff7072f09d372ec8cf536cdf06ea013eb5f479728b35d08a23f1b96bff56a884eeee8a5d244a4409db41553955732479b2026262f09bc5605915c1
6
+ metadata.gz: 9a4e4598c8a7e4924b21d9fb4030c052b2efdb280dcee3c614515e59cf651f896a7320c5fc27d22c9af6509ce3c05c723606c37fe3b3e1a981f19489a8062239
7
+ data.tar.gz: d4d55c62f888a877a31c8b8fcc8523a5e073d5b4ec3f26d12f4936bd3bf3bd373b61bbd0b75aada7842bdbf60a031f8b38e3a1292adca5920a88faa7482f3748
data/CHANGELOG.md CHANGED
@@ -4,6 +4,14 @@
4
4
  - Gemspec validation test. Infrastructure: rubocop, overcommit, bin/setup, CI matrix. VCR rake tasks for cassette freshness.
5
5
  # Changelog
6
6
 
7
+ ## [0.2.0] - 2026-08-16
8
+
9
+ ### Added
10
+
11
+ - **client.rb** — `Ask::GitHub.client(token: nil)` accepts an explicit token (the connector path; token resolution still falls back to `Ask::Auth.resolve(:github_token)`).
12
+ - **Content helpers** — `default_branch(repo)`, `tree(repo, branch:)`, `file(repo, path, branch:)`, and `license(repo)` for docs-as-code sources; 401s map to `Ask::Auth::InvalidCredential` like every other call.
13
+
14
+
7
15
  ## [0.1.2] - 2026-06-21
8
16
 
9
17
  ### Added
@@ -5,27 +5,36 @@ require "ask/auth"
5
5
 
6
6
  module Ask
7
7
  module GitHub
8
- # Returns an authenticated Octokit client configured for an AI agent.
8
+ # Returns an authenticated Octokit client configured for an AI agent
9
+ # or a content connector.
9
10
  #
10
- # Resolves the GitHub token via +Ask::Auth.resolve(:github_token)+ and
11
- # configures the client with sensible defaults:
11
+ # Resolves the GitHub token via +Ask::Auth.resolve(:github_token)+,
12
+ # or uses the +token:+ given explicitly (the connector path — the
13
+ # token comes from the host app's own credential store). Configures
14
+ # the client with sensible defaults:
12
15
  #
13
16
  # - +auto_paginate+: +true+ (collects all pages automatically)
14
17
  # - +per_page+: +100+ (maximum items per page)
15
18
  # - +middleware+: Faraday retry middleware (3 retries, exponential backoff)
16
19
  #
17
20
  # The client is wrapped in a +ClientProxy+ that converts
18
- # +Octokit::Unauthorized+ into +Ask::Auth::InvalidCredential+.
21
+ # +Octokit::Unauthorized+ into +Ask::Auth::InvalidCredential+, and
22
+ # exposes the repo-content helpers (+default_branch+, +tree+, +file+,
23
+ # +license+) for docs-as-code sources.
19
24
  #
20
25
  # @example
21
26
  # client = Ask::GitHub.client
22
27
  # client.issues("owner/repo")
23
28
  #
24
- # @return [Octokit::Client] an authenticated client
29
+ # @example connector with an explicit token
30
+ # client = Ask::GitHub.client(token: credential.token)
31
+ # client.default_branch("owner/repo")
32
+ #
33
+ # @return [ClientProxy] an authenticated client
25
34
  # @raise [Ask::Auth::MissingCredential] if no GitHub token is configured
26
35
  # @raise [Ask::Auth::InvalidCredential] if the token is rejected (401)
27
- def self.client
28
- token = Ask::Auth.resolve(:github_token)
36
+ def self.client(token: nil)
37
+ token ||= Ask::Auth.resolve(:github_token)
29
38
 
30
39
  client = Octokit::Client.new(access_token: token, auto_paginate: true, per_page: 100)
31
40
 
@@ -39,11 +48,78 @@ module Ask
39
48
  ClientProxy.new(client)
40
49
  end
41
50
 
42
- # Proxies method calls to an +Octokit::Client+, converting authentication
43
- # errors into +Ask::Auth::InvalidCredential+.
51
+ # The repo-content helpers: the raw pieces a docs-as-code connector
52
+ # needs (tree listing, raw file reads, the default branch, and the
53
+ # repo's license). Explicit methods, so connectors never poke at
54
+ # Octokit's full surface.
55
+ class Content
56
+ def initialize(client)
57
+ @client = client
58
+ end
59
+
60
+ # The repository's default branch name (e.g. "main").
61
+ def default_branch(repo)
62
+ call { @client.repo(repo).default_branch }
63
+ end
64
+
65
+ # The recursive file tree for a branch: [{path:, type:}] entries.
66
+ # GitHub truncates enormous trees; callers bound what they consume.
67
+ def tree(repo, branch: nil)
68
+ sha = branch || default_branch(repo)
69
+ call { @client.tree(repo, sha, recursive: true) }.tree.map do |entry|
70
+ {path: entry.path, type: entry.type}
71
+ end
72
+ end
73
+
74
+ # A file's raw content at a path, or nil when the path doesn't exist.
75
+ def file(repo, path, branch: nil)
76
+ call do
77
+ @client.contents(repo, path: path, ref: branch || default_branch(repo),
78
+ accept: "application/vnd.github.raw")
79
+ end
80
+ rescue ::Octokit::NotFound
81
+ nil
82
+ end
83
+
84
+ # The repo's SPDX license id (e.g. "mit"), or nil when unlicensed.
85
+ def license(repo)
86
+ call { @client.license(repo) }&.license&.spdx_id
87
+ rescue ::Octokit::NotFound
88
+ nil
89
+ end
90
+
91
+ private
92
+
93
+ def call
94
+ yield
95
+ rescue ::Octokit::Unauthorized
96
+ ::Kernel.raise ::Ask::Auth::InvalidCredential, :github_token
97
+ end
98
+ end
99
+
100
+ # Proxies method calls to an +Octokit::Client+, converting
101
+ # authentication errors into +Ask::Auth::InvalidCredential+, and
102
+ # exposing the content helpers.
44
103
  class ClientProxy < BasicObject
45
104
  def initialize(client)
46
105
  @client = client
106
+ @content = ::Ask::GitHub::Content.new(client)
107
+ end
108
+
109
+ def default_branch(repo)
110
+ @content.default_branch(repo)
111
+ end
112
+
113
+ def tree(repo, branch: nil)
114
+ @content.tree(repo, branch: branch)
115
+ end
116
+
117
+ def file(repo, path, branch: nil)
118
+ @content.file(repo, path, branch: branch)
119
+ end
120
+
121
+ def license(repo)
122
+ @content.license(repo)
47
123
  end
48
124
 
49
125
  def method_missing(name, ...)
@@ -52,9 +128,13 @@ module Ask
52
128
  ::Kernel.raise ::Ask::Auth::InvalidCredential, :github_token
53
129
  end
54
130
 
55
- def respond_to_missing?(name, include_private = false)
56
- @client.respond_to?(name, include_private) || super
131
+ # BasicObject has no +respond_to?+ — report the content helpers
132
+ # explicitly, forward everything else to the wrapped client.
133
+ def respond_to?(name, include_private = false)
134
+ CONTENT_METHODS.include?(name) || @client.respond_to?(name, include_private)
57
135
  end
136
+
137
+ CONTENT_METHODS = %i[default_branch tree file license].freeze
58
138
  end
59
139
  end
60
140
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Ask
4
4
  module GitHub
5
- VERSION = "0.1.4"
5
+ VERSION = "0.2.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ask-github
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kaka Ruto