@smwb/onreel-git-mcp 0.2.1 → 0.3.0

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.
@@ -1,3 +1,4 @@
1
+ import type { IssueCapabilities } from './tracker.types.ts';
1
2
  /** Потолок ожидания ответа внешнего трекера, мс. */
2
3
  export declare const TRACKER_TIMEOUT_MS = 15000;
3
4
  /** Размер страницы списка задач по умолчанию; потолок — 500 по контракту. */
@@ -8,3 +9,14 @@ export declare const TRACKER_ERROR_BODY_MAX = 300;
8
9
  export declare const TRACKER_SECRETS_FILE = "tracker-secrets.json";
9
10
  /** Автор комментариев, которые пользователь пишет в локальном трекере. */
10
11
  export declare const TRACKER_LOCAL_AUTHOR = "owner";
12
+ /** Фильтры списка задач — имена полей IssueQuery; порядок — для текстов отказов. */
13
+ export declare const ISSUE_FILTERS: readonly ['status', 'labels', 'assignee', 'author', 'search', 'createdAfter', 'createdBefore', 'updatedAfter', 'updatedBefore'];
14
+ export type IssueFilter = (typeof ISSUE_FILTERS)[number];
15
+ /** Поля сортировки задач единой модели. */
16
+ export declare const ISSUE_SORT_FIELDS: readonly ['created', 'updated', 'priority', 'title', 'comments'];
17
+ export type IssueSortField = (typeof ISSUE_SORT_FIELDS)[number];
18
+ /** Фильтры списка комментариев — имена полей CommentQuery. */
19
+ export declare const COMMENT_FILTERS: readonly ['updatedAfter'];
20
+ export type CommentFilter = (typeof COMMENT_FILTERS)[number];
21
+ /** Возможности трекера без раздела issues (свои трекеры потребителя): статус и страницы, комментарии по порядку. */
22
+ export declare const LEGACY_ISSUE_CAPABILITIES: IssueCapabilities;
@@ -1,5 +1,5 @@
1
1
  import type { IssuePriority, IssueStatusCategory } from '../contract/contract.types.ts';
2
- import type { TrackerFailure } from './tracker.types.ts';
2
+ import type { CommentCapabilities, CommentQuery, IssueCapabilities, ListCapabilities, ListSort, TrackerDefinition, TrackerFailure } from './tracker.types.ts';
3
3
  /** Отказ адаптера: потребитель превращает его в ошибку своего контракта (D-353). */
