@therocketcode/gsd-core 1.7.2 → 1.7.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.
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gsd-core",
|
|
3
3
|
"displayName": "GSD Core",
|
|
4
|
-
"version": "1.7.
|
|
4
|
+
"version": "1.7.3",
|
|
5
5
|
"description": "GSD Core is a meta-prompting, context engineering, and spec-driven development system for AI coding agents.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "TheRocketCodeMX",
|
package/gemini-extension.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gsd-core",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.3",
|
|
4
4
|
"description": "GSD Core — a meta-prompting, context engineering, and spec-driven development system for AI coding agents. Loads gsd's operating context into every Gemini CLI session.",
|
|
5
5
|
"contextFileName": "GEMINI.md"
|
|
6
6
|
}
|
|
@@ -56,6 +56,18 @@ const LEGACY_CACHE_FILENAMES = [
|
|
|
56
56
|
'gsd-update-check-opengsd-gsd-core.json',
|
|
57
57
|
];
|
|
58
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Legacy runtime directory names left inside a runtime config dir by a
|
|
61
|
+
* superseded install. The current fork installs its runtime under `gsd-core/`;
|
|
62
|
+
* the pre-rename upstream used `get-shit-done/`. When a user migrates, the
|
|
63
|
+
* file-level migration deletes the OLD dir's files but leaves the emptied
|
|
64
|
+
* directory tree behind — harmless, but untidy. We prune such a dir ONLY when
|
|
65
|
+
* it contains zero files (a strict emptiness guard, re-checked at apply time),
|
|
66
|
+
* so we can never delete a directory that still holds user-authored content.
|
|
67
|
+
* NEVER list 'gsd-core' here — that is the CURRENT runtime dir.
|
|
68
|
+
*/
|
|
69
|
+
const LEGACY_RUNTIME_DIR_NAMES = ['get-shit-done'];
|
|
70
|
+
|
|
59
71
|
/**
|
|
60
72
|
* Subtrees within a configDir that GSD actively scans for old-package content.
|
|
61
73
|
* Deliberately excludes 'gsd-core' — the current package's own infra and
|
|
@@ -151,6 +163,8 @@ function fileContainsOldPackageSignal(absPath, fsMod) {
|
|
|
151
163
|
* - 'content-references-old-package': a code file whose content contains
|
|
152
164
|
* the old package name signal (hooks/ and commands/ subtrees only).
|
|
153
165
|
* - 'legacy-shared-cache': the old package's shared update-check cache file.
|
|
166
|
+
* - 'empty-legacy-runtime-dir': a superseded runtime dir (e.g. get-shit-done/)
|
|
167
|
+
* left empty after a migration deleted its files.
|
|
154
168
|
*
|
|
155
169
|
* @param {string[]} configDirs - absolute paths to runtime config dirs to scan
|
|
156
170
|
* @param {object} [opts]
|
|
@@ -207,6 +221,25 @@ function planLegacyCleanup(configDirs, opts = {}) {
|
|
|
207
221
|
}
|
|
208
222
|
}
|
|
209
223
|
|
|
224
|
+
// Emptied legacy runtime directories left behind after a migration deleted
|
|
225
|
+
// their files. Flag ONLY when the dir exists and contains zero files — a
|
|
226
|
+
// dir that still holds any file is left untouched (its code files are caught
|
|
227
|
+
// by the content scan above instead).
|
|
228
|
+
for (const configDir of configDirs) {
|
|
229
|
+
for (const legacyDirName of LEGACY_RUNTIME_DIR_NAMES) {
|
|
230
|
+
const legacyDir = path.join(configDir, legacyDirName);
|
|
231
|
+
let stat;
|
|
232
|
+
try {
|
|
233
|
+
stat = fsMod.statSync(legacyDir);
|
|
234
|
+
} catch {
|
|
235
|
+
continue; // absent — skip
|
|
236
|
+
}
|
|
237
|
+
if (stat.isDirectory() && collectFilesUnder(legacyDir, fsMod).length === 0) {
|
|
238
|
+
addCandidate(legacyDir, 'empty-legacy-runtime-dir');
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
210
243
|
// Sort deterministically by path
|
|
211
244
|
const sorted = [...candidates.entries()]
|
|
212
245
|
.sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0)
|
|
@@ -246,6 +279,16 @@ function applyLegacyCleanup(plan, opts = {}) {
|
|
|
246
279
|
const errors = [];
|
|
247
280
|
|
|
248
281
|
for (const item of plan) {
|
|
282
|
+
// Legacy runtime dirs are removed recursively, but ONLY after re-verifying
|
|
283
|
+
// they are still empty at apply time — a defensive guard so a file that
|
|
284
|
+
// appeared between scan and apply is never destroyed.
|
|
285
|
+
const isLegacyDir = item.reason === 'empty-legacy-runtime-dir';
|
|
286
|
+
if (isLegacyDir && collectFilesUnder(item.path, fsMod).length > 0) {
|
|
287
|
+
errors.push({ path: item.path, error: 'legacy runtime dir not empty at apply time; skipped' });
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
const rmOpts = isLegacyDir ? { recursive: true, force: true } : { force: true };
|
|
291
|
+
|
|
249
292
|
let lastErr;
|
|
250
293
|
const maxAttempts = process.platform === 'win32' ? 3 : 1;
|
|
251
294
|
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
@@ -254,7 +297,7 @@ function applyLegacyCleanup(plan, opts = {}) {
|
|
|
254
297
|
// Synchronous 100ms delay before retry (win32 EBUSY/EPERM from Defender)
|
|
255
298
|
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 100);
|
|
256
299
|
}
|
|
257
|
-
fsMod.rmSync(item.path,
|
|
300
|
+
fsMod.rmSync(item.path, rmOpts);
|
|
258
301
|
lastErr = undefined;
|
|
259
302
|
break;
|
|
260
303
|
} catch (err) {
|
package/package.json
CHANGED