@bendyline/gilde 0.1.19 → 0.1.21
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.
- package/authoring/chat-models/muse-glimmer-30b-q4.json +1 -1
- package/authoring/chat-models/nemotron3.5-lightning-30b-q4.json +134 -0
- package/authoring/chat-models/nemotron3.5-lightning-30b-q8.json +134 -0
- package/data/chat-models/de/deepseek-v4-flash-284b-mxfp4/manifest.json +3 -1
- package/data/chat-models/de/deepseek-v4-flash-284b-mxfp4/versions/1.0.0/manifest.json +3 -1
- package/data/chat-models/de/deepseek-v4-flash-284b-q2/manifest.json +3 -1
- package/data/chat-models/de/deepseek-v4-flash-284b-q2/versions/1.0.0/manifest.json +3 -1
- package/data/chat-models/de/deepseek-v4-flash-284b-q2/versions/1.1.0/manifest.json +3 -1
- package/data/chat-models/de/deepseek-v4-flash-284b-q2q4/manifest.json +3 -1
- package/data/chat-models/de/deepseek-v4-flash-284b-q2q4/versions/1.0.0/manifest.json +3 -1
- package/data/chat-models/de/deepseek-v4-flash-284b-q4/manifest.json +3 -1
- package/data/chat-models/de/deepseek-v4-flash-284b-q4/versions/1.0.0/manifest.json +3 -1
- package/data/chat-models/de/deepseek-v4-flash-284b-q4/versions/1.1.0/manifest.json +3 -1
- package/data/chat-models/gl/glm-5.2-754b-q2/manifest.json +3 -1
- package/data/chat-models/gl/glm-5.2-754b-q2/versions/1.0.0/manifest.json +3 -1
- package/data/chat-models/index.json +1 -1
- package/data/chat-models/mu/muse-glimmer-30b-q4/manifest.json +1 -1
- package/data/chat-models/ne/nemotron3.5-lightning-30b-q4/manifest.json +193 -0
- package/data/chat-models/ne/nemotron3.5-lightning-30b-q4/versions/1.0.0/manifest.json +74 -0
- package/data/chat-models/ne/nemotron3.5-lightning-30b-q8/manifest.json +208 -0
- package/data/chat-models/ne/nemotron3.5-lightning-30b-q8/versions/1.0.0/manifest.json +89 -0
- package/data/connector-types/gi/github-pulls/manifest.json +17 -0
- package/data/connector-types/gi/github-pulls/versions/1.0.0/manifest.json +37 -0
- package/data/connector-types/index.json +1 -1
- package/data/craftbook-templates/index.json +1 -1
- package/data/craftbook-templates/pu/pull-request-review/manifest.json +1 -1
- package/data/craftbook-templates/pu/pull-request-review/versions/1.3.0/craftbook.json +156 -0
- package/data/craftbook-templates/pu/pull-request-review/versions/1.3.0/test.json +172 -0
- package/package.json +1 -1
- package/schemas/chat-model-version.schema.json +10 -0
- package/schemas/craftbook-doc.schema.json +24 -0
- package/schemas/craftbook-template-version.schema.json +24 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"schemaVersion":1,"kind":"connector-type","count":10,"entries":[{"manifest":{"schemaVersion":1,"kind":"connector-type","id":"airtable-records","name":"Airtable Records","description":"Mirror an Airtable table into a searchable corpus — one file per record — via the Airtable API, hosted off-platform through a vendored Prismatic component. Captures the table's current rows each sync.","tags":["airtable","records","spectral"],"maintainer":{"name":"Gezel"},"version":"1.0.0","releasedAt":"2026-07-08T00:00:00Z","driver":"spectral","configSchema":{"type":"object","properties":{"baseId":{"type":"string","title":"Base ID"},"tableName":{"type":"string","title":"Table name"},"view":{"type":"string","title":"View (optional)"},"filterByFormula":{"type":"string","title":"Filter by formula (optional)"}},"required":["baseId","tableName"]},"secretShape":{"kind":"apikey","field":"apiKey"},"source":{"component":"airtable","action":"listRecords","connectionKey":"personalAccessToken","connectionInput":"airtableConnection","inputs":{"baseId":"$config.baseId","tableName":"$config.tableName","view":"$config.view","filterByFormula":"$config.filterByFormula"},"itemsPath":"$.data"},"normalize":{"kind":"mapping","map":{"id":"$.id","title":"$.fields.Name","timestamp":"$.createdTime","body":"$.fields","frontmatter":{"recordId":"$.id","createdTime":"$.createdTime"}}},"actions":[],"completeness":"mirror","notes":"Personal Access Token connection. Each sync re-fetches every row in the table (no incremental cursor); the writer is content-hash idempotent, so re-syncs are cheap and only changed rows rewrite. Deleted Airtable rows are not pruned from the corpus. `title` maps to the `Name` field (Airtable's usual primary column) and falls back to the record id when absent.","availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"connector-type","id":"mail-imap","name":"Email (IMAP)","description":"Mirror an IMAP mailbox into a normalized, searchable corpus of messages.","tags":["email","native"],"maintainer":{"name":"Gezel"},"version":"1.0.0","releasedAt":"2026-07-08T00:00:00Z","driver":"native","configSchema":{"type":"object","properties":{"address":{"type":"string","title":"Email address"},"provider":{"type":"string","const":"imap"},"syncFolders":{"type":"array","title":"Folders to sync","items":{"type":"string"}},"allowedRecipients":{"type":"array","title":"Allowed send recipients","items":{"type":"string"}},"allowedDomains":{"type":"array","title":"Allowed send domains","items":{"type":"string"}}},"required":["address"]},"secretShape":{"kind":"imap"},"source":{"adapterId":"mail-imap"},"normalize":{"kind":"native"},"actions":[{"name":"send","consentScope":"recipient-allowlist"}],"completeness":"mirror","availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"connector-type","id":"github-issues","name":"GitHub Issues","description":"Mirror recent issues from one GitHub repository into searchable project files. Public repositories work without sign-in; add a token for private repositories or higher rate limits.","tags":["github","issues","script"],"maintainer":{"name":"Gezel"},"version":"1.0.0","releasedAt":"2026-07-13T00:00:00Z","driver":"script","configSchema":{"type":"object","properties":{"owner":{"type":"string","title":"Repository owner"},"repository":{"type":"string","title":"Repository name"},"apiBaseUrl":{"type":"string","title":"API base URL (GitHub Enterprise only)"}},"required":["owner","repository"]},"secretShape":{"kind":"apikey","field":"token","label":"GitHub personal access token","required":false},"source":{"inlineFetch":"import { defineScript, gezel } from '@bendyline/gezel-sdk';\n\nexport const meta = defineScript({\n name: 'github-issues-fetch',\n description: 'Fetches a bounded, incremental window of GitHub repository issues.',\n inputs: {\n cursor: { type: 'json', description: 'Last successfully synced GitHub updated_at value.' },\n config: { type: 'json', description: 'Repository owner, name, and optional API base URL.', required: true },\n },\n outputs: {\n records: { type: 'array', description: 'GitHub issues ready for connector normalization.', itemType: 'object' },\n cursor: { type: 'string', description: 'Newest updated_at value processed.', nullable: true },\n },\n requires: ['network', 'credential:$credential'],\n} as const);\n\ntype Config = { owner?: unknown; repository?: unknown; apiBaseUrl?: unknown };\ntype Issue = Record<string, unknown> & { updated_at?: unknown; pull_request?: unknown };\nconst input = gezel.input as { cursor?: unknown; config?: Config };\nconst config = input.config ?? {};\nconst owner = typeof config.owner === 'string' ? config.owner.trim() : '';\nconst repository = typeof config.repository === 'string' ? config.repository.trim() : '';\nif (!owner || !repository) throw new Error('GitHub owner and repository are required.');\n\nconst apiBaseUrl =\n typeof config.apiBaseUrl === 'string' && config.apiBaseUrl.trim()\n ? config.apiBaseUrl.trim().replace(/\\/+$/, '')\n : 'https://api.github.com';\nlet apiOrigin: string;\ntry {\n const parsed = new URL(apiBaseUrl);\n if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') throw new Error('bad protocol');\n apiOrigin = parsed.origin;\n} catch {\n throw new Error('GitHub API base URL must be an absolute HTTP or HTTPS URL.');\n}\n\nconst params = new URLSearchParams({\n state: 'all',\n sort: 'updated',\n direction: typeof input.cursor === 'string' ? 'asc' : 'desc',\n per_page: '100',\n});\nif (typeof input.cursor === 'string' && input.cursor) params.set('since', input.cursor);\nlet nextUrl =\n apiBaseUrl + '/repos/' + encodeURIComponent(owner) + '/' + encodeURIComponent(repository) + '/issues?' + params;\nlet nextCursor = typeof input.cursor === 'string' ? input.cursor : null;\nconst records: Issue[] = [];\n\nfunction nextPage(link: string | undefined): string | null {\n if (!link) return null;\n for (const part of link.split(',')) {\n const match = part.match(/<([^>]+)>;\\s*rel=\"next\"/);\n if (match?.[1]) return match[1];\n }\n return null;\n}\n\nfor (let page = 0; page < 5 && nextUrl; page++) {\n const target = new URL(nextUrl);\n if (target.origin !== apiOrigin) throw new Error('GitHub pagination changed origin; refusing to forward the token.');\n const headers = {\n Accept: 'application/vnd.github+json',\n 'X-GitHub-Api-Version': '2022-11-28',\n 'User-Agent': 'Gezel-GitHub-Issues-Connector',\n };\n let response;\n try {\n response = await gezel.http.authed(target.toString(), {\n credential: '$credential',\n headers,\n });\n } catch (error) {\n if ((error as { code?: string }).code !== 'CREDENTIAL_MISSING') throw error;\n response = await gezel.http.request(target.toString(), { headers });\n }\n if (!response.ok) {\n throw new Error('GitHub issues request failed (' + response.status + '): ' + response.body.slice(0, 240));\n }\n const pageItems = JSON.parse(response.body) as unknown;\n if (!Array.isArray(pageItems)) throw new Error('GitHub returned a non-array issues response.');\n for (const raw of pageItems) {\n if (!raw || typeof raw !== 'object') continue;\n const issue = raw as Issue;\n const updatedAt = typeof issue.updated_at === 'string' ? issue.updated_at : '';\n if (updatedAt && (!nextCursor || updatedAt > nextCursor)) nextCursor = updatedAt;\n if (issue.pull_request) continue;\n const labels = Array.isArray(issue.labels)\n ? issue.labels\n .map((label) =>\n typeof label === 'string'\n ? label\n : label && typeof label === 'object'\n ? String((label as Record<string, unknown>).name ?? '')\n : '',\n )\n .filter(Boolean)\n : [];\n const assignees = Array.isArray(issue.assignees)\n ? issue.assignees\n .map((person) =>\n person && typeof person === 'object'\n ? String((person as Record<string, unknown>).login ?? '')\n : '',\n )\n .filter(Boolean)\n : [];\n records.push({\n ...issue,\n gezel_repository: owner + '/' + repository,\n gezel_labels: labels,\n gezel_assignees: assignees,\n });\n }\n const candidate = nextPage(response.headers.link);\n nextUrl = candidate && new URL(candidate).origin === apiOrigin ? candidate : '';\n}\n\ngezel.output({ records, cursor: nextCursor });\n","idPath":"$.id"},"normalize":{"kind":"mapping","map":{"id":"$.id","title":"$.title","group":"$.gezel_repository","timestamp":"$.updated_at","body":"$.body","frontmatter":{"number":"$.number","state":"$.state","stateReason":"$.state_reason","author":"$.user.login","assignees":"$.gezel_assignees","labels":"$.gezel_labels","milestone":"$.milestone.title","comments":"$.comments","url":"$.html_url","createdAt":"$.created_at","closedAt":"$.closed_at","locked":"$.locked"}}},"actions":[],"completeness":"window","notes":"Uses GitHub's REST list-repository-issues endpoint anonymously for public repositories, or with an optional personal access token for private repositories and higher rate limits. Pull requests are excluded because GitHub's Issues API returns both. The first sync captures up to 500 recently updated issues; later syncs resume from updated_at in oldest-first order so busy repositories catch up over multiple passes. Issue comments are represented by their count but comment bodies are not mirrored in this version.","availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"connector-type","id":"github-releases","name":"GitHub Releases","description":"Mirror GitHub release notes and uploaded release assets into local project files. Public repositories work anonymously; Gezel's GitHub sign-in or an optional token also enables private repositories and draft releases.","tags":["github","releases","artifacts","binaries","native"],"maintainer":{"name":"Gezel"},"version":"1.0.0","releasedAt":"2026-08-09T00:00:00Z","driver":"native","configSchema":{"type":"object","properties":{"owner":{"type":"string","title":"Repository owner"},"repository":{"type":"string","title":"Repository name"},"maxReleases":{"type":"integer","title":"Latest releases (blank = all)","minimum":1,"maximum":10000},"includeDrafts":{"type":"boolean","title":"Include draft releases when signed in","default":true},"includePrereleases":{"type":"boolean","title":"Include prereleases","default":true},"downloadAssets":{"type":"boolean","title":"Download uploaded release assets","default":true},"assetNamePattern":{"type":"string","title":"Asset filename globs (optional, comma-separated)"},"maxAssetSizeMb":{"type":"number","title":"Maximum asset size in MB (blank = unlimited)","exclusiveMinimum":0},"apiBaseUrl":{"type":"string","title":"GitHub Enterprise API base URL (optional)"}},"required":["owner","repository"]},"secretShape":{"kind":"apikey","field":"token","label":"GitHub token (optional; uses your GitHub sign-in)","required":false},"source":{"adapterId":"github-releases"},"normalize":{"kind":"native"},"actions":[],"completeness":"mirror","notes":"Lists releases through GitHub's REST API and stores one release-notes record per release. Uploaded assets are streamed to disk, checked against GitHub's size and sha256 digest when supplied, and published as file-backed connector attachments without buffering the entire asset in memory. Public repositories work anonymously. For github.com, a per-binding token wins, then Gezel's stored GitHub sign-in, GH_TOKEN/GITHUB_TOKEN, or a signed-in GitHub CLI. Users with push access receive draft releases from GitHub's list-releases endpoint. Optional filters bound the newest release count, prerelease/draft inclusion, asset filename globs, and per-asset size. GitHub-generated source archives are not release assets and are not downloaded.","availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"connector-type","id":"github-wiki","name":"GitHub Wiki","description":"Mirror a repository's wiki pages into searchable project files. Public wikis work anonymously; add a token for private repositories.","tags":["github","wiki","documentation","native"],"maintainer":{"name":"Gezel"},"version":"1.0.0","releasedAt":"2026-07-13T00:00:00Z","driver":"native","configSchema":{"type":"object","properties":{"owner":{"type":"string","title":"Repository owner"},"repository":{"type":"string","title":"Repository name"},"host":{"type":"string","title":"GitHub Enterprise host (optional)"}},"required":["owner","repository"]},"secretShape":{"kind":"apikey","field":"token","label":"GitHub personal access token","required":false},"source":{"adapterId":"github-wiki"},"normalize":{"kind":"native"},"actions":[],"completeness":"mirror","notes":"Uses GitHub's separate .wiki.git repository as a read-only transport. Public wikis clone anonymously. An optional personal access token enables private repository wikis. Supported textual wiki markup is mirrored and scanned as untrusted external content; binary files and Git history are not exposed. Changed pages are stored as immutable revisions. Deletions are not currently pruned from the local corpus.","availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"connector-type","id":"mail-gmail","name":"Gmail","description":"Mirror a Gmail mailbox into a normalized, searchable corpus of messages (OAuth).","tags":["email","native","oauth"],"maintainer":{"name":"Gezel"},"version":"1.0.0","releasedAt":"2026-07-08T00:00:00Z","driver":"native","configSchema":{"type":"object","properties":{"address":{"type":"string","title":"Email address"},"provider":{"type":"string","const":"gmail"},"syncFolders":{"type":"array","title":"Labels to sync","items":{"type":"string"}},"allowedRecipients":{"type":"array","title":"Allowed send recipients","items":{"type":"string"}},"allowedDomains":{"type":"array","title":"Allowed send domains","items":{"type":"string"}}},"required":["address"]},"secretShape":{"kind":"oauth2","authorizeUrl":"https://accounts.google.com/o/oauth2/v2/auth","tokenUrl":"https://oauth2.googleapis.com/token","scopes":"https://mail.google.com/","clientIdEnv":"GEZEL_GOOGLE_CLIENT_ID","clientSecretEnv":"GEZEL_GOOGLE_CLIENT_SECRET","authParams":{"access_type":"offline","prompt":"consent"}},"source":{"adapterId":"mail-gmail"},"normalize":{"kind":"native"},"actions":[{"name":"send","consentScope":"recipient-allowlist"}],"completeness":"mirror","availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"connector-type","id":"calendar-google","name":"Google Calendar","description":"Mirror Google Calendar events into a normalized, searchable corpus (OAuth). Pairs with Gmail for cross-corpus reports.","tags":["calendar","native","oauth"],"maintainer":{"name":"Gezel"},"version":"1.0.0","releasedAt":"2026-07-08T00:00:00Z","driver":"native","configSchema":{"type":"object","properties":{"calendars":{"type":"array","title":"Calendar IDs (blank = all)","items":{"type":"string"}}}},"secretShape":{"kind":"oauth2","authorizeUrl":"https://accounts.google.com/o/oauth2/v2/auth","tokenUrl":"https://oauth2.googleapis.com/token","scopes":"https://www.googleapis.com/auth/calendar.readonly","clientIdEnv":"GEZEL_GOOGLE_CLIENT_ID","clientSecretEnv":"GEZEL_GOOGLE_CLIENT_SECRET","authParams":{"access_type":"offline","prompt":"consent"}},"source":{"adapterId":"calendar-google"},"normalize":{"kind":"native"},"actions":[],"completeness":"mirror","availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"connector-type","id":"linear-issues","name":"Linear Issues","description":"Mirror recent Linear issues into a searchable corpus via Linear's MCP server. A rolling window of recent activity, not full history.","tags":["issues","mcp"],"maintainer":{"name":"Gezel"},"version":"1.0.0","releasedAt":"2026-07-08T00:00:00Z","driver":"mcp","configSchema":{"type":"object","properties":{}},"secretShape":{"kind":"apikey","field":"Authorization"},"source":{"server":{"kind":"http","transport":"streamable-http","url":"https://mcp.linear.app/mcp","headersFromSecret":{"Authorization":"Bearer $secret"}},"list":{"tool":"list_issues","cursorArg":"updatedAfter","itemsPath":"$.issues","idPath":"$.id","tsPath":"$.updatedAt"},"fetch":{"tool":"get_issue","idArg":"id"}},"normalize":{"kind":"mapping","map":{"id":"$.id","title":"$.title","group":"$.team.name","timestamp":"$.updatedAt","body":"$.description","frontmatter":{"identifier":"$.identifier","state":"$.state.name","assignee":"$.assignee.name","url":"$.url"}}},"actions":[],"completeness":"window","availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"connector-type","id":"mail-microsoft365","name":"Microsoft 365 Mail","description":"Mirror a Microsoft 365 (work/school) mailbox into a normalized, searchable corpus of messages (OAuth).","tags":["email","native","oauth"],"maintainer":{"name":"Gezel"},"version":"1.0.0","releasedAt":"2026-08-09T00:00:00Z","driver":"native","configSchema":{"type":"object","properties":{"address":{"type":"string","title":"Email address"},"provider":{"type":"string","const":"microsoft365"},"tenant":{"type":"string","const":"organizations"},"syncFolders":{"type":"array","title":"Folders to sync","items":{"type":"string"}},"allowedRecipients":{"type":"array","title":"Allowed send recipients","items":{"type":"string"}},"allowedDomains":{"type":"array","title":"Allowed send domains","items":{"type":"string"}}},"required":["address"]},"secretShape":{"kind":"oauth2","authorizeUrl":"https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize","tokenUrl":"https://login.microsoftonline.com/organizations/oauth2/v2.0/token","scopes":"offline_access https://graph.microsoft.com/Mail.Read https://graph.microsoft.com/Mail.Send","clientIdEnv":"GEZEL_MICROSOFT_CLIENT_ID"},"source":{"adapterId":"mail-microsoft365"},"normalize":{"kind":"native"},"actions":[{"name":"send","consentScope":"recipient-allowlist"}],"completeness":"mirror","notes":"Work/school accounts in the 'organizations' Azure AD tenant. Sending is deny-by-default: only recipients on the binding's allowed recipients/domains lists can be sent to, and night shift defers sends to the outbox for daytime approval.","availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"connector-type","id":"mail-outlook","name":"Outlook.com Mail","description":"Mirror a personal Outlook.com mailbox into a normalized, searchable corpus of messages (OAuth).","tags":["email","native","oauth"],"maintainer":{"name":"Gezel"},"version":"1.0.0","releasedAt":"2026-08-09T00:00:00Z","driver":"native","configSchema":{"type":"object","properties":{"address":{"type":"string","title":"Email address"},"provider":{"type":"string","const":"outlook"},"tenant":{"type":"string","const":"consumers"},"syncFolders":{"type":"array","title":"Folders to sync","items":{"type":"string"}},"allowedRecipients":{"type":"array","title":"Allowed send recipients","items":{"type":"string"}},"allowedDomains":{"type":"array","title":"Allowed send domains","items":{"type":"string"}}},"required":["address"]},"secretShape":{"kind":"oauth2","authorizeUrl":"https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize","tokenUrl":"https://login.microsoftonline.com/consumers/oauth2/v2.0/token","scopes":"offline_access https://graph.microsoft.com/Mail.Read https://graph.microsoft.com/Mail.Send","clientIdEnv":"GEZEL_MICROSOFT_CLIENT_ID"},"source":{"adapterId":"mail-outlook"},"normalize":{"kind":"native"},"actions":[{"name":"send","consentScope":"recipient-allowlist"}],"completeness":"mirror","notes":"Personal Outlook.com accounts in the 'consumers' tenant. Sending is deny-by-default: only recipients on the binding's allowed recipients/domains lists can be sent to, and night shift defers sends to the outbox for daytime approval.","availableVersions":["1.0.0"]}}]}
|
|
1
|
+
{"schemaVersion":1,"kind":"connector-type","count":11,"entries":[{"manifest":{"schemaVersion":1,"kind":"connector-type","id":"airtable-records","name":"Airtable Records","description":"Mirror an Airtable table into a searchable corpus — one file per record — via the Airtable API, hosted off-platform through a vendored Prismatic component. Captures the table's current rows each sync.","tags":["airtable","records","spectral"],"maintainer":{"name":"Gezel"},"version":"1.0.0","releasedAt":"2026-07-08T00:00:00Z","driver":"spectral","configSchema":{"type":"object","properties":{"baseId":{"type":"string","title":"Base ID"},"tableName":{"type":"string","title":"Table name"},"view":{"type":"string","title":"View (optional)"},"filterByFormula":{"type":"string","title":"Filter by formula (optional)"}},"required":["baseId","tableName"]},"secretShape":{"kind":"apikey","field":"apiKey"},"source":{"component":"airtable","action":"listRecords","connectionKey":"personalAccessToken","connectionInput":"airtableConnection","inputs":{"baseId":"$config.baseId","tableName":"$config.tableName","view":"$config.view","filterByFormula":"$config.filterByFormula"},"itemsPath":"$.data"},"normalize":{"kind":"mapping","map":{"id":"$.id","title":"$.fields.Name","timestamp":"$.createdTime","body":"$.fields","frontmatter":{"recordId":"$.id","createdTime":"$.createdTime"}}},"actions":[],"completeness":"mirror","notes":"Personal Access Token connection. Each sync re-fetches every row in the table (no incremental cursor); the writer is content-hash idempotent, so re-syncs are cheap and only changed rows rewrite. Deleted Airtable rows are not pruned from the corpus. `title` maps to the `Name` field (Airtable's usual primary column) and falls back to the record id when absent.","availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"connector-type","id":"mail-imap","name":"Email (IMAP)","description":"Mirror an IMAP mailbox into a normalized, searchable corpus of messages.","tags":["email","native"],"maintainer":{"name":"Gezel"},"version":"1.0.0","releasedAt":"2026-07-08T00:00:00Z","driver":"native","configSchema":{"type":"object","properties":{"address":{"type":"string","title":"Email address"},"provider":{"type":"string","const":"imap"},"syncFolders":{"type":"array","title":"Folders to sync","items":{"type":"string"}},"allowedRecipients":{"type":"array","title":"Allowed send recipients","items":{"type":"string"}},"allowedDomains":{"type":"array","title":"Allowed send domains","items":{"type":"string"}}},"required":["address"]},"secretShape":{"kind":"imap"},"source":{"adapterId":"mail-imap"},"normalize":{"kind":"native"},"actions":[{"name":"send","consentScope":"recipient-allowlist"}],"completeness":"mirror","availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"connector-type","id":"github-issues","name":"GitHub Issues","description":"Mirror recent issues from one GitHub repository into searchable project files. Public repositories work without sign-in; add a token for private repositories or higher rate limits.","tags":["github","issues","script"],"maintainer":{"name":"Gezel"},"version":"1.0.0","releasedAt":"2026-07-13T00:00:00Z","driver":"script","configSchema":{"type":"object","properties":{"owner":{"type":"string","title":"Repository owner"},"repository":{"type":"string","title":"Repository name"},"apiBaseUrl":{"type":"string","title":"API base URL (GitHub Enterprise only)"}},"required":["owner","repository"]},"secretShape":{"kind":"apikey","field":"token","label":"GitHub personal access token","required":false},"source":{"inlineFetch":"import { defineScript, gezel } from '@bendyline/gezel-sdk';\n\nexport const meta = defineScript({\n name: 'github-issues-fetch',\n description: 'Fetches a bounded, incremental window of GitHub repository issues.',\n inputs: {\n cursor: { type: 'json', description: 'Last successfully synced GitHub updated_at value.' },\n config: { type: 'json', description: 'Repository owner, name, and optional API base URL.', required: true },\n },\n outputs: {\n records: { type: 'array', description: 'GitHub issues ready for connector normalization.', itemType: 'object' },\n cursor: { type: 'string', description: 'Newest updated_at value processed.', nullable: true },\n },\n requires: ['network', 'credential:$credential'],\n} as const);\n\ntype Config = { owner?: unknown; repository?: unknown; apiBaseUrl?: unknown };\ntype Issue = Record<string, unknown> & { updated_at?: unknown; pull_request?: unknown };\nconst input = gezel.input as { cursor?: unknown; config?: Config };\nconst config = input.config ?? {};\nconst owner = typeof config.owner === 'string' ? config.owner.trim() : '';\nconst repository = typeof config.repository === 'string' ? config.repository.trim() : '';\nif (!owner || !repository) throw new Error('GitHub owner and repository are required.');\n\nconst apiBaseUrl =\n typeof config.apiBaseUrl === 'string' && config.apiBaseUrl.trim()\n ? config.apiBaseUrl.trim().replace(/\\/+$/, '')\n : 'https://api.github.com';\nlet apiOrigin: string;\ntry {\n const parsed = new URL(apiBaseUrl);\n if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') throw new Error('bad protocol');\n apiOrigin = parsed.origin;\n} catch {\n throw new Error('GitHub API base URL must be an absolute HTTP or HTTPS URL.');\n}\n\nconst params = new URLSearchParams({\n state: 'all',\n sort: 'updated',\n direction: typeof input.cursor === 'string' ? 'asc' : 'desc',\n per_page: '100',\n});\nif (typeof input.cursor === 'string' && input.cursor) params.set('since', input.cursor);\nlet nextUrl =\n apiBaseUrl + '/repos/' + encodeURIComponent(owner) + '/' + encodeURIComponent(repository) + '/issues?' + params;\nlet nextCursor = typeof input.cursor === 'string' ? input.cursor : null;\nconst records: Issue[] = [];\n\nfunction nextPage(link: string | undefined): string | null {\n if (!link) return null;\n for (const part of link.split(',')) {\n const match = part.match(/<([^>]+)>;\\s*rel=\"next\"/);\n if (match?.[1]) return match[1];\n }\n return null;\n}\n\nfor (let page = 0; page < 5 && nextUrl; page++) {\n const target = new URL(nextUrl);\n if (target.origin !== apiOrigin) throw new Error('GitHub pagination changed origin; refusing to forward the token.');\n const headers = {\n Accept: 'application/vnd.github+json',\n 'X-GitHub-Api-Version': '2022-11-28',\n 'User-Agent': 'Gezel-GitHub-Issues-Connector',\n };\n let response;\n try {\n response = await gezel.http.authed(target.toString(), {\n credential: '$credential',\n headers,\n });\n } catch (error) {\n if ((error as { code?: string }).code !== 'CREDENTIAL_MISSING') throw error;\n response = await gezel.http.request(target.toString(), { headers });\n }\n if (!response.ok) {\n throw new Error('GitHub issues request failed (' + response.status + '): ' + response.body.slice(0, 240));\n }\n const pageItems = JSON.parse(response.body) as unknown;\n if (!Array.isArray(pageItems)) throw new Error('GitHub returned a non-array issues response.');\n for (const raw of pageItems) {\n if (!raw || typeof raw !== 'object') continue;\n const issue = raw as Issue;\n const updatedAt = typeof issue.updated_at === 'string' ? issue.updated_at : '';\n if (updatedAt && (!nextCursor || updatedAt > nextCursor)) nextCursor = updatedAt;\n if (issue.pull_request) continue;\n const labels = Array.isArray(issue.labels)\n ? issue.labels\n .map((label) =>\n typeof label === 'string'\n ? label\n : label && typeof label === 'object'\n ? String((label as Record<string, unknown>).name ?? '')\n : '',\n )\n .filter(Boolean)\n : [];\n const assignees = Array.isArray(issue.assignees)\n ? issue.assignees\n .map((person) =>\n person && typeof person === 'object'\n ? String((person as Record<string, unknown>).login ?? '')\n : '',\n )\n .filter(Boolean)\n : [];\n records.push({\n ...issue,\n gezel_repository: owner + '/' + repository,\n gezel_labels: labels,\n gezel_assignees: assignees,\n });\n }\n const candidate = nextPage(response.headers.link);\n nextUrl = candidate && new URL(candidate).origin === apiOrigin ? candidate : '';\n}\n\ngezel.output({ records, cursor: nextCursor });\n","idPath":"$.id"},"normalize":{"kind":"mapping","map":{"id":"$.id","title":"$.title","group":"$.gezel_repository","timestamp":"$.updated_at","body":"$.body","frontmatter":{"number":"$.number","state":"$.state","stateReason":"$.state_reason","author":"$.user.login","assignees":"$.gezel_assignees","labels":"$.gezel_labels","milestone":"$.milestone.title","comments":"$.comments","url":"$.html_url","createdAt":"$.created_at","closedAt":"$.closed_at","locked":"$.locked"}}},"actions":[],"completeness":"window","notes":"Uses GitHub's REST list-repository-issues endpoint anonymously for public repositories, or with an optional personal access token for private repositories and higher rate limits. Pull requests are excluded because GitHub's Issues API returns both. The first sync captures up to 500 recently updated issues; later syncs resume from updated_at in oldest-first order so busy repositories catch up over multiple passes. Issue comments are represented by their count but comment bodies are not mirrored in this version.","availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"connector-type","id":"github-pulls","name":"GitHub Pull Requests","description":"Mirror a project's open pull requests into local files: a summary, one file per changed file with its patch, and the complete unified diff. Lets a gezel review a PR by reading the workspace instead of calling the GitHub API mid-turn.","tags":["github","pull-requests","code-review","diff","native"],"maintainer":{"name":"Gezel"},"version":"1.0.0","releasedAt":"2026-08-10T00:00:00Z","driver":"native","configSchema":{"type":"object","properties":{"maxPulls":{"type":"integer","title":"Open pull requests to mirror","minimum":1,"maximum":200,"default":20},"includeComments":{"type":"boolean","title":"Include review and issue comments","default":true}}},"secretShape":{"kind":"apikey","field":"token","label":"GitHub token (optional; uses your GitHub sign-in)","required":false},"source":{"adapterId":"github-pulls"},"normalize":{"kind":"native"},"actions":[],"completeness":"window","notes":"Takes the repository from the project's own GitHub link rather than binding config, so the coordinates cannot drift from the project. The corpus lives in the project's managed artifacts tree, so mirrored data never dirties the user's checkout. Each open pull request becomes one scope (`pr-<number>`) holding an overview record — title, author, branches, counts, description, and comment digest — plus one record per changed file under `files/` carrying that file's patch, and the complete unified diff as an attachment. Patches and the diff are stored untruncated because a gezel opens these as files. Comment and description text is untrusted and passes through the standard content scan and quarantine. Completeness is `window`: only the newest open pull requests are mirrored, so absence from the corpus does not mean absence upstream. A task launch can target one pull request directly, which syncs just that scope.","availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"connector-type","id":"github-releases","name":"GitHub Releases","description":"Mirror GitHub release notes and uploaded release assets into local project files. Public repositories work anonymously; Gezel's GitHub sign-in or an optional token also enables private repositories and draft releases.","tags":["github","releases","artifacts","binaries","native"],"maintainer":{"name":"Gezel"},"version":"1.0.0","releasedAt":"2026-08-09T00:00:00Z","driver":"native","configSchema":{"type":"object","properties":{"owner":{"type":"string","title":"Repository owner"},"repository":{"type":"string","title":"Repository name"},"maxReleases":{"type":"integer","title":"Latest releases (blank = all)","minimum":1,"maximum":10000},"includeDrafts":{"type":"boolean","title":"Include draft releases when signed in","default":true},"includePrereleases":{"type":"boolean","title":"Include prereleases","default":true},"downloadAssets":{"type":"boolean","title":"Download uploaded release assets","default":true},"assetNamePattern":{"type":"string","title":"Asset filename globs (optional, comma-separated)"},"maxAssetSizeMb":{"type":"number","title":"Maximum asset size in MB (blank = unlimited)","exclusiveMinimum":0},"apiBaseUrl":{"type":"string","title":"GitHub Enterprise API base URL (optional)"}},"required":["owner","repository"]},"secretShape":{"kind":"apikey","field":"token","label":"GitHub token (optional; uses your GitHub sign-in)","required":false},"source":{"adapterId":"github-releases"},"normalize":{"kind":"native"},"actions":[],"completeness":"mirror","notes":"Lists releases through GitHub's REST API and stores one release-notes record per release. Uploaded assets are streamed to disk, checked against GitHub's size and sha256 digest when supplied, and published as file-backed connector attachments without buffering the entire asset in memory. Public repositories work anonymously. For github.com, a per-binding token wins, then Gezel's stored GitHub sign-in, GH_TOKEN/GITHUB_TOKEN, or a signed-in GitHub CLI. Users with push access receive draft releases from GitHub's list-releases endpoint. Optional filters bound the newest release count, prerelease/draft inclusion, asset filename globs, and per-asset size. GitHub-generated source archives are not release assets and are not downloaded.","availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"connector-type","id":"github-wiki","name":"GitHub Wiki","description":"Mirror a repository's wiki pages into searchable project files. Public wikis work anonymously; add a token for private repositories.","tags":["github","wiki","documentation","native"],"maintainer":{"name":"Gezel"},"version":"1.0.0","releasedAt":"2026-07-13T00:00:00Z","driver":"native","configSchema":{"type":"object","properties":{"owner":{"type":"string","title":"Repository owner"},"repository":{"type":"string","title":"Repository name"},"host":{"type":"string","title":"GitHub Enterprise host (optional)"}},"required":["owner","repository"]},"secretShape":{"kind":"apikey","field":"token","label":"GitHub personal access token","required":false},"source":{"adapterId":"github-wiki"},"normalize":{"kind":"native"},"actions":[],"completeness":"mirror","notes":"Uses GitHub's separate .wiki.git repository as a read-only transport. Public wikis clone anonymously. An optional personal access token enables private repository wikis. Supported textual wiki markup is mirrored and scanned as untrusted external content; binary files and Git history are not exposed. Changed pages are stored as immutable revisions. Deletions are not currently pruned from the local corpus.","availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"connector-type","id":"mail-gmail","name":"Gmail","description":"Mirror a Gmail mailbox into a normalized, searchable corpus of messages (OAuth).","tags":["email","native","oauth"],"maintainer":{"name":"Gezel"},"version":"1.0.0","releasedAt":"2026-07-08T00:00:00Z","driver":"native","configSchema":{"type":"object","properties":{"address":{"type":"string","title":"Email address"},"provider":{"type":"string","const":"gmail"},"syncFolders":{"type":"array","title":"Labels to sync","items":{"type":"string"}},"allowedRecipients":{"type":"array","title":"Allowed send recipients","items":{"type":"string"}},"allowedDomains":{"type":"array","title":"Allowed send domains","items":{"type":"string"}}},"required":["address"]},"secretShape":{"kind":"oauth2","authorizeUrl":"https://accounts.google.com/o/oauth2/v2/auth","tokenUrl":"https://oauth2.googleapis.com/token","scopes":"https://mail.google.com/","clientIdEnv":"GEZEL_GOOGLE_CLIENT_ID","clientSecretEnv":"GEZEL_GOOGLE_CLIENT_SECRET","authParams":{"access_type":"offline","prompt":"consent"}},"source":{"adapterId":"mail-gmail"},"normalize":{"kind":"native"},"actions":[{"name":"send","consentScope":"recipient-allowlist"}],"completeness":"mirror","availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"connector-type","id":"calendar-google","name":"Google Calendar","description":"Mirror Google Calendar events into a normalized, searchable corpus (OAuth). Pairs with Gmail for cross-corpus reports.","tags":["calendar","native","oauth"],"maintainer":{"name":"Gezel"},"version":"1.0.0","releasedAt":"2026-07-08T00:00:00Z","driver":"native","configSchema":{"type":"object","properties":{"calendars":{"type":"array","title":"Calendar IDs (blank = all)","items":{"type":"string"}}}},"secretShape":{"kind":"oauth2","authorizeUrl":"https://accounts.google.com/o/oauth2/v2/auth","tokenUrl":"https://oauth2.googleapis.com/token","scopes":"https://www.googleapis.com/auth/calendar.readonly","clientIdEnv":"GEZEL_GOOGLE_CLIENT_ID","clientSecretEnv":"GEZEL_GOOGLE_CLIENT_SECRET","authParams":{"access_type":"offline","prompt":"consent"}},"source":{"adapterId":"calendar-google"},"normalize":{"kind":"native"},"actions":[],"completeness":"mirror","availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"connector-type","id":"linear-issues","name":"Linear Issues","description":"Mirror recent Linear issues into a searchable corpus via Linear's MCP server. A rolling window of recent activity, not full history.","tags":["issues","mcp"],"maintainer":{"name":"Gezel"},"version":"1.0.0","releasedAt":"2026-07-08T00:00:00Z","driver":"mcp","configSchema":{"type":"object","properties":{}},"secretShape":{"kind":"apikey","field":"Authorization"},"source":{"server":{"kind":"http","transport":"streamable-http","url":"https://mcp.linear.app/mcp","headersFromSecret":{"Authorization":"Bearer $secret"}},"list":{"tool":"list_issues","cursorArg":"updatedAfter","itemsPath":"$.issues","idPath":"$.id","tsPath":"$.updatedAt"},"fetch":{"tool":"get_issue","idArg":"id"}},"normalize":{"kind":"mapping","map":{"id":"$.id","title":"$.title","group":"$.team.name","timestamp":"$.updatedAt","body":"$.description","frontmatter":{"identifier":"$.identifier","state":"$.state.name","assignee":"$.assignee.name","url":"$.url"}}},"actions":[],"completeness":"window","availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"connector-type","id":"mail-microsoft365","name":"Microsoft 365 Mail","description":"Mirror a Microsoft 365 (work/school) mailbox into a normalized, searchable corpus of messages (OAuth).","tags":["email","native","oauth"],"maintainer":{"name":"Gezel"},"version":"1.0.0","releasedAt":"2026-08-09T00:00:00Z","driver":"native","configSchema":{"type":"object","properties":{"address":{"type":"string","title":"Email address"},"provider":{"type":"string","const":"microsoft365"},"tenant":{"type":"string","const":"organizations"},"syncFolders":{"type":"array","title":"Folders to sync","items":{"type":"string"}},"allowedRecipients":{"type":"array","title":"Allowed send recipients","items":{"type":"string"}},"allowedDomains":{"type":"array","title":"Allowed send domains","items":{"type":"string"}}},"required":["address"]},"secretShape":{"kind":"oauth2","authorizeUrl":"https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize","tokenUrl":"https://login.microsoftonline.com/organizations/oauth2/v2.0/token","scopes":"offline_access https://graph.microsoft.com/Mail.Read https://graph.microsoft.com/Mail.Send","clientIdEnv":"GEZEL_MICROSOFT_CLIENT_ID"},"source":{"adapterId":"mail-microsoft365"},"normalize":{"kind":"native"},"actions":[{"name":"send","consentScope":"recipient-allowlist"}],"completeness":"mirror","notes":"Work/school accounts in the 'organizations' Azure AD tenant. Sending is deny-by-default: only recipients on the binding's allowed recipients/domains lists can be sent to, and night shift defers sends to the outbox for daytime approval.","availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"connector-type","id":"mail-outlook","name":"Outlook.com Mail","description":"Mirror a personal Outlook.com mailbox into a normalized, searchable corpus of messages (OAuth).","tags":["email","native","oauth"],"maintainer":{"name":"Gezel"},"version":"1.0.0","releasedAt":"2026-08-09T00:00:00Z","driver":"native","configSchema":{"type":"object","properties":{"address":{"type":"string","title":"Email address"},"provider":{"type":"string","const":"outlook"},"tenant":{"type":"string","const":"consumers"},"syncFolders":{"type":"array","title":"Folders to sync","items":{"type":"string"}},"allowedRecipients":{"type":"array","title":"Allowed send recipients","items":{"type":"string"}},"allowedDomains":{"type":"array","title":"Allowed send domains","items":{"type":"string"}}},"required":["address"]},"secretShape":{"kind":"oauth2","authorizeUrl":"https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize","tokenUrl":"https://login.microsoftonline.com/consumers/oauth2/v2.0/token","scopes":"offline_access https://graph.microsoft.com/Mail.Read https://graph.microsoft.com/Mail.Send","clientIdEnv":"GEZEL_MICROSOFT_CLIENT_ID"},"source":{"adapterId":"mail-outlook"},"normalize":{"kind":"native"},"actions":[{"name":"send","consentScope":"recipient-allowlist"}],"completeness":"mirror","notes":"Personal Outlook.com accounts in the 'consumers' tenant. Sending is deny-by-default: only recipients on the binding's allowed recipients/domains lists can be sent to, and night shift defers sends to the outbox for daytime approval.","availableVersions":["1.0.0"]}}]}
|