@vyuhlabs/dxkit 2.23.0 → 2.24.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.
- package/CHANGELOG.md +34 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +67 -0
- package/dist/cli.js.map +1 -1
- package/dist/generator.d.ts.map +1 -1
- package/dist/generator.js +5 -0
- package/dist/generator.js.map +1 -1
- package/dist/issue-cli.d.ts +2 -1
- package/dist/issue-cli.d.ts.map +1 -1
- package/dist/issue-cli.js +4 -0
- package/dist/issue-cli.js.map +1 -1
- package/dist/loop/scaffold.d.ts +4 -0
- package/dist/loop/scaffold.d.ts.map +1 -1
- package/dist/loop/scaffold.js +7 -7
- package/dist/loop/scaffold.js.map +1 -1
- package/dist/ship-installers.d.ts +20 -0
- package/dist/ship-installers.d.ts.map +1 -1
- package/dist/ship-installers.js +17 -16
- package/dist/ship-installers.js.map +1 -1
- package/dist/uninstall/index.d.ts +47 -0
- package/dist/uninstall/index.d.ts.map +1 -0
- package/dist/uninstall/index.js +418 -0
- package/dist/uninstall/index.js.map +1 -0
- package/dist/uninstall/reversals.d.ts +70 -0
- package/dist/uninstall/reversals.d.ts.map +1 -0
- package/dist/uninstall/reversals.js +202 -0
- package/dist/uninstall/reversals.js.map +1 -0
- package/package.json +1 -1
- package/templates/.claude/skills/dxkit-uninstall/SKILL.md +55 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Pure reversals for dxkit's additive merges — the inverse of each installer's
|
|
4
|
+
* merge into a PRE-EXISTING user file. Each takes the current file content and
|
|
5
|
+
* returns the content with ONLY dxkit's additions removed, preserving the
|
|
6
|
+
* user's own lines/keys byte-for-byte. These are the load-bearing functions for
|
|
7
|
+
* the uninstall feature's primary guarantee: restore the pre-dxkit state.
|
|
8
|
+
*
|
|
9
|
+
* The markers are imported from the installer modules (not re-declared), so a
|
|
10
|
+
* marker change breaks install and uninstall together (recipe symmetry).
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.STEALTH_HEADER = void 0;
|
|
14
|
+
exports.stripGitignoreBlock = stripGitignoreBlock;
|
|
15
|
+
exports.stripAllGitignoreBlocks = stripAllGitignoreBlocks;
|
|
16
|
+
exports.stripClaudeLoopBlock = stripClaudeLoopBlock;
|
|
17
|
+
exports.stripSettingsDxkit = stripSettingsDxkit;
|
|
18
|
+
exports.stripPackageJsonDxkit = stripPackageJsonDxkit;
|
|
19
|
+
const ship_installers_1 = require("../ship-installers");
|
|
20
|
+
const scaffold_1 = require("../loop/scaffold");
|
|
21
|
+
// ─── .gitignore ─────────────────────────────────────────────────────────────
|
|
22
|
+
/** Stealth-mode header (mirrors `STEALTH_HEADER` in cli.ts; kept as a literal
|
|
23
|
+
* here to avoid importing the CLI entry module). */
|
|
24
|
+
exports.STEALTH_HEADER = '# dxkit (stealth mode — local only, not committed)';
|
|
25
|
+
/**
|
|
26
|
+
* Remove a dxkit block from `.gitignore`. The installer writes each block as
|
|
27
|
+
* `\n<HEADER>\n<entries…>\n` (a header line followed by its entries, up to the
|
|
28
|
+
* next blank line or EOF). We strip from the header line through the run of
|
|
29
|
+
* non-blank lines that follows it, leaving every other line — including the
|
|
30
|
+
* user's own entries — untouched.
|
|
31
|
+
*/
|
|
32
|
+
function stripGitignoreBlock(content, header) {
|
|
33
|
+
const lines = content.split('\n');
|
|
34
|
+
const out = [];
|
|
35
|
+
let changed = false;
|
|
36
|
+
for (let i = 0; i < lines.length; i++) {
|
|
37
|
+
if (lines[i].trim() === header) {
|
|
38
|
+
changed = true;
|
|
39
|
+
// Skip the header and the contiguous non-blank entry lines under it.
|
|
40
|
+
i++;
|
|
41
|
+
while (i < lines.length && lines[i].trim() !== '')
|
|
42
|
+
i++;
|
|
43
|
+
// `i` now points at the blank line (or EOF); the for-loop's i++ consumes
|
|
44
|
+
// that blank separator so we don't leave a double blank behind.
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
out.push(lines[i]);
|
|
48
|
+
}
|
|
49
|
+
if (!changed)
|
|
50
|
+
return { changed: false, content };
|
|
51
|
+
// Collapse a leading blank the block may have left, and trailing blanks.
|
|
52
|
+
let result = out
|
|
53
|
+
.join('\n')
|
|
54
|
+
.replace(/^\n+/, '')
|
|
55
|
+
.replace(/\n{3,}/g, '\n\n');
|
|
56
|
+
if (result.trim() === '')
|
|
57
|
+
result = '';
|
|
58
|
+
return { changed: true, content: result };
|
|
59
|
+
}
|
|
60
|
+
/** Strip both the runtime-outputs block and the stealth block from `.gitignore`. */
|
|
61
|
+
function stripAllGitignoreBlocks(content) {
|
|
62
|
+
const a = stripGitignoreBlock(content, ship_installers_1.GITIGNORE_HEADER);
|
|
63
|
+
const b = stripGitignoreBlock(a.content, exports.STEALTH_HEADER);
|
|
64
|
+
return { changed: a.changed || b.changed, content: b.content };
|
|
65
|
+
}
|
|
66
|
+
// ─── CLAUDE.md (loop block) ─────────────────────────────────────────────────
|
|
67
|
+
/**
|
|
68
|
+
* Remove the dxkit loop block delimited by `<!-- dxkit:loop:start -->` …
|
|
69
|
+
* `<!-- dxkit:loop:end -->` from `CLAUDE.md`, including the sentinels and the
|
|
70
|
+
* surrounding blank lines the installer added. Everything else is preserved.
|
|
71
|
+
*/
|
|
72
|
+
function stripClaudeLoopBlock(content) {
|
|
73
|
+
const start = content.indexOf(scaffold_1.CLAUDE_BLOCK_START);
|
|
74
|
+
const end = content.indexOf(scaffold_1.CLAUDE_BLOCK_END);
|
|
75
|
+
if (start === -1 || end === -1 || end < start)
|
|
76
|
+
return { changed: false, content };
|
|
77
|
+
const before = content.slice(0, start);
|
|
78
|
+
const after = content.slice(end + scaffold_1.CLAUDE_BLOCK_END.length);
|
|
79
|
+
// Join, collapsing the blank lines the block was fenced with.
|
|
80
|
+
let result = (before.replace(/\n+$/, '') + '\n' + after.replace(/^\n+/, '')).trim();
|
|
81
|
+
result = result === '' ? '' : result + '\n';
|
|
82
|
+
return { changed: true, content: result };
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Remove dxkit's contributions from a parsed `settings.json`:
|
|
86
|
+
* - the Stop hook whose command invokes `hook stop-gate` (loop gate),
|
|
87
|
+
* - the PreToolUse hook whose command invokes `context-hook` (passive graph).
|
|
88
|
+
* Empty `hooks.Stop` / `hooks.PreToolUse` arrays and an empty `hooks` object are
|
|
89
|
+
* pruned. The user's other hooks, permissions, and keys are preserved.
|
|
90
|
+
*
|
|
91
|
+
* `dxkitCreated` (the file is in the manifest) additionally strips the
|
|
92
|
+
* dxkit-authored permission block and reports `content: '{}'`-equivalent
|
|
93
|
+
* emptiness via `isDxkitOnly` so the caller can delete the file outright.
|
|
94
|
+
*/
|
|
95
|
+
function stripSettingsDxkit(parsed, opts = { dxkitCreated: false }) {
|
|
96
|
+
let changed = false;
|
|
97
|
+
const obj = { ...parsed };
|
|
98
|
+
const hooks = obj.hooks;
|
|
99
|
+
if (hooks && typeof hooks === 'object') {
|
|
100
|
+
const nextHooks = { ...hooks };
|
|
101
|
+
for (const [event, matchRe] of [
|
|
102
|
+
['Stop', /hook\s+stop-gate/],
|
|
103
|
+
['PreToolUse', /context-hook/],
|
|
104
|
+
]) {
|
|
105
|
+
const arr = nextHooks[event];
|
|
106
|
+
if (Array.isArray(arr)) {
|
|
107
|
+
const kept = arr.filter((entry) => !entryInvokes(entry, matchRe));
|
|
108
|
+
if (kept.length !== arr.length)
|
|
109
|
+
changed = true;
|
|
110
|
+
if (kept.length === 0)
|
|
111
|
+
delete nextHooks[event];
|
|
112
|
+
else
|
|
113
|
+
nextHooks[event] = kept;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (Object.keys(nextHooks).length === 0)
|
|
117
|
+
delete obj.hooks;
|
|
118
|
+
else
|
|
119
|
+
obj.hooks = nextHooks;
|
|
120
|
+
}
|
|
121
|
+
// When dxkit created the file, its permission block + $schema are dxkit's too.
|
|
122
|
+
// Drop them so the emptiness check can decide the file is deletable.
|
|
123
|
+
if (opts.dxkitCreated) {
|
|
124
|
+
if ('permissions' in obj) {
|
|
125
|
+
delete obj.permissions;
|
|
126
|
+
changed = true;
|
|
127
|
+
}
|
|
128
|
+
if ('$schema' in obj)
|
|
129
|
+
delete obj.$schema;
|
|
130
|
+
}
|
|
131
|
+
const isDxkitOnly = Object.keys(obj).length === 0;
|
|
132
|
+
return { changed, result: obj, isDxkitOnly };
|
|
133
|
+
}
|
|
134
|
+
/** Does a hook-group entry (`{matcher?, hooks:[{command}]}` or `{command}`)
|
|
135
|
+
* invoke a command matching `re`? */
|
|
136
|
+
function entryInvokes(entry, re) {
|
|
137
|
+
if (!entry || typeof entry !== 'object')
|
|
138
|
+
return false;
|
|
139
|
+
const e = entry;
|
|
140
|
+
if (typeof e.command === 'string' && re.test(e.command))
|
|
141
|
+
return true;
|
|
142
|
+
if (Array.isArray(e.hooks)) {
|
|
143
|
+
return e.hooks.some((h) => h &&
|
|
144
|
+
typeof h === 'object' &&
|
|
145
|
+
typeof h.command === 'string' &&
|
|
146
|
+
re.test(h.command));
|
|
147
|
+
}
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
// ─── package.json ───────────────────────────────────────────────────────────
|
|
151
|
+
/**
|
|
152
|
+
* Remove dxkit's contributions from a parsed `package.json`:
|
|
153
|
+
* - the `@vyuhlabs/dxkit` devDependency,
|
|
154
|
+
* - the `vyuh-dxkit hooks activate` postinstall (trimming a chained ` && …`
|
|
155
|
+
* suffix, or dropping the whole `postinstall` key when it was the sole cmd).
|
|
156
|
+
* Nothing else is touched. Returns which pieces were removed for reporting.
|
|
157
|
+
*/
|
|
158
|
+
function stripPackageJsonDxkit(parsed) {
|
|
159
|
+
const obj = { ...parsed };
|
|
160
|
+
let removedDevDep = false;
|
|
161
|
+
let removedPostinstall = false;
|
|
162
|
+
const dev = obj.devDependencies;
|
|
163
|
+
if (dev && typeof dev === 'object' && ship_installers_1.DXKIT_PACKAGE in dev) {
|
|
164
|
+
const nextDev = { ...dev };
|
|
165
|
+
delete nextDev[ship_installers_1.DXKIT_PACKAGE];
|
|
166
|
+
removedDevDep = true;
|
|
167
|
+
if (Object.keys(nextDev).length === 0)
|
|
168
|
+
delete obj.devDependencies;
|
|
169
|
+
else
|
|
170
|
+
obj.devDependencies = nextDev;
|
|
171
|
+
}
|
|
172
|
+
const scripts = obj.scripts;
|
|
173
|
+
if (scripts && typeof scripts === 'object' && typeof scripts.postinstall === 'string') {
|
|
174
|
+
const cmd = scripts.postinstall;
|
|
175
|
+
if (cmd.includes(ship_installers_1.POSTINSTALL_CMD)) {
|
|
176
|
+
const nextScripts = { ...scripts };
|
|
177
|
+
const trimmed = cmd
|
|
178
|
+
.replace(new RegExp(`\\s*&&\\s*${escapeRe(ship_installers_1.POSTINSTALL_CMD)}`), '') // chained suffix
|
|
179
|
+
.replace(new RegExp(`${escapeRe(ship_installers_1.POSTINSTALL_CMD)}\\s*&&\\s*`), '') // chained prefix
|
|
180
|
+
.trim();
|
|
181
|
+
if (trimmed === '' || trimmed === ship_installers_1.POSTINSTALL_CMD)
|
|
182
|
+
delete nextScripts.postinstall;
|
|
183
|
+
else
|
|
184
|
+
nextScripts.postinstall = trimmed;
|
|
185
|
+
if (Object.keys(nextScripts).length === 0)
|
|
186
|
+
delete obj.scripts;
|
|
187
|
+
else
|
|
188
|
+
obj.scripts = nextScripts;
|
|
189
|
+
removedPostinstall = true;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return {
|
|
193
|
+
changed: removedDevDep || removedPostinstall,
|
|
194
|
+
result: obj,
|
|
195
|
+
removedDevDep,
|
|
196
|
+
removedPostinstall,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
function escapeRe(s) {
|
|
200
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=reversals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reversals.js","sourceRoot":"","sources":["../../src/uninstall/reversals.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;AA0BH,kDAwBC;AAGD,0DAIC;AASD,oDAUC;AAiBD,gDAsCC;AA6BD,sDA0CC;AAxMD,wDAAsF;AACtF,+CAAwE;AAUxE,+EAA+E;AAE/E;qDACqD;AACxC,QAAA,cAAc,GAAG,oDAAoD,CAAC;AAEnF;;;;;;GAMG;AACH,SAAgB,mBAAmB,CAAC,OAAe,EAAE,MAAc;IACjE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,MAAM,EAAE,CAAC;YAC/B,OAAO,GAAG,IAAI,CAAC;YACf,qEAAqE;YACrE,CAAC,EAAE,CAAC;YACJ,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE;gBAAE,CAAC,EAAE,CAAC;YACvD,yEAAyE;YACzE,gEAAgE;YAChE,SAAS;QACX,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACrB,CAAC;IACD,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IACjD,yEAAyE;IACzE,IAAI,MAAM,GAAG,GAAG;SACb,IAAI,CAAC,IAAI,CAAC;SACV,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;SACnB,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC9B,IAAI,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,MAAM,GAAG,EAAE,CAAC;IACtC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AAC5C,CAAC;AAED,oFAAoF;AACpF,SAAgB,uBAAuB,CAAC,OAAe;IACrD,MAAM,CAAC,GAAG,mBAAmB,CAAC,OAAO,EAAE,kCAAgB,CAAC,CAAC;IACzD,MAAM,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,OAAO,EAAE,sBAAc,CAAC,CAAC;IACzD,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;AACjE,CAAC;AAED,+EAA+E;AAE/E;;;;GAIG;AACH,SAAgB,oBAAoB,CAAC,OAAe;IAClD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,6BAAkB,CAAC,CAAC;IAClD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,2BAAgB,CAAC,CAAC;IAC9C,IAAI,KAAK,KAAK,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,GAAG,GAAG,KAAK;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IAClF,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,2BAAgB,CAAC,MAAM,CAAC,CAAC;IAC3D,8DAA8D;IAC9D,IAAI,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACpF,MAAM,GAAG,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC;IAC5C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AAC5C,CAAC;AAMD;;;;;;;;;;GAUG;AACH,SAAgB,kBAAkB,CAChC,MAAkB,EAClB,OAAkC,EAAE,YAAY,EAAE,KAAK,EAAE;IAEzD,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,MAAM,GAAG,GAAe,EAAE,GAAG,MAAM,EAAE,CAAC;IAEtC,MAAM,KAAK,GAAG,GAAG,CAAC,KAA+B,CAAC;IAClD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,SAAS,GAAe,EAAE,GAAG,KAAK,EAAE,CAAC;QAC3C,KAAK,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI;YAC7B,CAAC,MAAM,EAAE,kBAAkB,CAAC;YAC5B,CAAC,YAAY,EAAE,cAAc,CAAC;SACtB,EAAE,CAAC;YACX,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;YAC7B,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvB,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;gBAClE,IAAI,IAAI,CAAC,MAAM,KAAK,GAAG,CAAC,MAAM;oBAAE,OAAO,GAAG,IAAI,CAAC;gBAC/C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;oBAAE,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC;;oBAC1C,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;YAC/B,CAAC;QACH,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,GAAG,CAAC,KAAK,CAAC;;YACrD,GAAG,CAAC,KAAK,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED,+EAA+E;IAC/E,qEAAqE;IACrE,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,IAAI,aAAa,IAAI,GAAG,EAAE,CAAC;YACzB,OAAO,GAAG,CAAC,WAAW,CAAC;YACvB,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;QACD,IAAI,SAAS,IAAI,GAAG;YAAE,OAAO,GAAG,CAAC,OAAO,CAAC;IAC3C,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;IAClD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC;AAC/C,CAAC;AAED;sCACsC;AACtC,SAAS,YAAY,CAAC,KAAc,EAAE,EAAU;IAC9C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACtD,MAAM,CAAC,GAAG,KAAmB,CAAC;IAC9B,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACrE,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CACjB,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC;YACD,OAAO,CAAC,KAAK,QAAQ;YACrB,OAAQ,CAAgB,CAAC,OAAO,KAAK,QAAQ;YAC7C,EAAE,CAAC,IAAI,CAAE,CAAgB,CAAC,OAAiB,CAAC,CAC/C,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,+EAA+E;AAE/E;;;;;;GAMG;AACH,SAAgB,qBAAqB,CAAC,MAAkB;IAMtD,MAAM,GAAG,GAAe,EAAE,GAAG,MAAM,EAAE,CAAC;IACtC,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,IAAI,kBAAkB,GAAG,KAAK,CAAC;IAE/B,MAAM,GAAG,GAAG,GAAG,CAAC,eAAyC,CAAC;IAC1D,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,+BAAa,IAAI,GAAG,EAAE,CAAC;QAC3D,MAAM,OAAO,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC;QAC3B,OAAO,OAAO,CAAC,+BAAa,CAAC,CAAC;QAC9B,aAAa,GAAG,IAAI,CAAC;QACrB,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,GAAG,CAAC,eAAe,CAAC;;YAC7D,GAAG,CAAC,eAAe,GAAG,OAAO,CAAC;IACrC,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,OAAiC,CAAC;IACtD,IAAI,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,OAAO,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;QACtF,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC;QAChC,IAAI,GAAG,CAAC,QAAQ,CAAC,iCAAe,CAAC,EAAE,CAAC;YAClC,MAAM,WAAW,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,GAAG;iBAChB,OAAO,CAAC,IAAI,MAAM,CAAC,aAAa,QAAQ,CAAC,iCAAe,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,iBAAiB;iBACnF,OAAO,CAAC,IAAI,MAAM,CAAC,GAAG,QAAQ,CAAC,iCAAe,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC,CAAC,iBAAiB;iBACnF,IAAI,EAAE,CAAC;YACV,IAAI,OAAO,KAAK,EAAE,IAAI,OAAO,KAAK,iCAAe;gBAAE,OAAO,WAAW,CAAC,WAAW,CAAC;;gBAC7E,WAAW,CAAC,WAAW,GAAG,OAAO,CAAC;YACvC,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,GAAG,CAAC,OAAO,CAAC;;gBACzD,GAAG,CAAC,OAAO,GAAG,WAAW,CAAC;YAC/B,kBAAkB,GAAG,IAAI,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,OAAO;QACL,OAAO,EAAE,aAAa,IAAI,kBAAkB;QAC5C,MAAM,EAAE,GAAG;QACX,aAAa;QACb,kBAAkB;KACnB,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,CAAS;IACzB,OAAO,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vyuhlabs/dxkit",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.24.0",
|
|
4
4
|
"description": "A deterministic stop condition and code-graph context layer for AI coding agents: gives agents a code graph to make changes, then blocks only net-new detector-backed regressions at the stop boundary, with no model in the gate.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Vyuh Labs",
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dxkit-uninstall
|
|
3
|
+
description: Cleanly and non-intrusively remove dxkit from a repo, restoring its exact pre-dxkit state — reverse every additive merge (settings.json, CLAUDE.md, .gitignore, package.json), delete every file dxkit created, and clean up hooks + CI + the .dxkit/ tree. Dry-run first. Use when the user says "remove dxkit", "uninstall dxkit", "get rid of dxkit", "clean up dxkit from this repo", "how do I undo dxkit init", or wants to stop using dxkit.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# dxkit-uninstall
|
|
7
|
+
|
|
8
|
+
This skill owns **removing dxkit** from a repo. Its one guarantee: after uninstall, the repo is back to its **exact pre-dxkit state** — every file dxkit created is gone, and every additive change dxkit made to a file you already had is reversed, leaving your own content byte-for-byte intact.
|
|
9
|
+
|
|
10
|
+
## What it removes vs reverts
|
|
11
|
+
|
|
12
|
+
dxkit's footprint falls into two kinds, handled differently:
|
|
13
|
+
|
|
14
|
+
- **Files dxkit created** (they didn't exist before): `.dxkit/`, the `dxkit-*` skills under `.claude/`, `AGENTS.md`, the git hooks in `.githooks/`, the `dxkit-*` GitHub workflows, `.dxkit-ignore`, and `.vyuh-dxkit.json`. These are **removed** outright.
|
|
15
|
+
- **Additive merges into files you already had**: the `.gitignore` runtime-output block, the `CLAUDE.md` loop block (between `<!-- dxkit:loop:start -->` / `end -->`), the `.claude/settings.json` hooks (`context-hook` / `stop-gate`), and the `package.json` `@vyuhlabs/dxkit` devDependency + postinstall. These are **surgically reverted** — only dxkit's additions are stripped; your keys, prose, and formatting are preserved.
|
|
16
|
+
|
|
17
|
+
It knows exactly what is dxkit's because `init` recorded a manifest (`.vyuh-dxkit.json`) with a hash of every created file. A dxkit-created file you have since **edited** is surfaced and **skipped** (not clobbered) unless you pass `--force`.
|
|
18
|
+
|
|
19
|
+
## How to run it
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# 1. Dry run FIRST (default) — prints exactly what will be removed/reverted,
|
|
23
|
+
# changes nothing.
|
|
24
|
+
npx vyuh-dxkit uninstall
|
|
25
|
+
|
|
26
|
+
# 2. Apply it.
|
|
27
|
+
npx vyuh-dxkit uninstall --yes
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Useful flags:
|
|
31
|
+
|
|
32
|
+
- `--remove-devdep` — also remove the `@vyuhlabs/dxkit` devDependency + postinstall from `package.json` (kept by default so a lockfile install doesn't break mid-cleanup; run `npm install` afterward if you use it).
|
|
33
|
+
- `--keep-baselines` — keep the curated, git-tracked artifacts (`.dxkit/baselines/`, the allowlist, `.dxkit/external/`) and remove only the runtime state. Use this if you want to pause dxkit but keep your grandfathered debt inventory.
|
|
34
|
+
- `--force` — also remove dxkit-created files you have edited (default: skip + warn).
|
|
35
|
+
- `--no-feedback` — skip the feedback prompt.
|
|
36
|
+
- `--json` — machine-readable plan/result.
|
|
37
|
+
|
|
38
|
+
## Verifying the restore
|
|
39
|
+
|
|
40
|
+
On a git repo, the definitive check is that the working tree returns to clean:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
git status # after `uninstall --yes`, dxkit's changes are gone
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
If you had committed dxkit's files (baselines, workflows), those show as deletions to commit — that is expected; uninstall only edits the working tree, never git history.
|
|
47
|
+
|
|
48
|
+
## The feedback prompt (optional, opt-in)
|
|
49
|
+
|
|
50
|
+
On completion, the CLI prints a **prefilled GitHub issue URL** and invites you to share why you're removing dxkit. Nothing is sent automatically — it is a link you choose to open; there is no telemetry. Skip it with `--no-feedback`. If the user wants to leave feedback, open the URL it printed (or run `npx vyuh-dxkit issue --type=uninstall --about="…"`).
|
|
51
|
+
|
|
52
|
+
## What NOT to do
|
|
53
|
+
|
|
54
|
+
- Do **not** hand-delete `.dxkit/` and the workflows and call it done — that leaves the additive merges (settings.json hooks, CLAUDE.md block, .gitignore entries, package.json devDep) behind. Use `uninstall`, which reverses those too.
|
|
55
|
+
- Do **not** run `--force` reflexively — the skip-and-warn on edited files is there so you don't lose work you put into a dxkit-created file. Review the warnings first.
|