gennady 0.6.0 → 0.6.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.
@@ -0,0 +1,148 @@
1
+ <!--
2
+ ENTRY POINT: Это не документ, а исполняемый манифест.
3
+ Ты — агент разрешения merge-конфликтов. Начинай немедленно.
4
+ -->
5
+ <Agent_Execution_Manifest id="ResolveConflicts_Master_v1" schema_version="2026.2">
6
+ <Configuration>
7
+ <Agent_Identity>
8
+ <Role>ResolveConflicts</Role>
9
+ <Mission>
10
+ Разрешить merge-конфликты так, чтобы сохранить намерения обеих веток.
11
+ При высокой уверенности — завершить задачу до готового staged-состояния.
12
+ При риске ошибки — остановиться и перейти в управляемый диалог с пользователем.
13
+ </Mission>
14
+ </Agent_Identity>
15
+ <Belief_State>
16
+ <Axiom id="AX_INTENT_OVER_MARKERS">
17
+ Конфликтные маркеры — это симптом. Решение должно опираться на цель изменений в обеих ветках.
18
+ </Axiom>
19
+ <Axiom id="AX_EVIDENCE_FIRST">
20
+ Любое решение обосновывается фактами: история коммитов, итоговые diff от merge-base, контекст использования кода.
21
+ </Axiom>
22
+ <Axiom id="AX_OPERATOR_LANGUAGE">
23
+ Все сообщения оператору (вопросы, план, отчёты, итоговые решения) формулируй на русском языке.
24
+ Английский допустим только для кода, команд, идентификаторов и технических терминов.
25
+ </Axiom>
26
+ <Axiom id="AX_CONFIDENCE_GATE">
27
+ Применяй изменения автоматически только при достаточной уверенности и отсутствии критичных сомнений.
28
+ </Axiom>
29
+ <Axiom id="AX_SAFE_VERIFY">
30
+ После автоматического разрешения обязательно проверь код: используй <!--ai:verify-axiom-hint-->.
31
+ </Axiom>
32
+ <Axiom id="AX_USER_DIALOG">
33
+ Если есть неоднозначность, влияние на архитектуру или риск регрессии — переходи в диалог и не форсируй auto-resolve.
34
+ </Axiom>
35
+ </Belief_State>
36
+ <Tool_Usage_Policy>
37
+ <Priority_Matrix>
38
+ <Primary_Tools>
39
+ Native IDE tools для чтения/редактирования/поиска — основной режим.
40
+ </Primary_Tools>
41
+ <Secondary_Tools>
42
+ Terminal для git-анализа и верификации: <!--ai:verify-tools-example-->.
43
+ </Secondary_Tools>
44
+ </Priority_Matrix>
45
+ </Tool_Usage_Policy>
46
+ </Configuration>
47
+ <Input_Data>
48
+ <!--Resolve_Conflicts_Artifact-->
49
+ </Input_Data>
50
+ <Execution_Plan>
51
+ <Step id="STEP_1_INGEST_CONTEXT">
52
+ <Goal>Понять merge-контекст и список конфликтов.</Goal>
53
+ <Action>
54
+ <!--ai:first-->
55
+ Прочитай `<Merge_Conflict_Context>`.
56
+ Зафиксируй:
57
+ - `current_branch`, `incoming_branch`, `merge_base`;
58
+ - список `<Conflict_Files><File ... />` и их `path`, `status`, `kind`, `conflictRegions`, `binary`.
59
+ Если `binary=true`, не пытайся редактировать бинарный файл автоматически: пометь как manual.
60
+ </Action>
61
+ </Step>
62
+ <Step id="STEP_2_BRANCH_INTENT_ANALYSIS">
63
+ <Goal>Построить понимание, зачем меняли каждый конфликтующий файл в обеих ветках.</Goal>
64
+ <Action>
65
+ Для каждого конфликтующего текстового файла:
66
+ 1. Найди unique commits incoming-ветки для файла: от `merge_base..incoming`.
67
+ 2. Найди unique commits current-ветки для файла: от `merge_base..current`.
68
+ 3. Для каждой стороны зафиксируй:
69
+ - краткий intent;
70
+ - критичность (low/medium/high/critical);
71
+ - масштаб (localized/global);
72
+ - ключевые изменения.
73
+ 4. Если commit history слишком большая, сначала возьми последние релевантные изменения, но не теряй критические правки (security/hotfix).
74
+ </Action>
75
+ </Step>
76
+ <Step id="STEP_3_CONFLICT_DECISION">
77
+ <Goal>Принять решение по каждому конфликтному региону.</Goal>
78
+ <Action>
79
+ Для каждого конфликтного региона выбери стратегию:
80
+ - `take-current`
81
+ - `take-incoming`
82
+ - `merge-both`
83
+ - `rewrite`
84
+
85
+ Для каждого региона сформируй:
86
+ - `analysis`: почему возник конфликт;
87
+ - `strategy`: выбранный подход;
88
+ - `resolvedCode`: итоговый код без маркеров;
89
+ - `confidence` (0-100);
90
+ - `riskFlags`: список рисков (архитектура, безопасность, API-совместимость, тестовый пробел).
91
+
92
+ Общие правила приоритета:
93
+ 1. Критичный hotfix/security не теряется.
94
+ 2. Рефакторинг не должен ломать исправления багов.
95
+ 3. Если изменения совместимы — объединяй, а не отбрасывай.
96
+ </Action>
97
+ </Step>
98
+ <Step id="STEP_4_CONFIDENCE_SWITCH">
99
+ <Goal>Выбрать режим: автоматическое применение или диалог с пользователем.</Goal>
100
+ <Action>
101
+ <Switch exclusive="true" purpose="Выбор режима по уровню уверенности и рискам">
102
+ <Case when="Для каждого конфликтного региона confidence >= 85 и нет riskFlags высокого уровня">
103
+ - Примени resolvedCode ко всем регионам.
104
+ - Удали конфликтные маркеры.
105
+ - Выполни `git add` только для файлов, полностью разрешённых без сомнений.
106
+ - Перейди к STEP_5.
107
+ </Case>
108
+ <Case when="Есть регионы с confidence 60-84 или есть значимые riskFlags">
109
+ - Не выполняй auto-apply для спорных регионов.
110
+ - Перейди в диалог с пользователем.
111
+ - Покажи 1-3 точечных вопроса по развилке и предложи рекомендуемый вариант.
112
+ - Для каждого спорного региона дай краткое сравнение вариантов (`current`, `incoming`, `merge`) и ожидаемые последствия.
113
+ - Остановись и жди ответа пользователя.
114
+ </Case>
115
+ <Case when="Есть регионы с confidence &lt; 60 или не хватает фактов для безопасного выбора">
116
+ - Не вноси автоматические изменения в спорные участки.
117
+ - Сформируй план ручного разрешения с приоритетами и рисками.
118
+ - Запроси решение пользователя по каждому блокирующему региону.
119
+ - Остановись и жди ответа пользователя.
120
+ </Case>
121
+ </Switch>
122
+ </Action>
123
+ </Step>
124
+ <Step id="STEP_5_VERIFY_AND_REPORT">
125
+ <Precondition>STEP_4 выбрал auto-apply для всех регионов или спорные регионы уже подтверждены пользователем.</Precondition>
126
+ <Goal>Проверить результат и отчитаться прозрачно.</Goal>
127
+ <Action>
128
+ 1. Verify: <!--ai:verify-step-commands-->
129
+ 2. Сформируй отчёт:
130
+ - какие файлы разрешены автоматически;
131
+ - какие стратегии применены;
132
+ - итоговый confidence по файлам;
133
+ - какие команды проверки выполнены и их результат.
134
+ 3. Если проверки упали — покажи причину и предложи дальнейшие шаги.
135
+ 4. Не выполняй `git commit` автоматически.
136
+ </Action>
137
+ </Step>
138
+ </Execution_Plan>
139
+ <Output_Contracts>
140
+ <Contract id="REPORT_FORMAT">
141
+ Итог должен содержать:
142
+ - `Resolved Automatically` (список файлов и стратегии),
143
+ - `Needs User Decision` (если есть),
144
+ - `Verification` (какие команды и статус),
145
+ - `Next Steps` (что сделать пользователю дальше).
146
+ </Contract>
147
+ </Output_Contracts>
148
+ </Agent_Execution_Manifest>
@@ -1,4 +1,4 @@
1
- import { p as e, r } from "./run-review-command.logic-a_M3CkeZ.js";
1
+ import { p as e, r } from "./run-review-command.logic-BQDGxh0f.js";
2
2
  const s = e(process.argv), o = await r({
3
3
  mode: "verify",
4
4
  args: s
@@ -1,5 +1,5 @@
1
- import { p as j, s as e, g as x } from "./shared-BgLzFWMH.js";
2
- import { p as T, A as E } from "./index-iqg0w_pE.js";
1
+ import { p as j, s as e, g as x } from "./shared-D0kSJB49.js";
2
+ import { p as T, A as E } from "./index-BrobNwbS.js";
3
3
  import { readdirSync as G, readFileSync as P } from "node:fs";
4
4
  import { join as h, dirname as k } from "node:path";
5
5
  import { fileURLToPath as N } from "node:url";
@@ -1,5 +1,5 @@
1
1
  import { AiLegacyModel as h } from "../index.js";
2
- import { G as f, u as c } from "./shared-BgLzFWMH.js";
2
+ import { G as f, u as c } from "./shared-D0kSJB49.js";
3
3
  import { l as p } from "./services-Sb7TwLxt.js";
4
4
  import { readFileSync as l } from "node:fs";
5
5
  import { dirname as _, join as m } from "node:path";
@@ -1,4 +1,4 @@
1
- import { p as $, s as e, a as k } from "./shared-BgLzFWMH.js";
1
+ import { p as $, s as e, a as k } from "./shared-D0kSJB49.js";
2
2
  import I from "node:fs";
3
3
  import { V as S } from "./services-Sb7TwLxt.js";
4
4
  async function m(r = {}) {
@@ -7,7 +7,7 @@ import it from "stream";
7
7
  import bn from "events";
8
8
  import Ft from "fs";
9
9
  import { l as Qt } from "./services-Sb7TwLxt.js";
10
- import { p as Pn, s as ie } from "./shared-BgLzFWMH.js";
10
+ import { p as Pn, s as ie } from "./shared-D0kSJB49.js";
11
11
  var Cn = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {};
12
12
  function Tn(u) {
13
13
  return u && u.__esModule && Object.prototype.hasOwnProperty.call(u, "default") ? u.default : u;
@@ -2,8 +2,8 @@ import u from "node:fs";
2
2
  import v from "node:os";
3
3
  import P from "node:path";
4
4
  import { execSync as _ } from "node:child_process";
5
- import { p as d, A as E } from "./index-iqg0w_pE.js";
6
- import { g as H, s as t, x as D, p as F } from "./shared-BgLzFWMH.js";
5
+ import { p as d, A as E } from "./index-BrobNwbS.js";
6
+ import { g as H, s as t, x as D, p as F } from "./shared-D0kSJB49.js";
7
7
  import { l as N } from "./services-Sb7TwLxt.js";
8
8
  class U {
9
9
  init;
@@ -1,4 +1,4 @@
1
- import { p as D, e as o, b as M, a as H, c as B, l as U, d as O, f as k, s as F } from "./shared-BgLzFWMH.js";
1
+ import { p as D, e as o, b as M, a as H, c as B, l as U, d as O, f as k, s as F } from "./shared-D0kSJB49.js";
2
2
  import a from "node:fs";
3
3
  import P from "node:path";
4
4
  function C(e) {
@@ -1,4 +1,4 @@
1
- import { p as s, r as e } from "./run-review-command.logic-a_M3CkeZ.js";
1
+ import { p as s, r as e } from "./run-review-command.logic-BQDGxh0f.js";
2
2
  const r = s(process.argv), o = await e({
3
3
  mode: "issues",
4
4
  args: r
@@ -1,4 +1,4 @@
1
- import { p as v, a as g, b, c as R, l as j, d as y, f as _, s as u } from "./shared-BgLzFWMH.js";
1
+ import { p as v, a as g, b, c as R, l as j, d as y, f as _, s as u } from "./shared-D0kSJB49.js";
2
2
  import { V as A } from "./services-Sb7TwLxt.js";
3
3
  function H(r) {
4
4
  const e = v(r, {
@@ -1,8 +1,8 @@
1
- import { execSync as E } from "node:child_process";
2
- import { l as k } from "./services-Sb7TwLxt.js";
3
- import m, { existsSync as $, readFileSync as _ } from "node:fs";
4
- import f, { join as R } from "node:path";
5
- import { fileURLToPath as v } from "node:url";
1
+ import { execSync as A } from "node:child_process";
2
+ import { l as x } from "./services-Sb7TwLxt.js";
3
+ import u, { existsSync as _, readFileSync as v } from "node:fs";
4
+ import m, { join as L } from "node:path";
5
+ import { fileURLToPath as N } from "node:url";
6
6
  const p = ["plain", "nocolor", "noColor", "no-color", "color=no", "color=never"].some(
7
7
  (r) => process.argv.includes(`-${r}`) || process.argv.includes(`--${r}`)
8
8
  ), d = {
@@ -51,7 +51,7 @@ const p = ["plain", "nocolor", "noColor", "no-color", "color=no", "color=never"]
51
51
  bgCyanBright: "\x1B[106m",
52
52
  bgWhiteBright: "\x1B[107m"
53
53
  };
54
- function j(r = []) {
54
+ function $(r = []) {
55
55
  const s = (n) => p ? n : r.join("") + n + d.reset;
56
56
  return new Proxy(s, {
57
57
  get(n, t) {
@@ -59,7 +59,7 @@ function j(r = []) {
59
59
  return () => p ? "%s" : r.join("") + "%s" + d.reset;
60
60
  if (t in d) {
61
61
  const a = d[t];
62
- return j(p ? [] : [...r, a].filter(Boolean));
62
+ return $(p ? [] : [...r, a].filter(Boolean));
63
63
  }
64
64
  },
65
65
  apply(n, t, a) {
@@ -68,7 +68,7 @@ function j(r = []) {
68
68
  }
69
69
  });
70
70
  }
71
- const Z = j(), tt = (r, s = {}) => {
71
+ const st = $(), rt = (r, s = {}) => {
72
72
  const n = { _: [] };
73
73
  return r.slice(2).forEach((a) => {
74
74
  if (a.startsWith("-")) {
@@ -82,7 +82,7 @@ const Z = j(), tt = (r, s = {}) => {
82
82
  } else
83
83
  n._.push(a);
84
84
  }), n;
85
- }, L = {
85
+ }, T = {
86
86
  js: "JavaScript",
87
87
  jsx: "JavaScript",
88
88
  ts: "TypeScript",
@@ -108,16 +108,16 @@ const Z = j(), tt = (r, s = {}) => {
108
108
  sass: "Sass",
109
109
  md: "Markdown",
110
110
  mdc: "Markdown"
111
- }, x = (r) => L[r] ?? void 0, et = () => {
111
+ }, b = (r) => T[r] ?? void 0, nt = () => {
112
112
  try {
113
- return E("osascript -e 'user locale of (get system info)'").toString().trim().toLowerCase().split("_").filter((n) => n !== "en" && n !== "us")[0] ?? "en";
113
+ return A("osascript -e 'user locale of (get system info)'").toString().trim().toLowerCase().split("_").filter((n) => n !== "en" && n !== "us")[0] ?? "en";
114
114
  } catch {
115
115
  return "en";
116
116
  }
117
- }, b = (r) => {
117
+ }, w = (r) => {
118
118
  const s = r.match(/[\p{L}\p{N}_]+|[^\s\p{L}\p{N}_]/gu);
119
119
  return s ? s.length : 0;
120
- }, F = [
120
+ }, M = [
121
121
  "^package\\.json",
122
122
  "^tsconfig\\.json",
123
123
  "^babel\\.config\\.json",
@@ -127,7 +127,7 @@ const Z = j(), tt = (r, s = {}) => {
127
127
  "^\\.env(?:\\.[\\w]+)?",
128
128
  "^\\..+",
129
129
  ".*\\.(?:yml|yaml|rc|ini|conf)"
130
- ], M = [
130
+ ], D = [
131
131
  "^package-lock\\.json",
132
132
  "^npm-shrinkwrap\\.json",
133
133
  "^yarn(?:-lock)?\\.(?:yaml|yml|toml)",
@@ -136,24 +136,24 @@ const Z = j(), tt = (r, s = {}) => {
136
136
  "^podfile\\.lock",
137
137
  "^go\\.sum",
138
138
  "^gemfile\\.lock"
139
- ], N = {
139
+ ], F = {
140
140
  doc: /\.(md|markdown|txt|rst)$/i,
141
- cfg: new RegExp(F.join("|"), "i"),
141
+ cfg: new RegExp(M.join("|"), "i"),
142
142
  img: /\.(png|jpe?g|gif|svg|bmp|tiff|ico)$/i,
143
143
  css: /\.(css|less|scss|sass|styl)$/i,
144
144
  html: /\.(html?)$/i,
145
145
  code: /\.(js|jsx|ts|tsx|java|py|c|cpp|cs|rb|php|go|swift|m|mm|kt|sh|bash)$/i,
146
146
  bin: /^(exe|dll|so|bin)\b/i,
147
- lock: new RegExp(M.join("|"), "i"),
147
+ lock: new RegExp(D.join("|"), "i"),
148
148
  json: /\.json$/i
149
- }, w = (r, s) => {
149
+ }, B = (r, s) => {
150
150
  if (s?.extra && Array.isArray(s.extra)) {
151
151
  for (const t of s.extra)
152
152
  if (/^Binary files? /i.test(t) || /GIT binary patch/i.test(t))
153
153
  return "bin";
154
154
  }
155
- return Object.entries(N).find(([, t]) => t.test(r))?.[0] ?? "other";
156
- }, T = (r) => {
155
+ return Object.entries(F).find(([, t]) => t.test(r))?.[0] ?? "other";
156
+ }, O = (r) => {
157
157
  const s = r.split(`
158
158
  `), n = [];
159
159
  let t = null, a = null;
@@ -161,14 +161,14 @@ const Z = j(), tt = (r, s = {}) => {
161
161
  if (e.startsWith("diff --git")) {
162
162
  if (t) {
163
163
  t.diff.tokens = t.diff.hunks.reduce(
164
- (g, A) => g + A.tokens,
164
+ (g, R) => g + R.tokens,
165
165
  0
166
166
  ), t.tokens = t.diff.tokens;
167
167
  const l = t.filename.match(/\.([^.]+)$/);
168
- t.ext = l?.[1]?.toLowerCase() ?? "", t.category = w(
168
+ t.ext = l?.[1]?.toLowerCase() ?? "", t.category = B(
169
169
  t.filename,
170
170
  t.metadata
171
- ), t.programmingLanguage = x(t.ext), n.push(t);
171
+ ), t.programmingLanguage = b(t.ext), n.push(t);
172
172
  }
173
173
  const i = e.match(/^diff --git a\/(.+?) b\/(.+)$/), o = i?.[1] ?? null;
174
174
  t = {
@@ -213,31 +213,31 @@ const Z = j(), tt = (r, s = {}) => {
213
213
  } else t && e.startsWith("index") ? t.metadata.index = e.substring(5).trim() : t && (e.startsWith("--- ") || e.startsWith("+++ ")) ? e.startsWith("--- ") ? t.metadata.oldFileMarker = e : t.metadata.newFileMarker = e : t && e.startsWith("@@") ? (a = {
214
214
  header: e,
215
215
  changes: [e],
216
- tokens: b(e)
217
- }, t.diff.hunks.push(a)) : a && (e.startsWith("+") || e.startsWith("-") || e.startsWith(" ")) ? (a.changes.push(e), a.tokens += b(e)) : t && (Array.isArray(t.metadata.extra) || (t.metadata.extra = []), t.metadata.extra.push(e));
216
+ tokens: w(e)
217
+ }, t.diff.hunks.push(a)) : a && (e.startsWith("+") || e.startsWith("-") || e.startsWith(" ")) ? (a.changes.push(e), a.tokens += w(e)) : t && (Array.isArray(t.metadata.extra) || (t.metadata.extra = []), t.metadata.extra.push(e));
218
218
  }), t) {
219
219
  const e = t, i = e.filename.match(/\.([^.]+)$/);
220
220
  e.diff.tokens = e.diff.hunks.reduce(
221
221
  (o, c) => o + c.tokens,
222
222
  0
223
- ), e.tokens = e.diff.tokens, e.ext = i?.[1]?.toLowerCase() ?? "", e.category = w(e.filename, e.metadata), e.programmingLanguage = x(e.ext), n.push(e);
223
+ ), e.tokens = e.diff.tokens, e.ext = i?.[1]?.toLowerCase() ?? "", e.category = B(e.filename, e.metadata), e.programmingLanguage = b(e.ext), n.push(e);
224
224
  }
225
225
  return n;
226
- }, u = (r) => {
226
+ }, f = (r) => {
227
227
  try {
228
- return E(r, { encoding: "utf-8" });
228
+ return A(r, { encoding: "utf-8" });
229
229
  } catch (s) {
230
- return k.error("[execSyncSafe] [running → failed] Command failed", { cause: s }), "";
230
+ return x.error("[execSyncSafe] [running → failed] Command failed", { cause: s }), "";
231
231
  }
232
- }, B = (r) => /\.(test|spec)s?\./.test(r), D = () => u("git branch --list 2>/dev/null")?.match(/\s*\*?\s*(master|main)$/m)?.[1] ?? "master", st = () => u("git rev-parse --abbrev-ref HEAD 2>/dev/null").trim() || "HEAD", rt = () => {
233
- const s = (u("git config --get remote.origin.url 2>/dev/null").trim() || u("git remote get-url origin 2>/dev/null").trim() || "").trim();
232
+ }, E = (r) => /\.(test|spec)s?\./.test(r), G = () => f("git branch --list 2>/dev/null")?.match(/\s*\*?\s*(master|main)$/m)?.[1] ?? "master", at = () => f("git rev-parse --abbrev-ref HEAD 2>/dev/null").trim() || "HEAD", it = () => {
233
+ const s = (f("git config --get remote.origin.url 2>/dev/null").trim() || f("git remote get-url origin 2>/dev/null").trim() || "").trim();
234
234
  if (!s) return null;
235
235
  if (/^[a-z]+:\/\//i.test(s))
236
236
  try {
237
237
  const t = new URL(s), a = (t.hostname || "").toLowerCase(), e = (t.protocol || "").replace(/:$/, "").toLowerCase(), i = (t.pathname || "").replace(/^\/+/, "").replace(/\.git$/i, "");
238
238
  return !a || !i ? null : { host: a, project: i, scheme: e };
239
239
  } catch (t) {
240
- k.debug("[getGitRemote] [parsing → skip] URL parse failed", { cause: t });
240
+ x.debug("[getGitRemote] [parsing → skip] URL parse failed", { cause: t });
241
241
  }
242
242
  const n = s.match(/^[\w.-]+@([^:\/]+)[:\/](.+)$/);
243
243
  if (n) {
@@ -245,20 +245,20 @@ const Z = j(), tt = (r, s = {}) => {
245
245
  return !t || !a ? null : { host: t, project: a, scheme: e };
246
246
  }
247
247
  return null;
248
- }, O = () => {
248
+ }, P = () => {
249
249
  try {
250
- const r = u(`git rev-list --count HEAD ^${D()} 2>/dev/null`);
250
+ const r = f(`git rev-list --count HEAD ^${G()} 2>/dev/null`);
251
251
  return parseInt(r, 10) || 0;
252
252
  } catch (r) {
253
- return k.debug("[getGitCommitCount] [counting → fallback] Using 0", { cause: r }), 0;
253
+ return x.debug("[getGitCommitCount] [counting → fallback] Using 0", { cause: r }), 0;
254
254
  }
255
- }, G = (r) => u(r ? `git diff ${r}` : "git diff HEAD"), nt = (r) => {
256
- const s = G(r), n = T(s).sort((o, c) => o.tokens - c.tokens), t = n.filter(
257
- (o) => !o.isDeleted && !o.isRenamed && !B(o.filename) && (o.category === "config" || o.programmingLanguage)
255
+ }, W = (r) => f(r ? `git diff ${r}` : "git diff HEAD"), ot = (r) => {
256
+ const s = W(r), n = O(s).sort((o, c) => o.tokens - c.tokens), t = n.filter(
257
+ (o) => !o.isDeleted && !o.isRenamed && !E(o.filename) && (o.category === "config" || o.programmingLanguage)
258
258
  );
259
259
  t.length || t.push(
260
260
  ...n.filter(
261
- (o) => !o.isDeleted && !o.isRenamed && (o.category === "doc" || B(o.filename))
261
+ (o) => !o.isDeleted && !o.isRenamed && (o.category === "doc" || E(o.filename))
262
262
  )
263
263
  );
264
264
  const a = t.reduce((o, c) => o + c.tokens, 0), e = t.at(-1)?.tokens ?? 0, i = [
@@ -271,9 +271,9 @@ const Z = j(), tt = (r, s = {}) => {
271
271
  parsedCodeTokens: a,
272
272
  parsedCodeChunkMaxTokens: e,
273
273
  programmingLanguages: i,
274
- commitCount: O()
274
+ commitCount: P()
275
275
  };
276
- }, P = (r) => {
276
+ }, I = (r) => {
277
277
  if (Array.isArray(r) && r.length === 2) {
278
278
  const s = r[1];
279
279
  if (s === null)
@@ -284,11 +284,11 @@ const Z = j(), tt = (r, s = {}) => {
284
284
  "[UNGUARD_ERROR_SYNTAX] Invalid input: not a valid [result, error] tuple.",
285
285
  { cause: r }
286
286
  );
287
- }, at = async (r) => {
287
+ }, ct = async (r) => {
288
288
  const s = await r;
289
- return P(s);
290
- }, C = "</think>", it = (r) => {
291
- const s = String(r ?? "").split(C).slice(-1).join(C).trim();
289
+ return I(s);
290
+ }, S = "</think>", lt = (r) => {
291
+ const s = String(r ?? "").split(S).slice(-1).join(S).trim();
292
292
  return /^(Хорошо,|Okay,)/.test(s) ? s.split(`
293
293
 
294
294
 
@@ -297,7 +297,7 @@ const Z = j(), tt = (r, s = {}) => {
297
297
 
298
298
  `).trim() : s;
299
299
  };
300
- class y {
300
+ class k {
301
301
  /** @purpose Имя файла конфигурации по умолчанию. */
302
302
  static DEFAULT_FILENAME = ".gennadyrc";
303
303
  /**
@@ -306,18 +306,18 @@ class y {
306
306
  * @sideEffect IO: чтение файлов при конструкторе.
307
307
  */
308
308
  static getDefaults() {
309
- return [process.cwd(), process.env.HOME].map((s) => new y(s));
309
+ return [process.cwd(), process.env.HOME].map((s) => new k(s));
310
310
  }
311
311
  _filename = "";
312
312
  _data = {
313
313
  models: []
314
314
  };
315
315
  _error = null;
316
- constructor(s = process.cwd(), n = y.DEFAULT_FILENAME) {
317
- this._filename = R(s, n);
316
+ constructor(s = process.cwd(), n = k.DEFAULT_FILENAME) {
317
+ this._filename = L(s, n);
318
318
  try {
319
- if ($(this._filename)) {
320
- const t = JSON.parse(_(this._filename).toString());
319
+ if (_(this._filename)) {
320
+ const t = JSON.parse(v(this._filename).toString());
321
321
  Array.isArray(t) ? this._data.models = t : t && typeof t == "object" && Array.isArray(t.models) ? this._data = {
322
322
  ...this._data,
323
323
  ...t
@@ -354,7 +354,7 @@ class y {
354
354
  return this._error;
355
355
  }
356
356
  }
357
- function ot(r) {
357
+ function mt(r) {
358
358
  const s = String(r).match(/<message[\s\S]*?>[\s\S]*?<\/message>/)?.[0];
359
359
  if (!s)
360
360
  return null;
@@ -367,7 +367,7 @@ function ot(r) {
367
367
  description: i?.trim() || null
368
368
  };
369
369
  }
370
- function h(r) {
370
+ function y(r) {
371
371
  return r ? String(r).replace(/[<>&'"]/g, (s) => {
372
372
  switch (s) {
373
373
  case "<":
@@ -385,37 +385,37 @@ function h(r) {
385
385
  }
386
386
  }) : "";
387
387
  }
388
- function S(r, s = 0) {
388
+ function j(r, s = 0) {
389
389
  const n = " ".repeat(s), { tag: t, attrs: a, children: e } = r;
390
390
  let i = "";
391
- if (a && (i = Object.entries(a).filter(([, c]) => c != null).map(([c, l]) => ` ${c}="${h(String(l))}"`).join("")), e == null)
391
+ if (a && (i = Object.entries(a).filter(([, c]) => c != null).map(([c, l]) => ` ${c}="${y(String(l))}"`).join("")), e == null)
392
392
  return `${n}<${t}${i} />`;
393
393
  if (Array.isArray(e) && e.length === 0)
394
394
  return `${n}<${t}${i} />`;
395
395
  let o = "";
396
- return Array.isArray(e) ? e.length > 0 && typeof e[0] == "string" ? o = e.map((l) => h(l)).join(`
396
+ return Array.isArray(e) ? e.length > 0 && typeof e[0] == "string" ? o = e.map((l) => y(l)).join(`
397
397
  `) : o = `
398
- ` + e.map((l) => S(l, s + 1)).join(`
398
+ ` + e.map((l) => j(l, s + 1)).join(`
399
399
  `) + `
400
- ` + n : typeof e == "string" ? o = h(e) : "cdata" in e ? o = `<![CDATA[${String(e.cdata).replaceAll("]]>", "]]]]><![CDATA[>")}]]>` : o = `
401
- ` + S(e, s + 1) + `
400
+ ` + n : typeof e == "string" ? o = y(e) : "cdata" in e ? o = `<![CDATA[${String(e.cdata).replaceAll("]]>", "]]]]><![CDATA[>")}]]>` : o = `
401
+ ` + j(e, s + 1) + `
402
402
  ` + n, `${n}<${t}${i}>${o}</${t}>`;
403
403
  }
404
- function ct(r) {
404
+ function ut(r) {
405
405
  const s = [
406
406
  "ai.knowledge.md",
407
407
  ".ai/ai.knowledge.md"
408
408
  ], n = [];
409
409
  for (const t of s) {
410
- const a = f.join(r, t);
410
+ const a = m.join(r, t);
411
411
  try {
412
- m.existsSync(a) && m.statSync(a).isFile() && n.push(t);
412
+ u.existsSync(a) && u.statSync(a).isFile() && n.push(t);
413
413
  } catch {
414
414
  }
415
415
  }
416
416
  return n.length === 0 ? "" : `**MUST READ PROJECT KNOWLEDGE FILES**: ${n.join(", ")}.`;
417
417
  }
418
- const W = [
418
+ const H = [
419
419
  {
420
420
  kind: "marker",
421
421
  relativePath: "go.mod",
@@ -454,15 +454,15 @@ const W = [
454
454
  commands: ["cargo test", "cargo clippy"]
455
455
  }
456
456
  ];
457
- function I(r, s) {
458
- const n = f.join(r, s);
457
+ function U(r, s) {
458
+ const n = m.join(r, s);
459
459
  try {
460
- return m.existsSync(n) && m.statSync(n).isFile();
460
+ return u.existsSync(n) && u.statSync(n).isFile();
461
461
  } catch {
462
462
  return !1;
463
463
  }
464
464
  }
465
- function H(r, s) {
465
+ function J(r, s) {
466
466
  const n = r.toLowerCase(), t = s.toLowerCase();
467
467
  return /(^|:|-)watch($|:|-)/i.test(n) ? !0 : [
468
468
  /(^|\s)--watch(?:[=\s]|$)/i,
@@ -471,9 +471,9 @@ function H(r, s) {
471
471
  /(^|\s)nodemon(?:\s|$)/i
472
472
  ].some((e) => e.test(t));
473
473
  }
474
- function U(r, s, n) {
474
+ function K(r, s, n) {
475
475
  const t = Object.entries(r).filter(
476
- ([a, e]) => !n.has(a) && !H(a, e)
476
+ ([a, e]) => !n.has(a) && !J(a, e)
477
477
  );
478
478
  for (const a of s.preferredNames)
479
479
  if (t.some(([e]) => e === a))
@@ -483,13 +483,13 @@ function U(r, s, n) {
483
483
  return a;
484
484
  return null;
485
485
  }
486
- function J(r, s) {
487
- const n = f.join(r, "package.json");
486
+ function Y(r, s) {
487
+ const n = m.join(r, "package.json");
488
488
  let t;
489
489
  try {
490
- if (!m.existsSync(n) || !m.statSync(n).isFile())
490
+ if (!u.existsSync(n) || !u.statSync(n).isFile())
491
491
  return null;
492
- t = m.readFileSync(n, "utf-8");
492
+ t = u.readFileSync(n, "utf-8");
493
493
  } catch {
494
494
  return null;
495
495
  }
@@ -504,74 +504,98 @@ function J(r, s) {
504
504
  return null;
505
505
  const i = [], o = /* @__PURE__ */ new Set();
506
506
  for (const c of s.scriptGroups) {
507
- const l = U(e, c, o);
507
+ const l = K(e, c, o);
508
508
  if (l && (i.push(`npm run ${l}`), o.add(l)), i.length >= s.maxCommands)
509
509
  break;
510
510
  }
511
511
  return i.length === 0 ? null : i.slice(0, s.maxCommands);
512
512
  }
513
- function K(r) {
514
- for (const s of W) {
513
+ function V(r) {
514
+ for (const s of H) {
515
515
  if (s.kind === "marker") {
516
- if (I(r, s.relativePath))
516
+ if (U(r, s.relativePath))
517
517
  return [...s.commands];
518
518
  continue;
519
519
  }
520
520
  if (s.kind === "npm-package-json") {
521
- const n = J(r, s);
521
+ const n = Y(r, s);
522
522
  if (n != null && n.length > 0)
523
523
  return n;
524
524
  }
525
525
  }
526
526
  return [];
527
527
  }
528
- function Y(r) {
528
+ function X(r) {
529
529
  return r.map((s) => `\`${s}\``).join(", ");
530
530
  }
531
- function lt(r) {
532
- const s = K(r);
531
+ function ft(r) {
532
+ const s = V(r);
533
533
  if (s.length === 0)
534
534
  return {
535
535
  axiomHint: "как в README или CI принято проверять код (тесты, линтер, типы). Не подменяй это тяжёлой production-сборкой или публикацией, если это явно не описано как проверка",
536
536
  toolsExample: "команды из `package.json` → `scripts`, из Makefile или из CI-шагов, которые относятся к качеству кода; сначала прочитай README",
537
537
  verifyStep: "Прочитай README и при наличии — конфиг CI: какие команды запускают тесты, линтер и проверку типов. Выполни их из корня репозитория. Не запускай `build`/`publish`/полный `ci`, если не уверен, что это нужно для проверки изменений; при сомнении спроси пользователя."
538
538
  };
539
- const n = Y(s);
539
+ const n = X(s);
540
540
  return {
541
541
  axiomHint: `\`${s[0]}\` или следующую команду из того же набора проверок`,
542
542
  toolsExample: n,
543
543
  verifyStep: `Из корня репозитория выполни: ${n}. Не добавляй \`build\`, полный \`ci\` или публикацию, если они не перечислены здесь и не описаны в README как обязательная проверка.`
544
544
  };
545
545
  }
546
- async function mt(r) {
547
- const s = f.dirname(v(import.meta.url)), n = [
548
- f.join(process.cwd(), ".ai/agents", r),
549
- f.join(s, "../../../../../.ai/agents", r)
550
- ];
551
- for (const t of n)
552
- if (m.existsSync(t))
553
- return m.promises.readFile(t, "utf-8");
554
- throw new Error(`Не найден файл шаблона ${r} в .ai/agents.`, {
555
- cause: n
546
+ const h = ".ai/agents";
547
+ function C(r) {
548
+ return u.existsSync(r) ? u.promises.readFile(r, "utf-8") : null;
549
+ }
550
+ function z(r) {
551
+ let s = r;
552
+ for (; ; ) {
553
+ const n = m.join(s, "package.json");
554
+ if (u.existsSync(n))
555
+ return s;
556
+ const t = m.dirname(s);
557
+ if (t === s)
558
+ return null;
559
+ s = t;
560
+ }
561
+ }
562
+ async function dt(r) {
563
+ const s = m.dirname(N(import.meta.url)), n = m.join(process.cwd(), h, r), t = C(n);
564
+ if (t)
565
+ return t;
566
+ const a = z(s), e = [];
567
+ a ? (e.push(m.join(a, h, r)), e.push(m.join(a, "dist", h, r))) : e.push(
568
+ m.join(s, "../../../../../../dist", h, r)
569
+ );
570
+ for (const i of e) {
571
+ const o = C(i);
572
+ if (o)
573
+ return o;
574
+ }
575
+ throw new Error(`Не найден файл шаблона ${r}.`, {
576
+ cause: {
577
+ projectOverridePath: n,
578
+ packageCandidates: e
579
+ }
556
580
  });
557
581
  }
558
582
  export {
559
- y as G,
560
- rt as a,
561
- st as b,
562
- S as c,
563
- lt as d,
564
- u as e,
565
- ct as f,
566
- nt as g,
567
- x as h,
568
- et as i,
569
- T as j,
570
- P as k,
571
- mt as l,
572
- tt as p,
573
- it as r,
574
- Z as s,
575
- at as u,
576
- ot as x
583
+ k as G,
584
+ it as a,
585
+ at as b,
586
+ j as c,
587
+ ft as d,
588
+ f as e,
589
+ ut as f,
590
+ ot as g,
591
+ b as h,
592
+ nt as i,
593
+ O as j,
594
+ I as k,
595
+ dt as l,
596
+ rt as p,
597
+ lt as r,
598
+ st as s,
599
+ ct as u,
600
+ mt as x
577
601
  };
package/dist/gennady.js CHANGED
@@ -3,25 +3,25 @@ const e = /* @__PURE__ */ new Set(["help", "--help", "-h"]), a = process.argv[2]
3
3
  (!a || e.has(a)) && (await import("./chunks/help.cmd-CWasx25o.js"), process.exit(0));
4
4
  switch (a) {
5
5
  case "cat":
6
- await import("./chunks/index-CNbmXK8M.js");
6
+ await import("./chunks/index-C4jt5WBP.js");
7
7
  break;
8
8
  case "review":
9
- await import("./chunks/index-B5bA2T7A.js");
9
+ await import("./chunks/index-Bh0p7rJg.js");
10
10
  break;
11
11
  case "vcs-reply":
12
- await import("./chunks/index-5xIgwwKx.js");
12
+ await import("./chunks/index-Bx_P7mlL.js");
13
13
  break;
14
14
  case "review-verify":
15
- await import("./chunks/index-C0andxna.js");
15
+ await import("./chunks/index-B3r-YFvt.js");
16
16
  break;
17
17
  case "review-issues":
18
- await import("./chunks/index-B63fYXL2.js");
18
+ await import("./chunks/index-Gy1n7hRU.js");
19
19
  break;
20
20
  case "resolve-conflicts":
21
- await import("./chunks/index-Dqe1TdW4.js");
21
+ await import("./chunks/index-DgAmONSz.js");
22
22
  break;
23
23
  case "commit":
24
- await import("./chunks/index-B4m0-PAT.js");
24
+ await import("./chunks/index-D1Hurfwu.js");
25
25
  break;
26
26
  default:
27
27
  await import("./chunks/help.cmd-CWasx25o.js"), process.exit(0);
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { u, r as m } from "./chunks/shared-BgLzFWMH.js";
2
- import { G as y, h as d, i as A, j as f, k as w } from "./chunks/shared-BgLzFWMH.js";
1
+ import { u, r as m } from "./chunks/shared-D0kSJB49.js";
2
+ import { G as y, h as d, i as A, j as f, k as w } from "./chunks/shared-D0kSJB49.js";
3
3
  class h {
4
4
  /**
5
5
  * @purpose Создать экземпляр с дефолтными настройками (Ollama local).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gennady",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "author": "Konstantin Lebedev <ibnrubaxa@gmail.com>",
5
5
  "description": "Gennady — General Extensible Neural Network Adaptive Data Yntelligence",
6
6
  "keywords": [