Skip to content

Commit a92ed8e

Browse files
committed
Preserve inherited tool versions in generated integration docs
1 parent fe615b1 commit a92ed8e

5 files changed

Lines changed: 94 additions & 35 deletions

File tree

‎apps/docs/content/docs/integrations/github.mdx‎

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3414,6 +3414,46 @@ List users who have starred a repository
34143414
| ↳ `repos_url` | string | Repos API URL |
34153415
| `count` | number | Number of stargazers returned |
34163416

3417+
### GitHub List Review Threads
3418+
3419+
List one page of a pull request's review threads with their comments, plus the newest submitted review.
3420+
3421+
#### Input
3422+
3423+
| Parameter | Type | Required | Description |
3424+
| --------- | ---- | -------- | ----------- |
3425+
| `owner` | string | Yes | Repository owner |
3426+
| `repo` | string | Yes | Repository name |
3427+
| `pullNumber` | number | Yes | Pull request number |
3428+
| `threadsPerPage` | number | No | Review threads to fetch in this page \(1-100\) |
3429+
| `commentsPerThread` | number | No | Comments to fetch per thread \(1-100\) |
3430+
| `cursor` | string | No | Cursor from a previous page \(endCursor\) to continue from |
3431+
| `apiKey` | string | Yes | GitHub API token with pull request read access |
3432+
3433+
#### Output
3434+
3435+
| Parameter | Type | Description |
3436+
| --------- | ---- | ----------- |
3437+
| `threads` | array | Review threads in this page |
3438+
| ↳ `id` | string | Review thread node ID |
3439+
| ↳ `isResolved` | boolean | Whether the thread is resolved |
3440+
| ↳ `path` | string | Repository-relative file path |
3441+
| ↳ `line` | number | Line the thread is anchored to |
3442+
| ↳ `commentsTotalCount` | number | Total comments on the thread; exceeds the fetched count when the thread was truncated |
3443+
| ↳ `comments` | array | Fetched comments, oldest first |
3444+
| ↳ `body` | string | Comment body |
3445+
| ↳ `authorAssociation` | string | Author's association with the repository \(OWNER, MEMBER, ...\) |
3446+
| ↳ `authorLogin` | string | Author login |
3447+
| ↳ `authorType` | string | Author GraphQL type \(User, Bot, Organization\) |
3448+
| `totalCount` | number | Total review threads on the pull request |
3449+
| `hasNextPage` | boolean | Whether more thread pages remain |
3450+
| `endCursor` | string | Cursor to pass as `cursor` for the next page |
3451+
| `latestReview` | object | Newest submitted review on the pull request |
3452+
| ↳ `state` | string | Review state |
3453+
| ↳ `submittedAt` | string | Submission timestamp |
3454+
| ↳ `authorLogin` | string | Reviewer login |
3455+
| ↳ `authorType` | string | Reviewer GraphQL type \(User, Bot\) |
3456+
34173457

34183458

34193459
## Triggers

‎apps/docs/content/docs/integrations/gmail.mdx‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,21 @@ Remove label(s) from a Gmail message. Returns API-aligned fields only.
300300
| `threadId` | string | Gmail thread ID |
301301
| `labelIds` | array | Updated email labels |
302302

303+
### Gmail List Labels
304+
305+
List all labels in a Gmail account
306+
307+
#### Input
308+
309+
| Parameter | Type | Required | Description |
310+
| --------- | ---- | -------- | ----------- |
311+
312+
#### Output
313+
314+
| Parameter | Type | Description |
315+
| --------- | ---- | ----------- |
316+
| `labels` | json | Array of label objects with id, name, type, and visibility settings |
317+
303318

304319

305320
## Triggers

‎apps/docs/content/docs/integrations/greptile.mdx‎

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -53,35 +53,6 @@ Query repositories in natural language and get answers with relevant code refere
5353
| ↳ `summary` | string | Summary of the code section |
5454
| ↳ `distance` | number | Similarity score \(lower = more relevant\) |
5555

56-
### Greptile Search
57-
58-
Search repositories in natural language and get relevant code references without generating an answer. Useful for finding specific code locations.
59-
60-
#### Input
61-
62-
| Parameter | Type | Required | Description |
63-
| --------- | ---- | -------- | ----------- |
64-
| `query` | string | Yes | Natural language search query to find relevant code. Example: "authentication middleware" or "database connection handling" |
65-
| `repositories` | string | Yes | Comma-separated list of repositories. Format: "github:branch:owner/repo" or just "owner/repo" \(defaults to github:main\). Example: "facebook/react" or "github:main:facebook/react,github:main:facebook/relay" |
66-
| `sessionId` | string | No | Session ID for conversation continuity. Use the same sessionId across multiple searches to maintain context. Example: "session-abc123" |
67-
| `genius` | boolean | No | Enable genius mode for more thorough search \(slower but more accurate\) |
68-
| `apiKey` | string | Yes | Greptile API key |
69-
| `githubToken` | string | Yes | GitHub Personal Access Token with repo read access |
70-
71-
#### Output
72-
73-
| Parameter | Type | Description |
74-
| --------- | ---- | ----------- |
75-
| `sources` | array | Relevant code references matching the search query |
76-
| ↳ `repository` | string | Repository name \(owner/repo\) |
77-
| ↳ `remote` | string | Git remote \(github/gitlab\) |
78-
| ↳ `branch` | string | Branch name |
79-
| ↳ `filepath` | string | Path to the file |
80-
| ↳ `linestart` | number | Starting line number |
81-
| ↳ `lineend` | number | Ending line number |
82-
| ↳ `summary` | string | Summary of the code section |
83-
| ↳ `distance` | number | Similarity score \(lower = more relevant\) |
84-
8556
### Greptile Index Repository
8657

