agileflow 2.99.8 → 3.0.0
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 +5 -0
- package/lib/cache-provider.js +155 -0
- package/lib/codebase-indexer.js +1 -1
- package/lib/content-sanitizer.js +1 -0
- package/lib/dashboard-protocol.js +25 -0
- package/lib/dashboard-server.js +184 -133
- package/lib/errors.js +18 -0
- package/lib/file-cache.js +1 -1
- package/lib/flag-detection.js +11 -20
- package/lib/git-operations.js +15 -33
- package/lib/merge-operations.js +40 -34
- package/lib/process-executor.js +199 -0
- package/lib/registry-cache.js +13 -47
- package/lib/skill-loader.js +206 -0
- package/lib/smart-json-file.js +2 -4
- package/package.json +1 -1
- package/scripts/agileflow-configure.js +13 -12
- package/scripts/agileflow-statusline.sh +30 -0
- package/scripts/agileflow-welcome.js +181 -212
- package/scripts/auto-self-improve.js +3 -3
- package/scripts/claude-smart.sh +67 -0
- package/scripts/claude-tmux.sh +248 -161
- package/scripts/damage-control-multi-agent.js +227 -0
- package/scripts/lib/bus-utils.js +471 -0
- package/scripts/lib/configure-detect.js +5 -6
- package/scripts/lib/configure-features.js +44 -0
- package/scripts/lib/configure-repair.js +5 -6
- package/scripts/lib/configure-utils.js +2 -3
- package/scripts/lib/context-formatter.js +87 -8
- package/scripts/lib/damage-control-utils.js +37 -3
- package/scripts/lib/file-lock.js +392 -0
- package/scripts/lib/ideation-index.js +2 -5
- package/scripts/lib/lifecycle-detector.js +123 -0
- package/scripts/lib/process-cleanup.js +55 -81
- package/scripts/lib/scale-detector.js +357 -0
- package/scripts/lib/signal-detectors.js +779 -0
- package/scripts/lib/story-state-machine.js +1 -1
- package/scripts/lib/sync-ideation-status.js +2 -3
- package/scripts/lib/task-registry.js +7 -1
- package/scripts/lib/team-events.js +357 -0
- package/scripts/messaging-bridge.js +79 -36
- package/scripts/migrate-ideation-index.js +37 -14
- package/scripts/obtain-context.js +37 -19
- package/scripts/ralph-loop.js +3 -4
- package/scripts/smart-detect.js +390 -0
- package/scripts/team-manager.js +174 -30
- package/src/core/commands/audit.md +13 -11
- package/src/core/commands/babysit.md +162 -115
- package/src/core/commands/changelog.md +21 -4
- package/src/core/commands/configure.md +105 -2
- package/src/core/commands/debt.md +12 -2
- package/src/core/commands/feedback.md +7 -6
- package/src/core/commands/ideate/history.md +1 -1
- package/src/core/commands/ideate/new.md +5 -5
- package/src/core/commands/logic/audit.md +2 -2
- package/src/core/commands/pr.md +7 -6
- package/src/core/commands/research/analyze.md +28 -20
- package/src/core/commands/research/ask.md +43 -0
- package/src/core/commands/research/import.md +29 -21
- package/src/core/commands/research/list.md +8 -7
- package/src/core/commands/research/synthesize.md +356 -20
- package/src/core/commands/research/view.md +8 -5
- package/src/core/commands/review.md +24 -6
- package/src/core/commands/skill/create.md +34 -0
- package/tools/cli/lib/docs-setup.js +4 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [3.0.0] - 2026-02-13
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Scale-adaptive architecture, smart tmux sessions, and team observability
|
|
14
|
+
|
|
10
15
|
## [2.99.8] - 2026-02-12
|
|
11
16
|
|
|
12
17
|
### Fixed
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const { LRUCache } = require('./file-cache');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Cache Provider - Unified caching interface for AgileFlow
|
|
8
|
+
*
|
|
9
|
+
* Re-exports LRUCache from file-cache (canonical source) and adds
|
|
10
|
+
* MtimeCache for file-system-aware caching with mtime invalidation.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const CACHE_DEFAULTS = {
|
|
14
|
+
file: { maxSize: 50, ttlMs: 15000 },
|
|
15
|
+
command: { maxSize: 50, ttlMs: 30000 },
|
|
16
|
+
registry: { maxSize: 50, ttlMs: 60000 },
|
|
17
|
+
index: { maxSize: 10, ttlMs: 60000 },
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* LRU Cache with filesystem mtime-based invalidation.
|
|
22
|
+
* On set(), captures the file's mtime. On get(), validates that
|
|
23
|
+
* the file hasn't been modified since caching.
|
|
24
|
+
*/
|
|
25
|
+
class MtimeCache {
|
|
26
|
+
constructor({ maxSize = 100, ttlMs = 60000 } = {}) {
|
|
27
|
+
this._lru = new LRUCache({ maxSize, ttlMs });
|
|
28
|
+
this._stats = { hits: 0, misses: 0 };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Get cached value, validating both TTL and file mtime.
|
|
33
|
+
* @param {string} key - File/directory path used as cache key
|
|
34
|
+
* @returns {*} Cached value or undefined
|
|
35
|
+
*/
|
|
36
|
+
get(key) {
|
|
37
|
+
const entry = this._lru.get(key);
|
|
38
|
+
if (entry === undefined) {
|
|
39
|
+
this._stats.misses++;
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Validate mtime hasn't changed
|
|
44
|
+
try {
|
|
45
|
+
const currentMtime = fs.statSync(key).mtimeMs;
|
|
46
|
+
if (currentMtime !== entry.mtimeMs) {
|
|
47
|
+
this._lru.delete(key);
|
|
48
|
+
this._stats.misses++;
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
} catch {
|
|
52
|
+
// File deleted or inaccessible — invalidate
|
|
53
|
+
this._lru.delete(key);
|
|
54
|
+
this._stats.misses++;
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
this._stats.hits++;
|
|
59
|
+
return entry.value;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Store value with current file mtime snapshot.
|
|
64
|
+
* @param {string} key - File/directory path used as cache key
|
|
65
|
+
* @param {*} value - Value to cache
|
|
66
|
+
*/
|
|
67
|
+
set(key, value) {
|
|
68
|
+
try {
|
|
69
|
+
const mtimeMs = fs.statSync(key).mtimeMs;
|
|
70
|
+
this._lru.set(key, { value, mtimeMs });
|
|
71
|
+
} catch {
|
|
72
|
+
// Can't stat — don't cache
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Check if key exists (without promoting in LRU or updating stats).
|
|
78
|
+
* @param {string} key
|
|
79
|
+
* @returns {boolean}
|
|
80
|
+
*/
|
|
81
|
+
has(key) {
|
|
82
|
+
return this._lru.has(key);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Remove a cached entry.
|
|
87
|
+
* @param {string} key
|
|
88
|
+
* @returns {boolean}
|
|
89
|
+
*/
|
|
90
|
+
invalidate(key) {
|
|
91
|
+
return this._lru.delete(key);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Clear all entries.
|
|
96
|
+
*/
|
|
97
|
+
clear() {
|
|
98
|
+
this._lru.clear();
|
|
99
|
+
this._stats = { hits: 0, misses: 0 };
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Get cache statistics.
|
|
104
|
+
* @returns {{ hits: number, misses: number, size: number, hitRate: string }}
|
|
105
|
+
*/
|
|
106
|
+
getStats() {
|
|
107
|
+
const total = this._stats.hits + this._stats.misses;
|
|
108
|
+
return {
|
|
109
|
+
hits: this._stats.hits,
|
|
110
|
+
misses: this._stats.misses,
|
|
111
|
+
size: this._lru.size,
|
|
112
|
+
hitRate: total > 0 ? ((this._stats.hits / total) * 100).toFixed(1) + '%' : '0%',
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
get size() {
|
|
117
|
+
return this._lru.size;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Create a pre-configured LRUCache.
|
|
123
|
+
* @param {Object} [opts]
|
|
124
|
+
* @param {number} [opts.maxSize=100]
|
|
125
|
+
* @param {number} [opts.ttlMs=30000]
|
|
126
|
+
* @returns {LRUCache}
|
|
127
|
+
*/
|
|
128
|
+
function createCache(opts = {}) {
|
|
129
|
+
return new LRUCache({
|
|
130
|
+
maxSize: opts.maxSize || 100,
|
|
131
|
+
ttlMs: opts.ttlMs || 30000,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Create a pre-configured MtimeCache.
|
|
137
|
+
* @param {Object} [opts]
|
|
138
|
+
* @param {number} [opts.maxSize=100]
|
|
139
|
+
* @param {number} [opts.ttlMs=60000]
|
|
140
|
+
* @returns {MtimeCache}
|
|
141
|
+
*/
|
|
142
|
+
function createMtimeCache(opts = {}) {
|
|
143
|
+
return new MtimeCache({
|
|
144
|
+
maxSize: opts.maxSize || 100,
|
|
145
|
+
ttlMs: opts.ttlMs || 60000,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
module.exports = {
|
|
150
|
+
LRUCache,
|
|
151
|
+
MtimeCache,
|
|
152
|
+
createCache,
|
|
153
|
+
createMtimeCache,
|
|
154
|
+
CACHE_DEFAULTS,
|
|
155
|
+
};
|
package/lib/codebase-indexer.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
const fs = require('fs');
|
|
16
16
|
const path = require('path');
|
|
17
|
-
const { LRUCache } = require('./
|
|
17
|
+
const { LRUCache } = require('./cache-provider');
|
|
18
18
|
const { safeReadJSON, safeWriteJSON, debugLog } = require('./errors');
|
|
19
19
|
|
|
20
20
|
// Debug mode via env var
|
package/lib/content-sanitizer.js
CHANGED
|
@@ -159,6 +159,7 @@ function removeControlChars(text) {
|
|
|
159
159
|
function truncate(text, maxLength) {
|
|
160
160
|
if (!text || typeof text !== 'string') return '';
|
|
161
161
|
if (text.length <= maxLength) return text;
|
|
162
|
+
if (maxLength < 4) return text.substring(0, maxLength);
|
|
162
163
|
return text.substring(0, maxLength - 3) + '...';
|
|
163
164
|
}
|
|
164
165
|
|
|
@@ -81,6 +81,9 @@ const OutboundMessageType = {
|
|
|
81
81
|
// Sessions
|
|
82
82
|
SESSION_LIST: 'session_list', // Session list with sync status
|
|
83
83
|
|
|
84
|
+
// Team Metrics
|
|
85
|
+
TEAM_METRICS: 'team_metrics', // Team metrics update (per-agent, per-gate)
|
|
86
|
+
|
|
84
87
|
// Errors
|
|
85
88
|
ERROR: 'error', // General error
|
|
86
89
|
};
|
|
@@ -471,6 +474,27 @@ function createSessionList(sessions) {
|
|
|
471
474
|
};
|
|
472
475
|
}
|
|
473
476
|
|
|
477
|
+
/**
|
|
478
|
+
* Create a team metrics message
|
|
479
|
+
* @param {string} traceId - Trace ID for the team run
|
|
480
|
+
* @param {Object} metrics - Aggregated metrics
|
|
481
|
+
* @param {Object} metrics.per_agent - Per-agent metrics
|
|
482
|
+
* @param {Object} metrics.per_gate - Per-gate metrics
|
|
483
|
+
* @param {number|null} metrics.team_completion_ms - Team completion time in ms
|
|
484
|
+
* @param {string} metrics.computed_at - When metrics were computed
|
|
485
|
+
*/
|
|
486
|
+
function createTeamMetrics(traceId, metrics) {
|
|
487
|
+
return {
|
|
488
|
+
type: OutboundMessageType.TEAM_METRICS,
|
|
489
|
+
trace_id: traceId,
|
|
490
|
+
per_agent: (metrics && metrics.per_agent) || {},
|
|
491
|
+
per_gate: (metrics && metrics.per_gate) || {},
|
|
492
|
+
team_completion_ms: metrics && metrics.team_completion_ms,
|
|
493
|
+
computed_at: metrics && metrics.computed_at,
|
|
494
|
+
timestamp: new Date().toISOString(),
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
|
|
474
498
|
/**
|
|
475
499
|
* Create an AskUserQuestion message
|
|
476
500
|
* @param {string} toolId - Tool call ID for response correlation
|
|
@@ -571,6 +595,7 @@ module.exports = {
|
|
|
571
595
|
createAskUserQuestion,
|
|
572
596
|
createStatusUpdate,
|
|
573
597
|
createSessionList,
|
|
598
|
+
createTeamMetrics,
|
|
574
599
|
|
|
575
600
|
// Parsing
|
|
576
601
|
parseInboundMessage,
|