gennady 0.8.4-draft.2 → 0.8.4-draft.3

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 (146) hide show
  1. package/ai/directives/sdd-v2/root.directive.xml +36 -3
  2. package/ai/directives/sdd-v2/router.directive.xml +22 -1
  3. package/ai/kit/templates/sdd-v2/root.directive.hbs +11 -3
  4. package/ai/kit/templates/sdd-v2/router.directive.hbs +22 -1
  5. package/ai/skills/agent-inbox/SKILL.md +1 -1
  6. package/ai/skills/sdd/SKILL.md +5 -3
  7. package/ai/skills/sdd-audit/SKILL.md +5 -2
  8. package/ai/skills/sdd-check/SKILL.md +2 -2
  9. package/ai/skills/sdd-code-review/SKILL.md +4 -1
  10. package/ai/skills/sdd-critic/SKILL.md +5 -2
  11. package/ai/skills/sdd-execute/SKILL.md +5 -2
  12. package/ai/skills/sdd-reconcile/SKILL.md +5 -2
  13. package/ai/skills/sdd-scaffold/SKILL.md +5 -2
  14. package/dist/ai/directives/sdd-v2/root.directive.xml +36 -3
  15. package/dist/ai/directives/sdd-v2/router.directive.xml +22 -1
  16. package/dist/ai/kit/templates/sdd-v2/root.directive.hbs +11 -3
  17. package/dist/ai/kit/templates/sdd-v2/router.directive.hbs +22 -1
  18. package/dist/ai/skills/agent-inbox/SKILL.md +1 -1
  19. package/dist/ai/skills/sdd/SKILL.md +5 -3
  20. package/dist/ai/skills/sdd-audit/SKILL.md +5 -2
  21. package/dist/ai/skills/sdd-check/SKILL.md +2 -2
  22. package/dist/ai/skills/sdd-code-review/SKILL.md +4 -1
  23. package/dist/ai/skills/sdd-critic/SKILL.md +5 -2
  24. package/dist/ai/skills/sdd-execute/SKILL.md +5 -2
  25. package/dist/ai/skills/sdd-reconcile/SKILL.md +5 -2
  26. package/dist/ai/skills/sdd-scaffold/SKILL.md +5 -2
  27. package/dist/chunks/{classify-mr-stage.logic-BiCHTmPp.js → classify-mr-stage.logic-CazmQDwZ.js} +2 -2
  28. package/dist/chunks/{config-index-9VHWSDQD.js → config-index-DU8-FEjq.js} +1 -1
  29. package/dist/chunks/{devtools-b0DwO1x_.js → devtools-1JmXJjUG.js} +1 -1
  30. package/dist/chunks/{eval.cmd-CwNPaNJd.js → eval.cmd-CBANnOFG.js} +1 -1
  31. package/dist/chunks/{help-D5cXtdMI.js → help-DVloaFF5.js} +1 -1
  32. package/dist/chunks/{index-BVnJEutp.js → index-2xhpqJtd.js} +2 -2
  33. package/dist/chunks/{index-RR5OUxje.js → index-AxsLBUAx.js} +14 -14
  34. package/dist/chunks/{index-CUkeTGqM.js → index-B7sydB0W.js} +2 -2
  35. package/dist/chunks/{index-CMCn9ErF.js → index-BKxk4zOz.js} +2 -2
  36. package/dist/chunks/{index-Db13NlHh.js → index-BNMmX_Mv.js} +21 -21
  37. package/dist/chunks/{index-CmQO-RmM.js → index-BPzldG3a.js} +2 -2
  38. package/dist/chunks/{index-BOQl7F_Z.js → index-BQlFDvKW.js} +2 -2
  39. package/dist/chunks/{index-RzkvIfJQ.js → index-Baq7RL1L.js} +3 -3
  40. package/dist/chunks/index-BbPiwvY9.js +2 -0
  41. package/dist/chunks/{index-ClJLPEUB.js → index-BreGNLJ_.js} +1 -1
  42. package/dist/chunks/{index-DjSafAkN.js → index-BslPwGtM.js} +2 -2
  43. package/dist/chunks/{index-DiMFxS0z.js → index-BtCUN2fZ.js} +16 -16
  44. package/dist/chunks/{index-CS0VbiLD.js → index-C10-EOdB.js} +1 -1
  45. package/dist/chunks/{index-2BOEcJIa.js → index-C4JmZLaj.js} +2 -2
  46. package/dist/chunks/index-CA-JKLr4.js +2 -0
  47. package/dist/chunks/{index-43GiH--T.js → index-CG_jJZVu.js} +2 -2
  48. package/dist/chunks/{index-BdkFKsMm.js → index-CGyP2uDE.js} +3 -3
  49. package/dist/chunks/{index-BOKv0b01.js → index-CPl1s9XJ.js} +2 -2
  50. package/dist/chunks/{index-DIPrBH-4.js → index-CSxE4cEm.js} +9 -9
  51. package/dist/chunks/{index-Cm7U1-fU.js → index-CWR5EzXx.js} +2 -2
  52. package/dist/chunks/{index-BwN5llCR.js → index-Camql5kL.js} +2 -2
  53. package/dist/chunks/{index-Drh-J9O7.js → index-CdUiTipO.js} +7 -7
  54. package/dist/chunks/{index-Cn029KTN.js → index-Crg61pK5.js} +2 -2
  55. package/dist/chunks/{index-Dja2O-hV.js → index-Cv9ZYXso.js} +1 -1
  56. package/dist/chunks/{index-Ck8v_Gv7.js → index-D7ADMlG3.js} +1 -1
  57. package/dist/chunks/index-DNl2gC8l.js +158 -0
  58. package/dist/chunks/{index-BYIzl-Ut.js → index-DVJA0qVm.js} +36 -36
  59. package/dist/chunks/{index-BAEIZVx0.js → index-DcFJhkY1.js} +2 -2
  60. package/dist/chunks/{index-Dx5_CB2E.js → index-DdEd-L3x.js} +2 -2
  61. package/dist/chunks/{index-DVmqMmgb.js → index-DkGA1eW_.js} +32 -32
  62. package/dist/chunks/{index-3k7mPX1e.js → index-Dnwxlti3.js} +1 -1
  63. package/dist/chunks/{index-CrizvxOJ.js → index-DqdEJDi2.js} +2 -2
  64. package/dist/chunks/{index-BIPebtDl.js → index-DqiwmBt4.js} +1 -1
  65. package/dist/chunks/{index-DS4MhAw-.js → index-PfuqBWjY.js} +2 -2
  66. package/dist/chunks/{index-BmFT1Kx2.js → index-SVP6RfVl.js} +2 -2
  67. package/dist/chunks/{index-CDxV4b81.js → index-Y8wu48Q0.js} +1 -1
  68. package/dist/chunks/index-_ewSKppm.js +2 -0
  69. package/dist/chunks/{index-Ctcr_Qeu.js → index-aBVtCLIJ.js} +2 -2
  70. package/dist/chunks/index-dNdz9j6d.js +2 -0
  71. package/dist/chunks/{index-BFUkVkSo.js → index-gskOpu3H.js} +16 -16
  72. package/dist/chunks/{index-CXpkT25O.js → index-pBSLMn5Q.js} +3 -3
  73. package/dist/chunks/index-sqPhX5Io.js +2 -0
  74. package/dist/chunks/{index-BzmR4Es2.js → index-vfrjhUD1.js} +39 -39
  75. package/dist/chunks/{index-J2NvjjDV.js → index-xGF5XC_i.js} +2 -2
  76. package/dist/chunks/{run-review-command.logic-CA2Rjymb.js → run-review-command.logic-B9GoCxh-.js} +24 -24
  77. package/dist/chunks/{serve.cmd-RxYS6WoN.js → serve.cmd-UXkaeaPI.js} +2 -2
  78. package/dist/chunks/{services-Csd556Tv.js → services-BYCeGBlO.js} +4 -4
  79. package/dist/chunks/{shared-B5CTGvpG.js → shared-B3cXL2Np.js} +1178 -1117
  80. package/dist/chunks/{stats-index-BLztvK69.js → stats-index-AIAnnp9S.js} +2 -2
  81. package/dist/gennady.js +46 -46
  82. package/dist/index.js +4 -4
  83. package/dist/shared/sdd/ladder.d.ts +42 -0
  84. package/dist/shared/sdd/module-specs.d.ts +7 -0
  85. package/dist/shared/sdd/tracker.d.ts +9 -0
  86. package/package.json +1 -1
  87. package/dist/chunks/classify-mr-stage.logic-ClmhzQPQ.js +0 -53
  88. package/dist/chunks/config-index-RFeqlDWs.js +0 -104
  89. package/dist/chunks/devtools-p8tmPuLn.js +0 -79
  90. package/dist/chunks/eval.cmd-ewU5lcUY.js +0 -34
  91. package/dist/chunks/help-DzGnMNi2.js +0 -7
  92. package/dist/chunks/index--AXFi0ty.js +0 -89
  93. package/dist/chunks/index-64TSesTc.js +0 -186
  94. package/dist/chunks/index-9Gv5trS_.js +0 -125
  95. package/dist/chunks/index-B1DQIryA.js +0 -2
  96. package/dist/chunks/index-B1PiBeQ3.js +0 -2
  97. package/dist/chunks/index-B4rzuhkt.js +0 -183
  98. package/dist/chunks/index-B97HJjkg.js +0 -159
  99. package/dist/chunks/index-BF6qypm0.js +0 -131
  100. package/dist/chunks/index-BK84ZQsh.js +0 -128
  101. package/dist/chunks/index-BRVIirjj.js +0 -141
  102. package/dist/chunks/index-BXnryCGW.js +0 -96
  103. package/dist/chunks/index-BaZm7Otb.js +0 -2
  104. package/dist/chunks/index-Bhk746A2.js +0 -129
  105. package/dist/chunks/index-Bi-eY_dY.js +0 -164
  106. package/dist/chunks/index-BjumU69g.js +0 -2
  107. package/dist/chunks/index-BkWXcpXU.js +0 -16979
  108. package/dist/chunks/index-BlY4jQIA.js +0 -168
  109. package/dist/chunks/index-C0iy7GxD.js +0 -140
  110. package/dist/chunks/index-CCBTXczb.js +0 -56
  111. package/dist/chunks/index-CDAfkSrr.js +0 -2
  112. package/dist/chunks/index-CDHymWzC.js +0 -102
  113. package/dist/chunks/index-CNfXJAao.js +0 -2
  114. package/dist/chunks/index-CQsae1nq.js +0 -207
  115. package/dist/chunks/index-CVmd0prf.js +0 -2
  116. package/dist/chunks/index-CZuTNeNm.js +0 -2
  117. package/dist/chunks/index-CasNhhrL.js +0 -96
  118. package/dist/chunks/index-Ce7GWENF.js +0 -377
  119. package/dist/chunks/index-Cf-02TAg.js +0 -265
  120. package/dist/chunks/index-CfjQWSrh.js +0 -52
  121. package/dist/chunks/index-Chr7gBBz.js +0 -443
  122. package/dist/chunks/index-Ci875Zlg.js +0 -346
  123. package/dist/chunks/index-CwA6RzIB.js +0 -3793
  124. package/dist/chunks/index-D1dI63ej.js +0 -46
  125. package/dist/chunks/index-DCS32A2i.js +0 -663
  126. package/dist/chunks/index-DOFoNxvb.js +0 -131
  127. package/dist/chunks/index-DVkCEuws.js +0 -136
  128. package/dist/chunks/index-DkadaaXq.js +0 -658
  129. package/dist/chunks/index-Dn11CLtk.js +0 -7
  130. package/dist/chunks/index-Do3spFJT.js +0 -340
  131. package/dist/chunks/index-DrFRZ0Yg.js +0 -2
  132. package/dist/chunks/index-DvEQhXi2.js +0 -1054
  133. package/dist/chunks/index-GiS0x6jg.js +0 -90
  134. package/dist/chunks/index-NacvqeQ5.js +0 -69
  135. package/dist/chunks/index-RNJhFzdr.js +0 -227
  136. package/dist/chunks/index-R_vUB6CL.js +0 -2
  137. package/dist/chunks/index-TQft1s5H.js +0 -20
  138. package/dist/chunks/index-ZmQRP38W.js +0 -26969
  139. package/dist/chunks/index-jdOZ4AkD.js +0 -143
  140. package/dist/chunks/index-kNa21kUI.js +0 -279
  141. package/dist/chunks/index-v4AV9kAc.js +0 -108
  142. package/dist/chunks/run-review-command.logic-CU1Slmc_.js +0 -331
  143. package/dist/chunks/serve.cmd-dWu_k_G_.js +0 -162
  144. package/dist/chunks/services-CwvXl2MB.js +0 -46832
  145. package/dist/chunks/shared-DSZTUx5b.js +0 -4509
  146. package/dist/chunks/stats-index-H6ALcjxy.js +0 -66
