@townco/ui 0.1.44 → 0.1.46

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.
Files changed (34) hide show
  1. package/dist/core/hooks/use-chat-messages.d.ts +6 -0
  2. package/dist/core/hooks/use-chat-messages.js +22 -1
  3. package/dist/core/hooks/use-chat-session.js +19 -3
  4. package/dist/core/hooks/use-tool-calls.d.ts +6 -0
  5. package/dist/core/schemas/chat.d.ts +18 -0
  6. package/dist/core/schemas/tool-call.d.ts +9 -0
  7. package/dist/core/schemas/tool-call.js +9 -0
  8. package/dist/core/store/chat-store.d.ts +14 -0
  9. package/dist/core/store/chat-store.js +3 -0
  10. package/dist/gui/components/Button.d.ts +1 -1
  11. package/dist/gui/components/ChatView.js +29 -15
  12. package/dist/gui/components/ContextUsageButton.d.ts +11 -3
  13. package/dist/gui/components/ContextUsageButton.js +22 -3
  14. package/dist/gui/components/MessageContent.d.ts +5 -0
  15. package/dist/gui/components/MessageContent.js +2 -55
  16. package/dist/gui/components/ToolCall.js +1 -1
  17. package/dist/sdk/client/acp-client.d.ts +12 -0
  18. package/dist/sdk/client/acp-client.js +19 -0
  19. package/dist/sdk/schemas/message.d.ts +14 -2
  20. package/dist/sdk/schemas/message.js +16 -0
  21. package/dist/sdk/schemas/session.d.ts +19 -6
  22. package/dist/sdk/schemas/session.js +1 -0
  23. package/dist/sdk/transports/http.d.ts +8 -0
  24. package/dist/sdk/transports/http.js +79 -8
  25. package/dist/sdk/transports/stdio.d.ts +8 -0
  26. package/dist/sdk/transports/stdio.js +28 -0
  27. package/dist/sdk/transports/types.d.ts +12 -0
  28. package/dist/tui/components/ToolCall.js +1 -1
  29. package/package.json +3 -3
  30. package/src/styles/global.css +15 -0
  31. package/dist/core/lib/logger.d.ts +0 -59
  32. package/dist/core/lib/logger.js +0 -191
  33. package/dist/tui/components/LogsPanel.d.ts +0 -5
  34. package/dist/tui/components/LogsPanel.js +0 -29
@@ -13,9 +13,9 @@ export type MessageRole = z.infer<typeof MessageRole>;
13
13
  * Content type for messages
14
14
  */
15
15
  export declare const ContentType: z.ZodEnum<{
16
- file: "file";
17
16
  text: "text";
18
17
  image: "image";
18
+ file: "file";
19
19
  tool_call: "tool_call";
20
20
  tool_result: "tool_result";
21
21
  }>;
@@ -25,9 +25,9 @@ export type ContentType = z.infer<typeof ContentType>;
25
25
  */
26
26
  export declare const BaseContent: z.ZodObject<{
27
27
  type: z.ZodEnum<{
28
- file: "file";
29
28
  text: "text";
30
29
  image: "image";
30
+ file: "file";
31
31
  tool_call: "tool_call";
32
32
  tool_result: "tool_result";
33
33
  }>;
@@ -196,5 +196,17 @@ export declare const MessageChunk: z.ZodObject<{
196
196
  outputTokens: z.ZodOptional<z.ZodNumber>;
197
197
  totalTokens: z.ZodOptional<z.ZodNumber>;
198
198
  }, z.core.$strip>>;
199
+ contextInputTokens: z.ZodOptional<z.ZodNumber>;
200
+ _meta: z.ZodOptional<z.ZodObject<{
201
+ context_size: z.ZodOptional<z.ZodObject<{
202
+ systemPromptTokens: z.ZodNumber;
203
+ userMessagesTokens: z.ZodNumber;
204
+ assistantMessagesTokens: z.ZodNumber;
205
+ toolInputTokens: z.ZodNumber;
206
+ toolResultsTokens: z.ZodNumber;
207
+ totalEstimated: z.ZodNumber;
208
+ llmReportedInputTokens: z.ZodOptional<z.ZodNumber>;
209
+ }, z.core.$strip>>;
210
+ }, z.core.$strip>>;
199
211
  }, z.core.$strip>;
