total-recall-brain 3.41.4 → 3.41.6

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 (147) hide show
  1. package/bin/total-recall.mjs +10 -6
  2. package/docs/reference/cli-reference.md +18 -0
  3. package/frontend/dist/assets/index-4tGQfTa2.js +5605 -0
  4. package/frontend/dist/assets/index-DtwsDyFM.css +1 -0
  5. package/frontend/dist/index.html +2 -2
  6. package/frontend/package.json +11 -0
  7. package/frontend/src/App.tsx +47 -122
  8. package/frontend/src/components/plugins/plugin-frame.ts +1 -0
  9. package/frontend/src/index.css +152 -86
  10. package/frontend/src/pages/HelpPage.tsx +13 -10
  11. package/frontend/src/pages/MemoryPage.tsx +28 -30
  12. package/frontend/src/pages/NetworkPage.tsx +3 -3
  13. package/frontend/src/pages/PluginsPage.tsx +6 -5
  14. package/frontend/src/pages/RulesPage.tsx +16 -12
  15. package/package.json +4 -3
  16. package/scaffold/.agent/skills/total-recall/plugins/code-quality/package-lock.json +3114 -36
  17. package/scaffold/.agent/skills/total-recall/plugins/code-quality/package.json +4 -1
  18. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package-lock.json +3114 -36
  19. package/scaffold/.agent/skills/total-recall/plugins/composable-cli/package.json +4 -1
  20. package/scaffold/.agent/skills/total-recall/plugins/embeddings/package-lock.json +3121 -33
  21. package/scaffold/.agent/skills/total-recall/plugins/embeddings/package.json +4 -1
  22. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/package-lock.json +3122 -34
  23. package/scaffold/.agent/skills/total-recall/plugins/git-sentinel/package.json +4 -1
  24. package/scaffold/.agent/skills/total-recall/plugins/mesh/package-lock.json +3127 -49
  25. package/scaffold/.agent/skills/total-recall/plugins/mesh/package.json +5 -2
  26. package/scaffold/.agent/skills/total-recall/plugins/mesh/src/core/mesh.mjs +1 -1
  27. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/capability/index.mjs +136 -7
  28. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/cli.mjs +135 -26
  29. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package-lock.json +3121 -33
  30. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/package.json +5 -2
  31. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/plugin.json +228 -9
  32. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/skills/meta-harness/SKILL.md +24 -30
  33. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/alerts.mjs +29 -16
  34. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/cascade.mjs +73 -0
  35. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/coordinator.mjs +182 -365
  36. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/dispatch.mjs +33 -0
  37. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/documentation.mjs +40 -14
  38. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/executor.mjs +4 -4
  39. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/agy.mjs +187 -0
  40. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/claude.mjs +275 -0
  41. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/cline.mjs +132 -0
  42. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/codex.mjs +187 -0
  43. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/cursor.mjs +158 -0
  44. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/devin.mjs +157 -0
  45. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/dsh.mjs +183 -0
  46. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/grok.mjs +132 -0
  47. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/hermes.mjs +173 -0
  48. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/index.mjs +87 -0
  49. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/openclaw.mjs +173 -0
  50. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate-adapters/pi.mjs +129 -0
  51. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/gate.mjs +12 -0
  52. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/json-reply.mjs +22 -0
  53. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/learner.mjs +72 -70
  54. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/model-catalog.mjs +195 -0
  55. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/paths.mjs +11 -0
  56. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/pool.mjs +36 -0
  57. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/review.mjs +169 -0
  58. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/router.mjs +136 -346
  59. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/runtime.mjs +1 -1
  60. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/ssss-store.mjs +20 -0
  61. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/telemetry.mjs +43 -0
  62. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/threads.mjs +156 -0
  63. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/worker.mjs +117 -35
  64. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/src/worktree.mjs +51 -0
  65. package/scaffold/.agent/skills/total-recall/plugins/meta-harness/ui/card.js +398 -57
  66. package/scaffold/.agent/skills/total-recall/plugins/openwiki/cli.mjs +304 -46
  67. package/scaffold/.agent/skills/total-recall/plugins/openwiki/package-lock.json +367 -41
  68. package/scaffold/.agent/skills/total-recall/plugins/openwiki/package.json +5 -2
  69. package/scaffold/.agent/skills/total-recall/plugins/openwiki/plugin.json +33 -0
  70. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/config.mjs +2 -2
  71. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/generate.mjs +159 -0
  72. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/graph.mjs +197 -0
  73. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/lint.mjs +153 -0
  74. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/mesh-vaults.mjs +261 -0
  75. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/refresh.mjs +151 -4
  76. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/search.mjs +114 -0
  77. package/scaffold/.agent/skills/total-recall/plugins/openwiki/src/token.mjs +96 -0
  78. package/scaffold/.agent/skills/total-recall/plugins/openwiki/ui/card.js +899 -662
  79. package/scaffold/.agent/skills/total-recall/plugins/openwiki/vendor/openwiki.mjs +8987 -0
  80. package/scaffold/.agent/skills/total-recall/plugins/openwiki/vendor/skills/mermaid-diagrams/SKILL.md +44 -0
  81. package/scaffold/.agent/skills/total-recall/plugins/openwiki/vendor/skills/write-connector/SKILL.md +56 -0
  82. package/scaffold/.agent/skills/total-recall/plugins/security/package-lock.json +3097 -81
  83. package/scaffold/.agent/skills/total-recall/plugins/security/package.json +4 -1
  84. package/src/cli/agent.mjs +12 -1
  85. package/src/cli/compact.mjs +108 -0
  86. package/src/cli/connect.mjs +56 -1
  87. package/src/cli/context.mjs +55 -23
  88. package/src/cli/doctor.mjs +5 -2
  89. package/src/cli/forget.mjs +2 -0
  90. package/src/cli/harness.mjs +62 -50
  91. package/src/cli/memory-entry.mjs +2 -2
  92. package/src/cli/preflight.mjs +152 -16
  93. package/src/cli/release.mjs +386 -0
  94. package/src/cli/remember.mjs +19 -1
  95. package/src/cli/rules.mjs +54 -12
  96. package/src/cli/startup.mjs +1 -1
  97. package/src/cli/status.mjs +12 -2
  98. package/src/core/claude-hooks.mjs +41 -3
  99. package/src/core/cli-commands.mjs +2 -0
  100. package/src/core/cli-semantic-index.mjs +3 -2
  101. package/src/core/conflict-detector.mjs +23 -12
  102. package/src/core/context-compactor.mjs +145 -0
  103. package/src/core/context-policy.mjs +20 -0
  104. package/src/core/duplicate-guard.mjs +350 -0
  105. package/src/core/meta-harness.mjs +31 -11
  106. package/src/core/preflight-gate.mjs +2 -2
  107. package/src/core/preflight-receipt.mjs +29 -1
  108. package/src/core/scaffold-plugins.mjs +7 -0
  109. package/src/core/stdio-flush.mjs +23 -0
  110. package/src/core/surface.mjs +33 -10
  111. package/src/server/invoke-durability.mjs +39 -0
  112. package/src/server/invoke-write-child.mjs +25 -0
  113. package/src/server/routes/invoke.mjs +7 -0
  114. package/src/server/routes/plugins.mjs +2 -2
  115. package/frontend/dist/assets/index-BIQmqDKP.css +0 -1
  116. package/frontend/dist/assets/index-CRzjQLu7.js +0 -5631
  117. package/frontend/src/components/DaemonLogsTab.tsx +0 -54
  118. package/frontend/src/components/ResearchAgendaTab.tsx +0 -712
  119. package/frontend/src/components/TaskQueueTab.tsx +0 -193
  120. package/frontend/src/components/VoiceInput.tsx +0 -112
  121. package/frontend/src/pages/ChatPage.tsx +0 -1059
  122. package/frontend/src/pages/CollabPage.tsx +0 -470
  123. package/frontend/src/pages/DesignDocsPage.tsx +0 -621
  124. package/frontend/src/pages/FilesPage.tsx +0 -393
  125. package/frontend/src/pages/HealthPage.tsx +0 -359
  126. package/frontend/src/pages/InboxPage.tsx +0 -83
  127. package/frontend/src/pages/InstructionsPage.tsx +0 -583
  128. package/frontend/src/pages/IntegrationsPage.tsx +0 -761
  129. package/frontend/src/pages/MeshPage.css +0 -58
  130. package/frontend/src/pages/MeshPage.tsx +0 -1219
  131. package/frontend/src/pages/OkfPage.tsx +0 -535
  132. package/frontend/src/pages/SandboxPage.tsx +0 -113
  133. package/frontend/src/pages/SkillsPage.tsx +0 -1994
  134. package/frontend/src/pages/TasksPage.tsx +0 -427
  135. package/frontend/src/pages/UsagePage.tsx +0 -702
  136. package/scaffold/.agent/skills/total-recall/plugins/cli-agents/README.md +0 -65
  137. package/scaffold/.agent/skills/total-recall/plugins/cli-agents/cli.mjs +0 -76
  138. package/scaffold/.agent/skills/total-recall/plugins/cli-agents/package.json +0 -19
  139. package/scaffold/.agent/skills/total-recall/plugins/cli-agents/plugin.json +0 -266
  140. package/scaffold/.agent/skills/total-recall/plugins/cli-agents/src/adapters/dsh.mjs +0 -446
  141. package/scaffold/.agent/skills/total-recall/plugins/cli-agents/src/documentation.mjs +0 -152
  142. package/scaffold/.agent/skills/total-recall/plugins/cli-agents/src/executor.mjs +0 -71
  143. package/scaffold/.agent/skills/total-recall/plugins/cli-agents/src/runtime.mjs +0 -36
  144. package/scaffold/.agent/skills/total-recall/plugins/cli-agents/src/setup.mjs +0 -35
  145. package/scaffold/.agent/skills/total-recall/plugins/cli-agents/src/worker.mjs +0 -175
  146. package/scaffold/.agent/skills/total-recall/plugins/cli-agents/ui/DESIGN.md +0 -32
  147. package/scaffold/.agent/skills/total-recall/plugins/cli-agents/ui/card.js +0 -575
