GitHub issues are intent: a feature request or bug report is
exactly the "why we built this" content that drives braid-extract.
Today intent sources are filesystem or MCP; this issue adds a third
option that pulls issues from a GitHub repo into a filesystem
layout the existing skills can already read.
Independent package, not bundled into
@braidhq/source-loader-git. The git loader clones repos; this
loader hits the REST API. Auth, config shape, and sync semantics
share almost no code. GitLab and Bitbucket equivalents will be
separate packages by the same logic; whether a shared base layer
is worth extracting will be obvious after three providers exist.
Scope
- New package
@braidhq/source-loader-github, plugin
kind: 'github'.
- Config:
{ owner, repo, state?, labels?, includeComments?, includePullRequests? }. Token via ${GH_TOKEN} env
interpolation, same pattern as source-loader-git.
ingest: REST GET /repos/:owner/:repo/issues, paginated; each
issue becomes <destination>/issues/<number>.md with
frontmatter (title, state, labels, author, createdAt,
updatedAt, url) + body + a ## Comments section.
sync: same call with since=<lastFetchedAt>. Output is
diff-stable: deterministic key order in frontmatter; comments
sorted by createdAt.
- Register the plugin in
composeFs.ts when GH_TOKEN is set,
mirroring the gdrive OAuth gating.
Out of scope
- GitLab / Bitbucket loaders.
- PR reviews / inline diff comments.
includePullRequests in v0
only adds title + body + top-level comments.
- Webhook ingest. Separate issue.
- Comment-thread reconstruction; flat list is fine for v0.
Acceptance
- Plugin unit test with stubbed
fetch: ingest produces N
markdown files for N fixture issues; frontmatter parses;
content matches.
sync with a since cursor only rewrites changed issues;
untouched files stay byte-identical between syncs.
- Dogfood: register this repo as a github source on a local
workspace; manually run /braid-extract on the synced issue
directory; resulting proposals look sensible.
Depends on: #27 — needs IntentExtractionLedger API frozen.
GitHub issues are intent: a feature request or bug report is
exactly the "why we built this" content that drives braid-extract.
Today intent sources are filesystem or MCP; this issue adds a third
option that pulls issues from a GitHub repo into a filesystem
layout the existing skills can already read.
Independent package, not bundled into
@braidhq/source-loader-git. The git loader clones repos; thisloader hits the REST API. Auth, config shape, and sync semantics
share almost no code. GitLab and Bitbucket equivalents will be
separate packages by the same logic; whether a shared base layer
is worth extracting will be obvious after three providers exist.
Scope
@braidhq/source-loader-github, pluginkind: 'github'.{ owner, repo, state?, labels?, includeComments?, includePullRequests? }. Token via${GH_TOKEN}envinterpolation, same pattern as
source-loader-git.ingest: RESTGET /repos/:owner/:repo/issues, paginated; eachissue becomes
<destination>/issues/<number>.mdwithfrontmatter (
title,state,labels,author,createdAt,updatedAt,url) + body + a## Commentssection.sync: same call withsince=<lastFetchedAt>. Output isdiff-stable: deterministic key order in frontmatter; comments
sorted by
createdAt.composeFs.tswhenGH_TOKENis set,mirroring the gdrive OAuth gating.
Out of scope
includePullRequestsin v0only adds title + body + top-level comments.
Acceptance
fetch: ingest produces Nmarkdown files for N fixture issues; frontmatter parses;
content matches.
syncwith asincecursor only rewrites changed issues;untouched files stay byte-identical between syncs.
workspace; manually run
/braid-extracton the synced issuedirectory; resulting proposals look sensible.
Depends on: #27 — needs
IntentExtractionLedgerAPI frozen.