gennady 0.7.0 → 0.8.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.
Files changed (154) hide show
  1. package/ai/directives/coding/result-conventions.xml +25 -7
  2. package/ai/directives/sdd/audit.directive.xml +1 -1
  3. package/ai/directives/sdd/critic-protocol.xml +78 -0
  4. package/ai/directives/sdd/critic.directive.xml +158 -0
  5. package/ai/directives/sdd/phase-execution-protocol.xml +11 -9
  6. package/ai/skills/alt-opinion/SKILL.md +79 -0
  7. package/ai/skills/alt-opinion/opinion.prompt.md +11 -0
  8. package/ai/skills/alt-opinion/synth.prompt.md +8 -0
  9. package/ai/skills/sdd-audit/SKILL.md +13 -0
  10. package/ai/skills/sdd-check/SKILL.md +139 -0
  11. package/ai/skills/sdd-continue/SKILL.md +13 -0
  12. package/ai/skills/sdd-critic/SKILL.md +12 -0
  13. package/ai/skills/sdd-discover/SKILL.md +13 -0
  14. package/ai/skills/sdd-execute/SKILL.md +205 -0
  15. package/ai/skills/sdd-execute/scripts/README.md +84 -0
  16. package/ai/skills/sdd-execute/scripts/check-blockers.sh +158 -0
  17. package/ai/skills/sdd-execute/scripts/classify-scripts.js +111 -0
  18. package/ai/skills/sdd-execute/scripts/classify-scripts.ts +133 -0
  19. package/ai/skills/sdd-execute/scripts/extract-section.sh +219 -0
  20. package/ai/skills/sdd-execute/scripts/lint-artifacts.sh +143 -0
  21. package/ai/skills/sdd-execute/scripts/scan.sh +385 -0
  22. package/ai/skills/sdd-execute/scripts/sdd +114 -0
  23. package/ai/skills/sdd-execute/scripts/verify.sh +139 -0
  24. package/ai/skills/sdd-execute-batch/SKILL.md +213 -0
  25. package/ai/skills/sdd-fix/SKILL.md +13 -0
  26. package/ai/skills/sdd-infra/SKILL.md +13 -0
  27. package/ai/skills/sdd-module-decomposition/SKILL.md +13 -0
  28. package/ai/skills/sdd-scaffold/SKILL.md +13 -0
  29. package/ai/skills/sdd-setup/SKILL.md +13 -0
  30. package/dist/ai/directives/coding/result-conventions.xml +25 -7
  31. package/dist/ai/directives/sdd/audit.directive.xml +1 -1
  32. package/dist/ai/directives/sdd/critic-protocol.xml +78 -0
  33. package/dist/ai/directives/sdd/critic.directive.xml +158 -0
  34. package/dist/ai/directives/sdd/phase-execution-protocol.xml +11 -9
  35. package/dist/ai/skills/alt-opinion/SKILL.md +79 -0
  36. package/dist/ai/skills/alt-opinion/opinion.prompt.md +11 -0
  37. package/dist/ai/skills/alt-opinion/synth.prompt.md +8 -0
  38. package/dist/ai/skills/sdd-audit/SKILL.md +13 -0
  39. package/dist/ai/skills/sdd-check/SKILL.md +139 -0
  40. package/dist/ai/skills/sdd-continue/SKILL.md +13 -0
  41. package/dist/ai/skills/sdd-critic/SKILL.md +12 -0
  42. package/dist/ai/skills/sdd-discover/SKILL.md +13 -0
  43. package/dist/ai/skills/sdd-execute/SKILL.md +205 -0
  44. package/dist/ai/skills/sdd-execute/scripts/README.md +84 -0
  45. package/dist/ai/skills/sdd-execute/scripts/check-blockers.sh +158 -0
  46. package/dist/ai/skills/sdd-execute/scripts/classify-scripts.js +111 -0
  47. package/dist/ai/skills/sdd-execute/scripts/classify-scripts.ts +133 -0
  48. package/dist/ai/skills/sdd-execute/scripts/extract-section.sh +219 -0
  49. package/dist/ai/skills/sdd-execute/scripts/lint-artifacts.sh +143 -0
  50. package/dist/ai/skills/sdd-execute/scripts/scan.sh +385 -0
  51. package/dist/ai/skills/sdd-execute/scripts/sdd +114 -0
  52. package/dist/ai/skills/sdd-execute/scripts/verify.sh +139 -0
  53. package/dist/ai/skills/sdd-execute-batch/SKILL.md +213 -0
  54. package/dist/ai/skills/sdd-fix/SKILL.md +13 -0
  55. package/dist/ai/skills/sdd-infra/SKILL.md +13 -0
  56. package/dist/ai/skills/sdd-module-decomposition/SKILL.md +13 -0
  57. package/dist/ai/skills/sdd-scaffold/SKILL.md +13 -0
  58. package/dist/ai/skills/sdd-setup/SKILL.md +13 -0
  59. package/dist/chunks/_commonjsHelpers-DaMA6jEr.js +8 -0
  60. package/dist/chunks/{devtools-B-7ugZhF.js → devtools-CPZ0IUNM.js} +1 -1
  61. package/dist/chunks/help-5qCaicff.js +6 -0
  62. package/dist/chunks/help-B2ETH0j6.js +6 -0
  63. package/dist/chunks/help-BCDURaCQ.js +6 -0
  64. package/dist/chunks/help-BvgYOSyQ.js +6 -0
  65. package/dist/chunks/help-CSPhOoI9.js +8 -0
  66. package/dist/chunks/help-CV1vpwrh.js +6 -0
  67. package/dist/chunks/help-CaBNA6Qr.js +12 -0
  68. package/dist/chunks/help-CjkR6SB9.js +6 -0
  69. package/dist/chunks/help-Coi1l5u9.js +8 -0
  70. package/dist/chunks/help-CsuLpZn-.js +8 -0
  71. package/dist/chunks/help-DL_QBMwy.js +8 -0
  72. package/dist/chunks/help-DqBZ2xcp.js +6 -0
  73. package/dist/chunks/help-_Y_TN4DZ.js +6 -0
  74. package/dist/chunks/{help.cmd-B_G7EWzF.js → help.cmd-BseRtoBF.js} +10 -2
  75. package/dist/chunks/{index-zBnnuvLA.js → index-BU1AXJGA.js} +12 -7
  76. package/dist/chunks/{index-CXuhZzS3.js → index-BXWDYM_9.js} +1 -1
  77. package/dist/chunks/index-BgKyH0dB.js +658 -0
  78. package/dist/chunks/{index-CaahtXiM.js → index-BghL1-Nk.js} +2 -2
  79. package/dist/chunks/{index-BeL1Zcbg.js → index-BlqEQEGy.js} +1 -1
  80. package/dist/chunks/{index-D1qsi0Uc.js → index-CDM74qdR.js} +3 -3
  81. package/dist/chunks/{index-D9ceRUyB.js → index-CGsIRefC.js} +2 -2
  82. package/dist/chunks/{index-CiEM-8nJ.js → index-CIvkaAQ3.js} +2 -2
  83. package/dist/chunks/{index-UbHoePfr.js → index-CkczJ__m.js} +10 -10
  84. package/dist/chunks/index-CtJKSOL0.js +21 -0
  85. package/dist/chunks/index-DEzym4Ae.js +369 -0
  86. package/dist/chunks/{index-CVR66voe.js → index-DoaxOhQ8.js} +401 -393
  87. package/dist/chunks/index-Du1xR-qO.js +752 -0
  88. package/dist/chunks/{index-DU6jD7SS.js → index-OtehG7uM.js} +1 -1
  89. package/dist/chunks/index-ZM_FonZj.js +156 -0
  90. package/dist/chunks/{index-g1LXlp77.js → index-k0nToACp.js} +2 -2
  91. package/dist/chunks/{run-review-command.logic-DpkRoEi8.js → run-review-command.logic-BeYQin-I.js} +9 -9
  92. package/dist/chunks/services-IgZptnTi.js +2732 -0
  93. package/dist/chunks/shared-DL_1LG0K.js +753 -0
  94. package/dist/cli/cmd/agent-mon/help.d.ts +4 -0
  95. package/dist/cli/cmd/agents-rules/agents-rules.cmd.d.ts +8 -0
  96. package/dist/cli/cmd/agents-rules/index.d.ts +1 -0
  97. package/dist/cli/cmd/alt-opinion/help.d.ts +4 -0
  98. package/dist/cli/cmd/cat/help.d.ts +4 -0
  99. package/dist/cli/cmd/commit/help.d.ts +4 -0
  100. package/dist/cli/cmd/lint/checks/anchor-class-body.check.d.ts +11 -0
  101. package/dist/cli/cmd/lint/checks/invariant-count.check.d.ts +11 -0
  102. package/dist/cli/cmd/lint/checks/utils/glob-match.d.ts +15 -0
  103. package/dist/cli/cmd/lint/checks/utils/strip-strings-comments.d.ts +7 -0
  104. package/dist/cli/cmd/lint/help.d.ts +4 -0
  105. package/dist/cli/cmd/lint/lint.cmd.d.ts +1 -1
  106. package/dist/cli/cmd/lint/lint.types.d.ts +6 -0
  107. package/dist/cli/cmd/orient/core/build-index.d.ts +8 -0
  108. package/dist/cli/cmd/orient/core/damerau-levenshtein.d.ts +26 -0
  109. package/dist/cli/cmd/orient/core/extract-header.d.ts +8 -0
  110. package/dist/cli/cmd/orient/core/hints.d.ts +9 -0
  111. package/dist/cli/cmd/orient/core/query-consumer.d.ts +10 -0
  112. package/dist/cli/cmd/orient/core/query-entity.d.ts +11 -0
  113. package/dist/cli/cmd/orient/core/query-graph.d.ts +18 -0
  114. package/dist/cli/cmd/orient/core/query-keyword.d.ts +10 -0
  115. package/dist/cli/cmd/orient/core/query-spec.d.ts +15 -0
  116. package/dist/cli/cmd/orient/core/query-task.d.ts +8 -0
  117. package/dist/cli/cmd/orient/core/scan-files.d.ts +8 -0
  118. package/dist/cli/cmd/orient/help.d.ts +5 -0
  119. package/dist/cli/cmd/orient/index.d.ts +1 -0
  120. package/dist/cli/cmd/orient/orient.cmd.d.ts +7 -0
  121. package/dist/cli/cmd/orient/orient.types.d.ts +136 -0
  122. package/dist/cli/cmd/orient/render/render-detail.d.ts +10 -0
  123. package/dist/cli/cmd/orient/render/render-file-list.d.ts +15 -0
  124. package/dist/cli/cmd/orient/render/render-graph.d.ts +13 -0
  125. package/dist/cli/cmd/orient/render/render-search.d.ts +8 -0
  126. package/dist/cli/cmd/orient/render/render-specs.d.ts +13 -0
  127. package/dist/cli/cmd/orient/render/render-tree.d.ts +13 -0
  128. package/dist/cli/cmd/remote-console/help.d.ts +4 -0
  129. package/dist/cli/cmd/resolve-conflicts/help.d.ts +4 -0
  130. package/dist/cli/cmd/review/help.d.ts +4 -0
  131. package/dist/cli/cmd/review-issues/help.d.ts +4 -0
  132. package/dist/cli/cmd/review-verify/help.d.ts +4 -0
  133. package/dist/cli/cmd/sync/help.d.ts +4 -0
  134. package/dist/cli/cmd/sync/sync-core.d.ts +3 -2
  135. package/dist/cli/cmd/sync/sync-formatter.d.ts +8 -9
  136. package/dist/cli/cmd/sync/sync.cmd.d.ts +2 -21
  137. package/dist/cli/cmd/sync-skills/index.d.ts +1 -0
  138. package/dist/cli/cmd/sync-skills/sync-skills-core.d.ts +50 -0
  139. package/dist/cli/cmd/sync-skills/sync-skills-formatter.d.ts +13 -0
  140. package/dist/cli/cmd/sync-skills/sync-skills.cmd.d.ts +14 -0
  141. package/dist/cli/cmd/sync-skills/sync-skills.types.d.ts +56 -0
  142. package/dist/cli/cmd/vcs-reply/help.d.ts +4 -0
  143. package/dist/gennady.js +73 -18
  144. package/dist/index.js +5 -5
  145. package/dist/services/dbc/linter/implementations/ts/dbc-ts-ast-adapter.d.ts +3 -2
  146. package/dist/shared/common/sync/path-normalizer.d.ts +22 -0
  147. package/dist/shared/common/sync/sync-core.shared.d.ts +14 -0
  148. package/dist/shared/common/sync/sync-deps.type.d.ts +66 -0
  149. package/dist/shared/common/sync/sync-formatter.shared.d.ts +19 -0
  150. package/package.json +6 -5
  151. package/dist/chunks/index-DJpVmyp2.js +0 -176
  152. package/dist/chunks/index-KxSZKmZn.js +0 -540
  153. package/dist/chunks/services-CaLOhuLV.js +0 -2889
  154. package/dist/chunks/shared-Bjy30TeM.js +0 -665