@@ -1,193 +0,0 @@
1
- import React from 'react'
2
- import type { Task } from '../types'
3
-
4
- interface TaskQueueTabProps {
5
- tasks: Task[]
6
- loading: boolean
7
- showTaskForm: boolean
8
- setShowTaskForm: (v: boolean) => void
9
- taskCategory: string
10
- setTaskCategory: (v: string) => void
11
- taskTarget: string
12
- setTaskTarget: (v: string) => void
13
- taskBody: string
14
- setTaskBody: (v: string) => void
15
- taskSubmitting: boolean
16
- handleCreateTask: (e: React.FormEvent) => void
17
- }
18
-
19
- export default function TaskQueueTab(props: TaskQueueTabProps) {
20
- const {
21
- tasks,
22
- loading,
23
- showTaskForm,
24
- setShowTaskForm,
25
- taskCategory,
26
- setTaskCategory,
27
- taskTarget,
28
- setTaskTarget,
29
- taskBody,
30
- setTaskBody,
31
- taskSubmitting,
32
- handleCreateTask,
33
- } = props
34
-
35
- return (
36
- <div>
37
- <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 }}>
38
- <h3 style={{ margin: 0 }}>Active Scheduler Tasks</h3>
39
- <button
40
- className="btn btn-sm btn-ghost"
41
- onClick={() => setShowTaskForm(!showTaskForm)}
42
- style={{ borderColor: 'var(--border)' }}
43
- >
44
- {showTaskForm ? 'Cancel' : '+ Add Custom Task'}
45
- </button>
46
- </div>
47
-
48
- {/* Collapsible Task Form */}
49
- {showTaskForm && (
50
- <form onSubmit={handleCreateTask} style={{
51
- background: 'var(--bg-secondary)',
52
- border: '1px solid var(--border)',
53
- borderRadius: 12,
54
- padding: 20,
55
- marginBottom: 20,
56
- display: 'flex',
57
- flexDirection: 'column',
58
- gap: 12
59
- }}>
60
- <div style={{ display: 'grid', gridTemplateColumns: '1fr 2fr', gap: 16 }}>
61
- <label style={{ display: 'flex', flexDirection: 'column', gap: 6, fontSize: 12, color: 'var(--text-secondary)' }}>
62
- Subsystem Category
63
- <select
64
- value={taskCategory}
65
- onChange={e => setTaskCategory(e.target.value)}
66
- style={{
67
- padding: '8px 10px',
68
- borderRadius: 8,
69
- background: 'var(--bg-primary)',
70
- color: 'var(--text-primary)',
71
- border: '1px solid var(--border)',
72
- outline: 'none'
73
- }}
74
- >
75
- <option value="fact-seeker">Fact Seeker</option>
76
- <option value="post-mortem-daily">Post Mortem Daemon</option>
77
- <option value="clarity-rewriter">Clarity Rewriter</option>
78
- <option value="drift-detector">Drift Detector</option>
79
- <option value="dream">Dream Cycle</option>
80
- </select>
81
- </label>
82
- <label style={{ display: 'flex', flexDirection: 'column', gap: 6, fontSize: 12, color: 'var(--text-secondary)' }}>
83
- Target Operation / Description
84
- <input
85
- type="text"
86
- required
87
- placeholder="e.g. Audit security.yml files for weak encryption configs"
88
- value={taskTarget}
89
- onChange={e => setTaskTarget(e.target.value)}
90
- style={{
91
- padding: '8px 10px',
92
- borderRadius: 8,
93
- background: 'var(--bg-primary)',
94
- color: 'var(--text-primary)',
95
- border: '1px solid var(--border)',
96
- outline: 'none'
97
- }}
98
- />
99
- </label>
100
- </div>
101
- <label style={{ display: 'flex', flexDirection: 'column', gap: 6, fontSize: 12, color: 'var(--text-secondary)' }}>
102
- Verification Payload Body (Optional Markdown)
103
- <textarea
104
- placeholder="Additional context or markdown checklist rules..."
105
- value={taskBody}
106
- onChange={e => setTaskBody(e.target.value)}
107
- style={{
108
- padding: '10px',
109
- borderRadius: 8,
110
- background: 'var(--bg-primary)',
111
- color: 'var(--text-primary)',
112
- border: '1px solid var(--border)',
113
- outline: 'none',
114
- minHeight: 80,
115
- resize: 'vertical'
116
- }}
117
- />
118
- </label>
119
- <button
120
- type="submit"
121
- className="btn btn-primary"
122
- disabled={taskSubmitting || !taskTarget.trim()}
123
- style={{ alignSelf: 'flex-end', minWidth: 120 }}
124
- >
125
- {taskSubmitting ? 'Enqueuing...' : 'Create Task'}
126
- </button>
127
- </form>
128
- )}
129
-
130
- {/* Tasks Grid */}
131
- <div className="card-grid" style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
132
- {loading && tasks.length === 0 ? (
133
- [1, 2, 3].map(i => <div key={i} className="skeleton" style={{ height: 68 }} />)
134
- ) : tasks.length === 0 ? (
135
- <div style={{
136
- textAlign: 'center',
137
- padding: '50px 20px',
138
- color: 'var(--text-tertiary)',
139
- border: '1px dashed var(--border)',
140
- borderRadius: 12
141
- }}>
142
- No tasks are currently running.
143
- <br />
144
- <span style={{ fontSize: 12 }}>Click <strong>Seed Gaps</strong> above to trigger autonomous background schedules.</span>
145
- </div>
146
- ) : (
147
- tasks.map(t => (
148
- <div key={t.slug} className="card" style={{
149
- padding: '16px 20px',
150
- display: 'flex',
151
- justifyContent: 'space-between',
152
- alignItems: 'center',
153
- background: 'var(--bg-secondary)',
154
- border: '1px solid var(--border)',
155
- borderRadius: 12
156
- }}>
157
- <div style={{ flex: 1, marginRight: 16 }}>
158
- <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
159
- <span className={`badge ${
160
- t.category.includes('clarity') ? 'badge-primary' :
161
- t.category.includes('post-mortem') ? 'badge-error' :
162
- 'badge-accent'
163
- }`} style={{ fontSize: 11, display: 'flex', alignItems: 'center', gap: 4 }}>
164
- {t.category.includes('clarity') && <span>✨</span>}
165
- {t.category.includes('post-mortem') && <span>💀</span>}
166
- {t.category}
167
- </span>
168
- <h4 style={{ margin: 0, fontSize: 14, fontWeight: 600 }}>{t.target}</h4>
169
- </div>
170
- {t.body && (
171
- <p style={{ margin: '6px 0 0', fontSize: 12, color: 'var(--text-secondary)', lineBreak: 'anywhere' }}>
172
- {t.body}
173
- </p>
174
- )}
175
- <div style={{ display: 'flex', gap: 16, marginTop: 8, fontSize: 11, color: 'var(--text-tertiary)' }}>
176
- <span>Ref: <code>{t.slug}</code></span>
177
- <span>Priority Weight: {t.priority}</span>
178
- </div>
179
- </div>
180
- <span className={`badge ${
181
- t.status === 'completed' ? 'badge-success' :
182
- t.status === 'failed' ? 'badge-error' :
183
- 'badge-warning'
184
- }`} style={{ textTransform: 'capitalize', minWidth: 80, textAlign: 'center' }}>
185
- {t.status}
186
- </span>
187
- </div>
188
- ))
189
- )}
190
- </div>
191
- </div>
192
- )
193
- }
@@ -1,112 +0,0 @@
1
- import { useState, useRef, useEffect } from 'react';
2
-
3
- interface VoiceInputProps {
4
- onTranscript: (text: string) => void;
5
- isRecording?: boolean;
6
- }
7
-
8
- interface SpeechRecognitionObj {
9
- continuous: boolean;
10
- interimResults: boolean;
11
- onresult: ((event: { results: { transcript: string }[][] }) => void) | null;
12
- onerror: (() => void) | null;
13
- onend: (() => void) | null;
14
- start: () => void;
15
- stop: () => void;
16
- }
17
-
18
- interface SpeechRecognitionConstructor {
19
- new (): SpeechRecognitionObj;
20
- }
21
-
22
- export function VoiceInput({ onTranscript, isRecording = false }: VoiceInputProps) {
23
- const [recording, setRecording] = useState(isRecording);
24
- const recognitionRef = useRef<SpeechRecognitionObj | null>(null);
25
- const [supported, setSupported] = useState(true);
26
-
27
- useEffect(() => {
28
- if (typeof window !== 'undefined') {
29
- const win = window as unknown as { SpeechRecognition?: SpeechRecognitionConstructor, webkitSpeechRecognition?: SpeechRecognitionConstructor };
30
- const SpeechRecognition = win.SpeechRecognition || win.webkitSpeechRecognition;
31
- if (SpeechRecognition) {
32
- recognitionRef.current = new SpeechRecognition();
33
- recognitionRef.current.continuous = false;
34
- recognitionRef.current.interimResults = false;
35
-
36
- recognitionRef.current.onresult = (event) => {
37
- const transcript = event.results[0][0].transcript;
38
- onTranscript(transcript);
39
- setRecording(false);
40
- };
41
-
42
- recognitionRef.current.onerror = () => {
43
- setRecording(false);
44
- };
45
-
46
- recognitionRef.current.onend = () => {
47
- setRecording(false);
48
- };
49
- } else {
50
- setTimeout(() => setSupported(false), 0);
51
- }
52
- }
53
- }, [onTranscript]);
54
-
55
- const toggleRecording = () => {
56
- if (!supported) return;
57
- if (recording) {
58
- recognitionRef.current?.stop();
59
- setRecording(false);
60
- } else {
61
- recognitionRef.current?.start();
62
- setRecording(true);
63
- }
64
- };
65
-
66
- if (!supported) {
67
- return (
68
- <button
69
- disabled
70
- className="btn btn-ghost"
71
- style={{
72
- width: 44,
73
- height: 44,
74
- padding: 0,
75
- display: 'flex',
76
- justifyContent: 'center',
77
- alignItems: 'center',
78
- background: 'rgba(148, 163, 184, 0.03)',
79
- border: '1px solid var(--border)',
80
- color: 'var(--text-tertiary)',
81
- opacity: 0.5,
82
- cursor: 'not-allowed'
83
- }}
84
- title="Voice input not supported"
85
- >
86
- <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><line x1="12" x2="12" y1="19" y2="22"/></svg>
87
- </button>
88
- );
89
- }
90
-
91
- return (
92
- <button
93
- onClick={toggleRecording}
94
- className={`btn btn-ghost ${recording ? 'active' : ''}`}
95
- style={{
96
- width: 44,
97
- height: 44,
98
- padding: 0,
99
- display: 'flex',
100
- justifyContent: 'center',
101
- alignItems: 'center',
102
- background: recording ? 'var(--error-muted)' : 'rgba(148, 163, 184, 0.06)',
103
- border: recording ? '1px solid var(--error)' : '1px solid var(--border)',
104
- color: recording ? 'var(--error)' : 'var(--text-tertiary)',
105
- transition: 'all var(--transition-fast)'
106
- }}
107
- title={recording ? "Stop recording" : "Start voice input"}
108
- >
109
- <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><line x1="12" x2="12" y1="19" y2="22"/></svg>
110
- </button>
111
- );
112
- }