Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | 23x 23x 23x 23x 23x 23x 23x 23x 6x 6x 3x 3x 1x 2x 1x 1x 1x | /**
* Project and group search for choosing a working scope in the settings panel. It reads
* only what the account can already see in GitLab and returns paths and names, nothing
* else of the projects.
*/
import { gitlab } from '../../utils/gitlab-api';
import { GITLAB_ALLOWED_PROJECT_IDS } from '../../config';
import { findOperatorProjectTargets } from '../../configuration/operator-projects';
export const SCOPE_SEARCH_TOOL = 'find_scope_targets';
/** Results of one kind; projects and groups are listed together. */
const PER_KIND = 10;
export interface ScopeTarget {
type: 'project' | 'group';
/** Full path, as the scope setting takes it. */
path: string;
/** Display name with its namespace. */
name: string;
}
export const SCOPE_SEARCH_INPUT_SCHEMA = {
type: 'object' as const,
properties: {
query: {
type: 'string',
minLength: 2,
maxLength: 100,
description: 'Part of a project or group name or path.',
},
},
required: ['query'],
additionalProperties: false,
};
export const SCOPE_SEARCH_OUTPUT_SCHEMA = {
type: 'object' as const,
properties: {
targets: {
type: 'array',
items: {
type: 'object',
properties: {
type: { type: 'string', enum: ['project', 'group'] },
path: { type: 'string' },
name: { type: 'string' },
},
required: ['type', 'path', 'name'],
additionalProperties: false,
},
},
},
required: ['targets'],
additionalProperties: false,
};
interface GitLabProject {
path_with_namespace: string;
name_with_namespace: string;
}
interface GitLabGroup {
full_path: string;
full_name: string;
}
/** Projects the account is a member of and groups it can see, matching the query. */
export async function findScopeTargets(query: string): Promise<{ targets: ScopeTarget[] }> {
const search = query.trim();
if (search.length < 2 || search.length > 100) {
throw new Error('Search for 2 to 100 characters');
}
if (GITLAB_ALLOWED_PROJECT_IDS.length > 0) {
return { targets: await findOperatorProjectTargets(search) };
}
const [projects, groups] = await Promise.all([
gitlab.get<GitLabProject[]>('projects', {
query: {
search,
membership: 'true',
simple: 'true',
per_page: String(PER_KIND),
order_by: 'last_activity_at',
},
}),
// A non-administrator is listed only its member groups unless all_available is set.
gitlab.get<GitLabGroup[]>('groups', {
query: { search, all_available: 'true', per_page: String(PER_KIND) },
}),
]);
return {
targets: [
...groups.map((g) => ({ type: 'group' as const, path: g.full_path, name: g.full_name })),
...projects.map((p) => ({
type: 'project' as const,
path: p.path_with_namespace,
name: p.name_with_namespace,
})),
],
};
}
|