200
212
  export type MessageChunk = z.infer<typeof MessageChunk>;
@@ -99,4 +99,20 @@ export const MessageChunk = z.object({
99
99
  totalTokens: z.number().optional(),
100
100
  })
101
101
  .optional(),
102
+ contextInputTokens: z.number().optional(),
103
+ _meta: z
104
+ .object({
105
+ context_size: z
106
+ .object({
107
+ systemPromptTokens: z.number(),
108
+ userMessagesTokens: z.number(),
109
+ assistantMessagesTokens: z.number(),
110
+ toolInputTokens: z.number(),
111
+ toolResultsTokens: z.number(),
112
+ totalEstimated: z.number(),
113
+ llmReportedInputTokens: z.number().optional(),
114
+ })
115
+ .optional(),
116
+ })
117
+ .optional(),
102
118
  });
@@ -3,12 +3,12 @@ import { z } from "zod";
3
3
  * Session status
4
4
  */
5
5
  export declare const SessionStatus: z.ZodEnum<{
6
- error: "error";
7
6
  idle: "idle";
8
7
  connecting: "connecting";
9
8
  connected: "connected";
10
9
  active: "active";
11
10
  streaming: "streaming";
11
+ error: "error";
12
12
  disconnected: "disconnected";
13
13
  }>;
14
14
  export type SessionStatus = z.infer<typeof SessionStatus>;
