@blockspool/cli 0.4.0 → 0.4.1
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/package.json +1 -1
- package/dist/bin/blockspool.d.ts +0 -16
- package/dist/bin/blockspool.d.ts.map +0 -1
- package/dist/bin/blockspool.js +0 -45
- package/dist/bin/blockspool.js.map +0 -1
- package/dist/commands/solo-auto.d.ts +0 -6
- package/dist/commands/solo-auto.d.ts.map +0 -1
- package/dist/commands/solo-auto.js +0 -418
- package/dist/commands/solo-auto.js.map +0 -1
- package/dist/commands/solo-exec.d.ts +0 -6
- package/dist/commands/solo-exec.d.ts.map +0 -1
- package/dist/commands/solo-exec.js +0 -656
- package/dist/commands/solo-exec.js.map +0 -1
- package/dist/commands/solo-inspect.d.ts +0 -6
- package/dist/commands/solo-inspect.d.ts.map +0 -1
- package/dist/commands/solo-inspect.js +0 -690
- package/dist/commands/solo-inspect.js.map +0 -1
- package/dist/commands/solo-lifecycle.d.ts +0 -6
- package/dist/commands/solo-lifecycle.d.ts.map +0 -1
- package/dist/commands/solo-lifecycle.js +0 -188
- package/dist/commands/solo-lifecycle.js.map +0 -1
- package/dist/commands/solo-nudge.d.ts +0 -6
- package/dist/commands/solo-nudge.d.ts.map +0 -1
- package/dist/commands/solo-nudge.js +0 -49
- package/dist/commands/solo-nudge.js.map +0 -1
- package/dist/commands/solo-qa.d.ts +0 -6
- package/dist/commands/solo-qa.d.ts.map +0 -1
- package/dist/commands/solo-qa.js +0 -254
- package/dist/commands/solo-qa.js.map +0 -1
- package/dist/commands/solo.d.ts +0 -11
- package/dist/commands/solo.d.ts.map +0 -1
- package/dist/commands/solo.js +0 -43
- package/dist/commands/solo.js.map +0 -1
- package/dist/index.d.ts +0 -18
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -18
- package/dist/index.js.map +0 -1
- package/dist/lib/artifacts.d.ts +0 -136
- package/dist/lib/artifacts.d.ts.map +0 -1
- package/dist/lib/artifacts.js +0 -146
- package/dist/lib/artifacts.js.map +0 -1
- package/dist/lib/doctor.d.ts +0 -45
- package/dist/lib/doctor.d.ts.map +0 -1
- package/dist/lib/doctor.js +0 -383
- package/dist/lib/doctor.js.map +0 -1
- package/dist/lib/exec.d.ts +0 -24
- package/dist/lib/exec.d.ts.map +0 -1
- package/dist/lib/exec.js +0 -295
- package/dist/lib/exec.js.map +0 -1
- package/dist/lib/formulas.d.ts +0 -78
- package/dist/lib/formulas.d.ts.map +0 -1
- package/dist/lib/formulas.js +0 -295
- package/dist/lib/formulas.js.map +0 -1
- package/dist/lib/git.d.ts +0 -9
- package/dist/lib/git.d.ts.map +0 -1
- package/dist/lib/git.js +0 -60
- package/dist/lib/git.js.map +0 -1
- package/dist/lib/guidelines.d.ts +0 -43
- package/dist/lib/guidelines.d.ts.map +0 -1
- package/dist/lib/guidelines.js +0 -195
- package/dist/lib/guidelines.js.map +0 -1
- package/dist/lib/logger.d.ts +0 -17
- package/dist/lib/logger.d.ts.map +0 -1
- package/dist/lib/logger.js +0 -42
- package/dist/lib/logger.js.map +0 -1
- package/dist/lib/retention.d.ts +0 -62
- package/dist/lib/retention.d.ts.map +0 -1
- package/dist/lib/retention.js +0 -285
- package/dist/lib/retention.js.map +0 -1
- package/dist/lib/run-history.d.ts +0 -52
- package/dist/lib/run-history.d.ts.map +0 -1
- package/dist/lib/run-history.js +0 -116
- package/dist/lib/run-history.js.map +0 -1
- package/dist/lib/run-state.d.ts +0 -58
- package/dist/lib/run-state.d.ts.map +0 -1
- package/dist/lib/run-state.js +0 -119
- package/dist/lib/run-state.js.map +0 -1
- package/dist/lib/scope.d.ts +0 -95
- package/dist/lib/scope.d.ts.map +0 -1
- package/dist/lib/scope.js +0 -291
- package/dist/lib/scope.js.map +0 -1
- package/dist/lib/selection.d.ts +0 -35
- package/dist/lib/selection.d.ts.map +0 -1
- package/dist/lib/selection.js +0 -110
- package/dist/lib/selection.js.map +0 -1
- package/dist/lib/solo-auto.d.ts +0 -87
- package/dist/lib/solo-auto.d.ts.map +0 -1
- package/dist/lib/solo-auto.js +0 -1230
- package/dist/lib/solo-auto.js.map +0 -1
- package/dist/lib/solo-ci.d.ts +0 -84
- package/dist/lib/solo-ci.d.ts.map +0 -1
- package/dist/lib/solo-ci.js +0 -300
- package/dist/lib/solo-ci.js.map +0 -1
- package/dist/lib/solo-config.d.ts +0 -155
- package/dist/lib/solo-config.d.ts.map +0 -1
- package/dist/lib/solo-config.js +0 -236
- package/dist/lib/solo-config.js.map +0 -1
- package/dist/lib/solo-git.d.ts +0 -44
- package/dist/lib/solo-git.d.ts.map +0 -1
- package/dist/lib/solo-git.js +0 -174
- package/dist/lib/solo-git.js.map +0 -1
- package/dist/lib/solo-hints.d.ts +0 -32
- package/dist/lib/solo-hints.d.ts.map +0 -1
- package/dist/lib/solo-hints.js +0 -98
- package/dist/lib/solo-hints.js.map +0 -1
- package/dist/lib/solo-remote.d.ts +0 -14
- package/dist/lib/solo-remote.d.ts.map +0 -1
- package/dist/lib/solo-remote.js +0 -48
- package/dist/lib/solo-remote.js.map +0 -1
- package/dist/lib/solo-stdin.d.ts +0 -13
- package/dist/lib/solo-stdin.d.ts.map +0 -1
- package/dist/lib/solo-stdin.js +0 -33
- package/dist/lib/solo-stdin.js.map +0 -1
- package/dist/lib/solo-ticket.d.ts +0 -213
- package/dist/lib/solo-ticket.d.ts.map +0 -1
- package/dist/lib/solo-ticket.js +0 -850
- package/dist/lib/solo-ticket.js.map +0 -1
- package/dist/lib/solo-utils.d.ts +0 -133
- package/dist/lib/solo-utils.d.ts.map +0 -1
- package/dist/lib/solo-utils.js +0 -300
- package/dist/lib/solo-utils.js.map +0 -1
- package/dist/lib/spindle.d.ts +0 -144
- package/dist/lib/spindle.d.ts.map +0 -1
- package/dist/lib/spindle.js +0 -388
- package/dist/lib/spindle.js.map +0 -1
- package/dist/tui/app.d.ts +0 -17
- package/dist/tui/app.d.ts.map +0 -1
- package/dist/tui/app.js +0 -139
- package/dist/tui/app.js.map +0 -1
- package/dist/tui/index.d.ts +0 -8
- package/dist/tui/index.d.ts.map +0 -1
- package/dist/tui/index.js +0 -7
- package/dist/tui/index.js.map +0 -1
- package/dist/tui/poller.d.ts +0 -42
- package/dist/tui/poller.d.ts.map +0 -1
- package/dist/tui/poller.js +0 -62
- package/dist/tui/poller.js.map +0 -1
- package/dist/tui/screens/overview.d.ts +0 -9
- package/dist/tui/screens/overview.d.ts.map +0 -1
- package/dist/tui/screens/overview.js +0 -189
- package/dist/tui/screens/overview.js.map +0 -1
- package/dist/tui/state.d.ts +0 -93
- package/dist/tui/state.d.ts.map +0 -1
- package/dist/tui/state.js +0 -169
- package/dist/tui/state.js.map +0 -1
- package/dist/tui/types.d.ts +0 -18
- package/dist/tui/types.d.ts.map +0 -1
- package/dist/tui/types.js +0 -5
- package/dist/tui/types.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"spindle.d.ts","sourceRoot":"","sources":["../../src/lib/spindle.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/spindle.js
DELETED
|
@@ -1,388 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Spindle Loop Detection
|
|
3
|
-
*
|
|
4
|
-
* Monitors agent execution for unproductive patterns:
|
|
5
|
-
* - Oscillation: Similar diffs being applied and reverted
|
|
6
|
-
* - Spinning: High tool call rate without progress
|
|
7
|
-
* - Stalling: Verbose output without meaningful changes
|
|
8
|
-
* - Repetition: Same errors or phrases repeated
|
|
9
|
-
*
|
|
10
|
-
* Named "Spindle" after the spinning wheel component — when the spindle
|
|
11
|
-
* jams, it spins without producing thread.
|
|
12
|
-
*/
|
|
13
|
-
/**
|
|
14
|
-
* Default Spindle configuration
|
|
15
|
-
*/
|
|
16
|
-
export const DEFAULT_SPINDLE_CONFIG = {
|
|
17
|
-
enabled: true,
|
|
18
|
-
similarityThreshold: 0.8,
|
|
19
|
-
maxSimilarOutputs: 3,
|
|
20
|
-
maxStallIterations: 5,
|
|
21
|
-
verbosityThreshold: 10,
|
|
22
|
-
tokenBudgetWarning: 100000,
|
|
23
|
-
tokenBudgetAbort: 140000,
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* Create initial Spindle state
|
|
27
|
-
*/
|
|
28
|
-
export function createSpindleState() {
|
|
29
|
-
return {
|
|
30
|
-
outputs: [],
|
|
31
|
-
diffs: [],
|
|
32
|
-
iterationsSinceChange: 0,
|
|
33
|
-
estimatedTokens: 0,
|
|
34
|
-
warnings: [],
|
|
35
|
-
totalOutputChars: 0,
|
|
36
|
-
totalChangeChars: 0,
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Estimate token count from text
|
|
41
|
-
* Rough approximation: ~4 characters per token for English text
|
|
42
|
-
*/
|
|
43
|
-
export function estimateTokens(text) {
|
|
44
|
-
if (!text)
|
|
45
|
-
return 0;
|
|
46
|
-
return Math.ceil(text.length / 4);
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Compute similarity between two strings using Jaccard index on word tokens
|
|
50
|
-
*
|
|
51
|
-
* @returns Similarity score from 0 (completely different) to 1 (identical)
|
|
52
|
-
*/
|
|
53
|
-
export function computeSimilarity(a, b) {
|
|
54
|
-
if (!a && !b)
|
|
55
|
-
return 1;
|
|
56
|
-
if (!a || !b)
|
|
57
|
-
return 0;
|
|
58
|
-
// Tokenize on whitespace and punctuation, lowercase
|
|
59
|
-
const tokenize = (s) => {
|
|
60
|
-
const tokens = s
|
|
61
|
-
.toLowerCase()
|
|
62
|
-
.split(/[\s.,;:!?\-()[\]{}"']+/)
|
|
63
|
-
.filter(t => t.length > 0);
|
|
64
|
-
return new Set(tokens);
|
|
65
|
-
};
|
|
66
|
-
const tokensA = tokenize(a);
|
|
67
|
-
const tokensB = tokenize(b);
|
|
68
|
-
if (tokensA.size === 0 && tokensB.size === 0)
|
|
69
|
-
return 1;
|
|
70
|
-
if (tokensA.size === 0 || tokensB.size === 0)
|
|
71
|
-
return 0;
|
|
72
|
-
// Jaccard index: |intersection| / |union|
|
|
73
|
-
let intersectionSize = 0;
|
|
74
|
-
for (const token of tokensA) {
|
|
75
|
-
if (tokensB.has(token)) {
|
|
76
|
-
intersectionSize++;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
const unionSize = tokensA.size + tokensB.size - intersectionSize;
|
|
80
|
-
return intersectionSize / unionSize;
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Extract added and removed lines from a unified diff
|
|
84
|
-
*/
|
|
85
|
-
function extractDiffLines(diff) {
|
|
86
|
-
const lines = diff.split('\n');
|
|
87
|
-
const added = [];
|
|
88
|
-
const removed = [];
|
|
89
|
-
for (const line of lines) {
|
|
90
|
-
// Skip diff headers
|
|
91
|
-
if (line.startsWith('+++') || line.startsWith('---') || line.startsWith('@@')) {
|
|
92
|
-
continue;
|
|
93
|
-
}
|
|
94
|
-
if (line.startsWith('+')) {
|
|
95
|
-
added.push(line.slice(1).trim());
|
|
96
|
-
}
|
|
97
|
-
else if (line.startsWith('-')) {
|
|
98
|
-
removed.push(line.slice(1).trim());
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
return { added, removed };
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Detect oscillation pattern in diffs
|
|
105
|
-
*
|
|
106
|
-
* Looks for add→remove→add or remove→add→remove patterns where similar
|
|
107
|
-
* content is being repeatedly changed back and forth.
|
|
108
|
-
*
|
|
109
|
-
* @returns Object with detected flag and pattern description
|
|
110
|
-
*/
|
|
111
|
-
export function detectOscillation(diffs, similarityThreshold = 0.8) {
|
|
112
|
-
if (diffs.length < 2) {
|
|
113
|
-
return { detected: false, confidence: 0 };
|
|
114
|
-
}
|
|
115
|
-
// Analyze last 3 diffs (or 2 if only 2 available)
|
|
116
|
-
const recentDiffs = diffs.slice(-3);
|
|
117
|
-
const patterns = recentDiffs.map(d => extractDiffLines(d));
|
|
118
|
-
// With 2 diffs: check if what was added is now removed (or vice versa)
|
|
119
|
-
if (patterns.length >= 2) {
|
|
120
|
-
const [prev, curr] = patterns.slice(-2);
|
|
121
|
-
// Check: lines added in prev are now removed in curr
|
|
122
|
-
for (const addedLine of prev.added) {
|
|
123
|
-
if (addedLine.length < 3)
|
|
124
|
-
continue; // Skip trivial lines
|
|
125
|
-
for (const removedLine of curr.removed) {
|
|
126
|
-
const sim = computeSimilarity(addedLine, removedLine);
|
|
127
|
-
if (sim >= similarityThreshold) {
|
|
128
|
-
return {
|
|
129
|
-
detected: true,
|
|
130
|
-
pattern: `Added then removed: "${addedLine.slice(0, 50)}..."`,
|
|
131
|
-
confidence: sim,
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
// Check: lines removed in prev are now added in curr
|
|
137
|
-
for (const removedLine of prev.removed) {
|
|
138
|
-
if (removedLine.length < 3)
|
|
139
|
-
continue;
|
|
140
|
-
for (const addedLine of curr.added) {
|
|
141
|
-
const sim = computeSimilarity(removedLine, addedLine);
|
|
142
|
-
if (sim >= similarityThreshold) {
|
|
143
|
-
return {
|
|
144
|
-
detected: true,
|
|
145
|
-
pattern: `Removed then re-added: "${removedLine.slice(0, 50)}..."`,
|
|
146
|
-
confidence: sim,
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
// With 3 diffs: check for A→B→A pattern
|
|
153
|
-
if (patterns.length === 3) {
|
|
154
|
-
const [first, , third] = patterns;
|
|
155
|
-
// Check if first additions match third additions (came back to same state)
|
|
156
|
-
for (const line1 of first.added) {
|
|
157
|
-
if (line1.length < 3)
|
|
158
|
-
continue;
|
|
159
|
-
for (const line3 of third.added) {
|
|
160
|
-
const sim = computeSimilarity(line1, line3);
|
|
161
|
-
if (sim >= similarityThreshold) {
|
|
162
|
-
return {
|
|
163
|
-
detected: true,
|
|
164
|
-
pattern: `Oscillating: same content added in iterations 1 and 3`,
|
|
165
|
-
confidence: sim,
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
return { detected: false, confidence: 0 };
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Detect repetition in agent outputs
|
|
175
|
-
*
|
|
176
|
-
* Looks for consecutive similar outputs that indicate the agent is stuck
|
|
177
|
-
* in a loop saying the same things.
|
|
178
|
-
*/
|
|
179
|
-
export function detectRepetition(outputs, latestOutput, config) {
|
|
180
|
-
const patterns = [];
|
|
181
|
-
let maxSimilarity = 0;
|
|
182
|
-
// Compare latest output with recent outputs
|
|
183
|
-
for (const prevOutput of outputs.slice(-config.maxSimilarOutputs)) {
|
|
184
|
-
const sim = computeSimilarity(latestOutput, prevOutput);
|
|
185
|
-
if (sim >= config.similarityThreshold) {
|
|
186
|
-
maxSimilarity = Math.max(maxSimilarity, sim);
|
|
187
|
-
// Extract repeated phrases
|
|
188
|
-
const phrases = findRepeatedPhrases(latestOutput, prevOutput);
|
|
189
|
-
patterns.push(...phrases);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
// Check for common "stuck" phrases
|
|
193
|
-
const stuckPhrases = [
|
|
194
|
-
'let me try',
|
|
195
|
-
'i apologize',
|
|
196
|
-
"i'll try again",
|
|
197
|
-
'let me attempt',
|
|
198
|
-
'trying again',
|
|
199
|
-
'one more time',
|
|
200
|
-
'another approach',
|
|
201
|
-
];
|
|
202
|
-
const lowerOutput = latestOutput.toLowerCase();
|
|
203
|
-
for (const phrase of stuckPhrases) {
|
|
204
|
-
if (lowerOutput.includes(phrase)) {
|
|
205
|
-
const occurrences = outputs.filter(o => o.toLowerCase().includes(phrase)).length;
|
|
206
|
-
if (occurrences >= 2) {
|
|
207
|
-
patterns.push(`Repeated phrase: "${phrase}" (${occurrences + 1} times)`);
|
|
208
|
-
// Set high similarity since stuck phrases are a strong signal
|
|
209
|
-
maxSimilarity = Math.max(maxSimilarity, 0.85);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
const detected = patterns.length > 0 && maxSimilarity >= config.similarityThreshold;
|
|
214
|
-
return {
|
|
215
|
-
detected,
|
|
216
|
-
patterns: [...new Set(patterns)].slice(0, 5), // Dedupe and limit
|
|
217
|
-
confidence: maxSimilarity,
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
/**
|
|
221
|
-
* Find repeated phrases between two texts
|
|
222
|
-
*/
|
|
223
|
-
function findRepeatedPhrases(a, b) {
|
|
224
|
-
const phrases = [];
|
|
225
|
-
// Split into sentences/fragments
|
|
226
|
-
const fragmentsA = a.split(/[.!?\n]+/).filter(f => f.trim().length > 20);
|
|
227
|
-
const fragmentsB = b.split(/[.!?\n]+/).filter(f => f.trim().length > 20);
|
|
228
|
-
for (const fragA of fragmentsA) {
|
|
229
|
-
for (const fragB of fragmentsB) {
|
|
230
|
-
const sim = computeSimilarity(fragA, fragB);
|
|
231
|
-
if (sim >= 0.9) {
|
|
232
|
-
phrases.push(fragA.trim().slice(0, 60) + '...');
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
return phrases;
|
|
237
|
-
}
|
|
238
|
-
/**
|
|
239
|
-
* Check if agent is in a Spindle loop
|
|
240
|
-
*
|
|
241
|
-
* Updates state in-place and returns detection result.
|
|
242
|
-
*
|
|
243
|
-
* @param state - Current Spindle state (will be mutated)
|
|
244
|
-
* @param latestOutput - Agent's latest output text
|
|
245
|
-
* @param latestDiff - Latest git diff (null if no changes)
|
|
246
|
-
* @param config - Spindle configuration
|
|
247
|
-
* @returns Detection result
|
|
248
|
-
*/
|
|
249
|
-
export function checkSpindleLoop(state, latestOutput, latestDiff, config) {
|
|
250
|
-
// If disabled, always pass
|
|
251
|
-
if (!config.enabled) {
|
|
252
|
-
return { shouldAbort: false, confidence: 0, diagnostics: {} };
|
|
253
|
-
}
|
|
254
|
-
// Update state with latest data
|
|
255
|
-
const outputTokens = estimateTokens(latestOutput);
|
|
256
|
-
const diffTokens = estimateTokens(latestDiff ?? '');
|
|
257
|
-
state.estimatedTokens += outputTokens + diffTokens;
|
|
258
|
-
state.totalOutputChars += latestOutput.length;
|
|
259
|
-
state.totalChangeChars += (latestDiff ?? '').length;
|
|
260
|
-
// Store for pattern detection (keep last N)
|
|
261
|
-
state.outputs.push(latestOutput);
|
|
262
|
-
if (state.outputs.length > config.maxSimilarOutputs + 1) {
|
|
263
|
-
state.outputs.shift();
|
|
264
|
-
}
|
|
265
|
-
if (latestDiff) {
|
|
266
|
-
state.diffs.push(latestDiff);
|
|
267
|
-
if (state.diffs.length > 5) {
|
|
268
|
-
state.diffs.shift();
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
// Track iterations without changes
|
|
272
|
-
if (!latestDiff || latestDiff.trim() === '') {
|
|
273
|
-
state.iterationsSinceChange++;
|
|
274
|
-
}
|
|
275
|
-
else {
|
|
276
|
-
state.iterationsSinceChange = 0;
|
|
277
|
-
}
|
|
278
|
-
// Check 1: Token budget
|
|
279
|
-
if (state.estimatedTokens >= config.tokenBudgetAbort) {
|
|
280
|
-
return {
|
|
281
|
-
shouldAbort: true,
|
|
282
|
-
reason: 'token_budget',
|
|
283
|
-
confidence: 1.0,
|
|
284
|
-
diagnostics: {
|
|
285
|
-
estimatedTokens: state.estimatedTokens,
|
|
286
|
-
},
|
|
287
|
-
};
|
|
288
|
-
}
|
|
289
|
-
// Token budget warning (don't abort, just warn)
|
|
290
|
-
if (state.estimatedTokens >= config.tokenBudgetWarning) {
|
|
291
|
-
const warning = `Approaching token budget: ~${state.estimatedTokens} tokens`;
|
|
292
|
-
if (!state.warnings.includes(warning)) {
|
|
293
|
-
state.warnings.push(warning);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
// Check 2: Stalling (no changes for too many iterations)
|
|
297
|
-
if (state.iterationsSinceChange >= config.maxStallIterations) {
|
|
298
|
-
return {
|
|
299
|
-
shouldAbort: true,
|
|
300
|
-
reason: 'stalling',
|
|
301
|
-
confidence: 0.9,
|
|
302
|
-
diagnostics: {
|
|
303
|
-
iterationsWithoutChange: state.iterationsSinceChange,
|
|
304
|
-
},
|
|
305
|
-
};
|
|
306
|
-
}
|
|
307
|
-
// Check 3: Oscillation in diffs
|
|
308
|
-
if (state.diffs.length >= 2) {
|
|
309
|
-
const oscillation = detectOscillation(state.diffs, config.similarityThreshold);
|
|
310
|
-
if (oscillation.detected) {
|
|
311
|
-
return {
|
|
312
|
-
shouldAbort: true,
|
|
313
|
-
reason: 'oscillation',
|
|
314
|
-
confidence: oscillation.confidence,
|
|
315
|
-
diagnostics: {
|
|
316
|
-
oscillationPattern: oscillation.pattern,
|
|
317
|
-
},
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
// Check 4: Repetition in outputs
|
|
322
|
-
if (state.outputs.length >= 2) {
|
|
323
|
-
const repetition = detectRepetition(state.outputs.slice(0, -1), latestOutput, config);
|
|
324
|
-
if (repetition.detected) {
|
|
325
|
-
return {
|
|
326
|
-
shouldAbort: true,
|
|
327
|
-
reason: 'repetition',
|
|
328
|
-
confidence: repetition.confidence,
|
|
329
|
-
diagnostics: {
|
|
330
|
-
repeatedPatterns: repetition.patterns,
|
|
331
|
-
similarityScore: repetition.confidence,
|
|
332
|
-
},
|
|
333
|
-
};
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
// Check 5: Verbosity ratio (lots of output, few changes)
|
|
337
|
-
if (state.totalOutputChars > 5000 && state.totalChangeChars > 0) {
|
|
338
|
-
const verbosityRatio = state.totalOutputChars / state.totalChangeChars;
|
|
339
|
-
if (verbosityRatio >= config.verbosityThreshold) {
|
|
340
|
-
// Only warn, don't abort on verbosity alone
|
|
341
|
-
const warning = `High verbosity ratio: ${verbosityRatio.toFixed(1)}x output vs changes`;
|
|
342
|
-
if (!state.warnings.includes(warning)) {
|
|
343
|
-
state.warnings.push(warning);
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
// No issues detected
|
|
348
|
-
return {
|
|
349
|
-
shouldAbort: false,
|
|
350
|
-
confidence: 0,
|
|
351
|
-
diagnostics: {
|
|
352
|
-
estimatedTokens: state.estimatedTokens,
|
|
353
|
-
iterationsWithoutChange: state.iterationsSinceChange,
|
|
354
|
-
},
|
|
355
|
-
};
|
|
356
|
-
}
|
|
357
|
-
/**
|
|
358
|
-
* Format Spindle result for display
|
|
359
|
-
*/
|
|
360
|
-
export function formatSpindleResult(result) {
|
|
361
|
-
if (!result.shouldAbort) {
|
|
362
|
-
return 'No spindle loop detected';
|
|
363
|
-
}
|
|
364
|
-
const parts = [`Spindle loop detected: ${result.reason}`];
|
|
365
|
-
parts.push(`Confidence: ${(result.confidence * 100).toFixed(0)}%`);
|
|
366
|
-
if (result.diagnostics.estimatedTokens) {
|
|
367
|
-
parts.push(`Tokens: ~${result.diagnostics.estimatedTokens}`);
|
|
368
|
-
}
|
|
369
|
-
if (result.diagnostics.iterationsWithoutChange) {
|
|
370
|
-
parts.push(`Iterations without change: ${result.diagnostics.iterationsWithoutChange}`);
|
|
371
|
-
}
|
|
372
|
-
if (result.diagnostics.oscillationPattern) {
|
|
373
|
-
parts.push(`Pattern: ${result.diagnostics.oscillationPattern}`);
|
|
374
|
-
}
|
|
375
|
-
if (result.diagnostics.repeatedPatterns?.length) {
|
|
376
|
-
parts.push(`Repeated: ${result.diagnostics.repeatedPatterns.join(', ')}`);
|
|
377
|
-
}
|
|
378
|
-
return parts.join('\n');
|
|
379
|
-
}
|
|
380
|
-
/** @deprecated Use DEFAULT_SPINDLE_CONFIG */
|
|
381
|
-
export const DEFAULT_RALPH_CONFIG = DEFAULT_SPINDLE_CONFIG;
|
|
382
|
-
/** @deprecated Use createSpindleState */
|
|
383
|
-
export const createRalphState = createSpindleState;
|
|
384
|
-
/** @deprecated Use checkSpindleLoop */
|
|
385
|
-
export const checkRalphLoop = checkSpindleLoop;
|
|
386
|
-
/** @deprecated Use formatSpindleResult */
|
|
387
|
-
export const formatRalphResult = formatSpindleResult;
|
|
388
|
-
//# sourceMappingURL=spindle.js.map
|
package/dist/lib/spindle.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"spindle.js","sourceRoot":"","sources":["../../src/lib/spindle.ts"],"names":[],"mappings":"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"}
|
package/dist/tui/app.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TUI main application
|
|
3
|
-
*
|
|
4
|
-
* Keyboard-first terminal UI for solo mode.
|
|
5
|
-
* Uses blessed for rendering, repos for state, services for actions.
|
|
6
|
-
*/
|
|
7
|
-
import type { DatabaseAdapter } from '@blockspool/core/db';
|
|
8
|
-
import type { TuiActions } from './types.js';
|
|
9
|
-
export type TuiAppDeps = {
|
|
10
|
-
db: DatabaseAdapter;
|
|
11
|
-
repoRoot: string;
|
|
12
|
-
actions?: TuiActions;
|
|
13
|
-
};
|
|
14
|
-
export declare function startTuiApp(deps: TuiAppDeps): Promise<{
|
|
15
|
-
stop: () => Promise<void>;
|
|
16
|
-
}>;
|
|
17
|
-
//# sourceMappingURL=app.d.ts.map
|
package/dist/tui/app.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/tui/app.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAI3D,OAAO,KAAK,EAAa,UAAU,EAAE,MAAM,YAAY,CAAC;AAExD,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,eAAe,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB,CAAC;AA4CF,wBAAsB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CAsG1F"}
|
package/dist/tui/app.js
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TUI main application
|
|
3
|
-
*
|
|
4
|
-
* Keyboard-first terminal UI for solo mode.
|
|
5
|
-
* Uses blessed for rendering, repos for state, services for actions.
|
|
6
|
-
*/
|
|
7
|
-
import blessed from 'neo-blessed';
|
|
8
|
-
import { AdaptivePoller } from './poller.js';
|
|
9
|
-
import { buildSnapshot } from './state.js';
|
|
10
|
-
import { createOverviewScreen } from './screens/overview.js';
|
|
11
|
-
/**
|
|
12
|
-
* Manages screen lifecycle - mount/destroy/update
|
|
13
|
-
*/
|
|
14
|
-
class ScreenManager {
|
|
15
|
-
current = null;
|
|
16
|
-
screen;
|
|
17
|
-
constructor(screen) {
|
|
18
|
-
this.screen = screen;
|
|
19
|
-
}
|
|
20
|
-
set(next) {
|
|
21
|
-
if (this.current) {
|
|
22
|
-
this.current.destroy();
|
|
23
|
-
}
|
|
24
|
-
this.current = next;
|
|
25
|
-
next.mount(this.screen);
|
|
26
|
-
next.focus?.();
|
|
27
|
-
this.screen.render();
|
|
28
|
-
}
|
|
29
|
-
update(snapshot) {
|
|
30
|
-
if (!this.current)
|
|
31
|
-
return;
|
|
32
|
-
this.current.update(snapshot);
|
|
33
|
-
this.screen.render();
|
|
34
|
-
}
|
|
35
|
-
getCurrentName() {
|
|
36
|
-
return this.current?.name ?? null;
|
|
37
|
-
}
|
|
38
|
-
destroy() {
|
|
39
|
-
this.current?.destroy();
|
|
40
|
-
this.current = null;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
function safeString(err) {
|
|
44
|
-
if (err instanceof Error)
|
|
45
|
-
return err.stack || err.message;
|
|
46
|
-
return String(err);
|
|
47
|
-
}
|
|
48
|
-
export async function startTuiApp(deps) {
|
|
49
|
-
const { db, repoRoot, actions } = deps;
|
|
50
|
-
const screen = blessed.screen({
|
|
51
|
-
smartCSR: true,
|
|
52
|
-
fullUnicode: true,
|
|
53
|
-
title: 'BlockSpool',
|
|
54
|
-
});
|
|
55
|
-
// Toast bar at bottom for status messages
|
|
56
|
-
const toast = blessed.box({
|
|
57
|
-
parent: screen,
|
|
58
|
-
bottom: 0,
|
|
59
|
-
height: 1,
|
|
60
|
-
width: '100%',
|
|
61
|
-
tags: true,
|
|
62
|
-
style: { fg: 'white' },
|
|
63
|
-
content: ' {gray-fg}Starting...{/gray-fg}',
|
|
64
|
-
});
|
|
65
|
-
const manager = new ScreenManager(screen);
|
|
66
|
-
const overview = createOverviewScreen({
|
|
67
|
-
onHint: (msg) => {
|
|
68
|
-
toast.setContent(` {gray-fg}${msg}{/gray-fg}`);
|
|
69
|
-
},
|
|
70
|
-
});
|
|
71
|
-
manager.set(overview);
|
|
72
|
-
let actionInFlight = null;
|
|
73
|
-
async function runAction(name, fn) {
|
|
74
|
-
if (!fn) {
|
|
75
|
-
toast.setContent(` {yellow-fg}${name} not configured{/yellow-fg}`);
|
|
76
|
-
screen.render();
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
if (actionInFlight) {
|
|
80
|
-
toast.setContent(` {gray-fg}Action already running...{/gray-fg}`);
|
|
81
|
-
screen.render();
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
toast.setContent(` {cyan-fg}${name}...{/cyan-fg}`);
|
|
85
|
-
screen.render();
|
|
86
|
-
actionInFlight = (async () => {
|
|
87
|
-
try {
|
|
88
|
-
await fn();
|
|
89
|
-
toast.setContent(` {green-fg}${name} complete{/green-fg}`);
|
|
90
|
-
}
|
|
91
|
-
catch (e) {
|
|
92
|
-
toast.setContent(` {red-fg}${name} failed: ${safeString(e).slice(0, 50)}{/red-fg}`);
|
|
93
|
-
}
|
|
94
|
-
finally {
|
|
95
|
-
actionInFlight = null;
|
|
96
|
-
screen.render();
|
|
97
|
-
poller.tickNow();
|
|
98
|
-
}
|
|
99
|
-
})();
|
|
100
|
-
}
|
|
101
|
-
// Global keybindings
|
|
102
|
-
screen.key(['C-c'], async () => {
|
|
103
|
-
await stop();
|
|
104
|
-
});
|
|
105
|
-
screen.key(['s'], () => void runAction('Scout', actions?.runScout));
|
|
106
|
-
screen.key(['q'], () => void runAction('QA', actions?.runQa));
|
|
107
|
-
screen.key(['r'], () => {
|
|
108
|
-
toast.setContent(' {gray-fg}Refreshing...{/gray-fg}');
|
|
109
|
-
screen.render();
|
|
110
|
-
poller.tickNow();
|
|
111
|
-
});
|
|
112
|
-
// Poller wiring
|
|
113
|
-
const poller = new AdaptivePoller({
|
|
114
|
-
fetch: () => buildSnapshot({ db, repoRoot }),
|
|
115
|
-
hash: (snap) => snap.etag,
|
|
116
|
-
isActive: (snap) => snap.runs.activeCount > 0 || snap.runs.runningStep !== null,
|
|
117
|
-
intervals: {
|
|
118
|
-
idleMs: 1000,
|
|
119
|
-
activeMs: 300,
|
|
120
|
-
errorMs: 2000,
|
|
121
|
-
},
|
|
122
|
-
onUpdate: async (snap) => {
|
|
123
|
-
manager.update(snap);
|
|
124
|
-
toast.setContent(` {gray-fg}${snap.hintLine}{/gray-fg}`);
|
|
125
|
-
},
|
|
126
|
-
onError: (err) => {
|
|
127
|
-
toast.setContent(` {red-fg}Poll error: ${safeString(err).slice(0, 50)}{/red-fg}`);
|
|
128
|
-
screen.render();
|
|
129
|
-
},
|
|
130
|
-
});
|
|
131
|
-
poller.start();
|
|
132
|
-
async function stop() {
|
|
133
|
-
poller.stop();
|
|
134
|
-
manager.destroy();
|
|
135
|
-
screen.destroy();
|
|
136
|
-
}
|
|
137
|
-
return { stop };
|
|
138
|
-
}
|
|
139
|
-
//# sourceMappingURL=app.js.map
|
package/dist/tui/app.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/tui/app.ts"],"names":[],"mappings":"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"}
|
package/dist/tui/index.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TUI module exports
|
|
3
|
-
*/
|
|
4
|
-
export { startTuiApp, type TuiAppDeps } from './app.js';
|
|
5
|
-
export { buildSnapshot, type TuiSnapshot, type BuildSnapshotDeps } from './state.js';
|
|
6
|
-
export { AdaptivePoller, type AdaptivePollerOptions, type AdaptivePollerIntervals } from './poller.js';
|
|
7
|
-
export type { TuiScreen, TuiActions } from './types.js';
|
|
8
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/tui/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tui/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,KAAK,WAAW,EAAE,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACrF,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,KAAK,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACvG,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/tui/index.js
DELETED
package/dist/tui/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tui/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAmB,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,aAAa,EAA4C,MAAM,YAAY,CAAC;AACrF,OAAO,EAAE,cAAc,EAA4D,MAAM,aAAa,CAAC"}
|
package/dist/tui/poller.d.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Adaptive poller for TUI
|
|
3
|
-
*
|
|
4
|
-
* Polls faster when there's activity (running steps),
|
|
5
|
-
* slows down when idle. Uses hash-based dedupe to avoid
|
|
6
|
-
* unnecessary re-renders.
|
|
7
|
-
*/
|
|
8
|
-
export type AdaptivePollerIntervals = {
|
|
9
|
-
idleMs: number;
|
|
10
|
-
activeMs: number;
|
|
11
|
-
errorMs: number;
|
|
12
|
-
};
|
|
13
|
-
export type AdaptivePollerOptions<T> = {
|
|
14
|
-
fetch: () => Promise<T>;
|
|
15
|
-
onUpdate: (snapshot: T) => void | Promise<void>;
|
|
16
|
-
onError?: (err: unknown) => void;
|
|
17
|
-
/**
|
|
18
|
-
* Determines whether the app is "active" (e.g. a run is running),
|
|
19
|
-
* which switches polling to activeMs.
|
|
20
|
-
*/
|
|
21
|
-
isActive?: (snapshot: T) => boolean;
|
|
22
|
-
/**
|
|
23
|
-
* Used to avoid re-rendering when nothing changed.
|
|
24
|
-
* If omitted, every tick calls onUpdate.
|
|
25
|
-
*/
|
|
26
|
-
hash?: (snapshot: T) => string;
|
|
27
|
-
intervals: AdaptivePollerIntervals;
|
|
28
|
-
};
|
|
29
|
-
export declare class AdaptivePoller<T> {
|
|
30
|
-
private opts;
|
|
31
|
-
private stopped;
|
|
32
|
-
private timer;
|
|
33
|
-
private lastHash;
|
|
34
|
-
constructor(opts: AdaptivePollerOptions<T>);
|
|
35
|
-
start(): void;
|
|
36
|
-
stop(): void;
|
|
37
|
-
/** Force an immediate poll (e.g., after user action) */
|
|
38
|
-
tickNow(): void;
|
|
39
|
-
private schedule;
|
|
40
|
-
private loop;
|
|
41
|
-
}
|
|
42
|
-
//# sourceMappingURL=poller.d.ts.map
|
package/dist/tui/poller.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"poller.d.ts","sourceRoot":"","sources":["../../src/tui/poller.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,qBAAqB,CAAC,CAAC,IAAI;IACrC,KAAK,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;IACxB,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IAEjC;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,OAAO,CAAC;IAEpC;;;OAGG;IACH,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,MAAM,CAAC;IAE/B,SAAS,EAAE,uBAAuB,CAAC;CACpC,CAAC;AAEF,qBAAa,cAAc,CAAC,CAAC;IAC3B,OAAO,CAAC,IAAI,CAA2B;IACvC,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,KAAK,CAA8C;IAC3D,OAAO,CAAC,QAAQ,CAAuB;gBAE3B,IAAI,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAI1C,KAAK;IAML,IAAI;IAMJ,wDAAwD;IACxD,OAAO;IAOP,OAAO,CAAC,QAAQ;YAKF,IAAI;CAqBnB"}
|