hammoc 1.7.0 → 1.7.2
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/README.md +6 -2
- package/package.json +1 -1
- package/packages/client/dist/assets/{agentExampleHighlight-7Olvqdpf.js → agentExampleHighlight-De1SlBXH.js} +1 -1
- package/packages/client/dist/assets/{commandTokenHighlight-DtKwh4lx.js → commandTokenHighlight-COQi5YnH.js} +1 -1
- package/packages/client/dist/assets/index-BsHMOF5r.css +32 -0
- package/packages/client/dist/assets/{index-Bee52CKG.js → index-CQgqPGOG.js} +483 -469
- package/packages/client/dist/assets/{index-DLHBUw8c.js → index-D8XvfvVS.js} +1 -1
- package/packages/client/dist/assets/{snippetTokenHighlight-C8O688f4.js → snippetTokenHighlight-jMAHlrFd.js} +1 -1
- package/packages/client/dist/index.html +2 -2
- package/packages/client/dist/sw.js +1 -1
- package/packages/server/dist/controllers/gitController.d.ts.map +1 -1
- package/packages/server/dist/controllers/gitController.js +37 -0
- package/packages/server/dist/controllers/gitController.js.map +1 -1
- package/packages/server/dist/controllers/projectController.d.ts.map +1 -1
- package/packages/server/dist/controllers/projectController.js +3 -1
- package/packages/server/dist/controllers/projectController.js.map +1 -1
- package/packages/server/dist/controllers/sessionController.d.ts.map +1 -1
- package/packages/server/dist/controllers/sessionController.js +3 -1
- package/packages/server/dist/controllers/sessionController.js.map +1 -1
- package/packages/server/dist/handlers/streamCallbacks.d.ts +2 -0
- package/packages/server/dist/handlers/streamCallbacks.d.ts.map +1 -1
- package/packages/server/dist/handlers/streamCallbacks.js +4 -4
- package/packages/server/dist/handlers/streamCallbacks.js.map +1 -1
- package/packages/server/dist/handlers/websocket.d.ts +6 -0
- package/packages/server/dist/handlers/websocket.d.ts.map +1 -1
- package/packages/server/dist/handlers/websocket.js +68 -5
- package/packages/server/dist/handlers/websocket.js.map +1 -1
- package/packages/server/dist/locales/en/server.json +2 -0
- package/packages/server/dist/locales/es/server.json +2 -0
- package/packages/server/dist/locales/ja/server.json +2 -0
- package/packages/server/dist/locales/ko/server.json +2 -0
- package/packages/server/dist/locales/pt/server.json +2 -0
- package/packages/server/dist/locales/zh-CN/server.json +2 -0
- package/packages/server/dist/services/chatService.js +1 -1
- package/packages/server/dist/services/chatService.js.map +1 -1
- package/packages/server/dist/services/cliChatEngine.js +2 -2
- package/packages/server/dist/services/cliChatEngine.js.map +1 -1
- package/packages/server/dist/services/dashboardService.d.ts.map +1 -1
- package/packages/server/dist/services/dashboardService.js +6 -1
- package/packages/server/dist/services/dashboardService.js.map +1 -1
- package/packages/server/dist/services/gitService.d.ts +2 -0
- package/packages/server/dist/services/gitService.d.ts.map +1 -1
- package/packages/server/dist/services/gitService.js +41 -3
- package/packages/server/dist/services/gitService.js.map +1 -1
- package/packages/server/dist/services/queueService.d.ts +1 -0
- package/packages/server/dist/services/queueService.d.ts.map +1 -1
- package/packages/server/dist/services/queueService.js +15 -3
- package/packages/server/dist/services/queueService.js.map +1 -1
- package/packages/server/dist/services/workspaceContext.d.ts +2 -1
- package/packages/server/dist/services/workspaceContext.d.ts.map +1 -1
- package/packages/server/dist/services/workspaceContext.js +10 -2
- package/packages/server/dist/services/workspaceContext.js.map +1 -1
- package/packages/server/dist/utils/cliDebugLog.d.ts +4 -2
- package/packages/server/dist/utils/cliDebugLog.d.ts.map +1 -1
- package/packages/server/dist/utils/cliDebugLog.js +8 -2
- package/packages/server/dist/utils/cliDebugLog.js.map +1 -1
- package/packages/server/resources/bmad-method/4.44.3/LICENSE +30 -0
- package/packages/server/resources/manual/02-chat.md +2 -2
- package/packages/server/resources/manual/03-sessions.md +1 -0
- package/packages/server/resources/manual/05-projects.md +2 -2
- package/packages/server/resources/manual/07-git.md +23 -2
- package/packages/server/resources/manual/08-terminal.md +24 -1
- package/packages/server/resources/manual/11-bmad-method-integration.md +1 -0
- package/packages/server/resources/manual/13-settings.md +25 -25
- package/packages/shared/dist/types/dashboard.d.ts +1 -0
- package/packages/shared/dist/types/dashboard.d.ts.map +1 -1
- package/packages/shared/dist/types/git.d.ts +12 -0
- package/packages/shared/dist/types/git.d.ts.map +1 -1
- package/packages/shared/dist/types/git.js +10 -0
- package/packages/shared/dist/types/git.js.map +1 -1
- package/packages/shared/dist/types/preferences.d.ts +1 -0
- package/packages/shared/dist/types/preferences.d.ts.map +1 -1
- package/packages/shared/dist/types/preferences.js.map +1 -1
- package/packages/shared/dist/types/sdk.d.ts +2 -0
- package/packages/shared/dist/types/sdk.d.ts.map +1 -1
- package/packages/shared/dist/types/sdk.js.map +1 -1
- package/packages/shared/dist/types/session.d.ts +1 -0
- package/packages/shared/dist/types/session.d.ts.map +1 -1
- package/packages/shared/dist/types/session.js.map +1 -1
- package/packages/shared/dist/types/websocket.d.ts +6 -0
- package/packages/shared/dist/types/websocket.d.ts.map +1 -1
- package/packages/client/dist/assets/index-CVy582lU.css +0 -32
|
@@ -456,6 +456,38 @@ export function isSessionStreaming(sessionId) {
|
|
|
456
456
|
const stream = activeStreams.get(sessionId);
|
|
457
457
|
return !!stream && stream.status === 'running';
|
|
458
458
|
}
|
|
459
|
+
/** Check if a session has any pending AskUserQuestion interactions */
|
|
460
|
+
export function sessionHasPendingQuestion(sessionId) {
|
|
461
|
+
const stream = activeStreams.get(sessionId);
|
|
462
|
+
if (!stream)
|
|
463
|
+
return false;
|
|
464
|
+
for (const p of stream.pendingPermissions.values()) {
|
|
465
|
+
if (p.interactionType === 'question')
|
|
466
|
+
return true;
|
|
467
|
+
}
|
|
468
|
+
return false;
|
|
469
|
+
}
|
|
470
|
+
/** Get pending AskUserQuestion counts grouped by project slug (in-memory, no I/O) */
|
|
471
|
+
export function getPendingQuestionCountsByProject() {
|
|
472
|
+
const counts = new Map();
|
|
473
|
+
for (const [sessionId, stream] of activeStreams.entries()) {
|
|
474
|
+
if (stream.status !== 'running')
|
|
475
|
+
continue;
|
|
476
|
+
let hasQuestion = false;
|
|
477
|
+
for (const p of stream.pendingPermissions.values()) {
|
|
478
|
+
if (p.interactionType === 'question') {
|
|
479
|
+
hasQuestion = true;
|
|
480
|
+
break;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
if (hasQuestion) {
|
|
484
|
+
const slug = sessionProjectMap.get(sessionId);
|
|
485
|
+
if (slug)
|
|
486
|
+
counts.set(slug, (counts.get(slug) ?? 0) + 1);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
return counts;
|
|
490
|
+
}
|
|
459
491
|
/** Get session IDs that have active socket connections for a given project */
|
|
460
492
|
export function getJoinedSessionIdsByProject(projectSlug) {
|
|
461
493
|
const sessionIds = new Set();
|
|
@@ -566,6 +598,15 @@ function cleanupStream(streamKey, expectedStream) {
|
|
|
566
598
|
// Only delete from activeStreams and clean up socket mappings if the stream
|
|
567
599
|
// hasn't been replaced. When replaced, the new stream owns those resources.
|
|
568
600
|
if (!replaced) {
|
|
601
|
+
// Clear pending question state before removing the stream
|
|
602
|
+
if (current) {
|
|
603
|
+
for (const p of current.pendingPermissions.values()) {
|
|
604
|
+
if (p.interactionType === 'question') {
|
|
605
|
+
emitQuestionChange(streamKey, false);
|
|
606
|
+
break;
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
}
|
|
569
610
|
activeStreams.delete(streamKey);
|
|
570
611
|
for (const [sockId, sessId] of socketToSession.entries()) {
|
|
571
612
|
if (sessId === streamKey)
|
|
@@ -719,6 +760,17 @@ function emitStreamChange(sessionId, active, projectSlug) {
|
|
|
719
760
|
}
|
|
720
761
|
}
|
|
721
762
|
}
|
|
763
|
+
/**
|
|
764
|
+
* Emit session:question-change when an AskUserQuestion becomes pending or is resolved.
|
|
765
|
+
* Scoped to the project room so only relevant session list viewers receive it.
|
|
766
|
+
*/
|
|
767
|
+
function emitQuestionChange(sessionId, hasPendingQuestion) {
|
|
768
|
+
const projectSlug = sessionProjectMap.get(sessionId);
|
|
769
|
+
if (projectSlug) {
|
|
770
|
+
io.to(`project:${projectSlug}`).emit('session:question-change', { sessionId, hasPendingQuestion, projectSlug });
|
|
771
|
+
triggerDashboardStatusChange(projectSlug);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
722
774
|
/**
|
|
723
775
|
* Broadcast session:stream-change to project room (or all clients as fallback).
|
|
724
776
|
* Used by queue service to signal stream start/end.
|
|
@@ -1032,9 +1084,15 @@ export async function initializeWebSocket(httpServer) {
|
|
|
1032
1084
|
if (!sessionId)
|
|
1033
1085
|
return;
|
|
1034
1086
|
const stream = activeStreams.get(sessionId);
|
|
1035
|
-
if (stream
|
|
1036
|
-
|
|
1087
|
+
if (!stream)
|
|
1088
|
+
return;
|
|
1089
|
+
const pending = stream.pendingPermissions.get(data.requestId);
|
|
1090
|
+
if (pending) {
|
|
1091
|
+
const wasQuestion = pending.interactionType === 'question';
|
|
1092
|
+
pending.resolve({ approved: data.approved, response: data.response });
|
|
1037
1093
|
stream.pendingPermissions.delete(data.requestId);
|
|
1094
|
+
if (wasQuestion)
|
|
1095
|
+
emitQuestionChange(sessionId, sessionHasPendingQuestion(sessionId));
|
|
1038
1096
|
// Broadcast the actual resolution to all OTHER viewers so their
|
|
1039
1097
|
// tool/interactive cards can show the correct approve/deny state.
|
|
1040
1098
|
// Also buffer via createStreamEmit so reconnecting clients see the
|
|
@@ -1281,7 +1339,7 @@ export async function initializeWebSocket(httpServer) {
|
|
|
1281
1339
|
socket.emit('stream:history', { sessionId, messages: buf.messages });
|
|
1282
1340
|
}
|
|
1283
1341
|
socket.emit('stream:status', { active: true, sessionId, permissionMode: freshMode });
|
|
1284
|
-
socket.emit('stream:buffer-replay', { sessionId, events: [...freshStream.buffer] });
|
|
1342
|
+
socket.emit('stream:buffer-replay', { sessionId, events: [...freshStream.buffer], engineMode: freshStream.engineMode });
|
|
1285
1343
|
freshStream.sockets.add(socket);
|
|
1286
1344
|
return;
|
|
1287
1345
|
}
|
|
@@ -1297,7 +1355,7 @@ export async function initializeWebSocket(httpServer) {
|
|
|
1297
1355
|
socket.emit('stream:history', { sessionId, messages: buf.messages });
|
|
1298
1356
|
}
|
|
1299
1357
|
socket.emit('stream:status', { active: true, sessionId, permissionMode });
|
|
1300
|
-
socket.emit('stream:buffer-replay', { sessionId, events: [...completedStream.buffer] });
|
|
1358
|
+
socket.emit('stream:buffer-replay', { sessionId, events: [...completedStream.buffer], engineMode: completedStream.engineMode });
|
|
1301
1359
|
completedStream.sockets.add(socket);
|
|
1302
1360
|
return;
|
|
1303
1361
|
}
|
|
@@ -1368,7 +1426,7 @@ export async function initializeWebSocket(httpServer) {
|
|
|
1368
1426
|
}
|
|
1369
1427
|
socket.emit('stream:status', { active: true, sessionId, permissionMode });
|
|
1370
1428
|
// Replay raw event buffer so the client can build streaming segments
|
|
1371
|
-
socket.emit('stream:buffer-replay', { sessionId, events: [...stream.buffer] });
|
|
1429
|
+
socket.emit('stream:buffer-replay', { sessionId, events: [...stream.buffer], engineMode: stream.engineMode });
|
|
1372
1430
|
// NOW add to broadcast set — live events flow from here
|
|
1373
1431
|
stream.sockets.add(socket);
|
|
1374
1432
|
});
|
|
@@ -2522,6 +2580,7 @@ async function handleChatSend(stream, data, abortController, lang) {
|
|
|
2522
2580
|
const autoCompactEnabled = effectivePrefs.autoCompactEnabled ?? true;
|
|
2523
2581
|
const chatService = createChatEngine(engineMode, { workingDirectory, permissionMode, cliBinaryPath: effectivePrefs.cliBinaryPath, cliShowThinkingSummaries: effectivePrefs.cliShowThinkingSummaries, cliResumeChoice: effectivePrefs.cliResumeChoice, autoCompactEnabled, planModeBypassBehavior: effectivePrefs.planModeBypassBehavior });
|
|
2524
2582
|
stream.chatService = chatService;
|
|
2583
|
+
stream.engineMode = engineMode;
|
|
2525
2584
|
const effectiveEffort = clampEffortForModel(effort ?? effectivePrefs.defaultEffort, model);
|
|
2526
2585
|
// Opus 4.7+ flipped `thinking.display` default to 'omitted' — ThinkingBlock UI stays blank
|
|
2527
2586
|
// unless we explicitly opt in. For adaptive-thinking models, forward an explicit `thinking`
|
|
@@ -2546,6 +2605,7 @@ async function handleChatSend(stream, data, abortController, lang) {
|
|
|
2546
2605
|
: { images }),
|
|
2547
2606
|
// Advanced settings from preferences
|
|
2548
2607
|
customSystemPrompt: effectivePrefs.customSystemPrompt,
|
|
2608
|
+
displayName: effectivePrefs.displayName,
|
|
2549
2609
|
// maxThinkingTokens: legacy path; SDK docs say it takes precedence for backward-compat,
|
|
2550
2610
|
// which conflicts with adaptive mode on Opus 4.7+ (rejects enabled+budget). Skip on
|
|
2551
2611
|
// adaptive-capable models so the explicit `thinking` field governs.
|
|
@@ -2622,6 +2682,8 @@ async function handleChatSend(stream, data, abortController, lang) {
|
|
|
2622
2682
|
resolve,
|
|
2623
2683
|
interactionType: isAskUserQuestion ? 'question' : 'permission',
|
|
2624
2684
|
});
|
|
2685
|
+
if (isAskUserQuestion)
|
|
2686
|
+
emitQuestionChange(sessionIdRef.current || '', true);
|
|
2625
2687
|
});
|
|
2626
2688
|
if (isAskUserQuestion) {
|
|
2627
2689
|
const questions = input.questions;
|
|
@@ -2773,6 +2835,7 @@ async function handleChatSend(stream, data, abortController, lang) {
|
|
|
2773
2835
|
// slug resolution cannot disrupt the stream.
|
|
2774
2836
|
mcpRecorder: createMcpCallRecorder(() => projectService.findProjectByPath(workingDirectory).then((p) => p?.projectSlug)),
|
|
2775
2837
|
backgroundTracker,
|
|
2838
|
+
engineMode,
|
|
2776
2839
|
}, {
|
|
2777
2840
|
onCallbackActivity: (source) => resetTimeout(source),
|
|
2778
2841
|
onSessionIdResolved: (sid) => {
|