@devness/useai 0.5.4 → 0.5.5
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/index.js +80 -54
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1713,7 +1713,7 @@ function resolveClient(server2, session2) {
|
|
|
1713
1713
|
}
|
|
1714
1714
|
session2.setClient(detectClient());
|
|
1715
1715
|
}
|
|
1716
|
-
function registerTools(server2, session2) {
|
|
1716
|
+
function registerTools(server2, session2, opts) {
|
|
1717
1717
|
server2.tool(
|
|
1718
1718
|
"useai_start",
|
|
1719
1719
|
`Start tracking an AI coding session. Call this at the beginning of every response. Generate a session title from the user's prompt: a generic public "title" (no project/file names) and a detailed "private_title" (can include specifics).`,
|
|
@@ -1723,6 +1723,9 @@ function registerTools(server2, session2) {
|
|
|
1723
1723
|
private_title: z2.string().optional().describe('Detailed session title for private records. Can include project names and specifics. Example: "Fix JWT refresh in UseAI login flow"')
|
|
1724
1724
|
},
|
|
1725
1725
|
async ({ task_type, title, private_title }) => {
|
|
1726
|
+
if (session2.sessionRecordCount > 0 && opts?.sealBeforeReset) {
|
|
1727
|
+
opts.sealBeforeReset();
|
|
1728
|
+
}
|
|
1726
1729
|
session2.reset();
|
|
1727
1730
|
resolveClient(server2, session2);
|
|
1728
1731
|
session2.setTaskType(task_type ?? "coding");
|
|
@@ -1863,7 +1866,7 @@ function registerTools(server2, session2) {
|
|
|
1863
1866
|
chain_end_hash: endRecord.hash,
|
|
1864
1867
|
seal_signature: sealSignature
|
|
1865
1868
|
};
|
|
1866
|
-
const sessions2 = getSessions();
|
|
1869
|
+
const sessions2 = getSessions().filter((s) => s.session_id !== seal.session_id);
|
|
1867
1870
|
sessions2.push(seal);
|
|
1868
1871
|
writeJson(SESSIONS_FILE, sessions2);
|
|
1869
1872
|
let milestoneCount = 0;
|
|
@@ -2250,6 +2253,9 @@ function sealOrphanFile(sessionId) {
|
|
|
2250
2253
|
const client = startData["client"] ?? "unknown";
|
|
2251
2254
|
const taskType = startData["task_type"] ?? "coding";
|
|
2252
2255
|
const startTime = firstRecord.timestamp;
|
|
2256
|
+
const orphanTitle = startData["title"] ?? void 0;
|
|
2257
|
+
const orphanPrivateTitle = startData["private_title"] ?? void 0;
|
|
2258
|
+
const orphanProject = startData["project"] ?? void 0;
|
|
2253
2259
|
let heartbeatCount = 0;
|
|
2254
2260
|
for (const line of lines) {
|
|
2255
2261
|
try {
|
|
@@ -2297,30 +2303,29 @@ function sealOrphanFile(sessionId) {
|
|
|
2297
2303
|
renameSync3(filePath, join7(SEALED_DIR, `${sessionId}.jsonl`));
|
|
2298
2304
|
} catch {
|
|
2299
2305
|
}
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
}
|
|
2306
|
+
const convId = startData["conversation_id"] ?? void 0;
|
|
2307
|
+
const convIdx = startData["conversation_index"] ?? void 0;
|
|
2308
|
+
const seal = {
|
|
2309
|
+
session_id: sessionId,
|
|
2310
|
+
conversation_id: convId,
|
|
2311
|
+
conversation_index: convIdx,
|
|
2312
|
+
client,
|
|
2313
|
+
task_type: taskType,
|
|
2314
|
+
languages: [],
|
|
2315
|
+
files_touched: 0,
|
|
2316
|
+
project: orphanProject,
|
|
2317
|
+
title: orphanTitle,
|
|
2318
|
+
private_title: orphanPrivateTitle,
|
|
2319
|
+
started_at: startTime,
|
|
2320
|
+
ended_at: now,
|
|
2321
|
+
duration_seconds: duration,
|
|
2322
|
+
heartbeat_count: heartbeatCount,
|
|
2323
|
+
record_count: lines.length + 2,
|
|
2324
|
+
chain_start_hash: firstRecord.prev_hash,
|
|
2325
|
+
chain_end_hash: endRecord.hash,
|
|
2326
|
+
seal_signature: sealSignature
|
|
2327
|
+
};
|
|
2328
|
+
upsertSessionSeal(seal);
|
|
2324
2329
|
} catch {
|
|
2325
2330
|
}
|
|
2326
2331
|
}
|
|
@@ -2346,10 +2351,6 @@ function isSessionAlreadySealed(session2) {
|
|
|
2346
2351
|
const activePath = join7(ACTIVE_DIR, `${session2.sessionId}.jsonl`);
|
|
2347
2352
|
return !existsSync8(activePath);
|
|
2348
2353
|
}
|
|
2349
|
-
function isSessionInIndex(sessionId) {
|
|
2350
|
-
const allSessions = readJson(SESSIONS_FILE, []);
|
|
2351
|
-
return allSessions.some((s) => s.session_id === sessionId);
|
|
2352
|
-
}
|
|
2353
2354
|
function sealRichness(s) {
|
|
2354
2355
|
let score = 0;
|
|
2355
2356
|
if (s.title) score += 10;
|
|
@@ -2377,6 +2378,18 @@ function deduplicateSessionsIndex() {
|
|
|
2377
2378
|
writeJson(SESSIONS_FILE, deduped);
|
|
2378
2379
|
}
|
|
2379
2380
|
}
|
|
2381
|
+
function upsertSessionSeal(seal) {
|
|
2382
|
+
const allSessions = readJson(SESSIONS_FILE, []);
|
|
2383
|
+
const existingIdx = allSessions.findIndex((s) => s.session_id === seal.session_id);
|
|
2384
|
+
if (existingIdx >= 0) {
|
|
2385
|
+
if (sealRichness(seal) >= sealRichness(allSessions[existingIdx])) {
|
|
2386
|
+
allSessions[existingIdx] = seal;
|
|
2387
|
+
}
|
|
2388
|
+
} else {
|
|
2389
|
+
allSessions.push(seal);
|
|
2390
|
+
}
|
|
2391
|
+
writeJson(SESSIONS_FILE, allSessions);
|
|
2392
|
+
}
|
|
2380
2393
|
function autoSealSession(active) {
|
|
2381
2394
|
const { session: session2 } = active;
|
|
2382
2395
|
if (session2.sessionRecordCount === 0) return;
|
|
@@ -2399,6 +2412,9 @@ function autoSealSession(active) {
|
|
|
2399
2412
|
task_type: session2.sessionTaskType,
|
|
2400
2413
|
languages: [],
|
|
2401
2414
|
files_touched: 0,
|
|
2415
|
+
project: session2.project ?? void 0,
|
|
2416
|
+
title: session2.sessionTitle ?? void 0,
|
|
2417
|
+
private_title: session2.sessionPrivateTitle ?? void 0,
|
|
2402
2418
|
started_at: new Date(session2.sessionStartTime).toISOString(),
|
|
2403
2419
|
ended_at: now,
|
|
2404
2420
|
duration_seconds: duration,
|
|
@@ -2423,29 +2439,28 @@ function autoSealSession(active) {
|
|
|
2423
2439
|
}
|
|
2424
2440
|
} catch {
|
|
2425
2441
|
}
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
}
|
|
2442
|
+
const chainStartHash = session2.chainTipHash === "GENESIS" ? "GENESIS" : session2.chainTipHash;
|
|
2443
|
+
const seal = {
|
|
2444
|
+
session_id: session2.sessionId,
|
|
2445
|
+
conversation_id: session2.conversationId,
|
|
2446
|
+
conversation_index: session2.conversationIndex,
|
|
2447
|
+
client: session2.clientName,
|
|
2448
|
+
task_type: session2.sessionTaskType,
|
|
2449
|
+
languages: [],
|
|
2450
|
+
files_touched: 0,
|
|
2451
|
+
project: session2.project ?? void 0,
|
|
2452
|
+
title: session2.sessionTitle ?? void 0,
|
|
2453
|
+
private_title: session2.sessionPrivateTitle ?? void 0,
|
|
2454
|
+
started_at: new Date(session2.sessionStartTime).toISOString(),
|
|
2455
|
+
ended_at: now,
|
|
2456
|
+
duration_seconds: duration,
|
|
2457
|
+
heartbeat_count: session2.heartbeatCount,
|
|
2458
|
+
record_count: session2.sessionRecordCount,
|
|
2459
|
+
chain_start_hash: chainStartHash,
|
|
2460
|
+
chain_end_hash: endRecord.hash,
|
|
2461
|
+
seal_signature: sealSignature
|
|
2462
|
+
};
|
|
2463
|
+
upsertSessionSeal(seal);
|
|
2449
2464
|
}
|
|
2450
2465
|
function sealSessionData(active) {
|
|
2451
2466
|
autoSealSession(active);
|
|
@@ -2613,7 +2628,18 @@ async function startDaemon(port) {
|
|
|
2613
2628
|
name: "UseAI",
|
|
2614
2629
|
version: VERSION
|
|
2615
2630
|
});
|
|
2616
|
-
registerTools(mcpServer, sessionState
|
|
2631
|
+
registerTools(mcpServer, sessionState, {
|
|
2632
|
+
sealBeforeReset: () => {
|
|
2633
|
+
for (const [, active] of sessions) {
|
|
2634
|
+
if (active.session === sessionState) {
|
|
2635
|
+
if (active.session.sessionRecordCount > 0 && !isSessionAlreadySealed(active.session)) {
|
|
2636
|
+
autoSealSession(active);
|
|
2637
|
+
}
|
|
2638
|
+
break;
|
|
2639
|
+
}
|
|
2640
|
+
}
|
|
2641
|
+
}
|
|
2642
|
+
});
|
|
2617
2643
|
const transport = new StreamableHTTPServerTransport({
|
|
2618
2644
|
sessionIdGenerator: () => randomUUID4(),
|
|
2619
2645
|
onsessioninitialized: (newSid) => {
|