ac-framework 2.1.0 → 2.2.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/package.json +1 -1
- package/src/agents/runtime.js +31 -26
- package/src/commands/agents.js +9 -1
package/package.json
CHANGED
package/src/agents/runtime.js
CHANGED
|
@@ -47,6 +47,10 @@ function sleep(ms) {
|
|
|
47
47
|
return new Promise((resolvePromise) => setTimeout(resolvePromise, ms));
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
function stripAnsi(text) {
|
|
51
|
+
return String(text || '').replace(/\x1B\[[0-9;]*m/g, '');
|
|
52
|
+
}
|
|
53
|
+
|
|
50
54
|
function workerCommand(sessionId, role, roleLog) {
|
|
51
55
|
return `bash -lc 'node "${runnerPath}" agents worker --session ${sessionId} --role ${role} 2>&1 | tee -a "${roleLog}"'`;
|
|
52
56
|
}
|
|
@@ -95,26 +99,26 @@ export async function tmuxSessionExists(sessionName) {
|
|
|
95
99
|
}
|
|
96
100
|
|
|
97
101
|
async function writeZellijLayout({ layoutPath, sessionId, sessionDir }) {
|
|
98
|
-
const
|
|
102
|
+
const paneNode = (role) => {
|
|
99
103
|
const roleLog = roleLogPath(sessionDir, role);
|
|
100
104
|
const cmd = workerCommand(sessionId, role, roleLog).replace(/"/g, '\\"');
|
|
101
|
-
return
|
|
102
|
-
|
|
105
|
+
return [
|
|
106
|
+
` pane name="${role}" command="bash" {`,
|
|
107
|
+
` args "-lc" "${cmd}"`,
|
|
108
|
+
' }',
|
|
109
|
+
].join('\n');
|
|
110
|
+
};
|
|
103
111
|
|
|
104
112
|
const content = [
|
|
105
113
|
'layout {',
|
|
106
|
-
'
|
|
107
|
-
'
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
panes[2],
|
|
115
|
-
panes[3],
|
|
116
|
-
' }',
|
|
117
|
-
' }',
|
|
114
|
+
' pane split_direction="vertical" {',
|
|
115
|
+
' pane split_direction="horizontal" {',
|
|
116
|
+
paneNode(COLLAB_ROLES[0]),
|
|
117
|
+
paneNode(COLLAB_ROLES[1]),
|
|
118
|
+
' }',
|
|
119
|
+
' pane split_direction="horizontal" {',
|
|
120
|
+
paneNode(COLLAB_ROLES[2]),
|
|
121
|
+
paneNode(COLLAB_ROLES[3]),
|
|
118
122
|
' }',
|
|
119
123
|
' }',
|
|
120
124
|
'}',
|
|
@@ -132,27 +136,25 @@ export async function spawnZellijSession({
|
|
|
132
136
|
waitForSessionMs = 10000,
|
|
133
137
|
pollIntervalMs = 250,
|
|
134
138
|
runCommandImpl,
|
|
135
|
-
spawnImpl,
|
|
136
139
|
}) {
|
|
137
140
|
const layoutPath = resolve(sessionDir, 'synapsegrid-layout.kdl');
|
|
138
141
|
await writeZellijLayout({ layoutPath, sessionId, sessionDir });
|
|
139
142
|
const command = binaryPath || process.env.ACFM_ZELLIJ_BIN || 'zellij';
|
|
143
|
+
const runner = runCommandImpl || runCommand;
|
|
140
144
|
|
|
141
|
-
const
|
|
142
|
-
|
|
145
|
+
const existing = await zellijSessionExists(sessionName, binaryPath, { runCommandImpl: runner });
|
|
146
|
+
if (existing) {
|
|
147
|
+
return { layoutPath };
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
await runner(command, ['--layout', layoutPath, 'attach', '--create-background', sessionName], {
|
|
143
151
|
cwd: sessionDir,
|
|
144
|
-
env: process.env,
|
|
145
|
-
detached: true,
|
|
146
|
-
stdio: 'ignore',
|
|
147
152
|
});
|
|
148
|
-
if (typeof child.unref === 'function') {
|
|
149
|
-
child.unref();
|
|
150
|
-
}
|
|
151
153
|
|
|
152
154
|
const startedAt = Date.now();
|
|
153
155
|
while ((Date.now() - startedAt) < waitForSessionMs) {
|
|
154
156
|
// eslint-disable-next-line no-await-in-loop
|
|
155
|
-
const exists = await zellijSessionExists(sessionName, binaryPath, { runCommandImpl });
|
|
157
|
+
const exists = await zellijSessionExists(sessionName, binaryPath, { runCommandImpl: runner });
|
|
156
158
|
if (exists) {
|
|
157
159
|
return { layoutPath };
|
|
158
160
|
}
|
|
@@ -171,7 +173,10 @@ export async function zellijSessionExists(sessionName, binaryPath, options = {})
|
|
|
171
173
|
const runner = options.runCommandImpl || runCommand;
|
|
172
174
|
const command = binaryPath || process.env.ACFM_ZELLIJ_BIN || 'zellij';
|
|
173
175
|
const result = await runner(command, ['list-sessions']);
|
|
174
|
-
const lines = result.stdout
|
|
176
|
+
const lines = stripAnsi(result.stdout)
|
|
177
|
+
.split('\n')
|
|
178
|
+
.map((line) => line.trim())
|
|
179
|
+
.filter(Boolean);
|
|
175
180
|
return lines.some((line) => line === sessionName || line.startsWith(`${sessionName} `));
|
|
176
181
|
} catch {
|
|
177
182
|
return false;
|
package/src/commands/agents.js
CHANGED
|
@@ -1503,7 +1503,15 @@ Examples:
|
|
|
1503
1503
|
try {
|
|
1504
1504
|
await runZellij(['delete-session', muxSessionName], { binaryPath: zellijPath });
|
|
1505
1505
|
} catch {
|
|
1506
|
-
|
|
1506
|
+
try {
|
|
1507
|
+
await runZellij(['kill-session', muxSessionName], { binaryPath: zellijPath });
|
|
1508
|
+
} catch {
|
|
1509
|
+
try {
|
|
1510
|
+
await runZellij(['delete-session', '--force', muxSessionName], { binaryPath: zellijPath });
|
|
1511
|
+
} catch {
|
|
1512
|
+
// ignore if already closed
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1507
1515
|
}
|
|
1508
1516
|
}
|
|
1509
1517
|
if (multiplexer === 'tmux' && muxSessionName && hasCommand('tmux')) {
|