gennady 0.8.2 → 0.8.4
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.
- package/README.md +212 -3
- package/ai/agents/agent-resolve-conflicts.xml +148 -3
- package/ai/agents/agent-review-verifier.xml +181 -3
- package/ai/directives/sdd/audit.directive.xml +22 -11
- package/ai/directives/sdd/critic-protocol.xml +3 -0
- package/ai/directives/sdd/critic.directive.xml +25 -3
- package/ai/skills/README.md +150 -0
- package/ai/skills/sdd-check/SKILL.md +19 -9
- package/ai/skills/sdd-execute/scripts/README.md +3 -0
- package/ai/skills/sdd-execute/scripts/_sdd-lib.sh +60 -0
- package/ai/skills/sdd-execute/scripts/check.sh +238 -0
- package/ai/skills/sdd-execute/scripts/sdd +12 -0
- package/ai/skills/sdd-hooks-install/SKILL.md +88 -0
- package/ai/skills/workspace-permission-setup/SKILL.md +193 -0
- package/cli/cmd/README.md +185 -0
- package/dist/ai/agents/agent-resolve-conflicts.xml +148 -3
- package/dist/ai/agents/agent-review-verifier.xml +181 -3
- package/dist/ai/directives/sdd/audit.directive.xml +22 -11
- package/dist/ai/directives/sdd/critic-protocol.xml +3 -0
- package/dist/ai/directives/sdd/critic.directive.xml +25 -3
- package/dist/ai/skills/README.md +150 -0
- package/dist/ai/skills/sdd-check/SKILL.md +19 -9
- package/dist/ai/skills/sdd-execute/scripts/README.md +3 -0
- package/dist/ai/skills/sdd-execute/scripts/_sdd-lib.sh +60 -0
- package/dist/ai/skills/sdd-execute/scripts/check.sh +238 -0
- package/dist/ai/skills/sdd-execute/scripts/sdd +12 -0
- package/dist/ai/skills/sdd-hooks-install/SKILL.md +88 -0
- package/dist/ai/skills/workspace-permission-setup/SKILL.md +193 -0
- package/dist/chunks/index-BHEP1kYv.js +164 -0
- package/dist/chunks/index-DqSFtXFv.js +813 -0
- package/dist/chunks/index-Ukr3nSKB.js +377 -0
- package/dist/cli/cmd/lint/checks/anchor-thin.check.d.ts +11 -0
- package/dist/cli/cmd/lint/lint.cmd.d.ts +1 -1
- package/dist/cli/cmd/lint/lint.types.d.ts +2 -0
- package/dist/gennady.js +4 -4
- package/package.json +1 -1
- package/dist/chunks/index-4fUNp3za.js +0 -156
- package/dist/chunks/index-C9UEDrqg.js +0 -754
- package/dist/chunks/index-jOIhIHdS.js +0 -369
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { readdirSync as S, statSync as D, mkdirSync as O, writeFileSync as P, readFileSync as _ } from "node:fs";
|
|
2
|
+
import { join as a, sep as U } from "node:path";
|
|
3
|
+
import { fileURLToPath as $ } from "node:url";
|
|
4
|
+
import { l as x } from "./services-IgZptnTi.js";
|
|
5
|
+
import { n as T, b as A, r as b, S as z, p as I, f as Y } from "./shared-9J_oXE74.js";
|
|
6
|
+
class j {
|
|
7
|
+
/** @purpose List of all synced file entries. */
|
|
8
|
+
entries;
|
|
9
|
+
/**
|
|
10
|
+
* @purpose Construct a SyncResult from a list of entries.
|
|
11
|
+
* @param entries File entries.
|
|
12
|
+
*/
|
|
13
|
+
constructor(t) {
|
|
14
|
+
this.entries = t;
|
|
15
|
+
}
|
|
16
|
+
/** @purpose Files with status "added". | @returns Array of added entries. */
|
|
17
|
+
get added() {
|
|
18
|
+
return this.entries.filter((t) => t.status === "added");
|
|
19
|
+
}
|
|
20
|
+
/** @purpose Files with status "updated". | @returns Array of updated entries. */
|
|
21
|
+
get updated() {
|
|
22
|
+
return this.entries.filter((t) => t.status === "updated");
|
|
23
|
+
}
|
|
24
|
+
/** @purpose Files with status "unchanged". | @returns Array of unchanged entries. */
|
|
25
|
+
get unchanged() {
|
|
26
|
+
return this.entries.filter((t) => t.status === "unchanged");
|
|
27
|
+
}
|
|
28
|
+
/** @purpose Human-readable summary of added/updated/unchanged counts. | @returns Summary string. */
|
|
29
|
+
get summary() {
|
|
30
|
+
const t = this.added.length, s = this.updated.length, o = this.unchanged.length;
|
|
31
|
+
return `Synced: ${t} added, ${s} updated, ${o} skipped (unchanged)`;
|
|
32
|
+
}
|
|
33
|
+
/** @purpose Dry-run summary message. | @returns Dry-run message. */
|
|
34
|
+
get dryRunSummary() {
|
|
35
|
+
return "Dry-run: no files written.";
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const R = "ERR_SYNC_SUBDIR_NOT_FOUND", B = "ERR_SYNC_SOURCE_NOT_FOUND", w = /* @__PURE__ */ new Set([
|
|
39
|
+
"architecture",
|
|
40
|
+
"dbc-audit.directive.xml",
|
|
41
|
+
"dev-review.directive.xml",
|
|
42
|
+
"semantic-change-extractor.directive.xml"
|
|
43
|
+
]);
|
|
44
|
+
function L(e, t = "ai/directives") {
|
|
45
|
+
return b(e, t);
|
|
46
|
+
}
|
|
47
|
+
function W(e, t) {
|
|
48
|
+
if (t && t.length > 0) {
|
|
49
|
+
const o = S(e).filter(
|
|
50
|
+
(r) => !w.has(r) && D(a(e, r)).isDirectory()
|
|
51
|
+
);
|
|
52
|
+
for (const r of t)
|
|
53
|
+
if (!o.includes(r)) {
|
|
54
|
+
const c = `[scanDirectives] ai/directives/${r}/ not found in package.
|
|
55
|
+
Available: ${o.join(", ")}`, i = new Error(c);
|
|
56
|
+
throw i.code = R, i;
|
|
57
|
+
}
|
|
58
|
+
const n = [];
|
|
59
|
+
for (const r of t)
|
|
60
|
+
v(a(e, r), r, n);
|
|
61
|
+
return n.sort();
|
|
62
|
+
}
|
|
63
|
+
const s = [];
|
|
64
|
+
return v(e, "", s), s.sort();
|
|
65
|
+
}
|
|
66
|
+
function v(e, t, s) {
|
|
67
|
+
let o;
|
|
68
|
+
try {
|
|
69
|
+
o = S(e);
|
|
70
|
+
} catch {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
for (const n of o) {
|
|
74
|
+
if (n.startsWith(".") || w.has(n)) continue;
|
|
75
|
+
const r = a(e, n), c = t ? a(t, n) : n, i = D(r, { throwIfNoEntry: !1 });
|
|
76
|
+
i && (i.isDirectory() ? v(r, c, s) : i.isFile() && s.push(c.split(U).join("/")));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function H(e, t) {
|
|
80
|
+
try {
|
|
81
|
+
e.stat(t.sourceDir);
|
|
82
|
+
} catch {
|
|
83
|
+
const n = `[collectAndCompare] Source directory not found: ${t.sourceDir}`, r = new Error(n);
|
|
84
|
+
throw r.code = B, r;
|
|
85
|
+
}
|
|
86
|
+
const s = W(t.sourceDir, t.subdirs), o = [];
|
|
87
|
+
for (const n of s) {
|
|
88
|
+
const r = a(t.sourceDir, n), c = a(t.targetDir, n), i = e.readFile(r), y = T(i.toString("utf-8"), z), l = Buffer.from(y, "utf-8"), f = l.length;
|
|
89
|
+
let u = null;
|
|
90
|
+
try {
|
|
91
|
+
u = e.readFile(c);
|
|
92
|
+
} catch {
|
|
93
|
+
}
|
|
94
|
+
let d;
|
|
95
|
+
u === null ? d = "added" : A(l, u) ? d = "updated" : d = "unchanged", o.push({
|
|
96
|
+
relativePath: n,
|
|
97
|
+
status: d,
|
|
98
|
+
sourceSize: f,
|
|
99
|
+
targetSize: u?.length
|
|
100
|
+
}), !t.dryRun && d !== "unchanged" && (e.mkdir(a(t.targetDir, n, ".."), { recursive: !0 }), e.writeFile(c, l));
|
|
101
|
+
}
|
|
102
|
+
return new j(o);
|
|
103
|
+
}
|
|
104
|
+
function J(e) {
|
|
105
|
+
try {
|
|
106
|
+
const t = a(e, "..", ".."), s = _(a(t, "package.json"), "utf-8");
|
|
107
|
+
return JSON.parse(s).version ?? "0.0.0";
|
|
108
|
+
} catch {
|
|
109
|
+
return "0.0.0";
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function V(e, t, s, o, n) {
|
|
113
|
+
s.write(`Sync (v${n})${t ? " (dry-run)" : ""}: ${o}
|
|
114
|
+
`);
|
|
115
|
+
const r = Y(e, { dryRun: t });
|
|
116
|
+
for (const c of r)
|
|
117
|
+
s.write(c + `
|
|
118
|
+
`);
|
|
119
|
+
}
|
|
120
|
+
function E(e, t) {
|
|
121
|
+
const s = _, o = P, n = O, r = D, c = S, i = L, y = process.stdout, l = process.stderr, f = I(e, {
|
|
122
|
+
dryRun: ["dry-run"]
|
|
123
|
+
}), u = f.dryRun === !0 || f.dryRun === "true", d = f._.filter(
|
|
124
|
+
(g) => typeof g == "string" && g !== "sync"
|
|
125
|
+
), m = process.cwd(), p = i(m, "ai/directives");
|
|
126
|
+
if (!p)
|
|
127
|
+
return l.write(`Error: gennady package not found. Install it locally: npm i -D gennady
|
|
128
|
+
`), 1;
|
|
129
|
+
const N = J(p), k = a(m, "ai", "directives"), C = {
|
|
130
|
+
sourceDir: p,
|
|
131
|
+
targetDir: k,
|
|
132
|
+
subdirs: d.length > 0 ? d : void 0,
|
|
133
|
+
dryRun: u
|
|
134
|
+
};
|
|
135
|
+
try {
|
|
136
|
+
const h = H({
|
|
137
|
+
readFile: s,
|
|
138
|
+
writeFile: o,
|
|
139
|
+
mkdir: n,
|
|
140
|
+
stat: (F) => r(F),
|
|
141
|
+
readdir: c,
|
|
142
|
+
cwd: m
|
|
143
|
+
}, C);
|
|
144
|
+
return V(h.entries, u, y, m, N), 0;
|
|
145
|
+
} catch (g) {
|
|
146
|
+
const h = g;
|
|
147
|
+
if (h.code === R)
|
|
148
|
+
return l.write(`Error: ${h.message}
|
|
149
|
+
`), 1;
|
|
150
|
+
throw h;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (process.argv[1]) {
|
|
154
|
+
const e = $(import.meta.url);
|
|
155
|
+
if (e === process.argv[1] || e.endsWith(process.argv[1]))
|
|
156
|
+
try {
|
|
157
|
+
const t = E(process.argv);
|
|
158
|
+
process.exit(t);
|
|
159
|
+
} catch (t) {
|
|
160
|
+
const s = new Error("[syncCmd] Self-execution failed", { cause: t });
|
|
161
|
+
x.error("[syncCmd#run] [self-executing → failed]", { error: s }), process.exit(1);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
process.exit(E(process.argv));
|