@makefinks/daemon 0.3.0 → 0.3.1

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/package.json CHANGED
@@ -28,7 +28,7 @@
28
28
  },
29
29
  "module": "src/index.tsx",
30
30
  "type": "module",
31
- "version": "0.3.0",
31
+ "version": "0.3.1",
32
32
  "bin": {
33
33
  "daemon": "dist/cli.js"
34
34
  },
@@ -2,11 +2,12 @@
2
2
  * Component for rendering a single content block (reasoning, tool, or text).
3
3
  */
4
4
 
5
- import { DaemonText } from "./DaemonText";
6
- import { ToolCallView } from "./ToolCallView";
7
- import { COLORS, REASONING_MARKDOWN_STYLE } from "../ui/constants";
8
5
  import type { ContentBlock } from "../types";
6
+ import { COLORS, REASONING_MARKDOWN_STYLE } from "../ui/constants";
7
+ import { renderReasoningTicker } from "../ui/reasoning-ticker";
9
8
  import { formatElapsedTime, hasVisibleText } from "../utils/formatters";
9
+ import { DaemonText } from "./DaemonText";
10
+ import { ToolCallView } from "./ToolCallView";
10
11
 
11
12
  interface ContentBlockViewProps {
12
13
  block: ContentBlock;
@@ -64,14 +65,7 @@ export function ContentBlockView({
64
65
 
65
66
  // For non-full-reasoning mode, show animated display only for the latest reasoning block
66
67
  if (showReasoningTicker && isLastReasoningBlock && reasoningDisplay) {
67
- return (
68
- <text>
69
- <span fg={COLORS.REASONING_DIM}>
70
- {"// "}
71
- {reasoningDisplay}
72
- </span>
73
- </text>
74
- );
68
+ return renderReasoningTicker(reasoningDisplay);
75
69
  }
76
70
  const durationLabel =
77
71
  block.durationMs !== undefined
@@ -1,4 +1,4 @@
1
- import { useState, useEffect, useRef } from "react";
1
+ import { useEffect, useRef, useState } from "react";
2
2
  import { REASONING_ANIMATION } from "../ui/constants";
3
3
 
4
4
  export interface ReasoningState {
@@ -57,11 +57,16 @@ export function useReasoningAnimation(): UseReasoningAnimationReturn {
57
57
  const movedChars = queue.slice(0, charsToMove);
58
58
  const remainingQueue = queue.slice(charsToMove);
59
59
 
60
+ const terminalWidth =
61
+ typeof process !== "undefined" && process.stdout?.columns ? process.stdout.columns : undefined;
62
+ const maxWidth = terminalWidth ? Math.max(20, terminalWidth - 12) : REASONING_ANIMATION.LINE_WIDTH;
63
+ const lineWidth = Math.min(REASONING_ANIMATION.LINE_WIDTH, maxWidth);
64
+
60
65
  // Add to display, keeping it at max width by trimming from the left
61
66
  setReasoningDisplay((display: string) => {
62
67
  const newDisplay = display + movedChars;
63
- if (newDisplay.length > REASONING_ANIMATION.LINE_WIDTH) {
64
- return newDisplay.slice(-REASONING_ANIMATION.LINE_WIDTH);
68
+ if (newDisplay.length > lineWidth) {
69
+ return newDisplay.slice(-lineWidth);
65
70
  }
66
71
  return newDisplay;
67
72
  });
@@ -2,7 +2,7 @@
2
2
  * UI constants including colors, status text, and markdown syntax styles.
3
3
  */
4
4
 
5
- import { SyntaxStyle, RGBA } from "@opentui/core";
5
+ import { RGBA, SyntaxStyle } from "@opentui/core";
6
6
  import { DaemonState } from "../types";
7
7
 
8
8
  // Status text displayed for each daemon state
@@ -27,9 +27,11 @@ export const STATE_COLOR_HEX: Record<DaemonState, string> = {
27
27
 
28
28
  // Animation settings for reasoning text ticker
29
29
  export const REASONING_ANIMATION = {
30
- LINE_WIDTH: 120,
30
+ LINE_WIDTH: 200,
31
31
  CHARS_PER_TICK: 6,
32
- TICK_INTERVAL_MS: 16,
32
+ TICK_INTERVAL_MS: 12,
33
+ SEGMENT_LENGTH: 3,
34
+ PREFIX_COLOR: "#7a7a7a",
33
35
  INTENSITY: 0.5,
34
36
  } as const;
35
37
 
@@ -0,0 +1,38 @@
1
+ import { COLORS, REASONING_ANIMATION } from "./constants";
2
+
3
+ export function renderReasoningTicker(reasoningDisplay: string) {
4
+ const segmentLength = REASONING_ANIMATION.SEGMENT_LENGTH;
5
+ const segments: Array<{ text: string; color: string }> = [];
6
+ const segmentCount = Math.max(1, Math.ceil(reasoningDisplay.length / segmentLength));
7
+ for (let index = 0; index < segmentCount; index += 1) {
8
+ const start = index * segmentLength;
9
+ const text = reasoningDisplay.slice(start, start + segmentLength);
10
+ const normalized = segmentCount > 1 ? index / (segmentCount - 1) : 1;
11
+
12
+ let color: string = COLORS.REASONING_DIM;
13
+ if (normalized >= 0.9) {
14
+ color = "#b2a2e0";
15
+ } else if (normalized >= 0.75) {
16
+ color = "#9c8ac8";
17
+ } else if (normalized >= 0.6) {
18
+ color = "#8774b0";
19
+ } else if (normalized >= 0.45) {
20
+ color = "#725e98";
21
+ } else if (normalized >= 0.3) {
22
+ color = "#5e4a80";
23
+ }
24
+
25
+ segments.push({ text, color });
26
+ }
27
+
28
+ return (
29
+ <text>
30
+ <span fg={REASONING_ANIMATION.PREFIX_COLOR}>{"// "}</span>
31
+ {segments.map((segment, index) => (
32
+ <span fg={segment.color} key={`reasoning-seg-${index}`}>
33
+ {segment.text}
34
+ </span>
35
+ ))}
36
+ </text>
37
+ );
38
+ }