@@ -1,143 +0,0 @@
1
- import { p as j, s as e, g as x } from "./shared-DSZTUx5b.js";
2
- import { p as T, A as E } from "./index-2BOEcJIa.js";
3
- import { readdirSync as G, readFileSync as P } from "node:fs";
4
- import { join as h, dirname as k } from "node:path";
5
- import { fileURLToPath as N } from "node:url";
6
- const R = h(k(N(import.meta.url)), "specs");
7
- class v {
8
- /** @purpose Cached language specs loaded from specs directory on first access. */
9
- _langSpecs = {};
10
- /** @purpose Configuration with base prompt template and timeout. */
11
- init;
12
- /**
13
- * @purpose Initialize ReviewGen with configuration and AI core.
14
- * @param [init] Configuration overrides (timeout, logger).
15
- */
16
- constructor(t = {}) {
17
- this.init = {
18
- basePromptTemplate: T.review("base"),
19
- timeout: 120,
20
- ...t
21
- }, this._ai = new E({
22
- logger: this.init.logger,
23
- timeout: this.init.timeout
24
- });
25
- }
26
- /** @purpose Instance of AiLegacyCore for calling LLM. */
27
- _ai;
28
- /**
29
- * @purpose Instance of AiLegacyCore for calling LLM.
30
- * @returns AiLegacyCore instance.
31
- */
32
- get ai() {
33
- return this._ai;
34
- }
35
- /**
36
- * @purpose Logger (if passed during initialization).
37
- * @returns Logger instance or undefined.
38
- */
39
- get logger() {
40
- return this.init.logger;
41
- }
42
- /**
43
- * @purpose Generate review text from code and list of languages.
44
- * @param code Source code for analysis.
45
- * @param [langs] Languages (default derived from extension in code).
46
- * @returns Review text from LLM.
47
- * @sideEffect Network: request to AI; Filesystem: reading specs on first access.
48
- */
49
- async generate(t, s = [t.includes(".ts") ? "TypeScript" : "JavaScript"]) {
50
- const n = this.init.basePromptTemplate.replaceAll("{LANGUAGES}", s.join(", ")).replaceAll(`
51
- {EXTRA_RULES}
52
- `, this._getExtraRulesPrompt(s, t)).replaceAll("{INPUT}", t);
53
- return this._ai.generate(n);
54
- }
55
- /**
56
- * @purpose Build extra rules prompt from language specs matching the code under review.
57
- * @param langs List of programming language names.
58
- * @param code Source code to scan for known constructs.
59
- * @returns Extra rules prompt string (empty if no matches found).
60
- */
61
- _getExtraRulesPrompt(t, s) {
62
- const n = this._loadSpec(t), r = Object.keys(n.Global?.properties ?? {}), l = new RegExp(`\\b(${r.join("|")})\\b`, "g"), i = {};
63
- let o = "", p = null;
64
- for (; p = l.exec(s); ) {
65
- const c = p[0], y = n.Global?.properties?.[c];
66
- if (!y) continue;
67
- const { exceptions: d, type: w } = y;
68
- i[c] || (i[c] = !0, d?.length && (o += `## ${c} handling:
69
- `, d.forEach(
70
- ({ type: g, description: f }) => {
71
- o += `- ${g}: ${f}
72
- `;
73
- }
74
- )));
75
- const S = n[w]?.methods;
76
- S && Object.entries(S).forEach(([g, f]) => {
77
- const b = f.exceptions, A = f.hint;
78
- if (Array.isArray(b) && b.length > 0 && s.includes(g) && Array.isArray(A)) {
79
- const m = `${c}.${g}`;
80
- i[m] || (i[m] = !0, o += `## **${m}** handling:
81
- `, o += A.join(`
82
- `));
83
- }
84
- });
85
- }
86
- return o ? `
87
- ${o}
88
- ` : "";
89
- }
90
- /**
91
- * @purpose Load and cache language specs from JSON files in the specs directory.
92
- * @param langs List of programming language names.
93
- * @returns Merged spec shape for all requested languages.
94
- */
95
- _loadSpec(t) {
96
- return t.reduce((s, n) => {
97
- const r = n === "JavaScript" || n === "TypeScript" ? "js" : n, l = h(R, r);
98
- this._langSpecs[r] = {};
99
- try {
100
- for (const i of G(l)) {
101
- if (!i.endsWith(".json")) continue;
102
- const o = P(h(l, i)).toString(), p = JSON.parse(o);
103
- Object.assign(this._langSpecs[r], p);
104
- }
105
- } catch {
106
- }
107
- return {
108
- ...s,
109
- ...this._langSpecs[r]
110
- };
111
- }, {});
112
- }
113
- }
114
- const L = j(process.argv, {
115
- branch: ["branch", "b"]
116
- }), u = new v();
117
- console.info(
118
- "🤖",
119
- e.whiteBright.bold("GENNADY"),
120
- `(${e.cyan(u.ai.model ?? "")})`,
121
- "📝"
122
- );
123
- console.info(e.gray("-".repeat(40)));
124
- const { parsedCodeDiff: _, parsedCodeTokens: C, programmingLanguages: B, parsedCodeChunkMaxTokens: D } = x(L.branch);
125
- console.info(
126
- `- Tokens: ${e.bold.cyanBright(String(C))} ${e.gray(`(max per file: ${D})`)}`
127
- );
128
- console.info(`- Languages: ${e.yellow(B.join(", "))}`);
129
- _.length === 0 && (console.info("No changes detected, skipping review."), console.info(e.italic.gray("Hint: git add")), process.exit(0));
130
- const $ = u.ai.createPromptsBatchesByDiff(_);
131
- console.info(`- Queue: ${e.bold.cyan(String($.length))}`);
132
- console.info(e.gray("-".repeat(40)));
133
- const J = performance.now(), O = await Promise.all(
134
- $.map(async (a) => (console.info("- Task:", a.tokens, a.languages), u.generate(a.diff, a.languages)))
135
- );
136
- console.info(e.gray("-".repeat(40)));
137
- console.info(
138
- `- Generation time: ${e.blueBright(((performance.now() - J) / 1e3).toFixed(2))}s`
139
- );
140
- console.info(e.gray("-".repeat(40)));
141
- console.info(O.join(`
142
-
143
- `));
@@ -1,279 +0,0 @@
1
- import { s as n } from "./shared-DSZTUx5b.js";
2
- import { b as x, f as P, c as W, l as q, a as C } from "./classify-mr-stage.logic-BiCHTmPp.js";
3
- import { b as G, z as F, y as _, W as J, A as B, B as Q, C as V, P as K, ah as z, J as k, ai as Y, N as X, d as Z, c as ee, v as te, I as se, aj as re, ak as I, K as ne, al as oe, am as ae } from "./services-CwvXl2MB.js";
4
- const ie = {
5
- reviewer: "Ждут моё ревью",
6
- author: "Мои MR",
7
- mentioned: "Меня упомянули"
8
- };
9
- function ce(e) {
10
- return e.delta === "new" ? n.green("NEW ") : e.delta === "updated" ? n.yellow("↑ ") : "";
11
- }
12
- function le(e) {
13
- return e.stage === "reply_needed" ? n.redBright("[ответить] ") : e.stage === "review_needed" ? n.yellow("[ревью] ") : e.stage === "awaiting_reply" ? n.gray("[жду] ") : "";
14
- }
15
- function ue(e) {
16
- const t = [];
17
- return e.directlyAddressed && t.push(n.cyan("→")), e.shownEvents.includes("ci_failed") && t.push(n.red("✗ ci")), e.shownEvents.includes("unmergeable") && t.push(n.yellow("⚠ unmergeable")), e.draft && t.push(n.gray("(draft)")), t.length > 0 ? " " + t.join(" ") : "";
18
- }
19
- function de(e) {
20
- const t = [];
21
- return e.waiting > 0 && t.push(`${e.waiting} жду ответа`), e.approved > 0 && t.push(`${e.approved} approved`), e.stale > 0 && t.push(`${e.stale} stale`), e.drafts > 0 && t.push(`${e.drafts} drafts`), e.noise > 0 && t.push(`${e.noise} noise`), e.closed > 0 && t.push(`${e.closed} merged/closed`), t.length > 0 ? ` ${n.gray(`(скрыто: ${t.join(", ")})`)}` : "";
22
- }
23
- function L(e, t = 100) {
24
- const r = e.split(`
25
- `).find((s) => s.trim().length > 0)?.trim() ?? "";
26
- return r === "" ? "" : r.length > t ? `${r.slice(0, t - 1)}…` : r;
27
- }
28
- function pe(e) {
29
- const t = [];
30
- return e.new > 0 && t.push(n.green(`${e.new} new`)), e.updated > 0 && t.push(n.yellow(`${e.updated} updated`)), t.length > 0 ? ` [${t.join(", ")}]` : "";
31
- }
32
- function fe(e) {
33
- const t = [];
34
- t.push(
35
- n.bold(`Inbox — ${e.total} actionable`) + pe(e.delta) + de(e.hidden)
36
- );
37
- for (const r of e.groups) {
38
- t.push(""), t.push(n.bold(`▸ ${ie[r.role]} — ${r.items.length}`));
39
- for (const s of r.items) {
40
- const o = s.project ? `${s.project}!${s.iid}` : `!${s.iid}`, c = s.ageLabel ? n.gray(s.ageLabel) : "";
41
- t.push(
42
- ` ${ce(s)}${le(s)}${n.cyan(o)}${ue(s)} ${s.title} ${c}`
43
- );
44
- const d = [];
45
- s.author && d.push(`автор @${s.author}`), s.reviewers.length > 0 && d.push(`ревью: ${s.reviewers.map((u) => "@" + u).join(" ")}`), d.length > 0 && t.push(` ${n.gray(d.join(" · "))}`);
46
- const a = L(s.description);
47
- a && t.push(` ${n.gray(a)}`), t.push(` ${n.gray(s.webUrl)}`);
48
- }
49
- }
50
- return t.join(`
51
- `);
52
- }
53
- function ge(e, t, r, s = {}) {
54
- const o = [];
55
- o.push(n.bold(`Work packet — ${e}`) + ` ${n.gray(t)}`), o.push(`stage: ${n.cyan(r.stage)} · role: ${r.role ?? "—"}`);
56
- const c = [];
57
- s.author && c.push(`автор @${s.author}`), s.reviewers && s.reviewers.length > 0 && c.push(`ревью: ${s.reviewers.map((a) => "@" + a).join(" ")}`), s.approvedBy && s.approvedBy.length > 0 && c.push(`approved: ${s.approvedBy.map((a) => "@" + a).join(" ")}`), c.length > 0 && o.push(n.gray(c.join(" · ")));
58
- const d = L(s.description ?? "", 200);
59
- if (d && o.push(n.gray(d)), r.needsReview && o.push(n.yellow("→ Первый ревью: посмотри диф и оставь замечания.")), r.openNotes.length > 0) {
60
- o.push(""), o.push(n.bold(`Открытые вопросы (${r.openNotes.length}):`));
61
- for (const a of r.openNotes) {
62
- o.push(` ${n.cyan("@" + a.author)} ${n.gray(a.at)}`);
63
- for (const u of a.body.split(`
64
- `)) o.push(` ${u}`);
65
- }
66
- } else r.needsReview || o.push(n.gray("Нет открытых вопросов ко мне."));
67
- return o.join(`
68
- `);
69
- }
70
- const he = /^added (\d+) commit/, me = /merged branch '([^']+)' into/, ye = /^changed target branch from (.+) to (.+)/, we = /^changed title from/;
71
- function ve(e) {
72
- const t = e.match(he);
73
- if (!t) return null;
74
- const r = Number(t[1]), s = e.match(me), o = s ? "target_branch_merged" : "commits_pushed", c = s ? `влита ветка ${s[1]} (${r} коммитов)` : `добавлено ${r} коммитов`;
75
- return { type: o, at: "", summary: c, detail: e };
76
- }
77
- const $e = [
78
- ve,
79
- (e) => e.includes("changed the description") ? { type: "description_changed", at: "", summary: "изменено описание", detail: e } : null,
80
- (e) => e.match(we) ? { type: "title_changed", at: "", summary: "изменён заголовок", detail: e } : null,
81
- (e) => {
82
- if (!e.includes("marked this merge request as")) return null;
83
- const t = e.includes("ready");
84
- return {
85
- type: t ? "draft_removed" : "draft_marked",
86
- at: "",
87
- summary: t ? "снят draft" : "помечен как draft",
88
- detail: e
89
- };
90
- },
91
- (e) => e.includes("unapproved this merge request") ? { type: "unapproved", at: "", summary: "аппрув отозван", detail: e } : e.includes("approved this merge request") ? { type: "approved", at: "", summary: "аппрув", detail: e } : null,
92
- (e) => {
93
- const t = e.match(ye);
94
- return t ? {
95
- type: "target_branch_changed",
96
- at: "",
97
- summary: `целевая ветка: ${t[1]} → ${t[2]}`,
98
- detail: e
99
- } : null;
100
- },
101
- (e) => e.includes("requested review from") ? { type: "review_requested", at: "", summary: "запрошен ревью", detail: e } : null,
102
- (e) => e.includes("removed review request for") ? { type: "review_request_removed", at: "", summary: "снят запрос ревью", detail: e } : null,
103
- (e) => e.includes("resolved all threads") ? { type: "threads_resolved", at: "", summary: "все треды разрешены", detail: e } : null,
104
- (e) => e.includes("reopened") ? { type: "reopened", at: "", summary: "переоткрыт", detail: e } : null
105
- ];
106
- function be(e) {
107
- if (!e.system || !e.body) return null;
108
- for (const t of $e) {
109
- const r = t(e.body);
110
- if (r)
111
- return r.at = e.created_at ?? r.at, r;
112
- }
113
- return null;
114
- }
115
- function _e(e, t, r) {
116
- const s = (a) => Date.parse(a.created_at ?? "") || 0, o = Date.parse(t) || 0, c = [];
117
- for (const a of e) {
118
- if (s(a) <= o) continue;
119
- const u = be(a);
120
- u && c.push(u);
121
- }
122
- return e.some((a) => !a.system && a.author?.username && s(a) > o) && c.push({ type: "discussion_added", at: "", summary: "новые комментарии" }), r && r.current !== r.previous && (c.some(
123
- (u) => u.type === "commits_pushed" || u.type === "target_branch_merged"
124
- ) || c.push({ type: "commits_detected", at: "", summary: "новые коммиты" })), c.sort((a, u) => Date.parse(u.at || "") - Date.parse(a.at || "")), c;
125
- }
126
- function Se(e) {
127
- const t = (o) => e.includes(o), r = e.find((o) => o.startsWith("--stale-days=")), s = r ? Number(r.slice(13)) : 14;
128
- return {
129
- drafts: t("--drafts"),
130
- includeStale: t("--include-stale"),
131
- staleDays: Number.isFinite(s) && s > 0 ? s : 14,
132
- ciAll: t("--ci-all"),
133
- all: t("--all")
134
- };
135
- }
136
- function h(e, t) {
137
- const r = e.find((o) => o.startsWith(`${t}=`));
138
- if (r) return r.slice(t.length + 1);
139
- const s = e.indexOf(t);
140
- return s !== -1 ? e[s + 1] : void 0;
141
- }
142
- function Re(e) {
143
- const t = h(e, "--mr-shape") ?? "", r = new Set(
144
- t.split(",").map((s) => s.trim()).filter(Boolean)
145
- );
146
- return {
147
- newSymbols: r.has("newSymbols"),
148
- nestedLoops: r.has("nestedLoops"),
149
- filterMapChain: r.has("filterMapChain"),
150
- isTiny: r.has("isTiny"),
151
- securityHits: r.has("securityHits"),
152
- depManifest: r.has("depManifest")
153
- };
154
- }
155
- function Me(e) {
156
- const t = h(e, "--session-type") ?? "session", r = h(e, "--track"), s = Re(e);
157
- try {
158
- return console.info(oe(t, r, s)), 0;
159
- } catch (o) {
160
- return o instanceof ae ? (console.error(n.redBright.bold("✖ Ошибка:"), o.message), 1) : (console.error(n.redBright.bold("✖ Ошибка:"), o.message ?? String(o)), 1);
161
- }
162
- }
163
- async function Ae(e, t, r) {
164
- const s = e.lastIndexOf("!");
165
- if (s === -1)
166
- return console.error(n.redBright.bold("✖ Ошибка:"), "Ожидался ref вида group/project!iid"), 1;
167
- const o = e.slice(0, s), c = e.slice(s + 1), d = x(t, r), [a, u] = await Promise.all([d.Inbox.getActionable(), d.getCurrentUser()]), f = a.find((m) => m.project === o && m.iid === c), w = await d.MergeDiscussions.getAll({ project: o, iid: c }), S = C(P(w), u.login, f?.role ?? null);
168
- return console.info(
169
- ge(e, f?.title ?? "", S, {
170
- author: f?.author,
171
- reviewers: f?.reviewers,
172
- description: f?.description,
173
- approvedBy: f?.approvedBy
174
- })
175
- ), 0;
176
- }
177
- async function De() {
178
- try {
179
- const e = process.argv.slice(2);
180
- if (e.includes("--dump-directive")) return Me(e);
181
- const t = G(e);
182
- try {
183
- await F(_(t), J, Date.now()), B(_(t), Q, Date.now()), V(t, K, Date.now());
184
- } catch {
185
- }
186
- if (e.includes("--reset") || e.includes("reset")) {
187
- const { registryRemoved: l, outRemoved: p } = z(
188
- k(t),
189
- Y(t)
190
- ), i = await X(_(t)), E = B(_(t), 0, Date.now()).length > 0;
191
- return console.info(n.bold("Inbox reset — чистый лист.")), console.info(
192
- ` registry: ${l ? n.green("очищен") : n.gray("не было")}`
193
- ), console.info(` drafts: ${p ? n.green("очищены") : n.gray("не было")}`), console.info(
194
- ` worktrees: ${i.length > 0 ? n.green(`снесено ${i.length}`) : n.gray("не было")}`
195
- ), console.info(
196
- ` reports: ${E ? n.green("очищены") : n.gray("не было")}`
197
- ), 0;
198
- }
199
- const r = h(e, "--vcs-host") ?? h(e, "--vcs-source"), s = h(e, "--repos-base");
200
- let o = null;
201
- try {
202
- o = await Z(ee(t));
203
- } catch {
204
- }
205
- const c = o ?? { version: 1, reposBase: void 0, vcsHost: void 0 }, d = te(c), a = /* @__PURE__ */ new Set();
206
- r && a.add("vcsHost"), s && a.add("reposBase");
207
- const u = d.missing.filter((l) => !a.has(l));
208
- if (u.length > 0)
209
- return e.includes("--json") ? console.info(JSON.stringify({ configured: !1, missing: u })) : console.info(
210
- n.yellow("ℹ agent-inbox не настроен. Запустите gennady inbox config --init")
211
- ), 0;
212
- const f = h(e, "--pick");
213
- if (f) return await Ae(f, r, c.vcsHost);
214
- const w = Se(e), S = !e.includes("--no-save"), m = x(r, c.vcsHost), v = await m.Inbox.getActionable(), R = (/* @__PURE__ */ new Date()).toISOString(), N = k(t), M = se(N), { deltas: A, next: D } = re(v, M, R), $ = await m.getCurrentUser(), U = I(v, w, R, A, /* @__PURE__ */ new Map(), $.login), H = new Set(U.groups.flatMap((l) => l.items.map((p) => p.webUrl))), O = new Map(v.map((l) => [l.webUrl, l])), b = /* @__PURE__ */ new Map(), j = /* @__PURE__ */ new Map(), T = /* @__PURE__ */ new Map();
215
- await Promise.all(
216
- [...H].map(async (l) => {
217
- const p = O.get(l);
218
- if (!p) return;
219
- if (A.get(l) === "idle") {
220
- b.set(l, M.entries[l]?.stage ?? "idle");
221
- return;
222
- }
223
- const i = await m.MergeDiscussions.getAll({
224
- project: p.project,
225
- iid: p.iid
226
- }), g = P(i);
227
- b.set(l, W(g, $.login, p.role)), j.set(l, {
228
- openQuestions: C(g, $.login, p.role).openNotes.length,
229
- lastAuthor: q(g)
230
- });
231
- const E = M.entries[l];
232
- T.set(
233
- l,
234
- _e(g, E?.lastClassifiedAt ?? "", {
235
- current: i[0]?.notes?.[0]?.commit_id ?? ""
236
- })
237
- );
238
- })
239
- );
240
- for (const [l, p] of b)
241
- D.entries[l] && (D.entries[l].stage = p);
242
- const y = I(v, w, R, A, b, $.login, T);
243
- if (e.includes("--json")) {
244
- const l = {
245
- configured: !0,
246
- total: y.total,
247
- hidden: y.hidden,
248
- delta: y.delta,
249
- groups: y.groups.map((p) => ({
250
- role: p.role,
251
- items: p.items.map((i) => ({
252
- ref: i.project ? `${i.project}!${i.iid}` : `!${i.iid}`,
253
- project: i.project,
254
- iid: i.iid,
255
- webUrl: i.webUrl,
256
- title: i.title,
257
- description: i.description,
258
- author: i.author,
259
- reviewers: i.reviewers,
260
- role: i.role,
261
- stage: i.stage,
262
- delta: i.delta,
263
- age: i.ageLabel,
264
- draft: i.draft,
265
- events: i.shownEvents,
266
- openQuestions: j.get(i.webUrl)?.openQuestions ?? null,
267
- lastAuthor: j.get(i.webUrl)?.lastAuthor ?? null,
268
- reasons: (i.reasons ?? []).map((g) => g.summary)
269
- }))
270
- }))
271
- };
272
- console.info(JSON.stringify(l, null, 2));
273
- } else y.total === 0 ? console.info(n.yellow("ℹ Входящих MR, требующих реакции, нет.")) : console.info(fe(y));
274
- return S && ne(N, D), 0;
275
- } catch (e) {
276
- return console.error(n.redBright.bold("✖ Ошибка:"), e.message ?? String(e)), 1;
277
- }
278
- }
279
- process.exit(await De());
@@ -1,108 +0,0 @@
1
- import { existsSync as $, readFileSync as m } from "node:fs";
2
- import { resolve as v, join as y, relative as C } from "node:path";
3
- import { l as S, ae as h, af as F, ag as b } from "./services-Csd556Tv.js";
4
- import { p as j, n as B, ap as k, q as A, aq as E, ar as M, a1 as g, as as R, at as Y } from "./shared-B5CTGvpG.js";
5
- function q(t, n) {
6
- if (t.length === 0)
7
- return {
8
- text: `yagni: ✅ clean (${n} changed file(s) scanned)`,
9
- exitCode: 0
10
- };
11
- const a = t.map((e) => `${e.file}:1:1: ${e.severity}: ${e.code}: ${e.message}`);
12
- return a.push("", `yagni: ${t.length} finding(s) across ${n} changed file(s)`), { text: a.join(`
13
- `), exitCode: 1 };
14
- }
15
- function u(t) {
16
- return `'${t.replace(/'/g, "'\\''")}'`;
17
- }
18
- async function D(t, n, a) {
19
- const e = y(t, n);
20
- let o;
21
- try {
22
- o = m(e, "utf-8");
23
- } catch {
24
- return [];
25
- }
26
- const c = h(n, a), l = await c.declaredSymbols(n, o), r = A(t, n), d = r ? new Set((await c.declaredSymbols(n, r)).map((i) => i.name)) : /* @__PURE__ */ new Set();
27
- return l.filter((i) => !d.has(i.name)).map((i) => ({ name: i.name, kind: i.kind, file: n }));
28
- }
29
- function H(t, n) {
30
- return g(
31
- `grep -rlF --include='*.ts' --include='*.tsx' --include='*.js' --include='*.jsx' --include='*.py' --include='*.go' --include='*.rb' --include='*.java' --exclude-dir=node_modules --exclude-dir=dist --exclude-dir=.git --exclude-dir=coverage -- ${u(n)} ${u(t)} 2>/dev/null`,
32
- { expectedExitCodes: [1] }
33
- ).split(`
34
- `).map((e) => e.trim()).filter(Boolean);
35
- }
36
- async function I(t, n, a) {
37
- const e = H(t, n);
38
- let o = 0;
39
- for (const c of e) {
40
- const l = C(t, c);
41
- if (E(l)) continue;
42
- let r;
43
- try {
44
- r = m(c, "utf-8");
45
- } catch {
46
- continue;
47
- }
48
- const d = M(r), i = h(l, a), { count: p } = await i.countReferences(n, l, d);
49
- o += p;
50
- }
51
- return Math.max(0, o - 1);
52
- }
53
- function T(t, n) {
54
- const a = g(
55
- `grep -rlF --include='*.md' -- ${u("`" + n + "`")} ${u(t)} 2>/dev/null`,
56
- { expectedExitCodes: [1] }
57
- ).split(`
58
- `).map((e) => e.trim()).filter(Boolean);
59
- for (const e of a) {
60
- let o;
61
- try {
62
- o = m(e, "utf-8");
63
- } catch {
64
- continue;
65
- }
66
- const c = R(o, n);
67
- if (c) return c;
68
- }
69
- return null;
70
- }
71
- function U(t, n) {
72
- return g(
73
- `grep -rlF --include='*.md' -- ${u("### " + n)} ${u(t)} 2>/dev/null`,
74
- { expectedExitCodes: [1] }
75
- ).split(`
76
- `).map((e) => e.trim()).filter(Boolean).some((e) => {
77
- try {
78
- return Y(m(e, "utf-8"), n);
79
- } catch {
80
- return !1;
81
- }
82
- });
83
- }
84
- async function W(t) {
85
- const a = j(t, {})._.filter((s) => typeof s == "string" && s !== "yagni"), e = v(a[0] ?? "."), o = y(e, "specs"), c = {
86
- exact: new F(),
87
- approximate: new b()
88
- }, l = B(e), r = [];
89
- for (const s of l)
90
- r.push(...await D(e, s, c));
91
- const d = /* @__PURE__ */ new Map();
92
- for (const s of r)
93
- d.has(s.name) || d.set(s.name, await I(e, s.name, c));
94
- const i = /* @__PURE__ */ new Map(), p = /* @__PURE__ */ new Set();
95
- if ($(o))
96
- for (const s of r) {
97
- if ((d.get(s.name) ?? 0) >= 2 || i.has(s.name)) continue;
98
- const f = T(o, s.name);
99
- f && (i.set(s.name, f), f.decision && U(o, f.decision) && p.add(f.decision));
100
- }
101
- const x = k(r, d, i, p);
102
- return S.debug(
103
- `[YagniCommand#run] ${x.length} finding(s) across ${l.length} file(s)`
104
- ), q(x, l.length);
105
- }
106
- const w = await W(process.argv);
107
- console.log(w.text);
108
- process.exit(w.exitCode);