agileflow 2.95.2 → 2.96.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 +10 -0
- package/README.md +6 -6
- package/lib/api-routes.js +605 -0
- package/lib/api-server.js +260 -0
- package/lib/claude-cli-bridge.js +221 -0
- package/lib/dashboard-protocol.js +541 -0
- package/lib/dashboard-server.js +1601 -0
- package/lib/drivers/claude-driver.ts +310 -0
- package/lib/drivers/codex-driver.ts +454 -0
- package/lib/drivers/driver-manager.ts +158 -0
- package/lib/drivers/gemini-driver.ts +485 -0
- package/lib/drivers/index.ts +17 -0
- package/lib/flag-detection.js +350 -0
- package/lib/git-operations.js +267 -0
- package/lib/lock-file.js +144 -0
- package/lib/merge-operations.js +959 -0
- package/lib/protocol/driver.ts +360 -0
- package/lib/protocol/index.ts +12 -0
- package/lib/protocol/ir.ts +271 -0
- package/lib/session-display.js +330 -0
- package/lib/worktree-operations.js +221 -0
- package/package.json +2 -2
- package/scripts/agileflow-welcome.js +272 -24
- package/scripts/api-server-runner.js +177 -0
- package/scripts/archive-completed-stories.sh +22 -0
- package/scripts/automation-run-due.js +126 -0
- package/scripts/backfill-ideation-status.js +124 -0
- package/scripts/claude-tmux.sh +62 -1
- package/scripts/context-loader.js +292 -0
- package/scripts/dashboard-serve.js +323 -0
- package/scripts/lib/automation-registry.js +544 -0
- package/scripts/lib/automation-runner.js +476 -0
- package/scripts/lib/concurrency-limiter.js +513 -0
- package/scripts/lib/configure-features.js +46 -0
- package/scripts/lib/context-formatter.js +61 -0
- package/scripts/lib/damage-control-utils.js +29 -4
- package/scripts/lib/hook-metrics.js +324 -0
- package/scripts/lib/ideation-index.js +1196 -0
- package/scripts/lib/process-cleanup.js +359 -0
- package/scripts/lib/quality-gates.js +574 -0
- package/scripts/lib/status-task-bridge.js +522 -0
- package/scripts/lib/sync-ideation-status.js +292 -0
- package/scripts/lib/task-registry-cache.js +490 -0
- package/scripts/lib/task-registry.js +1181 -0
- package/scripts/migrate-ideation-index.js +515 -0
- package/scripts/precompact-context.sh +104 -0
- package/scripts/ralph-loop.js +2 -2
- package/scripts/session-manager.js +363 -2770
- package/scripts/spawn-parallel.js +45 -9
- package/src/core/agents/api-validator.md +180 -0
- package/src/core/agents/api.md +2 -0
- package/src/core/agents/code-reviewer.md +289 -0
- package/src/core/agents/configuration/damage-control.md +17 -0
- package/src/core/agents/database.md +2 -0
- package/src/core/agents/error-analyzer.md +203 -0
- package/src/core/agents/logic-analyzer-edge.md +171 -0
- package/src/core/agents/logic-analyzer-flow.md +254 -0
- package/src/core/agents/logic-analyzer-invariant.md +207 -0
- package/src/core/agents/logic-analyzer-race.md +267 -0
- package/src/core/agents/logic-analyzer-type.md +218 -0
- package/src/core/agents/logic-consensus.md +256 -0
- package/src/core/agents/orchestrator.md +89 -1
- package/src/core/agents/schema-validator.md +451 -0
- package/src/core/agents/team-coordinator.md +328 -0
- package/src/core/agents/ui-validator.md +328 -0
- package/src/core/agents/ui.md +2 -0
- package/src/core/commands/api.md +267 -0
- package/src/core/commands/automate.md +415 -0
- package/src/core/commands/babysit.md +290 -9
- package/src/core/commands/ideate/history.md +403 -0
- package/src/core/commands/{ideate.md → ideate/new.md} +244 -34
- package/src/core/commands/logic/audit.md +368 -0
- package/src/core/commands/roadmap/analyze.md +1 -1
- package/src/core/experts/documentation/expertise.yaml +29 -2
- package/src/core/templates/CONTEXT.md.example +49 -0
- package/src/core/templates/claude-settings.advanced.example.json +4 -0
- package/tools/cli/commands/serve.js +456 -0
- package/tools/cli/installers/core/installer.js +7 -2
- package/tools/cli/installers/ide/claude-code.js +85 -0
- package/tools/cli/lib/content-injector.js +27 -1
- package/tools/cli/lib/ui.js +26 -57
package/lib/lock-file.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lock-file.js - Lock file operations for session management
|
|
3
|
+
*
|
|
4
|
+
* Manages session lock files for PID-based liveness detection.
|
|
5
|
+
* Lock files use a simple key-value format: pid=12345\nstarted=1706825600
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Parse lock file content into an object
|
|
13
|
+
* @param {string} content - Raw lock file content
|
|
14
|
+
* @returns {Object} Parsed key-value pairs
|
|
15
|
+
*/
|
|
16
|
+
function parseLockContent(content) {
|
|
17
|
+
const lock = {};
|
|
18
|
+
content.split('\n').forEach(line => {
|
|
19
|
+
const [key, value] = line.split('=');
|
|
20
|
+
if (key && value) {
|
|
21
|
+
lock[key.trim()] = value.trim();
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
return lock;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Get lock file path for a session
|
|
29
|
+
* @param {string} sessionsDir - Sessions directory path
|
|
30
|
+
* @param {string} sessionId - Session identifier
|
|
31
|
+
* @returns {string} Full path to lock file
|
|
32
|
+
*/
|
|
33
|
+
function getLockPath(sessionsDir, sessionId) {
|
|
34
|
+
return path.join(sessionsDir, `${sessionId}.lock`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Read lock file synchronously
|
|
39
|
+
* @param {string} sessionsDir - Sessions directory path
|
|
40
|
+
* @param {string} sessionId - Session identifier
|
|
41
|
+
* @returns {Object|null} Parsed lock data or null if not found
|
|
42
|
+
*/
|
|
43
|
+
function readLock(sessionsDir, sessionId) {
|
|
44
|
+
const lockPath = getLockPath(sessionsDir, sessionId);
|
|
45
|
+
if (!fs.existsSync(lockPath)) return null;
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
const content = fs.readFileSync(lockPath, 'utf8');
|
|
49
|
+
return parseLockContent(content);
|
|
50
|
+
} catch (e) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Read lock file asynchronously
|
|
57
|
+
* @param {string} sessionsDir - Sessions directory path
|
|
58
|
+
* @param {string} sessionId - Session identifier
|
|
59
|
+
* @returns {Promise<Object|null>} Parsed lock data or null if not found
|
|
60
|
+
*/
|
|
61
|
+
async function readLockAsync(sessionsDir, sessionId) {
|
|
62
|
+
const lockPath = getLockPath(sessionsDir, sessionId);
|
|
63
|
+
try {
|
|
64
|
+
const content = await fs.promises.readFile(lockPath, 'utf8');
|
|
65
|
+
return parseLockContent(content);
|
|
66
|
+
} catch (e) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Write lock file for a session
|
|
73
|
+
* @param {string} sessionsDir - Sessions directory path
|
|
74
|
+
* @param {string} sessionId - Session identifier
|
|
75
|
+
* @param {number} pid - Process ID to record
|
|
76
|
+
*/
|
|
77
|
+
function writeLock(sessionsDir, sessionId, pid) {
|
|
78
|
+
const lockPath = getLockPath(sessionsDir, sessionId);
|
|
79
|
+
const content = `pid=${pid}\nstarted=${Math.floor(Date.now() / 1000)}\n`;
|
|
80
|
+
fs.writeFileSync(lockPath, content);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Remove lock file for a session
|
|
85
|
+
* @param {string} sessionsDir - Sessions directory path
|
|
86
|
+
* @param {string} sessionId - Session identifier
|
|
87
|
+
*/
|
|
88
|
+
function removeLock(sessionsDir, sessionId) {
|
|
89
|
+
const lockPath = getLockPath(sessionsDir, sessionId);
|
|
90
|
+
if (fs.existsSync(lockPath)) {
|
|
91
|
+
fs.unlinkSync(lockPath);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Check if a PID is alive
|
|
97
|
+
* @param {number} pid - Process ID to check
|
|
98
|
+
* @returns {boolean} True if process is alive
|
|
99
|
+
*/
|
|
100
|
+
function isPidAlive(pid) {
|
|
101
|
+
if (!pid) return false;
|
|
102
|
+
try {
|
|
103
|
+
process.kill(pid, 0);
|
|
104
|
+
return true;
|
|
105
|
+
} catch (e) {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Check if session is active (has lock with alive PID)
|
|
112
|
+
* @param {string} sessionsDir - Sessions directory path
|
|
113
|
+
* @param {string} sessionId - Session identifier
|
|
114
|
+
* @returns {boolean} True if session is active
|
|
115
|
+
*/
|
|
116
|
+
function isSessionActive(sessionsDir, sessionId) {
|
|
117
|
+
const lock = readLock(sessionsDir, sessionId);
|
|
118
|
+
if (!lock || !lock.pid) return false;
|
|
119
|
+
return isPidAlive(parseInt(lock.pid, 10));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Check if session is active asynchronously
|
|
124
|
+
* @param {string} sessionsDir - Sessions directory path
|
|
125
|
+
* @param {string} sessionId - Session identifier
|
|
126
|
+
* @returns {Promise<boolean>} True if session is active
|
|
127
|
+
*/
|
|
128
|
+
async function isSessionActiveAsync(sessionsDir, sessionId) {
|
|
129
|
+
const lock = await readLockAsync(sessionsDir, sessionId);
|
|
130
|
+
if (!lock || !lock.pid) return false;
|
|
131
|
+
return isPidAlive(parseInt(lock.pid, 10));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
module.exports = {
|
|
135
|
+
parseLockContent,
|
|
136
|
+
getLockPath,
|
|
137
|
+
readLock,
|
|
138
|
+
readLockAsync,
|
|
139
|
+
writeLock,
|
|
140
|
+
removeLock,
|
|
141
|
+
isPidAlive,
|
|
142
|
+
isSessionActive,
|
|
143
|
+
isSessionActiveAsync,
|
|
144
|
+
};
|