@m0xoo/openboard 1.0.8 → 1.0.10
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
CHANGED
|
@@ -176,9 +176,11 @@ export async function setupOpencodeEventListener(events, opencodeClient, session
|
|
|
176
176
|
// Handle Session Idle (Task Completed)
|
|
177
177
|
if (event.type === 'session.idle') {
|
|
178
178
|
console.log(`[opencode-agent] Agent task completed (idle) for ticket ${ticket.id}.`);
|
|
179
|
-
// Check if the session failed with a fatal error previously
|
|
179
|
+
// Check if the current session failed with a fatal error previously
|
|
180
180
|
const currentTicket = ticketRepository.findById(ticket.id);
|
|
181
|
-
const
|
|
181
|
+
const sessionsForColumn = currentTicket?.agent_sessions?.filter((s) => s.column_id === ticket.column_id) || [];
|
|
182
|
+
const latestSession = sessionsForColumn[sessionsForColumn.length - 1];
|
|
183
|
+
const hasError = latestSession?.status === 'blocked';
|
|
182
184
|
if (!hasError) {
|
|
183
185
|
// Mark the ticket as done now that the agent session finished processing
|
|
184
186
|
ticketRepository.updateAgentSession(ticket.id, {
|
|
@@ -361,6 +363,9 @@ export async function setupOpencodeEventListener(events, opencodeClient, session
|
|
|
361
363
|
}
|
|
362
364
|
} // End of agentType === 'opencode' block
|
|
363
365
|
}
|
|
366
|
+
// Wait! Since this ticket finished processing, we should re-evaluate the CURRENT column
|
|
367
|
+
// so the next pending ticket can be picked up by an agent.
|
|
368
|
+
agentQueue.evaluateColumnQueue(ticket.column_id);
|
|
364
369
|
// Clean up the server instance tracking after a brief delay
|
|
365
370
|
setTimeout(() => {
|
|
366
371
|
console.log(`[opencode-agent] Cleaning up tracking for ${ticket.id}`);
|
|
@@ -3,8 +3,19 @@ import path from 'path';
|
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
4
|
import { createRequire } from 'module';
|
|
5
5
|
import fs from 'fs';
|
|
6
|
+
import os from 'os';
|
|
6
7
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
-
const
|
|
8
|
+
const openboardDir = path.join(os.homedir(), '.openboard');
|
|
9
|
+
if (!fs.existsSync(openboardDir)) {
|
|
10
|
+
fs.mkdirSync(openboardDir, { recursive: true });
|
|
11
|
+
}
|
|
12
|
+
const DB_PATH = path.join(openboardDir, 'openboard.db');
|
|
13
|
+
console.log("[db] DB_PATH", DB_PATH);
|
|
14
|
+
// Migrate old database if it exists
|
|
15
|
+
const oldDbPath = path.join(__dirname, '..', '..', '..', 'openboard.db');
|
|
16
|
+
if (fs.existsSync(oldDbPath) && !fs.existsSync(DB_PATH)) {
|
|
17
|
+
fs.copyFileSync(oldDbPath, DB_PATH);
|
|
18
|
+
}
|
|
8
19
|
// Resolve sql.js WASM dynamically — handles npm workspace node_modules hoisting
|
|
9
20
|
const require = createRequire(import.meta.url);
|
|
10
21
|
const sqlJsDir = path.dirname(require.resolve('sql.js/dist/sql-wasm.wasm'));
|
|
@@ -56,8 +56,21 @@ async function start() {
|
|
|
56
56
|
app.get('*', (req, res) => {
|
|
57
57
|
res.sendFile(path.join(clientExtPath, 'index.html'));
|
|
58
58
|
});
|
|
59
|
-
app.listen(PORT
|
|
60
|
-
|
|
59
|
+
const server = app.listen(PORT);
|
|
60
|
+
server.on('listening', () => {
|
|
61
|
+
const address = server.address();
|
|
62
|
+
const actualPort = typeof address === 'string' ? address : address?.port;
|
|
63
|
+
console.log(`[openboard] Server running at http://localhost:${actualPort}`);
|
|
64
|
+
});
|
|
65
|
+
server.on('error', (err) => {
|
|
66
|
+
if (err.code === 'EADDRINUSE') {
|
|
67
|
+
console.log(`[openboard] Port ${PORT} is in use, trying a random available port...`);
|
|
68
|
+
server.close();
|
|
69
|
+
server.listen(0);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
console.error('[openboard] Server error:', err);
|
|
73
|
+
}
|
|
61
74
|
});
|
|
62
75
|
}
|
|
63
76
|
start().catch(err => {
|
|
@@ -19,7 +19,7 @@ router.get('/:id/config', (req, res) => {
|
|
|
19
19
|
});
|
|
20
20
|
// PUT /api/boards/:boardId/columns/:id/config
|
|
21
21
|
router.put('/:id/config', (req, res) => {
|
|
22
|
-
const { agentType, onFinishColumnId, onRejectColumnId } = req.body;
|
|
22
|
+
const { agentType, agentModel, maxAgents, onFinishColumnId, onRejectColumnId } = req.body;
|
|
23
23
|
if (!agentType) {
|
|
24
24
|
res.status(400).json({ error: 'agentType is required' });
|
|
25
25
|
return;
|
|
@@ -27,6 +27,8 @@ router.put('/:id/config', (req, res) => {
|
|
|
27
27
|
const config = columnConfigRepository.upsert({
|
|
28
28
|
columnId: req.params.id,
|
|
29
29
|
agentType,
|
|
30
|
+
agentModel,
|
|
31
|
+
maxAgents,
|
|
30
32
|
onFinishColumnId,
|
|
31
33
|
onRejectColumnId,
|
|
32
34
|
});
|