@blockrun/franklin 3.16.3 → 3.16.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.
@@ -233,7 +233,7 @@ const DIRECT_COMMANDS = {
233
233
  ` **Coding:** /commit /review /test /fix /debug /explain /search /find /refactor /scaffold\n` +
234
234
  ` **Git:** /push /pr /undo /status /diff /log /branch /stash /unstash\n` +
235
235
  ` **Analysis:** /security /lint /optimize /todo /deps /clean /migrate /doc\n` +
236
- ` **Session:** /plan /ultraplan /execute /compact /retry /sessions /resume /session-search /context /tasks\n` +
236
+ ` **Session:** /plan /ultraplan /execute /compact /retry /sessions /resume /session-search /context /tasks /history /transcript\n` +
237
237
  ` **Power:** /ultrathink [query] /ultraplan /noplan /moa [query] /dump\n` +
238
238
  ` **Info:** /model /auto /wallet /cost /tokens /learnings /brain /mcp /doctor /version /bug /help\n` +
239
239
  ` **UI:** /clear /exit\n` +
@@ -259,6 +259,53 @@ const DIRECT_COMMANDS = {
259
259
  }
260
260
  }
261
261
  output += 'Use `/delete <number>` to remove exchanges (e.g., `/delete 2` or `/delete 3-5`).\n';
262
+ output += 'Use `/transcript` for the full, un-truncated transcript.\n';
263
+ ctx.onEvent({ kind: 'text_delta', text: output });
264
+ emitDone(ctx);
265
+ },
266
+ '/transcript': (ctx) => {
267
+ // Dump the FULL, un-truncated conversation as a single fresh stdout
268
+ // block. Works around the limitation that the terminal's native
269
+ // scrollback fills up faster than we can render long Franklin sessions
270
+ // — by the time you scroll up to look for the first message, the
271
+ // older Ink output has been pushed out of the terminal's ring buffer.
272
+ // The fresh emit here becomes one contiguous block, so the user can
273
+ // scroll *that* to read everything in order.
274
+ const { history, config } = ctx;
275
+ const modelName = config.model.split('/').pop() || config.model;
276
+ const exchanges = buildExchanges(history);
277
+ if (exchanges.length === 0) {
278
+ ctx.onEvent({ kind: 'text_delta', text: 'No history in the current session yet.\n' });
279
+ emitDone(ctx);
280
+ return;
281
+ }
282
+ let output = `**Full Transcript** — ${exchanges.length} exchange${exchanges.length === 1 ? '' : 's'}, session \`${ctx.sessionId}\`\n\n`;
283
+ output += '─'.repeat(70) + '\n\n';
284
+ for (let i = 0; i < exchanges.length; i++) {
285
+ const ex = exchanges[i];
286
+ // Re-read full text from raw history (buildExchanges truncated).
287
+ const userMsg = history[ex.startIdx];
288
+ const fullUser = extractText(userMsg);
289
+ // Find first assistant text in this exchange (full, not truncated).
290
+ let fullAssistant = '';
291
+ for (let j = ex.startIdx + 1; j <= ex.endIdx; j++) {
292
+ const m = history[j];
293
+ if (m.role === 'assistant') {
294
+ const t = extractText(m);
295
+ if (t && !fullAssistant)
296
+ fullAssistant = t;
297
+ }
298
+ }
299
+ output += `❯ [${i + 1}] ${fullUser}\n\n`;
300
+ if (fullAssistant)
301
+ output += `${fullAssistant}\n`;
302
+ if (ex.toolNames.length > 0) {
303
+ output += `\n _tools: ${ex.toolNames.join(', ')}_\n`;
304
+ }
305
+ output += `\n[${modelName}]\n\n`;
306
+ output += '─'.repeat(70) + '\n\n';
307
+ }
308
+ output += `End of transcript — ${history.length} raw messages, ${exchanges.length} user/assistant exchanges.\n`;
262
309
  ctx.onEvent({ kind: 'text_delta', text: output });
263
310
  emitDone(ctx);
264
311
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blockrun/franklin",
3
- "version": "3.16.3",
3
+ "version": "3.16.4",
4
4
  "description": "Franklin Agent — The AI agent with a wallet. Spends USDC autonomously to get real work done. Pay per action, no subscriptions.",
5
5
  "type": "module",
6
6
  "exports": {