4
4
  export declare class TrackerError extends Error {
5
5
  readonly failure: TrackerFailure;
@@ -19,3 +19,28 @@ export declare function requireTarget(target: string | undefined, hint: string):
19
19
  /** Обратная таблица: категория → первое имя статуса трекера. */
20
20
  export declare function nameOf(table: Readonly<Record<string, IssueStatusCategory>>, category: IssueStatusCategory): string | undefined;
21
21
  export declare function priorityName(table: Readonly<Record<string, IssuePriority>>, priority: IssuePriority): string | undefined;
22
+ /** Фильтры запроса со значением (не undefined и не пустой массив), в порядке names. */
23
+ export declare function usedFilters<F extends string>(query: Readonly<Partial<Record<F, unknown>>>, names: readonly F[]): F[];
24
+ /**
25
+ * Проверка запроса списка по возможностям (D-004, R-002): фильтр со значением вне filters или sort.field вне sorts —
26
+ * TrackerError('unsupported', `${subject}: фильтр ${name} не поддерживается.`); значение не той формы — invalid_request:
27
+ * время не числом или не целое ≥ 0, пустая строка фильтра, список со строкой-пустышкой. subject — что за список:
28
+ * 'Задачи GitHub', 'PR GitLab', 'Прогоны CI SourceCraft'.
29
+ */
30
+ export declare function assertListQuery<F extends string, S extends string>(subject: string, capabilities: ListCapabilities<F, S>, query: Readonly<Partial<Record<F, unknown>>> & {
31
+ readonly sort?: ListSort<S> | undefined;
32
+ }, names: readonly F[]): void;
33
+ /** Проверка запроса комментариев: updatedAfter вне filters или order вне capabilities.order — unsupported. */
34
+ export declare function assertCommentQuery(subject: string, capabilities: CommentCapabilities, query: CommentQuery): void;
35
+ /** Возможности задач трекера: раздел issues или LEGACY_ISSUE_CAPABILITIES. */
36
+ export declare function issueCapabilitiesOf(definition: TrackerDefinition): IssueCapabilities;
37
+ /** Мс единой модели → ISO 8601 UTC для параметров трекера. */
38
+ export declare function isoTime(ms: number): string;
39
+ /** Время записи в границах [after, before] включительно; граница задана, а время неизвестно — не проходит. */
40
+ export declare function inTimeRange(value: number | undefined, after: number | undefined, before: number | undefined): boolean;
41
+ /** Есть ли needle (без учёта регистра) подстрокой в одном из текстов. */
42
+ export declare function containsText(texts: readonly (string | undefined)[], needle: string): boolean;
43
+ /** Значение в двойных кавычках для JQL, QL SourceCraft и q поиска GitHub: экранирует \ и ". */
44
+ export declare function quoted(value: string): string;
45
+ /** Ключи таблицы сопоставления, чьё значение — одна из категорий (обратный поиск для фильтров трекера). */
46
+ export declare function keysFor<T>(table: Readonly<Record<string, T>>, values: readonly T[]): string[];
@@ -1,5 +1,6 @@
1
1
  import type { Issue, IssueComment, IssuePriority, IssueStatusCategory, TrackerDescriptor } from '../contract/contract.types.ts';
2
2
  import type { LocalIssueStore } from '../kernel/store.types.ts';
3
+ import type { CommentFilter, IssueFilter, IssueSortField } from './tracker.const.ts';
3
4
  export type TrackerFetch = (input: string, init?: {
4
5
  method?: string;
5
6
  headers?: Record<string, string>;
@@ -26,8 +27,57 @@ export type PageQuery = {
26
27
  limit: number;
27
28
  cursor?: string | undefined;
28
29
  };
30
+ export type SortDirection = 'asc' | 'desc';
31
+ /**
32
+ * Сортировка списка; нет — прежний порядок трекера: GitHub, GitLab, Jira и локальный отдают новые первыми,
33
+ * у SourceCraft свой порядок по умолчанию (старые первыми). direction по умолчанию — desc.
34
+ */
35
+ export type ListSort<F extends string> = {
36
+ field: F;
37
+ direction?: SortDirection | undefined;
38
+ };
39
+ /**
40
+ * Возможности списка (D-004): filters — фильтры, которые адаптер применяет, фильтр вне них — отказ unsupported до запроса;
41
+ * clientSide — часть filters, которую адаптер проверяет по полученной странице: страница бывает короче limit и пустой
42
+ * при nextCursor; sorts — поля сортировки, пусто — только порядок трекера.
43
+ */
44
+ export type ListCapabilities<F extends string, S extends string> = {
45
+ filters: readonly F[];
46
+ clientSide: readonly F[];
47
+ sorts: readonly S[];
48
+ };
49
+ /** Возможности списка комментариев: фильтры и допустимые порядки, первый — порядок по умолчанию. */
50
+ export type CommentCapabilities = {
51
+ filters: readonly CommentFilter[];
52
+ clientSide: readonly CommentFilter[];
53
+ order: readonly SortDirection[];
54
+ };
55
+ export type IssueCapabilities = {
56
+ list: ListCapabilities<IssueFilter, IssueSortField>;
57
+ comments: CommentCapabilities;
58
+ };
29
59
  export type IssueQuery = PageQuery & {
30
60
  status?: readonly IssueStatusCategory[] | undefined;
61
+ /** Все перечисленные метки (И). */
62
+ labels?: readonly string[] | undefined;
63
+ /** Исполнитель — как в Issue.assignee; null — задачи без исполнителя. */
64
+ assignee?: string | null | undefined;
65
+ /** Автор задачи — логин или slug трекера. */
66
+ author?: string | undefined;
67
+ /** Поиск по тексту так, как ищет трекер (у SourceCraft — префикс заголовка, у локального — подстрока). */
68
+ search?: string | undefined;
69
+ /** Границы по времени включительно, мс Unix epoch. */
70
+ createdAfter?: number | undefined;
71
+ createdBefore?: number | undefined;
72
+ updatedAfter?: number | undefined;
73
+ updatedBefore?: number | undefined;
74
+ sort?: ListSort<IssueSortField> | undefined;
75
+ };
76
+ export type CommentQuery = PageQuery & {
77
+ /** Только комментарии, изменённые не раньше момента, мс. */
78
+ updatedAfter?: number | undefined;
79
+ /** Порядок по времени создания; по умолчанию asc — как было. */
80
+ order?: SortDirection | undefined;
31
81
  };
32
82
  export type TrackerPage<T> = {
33
83
  items: T[];
@@ -54,15 +104,17 @@ export type TrackerAdapter = {
54
104
  get(key: string): Promise<Issue>;
55
105
  create(input: NewIssueInput): Promise<Issue>;
56
106
  update(key: string, patch: IssuePatchInput): Promise<Issue>;
57
- comments(key: string, query: PageQuery): Promise<TrackerPage<IssueComment>>;
107
+ comments(key: string, query: CommentQuery): Promise<TrackerPage<IssueComment>>;
58
108
  comment(key: string, body: string): Promise<IssueComment>;
59
109
  };
60
110
  /** Подключаемый трекер: описание для интерфейса и фабрика адаптера (D-350). */
61
111
  export type TrackerDefinition = {
62
112
  descriptor: TrackerDescriptor;
63
113
  create(context: AdapterContext): TrackerAdapter;
114
+ /** Фильтры и сортировка задач и комментариев; нет — LEGACY_ISSUE_CAPABILITIES. */
115
+ issues?: IssueCapabilities | undefined;
64
116
  };
65
- export type TrackerFailure = 'failed' | 'unknown_issue' | 'invalid_request';
117
+ export type TrackerFailure = 'failed' | 'unknown_issue' | 'invalid_request' | 'not_found' | 'unsupported' | 'conflict' | 'rate_limited';
66
118
  export type JsonRequest = {
67
119
  fetch: TrackerFetch;
68
120
  method?: 'GET' | 'POST' | 'PUT' | 'PATCH';
@@ -70,6 +122,13 @@ export type JsonRequest = {
70
122
  body?: unknown;
71
123
  /** 404 — «нет такой задачи», а не «неверный адрес». */
72
124
  missingIsIssue?: boolean;
125
+ /** 404 — нет этой сущности (PR, прогон, задание): код и текст отказа. Важнее missingIsIssue. */
126
+ missing?: {
127
+ failure: TrackerFailure;
128
+ message: string;
129
+ } | undefined;
130
+ /** Статусы ответа «переход сейчас невозможен» (409 отмены, 405/409/422 слияния): отказ conflict. */
131
+ conflictOn?: readonly number[] | undefined;
73
132
  };
74
133
  export type JsonResponse = {
75
134
  body: unknown;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smwb/onreel-git-mcp",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Библиотека модулей, выделенных из onreel: git-операции и безопасные пути, список файлов worktree, жизненный цикл worktree против порта WorktreeStore, адаптеры трекеров GitHub/GitLab/Jira/SourceCraft/локального и MCP-сервер на stdio",
5
5
  "keywords": [
6
6
  "git",