lv24-opencode-consilium 0.0.0-stage → 1.4.1

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.
Files changed (106) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +511 -3
  3. package/bin/cli.js +19 -0
  4. package/bin/mcp.js +24 -0
  5. package/consilium.config.example.json +84 -0
  6. package/dist/agents.d.ts +79 -0
  7. package/dist/agents.d.ts.map +1 -0
  8. package/dist/agents.js +1051 -0
  9. package/dist/agents.js.map +1 -0
  10. package/dist/artifacts.d.ts +75 -0
  11. package/dist/artifacts.d.ts.map +1 -0
  12. package/dist/artifacts.js +464 -0
  13. package/dist/artifacts.js.map +1 -0
  14. package/dist/cli.d.ts +12 -0
  15. package/dist/cli.d.ts.map +1 -0
  16. package/dist/cli.js +1392 -0
  17. package/dist/cli.js.map +1 -0
  18. package/dist/compat.d.ts +160 -0
  19. package/dist/compat.d.ts.map +1 -0
  20. package/dist/compat.js +419 -0
  21. package/dist/compat.js.map +1 -0
  22. package/dist/config.d.ts +112 -0
  23. package/dist/config.d.ts.map +1 -0
  24. package/dist/config.js +728 -0
  25. package/dist/config.js.map +1 -0
  26. package/dist/consensus.d.ts +73 -0
  27. package/dist/consensus.d.ts.map +1 -0
  28. package/dist/consensus.js +273 -0
  29. package/dist/consensus.js.map +1 -0
  30. package/dist/defaults.d.ts +34 -0
  31. package/dist/defaults.d.ts.map +1 -0
  32. package/dist/defaults.js +102 -0
  33. package/dist/defaults.js.map +1 -0
  34. package/dist/doctor.d.ts +27 -0
  35. package/dist/doctor.d.ts.map +1 -0
  36. package/dist/doctor.js +798 -0
  37. package/dist/doctor.js.map +1 -0
  38. package/dist/fallback.d.ts +50 -0
  39. package/dist/fallback.d.ts.map +1 -0
  40. package/dist/fallback.js +134 -0
  41. package/dist/fallback.js.map +1 -0
  42. package/dist/git.d.ts +28 -0
  43. package/dist/git.d.ts.map +1 -0
  44. package/dist/git.js +71 -0
  45. package/dist/git.js.map +1 -0
  46. package/dist/index.d.ts +100 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +653 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/mcp.d.ts +20 -0
  51. package/dist/mcp.d.ts.map +1 -0
  52. package/dist/mcp.js +1215 -0
  53. package/dist/mcp.js.map +1 -0
  54. package/dist/models.d.ts +97 -0
  55. package/dist/models.d.ts.map +1 -0
  56. package/dist/models.js +873 -0
  57. package/dist/models.js.map +1 -0
  58. package/dist/plugin.d.ts +59 -0
  59. package/dist/plugin.d.ts.map +1 -0
  60. package/dist/plugin.js +223 -0
  61. package/dist/plugin.js.map +1 -0
  62. package/dist/presets.d.ts +27 -0
  63. package/dist/presets.d.ts.map +1 -0
  64. package/dist/presets.js +86 -0
  65. package/dist/presets.js.map +1 -0
  66. package/dist/replay.d.ts +37 -0
  67. package/dist/replay.d.ts.map +1 -0
  68. package/dist/replay.js +103 -0
  69. package/dist/replay.js.map +1 -0
  70. package/dist/report.d.ts +28 -0
  71. package/dist/report.d.ts.map +1 -0
  72. package/dist/report.js +300 -0
  73. package/dist/report.js.map +1 -0
  74. package/dist/smart-experts.d.ts +44 -0
  75. package/dist/smart-experts.d.ts.map +1 -0
  76. package/dist/smart-experts.js +242 -0
  77. package/dist/smart-experts.js.map +1 -0
  78. package/dist/stream.d.ts +50 -0
  79. package/dist/stream.d.ts.map +1 -0
  80. package/dist/stream.js +219 -0
  81. package/dist/stream.js.map +1 -0
  82. package/dist/tool-run.d.ts +49 -0
  83. package/dist/tool-run.d.ts.map +1 -0
  84. package/dist/tool-run.js +143 -0
  85. package/dist/tool-run.js.map +1 -0
  86. package/dist/types.d.ts +352 -0
  87. package/dist/types.d.ts.map +1 -0
  88. package/dist/types.js +6 -0
  89. package/dist/types.js.map +1 -0
  90. package/dist/variants.d.ts +30 -0
  91. package/dist/variants.d.ts.map +1 -0
  92. package/dist/variants.js +111 -0
  93. package/dist/variants.js.map +1 -0
  94. package/dist/verify.d.ts +33 -0
  95. package/dist/verify.d.ts.map +1 -0
  96. package/dist/verify.js +80 -0
  97. package/dist/verify.js.map +1 -0
  98. package/dist/watch.d.ts +73 -0
  99. package/dist/watch.d.ts.map +1 -0
  100. package/dist/watch.js +350 -0
  101. package/dist/watch.js.map +1 -0
  102. package/docs/README.ru.md +508 -0
  103. package/docs/README.zh.md +196 -0
  104. package/docs/session-and-plugin.md +642 -0
  105. package/package.json +88 -6
  106. package/schema/config.schema.json +100 -0
