Adds GitHub Projects V2 fetching to skill-tree.#29
Open
gme-muriuki wants to merge 13 commits into
Open
Conversation
Add an AGENTS.md / CLAUDE.md pair: CLAUDE.md imports AGENTS.md; AGENTS.md holds the agent contract for documentation updates, build/test discipline, and co-authorship. Restructure the design docs to be factual and descriptive. md/summary.md gains a style block codifying these conventions. - AGENTS.md, CLAUDE.md: new at repo root. - md/summary.md: add style block. - md/design/01-config.md: rewrite, 184 → 75 lines. - md/design/02-github-client.md: rewrite, 285 → 94 lines; remove the v2-scope appendix. Co-authored-by: Claude <claude@anthropic.com>
Describes the three-query strategy for github/projects.rs (metadata, items, sub-issue overflow), the typed FieldValue enum with #[serde(other)] Unknown for forward-compat, and ItemContent carrying Issue / PullRequest / DraftIssue / Redacted unfiltered through the transport layer. - md/design/project-fetch.md: new. - md/summary.md: repoint design TOC at the three docs that exist. - fix naming of the md files Co-authored-by: Claude <claude@anthropic.com>
mdbook serve was failing on the additional-css reference because the theme directory does not exist. fix: mdbook path failures due to inconcistency in the naming convention in the summary.md file git ignore the generated book directory by the mdbook
Define the typed response shapes for the items half of the project-fetch query: FieldValue (Text, Number, SingleSelect, Date, Iteration, plus an Unknown variant for forward-compat), ItemContent (Issue, PullRequest, DraftIssue, plus Redacted for null content or unrecognized __typename), and the supporting struct types (ProjectItem, IssueContent, PullRequestContent, DraftIssueContent, SubIssueRef, NodeList). Includes serde fixture tests for every typed FieldValue and ItemContent variant, the Unknown / Redacted forward-compat paths, and a full ProjectItem round-trip. Co-authored-by: Claude <claude@anthropic.com>
Co-Authored-By: Claude <claude@anthropic.com>
node-model and edge-convention cover the graph layer that slice 2 will build: node identity, label format with auto repo prefix, cluster derivation from a SingleSelect field, ghost nodes for off-board endpoints, and deterministic node and edge sort. Edge sources are GitHub-native only — sub-issue, blocking, and cross-reference — with on-board endpoint filter and an optional source-issue label filter on cross-refs. Blocking and cross-refs both come from github/issues.rs in a later slice. project-fetch tightened. fetch_project now takes &Config and validates against ProjectMeta after the metadata query, before the items query, so a misconfigured field name fails fast on one cheap call instead of after the full paginated fetch. Sub-issue overflow is resolved eagerly inside fetch — graph layer receives complete sub-issue lists, never pagination state. Errors gain a ConfigMismatch variant. Co-authored-by: Claude <claude@anthropic.com>
Labels move to slice 2 — github/issues.rs fetches them alongside blocking and cross-references, where the cross-ref label filter needs them. Slice 1 doesn't render labels, so carrying LabelRef on IssueContent and PullRequestContent is dead weight. createdAt on DraftIssueContent gives drafts a deterministic sort key. Issues and pull requests sort by (repository, number); drafts have no number, so the sort tail is (created_at, id) per the node-model determinism rule. Co-authored-by: Claude <claude@anthropic.com>
Probes organization(login) and user(login) in a single GraphQL
document — at most one branch is non-null since GitHub's account
namespaces are disjoint — and returns ProjectMeta carrying the
detected owner_kind for downstream queries to reuse. Saves one
round-trip on user-owned projects compared to a sequential
org-then-user fallback.
Three project field shapes ride through one flat RawProjectField
(typename + dataType + options + configuration) and collapse to
the typed ProjectField + FieldKind in code, keeping the Unknown
variant cheap and forward-compatible with future GitHub field
kinds. Iteration fields carry their iteration list fully modeled
(id, title, startDate, duration), not stubbed.
Two new error variants: OwnerUnreachable when both probes return
null (nonexistent or token-private owner — GitHub returns null in
both cases, so we don't pretend to distinguish them); ProjectNotFound
{ owner_kind } when the owner resolves but the project number does
not, so the message can say "organization X has no project #N"
rather than a generic not-found.
Tests: unit fixtures cover RawProjectField → FieldKind routing for
each typename and the dataType sub-cases. Integration tests against
MockGitHub cover both owner kinds, the both-null path, the
project-null path on each owner kind, and the mixed-FieldKind
deserialization end-to-end.
Co-authored-by: Claude <claude@anthropic.com>
Replace the project_meta_fixture() helper with inlined JSON to keep each test readable top-to-bottom. project-fetch.md now records that metadata fetch probes organization and user in one GraphQL document.
fetch_project_items pages the project items connection at first:100, stitches the pages, and returns a flat Vec<ProjectItem>. Sub-issues ride along inline at first:50. resolve_sub_issue_overflow walks the items, finds issues whose inline sub-issue connection reports has_next_page, and follows up with the per-issue overflow query at first:100 until the list is complete. Sets has_next_page false on every resolved issue so the graph layer can rely on nodes being the full list. IssueContent.sub_issues changes from NodeList<SubIssueRef> to Connection<SubIssueRef> to expose the overflow flag during fetch; existing tests updated for the new shape. Co-authored-by: Claude <claude@anthropic.com>
fetch_project sequences metadata fetch, Config::validate_against,
items fetch, and sub-issue overflow resolution into one async call
returning ProjectFetch { meta, items }. Validation runs after the
cheap metadata query and before the paginated items query, so a typo
in .skill-tree.toml fails fast on one round-trip.
Config::validate_against walks every applicable rule, accumulating
mismatches into Vec<ConfigIssue>. A missing colors.github-name, an
option value that isn't on the SingleSelect, and a [[field]]
github-name that doesn't exist on the project surface together
instead of one at a time. GitHubError::ConfigMismatch carries the
vec and renders one line per issue.
Project numbers widen from u32 to u64 throughout the metadata path
to match the existing GithubConfig.project field type.
Co-authored-by: Claude <claude@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds GitHub Projects V2 fetching to skill-tree.
Changes:
Tests: