tycono 0.3.14-beta.21 → 0.3.14-beta.23

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tycono",
3
- "version": "0.3.14-beta.21",
3
+ "version": "0.3.14-beta.23",
4
4
  "description": "Build an AI company. Watch them work.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -35,7 +35,7 @@
35
35
  "cors": "^2.8.5",
36
36
  "dotenv": "^16.4.7",
37
37
  "express": "^5.0.1",
38
- "glob": "^11.0.1",
38
+ "glob": "^13.0.6",
39
39
  "gray-matter": "^4.0.3",
40
40
  "ink": "^5.2.1",
41
41
  "ink-select-input": "^6.2.0",
@@ -83,16 +83,8 @@ export function summarizeEvent(event: SSEEvent, allRoleIds: string[]): StreamLin
83
83
  }
84
84
 
85
85
  case 'thinking': {
86
- const text = ((event.data.text as string) ?? '').slice(0, 120);
87
- if (!text.trim()) return null;
88
- return {
89
- id: ++lineCounter,
90
- prefix: isSupervisor ? undefined : event.roleId,
91
- prefixColor: roleColor,
92
- text: `\uD83D\uDCAD ${text}`,
93
- color: 'gray',
94
- indent: !isSupervisor,
95
- };
86
+ // Hide thinking by default internal noise for user
87
+ return null;
96
88
  }
97
89
 
98
90
  case 'dispatch:start': {
@@ -130,17 +122,19 @@ export function summarizeEvent(event: SSEEvent, allRoleIds: string[]): StreamLin
130
122
 
131
123
  case 'tool:start': {
132
124
  const toolName = (event.data.name as string) ?? 'tool';
125
+ // Only show Write/Edit (file changes) + Bash (commands). Hide Read/Grep/Glob (noise).
126
+ const isWrite = ['Write', 'Edit', 'NotebookEdit'].includes(toolName);
127
+ const isBash = toolName === 'Bash';
128
+ if (!isWrite && !isBash) return null; // Hide read-only tools
129
+
133
130
  const input = event.data.input;
134
131
  let detail = '';
135
132
  if (input && typeof input === 'object') {
136
133
  const inp = input as Record<string, unknown>;
137
- if (inp.file_path) detail = ` ${String(inp.file_path)}`;
138
- else if (inp.command) detail = ` ${String(inp.command).slice(0, 80)}`;
139
- else if (inp.pattern) detail = ` ${String(inp.pattern)}`;
140
- else if (inp.description) detail = ` ${String(inp.description).slice(0, 60)}`;
134
+ if (inp.file_path) detail = ` ${String(inp.file_path).split('/').slice(-2).join('/')}`;
135
+ else if (inp.command) detail = ` ${String(inp.command).slice(0, 60)}`;
136
+ else if (inp.description) detail = ` ${String(inp.description).slice(0, 40)}`;
141
137
  }
142
- // Highlight file writes
143
- const isWrite = ['Write', 'Edit'].includes(toolName);
144
138
  return {
145
139
  id: ++lineCounter,
146
140
  prefix: isSupervisor ? undefined : event.roleId,
@@ -152,15 +146,8 @@ export function summarizeEvent(event: SSEEvent, allRoleIds: string[]): StreamLin
152
146
  }
153
147
 
154
148
  case 'tool:result': {
155
- const toolName = (event.data.name as string) ?? 'tool';
156
- return {
157
- id: ++lineCounter,
158
- prefix: isSupervisor ? undefined : event.roleId,
159
- prefixColor: roleColor,
160
- text: ` \u2190 ${toolName} done`,
161
- color: 'gray',
162
- indent: !isSupervisor,
163
- };
149
+ // Hide tool results tool:start is sufficient
150
+ return null;
164
151
  }
165
152
 
166
153
  case 'msg:start': {
@@ -421,10 +408,10 @@ export const CommandMode: React.FC<CommandModeProps> = ({
421
408
  const handleSubmit = useCallback((value: string) => {
422
409
  const trimmed = value.trim();
423
410
  if (trimmed) {
424
- // Show user input immediately in scrollback (before AI responds)
411
+ // Show user input with visual separator for emphasis
425
412
  setUserInputs(prev => [...prev.slice(-10), {
426
413
  id: ++lineCounter,
427
- text: `> ${trimmed}`,
414
+ text: `\u2501\u2501 > ${trimmed}`,
428
415
  color: 'green',
429
416
  }]);
430
417
  onSubmit(trimmed);
@@ -175,20 +175,24 @@ const PanelModeInner: React.FC<PanelModeProps> = ({
175
175
  })),
176
176
  ];
177
177
 
178
+ // Derive selectedRoleId from index (more reliable than prop — avoids sync issues)
179
+ const activeRoleId = flatRoles[selectedRoleIndex] ?? null;
180
+
178
181
  // === Build right column: Stream/Info/Docs ===
179
182
  const rightContentLines: string[] = [];
180
183
  let selectedDocPath: string | null = null;
181
184
  if (rightTab === 'stream') {
182
- const maxEv = Math.max(5, contentHeight - 2);
183
- const filtered = selectedRoleId ? events.filter(e => e.roleId === selectedRoleId) : events;
185
+ if (activeRoleId) rightContentLines.push(`\u25B8 ${activeRoleId}`);
186
+ const maxEv = Math.max(5, contentHeight - 3);
187
+ const filtered = activeRoleId ? events.filter(e => e.roleId === activeRoleId) : events;
184
188
  const visible = filtered.slice(-maxEv);
185
189
  for (const ev of visible) {
186
190
  const line = eventLine(ev);
187
191
  if (line) rightContentLines.push(line.slice(0, rightWidth));
188
192
  }
189
193
  if (rightContentLines.length === 0) {
190
- if (selectedRoleId && events.length > 0) {
191
- rightContentLines.push(`No events for ${selectedRoleId} (${events.length} total)`);
194
+ if (activeRoleId && events.length > 0) {
195
+ rightContentLines.push(`No events for ${activeRoleId} (${events.length} total)`);
192
196
  rightContentLines.push('Press Enter to show all roles');
193
197
  } else {
194
198
  rightContentLines.push(waveId ? `Waiting for events... (${events.length} in buffer)` : 'No active stream. Type a directive to start.');