@@ -40,12 +40,12 @@ export type SessionMetadata = z.infer<typeof SessionMetadata>;
40
40
  export declare const Session: z.ZodObject<{
41
41
  id: z.ZodString;
42
42
  status: z.ZodEnum<{
43
- error: "error";
44
43
  idle: "idle";
45
44
  connecting: "connecting";
46
45
  connected: "connected";
47
46
  active: "active";
48
47
  streaming: "streaming";
48
+ error: "error";
49
49
  disconnected: "disconnected";
50
50
  }>;
51
51
  config: z.ZodObject<{
@@ -108,12 +108,12 @@ export type Session = z.infer<typeof Session>;
108
108
  export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
109
109
  sessionId: z.ZodString;
110
110
  status: z.ZodOptional<z.ZodEnum<{
111
- error: "error";
112
111
  idle: "idle";
113
112
  connecting: "connecting";
114
113
  connected: "connected";
115
114
  active: "active";
116
115
  streaming: "streaming";
116
+ error: "error";
117
117
  disconnected: "disconnected";
118
118
  }>>;
119
119
  message: z.ZodOptional<z.ZodObject<{
@@ -154,6 +154,7 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
154
154
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
155
155
  }, z.core.$strip>>;
156
156
  error: z.ZodOptional<z.ZodString>;
157
+ _meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
157
158
  type: z.ZodLiteral<"tool_call">;
158
159
  toolCall: z.ZodObject<{
159
160
  id: z.ZodString;
@@ -212,17 +213,26 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
212
213
  outputTokens: z.ZodOptional<z.ZodNumber>;
213
214
  totalTokens: z.ZodOptional<z.ZodNumber>;
214
215
  }, z.core.$strip>>;
216
+ _meta: z.ZodOptional<z.ZodObject<{
217
+ truncationWarning: z.ZodOptional<z.ZodString>;
218
+ compactionAction: z.ZodOptional<z.ZodEnum<{
219
+ compacted: "compacted";
220
+ truncated: "truncated";
221
+ }>>;
222
+ originalTokens: z.ZodOptional<z.ZodNumber>;
223
+ finalTokens: z.ZodOptional<z.ZodNumber>;
224
+ }, z.core.$strip>>;
215
225
  }, z.core.$strip>;
216
226
  messageId: z.ZodOptional<z.ZodString>;
217
227
  }, z.core.$strip>, z.ZodObject<{
218
228
  sessionId: z.ZodString;
219
229
  status: z.ZodOptional<z.ZodEnum<{
220
- error: "error";
221
230
  idle: "idle";
222
231
  connecting: "connecting";
223
232
  connected: "connected";
224
233
  active: "active";
225
234
  streaming: "streaming";
235
+ error: "error";
226
236
  disconnected: "disconnected";
227
237
  }>>;
228
238
  message: z.ZodOptional<z.ZodObject<{
@@ -263,6 +273,7 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
263
273
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
264
274
  }, z.core.$strip>>;
265
275
  error: z.ZodOptional<z.ZodString>;
276
+ _meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
266
277
  type: z.ZodLiteral<"tool_call_update">;
267
278
  toolCallUpdate: z.ZodObject<{
268
279
  id: z.ZodString;
@@ -308,12 +319,12 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
308
319
  }, z.core.$strip>, z.ZodObject<{
309
320
  sessionId: z.ZodString;
310
321
  status: z.ZodOptional<z.ZodEnum<{
311
- error: "error";
312
322
  idle: "idle";
313
323
  connecting: "connecting";
314
324
  connected: "connected";
315
325
  active: "active";
316
326
  streaming: "streaming";
327
+ error: "error";
317
328
  disconnected: "disconnected";
318
329
  }>>;
319
330
  message: z.ZodOptional<z.ZodObject<{
@@ -354,6 +365,7 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
354
365
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
355
366
  }, z.core.$strip>>;
356
367
  error: z.ZodOptional<z.ZodString>;
368
+ _meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
357
369
  type: z.ZodLiteral<"tool_output">;
358
370
  toolOutput: z.ZodObject<{
359
371
  id: z.ZodString;
@@ -364,12 +376,12 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
364
376
  }, z.core.$strip>, z.ZodObject<{
365
377
  sessionId: z.ZodString;
366
378
  status: z.ZodOptional<z.ZodEnum<{
367
- error: "error";
368
379
  idle: "idle";
369
380
  connecting: "connecting";
370
381
  connected: "connected";
371
382
  active: "active";
372
383
  streaming: "streaming";
384
+ error: "error";
373
385
  disconnected: "disconnected";
374
386
  }>>;
375
387
  message: z.ZodOptional<z.ZodObject<{
@@ -410,6 +422,7 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
410
422
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
411
423
  }, z.core.$strip>>;
412
424
  error: z.ZodOptional<z.ZodString>;
425
+ _meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
413
426
  type: z.ZodOptional<z.ZodLiteral<"generic">>;
414
427
  }, z.core.$strip>]>;
415
428
  export type SessionUpdate = z.infer<typeof SessionUpdate>;
@@ -52,6 +52,7 @@ const BaseSessionUpdate = z.object({
52
52
  status: SessionStatus.optional(),
53
53
  message: Message.optional(),
54
54
  error: z.string().optional(),
55
+ _meta: z.record(z.string(), z.unknown()).optional(),
55
56
  });
56
57
  /**
57
58
  * Session update with tool call (sessionUpdate: "tool_call")
@@ -21,6 +21,7 @@ export declare class HttpTransport implements Transport {
21
21
  private options;
22
22
  private isReceivingMessages;
23
23
  private isInReplayMode;
24
+ private agentInfo?;
24
25
  constructor(options: HttpTransportOptions);
25
26
  connect(): Promise<void>;
26
27
  /**
@@ -34,6 +35,13 @@ export declare class HttpTransport implements Transport {
34
35
  isConnected(): boolean;
35
36
  onSessionUpdate(callback: (update: SessionUpdate) => void): () => void;
36
37
  onError(callback: (error: Error) => void): () => void;
38
+ getAgentInfo(): {
39
+ name?: string;
40
+ displayName?: string;
41
+ version?: string;
42
+ description?: string;
43
+ suggestedPrompts?: string[];
44
+ };
37
45
  /**
38
46
  * Send an ACP RPC request to the server
39
47
  */
@@ -22,6 +22,7 @@ export class HttpTransport {
22
22
  options;
23
23
  isReceivingMessages = false;
24
24
  isInReplayMode = false; // True during session replay, ignores non-replay streaming
25
+ agentInfo;
25
26
  constructor(options) {
26
27
  // Ensure baseUrl doesn't end with a slash
27
28
  this.options = { ...options, baseUrl: options.baseUrl.replace(/\/$/, "") };
@@ -43,6 +44,30 @@ export class HttpTransport {
43
44
  },
44
45
  };
45
46
  const initResponse = await this.sendRpcRequest("initialize", initRequest);
47
+ if (initResponse.agentInfo) {
48
+ // Read description and suggestedPrompts from _meta extension point (ACP protocol extension)
49
+ const description = initResponse._meta &&
50
+ typeof initResponse._meta === "object" &&
51
+ "agentDescription" in initResponse._meta
52
+ ? String(initResponse._meta.agentDescription)
53
+ : undefined;
54
+ const suggestedPrompts = initResponse._meta &&
55
+ typeof initResponse._meta === "object" &&
56
+ "suggestedPrompts" in initResponse._meta &&
57
+ Array.isArray(initResponse._meta.suggestedPrompts)
58
+ ? initResponse._meta.suggestedPrompts
59
+ : undefined;
60
+ this.agentInfo = {
61
+ name: initResponse.agentInfo.name,
62
+ // title is the ACP field for human-readable display name
63
+ ...(initResponse.agentInfo.title
64
+ ? { displayName: initResponse.agentInfo.title }
65
+ : {}),
66
+ version: initResponse.agentInfo.version,
67
+ ...(description ? { description } : {}),
68
+ ...(suggestedPrompts ? { suggestedPrompts } : {}),
69
+ };
70
+ }
46
71
  logger.info("ACP connection initialized", { initResponse });
47
72
  // Step 2: Create a new session
48
73
  const sessionRequest = {
@@ -89,6 +114,30 @@ export class HttpTransport {
89
114
  };
90
115
  logger.info("Loading session - initializing connection", { sessionId });
91
116
  const initResponse = await this.sendRpcRequest("initialize", initRequest);
117
+ if (initResponse.agentInfo) {
118
+ // Read description and suggestedPrompts from _meta extension point (ACP protocol extension)
119
+ const description = initResponse._meta &&
120
+ typeof initResponse._meta === "object" &&
121
+ "agentDescription" in initResponse._meta
122
+ ? String(initResponse._meta.agentDescription)
123
+ : undefined;
124
+ const suggestedPrompts = initResponse._meta &&
125
+ typeof initResponse._meta === "object" &&
126
+ "suggestedPrompts" in initResponse._meta &&
127
+ Array.isArray(initResponse._meta.suggestedPrompts)
128
+ ? initResponse._meta.suggestedPrompts
129
+ : undefined;
130
+ this.agentInfo = {
131
+ name: initResponse.agentInfo.name,
132
+ // title is the ACP field for human-readable display name
133
+ ...(initResponse.agentInfo.title
134
+ ? { displayName: initResponse.agentInfo.title }
135
+ : {}),
136
+ version: initResponse.agentInfo.version,
137
+ ...(description ? { description } : {}),
138
+ ...(suggestedPrompts ? { suggestedPrompts } : {}),
139
+ };
140
+ }
92
141
  // Check if loadSession is supported
93
142
  if (!initResponse.agentCapabilities?.loadSession) {
94
143
  logger.error("Agent does not support loading sessions", {
@@ -287,6 +336,9 @@ export class HttpTransport {
287
336
  this.errorCallbacks.delete(callback);
288
337
  };
289
338
  }
339
+ getAgentInfo() {
340
+ return this.agentInfo || {};
341
+ }
290
342
  /**
291
343
  * Send an ACP RPC request to the server
292
344
  */
@@ -759,18 +811,32 @@ export class HttpTransport {
759
811
  if (this.isInReplayMode && !isReplay) {
760
812
  return;
761
813
  }
762
- // Handle agent message chunks
763
- const sessionUpdate = {
764
- type: "generic",
765
- sessionId,
766
- status: "active",
767
- };
768
814
  // Extract token usage from _meta if present
769
815
  const tokenUsage = update._meta &&
770
816
  typeof update._meta === "object" &&
771
817
  "tokenUsage" in update._meta
772
818
  ? update._meta.tokenUsage
773
819
  : undefined;
820
+ // Extract context input tokens from _meta if present
821
+ const contextInputTokens = update._meta &&
822
+ typeof update._meta === "object" &&
823
+ "contextInputTokens" in update._meta &&
824
+ typeof update._meta.contextInputTokens === "number"
825
+ ? update._meta.contextInputTokens
826
+ : undefined;
827
+ // Extract context_size from _meta if present
828
+ const context_size = update._meta &&
829
+ typeof update._meta === "object" &&
830
+ "context_size" in update._meta
831
+ ? update._meta.context_size
832
+ : undefined;
833
+ // Handle agent message chunks
834
+ const sessionUpdate = {
835
+ type: "generic",
836
+ sessionId,
837
+ status: "active",
838
+ _meta: update._meta,
839
+ };
774
840
  // Queue message chunks if present (but skip during replay)
775
841
  // For agent_message_chunk, content is an object, not an array
776
842
  const content = update.content;
@@ -783,6 +849,8 @@ export class HttpTransport {
783
849
  role: "assistant",
784
850
  contentDelta: { type: "text", text: contentObj.text },
785
851
  tokenUsage,
852
+ contextInputTokens,
853
+ _meta: context_size ? { context_size } : undefined,
786
854
  isComplete: false,
787
855
  };
788
856
  }
@@ -824,8 +892,11 @@ export class HttpTransport {
824
892
  this.notifySessionUpdate(messageSessionUpdate);
825
893
  }
826
894
  }
827
- // Only send generic session update during live streaming (not replay)
828
- if (!isReplay) {
895
+ // Send session update for:
896
+ // 1. Live streaming (not replay)
897
+ // 2. Replay messages with context_size (need to restore context on session load)
898
+ const hasContextSize = sessionUpdate._meta && "context_size" in sessionUpdate._meta;
899
+ if (!isReplay || hasContextSize) {
829
900
  this.notifySessionUpdate(sessionUpdate);
830
901
  }
831
902
  }
@@ -15,6 +15,7 @@ export declare class StdioTransport implements Transport {
15
15
  private currentSessionId;
16
16
  private chunkResolvers;
17
17
  private streamComplete;
18
+ private agentInfo?;
18
19
  private originalConsole;
19
20
  constructor(options: StdioTransportOptions);
20
21
  connect(): Promise<void>;
@@ -24,6 +25,13 @@ export declare class StdioTransport implements Transport {
24
25
  isConnected(): boolean;
25
26
  onSessionUpdate(callback: (update: SessionUpdate) => void): () => void;
26
27
  onError(callback: (error: Error) => void): () => void;
28
+ getAgentInfo(): {
29
+ name?: string;
30
+ displayName?: string;
31
+ version?: string;
32
+ description?: string;
33
+ suggestedPrompts?: string[];
34
+ };
27
35
  private notifySessionUpdate;
28
36
  private notifyError;
29
37
  }
@@ -18,6 +18,7 @@ export class StdioTransport {
18
18
  currentSessionId = null;
19
19
  chunkResolvers = [];
20
20
  streamComplete = false;
21
+ agentInfo;
21
22
  originalConsole = null;
22
23
  constructor(options) {
23
24
  this.options = options;
@@ -353,6 +354,30 @@ export class StdioTransport {
353
354
  },
354
355
  },
355
356
  });
357
+ if (initResponse.agentInfo) {
358
+ // Read description and suggestedPrompts from _meta extension point (ACP protocol extension)
359
+ const description = initResponse._meta &&
360
+ typeof initResponse._meta === "object" &&
361
+ "agentDescription" in initResponse._meta
362
+ ? String(initResponse._meta.agentDescription)
363
+ : undefined;
364
+ const suggestedPrompts = initResponse._meta &&
365
+ typeof initResponse._meta === "object" &&
366
+ "suggestedPrompts" in initResponse._meta &&
367
+ Array.isArray(initResponse._meta.suggestedPrompts)
368
+ ? initResponse._meta.suggestedPrompts
369
+ : undefined;
370
+ this.agentInfo = {
371
+ name: initResponse.agentInfo.name,
372
+ // title is the ACP field for human-readable display name
373
+ ...(initResponse.agentInfo.title
374
+ ? { displayName: initResponse.agentInfo.title }
375
+ : {}),
376
+ version: initResponse.agentInfo.version,
377
+ ...(description ? { description } : {}),
378
+ ...(suggestedPrompts ? { suggestedPrompts } : {}),
379
+ };
380
+ }
356
381
  logger.info("ACP connection initialized", { initResponse });
357
382
  this.connected = true;
358
383
  }
@@ -511,6 +536,9 @@ export class StdioTransport {
511
536
  this.errorCallbacks.delete(callback);
512
537
  };
513
538
  }
539
+ getAgentInfo() {
540
+ return this.agentInfo || {};
541
+ }
514
542
  notifySessionUpdate(update) {
515
543
  for (const callback of this.sessionUpdateCallbacks) {
516
544
  try {
@@ -36,6 +36,18 @@ export interface Transport {
36
36
  * Subscribe to errors
37
37
  */
38
38
  onError(callback: (error: Error) => void): () => void;
39
+ /**
40
+ * Get agent information
41
+ * - displayName: Human-readable name for UI (from ACP title field)
42
+ * - name: Programmatic name (fallback if displayName not set)
43
+ */
44
+ getAgentInfo?(): {
45
+ name?: string;
46
+ displayName?: string;
47
+ version?: string;
48
+ description?: string;
49
+ suggestedPrompts?: string[];
50
+ };
39
51
  }
40
52
  /**
41
53
  * Stdio transport options
@@ -37,5 +37,5 @@ export function ToolCall({ toolCall }) {
37
37
  ? ((toolCall.tokenUsage.inputTokens / 1_000_000) * 3 +
38
38
  (toolCall.tokenUsage.outputTokens / 1_000_000) * 15).toFixed(4)
39
39
  : null;
40
- return (_jsxs(Box, { flexDirection: "row", gap: 1, children: [_jsx(Text, { color: statusColors[toolCall.status], children: statusIndicators[toolCall.status] }), _jsx(Text, { color: "cyan", bold: true, children: "[TOOL]" }), _jsx(Text, { children: toolCall.title }), startTime && (_jsxs(Text, { color: "gray", dimColor: true, children: ["| ", startTime] })), duration && (_jsxs(Text, { color: "gray", dimColor: true, children: ["| ", duration, "s"] })), cost && (_jsxs(Text, { color: "gray", dimColor: true, children: ["| $", cost] }))] }));
40
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { flexDirection: "row", gap: 1, children: [_jsx(Text, { color: statusColors[toolCall.status], children: statusIndicators[toolCall.status] }), _jsx(Text, { color: "cyan", bold: true, children: "[TOOL]" }), _jsx(Text, { children: toolCall.title }), startTime && (_jsxs(Text, { color: "gray", dimColor: true, children: ["| ", startTime] })), duration && (_jsxs(Text, { color: "gray", dimColor: true, children: ["| ", duration, "s"] })), cost && (_jsxs(Text, { color: "gray", dimColor: true, children: ["| $", cost] }))] }), toolCall._meta?.truncationWarning && (_jsx(Box, { marginLeft: 2, children: _jsxs(Text, { color: "yellow", bold: true, children: ["\u26A0\uFE0F ", toolCall._meta.truncationWarning] }) }))] }));
41
41
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@townco/ui",
3
- "version": "0.1.44",
3
+ "version": "0.1.46",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -40,7 +40,7 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@agentclientprotocol/sdk": "^0.5.1",
43
- "@townco/core": "0.0.22",
43
+ "@townco/core": "0.0.24",
44
44
  "@radix-ui/react-dialog": "^1.1.15",
45
45
  "@radix-ui/react-dropdown-menu": "^2.1.16",
46
46
  "@radix-ui/react-label": "^2.1.8",
@@ -63,7 +63,7 @@
63
63
  },
64
64
  "devDependencies": {
65
65
  "@tailwindcss/postcss": "^4.1.17",
66
- "@townco/tsconfig": "0.1.41",
66
+ "@townco/tsconfig": "0.1.43",
67
67
  "@types/node": "^24.10.0",
68
68
  "@types/react": "^19.2.2",
69
69
  "ink": "^6.4.0",
@@ -378,3 +378,18 @@
378
378
  transform: translateX(0);
379
379
  }
380
380
  }
381
+
382
+ @keyframes pulse-scale {
383
+ 0%, 100% {
384
+ transform: scale(1);
385
+ background-color: var(--color-neutral-500);
386
+ }
387
+ 50% {
388
+ transform: scale(.9);
389
+ background-color: var(--color-neutral-500);
390
+ }
391
+ }
392
+
393
+ .animate-pulse-scale {
394
+ animation: pulse-scale 1s ease-in-out infinite;
395
+ }
@@ -1,59 +0,0 @@
1
- /**
2
- * Browser-compatible logger
3
- * Outputs structured JSON logs to console with color-coding
4
- * Also captures logs to a global store for in-app viewing
5
- * In Node.js environment with logsDir option, also writes to .logs/ directory
6
- */
7
- export type LogLevel = "trace" | "debug" | "info" | "warn" | "error" | "fatal";
8
- export interface LogEntry {
9
- id: string;
10
- timestamp: string;
11
- level: LogLevel;
12
- service: string;
13
- message: string;
14
- metadata?: Record<string, unknown>;
15
- }
16
- /**
17
- * Get all captured logs
18
- */
19
- export declare function getCapturedLogs(): LogEntry[];
20
- /**
21
- * Clear all captured logs
22
- */
23
- export declare function clearCapturedLogs(): void;
24
- /**
25
- * Subscribe to log updates
26
- */
27
- type LogSubscriber = (entry: LogEntry) => void;
28
- export declare function subscribeToLogs(callback: LogSubscriber): () => void;
29
- /**
30
- * Configure global logs directory for file writing
31
- * Must be called before creating any loggers (typically at TUI startup)
32
- */
33
- export declare function configureLogsDir(logsDir: string): void;
34
- export declare class Logger {
35
- private service;
36
- private minLevel;
37
- private logFilePath?;
38
- private logsDir?;
39
- private writeQueue;
40
- private isWriting;
41
- constructor(service: string, minLevel?: LogLevel);
42
- private setupFileLogging;
43
- private writeToFile;
44
- private shouldLog;
45
- private log;
46
- trace(message: string, metadata?: Record<string, unknown>): void;
47
- debug(message: string, metadata?: Record<string, unknown>): void;
48
- info(message: string, metadata?: Record<string, unknown>): void;
49
- warn(message: string, metadata?: Record<string, unknown>): void;
50
- error(message: string, metadata?: Record<string, unknown>): void;
51
- fatal(message: string, metadata?: Record<string, unknown>): void;
52
- }
53
- /**
54
- * Create a logger instance for a service
55
- * @param service - Service name (e.g., "gui", "http-agent", "tui")
56
- * @param minLevel - Minimum log level to display (default: "debug")
57
- */
58
- export declare function createLogger(service: string, minLevel?: LogLevel): Logger;
59
- export {};