@ikunin/sprintpilot 2.2.6 → 2.2.7
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.
|
@@ -56,7 +56,65 @@ function canonicalizeYaml(text) {
|
|
|
56
56
|
return `${lines.join('\n')}\n`;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
// Directory names always pruned from fingerprint walks. These are
|
|
60
|
+
// regenerable build/cache artifacts that change between sessions for
|
|
61
|
+
// reasons unrelated to BMad state (Python bytecode, dependency
|
|
62
|
+
// installs, transpiler output, OS metadata). Without pruning, a single
|
|
63
|
+
// halt fingerprint can balloon to 100s of MB and a `.pyc` regen on
|
|
64
|
+
// resume produces spurious divergence prompts.
|
|
65
|
+
//
|
|
66
|
+
// Real-world trigger: a user's `_bmad-output/spikes/<name>/.venv/` was
|
|
67
|
+
// 794 MB; every halt entry captured every path inside it.
|
|
68
|
+
const FINGERPRINT_PRUNE_DIRS = new Set([
|
|
69
|
+
'.venv',
|
|
70
|
+
'venv',
|
|
71
|
+
'env',
|
|
72
|
+
'node_modules',
|
|
73
|
+
'__pycache__',
|
|
74
|
+
'.pytest_cache',
|
|
75
|
+
'.mypy_cache',
|
|
76
|
+
'.ruff_cache',
|
|
77
|
+
'.tox',
|
|
78
|
+
'.gradle',
|
|
79
|
+
'target',
|
|
80
|
+
'dist',
|
|
81
|
+
'build',
|
|
82
|
+
'.next',
|
|
83
|
+
'.nuxt',
|
|
84
|
+
'.cache',
|
|
85
|
+
'.parcel-cache',
|
|
86
|
+
'.turbo',
|
|
87
|
+
'.git',
|
|
88
|
+
'.svn',
|
|
89
|
+
'.hg',
|
|
90
|
+
'.idea',
|
|
91
|
+
'.vscode',
|
|
92
|
+
// BMad/Sprintpilot internal — worktrees aren't fingerprinted; they're
|
|
93
|
+
// captured separately via context.worktreeScanner.
|
|
94
|
+
'.worktrees',
|
|
95
|
+
]);
|
|
96
|
+
|
|
97
|
+
// File suffixes always pruned. Generated / binary content that changes
|
|
98
|
+
// for non-state reasons.
|
|
99
|
+
const FINGERPRINT_PRUNE_SUFFIXES = [
|
|
100
|
+
'.pyc',
|
|
101
|
+
'.pyo',
|
|
102
|
+
'.pyd',
|
|
103
|
+
'.so',
|
|
104
|
+
'.o',
|
|
105
|
+
'.class',
|
|
106
|
+
'.DS_Store',
|
|
107
|
+
];
|
|
108
|
+
|
|
109
|
+
// Hard cap on number of entries in the fingerprint tree. Defends against
|
|
110
|
+
// pathological cases where prune lists don't catch a large embedded
|
|
111
|
+
// dependency tree. When hit, the walk stops and `out[__truncated__]`
|
|
112
|
+
// is set so callers know the fingerprint is incomplete (treated as
|
|
113
|
+
// divergent on diff to avoid false-negative resume).
|
|
114
|
+
const FINGERPRINT_MAX_ENTRIES = 5000;
|
|
115
|
+
|
|
59
116
|
function walkTree(fs, root, out, relBase) {
|
|
117
|
+
if (out.__truncated__) return;
|
|
60
118
|
let entries;
|
|
61
119
|
try {
|
|
62
120
|
entries = fs.readdirSync(root, { withFileTypes: true });
|
|
@@ -64,14 +122,31 @@ function walkTree(fs, root, out, relBase) {
|
|
|
64
122
|
return;
|
|
65
123
|
}
|
|
66
124
|
for (const ent of entries) {
|
|
125
|
+
if (out.__truncated__) return;
|
|
126
|
+
if (FINGERPRINT_PRUNE_DIRS.has(ent.name)) continue;
|
|
67
127
|
const full = path.join(root, ent.name);
|
|
68
128
|
const rel = path.join(relBase, ent.name);
|
|
69
129
|
if (ent.isDirectory()) {
|
|
70
130
|
walkTree(fs, full, out, rel);
|
|
71
131
|
} else if (ent.isFile()) {
|
|
132
|
+
let prune = false;
|
|
133
|
+
for (const sfx of FINGERPRINT_PRUNE_SUFFIXES) {
|
|
134
|
+
if (ent.name.endsWith(sfx)) {
|
|
135
|
+
prune = true;
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (prune) continue;
|
|
72
140
|
try {
|
|
73
141
|
const st = fs.statSync(full);
|
|
74
142
|
out[rel.split(path.sep).join('/')] = st.size;
|
|
143
|
+
// -1 for the future __truncated__ marker; -2 below for the actual count
|
|
144
|
+
// (avoid counting the marker itself).
|
|
145
|
+
const count = Object.keys(out).length - (out.__truncated__ ? 1 : 0);
|
|
146
|
+
if (count >= FINGERPRINT_MAX_ENTRIES) {
|
|
147
|
+
out.__truncated__ = true;
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
75
150
|
} catch (_e) {
|
|
76
151
|
// ignore unreadable
|
|
77
152
|
}
|
package/package.json
CHANGED