@@ -0,0 +1,242 @@
1
+ /**
2
+ * @fileoverview Умный выбор экспертов консилиума по тексту задачи и диффу.
3
+ * @module lv24-opencode-consilium/smart-experts
4
+ */
5
+ /**
6
+ * Ключевые слова ролей (RU-основы + EN-термины) для скоринга задачи.
7
+ *
8
+ * Ключ `generic` — общий запасной лексикон для интеграторов;
9
+ * неизвестные имена экспертов всегда получают счёт 0 и не используют его.
10
+ */
11
+ export const ROLE_KEYWORDS = {
12
+ arch: [
13
+ 'архитектур',
14
+ 'слой',
15
+ 'модул',
16
+ 'масштаб',
17
+ 'миграц',
18
+ 'схем',
19
+ 'рефактор',
20
+ 'монолит',
21
+ 'микросервис',
22
+ 'зависимо',
23
+ 'структур',
24
+ 'проектир',
25
+ 'migration',
26
+ 'schema',
27
+ 'api',
28
+ 'refactor',
29
+ 'design',
30
+ 'monolith',
31
+ ],
32
+ ux: [
33
+ 'интерфейс',
34
+ 'пользов',
35
+ 'доступн',
36
+ 'экран',
37
+ 'форм',
38
+ 'кнопк',
39
+ 'макет',
40
+ 'дизайн',
41
+ 'верстк',
42
+ 'навигац',
43
+ 'ui',
44
+ 'ux',
45
+ 'layout',
46
+ 'screen',
47
+ 'button',
48
+ 'form',
49
+ 'a11y',
50
+ 'accessibility',
51
+ ],
52
+ ba: [
53
+ 'бизнес',
54
+ 'требован',
55
+ 'ценност',
56
+ 'процесс',
57
+ 'метрик',
58
+ 'выгод',
59
+ 'доход',
60
+ 'риск',
61
+ 'стейкхолдер',
62
+ 'заказчик',
63
+ 'приоритет',
64
+ 'тз',
65
+ 'cost',
66
+ 'stakeholder',
67
+ 'metric',
68
+ 'business',
69
+ 'requirement',
70
+ 'value',
71
+ ],
72
+ sec: [
73
+ 'безоп',
74
+ 'уязв',
75
+ 'инъекц',
76
+ 'секрет',
77
+ 'парол',
78
+ 'шифр',
79
+ 'аутентиф',
80
+ 'авторизац',
81
+ 'атак',
82
+ 'доступ',
83
+ 'xss',
84
+ 'csrf',
85
+ 'sqli',
86
+ 'sql',
87
+ 'auth',
88
+ 'permission',
89
+ 'injection',
90
+ 'secret',
91
+ 'password',
92
+ 'vulnerability',
93
+ ],
94
+ generic: [
95
+ 'код',
96
+ 'качеств',
97
+ 'ревью',
98
+ 'тест',
99
+ 'покрыт',
100
+ 'читаем',
101
+ 'стандарт',
102
+ 'практик',
103
+ 'code',
104
+ 'review',
105
+ 'quality',
106
+ 'test',
107
+ 'readability',
108
+ 'best',
109
+ ],
110
+ };
111
+ /**
112
+ * Экранирует строку для использования в регулярном выражении.
113
+ *
114
+ * @param value - Исходная строка.
115
+ * @returns Экранированная строка.
116
+ */
117
+ function escapeRegExp(value) {
118
+ return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
119
+ }
120
+ /**
121
+ * Проверяет, встречается ли ключевое слово в тексте.
122
+ *
123
+ * Латиница — приближённо по границам слов (не часть длинного слова),
124
+ * кириллические основы — подстрокой (стемминг усечением).
125
+ *
126
+ * @param haystack - Текст задачи в нижнем регистре.
127
+ * @param keyword - Ключевое слово в нижнем регистре.
128
+ * @returns true при совпадении.
129
+ */
130
+ function matchesKeyword(haystack, keyword) {
131
+ if (/^[a-z0-9]+$/.test(keyword)) {
132
+ const pattern = new RegExp(`(?:^|[^a-z0-9_])${escapeRegExp(keyword)}(?![a-z0-9_])`);
133
+ return pattern.test(haystack);
134
+ }
135
+ return haystack.includes(keyword);
136
+ }
137
+ /**
138
+ * Подсчитывает очки эксперта: число различных совпавших ключевых слов.
139
+ *
140
+ * @param haystack - Текст задачи (+ дифф) в нижнем регистре.
141
+ * @param keywords - Лексикон роли.
142
+ * @returns Счёт и список совпавших слов (в порядке лексикона).
143
+ */
144
+ function scoreKeywords(haystack, keywords) {
145
+ const matched = [];
146
+ for (const keyword of keywords) {
147
+ if (matchesKeyword(haystack, keyword.toLowerCase())) {
148
+ matched.push(keyword);
149
+ }
150
+ }
151
+ return { score: matched.length, matched };
152
+ }
153
+ /**
154
+ * Приводит опцию min/max к конечному целому >= 1.
155
+ *
156
+ * @param value - Значение опции.
157
+ * @param fallback - Значение по умолчанию.
158
+ * @returns Корректное целое число.
159
+ */
160
+ function toPositiveInt(value, fallback) {
161
+ if (typeof value !== 'number' || !Number.isFinite(value)) {
162
+ return fallback;
163
+ }
164
+ return Math.max(1, Math.floor(value));
165
+ }
166
+ /**
167
+ * Выбирает релевантных экспертов по тексту задачи и опциональному диффу.
168
+ *
169
+ * Учитывает только экспертов с `enabled !== false`, порядок вывода —
170
+ * исходный (приоритет уже применён вызывающей стороной).
171
+ * Неизвестные имена получают счёт 0 без причины.
172
+ * Входной массив и объекты экспертов не мутируются.
173
+ *
174
+ * @param experts - Кандидаты в исходном приоритетном порядке.
175
+ * @param task - Текст задачи.
176
+ * @param options - Лимиты совета и дифф (`max` по умолчанию 3, `min` — 2).
177
+ * @returns Выборка, отсеянные, очки и русские причины.
178
+ */
179
+ export function selectSmartExperts(experts, task, options) {
180
+ const haystack = `${task} ${options?.diff ?? ''}`.toLowerCase();
181
+ const enabled = [];
182
+ experts.forEach((expert, index) => {
183
+ if (expert.enabled !== false) {
184
+ enabled.push({ expert, index });
185
+ }
186
+ });
187
+ const scores = {};
188
+ const matchedBy = {};
189
+ for (const { expert } of enabled) {
190
+ const hasLexicon = Object.prototype.hasOwnProperty.call(ROLE_KEYWORDS, expert.name);
191
+ const lexicon = hasLexicon ? ROLE_KEYWORDS[expert.name] : undefined;
192
+ if (lexicon === undefined) {
193
+ scores[expert.name] = 0;
194
+ continue;
195
+ }
196
+ const { score, matched } = scoreKeywords(haystack, lexicon);
197
+ scores[expert.name] = score;
198
+ matchedBy[expert.name] = matched;
199
+ }
200
+ if (enabled.length === 0) {
201
+ return { experts: [], dropped: [], scores, reasons: {} };
202
+ }
203
+ const max = Math.min(toPositiveInt(options?.max, 3), enabled.length);
204
+ const min = Math.min(toPositiveInt(options?.min, 2), max);
205
+ // Сортировка по счёту (убыв.), затем по исходному индексу.
206
+ const ranked = [...enabled].sort((a, b) => (scores[b.expert.name] ?? 0) - (scores[a.expert.name] ?? 0) || a.index - b.index);
207
+ const positives = ranked.filter(({ expert }) => (scores[expert.name] ?? 0) > 0);
208
+ let picked;
209
+ if (positives.length === 0) {
210
+ // Все нули — держим первые min, чтобы совет не был пустым.
211
+ picked = ranked.slice(0, min);
212
+ }
213
+ else if (positives.length < min) {
214
+ // Положительных меньше min — не роняем ни одного из них, добираем нулями до min.
215
+ const zeroes = ranked.filter(({ expert }) => (scores[expert.name] ?? 0) === 0);
216
+ picked = [...positives, ...zeroes.slice(0, min - positives.length)];
217
+ }
218
+ else {
219
+ picked = ranked.slice(0, max);
220
+ }
221
+ // Возвращаем в исходном порядке.
222
+ picked.sort((a, b) => a.index - b.index);
223
+ const pickedIndexes = new Set(picked.map((item) => item.index));
224
+ const reasons = {};
225
+ for (const { expert } of picked) {
226
+ const matched = Object.prototype.hasOwnProperty.call(matchedBy, expert.name)
227
+ ? matchedBy[expert.name]
228
+ : [];
229
+ if (Array.isArray(matched) && matched.length > 0) {
230
+ reasons[expert.name] = `совпадения: ${matched.join(', ')}`;
231
+ }
232
+ }
233
+ return {
234
+ experts: picked.map((item) => item.expert),
235
+ dropped: enabled
236
+ .filter(({ index }) => !pickedIndexes.has(index))
237
+ .map(({ expert }) => expert.name),
238
+ scores,
239
+ reasons,
240
+ };
241
+ }
242
+ //# sourceMappingURL=smart-experts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smart-experts.js","sourceRoot":"","sources":["../src/smart-experts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @fileoverview Декодер NDJSON-потока OpenCode CLI
3
+ * @module lv24-opencode-consilium
4
+ */
5
+ import type { AgentUsage } from './types.js';
6
+ /** Структурированная ошибка из потока событий OpenCode */
7
+ export interface StreamError {
8
+ /** Тип ошибки OpenCode, например `provider.free-limit` */
9
+ type?: string;
10
+ /** Текст ошибки */
11
+ message: string;
12
+ /** HTTP-статус, если провайдер его вернул */
13
+ status?: number;
14
+ /** Задержка до повторной попытки, если OpenCode её сообщил */
15
+ retryAfterMs?: number;
16
+ /** Машинный код ошибки, если он есть */
17
+ code?: string;
18
+ }
19
+ /** Результат разбора потока событий */
20
+ export interface ParsedStream {
21
+ /** Собранный текст ответа */
22
+ text: string;
23
+ /** Сообщения об ошибках из потока */
24
+ errors: string[];
25
+ /** Структурированные ошибки из потока */
26
+ errorDetails: StreamError[];
27
+ /** Суммарный расход токенов и стоимость */
28
+ usage: AgentUsage;
29
+ /** Количество разобранных JSON-событий */
30
+ eventCount: number;
31
+ /** Идентификатор сессии OpenCode из событий */
32
+ sessionID?: string;
33
+ }
34
+ /** Буферизованный декодер событий */
35
+ export interface EventDecoder {
36
+ /** Добавляет очередной фрагмент потока */
37
+ push(chunk: string | Buffer): void;
38
+ /** Возвращает текущее состояние без завершения */
39
+ snapshot(): ParsedStream;
40
+ /** Завершает разбор (обрабатывает остаток буфера) */
41
+ end(): ParsedStream;
42
+ }
43
+ /**
44
+ * Создаёт декодер NDJSON-потока.
45
+ * Понимает события text, step_finish, error и message.part.updated.
46
+ */
47
+ export declare function createEventDecoder(): EventDecoder;
48
+ /** Разовый разбор JSON-вывода OpenCode CLI (обратная совместимость) */
49
+ export declare function parseJsonOutput(output: string): string;
50
+ //# sourceMappingURL=stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,0DAA0D;AAC1D,MAAM,WAAW,WAAW;IAC1B,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mBAAmB;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,uCAAuC;AACvC,MAAM,WAAW,YAAY;IAC3B,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,qCAAqC;IACrC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,yCAAyC;IACzC,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,2CAA2C;IAC3C,KAAK,EAAE,UAAU,CAAC;IAClB,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qCAAqC;AACrC,MAAM,WAAW,YAAY;IAC3B,0CAA0C;IAC1C,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACnC,kDAAkD;IAClD,QAAQ,IAAI,YAAY,CAAC;IACzB,qDAAqD;IACrD,GAAG,IAAI,YAAY,CAAC;CACrB;AA8BD;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,YAAY,CAgMjD;AAED,uEAAuE;AACvE,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAItD"}
package/dist/stream.js ADDED
@@ -0,0 +1,219 @@
1
+ /**
2
+ * @fileoverview Декодер NDJSON-потока OpenCode CLI
3
+ * @module lv24-opencode-consilium
4
+ */
5
+ import { StringDecoder } from 'string_decoder';
6
+ const MAX_ERRORS = 20;
7
+ const MAX_ERROR_LENGTH = 500;
8
+ function isRecord(value) {
9
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
10
+ }
11
+ function asString(value) {
12
+ return typeof value === 'string' ? value : undefined;
13
+ }
14
+ function asNumber(value) {
15
+ return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
16
+ }
17
+ function safeStringify(value) {
18
+ try {
19
+ return JSON.stringify(value) ?? '';
20
+ }
21
+ catch {
22
+ return '';
23
+ }
24
+ }
25
+ /**
26
+ * Создаёт декодер NDJSON-потока.
27
+ * Понимает события text, step_finish, error и message.part.updated.
28
+ */
29
+ export function createEventDecoder() {
30
+ let buffer = '';
31
+ let sawText = false;
32
+ let eventCount = 0;
33
+ let sessionID;
34
+ const segments = [];
35
+ const segmentIndex = new Map();
36
+ const errors = [];
37
+ const errorDetails = [];
38
+ const usage = {};
39
+ const stringDecoder = new StringDecoder('utf8');
40
+ function addError(message) {
41
+ if (errors.length >= MAX_ERRORS)
42
+ return;
43
+ errors.push(message.slice(0, MAX_ERROR_LENGTH));
44
+ }
45
+ function addErrorDetail(detail) {
46
+ if (errorDetails.length >= MAX_ERRORS)
47
+ return;
48
+ errorDetails.push({ ...detail, message: detail.message.slice(0, MAX_ERROR_LENGTH) });
49
+ }
50
+ function addUsage(field, value) {
51
+ if (value === undefined)
52
+ return;
53
+ const current = usage[field];
54
+ usage[field] = (typeof current === 'number' ? current : 0) + value;
55
+ }
56
+ function appendText(text) {
57
+ segments.push({ id: null, text });
58
+ sawText = true;
59
+ }
60
+ function storeTextById(id, text) {
61
+ const existing = segmentIndex.get(id);
62
+ if (existing !== undefined) {
63
+ segments[existing] = { id, text };
64
+ }
65
+ else {
66
+ segmentIndex.set(id, segments.length);
67
+ segments.push({ id, text });
68
+ }
69
+ sawText = true;
70
+ }
71
+ function handleStepFinish(part) {
72
+ const tokens = isRecord(part.tokens) ? part.tokens : undefined;
73
+ if (tokens) {
74
+ addUsage('inputTokens', asNumber(tokens.input));
75
+ addUsage('outputTokens', asNumber(tokens.output));
76
+ addUsage('reasoningTokens', asNumber(tokens.reasoning));
77
+ const cache = isRecord(tokens.cache) ? tokens.cache : undefined;
78
+ if (cache) {
79
+ addUsage('cacheReadTokens', asNumber(cache.read));
80
+ addUsage('cacheWriteTokens', asNumber(cache.write));
81
+ }
82
+ }
83
+ const cost = asNumber(part.cost);
84
+ if (cost !== undefined) {
85
+ usage.cost = (usage.cost ?? 0) + cost;
86
+ }
87
+ }
88
+ function handleEvent(event) {
89
+ if (!isRecord(event))
90
+ return;
91
+ eventCount += 1;
92
+ // OpenCode V2 может присылать полезную нагрузку в event.properties.
93
+ const envelope = isRecord(event.properties) ? event.properties : undefined;
94
+ const payload = envelope ?? event;
95
+ const type = asString(event.type) ?? asString(payload.type);
96
+ const eventSessionID = asString(event.sessionID) ?? asString(payload.sessionID);
97
+ if (eventSessionID !== undefined && sessionID === undefined) {
98
+ sessionID = eventSessionID;
99
+ }
100
+ const part = isRecord(payload.part)
101
+ ? payload.part
102
+ : isRecord(event.part)
103
+ ? event.part
104
+ : undefined;
105
+ if (type === 'text') {
106
+ const text = part ? asString(part.text) : undefined;
107
+ if (text !== undefined) {
108
+ appendText(text);
109
+ return;
110
+ }
111
+ const delta = part ? asString(part.delta) : undefined;
112
+ if (delta !== undefined)
113
+ appendText(delta);
114
+ return;
115
+ }
116
+ if (type === 'step_finish') {
117
+ if (part)
118
+ handleStepFinish(part);
119
+ return;
120
+ }
121
+ if (type === 'error') {
122
+ const errorPart = isRecord(payload.error)
123
+ ? payload.error
124
+ : isRecord(event.error)
125
+ ? event.error
126
+ : undefined;
127
+ const message = asString(errorPart?.message) ??
128
+ asString(part?.message) ??
129
+ safeStringify(event).slice(0, MAX_ERROR_LENGTH);
130
+ addError(message);
131
+ addErrorDetail({
132
+ type: asString(errorPart?.type),
133
+ message,
134
+ status: asNumber(errorPart?.status),
135
+ retryAfterMs: asNumber(errorPart?.retryAfterMs),
136
+ code: asString(errorPart?.code)
137
+ });
138
+ return;
139
+ }
140
+ if (type === 'message.part.updated') {
141
+ if (!part || asString(part.type) !== 'text')
142
+ return;
143
+ const text = asString(part.text);
144
+ const delta = asString(part.delta);
145
+ const id = asString(part.id);
146
+ if (text !== undefined) {
147
+ if (id !== undefined) {
148
+ storeTextById(id, text);
149
+ }
150
+ else {
151
+ appendText(text);
152
+ }
153
+ return;
154
+ }
155
+ if (delta !== undefined)
156
+ appendText(delta);
157
+ }
158
+ }
159
+ function processLine(rawLine) {
160
+ const line = rawLine.endsWith('\r') ? rawLine.slice(0, -1) : rawLine;
161
+ const trimmed = line.trim();
162
+ if (trimmed.length === 0)
163
+ return;
164
+ let event;
165
+ try {
166
+ event = JSON.parse(trimmed);
167
+ }
168
+ catch {
169
+ // Плейн-текст до первого текстового события сохраняем как ошибку
170
+ if (!sawText)
171
+ addError(trimmed);
172
+ return;
173
+ }
174
+ handleEvent(event);
175
+ }
176
+ function buildSnapshot() {
177
+ const snapshot = {
178
+ text: segments.map(segment => segment.text).join(''),
179
+ errors: [...errors],
180
+ errorDetails: errorDetails.map(detail => ({ ...detail })),
181
+ usage: { ...usage },
182
+ eventCount
183
+ };
184
+ if (sessionID !== undefined)
185
+ snapshot.sessionID = sessionID;
186
+ return snapshot;
187
+ }
188
+ return {
189
+ push(chunk) {
190
+ buffer += typeof chunk === 'string' ? chunk : stringDecoder.write(chunk);
191
+ let lineEnd = buffer.indexOf('\n');
192
+ while (lineEnd !== -1) {
193
+ const line = buffer.slice(0, lineEnd);
194
+ buffer = buffer.slice(lineEnd + 1);
195
+ processLine(line);
196
+ lineEnd = buffer.indexOf('\n');
197
+ }
198
+ },
199
+ snapshot() {
200
+ return buildSnapshot();
201
+ },
202
+ end() {
203
+ buffer += stringDecoder.end();
204
+ if (buffer.length > 0) {
205
+ const rest = buffer;
206
+ buffer = '';
207
+ processLine(rest);
208
+ }
209
+ return buildSnapshot();
210
+ }
211
+ };
212
+ }
213
+ /** Разовый разбор JSON-вывода OpenCode CLI (обратная совместимость) */
214
+ export function parseJsonOutput(output) {
215
+ const decoder = createEventDecoder();
216
+ decoder.push(output);
217
+ return decoder.end().text;
218
+ }
219
+ //# sourceMappingURL=stream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.js","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * @fileoverview Shared use-case for running the Consilium council as a tool.
3
+ * Used by the native OpenCode V2 plugin (and, later, other hosts).
4
+ * No MCP or `@opencode/plugin` imports here — pure library orchestration.
5
+ * @module lv24-opencode-consilium/tool-run
6
+ */
7
+ import type { ConsiliumConfig, ConsiliumResult } from './types.js';
8
+ /**
9
+ * Arguments accepted by {@link runConsiliumTool}.
10
+ */
11
+ export interface ToolRunArgs {
12
+ task: string;
13
+ experts?: string[];
14
+ chair?: string;
15
+ timeoutMs?: number;
16
+ consensus?: boolean;
17
+ smartExperts?: boolean;
18
+ maxCost?: number;
19
+ fallbackModels?: string[];
20
+ session?: string;
21
+ artifacts?: boolean | string;
22
+ preset?: string;
23
+ }
24
+ /**
25
+ * Totally ordered result of {@link runConsiliumTool}.
26
+ */
27
+ export interface ToolRunResult {
28
+ text: string;
29
+ isError: boolean;
30
+ metadata?: Record<string, unknown>;
31
+ }
32
+ /** Опции выполнения инструмента (отмена из хоста) */
33
+ export interface ToolRunOptions {
34
+ signal?: AbortSignal;
35
+ /** Рабочая директория активного проекта (OpenCode V2 передаёт её в ctx.location.directory) */
36
+ workspace?: string;
37
+ }
38
+ /**
39
+ * Formats a council result for chat display: chair text, expert opinions
40
+ * (truncated to 4000 chars each) and a JSON summary block.
41
+ */
42
+ export declare function formatToolResult(result: ConsiliumResult): string;
43
+ /**
44
+ * Runs the council with the given tool arguments.
45
+ * Throws on empty task or unknown preset; never catches run errors
46
+ * (the caller maps them to a visible tool result).
47
+ */
48
+ export declare function runConsiliumTool(args: ToolRunArgs, baseConfig?: ConsiliumConfig, options?: ToolRunOptions): Promise<ToolRunResult>;
49
+ //# sourceMappingURL=tool-run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-run.d.ts","sourceRoot":"","sources":["../src/tool-run.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAc,MAAM,YAAY,CAAC;AAe/E;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,qDAAqD;AACrD,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,8FAA8F;IAC9F,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAMD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAoDhE;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,WAAW,EACjB,UAAU,CAAC,EAAE,eAAe,EAC5B,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,aAAa,CAAC,CA+DxB"}