8758
Submit a repository to be indexed by Greptile. Indexing must complete before the repository can be queried. Small repos take 3-5 minutes, larger ones can take over an hour.

‎scripts/generate-docs.test.ts‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,23 @@ describe('documentation editor icon metadata', () => {
5050
})
5151

5252
describe('documentation tool metadata', () => {
53+
it('preserves versioned inherited tools when the access array appends another operation', () => {
54+
const [block] = extractAllBlockConfigs(`
55+
export const ExampleBlock: BlockConfig = {
56+
type: 'example', name: 'Example', category: 'tools', hideFromToolbar: true,
57+
tools: { access: ['example_read', 'example_list'] },
58+
}
59+
export const ExampleV2Block: BlockConfig = {
60+
...ExampleBlock, type: 'example_v2', hideFromToolbar: false,
61+
tools: { access: [
62+
...(ExampleBlock.tools?.access || []).map((toolId) => \`\${toolId}_v2\`),
63+
'example_comments',
64+
] },
65+
}
66+
`)
67+
expect(block.tools?.access).toEqual(['example_read_v2', 'example_list_v2', 'example_comments'])
68+
})
69+
5370
it('preserves a satisfies block and replaces only the versioned download operation', () => {
5471
const [block] = extractAllBlockConfigs(`
5572
export const DownloadBlock = ({

‎scripts/generate-docs.ts‎

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2279,17 +2279,20 @@ function extractBlockConfigFromContent(
22792279
: ownOutputs
22802280
const toolsAccess = extractToolsAccessFromContent(blockContent)
22812281

2282-
// For tools.access, if not found directly, check if it's derived from base via map
2282+
/** Versioned mapped spreads retain their base tools alongside explicit additions. */
22832283
let finalToolsAccess = toolsAccess
2284-
if (toolsAccess.length === 0 && baseConfig?.tools?.access) {
2284+
if (baseConfig?.tools?.access) {
22852285
// Check if there's a map operation on base tools
22862286
// Pattern: access: (SomeBlock.tools?.access || []).map((toolId) => `${toolId}_v2`)
22872287
const mapMatch = blockContent.match(
2288-
/access\s*:\s*\(\s*\w+Block\.tools\?\.access\s*\|\|\s*\[\]\s*\)\.map\s*\(\s*\(\s*\w+\s*\)\s*=>\s*`\$\{\s*\w+\s*\}_v(\d+)`\s*\)/
2288+
/access\s*:\s*(?:\[\s*\.\.\.)?\(\s*\w+Block\.tools\?\.access\s*\|\|\s*\[\]\s*\)\.map\s*\(\s*\(\s*\w+\s*\)\s*=>\s*`\$\{\s*\w+\s*\}_v(\d+)`\s*\)/
22892289
)
22902290
if (mapMatch) {
22912291
const versionSuffix = `_v${mapMatch[1]}`
2292-
finalToolsAccess = baseConfig.tools.access.map((tool) => `${tool}${versionSuffix}`)
2292+
finalToolsAccess = [
2293+
...baseConfig.tools.access.map((tool) => `${tool}${versionSuffix}`),
2294+
...toolsAccess,
2295+
]
22932296
}
22942297
const replacement = blockContent.match(
22952298
/access\s*:\s*\w+Block\.tools\.access\.map\s*\(\s*\(\s*(\w+)\s*\)\s*=>\s*\1\s*===\s*['"]([^'"]+)['"]\s*\?\s*['"]([^'"]+)['"]\s*:\s*\1\s*\)/
@@ -2698,9 +2701,22 @@ function extractToolsAccessFromContent(content: string): string[] {
26982701
if (toolsEnd === -1) return []
26992702

27002703
const toolsContent = content.substring(toolsStart, toolsEnd)
2701-
const accessMatch = toolsContent.match(/access\s*:\s*\[\s*([^\]]+)\s*\]/)
2704+
const accessMatch = /access\s*:\s*\[/.exec(toolsContent)
27022705
if (!accessMatch) return []
2703-
return [...accessMatch[1].matchAll(/['"]([^'"]+)['"]/g)].map((m) => m[1])
2706+
const start = accessMatch.index + accessMatch[0].lastIndexOf('[')
2707+
const end = findMatchingClose(toolsContent, start, '[', ']')
2708+
if (end === -1) return []
2709+
const source = ts.createSourceFile(
2710+
'tool-access.ts',
2711+
`const access = ${toolsContent.slice(start, end)}`,
2712+
ts.ScriptTarget.Latest,
2713+
true
2714+
)
2715+
const statement = source.statements[0]
2716+
if (!statement || !ts.isVariableStatement(statement)) return []
2717+
const array = statement.declarationList.declarations[0]?.initializer
2718+
if (!array || !ts.isArrayLiteralExpression(array)) return []
2719+
return array.elements.flatMap((element) => (ts.isStringLiteral(element) ? [element.text] : []))
27042720
}
27052721

27062722
/**

0 commit comments

Comments
 (0)