omp-fabric 1.25.28 → 1.25.31
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,35 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.25.31
|
|
4
|
+
|
|
5
|
+
### Notes
|
|
6
|
+
|
|
7
|
+
- Test-only fix for the Windows job: the temporary-tier sweep test removed the right ledger but compared that path against a freshly canonicalized one, which differs in path form between platforms. It now asserts one removal whose tail is the fixture project.
|
|
8
|
+
- 1.25.29 and 1.25.30 both failed the windows-latest Test job and never published; every sweep change described under 1.25.29 and 1.25.30 ships in this release. Their `v1.25.29` and `v1.25.30` tags stay where they are.
|
|
9
|
+
|
|
10
|
+
## 1.25.30
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Temporary-root detection survives Windows path forms. `os.tmpdir()` reports the short-name form (`C:\Users\RUNNER~1\AppData\Local\Temp`) while a project path that went through `realpath` is long-name, and the comparison was case-sensitive, so the temporary retention tier missed those projects on Windows. Both sides now resolve through `fs.realpathSync.native` (falling back to the deepest existing ancestor) and compare case-insensitively on win32.
|
|
15
|
+
- The stale-record sweep test asserts on the record's path tail instead of a canonicalized equality, which differed between platforms.
|
|
16
|
+
|
|
17
|
+
### Notes
|
|
18
|
+
|
|
19
|
+
- 1.25.29's Test job failed on windows-latest for those two cases and it never published; its sweep changes ship in this release. Its `v1.25.29` tag stays where it is.
|
|
20
|
+
|
|
21
|
+
## 1.25.29
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- Ledger sweep works on two retention tiers: a project path under a temporary root (`os.tmpdir()`, `/tmp`, `/var/tmp`) is reclaimed after 2 days instead of 30, because fixture and smoke repos are throwaway by construction while a real project directory can be missing temporarily (unmounted drive, renamed checkout) and still deserve its history. `sweepLedgers` takes `tempRetentionMs` for callers that want a different tier. The sweep interval stays 24h.
|
|
26
|
+
- The sweep also drops a directory record whose ledger file is gone. It used to skip those records forever (`statSync` failed, `continue`), so every deleted ledger left a permanent entry in `projects.json`.
|
|
27
|
+
|
|
28
|
+
### Notes
|
|
29
|
+
|
|
30
|
+
- Measured before this change: the ledger root held 17.36GB across 69 files, and the biggest ones belong to real projects (Kaitech/Odoo19/modifier 2.5GB, Kaitech/Odoo19 2.4GB, apollo-coworker 2.0GB, paperclip-pro 1.9GB). Files whose project directory is gone totalled 0.15GB, so reclaiming abandoned paths is a hygiene fix, not a disk fix; per-project ledger growth is the real consumer and needs entry-level retention inside a ledger.
|
|
31
|
+
- Operational hazard found while aligning the plugin tree: with `~/.omp/plugins` pinning `@oh-my-pi/pi-coding-agent` at 18.11.0 instead of 18.7.0, one measurement session logged a `session_start` timeout again, and reverting the pin cleared it (6 sessions clean at 18.7.0). Fabric eagerly imports host tool subpaths, which the tree resolves to raw TypeScript, so the tree's host pin changes the extension's own load cost. Making those imports lazy is the prerequisite for moving that pin.
|
|
32
|
+
|
|
3
33
|
## 1.25.28
|
|
4
34
|
|
|
5
35
|
### Fixed
|
|
@@ -59,11 +59,51 @@ import crypto from "node:crypto";
|
|
|
59
59
|
|
|
60
60
|
// src/storage/lcm-directory.ts
|
|
61
61
|
import fs from "node:fs";
|
|
62
|
+
import os from "node:os";
|
|
62
63
|
import path from "node:path";
|
|
63
64
|
var DIRECTORY_FILE = "projects.json";
|
|
64
65
|
var DIRECTORY_VERSION = 1;
|
|
65
66
|
var SWEEP_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
66
67
|
var RETENTION_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
68
|
+
var TEMP_RETENTION_MS = 2 * 24 * 60 * 60 * 1e3;
|
|
69
|
+
var tempRootCandidates = () => {
|
|
70
|
+
const roots = /* @__PURE__ */ new Set();
|
|
71
|
+
for (const root of [os.tmpdir(), "/tmp", "/var/tmp"]) {
|
|
72
|
+
const resolved = path.resolve(root);
|
|
73
|
+
roots.add(resolved);
|
|
74
|
+
try {
|
|
75
|
+
roots.add(fs.realpathSync.native(resolved));
|
|
76
|
+
} catch {
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return [...roots];
|
|
80
|
+
};
|
|
81
|
+
var isUnderTempRoot = (target) => {
|
|
82
|
+
const resolved = path.resolve(target);
|
|
83
|
+
const candidates = /* @__PURE__ */ new Set([resolved]);
|
|
84
|
+
try {
|
|
85
|
+
candidates.add(fs.realpathSync.native(resolved));
|
|
86
|
+
} catch {
|
|
87
|
+
let probe = resolved;
|
|
88
|
+
while (true) {
|
|
89
|
+
const parent = path.dirname(probe);
|
|
90
|
+
if (parent === probe) break;
|
|
91
|
+
probe = parent;
|
|
92
|
+
try {
|
|
93
|
+
const real = fs.realpathSync.native(probe);
|
|
94
|
+
candidates.add(path.join(real, path.relative(probe, resolved)));
|
|
95
|
+
break;
|
|
96
|
+
} catch {
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const normalize = (value) => process.platform === "win32" ? value.toLowerCase() : value;
|
|
101
|
+
const normalized = [...candidates].map(normalize);
|
|
102
|
+
return tempRootCandidates().some((root) => {
|
|
103
|
+
const base = normalize(root.endsWith(path.sep) ? root.slice(0, -1) : root);
|
|
104
|
+
return normalized.some((candidate) => candidate === base || candidate.startsWith(base + path.sep));
|
|
105
|
+
});
|
|
106
|
+
};
|
|
67
107
|
var empty = () => ({ version: DIRECTORY_VERSION, sweptAt: 0, projects: [] });
|
|
68
108
|
var directoryFile = (rootDir) => path.join(rootDir, DIRECTORY_FILE);
|
|
69
109
|
var read = (rootDir) => {
|
|
@@ -112,6 +152,7 @@ var stableProjectKey = (rootDir, identity, now = Date.now()) => {
|
|
|
112
152
|
var sweepLedgers = (rootDir, options) => {
|
|
113
153
|
const now = options.now ?? Date.now();
|
|
114
154
|
const retentionMs = options.retentionMs ?? RETENTION_MS;
|
|
155
|
+
const tempRetentionMs = options.tempRetentionMs ?? TEMP_RETENTION_MS;
|
|
115
156
|
const file = read(rootDir);
|
|
116
157
|
if (!options.force && now - file.sweptAt < SWEEP_INTERVAL_MS) return { removed: [], bytes: 0, skipped: true };
|
|
117
158
|
const removed = [];
|
|
@@ -123,9 +164,12 @@ var sweepLedgers = (rootDir, options) => {
|
|
|
123
164
|
try {
|
|
124
165
|
stats = fs.statSync(ledger);
|
|
125
166
|
} catch {
|
|
167
|
+
if (record2.key !== options.keepKey) continue;
|
|
168
|
+
kept.push(record2);
|
|
126
169
|
continue;
|
|
127
170
|
}
|
|
128
|
-
const
|
|
171
|
+
const retention = isUnderTempRoot(record2.path) ? tempRetentionMs : retentionMs;
|
|
172
|
+
const abandoned = record2.key !== options.keepKey && !fs.existsSync(record2.path) && now - Math.max(stats.mtimeMs, record2.updatedAt) >= retention;
|
|
129
173
|
if (!abandoned) {
|
|
130
174
|
kept.push(record2);
|
|
131
175
|
continue;
|