@rubytech/taskmaster 1.0.60 → 1.0.61

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.
@@ -6,7 +6,7 @@
6
6
  <title>Taskmaster Control</title>
7
7
  <meta name="color-scheme" content="dark light" />
8
8
  <link rel="icon" type="image/png" href="./favicon.png" />
9
- <script type="module" crossorigin src="./assets/index-Dlud-Ha4.js"></script>
9
+ <script type="module" crossorigin src="./assets/index-Sm-M_hDk.js"></script>
10
10
  <link rel="stylesheet" crossorigin href="./assets/index-wibL0JHX.css">
11
11
  </head>
12
12
  <body>
@@ -155,7 +155,18 @@ export const chatHandlers = {
155
155
  const max = Math.min(hardMax, requested);
156
156
  const sliced = rawMessages.length > max ? rawMessages.slice(-max) : rawMessages;
157
157
  const sanitized = stripEnvelopeFromMessages(sliced);
158
- const capped = capArrayByJsonBytes(sanitized, getMaxChatHistoryMessagesBytes()).items;
158
+ const { items: capped, bytes: cappedBytes } = capArrayByJsonBytes(sanitized, getMaxChatHistoryMessagesBytes());
159
+ // Diagnostic: log resolution details so we can trace "lost history" reports.
160
+ context.logGateway.info(`chat.history: sessionKey=${sessionKey} resolvedSessionId=${sessionId ?? "none"} storePath=${storePath ?? "none"} entryExists=${!!entry} rawMessages=${rawMessages.length} sliced=${sliced.length} capped=${capped.length} cappedBytes=${cappedBytes}`);
161
+ if (!entry) {
162
+ context.logGateway.warn(`chat.history: no session entry found for sessionKey=${sessionKey}`);
163
+ }
164
+ else if (!sessionId) {
165
+ context.logGateway.warn(`chat.history: sessionId resolved to undefined for sessionKey=${sessionKey} requestedSessionId=${requestedSessionId ?? "none"}`);
166
+ }
167
+ else if (rawMessages.length === 0) {
168
+ context.logGateway.warn(`chat.history: transcript empty or missing for sessionId=${sessionId} sessionFile=${sessionFile ?? "none"}`);
169
+ }
159
170
  // Thinking level comes from config (per-agent or global default), like model.
160
171
  const thinkingAgentId = resolveSessionAgentId({ sessionKey, config: cfg });
161
172
  const { provider: thinkProvider, model: thinkModel } = resolveSessionModelRef(cfg, entry, sessionKey);
@@ -208,7 +208,7 @@ async function readTranscriptTail(params) {
208
208
  }
209
209
  }
210
210
  export const sessionsTranscriptHandlers = {
211
- "sessions.transcript": async ({ params, respond }) => {
211
+ "sessions.transcript": async ({ params, respond, context }) => {
212
212
  if (!validateSessionsTranscriptParams(params)) {
213
213
  respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, `invalid sessions.transcript params: ${formatValidationErrors(validateSessionsTranscriptParams.errors)}`));
214
214
  return;
@@ -222,9 +222,13 @@ export const sessionsTranscriptHandlers = {
222
222
  try {
223
223
  const cfg = loadConfig();
224
224
  const { storePath, store } = loadCombinedSessionStoreForGateway(cfg);
225
+ const storeKeys = Object.keys(store);
225
226
  // Filter to sessions updated within last 24 hours
226
227
  const now = Date.now();
227
228
  const cutoff = now - ACTIVE_WINDOW_MS;
229
+ const staleKeys = Object.entries(store)
230
+ .filter(([, entry]) => (entry.updatedAt ?? 0) < cutoff)
231
+ .map(([key, entry]) => `${key}(${entry.updatedAt ?? 0})`);
228
232
  let activeSessions = Object.entries(store)
229
233
  .filter(([, entry]) => {
230
234
  const updatedAt = entry.updatedAt ?? 0;
@@ -239,6 +243,14 @@ export const sessionsTranscriptHandlers = {
239
243
  return agentFilter.has(agentId);
240
244
  });
241
245
  }
246
+ // Diagnostic: log store resolution so we can trace "missing session logs" reports.
247
+ context.logGateway.info(`sessions.transcript: storePath=${storePath} storeKeys=${storeKeys.length} active=${activeSessions.length} stale=${staleKeys.length} cutoffAge=24h`);
248
+ if (storeKeys.length === 0) {
249
+ context.logGateway.warn(`sessions.transcript: combined store is empty — no agents found or no session entries`);
250
+ }
251
+ else if (activeSessions.length === 0) {
252
+ context.logGateway.warn(`sessions.transcript: all ${storeKeys.length} sessions are stale (>24h): ${staleKeys.slice(0, 5).join(", ")}`);
253
+ }
242
254
  const allEntries = [];
243
255
  const cursors = {};
244
256
  const agentIds = new Set();
@@ -312,6 +324,9 @@ export const sessionsTranscriptHandlers = {
312
324
  });
313
325
  const entries = allEntries.slice(0, limit);
314
326
  const agents = Array.from(agentIds).sort();
327
+ if (allEntries.length === 0 && activeSessions.length > 0) {
328
+ context.logGateway.warn(`sessions.transcript: ${activeSessions.length} active session(s) but 0 transcript entries — files may be missing or unreadable`);
329
+ }
315
330
  respond(true, { entries, cursors, agents }, undefined);
316
331
  }
317
332
  catch (err) {
@@ -1,6 +1,6 @@
1
1
  import { loadConfig } from "../../config/config.js";
2
2
  import { resolveTaskmasterPackageRoot } from "../../infra/taskmaster-root.js";
3
- import { scheduleGatewaySigusr1Restart, triggerTaskmasterRestart, } from "../../infra/restart.js";
3
+ import { scheduleGatewaySigusr1Restart, triggerTaskmasterRestart } from "../../infra/restart.js";
4
4
  import { formatDoctorNonInteractiveHint, readRestartSentinel, writeRestartSentinel, } from "../../infra/restart-sentinel.js";
5
5
  import { checkUpdateStatus, compareSemverStrings } from "../../infra/update-check.js";
6
6
  import { normalizeUpdateChannel, resolveEffectiveUpdateChannel, } from "../../infra/update-channels.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubytech/taskmaster",
3
- "version": "1.0.60",
3
+ "version": "1.0.61",
4
4
  "description": "AI-powered business assistant for small businesses",
5
5
  "publishConfig": {
6
6
  "access": "public"