@bigking67/pi-67 0.10.13 → 0.10.14
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
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.10.14]
|
|
4
|
+
|
|
5
|
+
- Refreshes the Git index stat cache for `settings.json` during
|
|
6
|
+
`update --repair` when Git reports `M settings.json` but `git diff` has no
|
|
7
|
+
real content changes, clearing the remaining Windows false-dirty state after
|
|
8
|
+
line-ending/runtime-state cleanup.
|
|
9
|
+
|
|
3
10
|
## [0.10.13]
|
|
4
11
|
|
|
5
12
|
- Normalizes `settings.json` BOM/CRLF line endings during `update --repair`
|
package/package.json
CHANGED
package/scripts/check.mjs
CHANGED
|
@@ -11,6 +11,7 @@ import { buildPlanDecisions, classifyGitShort } from "../src/lib/update-plan.mjs
|
|
|
11
11
|
import {
|
|
12
12
|
migrateSettingsRuntimeState,
|
|
13
13
|
mergeSettingsRuntimeMarkerIntoState,
|
|
14
|
+
refreshSettingsGitIndex,
|
|
14
15
|
settingsRuntimeMarkerFromObject,
|
|
15
16
|
stripSettingsRuntimeMarkerText,
|
|
16
17
|
} from "../src/lib/settings-runtime-state.mjs";
|
|
@@ -428,6 +429,33 @@ function runSettingsRuntimeStateSelfTests() {
|
|
|
428
429
|
"settings line-ending normalization must preserve JSON content and indentation",
|
|
429
430
|
);
|
|
430
431
|
fs.rmSync(tmpRoot, { recursive: true, force: true });
|
|
432
|
+
|
|
433
|
+
if (spawnSync("git", ["--version"], { encoding: "utf8" }).status === 0) {
|
|
434
|
+
const gitRoot = fs.mkdtempSync(path.join(os.tmpdir(), "pi67-settings-index-refresh-"));
|
|
435
|
+
const gitStateDir = path.join(gitRoot, "state");
|
|
436
|
+
fs.writeFileSync(path.join(gitRoot, ".gitattributes"), "settings.json text eol=lf\n");
|
|
437
|
+
fs.writeFileSync(path.join(gitRoot, "settings.json"), "{\n \"theme\": \"gruvbox-dark\"\n}\n");
|
|
438
|
+
for (const args of [
|
|
439
|
+
["-C", gitRoot, "init", "-q"],
|
|
440
|
+
["-C", gitRoot, "config", "user.email", "pi67-check@example.invalid"],
|
|
441
|
+
["-C", gitRoot, "config", "user.name", "pi67-check"],
|
|
442
|
+
["-C", gitRoot, "add", ".gitattributes", "settings.json"],
|
|
443
|
+
["-C", gitRoot, "commit", "-q", "-m", "init"],
|
|
444
|
+
]) {
|
|
445
|
+
const result = spawnSync("git", args, { encoding: "utf8" });
|
|
446
|
+
assert(result.status === 0, `git setup failed for settings index refresh self-test: git ${args.join(" ")}\n${result.stderr}`);
|
|
447
|
+
}
|
|
448
|
+
fs.writeFileSync(path.join(gitRoot, "settings.json"), "{\r\n \"theme\": \"gruvbox-dark\"\r\n}\r\n");
|
|
449
|
+
const statusBefore = spawnSync("git", ["-C", gitRoot, "status", "--short", "--", "settings.json"], { encoding: "utf8" });
|
|
450
|
+
const diffBefore = spawnSync("git", ["-C", gitRoot, "diff", "--quiet", "--", "settings.json"], { encoding: "utf8" });
|
|
451
|
+
assert(statusBefore.stdout.includes("settings.json"), "settings index refresh self-test must start with false-dirty status");
|
|
452
|
+
assert(diffBefore.status === 0, "settings index refresh self-test must have no real content diff");
|
|
453
|
+
const refreshResult = refreshSettingsGitIndex({ agentDir: gitRoot, repoRoot: gitRoot, stateDir: gitStateDir });
|
|
454
|
+
const statusAfter = spawnSync("git", ["-C", gitRoot, "status", "--short", "--", "settings.json"], { encoding: "utf8" });
|
|
455
|
+
assert(refreshResult.refreshed === true, "settings index refresh must classify cleared false-dirty status");
|
|
456
|
+
assert(!statusAfter.stdout.trim(), `settings index refresh must clear false-dirty status\n${statusAfter.stdout}`);
|
|
457
|
+
fs.rmSync(gitRoot, { recursive: true, force: true });
|
|
458
|
+
}
|
|
431
459
|
}
|
|
432
460
|
|
|
433
461
|
function runUpdatePreflightMigrationSelfTests() {
|
package/src/commands/install.mjs
CHANGED
|
@@ -60,6 +60,9 @@ export async function installCommand(ctx, argv) {
|
|
|
60
60
|
if (runtimeState.settingsNormalized) {
|
|
61
61
|
info("Normalized settings.json runtime marker/line endings.");
|
|
62
62
|
}
|
|
63
|
+
if (runtimeState.gitIndexRefreshed) {
|
|
64
|
+
info("Refreshed settings.json Git index stat cache.");
|
|
65
|
+
}
|
|
63
66
|
if (runtimeState.gitFilterInstalled) {
|
|
64
67
|
info("Installed local git clean filter for future settings.json runtime markers.");
|
|
65
68
|
}
|
package/src/commands/update.mjs
CHANGED
|
@@ -102,6 +102,9 @@ function reportSettingsRuntimeStateMigration(ctx, options = {}) {
|
|
|
102
102
|
if (result.settingsNormalized) {
|
|
103
103
|
info(`${phase}${dryRun ? "would normalize" : "Normalized"} settings.json runtime marker/line endings.`);
|
|
104
104
|
}
|
|
105
|
+
if (result.gitIndexRefreshed) {
|
|
106
|
+
info(`${phase}${dryRun ? "would refresh" : "Refreshed"} settings.json Git index stat cache.`);
|
|
107
|
+
}
|
|
105
108
|
if (result.gitFilterInstalled) {
|
|
106
109
|
info(`${phase}${dryRun ? "would install" : "Installed"} local git clean filter for future settings.json runtime markers.`);
|
|
107
110
|
}
|
|
@@ -68,6 +68,8 @@ export function migrateSettingsRuntimeState(ctx, options = {}) {
|
|
|
68
68
|
stateWritten: false,
|
|
69
69
|
settingsNormalized: false,
|
|
70
70
|
settingsNormalizeReasons: [],
|
|
71
|
+
gitIndexRefreshed: false,
|
|
72
|
+
gitIndexRefreshSkipped: "",
|
|
71
73
|
gitFilterInstalled: false,
|
|
72
74
|
skipped: [],
|
|
73
75
|
errors: [],
|
|
@@ -131,6 +133,13 @@ export function migrateSettingsRuntimeState(ctx, options = {}) {
|
|
|
131
133
|
if (filterResult.error) result.errors.push(filterResult.error);
|
|
132
134
|
}
|
|
133
135
|
|
|
136
|
+
if (normalizeSettingsJson) {
|
|
137
|
+
const refreshResult = refreshSettingsGitIndex(ctx, { dryRun });
|
|
138
|
+
result.gitIndexRefreshed = refreshResult.refreshed;
|
|
139
|
+
result.gitIndexRefreshSkipped = refreshResult.skipped;
|
|
140
|
+
if (refreshResult.error) result.errors.push(refreshResult.error);
|
|
141
|
+
}
|
|
142
|
+
|
|
134
143
|
return result;
|
|
135
144
|
}
|
|
136
145
|
|
|
@@ -140,6 +149,63 @@ export function normalizeSettingsTextLineEndings(text) {
|
|
|
140
149
|
.replace(/\r\n?/g, "\n");
|
|
141
150
|
}
|
|
142
151
|
|
|
152
|
+
export function refreshSettingsGitIndex(ctx, options = {}) {
|
|
153
|
+
const result = {
|
|
154
|
+
refreshed: false,
|
|
155
|
+
skipped: "",
|
|
156
|
+
error: "",
|
|
157
|
+
};
|
|
158
|
+
if (options.dryRun) {
|
|
159
|
+
result.refreshed = true;
|
|
160
|
+
return result;
|
|
161
|
+
}
|
|
162
|
+
if (!isGitRepo(ctx.repoRoot)) {
|
|
163
|
+
result.skipped = "repo root is not a git checkout";
|
|
164
|
+
return result;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const settingsPath = path.join(ctx.agentDir, "settings.json");
|
|
168
|
+
if (!fs.existsSync(settingsPath)) {
|
|
169
|
+
result.skipped = "settings.json missing";
|
|
170
|
+
return result;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const relativePath = path.relative(ctx.repoRoot, settingsPath);
|
|
174
|
+
if (!relativePath || relativePath.startsWith("..") || path.isAbsolute(relativePath)) {
|
|
175
|
+
result.skipped = "settings.json is outside repo root";
|
|
176
|
+
return result;
|
|
177
|
+
}
|
|
178
|
+
const gitPath = relativePath.split(path.sep).join("/");
|
|
179
|
+
|
|
180
|
+
const statusBefore = captureCommand("git", ["-C", ctx.repoRoot, "status", "--short", "--", gitPath]);
|
|
181
|
+
if (!statusBefore.ok) {
|
|
182
|
+
result.skipped = "could not inspect settings.json git status before index refresh";
|
|
183
|
+
return result;
|
|
184
|
+
}
|
|
185
|
+
if (!statusBefore.stdout.trim()) {
|
|
186
|
+
result.skipped = "settings.json git index already fresh";
|
|
187
|
+
return result;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const diffBefore = captureCommand("git", ["-C", ctx.repoRoot, "diff", "--quiet", "--", gitPath]);
|
|
191
|
+
if (diffBefore.status !== 0) {
|
|
192
|
+
result.skipped = "settings.json has real content diff; index refresh left it visible";
|
|
193
|
+
return result;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const refresh = captureCommand("git", ["-C", ctx.repoRoot, "update-index", "--refresh", "--", gitPath]);
|
|
197
|
+
|
|
198
|
+
const statusAfter = captureCommand("git", ["-C", ctx.repoRoot, "status", "--short", "--", gitPath]);
|
|
199
|
+
if (statusAfter.ok && !statusAfter.stdout.trim()) {
|
|
200
|
+
result.refreshed = true;
|
|
201
|
+
} else if (!refresh.ok) {
|
|
202
|
+
result.error = refresh.stderr || refresh.error || "failed to refresh settings.json git index";
|
|
203
|
+
} else {
|
|
204
|
+
result.skipped = "settings.json still appears dirty after git index refresh";
|
|
205
|
+
}
|
|
206
|
+
return result;
|
|
207
|
+
}
|
|
208
|
+
|
|
143
209
|
export function installSettingsRuntimeGitFilter(ctx, options = {}) {
|
|
144
210
|
const result = {
|
|
145
211
|
installed: false,
|
|
@@ -53,6 +53,9 @@ function printHuman(result) {
|
|
|
53
53
|
if (result.settingsNormalized) {
|
|
54
54
|
console.log("PASS normalized settings.json runtime marker/line endings");
|
|
55
55
|
}
|
|
56
|
+
if (result.gitIndexRefreshed) {
|
|
57
|
+
console.log("PASS refreshed settings.json Git index stat cache");
|
|
58
|
+
}
|
|
56
59
|
if (result.gitFilterInstalled) {
|
|
57
60
|
console.log("PASS installed local git clean filter for settings.json runtime marker");
|
|
58
61
|
}
|