@@ -0,0 +1,753 @@
1
+ import { spawn as Y, execSync as j } from "node:child_process";
2
+ import f, { mkdirSync as V, readFileSync as O, existsSync as x } from "node:fs";
3
+ import d, { resolve as p, dirname as J, join as A } from "node:path";
4
+ import { platform as w, homedir as k } from "node:os";
5
+ import { fileURLToPath as L } from "node:url";
6
+ import { l as S } from "./services-IgZptnTi.js";
7
+ const X = 864e5, z = 3e3, q = "update-check-worker.ts", Q = "update-check-cache.json";
8
+ function Z(n) {
9
+ return w() === "win32" ? p(process.env.LOCALAPPDATA ?? p(k(), "AppData", "Local"), "gennady") : w() === "darwin" ? p(k(), "Library", "Caches", "gennady") : p(k(), ".cache", "gennady");
10
+ }
11
+ function ee(n) {
12
+ try {
13
+ const t = O(n, "utf-8"), r = JSON.parse(t);
14
+ return typeof r?.lastCheck != "string" || typeof r?.latestVersion != "string" ? null : r;
15
+ } catch {
16
+ return null;
17
+ }
18
+ }
19
+ function te(n, t) {
20
+ return Date.now() - new Date(n.lastCheck).getTime() < t;
21
+ }
22
+ function D(n, t) {
23
+ let r = !1;
24
+ process.on("beforeExit", () => {
25
+ r || (r = !0, process.stderr.write(`
26
+ Update available: ${n} → ${t}
27
+ `), process.stderr.write(`Run: npm i -g gennady@latest
28
+
29
+ `));
30
+ });
31
+ }
32
+ function je(n, t) {
33
+ if (process.env.GENNADY_NO_UPDATE_CHECK === "1" || process.argv.includes("--no-update-check")) {
34
+ process.env.GENNADY_DEBUG === "1" && process.stderr.write(
35
+ `[update-check] skipped: opt-out (GENNADY_NO_UPDATE_CHECK or --no-update-check)
36
+ `
37
+ );
38
+ return;
39
+ }
40
+ if (process.env.CI === "true" || process.env.CONTINUOUS_INTEGRATION === "true" || process.env.NODE_ENV === "test") {
41
+ process.env.GENNADY_DEBUG === "1" && process.stderr.write(`[update-check] skipped: CI/test environment
42
+ `);
43
+ return;
44
+ }
45
+ const r = Number(process.env.GENNADY_UPDATE_CHECK_INTERVAL) || X, e = Z(), o = p(e, Q);
46
+ V(e, { recursive: !0 });
47
+ const s = ee(o);
48
+ if (s && te(s, r)) {
49
+ s.latestVersion && s.latestVersion !== n.version && (process.stderr.isTTY || t?.skipNotificationIfNoTty === !1) && D(n.version, s.latestVersion);
50
+ return;
51
+ }
52
+ const i = p(J(L(import.meta.url)), q);
53
+ Y(
54
+ process.execPath,
55
+ [i, n.name, n.version, o, String(z)],
56
+ {
57
+ stdio: "ignore"
58
+ }
59
+ ).unref(), s?.latestVersion && s.latestVersion !== n.version && (process.stderr.isTTY || t?.skipNotificationIfNoTty === !1) && D(n.version, s.latestVersion);
60
+ }
61
+ const y = ["plain", "nocolor", "noColor", "no-color", "color=no", "color=never"].some(
62
+ (n) => process.argv.includes(`-${n}`) || process.argv.includes(`--${n}`)
63
+ ), h = {
64
+ // Modifiers
65
+ reset: "\x1B[0m",
66
+ bold: "\x1B[1m",
67
+ dim: "\x1B[2m",
68
+ italic: "\x1B[3m",
69
+ underline: "\x1B[4m",
70
+ overline: "\x1B[53m",
71
+ inverse: "\x1B[7m",
72
+ hidden: "\x1B[8m",
73
+ strikethrough: "\x1B[9m",
74
+ // Colors (foreground)
75
+ black: "\x1B[30m",
76
+ red: "\x1B[31m",
77
+ green: "\x1B[32m",
78
+ yellow: "\x1B[33m",
79
+ blue: "\x1B[34m",
80
+ magenta: "\x1B[35m",
81
+ cyan: "\x1B[36m",
82
+ white: "\x1B[37m",
83
+ gray: "\x1B[90m",
84
+ redBright: "\x1B[91m",
85
+ greenBright: "\x1B[92m",
86
+ yellowBright: "\x1B[93m",
87
+ blueBright: "\x1B[94m",
88
+ magentaBright: "\x1B[95m",
89
+ cyanBright: "\x1B[96m",
90
+ whiteBright: "\x1B[97m",
91
+ // Background colors
92
+ bgBlack: "\x1B[40m",
93
+ bgRed: "\x1B[41m",
94
+ bgGreen: "\x1B[42m",
95
+ bgYellow: "\x1B[43m",
96
+ bgBlue: "\x1B[44m",
97
+ bgMagenta: "\x1B[45m",
98
+ bgCyan: "\x1B[46m",
99
+ bgWhite: "\x1B[47m",
100
+ bgGray: "\x1B[100m",
101
+ bgRedBright: "\x1B[101m",
102
+ bgGreenBright: "\x1B[102m",
103
+ bgYellowBright: "\x1B[103m",
104
+ bgBlueBright: "\x1B[104m",
105
+ bgMagentaBright: "\x1B[105m",
106
+ bgCyanBright: "\x1B[106m",
107
+ bgWhiteBright: "\x1B[107m"
108
+ };
109
+ function I(n = []) {
110
+ const t = (r) => y ? r : n.join("") + r + h.reset;
111
+ return new Proxy(t, {
112
+ get(r, e) {
113
+ if (e === "toString")
114
+ return () => y ? "%s" : n.join("") + "%s" + h.reset;
115
+ if (e in h) {
116
+ const o = h[e];
117
+ return I(y ? [] : [...n, o].filter(Boolean));
118
+ }
119
+ },
120
+ apply(r, e, o) {
121
+ const s = o[0] ?? "";
122
+ return y ? s : n.join("") + s + h.reset;
123
+ }
124
+ });
125
+ }
126
+ const Oe = I(), Ie = (n, t = {}) => {
127
+ const r = { _: [] };
128
+ return n.slice(2).forEach((o) => {
129
+ if (o.startsWith("-")) {
130
+ const s = o.replace(/^-+/, ""), [i, a] = s.split("=");
131
+ for (const [c, l] of Object.entries(t))
132
+ if (Array.isArray(l) && i && l.includes(i)) {
133
+ const u = a ? a.replace(/^"|"$/g, "") : !0;
134
+ c in r ? (Array.isArray(r[c]) || (r[c] = [r[c]]), r[c].push(u)) : r[c] = u;
135
+ break;
136
+ }
137
+ } else
138
+ r._.push(o);
139
+ }), r;
140
+ }, ne = {
141
+ js: "JavaScript",
142
+ jsx: "JavaScript",
143
+ ts: "TypeScript",
144
+ tsx: "TypeScript",
145
+ java: "Java",
146
+ py: "Python",
147
+ c: "C",
148
+ cpp: "C++",
149
+ cs: "C#",
150
+ rb: "Ruby",
151
+ php: "PHP",
152
+ go: "Go",
153
+ swift: "Swift",
154
+ m: "Objective-C",
155
+ mm: "Objective-C++",
156
+ kt: "Kotlin",
157
+ sh: "Shell",
158
+ bash: "Shell",
159
+ html: "HTML",
160
+ css: "CSS",
161
+ less: "Less",
162
+ scss: "SCSS",
163
+ sass: "Sass",
164
+ md: "Markdown",
165
+ mdc: "Markdown"
166
+ }, b = (n) => ne[n] ?? void 0, Pe = () => {
167
+ try {
168
+ return j("osascript -e 'user locale of (get system info)'").toString().trim().toLowerCase().split("_").filter((r) => r !== "en" && r !== "us")[0] ?? "en";
169
+ } catch {
170
+ return "en";
171
+ }
172
+ }, v = (n) => {
173
+ const t = n.match(/[\p{L}\p{N}_]+|[^\s\p{L}\p{N}_]/gu);
174
+ return t ? t.length : 0;
175
+ }, se = [
176
+ "^package\\.json",
177
+ "^tsconfig\\.json",
178
+ "^babel\\.config\\.json",
179
+ "^\\.pnpmfile\\.cjs",
180
+ "^\\.yarnrc(?:\\.(?:yml|yaml))?",
181
+ "^go\\.(?:mod|sum)",
182
+ "^\\.env(?:\\.[\\w]+)?",
183
+ "^\\..+",
184
+ ".*\\.(?:yml|yaml|rc|ini|conf)"
185
+ ], re = [
186
+ "^package-lock\\.json",
187
+ "^npm-shrinkwrap\\.json",
188
+ "^yarn(?:-lock)?\\.(?:yaml|yml|toml)",
189
+ "^pnpm-lock\\.yaml",
190
+ "^composer\\.lock",
191
+ "^podfile\\.lock",
192
+ "^go\\.sum",
193
+ "^gemfile\\.lock"
194
+ ], oe = {
195
+ doc: /\.(md|markdown|txt|rst)$/i,
196
+ cfg: new RegExp(se.join("|"), "i"),
197
+ img: /\.(png|jpe?g|gif|svg|bmp|tiff|ico)$/i,
198
+ css: /\.(css|less|scss|sass|styl)$/i,
199
+ html: /\.(html?)$/i,
200
+ code: /\.(js|jsx|ts|tsx|java|py|c|cpp|cs|rb|php|go|swift|m|mm|kt|sh|bash)$/i,
201
+ bin: /^(exe|dll|so|bin)\b/i,
202
+ lock: new RegExp(re.join("|"), "i"),
203
+ json: /\.json$/i
204
+ }, B = (n, t) => {
205
+ if (t?.extra && Array.isArray(t.extra)) {
206
+ for (const e of t.extra)
207
+ if (/^Binary files? /i.test(e) || /GIT binary patch/i.test(e))
208
+ return "bin";
209
+ }
210
+ return Object.entries(oe).find(([, e]) => e.test(n))?.[0] ?? "other";
211
+ }, ae = (n) => {
212
+ const t = n.split(`
213
+ `), r = [];
214
+ let e = null, o = null;
215
+ if (t.forEach((s) => {
216
+ if (s.startsWith("diff --git")) {
217
+ if (e) {
218
+ e.diff.tokens = e.diff.hunks.reduce(
219
+ (u, m) => u + m.tokens,
220
+ 0
221
+ ), e.tokens = e.diff.tokens;
222
+ const l = e.filename.match(/\.([^.]+)$/);
223
+ e.ext = l?.[1]?.toLowerCase() ?? "", e.category = B(
224
+ e.filename,
225
+ e.metadata
226
+ ), e.programmingLanguage = b(e.ext), r.push(e);
227
+ }
228
+ const i = s.match(/^diff --git a\/(.+?) b\/(.+)$/), a = i?.[1] ?? null;
229
+ e = {
230
+ isNew: !1,
231
+ isDeleted: !1,
232
+ isRenamed: !1,
233
+ filename: i?.[2] ?? null ?? "",
234
+ oldFilename: a ?? null,
235
+ newFileMode: null,
236
+ deletedFileMode: null,
237
+ diff: {
238
+ tokens: 0,
239
+ hunks: []
240
+ },
241
+ tokens: 0,
242
+ metadata: {},
243
+ ext: "",
244
+ category: "other",
245
+ programmingLanguage: void 0
246
+ }, o = null;
247
+ } else if (e && s.startsWith("new file mode")) {
248
+ const i = s.split(" ");
249
+ e.isNew = !0, e.newFileMode = i[3] ?? null, e.metadata.newFileMode = e.newFileMode;
250
+ } else if (e && s.startsWith("deleted file mode")) {
251
+ const i = s.split(" ");
252
+ e.isDeleted = !0, e.deletedFileMode = i[3] ?? null, e.metadata.deletedFileMode = e.deletedFileMode;
253
+ } else if (e && s.startsWith("old mode")) {
254
+ const i = s.split(" ");
255
+ e.metadata.oldMode = i[2] ?? null;
256
+ } else if (e && s.startsWith("new mode")) {
257
+ const i = s.split(" ");
258
+ e.metadata.newMode = i[2] ?? null;
259
+ } else if (e && s.startsWith("similarity index")) {
260
+ const i = s.split(" ");
261
+ e.metadata.similarityIndex = i[2] ?? null;
262
+ } else if (e && s.startsWith("rename from")) {
263
+ const i = s.substring(11).trim();
264
+ e.isRenamed = !0, e.oldFilename = i, e.metadata.renameFrom = i;
265
+ } else if (e && s.startsWith("rename to")) {
266
+ const i = s.substring(9).trim();
267
+ e.isRenamed = !0, e.filename = i, e.metadata.renameTo = i;
268
+ } else e && s.startsWith("index") ? e.metadata.index = s.substring(5).trim() : e && (s.startsWith("--- ") || s.startsWith("+++ ")) ? s.startsWith("--- ") ? e.metadata.oldFileMarker = s : e.metadata.newFileMarker = s : e && s.startsWith("@@") ? (o = {
269
+ header: s,
270
+ changes: [s],
271
+ tokens: v(s)
272
+ }, e.diff.hunks.push(o)) : o && (s.startsWith("+") || s.startsWith("-") || s.startsWith(" ")) ? (o.changes.push(s), o.tokens += v(s)) : e && (Array.isArray(e.metadata.extra) || (e.metadata.extra = []), e.metadata.extra.push(s));
273
+ }), e) {
274
+ const s = e, i = s.filename.match(/\.([^.]+)$/);
275
+ s.diff.tokens = s.diff.hunks.reduce(
276
+ (a, c) => a + c.tokens,
277
+ 0
278
+ ), s.tokens = s.diff.tokens, s.ext = i?.[1]?.toLowerCase() ?? "", s.category = B(s.filename, s.metadata), s.programmingLanguage = b(s.ext), r.push(s);
279
+ }
280
+ return r;
281
+ }, g = (n) => {
282
+ try {
283
+ return j(n, { encoding: "utf-8" });
284
+ } catch (t) {
285
+ return S.error("[execSyncSafe] [running → failed] Command failed", { cause: t }), "";
286
+ }
287
+ }, R = (n) => /\.(test|spec)s?\./.test(n), ie = () => g("git branch --list 2>/dev/null")?.match(/\s*\*?\s*(master|main)$/m)?.[1] ?? "master", Me = () => g("git rev-parse --abbrev-ref HEAD 2>/dev/null").trim() || "HEAD", Ue = () => {
288
+ const t = (g("git config --get remote.origin.url 2>/dev/null").trim() || g("git remote get-url origin 2>/dev/null").trim() || "").trim();
289
+ if (!t) return null;
290
+ if (/^[a-z]+:\/\//i.test(t))
291
+ try {
292
+ const e = new URL(t), o = (e.hostname || "").toLowerCase(), s = (e.protocol || "").replace(/:$/, "").toLowerCase(), i = (e.pathname || "").replace(/^\/+/, "").replace(/\.git$/i, "");
293
+ return !o || !i ? null : { host: o, project: i, scheme: s };
294
+ } catch (e) {
295
+ S.debug("[getGitRemote] [parsing → skip] URL parse failed", { cause: e });
296
+ }
297
+ const r = t.match(/^[\w.-]+@([^:\/]+)[:\/](.+)$/);
298
+ if (r) {
299
+ const e = (r[1] || "").toLowerCase(), o = (r[2] || "").replace(/^\/+/, "").replace(/\.git$/i, ""), s = "ssh";
300
+ return !e || !o ? null : { host: e, project: o, scheme: s };
301
+ }
302
+ return null;
303
+ }, ce = () => {
304
+ try {
305
+ const n = g(`git rev-list --count HEAD ^${ie()} 2>/dev/null`);
306
+ return parseInt(n, 10) || 0;
307
+ } catch (n) {
308
+ return S.debug("[getGitCommitCount] [counting → fallback] Using 0", { cause: n }), 0;
309
+ }
310
+ }, le = (n) => g(n ? `git diff ${n}` : "git diff HEAD"), Fe = (n) => {
311
+ const t = le(n), r = ae(t).sort((a, c) => a.tokens - c.tokens), e = r.filter(
312
+ (a) => !a.isDeleted && !a.isRenamed && !R(a.filename) && (a.category === "config" || a.programmingLanguage)
313
+ );
314
+ e.length || e.push(
315
+ ...r.filter(
316
+ (a) => !a.isDeleted && !a.isRenamed && (a.category === "doc" || R(a.filename))
317
+ )
318
+ );
319
+ const o = e.reduce((a, c) => a + c.tokens, 0), s = e.at(-1)?.tokens ?? 0, i = [
320
+ ...new Set(e.map((a) => a.programmingLanguage).filter(Boolean))
321
+ ];
322
+ return {
323
+ diff: t,
324
+ parsedDiff: r,
325
+ parsedCodeDiff: e,
326
+ parsedCodeTokens: o,
327
+ parsedCodeChunkMaxTokens: s,
328
+ programmingLanguages: i,
329
+ commitCount: ce()
330
+ };
331
+ }, ue = (n) => {
332
+ if (Array.isArray(n) && n.length === 2) {
333
+ const t = n[1];
334
+ if (t === null)
335
+ return n[0];
336
+ throw t instanceof Error ? t : new TypeError(`[UNGUARD_ERROR_TYPE] Error "${t}"`, { cause: t });
337
+ }
338
+ throw new SyntaxError(
339
+ "[UNGUARD_ERROR_SYNTAX] Invalid input: not a valid [result, error] tuple.",
340
+ { cause: n }
341
+ );
342
+ }, Ge = async (n) => {
343
+ const t = await n;
344
+ return ue(t);
345
+ }, N = "</think>", We = (n) => {
346
+ const t = String(n ?? "").split(N).slice(-1).join(N).trim();
347
+ return /^(Хорошо,|Okay,)/.test(t) ? t.split(`
348
+
349
+
350
+ `).slice(-1).join(`
351
+
352
+
353
+ `).trim() : t;
354
+ };
355
+ class C {
356
+ /** @purpose Default configuration filename. */
357
+ static DEFAULT_FILENAME = ".gennadyrc";
358
+ /**
359
+ * @purpose Create GennadyRc instances for current directory and HOME (lookup priority).
360
+ * @returns Array of two instances: [cwd, HOME].
361
+ * @sideEffect IO: file read at constructor.
362
+ */
363
+ static getDefaults() {
364
+ return [process.cwd(), process.env.HOME].map((t) => new C(t));
365
+ }
366
+ /** @purpose Full path to the loaded rc config file. */
367
+ _filename = "";
368
+ /** @purpose Parsed configuration data with model list. */
369
+ _data = {
370
+ models: []
371
+ };
372
+ /** @purpose Load/parse error if config is invalid, null otherwise. */
373
+ _error = null;
374
+ /**
375
+ * @purpose Load and parse Gennady RC config file from a directory.
376
+ * @param [dir] Directory to look for the rc file in (defaults to cwd).
377
+ * @param [name] Config filename (defaults to .gennadyrc).
378
+ */
379
+ constructor(t = process.cwd(), r = C.DEFAULT_FILENAME) {
380
+ this._filename = A(t, r);
381
+ try {
382
+ if (x(this._filename)) {
383
+ const e = JSON.parse(O(this._filename).toString());
384
+ Array.isArray(e) ? this._data.models = e : e && typeof e == "object" && Array.isArray(e.models) ? this._data = {
385
+ ...this._data,
386
+ ...e
387
+ } : this._error = new Error(
388
+ `[GENNADY_RC_ERROR_CONFIG] Invalid "${this._filename}" config data`,
389
+ { cause: e }
390
+ );
391
+ }
392
+ } catch (e) {
393
+ this._error = new Error(`[GENNADY_RC_ERROR_PARSE] Read "${this._filename}" config failed`, {
394
+ cause: e
395
+ });
396
+ }
397
+ }
398
+ /**
399
+ * @purpose Check that configuration was successfully loaded and recognized.
400
+ * @returns true if no error; false on parse error or invalid data.
401
+ */
402
+ isValid() {
403
+ return !this._error;
404
+ }
405
+ /**
406
+ * @purpose Get list of models from loaded rc.
407
+ * @returns Array of RcModel (empty on error or missing file).
408
+ */
409
+ getModels() {
410
+ return this._data.models;
411
+ }
412
+ /**
413
+ * @purpose Get load/parse error if one occurred.
414
+ * @returns Error or null on successful load.
415
+ */
416
+ getError() {
417
+ return this._error;
418
+ }
419
+ }
420
+ function He(n) {
421
+ const t = String(n).match(/<message[\s\S]*?>[\s\S]*?<\/message>/)?.[0];
422
+ if (!t)
423
+ return null;
424
+ const r = (a) => t.match(a)?.[1] ?? "", e = r(/type="([^"]+)"/), o = r(/icon="([^"]+)"/), s = r(/<subject>([\s\S]*?)<\/subject>/), i = r(/<description>([\s\S]*?)<\/description>/).replace(/\n\s+-/g, `
425
+ -`);
426
+ return {
427
+ type: e,
428
+ icon: o,
429
+ subject: s?.trim() || null,
430
+ description: i?.trim() || null
431
+ };
432
+ }
433
+ function _(n) {
434
+ return n ? String(n).replace(/[<>&'"]/g, (t) => {
435
+ switch (t) {
436
+ case "<":
437
+ return "&lt;";
438
+ case ">":
439
+ return "&gt;";
440
+ case "&":
441
+ return "&amp;";
442
+ case "'":
443
+ return "&apos;";
444
+ case '"':
445
+ return "&quot;";
446
+ default:
447
+ return t;
448
+ }
449
+ }) : "";
450
+ }
451
+ function T(n, t = 0) {
452
+ const r = " ".repeat(t), { tag: e, attrs: o, children: s } = n;
453
+ let i = "";
454
+ if (o && (i = Object.entries(o).filter(([, c]) => c != null).map(([c, l]) => ` ${c}="${_(String(l))}"`).join("")), s == null)
455
+ return `${r}<${e}${i} />`;
456
+ if (Array.isArray(s) && s.length === 0)
457
+ return `${r}<${e}${i} />`;
458
+ let a = "";
459
+ return Array.isArray(s) ? s.length > 0 && typeof s[0] == "string" ? a = s.map((l) => _(l)).join(`
460
+ `) : a = `
461
+ ` + s.map((l) => T(l, t + 1)).join(`
462
+ `) + `
463
+ ` + r : typeof s == "string" ? a = _(s) : "cdata" in s ? a = `<![CDATA[${String(s.cdata).replaceAll("]]>", "]]]]><![CDATA[>")}]]>` : a = `
464
+ ` + T(s, t + 1) + `
465
+ ` + r, `${r}<${e}${i}>${a}</${e}>`;
466
+ }
467
+ function Ke(n) {
468
+ const t = [
469
+ "ai.knowledge.md",
470
+ "ai/ai.knowledge.md"
471
+ ], r = [];
472
+ for (const e of t) {
473
+ const o = d.join(n, e);
474
+ try {
475
+ f.existsSync(o) && f.statSync(o).isFile() && r.push(e);
476
+ } catch {
477
+ }
478
+ }
479
+ return r.length === 0 ? "" : `**MUST READ PROJECT KNOWLEDGE FILES**: ${r.join(", ")}.`;
480
+ }
481
+ const de = [
482
+ {
483
+ kind: "marker",
484
+ relativePath: "go.mod",
485
+ commands: ["go test ./...", "go vet ./...", "go fmt ./..."]
486
+ },
487
+ {
488
+ kind: "npm-package-json",
489
+ scriptGroups: [
490
+ {
491
+ preferredNames: [
492
+ "test",
493
+ "test:run",
494
+ "test:ci",
495
+ "test:app",
496
+ "mc:test",
497
+ "unit",
498
+ "jest",
499
+ "vitest"
500
+ ],
501
+ fallbackPatterns: [/(^|:)test($|:)/i, /(^|:)unit($|:)/i, /(^|:)spec($|:)/i]
502
+ },
503
+ {
504
+ preferredNames: ["lint:ci", "lint", "eslint", "stylelint", "format:check"],
505
+ fallbackPatterns: [/(^|:)(lint|eslint|stylelint)($|:)/i]
506
+ },
507
+ {
508
+ preferredNames: ["type-check", "typecheck", "check"],
509
+ fallbackPatterns: [/(^|:)(typecheck|type-check|check)($|:)/i]
510
+ }
511
+ ],
512
+ maxCommands: 5
513
+ },
514
+ {
515
+ kind: "marker",
516
+ relativePath: "Cargo.toml",
517
+ commands: ["cargo test", "cargo clippy"]
518
+ }
519
+ ];
520
+ function fe(n, t) {
521
+ const r = d.join(n, t);
522
+ try {
523
+ return f.existsSync(r) && f.statSync(r).isFile();
524
+ } catch {
525
+ return !1;
526
+ }
527
+ }
528
+ function me(n, t) {
529
+ const r = n.toLowerCase(), e = t.toLowerCase();
530
+ return /(^|:|-)watch($|:|-)/i.test(r) ? !0 : [
531
+ /(^|\s)--watch(?:[=\s]|$)/i,
532
+ /(^|\s)--watchall(?:[=\s]|$)/i,
533
+ /(^|\s)watch(?:\s|$)/i,
534
+ /(^|\s)nodemon(?:\s|$)/i
535
+ ].some((s) => s.test(e));
536
+ }
537
+ function ge(n, t, r) {
538
+ const e = Object.entries(n).filter(
539
+ ([o, s]) => !r.has(o) && !me(o, s)
540
+ );
541
+ for (const o of t.preferredNames)
542
+ if (e.some(([s]) => s === o))
543
+ return o;
544
+ for (const [o] of e)
545
+ if (t.fallbackPatterns.some((s) => s.test(o)))
546
+ return o;
547
+ return null;
548
+ }
549
+ function pe(n, t) {
550
+ const r = d.join(n, "package.json");
551
+ let e;
552
+ try {
553
+ if (!f.existsSync(r) || !f.statSync(r).isFile())
554
+ return null;
555
+ e = f.readFileSync(r, "utf-8");
556
+ } catch {
557
+ return null;
558
+ }
559
+ let o;
560
+ try {
561
+ o = JSON.parse(e);
562
+ } catch {
563
+ return null;
564
+ }
565
+ const s = o.scripts;
566
+ if (!s || typeof s != "object")
567
+ return null;
568
+ const i = [], a = /* @__PURE__ */ new Set();
569
+ for (const c of t.scriptGroups) {
570
+ const l = ge(s, c, a);
571
+ if (l && (i.push(`npm run ${l}`), a.add(l)), i.length >= t.maxCommands)
572
+ break;
573
+ }
574
+ return i.length === 0 ? null : i.slice(0, t.maxCommands);
575
+ }
576
+ function he(n) {
577
+ for (const t of de) {
578
+ if (t.kind === "marker") {
579
+ if (fe(n, t.relativePath))
580
+ return [...t.commands];
581
+ continue;
582
+ }
583
+ if (t.kind === "npm-package-json") {
584
+ const r = pe(n, t);
585
+ if (r != null && r.length > 0)
586
+ return r;
587
+ }
588
+ }
589
+ return [];
590
+ }
591
+ function ye(n) {
592
+ return n.map((t) => `\`${t}\``).join(", ");
593
+ }
594
+ function Ye(n) {
595
+ const t = he(n);
596
+ if (t.length === 0)
597
+ return {
598
+ axiomHint: "как в README или CI принято проверять код (тесты, линтер, типы). Не подменяй это тяжёлой production-сборкой или публикацией, если это явно не описано как проверка",
599
+ toolsExample: "команды из `package.json` → `scripts`, из Makefile или из CI-шагов, которые относятся к качеству кода; сначала прочитай README",
600
+ verifyStep: "Прочитай README и при наличии — конфиг CI: какие команды запускают тесты, линтер и проверку типов. Выполни их из корня репозитория. Не запускай `build`/`publish`/полный `ci`, если не уверен, что это нужно для проверки изменений; при сомнении спроси пользователя."
601
+ };
602
+ const r = ye(t);
603
+ return {
604
+ axiomHint: `\`${t[0]}\` или следующую команду из того же набора проверок`,
605
+ toolsExample: r,
606
+ verifyStep: `Из корня репозитория выполни: ${r}. Не добавляй \`build\`, полный \`ci\` или публикацию, если они не перечислены здесь и не описаны в README как обязательная проверка.`
607
+ };
608
+ }
609
+ const E = "ai/agents";
610
+ function $(n) {
611
+ return f.existsSync(n) ? f.promises.readFile(n, "utf-8") : null;
612
+ }
613
+ function Ee(n) {
614
+ let t = n;
615
+ for (; ; ) {
616
+ const r = d.join(t, "package.json");
617
+ if (f.existsSync(r))
618
+ return t;
619
+ const e = d.dirname(t);
620
+ if (e === t)
621
+ return null;
622
+ t = e;
623
+ }
624
+ }
625
+ async function Ve(n) {
626
+ const t = d.dirname(L(import.meta.url)), r = d.join(process.cwd(), E, n), e = $(r);
627
+ if (e)
628
+ return e;
629
+ const o = Ee(t), s = [];
630
+ o ? (s.push(d.join(o, E, n)), s.push(d.join(o, "dist", E, n))) : s.push(
631
+ d.join(t, "../../../../../../dist", E, n)
632
+ );
633
+ for (const i of s) {
634
+ const a = $(i);
635
+ if (a)
636
+ return a;
637
+ }
638
+ throw new Error(`Не найден файл шаблона ${n}.`, {
639
+ cause: {
640
+ projectOverridePath: r,
641
+ packageCandidates: s
642
+ }
643
+ });
644
+ }
645
+ function Je(n, t) {
646
+ try {
647
+ const r = A(n, "node_modules", "gennady", t);
648
+ if (x(r)) return r;
649
+ } catch {
650
+ }
651
+ try {
652
+ const r = import.meta.resolve("gennady"), o = L(r).replace(/[/\\]dist[/\\].*$/, ""), s = A(o, t);
653
+ if (x(s)) return s;
654
+ } catch {
655
+ }
656
+ return null;
657
+ }
658
+ function Xe(n, t) {
659
+ return !Buffer.isBuffer(n) || !Buffer.isBuffer(t) ? !0 : Buffer.compare(n, t) !== 0;
660
+ }
661
+ function ze(n, t) {
662
+ let r = n;
663
+ for (const e of t)
664
+ r = r.replace(e.from, e.to);
665
+ return r;
666
+ }
667
+ const P = {
668
+ from: /npx\s+tsx\s+~\/Developer\/gennady\/cli\/gennady\.ts\b/g,
669
+ to: "npx gennady"
670
+ }, M = {
671
+ from: /npx tsx ~\/Developer\/gennady\/cli[ \t]+/g,
672
+ to: "npx gennady "
673
+ }, U = {
674
+ from: /~\/Developer\/gennady\/cli\/gennady\.ts/g,
675
+ to: "npx gennady"
676
+ }, ke = {
677
+ from: /~\/Developer\/gennady\/ai\/skills\//g,
678
+ to: ".claude/skills/"
679
+ }, F = {
680
+ from: /~\/Developer\/gennady\/ai\/directives\//g,
681
+ to: "ai/directives/"
682
+ }, G = {
683
+ from: /\/Users\/k\.lebedev\/Developer\/gennady\/ai\//g,
684
+ to: "ai/"
685
+ }, W = {
686
+ from: /\/Users\/k\.lebedev\/Developer\/gennady\/cli\/gennady\.ts/g,
687
+ to: "npx gennady"
688
+ }, H = {
689
+ from: /\$HOME\/Developer\/gennady\/cli\/gennady\.ts\b/g,
690
+ to: "~/Developer/gennady/cli/gennady.ts"
691
+ }, qe = [
692
+ P,
693
+ M,
694
+ U,
695
+ F,
696
+ G,
697
+ W,
698
+ H
699
+ ], Qe = [
700
+ P,
701
+ M,
702
+ U,
703
+ ke,
704
+ F,
705
+ G,
706
+ W,
707
+ H
708
+ ], _e = "+", xe = "~", Ae = "-", Ce = "=", Le = "(unchanged)", Se = "(would add)", we = "(would update)", De = "(would delete)", be = "(unchanged, skip)";
709
+ function Ze(n, t = {}) {
710
+ const r = [];
711
+ for (const a of n) {
712
+ const { relativePath: c, status: l } = a;
713
+ let u, m;
714
+ l === "added" ? (u = _e, m = t.dryRun ? Se : "") : l === "updated" ? (u = xe, m = t.dryRun ? we : "") : l === "deleted" ? (u = Ae, m = t.dryRun ? De : "") : (u = Ce, m = t.dryRun ? be : Le);
715
+ const K = c.padEnd(64);
716
+ m ? r.push(` ${u} ${K} ${m}`) : r.push(` ${u} ${c}`);
717
+ }
718
+ const e = n.filter((a) => a.status === "added").length, o = n.filter((a) => a.status === "updated").length, s = n.filter((a) => a.status === "unchanged").length, i = n.filter((a) => a.status === "deleted").length;
719
+ if (t.dryRun)
720
+ r.push("Dry-run: no files written.");
721
+ else {
722
+ let a = `Synced: ${e} added, ${o} updated, ${s} skipped (unchanged)`;
723
+ i > 0 && (a += `, ${i} deleted`), r.push(a);
724
+ }
725
+ return r;
726
+ }
727
+ export {
728
+ C as G,
729
+ qe as S,
730
+ Ue as a,
731
+ Xe as b,
732
+ je as c,
733
+ Qe as d,
734
+ g as e,
735
+ Ze as f,
736
+ Fe as g,
737
+ Me as h,
738
+ T as i,
739
+ Ye as j,
740
+ Ke as k,
741
+ Ve as l,
742
+ We as m,
743
+ ze as n,
744
+ b as o,
745
+ Ie as p,
746
+ Pe as q,
747
+ Je as r,
748
+ Oe as s,
749
+ ae as t,
750
+ Ge as u,
751
+ ue as v,
752
+ He as x
753
+ };