@bigking67/pi-67 0.10.8 → 0.10.10
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 +11 -0
- package/package.json +1 -1
- package/scripts/check.mjs +105 -0
- package/src/commands/update.mjs +11 -6
- package/src/lib/settings-runtime-state.mjs +26 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.10.10]
|
|
4
|
+
|
|
5
|
+
- Extends the update preflight runtime-marker regression to include the
|
|
6
|
+
PowerShell updater entrypoint used on Windows.
|
|
7
|
+
|
|
8
|
+
## [0.10.9]
|
|
9
|
+
|
|
10
|
+
- Runs settings runtime-marker migration before the local distro updater script
|
|
11
|
+
as well as after it, so latest npm manager repair can clean `M settings.json`
|
|
12
|
+
even when the local checkout still contains an older updater script.
|
|
13
|
+
|
|
3
14
|
## [0.10.8]
|
|
4
15
|
|
|
5
16
|
- Adds actionable `pi-67 version` recommendations when the npm manager has
|
package/package.json
CHANGED
package/scripts/check.mjs
CHANGED
|
@@ -42,6 +42,7 @@ runPublishTargetSelfTests();
|
|
|
42
42
|
runShellRunnerSelfTests();
|
|
43
43
|
runExtensionRegistrySelfTests();
|
|
44
44
|
runSettingsRuntimeStateSelfTests();
|
|
45
|
+
runUpdatePreflightMigrationSelfTests();
|
|
45
46
|
runUpdatePlanSelfTests();
|
|
46
47
|
runUpdateSafetySelfTests();
|
|
47
48
|
|
|
@@ -407,6 +408,110 @@ function runSettingsRuntimeStateSelfTests() {
|
|
|
407
408
|
);
|
|
408
409
|
}
|
|
409
410
|
|
|
411
|
+
function runUpdatePreflightMigrationSelfTests() {
|
|
412
|
+
if (spawnSync("git", ["--version"], { encoding: "utf8" }).status !== 0) return;
|
|
413
|
+
const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), "pi67-update-preflight-migration-"));
|
|
414
|
+
const home = path.join(tmpRoot, "home");
|
|
415
|
+
const repo = path.join(tmpRoot, "agent");
|
|
416
|
+
const skillsDir = path.join(tmpRoot, "skills");
|
|
417
|
+
const packagesDir = path.join(tmpRoot, "packages");
|
|
418
|
+
fs.mkdirSync(path.join(repo, "scripts"), { recursive: true });
|
|
419
|
+
fs.mkdirSync(home, { recursive: true });
|
|
420
|
+
fs.mkdirSync(skillsDir, { recursive: true });
|
|
421
|
+
fs.mkdirSync(packagesDir, { recursive: true });
|
|
422
|
+
fs.writeFileSync(path.join(repo, "VERSION"), "0.10.0\n");
|
|
423
|
+
fs.writeFileSync(path.join(repo, "settings.json"), "{\n \"theme\": \"gruvbox-dark\"\n}\n");
|
|
424
|
+
fs.writeFileSync(path.join(repo, "scripts", "pi67-update.sh"), `#!/usr/bin/env bash
|
|
425
|
+
set -euo pipefail
|
|
426
|
+
agent_dir=""
|
|
427
|
+
while [ "$#" -gt 0 ]; do
|
|
428
|
+
case "$1" in
|
|
429
|
+
--agent-dir)
|
|
430
|
+
agent_dir="$2"
|
|
431
|
+
shift 2
|
|
432
|
+
;;
|
|
433
|
+
*)
|
|
434
|
+
shift
|
|
435
|
+
;;
|
|
436
|
+
esac
|
|
437
|
+
done
|
|
438
|
+
if grep -q "lastChangelogVersion" "$agent_dir/settings.json"; then
|
|
439
|
+
echo "marker still present before distro script" >&2
|
|
440
|
+
exit 44
|
|
441
|
+
fi
|
|
442
|
+
`);
|
|
443
|
+
fs.writeFileSync(path.join(repo, "scripts", "pi67-update.ps1"), `param(
|
|
444
|
+
[string]$AgentDir,
|
|
445
|
+
[string]$RepoRoot,
|
|
446
|
+
[string]$SkillsDir,
|
|
447
|
+
[switch]$DryRun,
|
|
448
|
+
[switch]$ForceNpm,
|
|
449
|
+
[switch]$NoNpm,
|
|
450
|
+
[switch]$AllowDirty,
|
|
451
|
+
[switch]$StrictSharedSkills
|
|
452
|
+
)
|
|
453
|
+
$settings = Get-Content -LiteralPath (Join-Path $AgentDir "settings.json") -Raw
|
|
454
|
+
if ($settings -match "lastChangelogVersion") {
|
|
455
|
+
Write-Error "marker still present before distro script"
|
|
456
|
+
exit 44
|
|
457
|
+
}
|
|
458
|
+
`);
|
|
459
|
+
for (const args of [
|
|
460
|
+
["-C", repo, "init", "-q"],
|
|
461
|
+
["-C", repo, "config", "user.email", "pi67-check@example.invalid"],
|
|
462
|
+
["-C", repo, "config", "user.name", "pi67-check"],
|
|
463
|
+
["-C", repo, "add", "VERSION", "settings.json", "scripts/pi67-update.sh", "scripts/pi67-update.ps1"],
|
|
464
|
+
["-C", repo, "commit", "-q", "-m", "init"],
|
|
465
|
+
]) {
|
|
466
|
+
const result = spawnSync("git", args, { encoding: "utf8" });
|
|
467
|
+
assert(result.status === 0, `git setup failed for update preflight migration self-test: git ${args.join(" ")}\n${result.stderr}`);
|
|
468
|
+
}
|
|
469
|
+
fs.writeFileSync(path.join(repo, "settings.json"), "{\n \"lastChangelogVersion\": \"0.80.4\",\n \"theme\": \"gruvbox-dark\"\n}\n");
|
|
470
|
+
const env = { ...process.env, HOME: home, USERPROFILE: home };
|
|
471
|
+
const result = spawnSync(process.execPath, [
|
|
472
|
+
path.join(root, "bin", "pi-67.mjs"),
|
|
473
|
+
"--agent-dir",
|
|
474
|
+
repo,
|
|
475
|
+
"--repo-root",
|
|
476
|
+
repo,
|
|
477
|
+
"--skills-dir",
|
|
478
|
+
skillsDir,
|
|
479
|
+
"--packages-dir",
|
|
480
|
+
packagesDir,
|
|
481
|
+
"update",
|
|
482
|
+
"--repair",
|
|
483
|
+
"--no-remote",
|
|
484
|
+
"--no-npm",
|
|
485
|
+
], {
|
|
486
|
+
cwd: root,
|
|
487
|
+
env,
|
|
488
|
+
encoding: "utf8",
|
|
489
|
+
});
|
|
490
|
+
assert(
|
|
491
|
+
result.status === 0,
|
|
492
|
+
`update must preflight-normalize settings runtime marker before calling the distro script\nstdout:\n${result.stdout}\nstderr:\n${result.stderr}`,
|
|
493
|
+
);
|
|
494
|
+
assert(
|
|
495
|
+
result.stdout.includes("Preflight: Migrated settings.json lastChangelogVersion") &&
|
|
496
|
+
result.stdout.includes("Preflight: Normalized settings.json"),
|
|
497
|
+
`update output must report preflight runtime marker migration\n${result.stdout}`,
|
|
498
|
+
);
|
|
499
|
+
const settings = JSON.parse(fs.readFileSync(path.join(repo, "settings.json"), "utf8"));
|
|
500
|
+
assert(settings.lastChangelogVersion === undefined, "update preflight migration must remove lastChangelogVersion from settings.json");
|
|
501
|
+
const state = JSON.parse(fs.readFileSync(path.join(home, ".pi", "pi67", "state.json"), "utf8"));
|
|
502
|
+
assert(
|
|
503
|
+
state.runtimeMarkers?.lastChangelogVersion?.value === "0.80.4",
|
|
504
|
+
"update preflight migration must persist lastChangelogVersion into ignored state",
|
|
505
|
+
);
|
|
506
|
+
const status = spawnSync("git", ["-C", repo, "status", "--short"], { encoding: "utf8" });
|
|
507
|
+
assert(status.status === 0, `git status failed for update preflight migration self-test\n${status.stderr}`);
|
|
508
|
+
assert(
|
|
509
|
+
!status.stdout.split(/\r?\n/).some((line) => line.trim().endsWith("settings.json")),
|
|
510
|
+
`settings.json should be clean after preflight marker migration\n${status.stdout}`,
|
|
511
|
+
);
|
|
512
|
+
fs.rmSync(tmpRoot, { recursive: true, force: true });
|
|
513
|
+
}
|
|
514
|
+
|
|
410
515
|
function runUpdatePlanSelfTests() {
|
|
411
516
|
assert(
|
|
412
517
|
classifyGitShort(" M settings.json\n?? tmp.txt").preservedRuntime.includes("settings.json"),
|
package/src/commands/update.mjs
CHANGED
|
@@ -61,6 +61,8 @@ export async function updateCommand(ctx, argv) {
|
|
|
61
61
|
info(`Preserved runtime backup skipped: ${lifecycle.backupReason}`);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
reportSettingsRuntimeStateMigration(ctx, { dryRun, phase: "Preflight" });
|
|
65
|
+
|
|
64
66
|
const args = isWindows()
|
|
65
67
|
? buildWindowsUpdateArgs(ctx, options, dryRun)
|
|
66
68
|
: buildBashUpdateArgs(ctx, options, dryRun);
|
|
@@ -68,7 +70,7 @@ export async function updateCommand(ctx, argv) {
|
|
|
68
70
|
runDistroScript(ctx, { sh: "pi67-update.sh", ps1: "pi67-update.ps1" }, args, { dryRun: false });
|
|
69
71
|
if (!dryRun) {
|
|
70
72
|
writeState(ctx, options.repair ? "repair" : "update");
|
|
71
|
-
reportSettingsRuntimeStateMigration(ctx);
|
|
73
|
+
reportSettingsRuntimeStateMigration(ctx, { phase: "Post-update" });
|
|
72
74
|
}
|
|
73
75
|
} finally {
|
|
74
76
|
lifecycle.release();
|
|
@@ -86,19 +88,22 @@ export async function updateCommand(ctx, argv) {
|
|
|
86
88
|
}
|
|
87
89
|
}
|
|
88
90
|
|
|
89
|
-
function reportSettingsRuntimeStateMigration(ctx) {
|
|
91
|
+
function reportSettingsRuntimeStateMigration(ctx, options = {}) {
|
|
92
|
+
const dryRun = Boolean(options.dryRun);
|
|
93
|
+
const phase = options.phase ? `${options.phase}: ` : "";
|
|
90
94
|
const result = migrateSettingsRuntimeState(ctx, {
|
|
91
95
|
normalizeSettingsJson: true,
|
|
92
96
|
installGitFilter: true,
|
|
97
|
+
dryRun,
|
|
93
98
|
});
|
|
94
|
-
if (result.markerFound && result.stateWritten) {
|
|
95
|
-
info("Migrated settings.json lastChangelogVersion to ignored state: ~/.pi/pi67/state.json
|
|
99
|
+
if (result.markerFound && (result.stateWritten || dryRun)) {
|
|
100
|
+
info(`${phase}${dryRun ? "would migrate" : "Migrated"} settings.json lastChangelogVersion to ignored state: ~/.pi/pi67/state.json`);
|
|
96
101
|
}
|
|
97
102
|
if (result.settingsNormalized) {
|
|
98
|
-
info("Normalized settings.json by removing runtime-only lastChangelogVersion
|
|
103
|
+
info(`${phase}${dryRun ? "would normalize" : "Normalized"} settings.json by removing runtime-only lastChangelogVersion.`);
|
|
99
104
|
}
|
|
100
105
|
if (result.gitFilterInstalled) {
|
|
101
|
-
info("Installed local git clean filter for future settings.json runtime markers
|
|
106
|
+
info(`${phase}${dryRun ? "would install" : "Installed"} local git clean filter for future settings.json runtime markers.`);
|
|
102
107
|
}
|
|
103
108
|
for (const error of result.errors) {
|
|
104
109
|
warn(`settings runtime marker migration skipped: ${error}`);
|
|
@@ -138,6 +138,32 @@ export function installSettingsRuntimeGitFilter(ctx, options = {}) {
|
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
const cleanCommand = `node ${SETTINGS_RUNTIME_FILTER_SCRIPT} --clean`;
|
|
141
|
+
const existingClean = captureCommand("git", [
|
|
142
|
+
"-C",
|
|
143
|
+
ctx.repoRoot,
|
|
144
|
+
"config",
|
|
145
|
+
"--local",
|
|
146
|
+
"--get",
|
|
147
|
+
`filter.${SETTINGS_RUNTIME_FILTER_NAME}.clean`,
|
|
148
|
+
]);
|
|
149
|
+
const existingRequired = captureCommand("git", [
|
|
150
|
+
"-C",
|
|
151
|
+
ctx.repoRoot,
|
|
152
|
+
"config",
|
|
153
|
+
"--local",
|
|
154
|
+
"--get",
|
|
155
|
+
`filter.${SETTINGS_RUNTIME_FILTER_NAME}.required`,
|
|
156
|
+
]);
|
|
157
|
+
if (
|
|
158
|
+
existingClean.ok &&
|
|
159
|
+
existingClean.stdout.trim() === cleanCommand &&
|
|
160
|
+
existingRequired.ok &&
|
|
161
|
+
existingRequired.stdout.trim() === "false"
|
|
162
|
+
) {
|
|
163
|
+
result.skipped = "settings runtime filter already installed";
|
|
164
|
+
return result;
|
|
165
|
+
}
|
|
166
|
+
|
|
141
167
|
const clean = captureCommand("git", [
|
|
142
168
|
"-C",
|
|
143
169
|
ctx.repoRoot,
|