A collection of GitHub adapters and an HTTP API for reading and writing GitHub issues and repository files, built on Val Town.
This page is served at the root of the app (Try the app):
GET / renders this README as markdown.
The API lives at backend/index.tsx (Hono) and is served at
https://github-api-demo.val.run/.
Returns open GitHub issues for a repository that are tagged with the public label.
No authentication required.
| Query param | Type | Required | Description |
|---|---|---|---|
owner | string | yes | Repository owner (user or org) |
repo | string | yes | Repository name |
Behavior:
- Fetches up to 50 open issues, sorted by last updated (descending).
- Only returns issues carrying the
publiclabel. - Filters out pull requests (GitHub folds PRs into the issues endpoint).
- Returns the raw GitHub issue JSON array.
Example:
curl 'https://github-api-demo.val.run/api/public/issues?owner=oguzhanogreden&repo=notes'
Errors: 400 when owner/repo are missing, 500 when the GitHub fetch fails.
Creates or updates a file in a GitHub repository, wrapping its content in YAML frontmatter (createdAt / updatedAt / source / llm metadata, plus any extra keys).
Authentication: requires a GitHub-Token header carrying a GitHub token with write
access to the target repo. Returns 401 if the header is missing.
JSON body fields:
| Field | Type | Required | Description |
|---|---|---|---|
path | string | yes | Repo path of the file to create/update |
commitMessage | string | yes | Message for the commit |
source | { url: string } | yes | The originating GitHub issue URL, etc. |
llm | object | yes | Structured LLM payload (see below) |
repoOwner | string | no | Defaults to oguzhanogreden |
repoName | string | no | Defaults to notes |
branch | string | no | Defaults to main |
frontmatter | object | no | Extra keys merged into the YAML frontmatter |
llm payload:
| Field | Type | Description |
|---|---|---|
model | string | e.g. gpt-4.1-mini |
content | string | Markdown/text body to write to the file |
tokens | number | Optional total token count |
temperature | number | Optional sampling temperature |
promptHash | string | Optional hash/id of the exact prompt |
extras | object | Optional model-specific fields |
If the file already exists it is overwritten (new sha); otherwise it is created.
Example:
curl -X POST 'https://github-api-demo.val.run/api/files/create-or-update' \ -H 'Content-Type: application/json' \ -H 'GitHub-Token: <your-token>' \ -d '{ "path": "notes/hello.md", "commitMessage": "Add hello note", "source": { "url": "https://github.com/oguzhanogreden/notes/issues/124" }, "llm": { "model": "gpt-4.1-mini", "content": "# Hello\n\nThanks!" } }'
The val also exports reusable TypeScript functions (import from
https://esm.town/v/cricks_unmixed4u/github-api/api/index.tsx). Highlights:
getIssue({ issueNumber, repoOwner?, repoName? })— fetch a single issue.getIssueComments({ issueNumber, perPage?, ... })— async-generator over an issue's comments.readFileContent({ repoOwner, repoName, path })— read a raw file from a repo.getStalestGitHubIssues(options)/getGitHubIssuesUpdatedSinceLastRun(options)— issue monitors backed by SQLite.getIssueContentAsMarkdown(issueNumber, options)— render an issue + comments + extracted URLs as markdown.createOrUpdateFile(params)— the same logic behind thecreate-or-updateendpoint, callable directly.
All library functions require a GitHub token and repo identity, provided either via options
or the GITHUB_TOKEN, GITHUB_REPO_OWNER, and GITHUB_REPO_NAME environment variables
(see backend/create-or-update usage in main.tsx).