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,96 +0,0 @@
1
- import { p as v, c as h, d as x, V as j, r as p } from "./shared-B5CTGvpG.js";
2
- import { mkdtempSync as C, writeFileSync as V } from "node:fs";
3
- import { tmpdir as y } from "node:os";
4
- import { join as w } from "node:path";
5
- import { l as t } from "./services-Csd556Tv.js";
6
- function F() {
7
- return {
8
- resolveVcsContext: p,
9
- stdout: process.stdout,
10
- stderr: process.stderr,
11
- exit: (o) => process.exit(o)
12
- };
13
- }
14
- async function I(o, e) {
15
- try {
16
- t.debug("[resolveContextOrFail] [idle → resolving]");
17
- const r = await e.resolveVcsContext(o);
18
- return t.info(
19
- `[resolveContextOrFail] [resolving → resolved] ${r.host}/${r.project}${r.iid ? `!${r.iid}` : ""}`
20
- ), r;
21
- } catch (r) {
22
- r instanceof j && (t.error(
23
- `[resolveContextOrFail] [resolving → failed] ${r.message}`,
24
- { cause: r }
25
- ), e.stderr.write(`✖ Ошибка: ${r.message}
26
- `), e.exit(1));
27
- const n = new Error("[resolveContextOrFail] VCS context resolution failed", { cause: r });
28
- t.error("[resolveContextOrFail] [resolving → failed]", { error: n }), e.stderr.write(`✖ Ошибка: ${r.message ?? "неизвестная ошибка"}
29
- `), e.exit(1);
30
- }
31
- }
32
- function g(o) {
33
- const e = o.match(/(\d+)$/);
34
- return e ? e[1] : o;
35
- }
36
- function O(o, e) {
37
- const r = o.jobs.find((i) => g(i.id) === e);
38
- if (r) return g(r.id);
39
- const n = o.jobs.find((i) => i.name === e);
40
- if (n) return g(n.id);
41
- throw new Error(`[resolveJobId] Job not found: ${e}`);
42
- }
43
- async function P(o, e = F()) {
44
- t.debug("[run] [idle → parsing]");
45
- const r = v(o, {
46
- ref: { aliases: ["ref"], takesValue: !0 },
47
- host: { aliases: ["host", "vcs-host"], takesValue: !0 },
48
- url: { aliases: ["url"], takesValue: !0 },
49
- job: { aliases: ["job"], takesValue: !0 },
50
- raw: { aliases: ["raw"] }
51
- }), n = {
52
- ref: r.ref,
53
- host: r.host,
54
- url: r.url
55
- }, i = r.job, $ = !!r.raw;
56
- i || (e.stderr.write(`✖ Ошибка: --job <name|id> обязателен
57
- `), e.exit(1)), t.debug(
58
- `[run] [parsing → parsed] job=${i} ref=${n.ref ?? ""} host=${n.host ?? ""}`
59
- );
60
- const s = await I(n, e);
61
- let c;
62
- s.iid !== void 0 ? (c = s.iid, t.debug(`[run] [determining-iid → explicit] iid=${c}`)) : (e.stderr.write(`✖ Ошибка: vcs-job-log требует явный MR ref (--ref group/repo!iid)
63
- `), e.exit(1));
64
- const f = h(s);
65
- f.Pipeline || (e.stderr.write(`✖ Ошибка: Pipeline API не поддерживается данным VCS-клиентом
66
- `), e.exit(1));
67
- try {
68
- t.debug(`[run] [resolved → fetching-pipeline] ${s.project}!${c}`);
69
- const a = await f.MergeRequests.getPipeline({
70
- project: s.project,
71
- iid: c
72
- });
73
- t.info(
74
- `[run] [fetching-pipeline → fetched] status=${a.status || "none"} jobs=${a.jobs.length}`
75
- );
76
- const l = O(a, i);
77
- t.debug(`[run] [resolving-job → resolved] spec=${i} id=${l}`), t.debug(`[run] [idle → fetching-log] ${l}`);
78
- const u = await f.Pipeline.getJobLog({ project: s.project, jobId: l });
79
- t.info(`[run] [fetching-log → fetched] ${l} length=${u.length}`), $ && (e.stdout.write(u), e.exit(0));
80
- const m = C(w(y(), "gennady-job-log-")), d = w(m, "raw.log");
81
- V(d, u, "utf-8"), t.debug(`[run] [raw-log → saved] ${d}`);
82
- const b = x(u);
83
- b.trim() ? (e.stdout.write(b), e.stdout.write(`
84
- `)) : e.stdout.write(`(empty — no error lines detected)
85
- `), e.stdout.write(`
86
- 📁 Полный лог: ${d} (--raw для вывода без фильтрации)
87
- `), e.exit(0);
88
- } catch (a) {
89
- const l = new Error(`[run] Fetch failed for ${s.project}!${c} job=${i}`, {
90
- cause: a
91
- });
92
- t.error("[run] [fetching → failed]", { error: l }), e.stderr.write(`✖ GitLab API error: ${a.message ?? "неизвестная ошибка"}
93
- `), e.exit(1);
94
- }
95
- }
96
- await P(process.argv);
@@ -1,377 +0,0 @@
1
- import { readdirSync as $, statSync as L, readFileSync as N, rmdirSync as O, unlinkSync as x, mkdirSync as T, writeFileSync as W } from "node:fs";
2
- import { join as k, sep as K } from "node:path";
3
- import { fileURLToPath as z } from "node:url";
4
- import { l as I } from "./services-CwvXl2MB.js";
5
- import { au as B, az as b, av as M, p as j, aw as G } from "./shared-DSZTUx5b.js";
6
- class H {
7
- /** @purpose List of all synced file entries, sorted lexicographically by skillName then relativePath. */
8
- entries;
9
- /**
10
- * @purpose Construct a SyncSkillsResult from a list of entries.
11
- * @param entries File entries.
12
- */
13
- constructor(e) {
14
- this.entries = e;
15
- }
16
- /** @purpose Files with status "added". | @returns Array of added entries. */
17
- get added() {
18
- return this.entries.filter((e) => e.status === "added");
19
- }
20
- /** @purpose Files with status "updated". | @returns Array of updated entries. */
21
- get updated() {
22
- return this.entries.filter((e) => e.status === "updated");
23
- }
24
- /** @purpose Files with status "deleted". | @returns Array of deleted entries. */
25
- get deleted() {
26
- return this.entries.filter((e) => e.status === "deleted");
27
- }
28
- /** @purpose Files with status "unchanged". | @returns Array of unchanged entries. */
29
- get unchanged() {
30
- return this.entries.filter((e) => e.status === "unchanged");
31
- }
32
- /** @purpose Files with status "deleteFailed". | @returns Array of delete-failed entries. */
33
- get deleteFailed() {
34
- return this.entries.filter((e) => e.status === "deleteFailed");
35
- }
36
- /** @purpose Human-readable summary of sync counts. | @returns Summary string. */
37
- get summary() {
38
- const e = this.added.length, r = this.updated.length, a = this.unchanged.length, l = this.deleted.length, i = this.deleteFailed.length;
39
- let c = `Synced: ${e} added, ${r} updated, ${a} skipped, ${l} deleted`;
40
- return i > 0 && (c += `, ${i} delete failed`), c;
41
- }
42
- /** @purpose Dry-run summary message. | @returns Dry-run message. */
43
- get dryRunSummary() {
44
- return "Dry-run: no files written.";
45
- }
46
- }
47
- const C = "ERR_SKILLS_SOURCE_NOT_FOUND", R = "ERR_SKILLS_SKILL_NOT_FOUND", v = /* @__PURE__ */ new Set([".DS_Store"]);
48
- function J(t, e) {
49
- const r = $(t).filter((i) => {
50
- if (i.startsWith(".") || v.has(i)) return !1;
51
- try {
52
- return L(k(t, i)).isDirectory();
53
- } catch {
54
- return !1;
55
- }
56
- }), a = e && e.length > 0 ? e : r;
57
- for (const i of a)
58
- if (!r.includes(i)) {
59
- const c = `[scanSkills] Skill "${i}" not found in source.
60
- Available: ${r.join(", ")}`, n = new Error(c);
61
- throw n.code = R, n;
62
- }
63
- const l = /* @__PURE__ */ new Map();
64
- for (const i of a) {
65
- const c = k(t, i), n = /* @__PURE__ */ new Map();
66
- P(c, "", void 0, n), l.set(i, n);
67
- }
68
- return l;
69
- }
70
- function P(t, e, r, a) {
71
- const l = r ? r.readdir : $, i = r ? r.stat : L, c = r ? r.readFile : N;
72
- let n;
73
- try {
74
- n = l(t);
75
- } catch {
76
- return;
77
- }
78
- for (const d of n) {
79
- if (d.startsWith(".") || v.has(d)) continue;
80
- const g = k(t, d), y = e ? k(e, d) : d;
81
- let s;
82
- try {
83
- s = i(g);
84
- } catch {
85
- continue;
86
- }
87
- if (s) {
88
- if (s.isDirectory())
89
- P(g, y, r, a);
90
- else if (s.isFile()) {
91
- const u = y.split(K).join("/");
92
- a.set(u, c(g));
93
- }
94
- }
95
- }
96
- }
97
- function V(t, e, r, a, l, i, c, n) {
98
- let d;
99
- if (a ? M(r, a) ? d = "updated" : d = "unchanged" : d = "added", !i && d !== "unchanged") {
100
- const g = k(l, e);
101
- n(k(g, ".."), { recursive: !0 }), c(g, r);
102
- }
103
- return {
104
- skillName: t,
105
- relativePath: e,
106
- status: d,
107
- sourceSize: r.length,
108
- targetSize: a?.length
109
- };
110
- }
111
- function F(t, e) {
112
- const r = [];
113
- let a;
114
- try {
115
- a = e.readdir(t);
116
- } catch {
117
- return r;
118
- }
119
- for (const l of a) {
120
- if (l.startsWith(".") || v.has(l)) continue;
121
- const i = k(t, l);
122
- try {
123
- const c = e.stat(i);
124
- c.isDirectory() ? r.push(...F(i, e).map((n) => k(l, n))) : c.isFile() && r.push(l);
125
- } catch {
126
- }
127
- }
128
- return r;
129
- }
130
- function X(t, e, r, a) {
131
- const l = k(e, t);
132
- let i = [];
133
- try {
134
- i = F(l, a);
135
- } catch {
136
- }
137
- if (r) {
138
- const y = [
139
- {
140
- skillName: t,
141
- relativePath: "",
142
- status: "deleted",
143
- sourceSize: void 0,
144
- targetSize: void 0
145
- }
146
- ];
147
- for (const s of i.sort())
148
- y.push({
149
- skillName: t,
150
- relativePath: s,
151
- status: "deleted",
152
- sourceSize: void 0,
153
- targetSize: void 0
154
- });
155
- return y;
156
- }
157
- const c = a.unlink ?? (() => {
158
- }), n = a.rmdir ?? (() => {
159
- });
160
- let d = !1, g;
161
- for (const y of i) {
162
- const s = k(l, y);
163
- try {
164
- c(s);
165
- } catch (u) {
166
- d = !0, g = u.code ?? "UNKNOWN";
167
- }
168
- }
169
- try {
170
- n(l, { recursive: !0 });
171
- } catch (y) {
172
- d = !0, g = y.code ?? "UNKNOWN";
173
- }
174
- return d ? [
175
- {
176
- skillName: t,
177
- relativePath: "",
178
- status: "deleteFailed",
179
- errorCode: g
180
- }
181
- ] : [
182
- {
183
- skillName: t,
184
- relativePath: "",
185
- status: "deleted"
186
- }
187
- ];
188
- }
189
- function Y(t, e) {
190
- let r;
191
- try {
192
- r = t.stat(e.sourceDir);
193
- } catch {
194
- const s = `[collectAndCompareSkills] Source directory not found: ${e.sourceDir}`, u = new Error(s);
195
- throw u.code = C, u;
196
- }
197
- if (!r.isDirectory())
198
- throw new Error(`[collectAndCompareSkills] sourceDir is not a directory: ${e.sourceDir}`);
199
- const a = k(e.targetDir, "..");
200
- try {
201
- if (t.stat(a).isFile())
202
- throw new Error("[collectAndCompareSkills] .claude exists but is not a directory");
203
- } catch (s) {
204
- if (s.code !== "ENOENT") throw s;
205
- }
206
- try {
207
- t.mkdir(e.targetDir, { recursive: !0 });
208
- } catch (s) {
209
- const u = s;
210
- throw u.code === "EACCES" ? new Error(`[collectAndCompareSkills] cannot write to ${e.targetDir}: ${u.code}`, {
211
- cause: s
212
- }) : u.code === "ENOTDIR" ? new Error("[collectAndCompareSkills] .claude exists but is not a directory", {
213
- cause: s
214
- }) : s;
215
- }
216
- const l = t.writeFile, i = t.mkdir, c = J(e.sourceDir, e.skillNames);
217
- let n = [];
218
- try {
219
- n = t.readdir(e.targetDir).filter((s) => {
220
- if (s.startsWith(".") || v.has(s)) return !1;
221
- try {
222
- return t.stat(k(e.targetDir, s)).isDirectory();
223
- } catch {
224
- return !1;
225
- }
226
- });
227
- } catch {
228
- }
229
- const d = [];
230
- for (const s of [...c.keys()].sort()) {
231
- const u = c.get(s), o = k(e.targetDir, s);
232
- let f = /* @__PURE__ */ new Map();
233
- P(o, "", t, f);
234
- for (const [p, D] of [...u.entries()].sort(
235
- ([h], [S]) => h.localeCompare(S)
236
- )) {
237
- const h = B(D.toString("utf-8"), b), S = Buffer.from(h, "utf-8"), m = f.get(p);
238
- d.push(
239
- V(
240
- s,
241
- p,
242
- S,
243
- m,
244
- o,
245
- e.dryRun ?? !1,
246
- l,
247
- i
248
- )
249
- );
250
- }
251
- n = n.filter((p) => p !== s);
252
- }
253
- const g = e.skillNames, y = g ? n.filter((s) => g.includes(s)) : n;
254
- for (const s of y.sort())
255
- d.push(...X(s, e.targetDir, e.dryRun ?? !1, t));
256
- return new H(d);
257
- }
258
- const q = "(would add)", Q = "(would update)", Z = "(would delete)", ee = "(unchanged, skip)", te = "(unchanged)", E = {
259
- added: 0,
260
- updated: 1,
261
- deleted: 2,
262
- deleteFailed: 3,
263
- unchanged: 4
264
- };
265
- function re(t, e = {}) {
266
- const r = e.dryRun === !0;
267
- if (t.length === 0)
268
- return r ? ["Dry-run: no files written."] : ["Synced: 0 added, 0 updated, 0 skipped, 0 deleted"];
269
- const a = /* @__PURE__ */ new Map();
270
- for (const o of t) {
271
- let f = a.get(o.skillName);
272
- f || (f = { entries: [], dominantStatus: "unchanged" }, a.set(o.skillName, f)), f.entries.push(o);
273
- const p = E[o.status], D = E[f.dominantStatus];
274
- p < D && (f.dominantStatus = o.status);
275
- }
276
- const l = [...a.entries()].sort(([o, f], [p, D]) => {
277
- const h = E[f.dominantStatus] - E[D.dominantStatus];
278
- return h !== 0 ? h : o.localeCompare(p);
279
- }), c = Math.max(...l.map(([o]) => ` _ ${o}/`.length)) + 4, n = [];
280
- for (const [o, f] of l) {
281
- const p = f.dominantStatus;
282
- if (p === "added") {
283
- const h = ` + ${o}/`;
284
- n.push(h);
285
- for (const S of f.entries.sort((m, _) => m.relativePath.localeCompare(_.relativePath)))
286
- r ? n.push(` ${S.relativePath}`.padEnd(c) + q) : n.push(` ${S.relativePath}`);
287
- } else if (p === "updated") {
288
- const h = ` ~ ${o}/`;
289
- n.push(h);
290
- const S = f.entries.filter((m) => m.status === "added" || m.status === "updated").sort((m, _) => m.relativePath.localeCompare(_.relativePath));
291
- for (const m of S)
292
- r ? n.push(` ${m.relativePath}`.padEnd(c) + Q) : n.push(` ${m.relativePath}`);
293
- } else if (p === "deleted") {
294
- const h = ` - ${o}/`;
295
- r ? n.push(h.padEnd(c) + Z) : n.push(h);
296
- for (const S of f.entries.filter((m) => m.relativePath !== "").sort((m, _) => m.relativePath.localeCompare(_.relativePath)))
297
- n.push(` ${S.relativePath}`);
298
- } else if (p === "deleteFailed") {
299
- const h = f.entries.find((m) => m.errorCode)?.errorCode ?? "UNKNOWN", S = ` ! ${o}/`;
300
- n.push(S.padEnd(c) + `(delete failed: ${h})`);
301
- } else {
302
- const h = ` = ${o}/`, S = r ? ee : te;
303
- n.push(h.padEnd(c) + S);
304
- }
305
- }
306
- const d = t.filter((o) => o.status === "added").length, g = t.filter((o) => o.status === "updated").length, y = t.filter((o) => o.status === "unchanged").length, s = t.filter((o) => o.status === "deleted").length, u = t.filter((o) => o.status === "deleteFailed").length;
307
- if (r)
308
- n.push("Dry-run: no files written.");
309
- else {
310
- let o = `Synced: ${d} added, ${g} updated, ${y} skipped, ${s} deleted`;
311
- u > 0 && (o += `, ${u} delete failed`), n.push(o);
312
- }
313
- return n;
314
- }
315
- function ne(t) {
316
- try {
317
- const e = k(t, "..", ".."), r = N(k(e, "package.json"), "utf-8");
318
- return JSON.parse(r).version ?? "0.0.0";
319
- } catch {
320
- return "0.0.0";
321
- }
322
- }
323
- function se(t, e, r, a, l) {
324
- r.write(`Sync skills (v${l})${e ? " (dry-run)" : ""}: ${a}
325
- `);
326
- const i = re(t, { dryRun: e });
327
- for (const c of i)
328
- r.write(c + `
329
- `);
330
- }
331
- function A(t, e) {
332
- const r = N, a = W, l = T, i = L, c = $, n = x, d = O, g = G, y = process.stdout, s = process.stderr, u = j(t, {
333
- dryRun: ["dry-run"]
334
- }), o = u.dryRun === !0 || u.dryRun === "true", f = u._.filter(
335
- (_) => typeof _ == "string" && _ !== "sync-skills"
336
- ), p = process.cwd(), D = g(p, "ai/skills");
337
- if (!D)
338
- return s.write(`Error: gennady package not found. Install it locally: npm i -D gennady
339
- `), 1;
340
- const h = ne(D), S = k(p, ".claude", "skills"), m = {
341
- sourceDir: D,
342
- targetDir: S,
343
- skillNames: f.length > 0 ? f : void 0,
344
- dryRun: o
345
- };
346
- try {
347
- const w = Y({
348
- readFile: r,
349
- writeFile: a,
350
- mkdir: l,
351
- stat: (U) => i(U),
352
- readdir: c,
353
- unlink: n,
354
- rmdir: d,
355
- resolvePackageDir: g
356
- }, m);
357
- return se(w.entries, o, y, p, h), 0;
358
- } catch (_) {
359
- const w = _;
360
- if (w.code === R || w.code === C)
361
- return s.write(`Error: ${w.message}
362
- `), 1;
363
- throw w;
364
- }
365
- }
366
- if (process.argv[1]) {
367
- const t = z(import.meta.url);
368
- if (t === process.argv[1] || t.endsWith(process.argv[1]))
369
- try {
370
- const e = A(process.argv);
371
- process.exit(e);
372
- } catch (e) {
373
- const r = new Error("[syncSkillsCmd] Self-execution failed", { cause: e });
374
- I.error("[syncSkillsCmd#run] [self-executing → failed]", { error: r }), process.exit(1);
375
- }
376
- }
377
- process.exit(A(process.argv));