agor-live 0.6.2 → 0.6.4
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/dist/core/config/index.cjs +0 -5
- package/dist/core/config/index.d.cts +7 -3
- package/dist/core/config/index.d.ts +7 -3
- package/dist/core/config/index.js +0 -5
- package/dist/core/db/index.cjs +132 -84
- package/dist/core/db/index.d.cts +6 -3
- package/dist/core/db/index.d.ts +6 -3
- package/dist/core/db/index.js +132 -84
- package/dist/core/index.cjs +132 -89
- package/dist/core/index.d.cts +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js +132 -89
- package/dist/core/tools/index.cjs +0 -5
- package/dist/core/tools/index.d.cts +1 -1
- package/dist/core/tools/index.d.ts +1 -1
- package/dist/core/tools/index.js +0 -5
- package/dist/core/{worktrees-Df_shHCZ.d.cts → worktrees-BEIruvGs.d.cts} +13 -3
- package/dist/core/{worktrees-DCLpNeje.d.ts → worktrees-Dv8M5-3U.d.ts} +13 -3
- package/package.json +1 -1
|
@@ -230,11 +230,6 @@ async function getDaemonUrl() {
|
|
|
230
230
|
const envPort = process.env.PORT ? Number.parseInt(process.env.PORT, 10) : void 0;
|
|
231
231
|
const port = envPort || config.daemon?.port || defaults.daemon?.port || 3030;
|
|
232
232
|
const host = config.daemon?.host || defaults.daemon?.host || "localhost";
|
|
233
|
-
const codespaceName = process.env.CODESPACE_NAME;
|
|
234
|
-
const codespacesDomain = process.env.GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN;
|
|
235
|
-
if (codespaceName && codespacesDomain) {
|
|
236
|
-
return `https://${codespaceName}-${port}.${codespacesDomain}`;
|
|
237
|
-
}
|
|
238
233
|
return `http://${host}:${port}`;
|
|
239
234
|
}
|
|
240
235
|
function loadConfigSync() {
|
|
@@ -69,10 +69,14 @@ declare function unsetConfigValue(key: string): Promise<void>;
|
|
|
69
69
|
/**
|
|
70
70
|
* Get daemon URL from config
|
|
71
71
|
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
72
|
+
* Returns internal daemon URL for backend-to-backend communication.
|
|
73
|
+
* Always returns localhost-based URL since all backend components (daemon, CLI, SDKs)
|
|
74
|
+
* run in the same environment.
|
|
74
75
|
*
|
|
75
|
-
*
|
|
76
|
+
* For external access (browser UI), use frontend's getDaemonUrl() which detects
|
|
77
|
+
* the appropriate public URL via window.location.
|
|
78
|
+
*
|
|
79
|
+
* @returns Daemon URL (e.g., "http://localhost:3030")
|
|
76
80
|
*/
|
|
77
81
|
declare function getDaemonUrl(): Promise<string>;
|
|
78
82
|
/**
|
|
@@ -69,10 +69,14 @@ declare function unsetConfigValue(key: string): Promise<void>;
|
|
|
69
69
|
/**
|
|
70
70
|
* Get daemon URL from config
|
|
71
71
|
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
72
|
+
* Returns internal daemon URL for backend-to-backend communication.
|
|
73
|
+
* Always returns localhost-based URL since all backend components (daemon, CLI, SDKs)
|
|
74
|
+
* run in the same environment.
|
|
74
75
|
*
|
|
75
|
-
*
|
|
76
|
+
* For external access (browser UI), use frontend's getDaemonUrl() which detects
|
|
77
|
+
* the appropriate public URL via window.location.
|
|
78
|
+
*
|
|
79
|
+
* @returns Daemon URL (e.g., "http://localhost:3030")
|
|
76
80
|
*/
|
|
77
81
|
declare function getDaemonUrl(): Promise<string>;
|
|
78
82
|
/**
|
|
@@ -156,11 +156,6 @@ async function getDaemonUrl() {
|
|
|
156
156
|
const envPort = process.env.PORT ? Number.parseInt(process.env.PORT, 10) : void 0;
|
|
157
157
|
const port = envPort || config.daemon?.port || defaults.daemon?.port || 3030;
|
|
158
158
|
const host = config.daemon?.host || defaults.daemon?.host || "localhost";
|
|
159
|
-
const codespaceName = process.env.CODESPACE_NAME;
|
|
160
|
-
const codespacesDomain = process.env.GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN;
|
|
161
|
-
if (codespaceName && codespacesDomain) {
|
|
162
|
-
return `https://${codespaceName}-${port}.${codespacesDomain}`;
|
|
163
|
-
}
|
|
164
159
|
return `http://${host}:${port}`;
|
|
165
160
|
}
|
|
166
161
|
function loadConfigSync() {
|
package/dist/core/db/index.cjs
CHANGED
|
@@ -2112,6 +2112,47 @@ var MessagesRepository = class {
|
|
|
2112
2112
|
// src/db/repositories/repos.ts
|
|
2113
2113
|
var import_drizzle_orm8 = require("drizzle-orm");
|
|
2114
2114
|
init_ids();
|
|
2115
|
+
|
|
2116
|
+
// src/db/repositories/merge-utils.ts
|
|
2117
|
+
function isPlainObject(value) {
|
|
2118
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) && !(value instanceof Date) && Object.getPrototypeOf(value) === Object.prototype;
|
|
2119
|
+
}
|
|
2120
|
+
function deepMerge(target, source) {
|
|
2121
|
+
const result = { ...target };
|
|
2122
|
+
for (const key in source) {
|
|
2123
|
+
if (!Object.hasOwn(source, key)) {
|
|
2124
|
+
continue;
|
|
2125
|
+
}
|
|
2126
|
+
const sourceValue = source[key];
|
|
2127
|
+
const targetValue = target[key];
|
|
2128
|
+
if (sourceValue === void 0) {
|
|
2129
|
+
continue;
|
|
2130
|
+
}
|
|
2131
|
+
if (sourceValue === null) {
|
|
2132
|
+
result[key] = null;
|
|
2133
|
+
continue;
|
|
2134
|
+
}
|
|
2135
|
+
if (Array.isArray(sourceValue)) {
|
|
2136
|
+
result[key] = sourceValue;
|
|
2137
|
+
continue;
|
|
2138
|
+
}
|
|
2139
|
+
if (isPlainObject(sourceValue)) {
|
|
2140
|
+
if (isPlainObject(targetValue)) {
|
|
2141
|
+
result[key] = deepMerge(
|
|
2142
|
+
targetValue,
|
|
2143
|
+
sourceValue
|
|
2144
|
+
);
|
|
2145
|
+
} else {
|
|
2146
|
+
result[key] = sourceValue;
|
|
2147
|
+
}
|
|
2148
|
+
continue;
|
|
2149
|
+
}
|
|
2150
|
+
result[key] = sourceValue;
|
|
2151
|
+
}
|
|
2152
|
+
return result;
|
|
2153
|
+
}
|
|
2154
|
+
|
|
2155
|
+
// src/db/repositories/repos.ts
|
|
2115
2156
|
var RepoRepository = class {
|
|
2116
2157
|
constructor(db) {
|
|
2117
2158
|
this.db = db;
|
|
@@ -2250,27 +2291,29 @@ var RepoRepository = class {
|
|
|
2250
2291
|
return this.findAll();
|
|
2251
2292
|
}
|
|
2252
2293
|
/**
|
|
2253
|
-
* Update repo by ID
|
|
2294
|
+
* Update repo by ID (atomic with database-level transaction)
|
|
2295
|
+
*
|
|
2296
|
+
* Uses a transaction to ensure read-merge-write is atomic, preventing race conditions
|
|
2297
|
+
* when multiple updates happen concurrently (e.g., permission_config updates).
|
|
2254
2298
|
*/
|
|
2255
2299
|
async update(id, updates) {
|
|
2256
2300
|
try {
|
|
2257
2301
|
const fullId = await this.resolveId(id);
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
}
|
|
2273
|
-
return updated;
|
|
2302
|
+
return await this.db.transaction(async (tx) => {
|
|
2303
|
+
const currentRow = await tx.select().from(repos).where((0, import_drizzle_orm8.eq)(repos.repo_id, fullId)).get();
|
|
2304
|
+
if (!currentRow) {
|
|
2305
|
+
throw new EntityNotFoundError("Repo", id);
|
|
2306
|
+
}
|
|
2307
|
+
const current = this.rowToRepo(currentRow);
|
|
2308
|
+
const merged = deepMerge(current, updates);
|
|
2309
|
+
const insert = this.repoToInsert(merged);
|
|
2310
|
+
await tx.update(repos).set({
|
|
2311
|
+
slug: insert.slug,
|
|
2312
|
+
updated_at: /* @__PURE__ */ new Date(),
|
|
2313
|
+
data: insert.data
|
|
2314
|
+
}).where((0, import_drizzle_orm8.eq)(repos.repo_id, fullId));
|
|
2315
|
+
return merged;
|
|
2316
|
+
});
|
|
2274
2317
|
} catch (error) {
|
|
2275
2318
|
if (error instanceof RepositoryError) throw error;
|
|
2276
2319
|
if (error instanceof EntityNotFoundError) throw error;
|
|
@@ -2580,45 +2623,37 @@ var SessionRepository = class {
|
|
|
2580
2623
|
}
|
|
2581
2624
|
}
|
|
2582
2625
|
/**
|
|
2583
|
-
* Update session by ID
|
|
2626
|
+
* Update session by ID (atomic with database-level transaction)
|
|
2627
|
+
*
|
|
2628
|
+
* Uses a transaction to ensure read-merge-write is atomic, preventing race conditions
|
|
2629
|
+
* when multiple updates happen concurrently (e.g., user changes settings while permission
|
|
2630
|
+
* hook is saving allowedTools).
|
|
2584
2631
|
*/
|
|
2585
2632
|
async update(id, updates) {
|
|
2586
2633
|
try {
|
|
2587
2634
|
const fullId = await this.resolveId(id);
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
`
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
);
|
|
2611
|
-
await this.db.update(sessions).set({
|
|
2612
|
-
status: insert.status,
|
|
2613
|
-
updated_at: /* @__PURE__ */ new Date(),
|
|
2614
|
-
data: insert.data
|
|
2615
|
-
}).where((0, import_drizzle_orm9.eq)(sessions.session_id, fullId));
|
|
2616
|
-
console.log(`\u2705 [SessionRepository] DB update complete`);
|
|
2617
|
-
const updated = await this.findById(fullId);
|
|
2618
|
-
if (!updated) {
|
|
2619
|
-
throw new RepositoryError("Failed to retrieve updated session");
|
|
2620
|
-
}
|
|
2621
|
-
return updated;
|
|
2635
|
+
return await this.db.transaction(async (tx) => {
|
|
2636
|
+
const currentRow = await tx.select().from(sessions).where((0, import_drizzle_orm9.eq)(sessions.session_id, fullId)).get();
|
|
2637
|
+
if (!currentRow) {
|
|
2638
|
+
throw new EntityNotFoundError("Session", id);
|
|
2639
|
+
}
|
|
2640
|
+
const current = this.rowToSession(currentRow);
|
|
2641
|
+
const merged = deepMerge(current, updates);
|
|
2642
|
+
if (updates.permission_config) {
|
|
2643
|
+
console.log(`\u{1F4DD} [SessionRepository] Merging permission_config update (atomic tx)`);
|
|
2644
|
+
console.log(` Before merge: ${JSON.stringify(current.permission_config)}`);
|
|
2645
|
+
console.log(` Update: ${JSON.stringify(updates.permission_config)}`);
|
|
2646
|
+
console.log(` After merge: ${JSON.stringify(merged.permission_config)}`);
|
|
2647
|
+
}
|
|
2648
|
+
const insert = this.sessionToInsert(merged);
|
|
2649
|
+
await tx.update(sessions).set({
|
|
2650
|
+
status: insert.status,
|
|
2651
|
+
updated_at: /* @__PURE__ */ new Date(),
|
|
2652
|
+
data: insert.data
|
|
2653
|
+
}).where((0, import_drizzle_orm9.eq)(sessions.session_id, fullId));
|
|
2654
|
+
console.log(`\u2705 [SessionRepository] Atomic update complete`);
|
|
2655
|
+
return merged;
|
|
2656
|
+
});
|
|
2622
2657
|
} catch (error) {
|
|
2623
2658
|
if (error instanceof RepositoryError) throw error;
|
|
2624
2659
|
if (error instanceof EntityNotFoundError) throw error;
|
|
@@ -2982,9 +3017,7 @@ var TaskRepository = class {
|
|
|
2982
3017
|
const inserts = taskList.map((task) => this.taskToInsert(task));
|
|
2983
3018
|
await this.db.insert(tasks).values(inserts);
|
|
2984
3019
|
const taskIds = inserts.map((t) => t.task_id);
|
|
2985
|
-
const rows = await this.db.select().from(tasks).where(
|
|
2986
|
-
import_drizzle_orm11.sql`${tasks.task_id} IN ${import_drizzle_orm11.sql.raw(`(${taskIds.map((id) => `'${id}'`).join(",")})`)}`
|
|
2987
|
-
);
|
|
3020
|
+
const rows = await this.db.select().from(tasks).where(import_drizzle_orm11.sql`${tasks.task_id} IN ${import_drizzle_orm11.sql.raw(`(${taskIds.map((id) => `'${id}'`).join(",")})`)}`);
|
|
2988
3021
|
return rows.map((row) => this.rowToTask(row));
|
|
2989
3022
|
} catch (error) {
|
|
2990
3023
|
throw new RepositoryError(
|
|
@@ -3067,27 +3100,29 @@ var TaskRepository = class {
|
|
|
3067
3100
|
}
|
|
3068
3101
|
}
|
|
3069
3102
|
/**
|
|
3070
|
-
* Update task by ID
|
|
3103
|
+
* Update task by ID (atomic with database-level transaction)
|
|
3104
|
+
*
|
|
3105
|
+
* Uses a transaction to ensure read-merge-write is atomic, preventing race conditions
|
|
3106
|
+
* when multiple updates happen concurrently (e.g., task status + message_range updates).
|
|
3071
3107
|
*/
|
|
3072
3108
|
async update(id, updates) {
|
|
3073
3109
|
try {
|
|
3074
3110
|
const fullId = await this.resolveId(id);
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
}
|
|
3090
|
-
return updated;
|
|
3111
|
+
return await this.db.transaction(async (tx) => {
|
|
3112
|
+
const currentRow = await tx.select().from(tasks).where((0, import_drizzle_orm11.eq)(tasks.task_id, fullId)).get();
|
|
3113
|
+
if (!currentRow) {
|
|
3114
|
+
throw new EntityNotFoundError("Task", id);
|
|
3115
|
+
}
|
|
3116
|
+
const current = this.rowToTask(currentRow);
|
|
3117
|
+
const merged = deepMerge(current, updates);
|
|
3118
|
+
const insert = this.taskToInsert(merged);
|
|
3119
|
+
await tx.update(tasks).set({
|
|
3120
|
+
status: insert.status,
|
|
3121
|
+
completed_at: insert.completed_at,
|
|
3122
|
+
data: insert.data
|
|
3123
|
+
}).where((0, import_drizzle_orm11.eq)(tasks.task_id, fullId));
|
|
3124
|
+
return merged;
|
|
3125
|
+
});
|
|
3091
3126
|
} catch (error) {
|
|
3092
3127
|
if (error instanceof RepositoryError) throw error;
|
|
3093
3128
|
if (error instanceof EntityNotFoundError) throw error;
|
|
@@ -3240,24 +3275,37 @@ var WorktreeRepository = class {
|
|
|
3240
3275
|
return rows.map((row) => this.rowToWorktree(row));
|
|
3241
3276
|
}
|
|
3242
3277
|
/**
|
|
3243
|
-
* Update worktree by ID
|
|
3278
|
+
* Update worktree by ID (atomic with database-level transaction)
|
|
3279
|
+
*
|
|
3280
|
+
* Uses a transaction to ensure read-merge-write is atomic, preventing race conditions
|
|
3281
|
+
* when multiple updates happen concurrently (e.g., schedule config + environment updates).
|
|
3244
3282
|
*/
|
|
3245
3283
|
async update(id, updates) {
|
|
3246
3284
|
const existing = await this.findById(id);
|
|
3247
3285
|
if (!existing) {
|
|
3248
3286
|
throw new EntityNotFoundError("Worktree", id);
|
|
3249
3287
|
}
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3288
|
+
return await this.db.transaction(async (tx) => {
|
|
3289
|
+
const currentRow = await tx.select().from(worktrees).where((0, import_drizzle_orm12.eq)(worktrees.worktree_id, existing.worktree_id)).get();
|
|
3290
|
+
if (!currentRow) {
|
|
3291
|
+
throw new EntityNotFoundError("Worktree", id);
|
|
3292
|
+
}
|
|
3293
|
+
const current = this.rowToWorktree(currentRow);
|
|
3294
|
+
const merged = deepMerge(current, {
|
|
3295
|
+
...updates,
|
|
3296
|
+
worktree_id: current.worktree_id,
|
|
3297
|
+
// Never change ID
|
|
3298
|
+
repo_id: current.repo_id,
|
|
3299
|
+
// Never change repo
|
|
3300
|
+
created_at: current.created_at,
|
|
3301
|
+
// Never change created timestamp
|
|
3302
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
3303
|
+
// Always update timestamp
|
|
3304
|
+
});
|
|
3305
|
+
const insert = this.worktreeToInsert(merged);
|
|
3306
|
+
const [row] = await tx.update(worktrees).set(insert).where((0, import_drizzle_orm12.eq)(worktrees.worktree_id, current.worktree_id)).returning();
|
|
3307
|
+
return this.rowToWorktree(row);
|
|
3308
|
+
});
|
|
3261
3309
|
}
|
|
3262
3310
|
/**
|
|
3263
3311
|
* Delete worktree by ID
|
package/dist/core/db/index.d.cts
CHANGED
|
@@ -2,8 +2,8 @@ export { and, desc, eq, inArray, like, or, sql } from 'drizzle-orm';
|
|
|
2
2
|
import bcryptjs from 'bcryptjs';
|
|
3
3
|
import { d as Database } from '../client-B7p2_7Ut.cjs';
|
|
4
4
|
export { H as BoardCommentInsert, G as BoardCommentRow, p as BoardInsert, F as BoardObjectInsert, E as BoardObjectRow, B as BoardRow, e as DEFAULT_DB_PATH, a as DatabaseConnectionError, D as DbConfig, z as MCPServerInsert, y as MCPServerRow, o as MessageInsert, M as MessageRow, q as RepoInsert, R as RepoRow, l as SessionInsert, C as SessionMCPServerInsert, A as SessionMCPServerRow, S as SessionRow, n as TaskInsert, T as TaskRow, x as UserInsert, U as UserRow, v as WorktreeInsert, W as WorktreeRow, k as boardComments, i as boardObjects, g as boards, c as createDatabase, b as createDatabaseAsync, f as createLocalDatabase, h as mcpServers, m as messages, r as repos, j as sessionMcpServers, s as sessions, t as tasks, u as users, w as worktrees } from '../client-B7p2_7Ut.cjs';
|
|
5
|
-
import { B as BaseRepository } from '../worktrees-
|
|
6
|
-
export { A as AmbiguousIdError, E as EntityNotFoundError, M as MCPServerRepository, a as MessagesRepository, b as RepoRepository, R as RepositoryError, S as SessionMCPServerRepository, c as SessionRepository, W as WorktreeRepository } from '../worktrees-
|
|
5
|
+
import { B as BaseRepository } from '../worktrees-BEIruvGs.cjs';
|
|
6
|
+
export { A as AmbiguousIdError, E as EntityNotFoundError, M as MCPServerRepository, a as MessagesRepository, b as RepoRepository, R as RepositoryError, S as SessionMCPServerRepository, c as SessionRepository, W as WorktreeRepository } from '../worktrees-BEIruvGs.cjs';
|
|
7
7
|
import { B as BoardComment } from '../board-comment-CaUiaZB5.cjs';
|
|
8
8
|
import { B as BoardID, W as WorktreeID } from '../id-DMqyogFB.cjs';
|
|
9
9
|
import { a as BoardEntityObject, e as Board, d as BoardObject } from '../board-Oa2OJ-K3.cjs';
|
|
@@ -506,7 +506,10 @@ declare class TaskRepository implements BaseRepository<Task, Partial<Task>> {
|
|
|
506
506
|
*/
|
|
507
507
|
findByStatus(status: Task['status']): Promise<Task[]>;
|
|
508
508
|
/**
|
|
509
|
-
* Update task by ID
|
|
509
|
+
* Update task by ID (atomic with database-level transaction)
|
|
510
|
+
*
|
|
511
|
+
* Uses a transaction to ensure read-merge-write is atomic, preventing race conditions
|
|
512
|
+
* when multiple updates happen concurrently (e.g., task status + message_range updates).
|
|
510
513
|
*/
|
|
511
514
|
update(id: string, updates: Partial<Task>): Promise<Task>;
|
|
512
515
|
/**
|
package/dist/core/db/index.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ export { and, desc, eq, inArray, like, or, sql } from 'drizzle-orm';
|
|
|
2
2
|
import bcryptjs from 'bcryptjs';
|
|
3
3
|
import { d as Database } from '../client-CklMhh5V.js';
|
|
4
4
|
export { H as BoardCommentInsert, G as BoardCommentRow, p as BoardInsert, F as BoardObjectInsert, E as BoardObjectRow, B as BoardRow, e as DEFAULT_DB_PATH, a as DatabaseConnectionError, D as DbConfig, z as MCPServerInsert, y as MCPServerRow, o as MessageInsert, M as MessageRow, q as RepoInsert, R as RepoRow, l as SessionInsert, C as SessionMCPServerInsert, A as SessionMCPServerRow, S as SessionRow, n as TaskInsert, T as TaskRow, x as UserInsert, U as UserRow, v as WorktreeInsert, W as WorktreeRow, k as boardComments, i as boardObjects, g as boards, c as createDatabase, b as createDatabaseAsync, f as createLocalDatabase, h as mcpServers, m as messages, r as repos, j as sessionMcpServers, s as sessions, t as tasks, u as users, w as worktrees } from '../client-CklMhh5V.js';
|
|
5
|
-
import { B as BaseRepository } from '../worktrees-
|
|
6
|
-
export { A as AmbiguousIdError, E as EntityNotFoundError, M as MCPServerRepository, a as MessagesRepository, b as RepoRepository, R as RepositoryError, S as SessionMCPServerRepository, c as SessionRepository, W as WorktreeRepository } from '../worktrees-
|
|
5
|
+
import { B as BaseRepository } from '../worktrees-Dv8M5-3U.js';
|
|
6
|
+
export { A as AmbiguousIdError, E as EntityNotFoundError, M as MCPServerRepository, a as MessagesRepository, b as RepoRepository, R as RepositoryError, S as SessionMCPServerRepository, c as SessionRepository, W as WorktreeRepository } from '../worktrees-Dv8M5-3U.js';
|
|
7
7
|
import { B as BoardComment } from '../board-comment-BCrDUioT.js';
|
|
8
8
|
import { B as BoardID, W as WorktreeID } from '../id-DMqyogFB.js';
|
|
9
9
|
import { a as BoardEntityObject, e as Board, d as BoardObject } from '../board-ava4cdq5.js';
|
|
@@ -506,7 +506,10 @@ declare class TaskRepository implements BaseRepository<Task, Partial<Task>> {
|
|
|
506
506
|
*/
|
|
507
507
|
findByStatus(status: Task['status']): Promise<Task[]>;
|
|
508
508
|
/**
|
|
509
|
-
* Update task by ID
|
|
509
|
+
* Update task by ID (atomic with database-level transaction)
|
|
510
|
+
*
|
|
511
|
+
* Uses a transaction to ensure read-merge-write is atomic, preventing race conditions
|
|
512
|
+
* when multiple updates happen concurrently (e.g., task status + message_range updates).
|
|
510
513
|
*/
|
|
511
514
|
update(id: string, updates: Partial<Task>): Promise<Task>;
|
|
512
515
|
/**
|