@ironmussa/funny 0.1.0 → 0.1.2
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/README.md +231 -214
- package/bin/funny.js +80 -80
- package/package.json +79 -59
- package/packages/client/dist/assets/AddProjectView-yopCTuKC.js +1 -0
- package/packages/client/dist/assets/AllThreadsView-vCQJYKkF.js +2 -0
- package/packages/client/dist/assets/AnalyticsView-vz1-NSOv.js +36 -0
- package/packages/client/dist/assets/App-BEFplUGa.js +2 -0
- package/packages/client/dist/assets/AutomationInboxView-Dj7f9gOu.js +1 -0
- package/packages/client/dist/assets/CircuitBreakerDialog-C76CZi4q.js +1 -0
- package/packages/client/dist/assets/CommandPalette-7Y8qqH7R.js +1 -0
- package/packages/client/dist/assets/LiveColumnsView-CSRiYBNg.js +1 -0
- package/packages/client/dist/assets/LoginPage-C61IUXzX.js +1 -0
- package/packages/client/dist/assets/MobilePage-B4kbWfE1.js +1 -0
- package/packages/client/dist/assets/MonacoEditorDialog-PPXTSIdX.js +1 -0
- package/packages/client/dist/assets/PreviewBrowser-Bo2zmDPh.js +2 -0
- package/packages/client/dist/assets/PromptInput-Cq_fXmwj.js +1 -0
- package/packages/client/dist/assets/ReviewPane-1r1cuH2I.js +10 -0
- package/packages/client/dist/assets/SettingsDetailView-D-J9TfZx.js +1 -0
- package/packages/client/dist/assets/SetupWizard-BbLWm6BX.js +1 -0
- package/packages/client/dist/assets/Sidebar-3Jd5JyAp.js +1 -0
- package/packages/client/dist/assets/SlideUpPrompt-_ulHi9sN.js +1 -0
- package/packages/client/dist/assets/TerminalPanel-BiLDlQZQ.js +4 -0
- package/packages/client/dist/assets/ThreadListView-DthHUodE.js +1 -0
- package/packages/client/dist/assets/ThreadView-DsqoxCXZ.js +16 -0
- package/packages/client/dist/assets/ToolCallGroup-BgROpRwn.js +22 -0
- package/packages/client/dist/assets/_basePickBy-BeHeP2rS.js +1 -0
- package/packages/client/dist/assets/_baseUniq-CZf5jOXa.js +1 -0
- package/packages/client/dist/assets/ansi_to_html-DYje8R53.js +3 -0
- package/packages/client/dist/assets/app-store-B3iAaYzj.js +1 -0
- package/packages/client/dist/assets/architectureDiagram-VXUJARFQ-CysgSV_T.js +36 -0
- package/packages/client/dist/assets/arrow-down-DQYiOM3D.js +1 -0
- package/packages/client/dist/assets/arrow-right-Bbusk4uX.js +1 -0
- package/packages/client/dist/assets/automation-store-DiFgwQi4.js +1 -0
- package/packages/client/dist/assets/badge-CrCqde50.js +1 -0
- package/packages/client/dist/assets/blockDiagram-VD42YOAC-DU32EjW8.js +122 -0
- package/packages/client/dist/assets/breadcrumb-BiY69_Mg.js +1 -0
- package/packages/client/dist/assets/button-D8qrc3hb.js +1 -0
- package/packages/client/dist/assets/c4Diagram-YG6GDRKO-D31N17G_.js +10 -0
- package/packages/client/dist/assets/check-Dj_ZR5Y7.js +1 -0
- package/packages/client/dist/assets/chevron-down-BJhJsMnL.js +1 -0
- package/packages/client/dist/assets/chevron-left-BVsM9RGq.js +1 -0
- package/packages/client/dist/assets/chevron-right-PEOnBrxM.js +1 -0
- package/packages/client/dist/assets/chevrons-up-down-Sa8XJRBx.js +1 -0
- package/packages/client/dist/assets/chunk-4BX2VUAB-CSqlINSL.js +1 -0
- package/packages/client/dist/assets/chunk-55IACEB6-D5_ai8AA.js +1 -0
- package/packages/client/dist/assets/chunk-B4BG7PRW-DKOAlNfo.js +165 -0
- package/packages/client/dist/assets/chunk-DI55MBZ5-BNwqKgG-.js +220 -0
- package/packages/client/dist/assets/chunk-FMBD7UC4-MKWtG46g.js +15 -0
- package/packages/client/dist/assets/chunk-QN33PNHL-BWGv-iLk.js +1 -0
- package/packages/client/dist/assets/chunk-QZHKN3VN-Brx07f_u.js +1 -0
- package/packages/client/dist/assets/chunk-TZMSLE5B-Cgz2v9ud.js +1 -0
- package/packages/client/dist/assets/circle-x-BNvrcCvx.js +1 -0
- package/packages/client/dist/assets/classDiagram-2ON5EDUG-Bi8VPWgp.js +1 -0
- package/packages/client/dist/assets/classDiagram-v2-WZHVMYZB-Bi8VPWgp.js +1 -0
- package/packages/client/dist/assets/clipboard-list-zkC7qTDO.js +1 -0
- package/packages/client/dist/assets/clone-CzE9L7Ig.js +1 -0
- package/packages/client/dist/assets/collapsible-DP3s_8s3.js +1 -0
- package/packages/client/dist/assets/columns-3-DhvlrNjA.js +1 -0
- package/packages/client/dist/assets/command-DOlrnbnh.js +1 -0
- package/packages/client/dist/assets/copy-DXKK6zMx.js +1 -0
- package/packages/client/dist/assets/cose-bilkent-S5V4N54A-DabFXskf.js +1 -0
- package/packages/client/dist/assets/createLucideIcon-CsWFljth.js +1 -0
- package/packages/client/dist/assets/cytoscape.esm-5J0xJHOV.js +321 -0
- package/packages/client/dist/assets/dagre-6UL2VRFP-BgQrFrWh.js +4 -0
- package/packages/client/dist/assets/diagram-PSM6KHXK-B0rQdwLC.js +24 -0
- package/packages/client/dist/assets/diagram-QEK2KX5R-aX13lt6A.js +43 -0
- package/packages/client/dist/assets/diagram-S2PKOQOG-cgHvdjCm.js +24 -0
- package/packages/client/dist/assets/dialog-DapeOKPE.js +1 -0
- package/packages/client/dist/assets/draft-store-DnVbStYY.js +1 -0
- package/packages/client/dist/assets/dropdown-menu-Bi54WPTK.js +1 -0
- package/packages/client/dist/assets/editor-utils-DgK9pIvP.js +2 -0
- package/packages/client/dist/assets/erDiagram-Q2GNP2WA-DwocRLhB.js +60 -0
- package/packages/client/dist/assets/external-link-Dg0Hq511.js +1 -0
- package/packages/client/dist/assets/eye-BAXsQYWt.js +1 -0
- package/packages/client/dist/assets/eye-off-ICXVwkI1.js +1 -0
- package/packages/client/dist/assets/flowDiagram-NV44I4VS-C0ldc02M.js +162 -0
- package/packages/client/dist/assets/folder-d8RRIu-j.js +1 -0
- package/packages/client/dist/assets/folder-open-BbwqJxUi.js +1 -0
- package/packages/client/dist/assets/ganttDiagram-JELNMOA3-DxdfUar4.js +267 -0
- package/packages/client/dist/assets/git-merge-CB0ebeXg.js +1 -0
- package/packages/client/dist/assets/gitGraphDiagram-V2S2FVAM-uM_Ec7JF.js +65 -0
- package/packages/client/dist/assets/github-DiENtmNz.js +1 -0
- package/packages/client/dist/assets/globe-B1hiCqlb.js +1 -0
- package/packages/client/dist/assets/graph-Qo1vygVG.js +1 -0
- package/packages/client/dist/assets/history-D7cvrs7x.js +1 -0
- package/packages/client/dist/assets/inbox-4g-W9WtW.js +1 -0
- package/packages/client/dist/assets/index-BplxL2Qj.js +1 -0
- package/packages/client/dist/assets/index-DmIp58b6.js +1 -0
- package/packages/client/dist/assets/index-Z_QI94Zg.js +18 -0
- package/packages/client/dist/assets/{index-B0nLATLY.js → index-cSW024sc.js} +1 -1
- package/packages/client/dist/assets/index-zxpgGDAW.css +1 -0
- package/packages/client/dist/assets/infoDiagram-HS3SLOUP-C-koF35b.js +2 -0
- package/packages/client/dist/assets/input-Dyxe5hqI.js +1 -0
- package/packages/client/dist/assets/internal-editor-store-CuhCMFlj.js +1 -0
- package/packages/client/dist/assets/journeyDiagram-XKPGCS4Q-DRqupubT.js +139 -0
- package/packages/client/dist/assets/kanban-definition-3W4ZIXB7-BvWguxdE.js +89 -0
- package/packages/client/dist/assets/katex-DhXJpUyf.js +261 -0
- package/packages/client/dist/assets/layout-UD4laNpY.js +1 -0
- package/packages/client/dist/assets/markdown-9_JKOUHQ.js +29 -0
- package/packages/client/dist/assets/maximize-2-DW-IsQiI.js +1 -0
- package/packages/client/dist/assets/mermaid-C0IQv4mH.js +250 -0
- package/packages/client/dist/assets/mindmap-definition-VGOIOE7T-C0fzBd6g.js +68 -0
- package/packages/client/dist/assets/minimize-2-CWn5BNKr.js +1 -0
- package/packages/client/dist/assets/monaco-CvC2RZDL.js +11 -0
- package/packages/client/dist/assets/{motion-DRu4QWVj.js → motion-Cyp39Uo1.js} +1 -1
- package/packages/client/dist/assets/pencil-pMey300q.js +1 -0
- package/packages/client/dist/assets/pieDiagram-ADFJNKIX-CUBE4hL3.js +30 -0
- package/packages/client/dist/assets/pin-off-DpiyTpTd.js +1 -0
- package/packages/client/dist/assets/pin-uzq68OVB.js +1 -0
- package/packages/client/dist/assets/plus-ChfperZy.js +1 -0
- package/packages/client/dist/assets/popover-CRZjc4jI.js +1 -0
- package/packages/client/dist/assets/project-chip-CkL3EaeE.js +5 -0
- package/packages/client/dist/assets/providers-Bv7fzJNY.js +1 -0
- package/packages/client/dist/assets/quadrantDiagram-AYHSOK5B-DF7I9OHz.js +7 -0
- package/packages/client/dist/assets/refresh-cw-Svvcff2v.js +1 -0
- package/packages/client/dist/assets/requirementDiagram-UZGBJVZJ-BBI4q-3_.js +64 -0
- package/packages/client/dist/assets/review-pane-store-CrK1Czq6.js +1 -0
- package/packages/client/dist/assets/rotate-ccw-DFiWNcpH.js +1 -0
- package/packages/client/dist/assets/sankeyDiagram-TZEHDZUN-lqpKxyZi.js +10 -0
- package/packages/client/dist/assets/scroll-area-Bj4yTRJP.js +1 -0
- package/packages/client/dist/assets/search-JGV9EPmW.js +1 -0
- package/packages/client/dist/assets/select-CkTnmILP.js +1 -0
- package/packages/client/dist/assets/sequenceDiagram-WL72ISMW-DHImpRwJ.js +145 -0
- package/packages/client/dist/assets/shallow-B0DA4RsP.js +1 -0
- package/packages/client/dist/assets/square-BqmNpRIH.js +1 -0
- package/packages/client/dist/assets/stateDiagram-FKZM4ZOC-C7L7Pt_V.js +1 -0
- package/packages/client/dist/assets/stateDiagram-v2-4FDKWEC3-FyYG2QfD.js +1 -0
- package/packages/client/dist/assets/{syntax-qKqB8BhQ.js → syntax-CG1UoaFw.js} +17 -17
- package/packages/client/dist/assets/terminal-CuAYwdh-.js +1 -0
- package/packages/client/dist/assets/timeline-definition-IT6M3QCI-BGABo1HM.js +61 -0
- package/packages/client/dist/assets/trash-2-QvY6JeI_.js +1 -0
- package/packages/client/dist/assets/treemap-GDKQZRPO-DZ7i2Nwu.js +160 -0
- package/packages/client/dist/assets/upload-DXXUmYu2.js +1 -0
- package/packages/client/dist/assets/use-minute-tick-BoS3Ec2H.js +1 -0
- package/packages/client/dist/assets/use-ws-BIe6kKa2.js +48 -0
- package/packages/client/dist/assets/utils-VDOOGGvU.js +2 -0
- package/packages/client/dist/assets/x-AprddF_b.js +1 -0
- package/packages/client/dist/assets/xychartDiagram-PRI3JC2R-D_bazwNo.js +7 -0
- package/packages/client/dist/index.html +9 -13
- package/packages/server/dist/index.js +117479 -69360
- package/packages/server/dist/index.js.map +682 -138
- package/packages/server/dist/pty-helper.mjs +115 -115
- package/packages/client/dist/assets/AddProjectView-CODm54MP.js +0 -1
- package/packages/client/dist/assets/AllThreadsView--Dd7YSK5.js +0 -1
- package/packages/client/dist/assets/AnalyticsView-eRhWGG3y.js +0 -36
- package/packages/client/dist/assets/AutomationInboxView-DwBaGJed.js +0 -1
- package/packages/client/dist/assets/CircuitBreakerDialog-C2iBwp5W.js +0 -1
- package/packages/client/dist/assets/CommandPalette-BXweSrdO.js +0 -1
- package/packages/client/dist/assets/ReviewPane-DxtlJNNu.js +0 -10
- package/packages/client/dist/assets/SettingsDetailView-BKh9OBM2.js +0 -1
- package/packages/client/dist/assets/SetupWizard-BekJX-tc.js +0 -1
- package/packages/client/dist/assets/TerminalPanel-DC4U0OTm.js +0 -4
- package/packages/client/dist/assets/ThreadListView-B6HvQ8NV.js +0 -1
- package/packages/client/dist/assets/arrow-right-3Bby9NNK.js +0 -1
- package/packages/client/dist/assets/command-B76T8z-A.js +0 -1
- package/packages/client/dist/assets/index-BRi6al6L.js +0 -99
- package/packages/client/dist/assets/index-DXO1sSe9.css +0 -1
- package/packages/client/dist/assets/markdown-B7CXSXYD.js +0 -29
- package/packages/client/dist/assets/review-pane-store-BLhxZHRI.js +0 -1
package/README.md
CHANGED
|
@@ -1,214 +1,231 @@
|
|
|
1
|
-
# funny
|
|
2
|
-
|
|
3
|
-
> Parallel Claude Code agent orchestration powered by git worktrees
|
|
4
|
-
|
|
5
|
-
funny is a web UI for orchestrating multiple [Claude Code](https://claude.ai/code) agents in parallel. It uses git worktrees to let each agent work on its own branch simultaneously without conflicts. Think of it as a Codex App clone powered by the [Claude Agent SDK](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk) (`@anthropic-ai/claude-agent-sdk`).
|
|
6
|
-
|
|
7
|
-
## Features
|
|
8
|
-
|
|
9
|
-
- **Parallel agent execution** — Run multiple Claude Code agents simultaneously on different branches
|
|
10
|
-
- **Git worktree isolation** — Each agent gets its own isolated working directory
|
|
11
|
-
- **Real-time monitoring** — WebSocket-based live updates for all agent activities
|
|
12
|
-
- **Git integration** — Built-in diff viewer, staging, commits, and PR creation
|
|
13
|
-
- **Kanban board** — Drag-and-drop task management with columns (backlog, in progress, review, done, archived)
|
|
14
|
-
- **Search** — Find threads by title, branch name, status, or message content with real-time filtering
|
|
15
|
-
- **Analytics dashboard** — Track task creation, completion rates, stage distribution, and cost metrics over time
|
|
16
|
-
- **MCP support** — Model Context Protocol integration
|
|
17
|
-
- **Automation scheduling** — Cron-based recurring tasks
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
funny
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
bun
|
|
45
|
-
bun
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
- **
|
|
52
|
-
- **
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
|
74
|
-
| `-
|
|
75
|
-
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
|
82
|
-
| `
|
|
83
|
-
| `
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
- **
|
|
91
|
-
- **
|
|
92
|
-
- **
|
|
93
|
-
- **
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
- **
|
|
103
|
-
- **
|
|
104
|
-
- **
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
- **
|
|
114
|
-
- **
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
#
|
|
137
|
-
bun
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
-
|
|
164
|
-
-
|
|
165
|
-
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
-
|
|
206
|
-
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
1
|
+
# funny
|
|
2
|
+
|
|
3
|
+
> Parallel Claude Code agent orchestration powered by git worktrees
|
|
4
|
+
|
|
5
|
+
funny is a web UI for orchestrating multiple [Claude Code](https://claude.ai/code) agents in parallel. It uses git worktrees to let each agent work on its own branch simultaneously without conflicts. Think of it as a Codex App clone powered by the [Claude Agent SDK](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk) (`@anthropic-ai/claude-agent-sdk`).
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Parallel agent execution** — Run multiple Claude Code agents simultaneously on different branches
|
|
10
|
+
- **Git worktree isolation** — Each agent gets its own isolated working directory
|
|
11
|
+
- **Real-time monitoring** — WebSocket-based live updates for all agent activities
|
|
12
|
+
- **Git integration** — Built-in diff viewer, staging, commits, and PR creation
|
|
13
|
+
- **Kanban board** — Drag-and-drop task management with columns (backlog, in progress, review, done, archived)
|
|
14
|
+
- **Search** — Find threads by title, branch name, status, or message content with real-time filtering
|
|
15
|
+
- **Analytics dashboard** — Track task creation, completion rates, stage distribution, and cost metrics over time
|
|
16
|
+
- **MCP support** — Model Context Protocol integration
|
|
17
|
+
- **Automation scheduling** — Cron-based recurring tasks
|
|
18
|
+
- **Mobile support** — Responsive mobile view with touch-friendly navigation for on-the-go monitoring
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
### Quick Start (bunx)
|
|
23
|
+
|
|
24
|
+
No installation needed! Run directly with:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
bunx @ironmussa/funny
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The app will start and open at `http://localhost:3001`
|
|
31
|
+
|
|
32
|
+
### Global Installation
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
bun install -g @ironmussa/funny
|
|
36
|
+
funny
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### From Source
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
git clone https://github.com/ironmussa/funny.git
|
|
43
|
+
cd funny
|
|
44
|
+
bun install
|
|
45
|
+
bun run build
|
|
46
|
+
bun start
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Requirements
|
|
50
|
+
|
|
51
|
+
- **Bun** >= 1.0.0 (install from [bun.sh](https://bun.sh))
|
|
52
|
+
- **Claude CLI** installed and authenticated ([claude.ai/code](https://claude.ai/code))
|
|
53
|
+
- **Git** installed and configured
|
|
54
|
+
|
|
55
|
+
## Usage
|
|
56
|
+
|
|
57
|
+
### Starting the Server
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# Default (port 3001)
|
|
61
|
+
funny
|
|
62
|
+
|
|
63
|
+
# Custom port
|
|
64
|
+
funny --port 8080
|
|
65
|
+
|
|
66
|
+
# Show all options
|
|
67
|
+
funny --help
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### CLI Options
|
|
71
|
+
|
|
72
|
+
| Option | Description | Default |
|
|
73
|
+
| ------------------- | ----------------- | ----------- |
|
|
74
|
+
| `-p, --port <port>` | Server port | `3001` |
|
|
75
|
+
| `-h, --host <host>` | Server host | `127.0.0.1` |
|
|
76
|
+
| `--help` | Show help message | - |
|
|
77
|
+
|
|
78
|
+
### Environment Variables
|
|
79
|
+
|
|
80
|
+
| Variable | Description | Default |
|
|
81
|
+
| ------------- | ------------------------------------- | --------------- |
|
|
82
|
+
| `PORT` | Server port | `3001` |
|
|
83
|
+
| `HOST` | Server hostname | `127.0.0.1` |
|
|
84
|
+
| `CORS_ORIGIN` | Custom CORS origins (comma-separated) | Auto-configured |
|
|
85
|
+
|
|
86
|
+
## Kanban Board
|
|
87
|
+
|
|
88
|
+
Threads can be visualized and managed as a Kanban board with five columns:
|
|
89
|
+
|
|
90
|
+
- **Backlog** — Tasks waiting to be started
|
|
91
|
+
- **In Progress** — Tasks currently being worked on
|
|
92
|
+
- **Review** — Tasks ready for code review
|
|
93
|
+
- **Done** — Completed tasks
|
|
94
|
+
- **Archived** — Archived tasks
|
|
95
|
+
|
|
96
|
+
Drag and drop cards between columns to update their stage. Cards show thread status, git sync state, cost, and time since last update. Pinned threads appear first in each column. You can create new threads directly from the board and switch between list and board views.
|
|
97
|
+
|
|
98
|
+
## Search & Filtering
|
|
99
|
+
|
|
100
|
+
Find threads quickly using the search bar. Search matches against:
|
|
101
|
+
|
|
102
|
+
- **Thread title**
|
|
103
|
+
- **Branch name**
|
|
104
|
+
- **Thread status**
|
|
105
|
+
- **Message content** (server-side full-text search with content snippets)
|
|
106
|
+
|
|
107
|
+
Results highlight matching text. Combine search with filters for status, git state, and mode to narrow results further. Filters sync to URL query parameters so you can share filtered views.
|
|
108
|
+
|
|
109
|
+
## Analytics
|
|
110
|
+
|
|
111
|
+
The analytics dashboard provides an overview of task activity and costs:
|
|
112
|
+
|
|
113
|
+
- **Metric cards** — Tasks created, completed, moved to review/done/archived, and total cost
|
|
114
|
+
- **Stage distribution chart** — Pie chart showing current distribution of threads across stages
|
|
115
|
+
- **Timeline chart** — Bar chart showing task activity over time, grouped by day/week/month/year
|
|
116
|
+
|
|
117
|
+
Filter analytics by project and time range (day, week, month, or all-time).
|
|
118
|
+
|
|
119
|
+
## Mobile Support
|
|
120
|
+
|
|
121
|
+
funny includes a dedicated mobile view that automatically activates on screens narrower than 768px. The mobile interface provides a streamlined, touch-friendly experience for monitoring and interacting with your agents on the go.
|
|
122
|
+
|
|
123
|
+
**Mobile features:**
|
|
124
|
+
|
|
125
|
+
- **Stack-based navigation** — Projects → Threads → Chat, with back buttons for easy navigation
|
|
126
|
+
- **Full chat interaction** — Send messages, view agent responses, approve/reject tool calls, and monitor running agents
|
|
127
|
+
- **Thread management** — Create new threads with model and mode selection directly from your phone
|
|
128
|
+
- **Status monitoring** — Real-time status badges and agent activity indicators
|
|
129
|
+
- **Auto-scrolling** — Smart scroll behavior that follows new messages while preserving your scroll position
|
|
130
|
+
|
|
131
|
+
The sidebar automatically converts to a slide-out drawer on mobile via the shadcn/ui Sheet component.
|
|
132
|
+
|
|
133
|
+
## Development
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
# Install dependencies
|
|
137
|
+
bun install
|
|
138
|
+
|
|
139
|
+
# Run in development mode (client + server with hot reload)
|
|
140
|
+
bun run dev
|
|
141
|
+
|
|
142
|
+
# Run only server (port 3001)
|
|
143
|
+
bun run dev:server
|
|
144
|
+
|
|
145
|
+
# Run only client (port 5173)
|
|
146
|
+
bun run dev:client
|
|
147
|
+
|
|
148
|
+
# Build for production
|
|
149
|
+
bun run build
|
|
150
|
+
|
|
151
|
+
# Database operations
|
|
152
|
+
bun run db:push # Push schema changes
|
|
153
|
+
bun run db:studio # Open Drizzle Studio
|
|
154
|
+
|
|
155
|
+
# Run tests
|
|
156
|
+
bun test
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Architecture
|
|
160
|
+
|
|
161
|
+
### Monorepo Structure
|
|
162
|
+
|
|
163
|
+
- **`packages/shared`** — Shared TypeScript types
|
|
164
|
+
- **`packages/server`** — Hono HTTP server with [Claude Agent SDK](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk) (port 3001)
|
|
165
|
+
- **`packages/client`** — React 19 + Vite SPA (port 5173 in dev)
|
|
166
|
+
|
|
167
|
+
### Tech Stack
|
|
168
|
+
|
|
169
|
+
**Server:**
|
|
170
|
+
|
|
171
|
+
- Hono (HTTP framework)
|
|
172
|
+
- [Claude Agent SDK](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk) (`@anthropic-ai/claude-agent-sdk`)
|
|
173
|
+
- Drizzle ORM + SQLite
|
|
174
|
+
- WebSocket (real-time updates)
|
|
175
|
+
|
|
176
|
+
**Client:**
|
|
177
|
+
|
|
178
|
+
- React 19
|
|
179
|
+
- Vite
|
|
180
|
+
- Zustand (state management)
|
|
181
|
+
- shadcn/ui (components)
|
|
182
|
+
- Tailwind CSS
|
|
183
|
+
|
|
184
|
+
## Data Storage
|
|
185
|
+
|
|
186
|
+
All data is stored in:
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
~/.funny/
|
|
190
|
+
├── data.db # SQLite database (projects, threads, messages)
|
|
191
|
+
└── auth-token # Bearer token for authentication
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Git Worktrees
|
|
195
|
+
|
|
196
|
+
Worktrees are created in `.funny-worktrees/` adjacent to your project:
|
|
197
|
+
|
|
198
|
+
```
|
|
199
|
+
/your-project/
|
|
200
|
+
├── .git/
|
|
201
|
+
├── src/
|
|
202
|
+
└── ...
|
|
203
|
+
|
|
204
|
+
/your-project-worktrees/
|
|
205
|
+
├── feature-branch-1/
|
|
206
|
+
├── feature-branch-2/
|
|
207
|
+
└── ...
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Each worktree is an isolated working directory allowing parallel agent work without conflicts.
|
|
211
|
+
|
|
212
|
+
## Commands
|
|
213
|
+
|
|
214
|
+
See [CLAUDE.md](./CLAUDE.md) for detailed commands and architecture documentation.
|
|
215
|
+
|
|
216
|
+
## License
|
|
217
|
+
|
|
218
|
+
MIT
|
|
219
|
+
|
|
220
|
+
## Support
|
|
221
|
+
|
|
222
|
+
- [GitHub Issues](https://github.com/ironmussa/funny/issues)
|
|
223
|
+
- [Claude Code Documentation](https://claude.ai/code)
|
|
224
|
+
|
|
225
|
+
## Contributing
|
|
226
|
+
|
|
227
|
+
Contributions are welcome! Please read [CLAUDE.md](./CLAUDE.md) for development guidelines.
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
Built with [Claude Code](https://claude.ai/code)
|
package/bin/funny.js
CHANGED
|
@@ -1,80 +1,80 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
import {
|
|
3
|
-
import { resolve } from 'path';
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
// Parse CLI arguments
|
|
7
|
-
const { values } = parseArgs({
|
|
8
|
-
options: {
|
|
9
|
-
port: {
|
|
10
|
-
type: 'string',
|
|
11
|
-
short: 'p',
|
|
12
|
-
default: '3001',
|
|
13
|
-
},
|
|
14
|
-
host: {
|
|
15
|
-
type: 'string',
|
|
16
|
-
short: 'h',
|
|
17
|
-
default: '127.0.0.1',
|
|
18
|
-
},
|
|
19
|
-
'auth-mode': {
|
|
20
|
-
type: 'string',
|
|
21
|
-
default: 'local',
|
|
22
|
-
},
|
|
23
|
-
help: {
|
|
24
|
-
type: 'boolean',
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
allowPositionals: true,
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
if (values.help) {
|
|
31
|
-
console.log(`
|
|
32
|
-
funny - Parallel Claude Code agent orchestration
|
|
33
|
-
|
|
34
|
-
Usage:
|
|
35
|
-
funny [options]
|
|
36
|
-
|
|
37
|
-
Options:
|
|
38
|
-
-p, --port <port> Server port (default: 3001)
|
|
39
|
-
-h, --host <host> Server host (default: 127.0.0.1)
|
|
40
|
-
--auth-mode <mode> Authentication mode: local | multi (default: local)
|
|
41
|
-
--help Show this help message
|
|
42
|
-
|
|
43
|
-
Examples:
|
|
44
|
-
funny # Start on http://127.0.0.1:3001
|
|
45
|
-
funny --port 8080 # Start on custom port
|
|
46
|
-
funny --auth-mode multi # Start in multi-user mode
|
|
47
|
-
|
|
48
|
-
Environment Variables:
|
|
49
|
-
PORT Server port
|
|
50
|
-
HOST Server host
|
|
51
|
-
AUTH_MODE Authentication mode (local or multi)
|
|
52
|
-
CORS_ORIGIN Custom CORS origins (comma-separated)
|
|
53
|
-
|
|
54
|
-
For more information, visit: https://github.com/anthropics/funny
|
|
55
|
-
`);
|
|
56
|
-
process.exit(0);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Set environment variables from CLI args
|
|
60
|
-
process.env.PORT = values.port;
|
|
61
|
-
process.env.HOST = values.host;
|
|
62
|
-
process.env.AUTH_MODE = values['auth-mode'];
|
|
63
|
-
|
|
64
|
-
// Resolve server entry point
|
|
65
|
-
const serverEntry = resolve(import.meta.dir, '../packages/server/dist/index.js');
|
|
66
|
-
const serverSrc = resolve(import.meta.dir, '../packages/server/src/index.ts');
|
|
67
|
-
|
|
68
|
-
// Check if built version exists, otherwise use source (for development)
|
|
69
|
-
if (existsSync(serverEntry)) {
|
|
70
|
-
console.log('[funny] Starting from built server...');
|
|
71
|
-
await import(serverEntry);
|
|
72
|
-
} else if (existsSync(serverSrc)) {
|
|
73
|
-
console.log('[funny] Built server not found, starting from source...');
|
|
74
|
-
console.log('[funny] Run "npm run build" for production use.');
|
|
75
|
-
await import(serverSrc);
|
|
76
|
-
} else {
|
|
77
|
-
console.error('[funny] Error: Server files not found.');
|
|
78
|
-
console.error('Please run "npm install" and "npm run build" first.');
|
|
79
|
-
process.exit(1);
|
|
80
|
-
}
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { existsSync } from 'fs';
|
|
3
|
+
import { resolve } from 'path';
|
|
4
|
+
import { parseArgs } from 'util';
|
|
5
|
+
|
|
6
|
+
// Parse CLI arguments
|
|
7
|
+
const { values } = parseArgs({
|
|
8
|
+
options: {
|
|
9
|
+
port: {
|
|
10
|
+
type: 'string',
|
|
11
|
+
short: 'p',
|
|
12
|
+
default: '3001',
|
|
13
|
+
},
|
|
14
|
+
host: {
|
|
15
|
+
type: 'string',
|
|
16
|
+
short: 'h',
|
|
17
|
+
default: '127.0.0.1',
|
|
18
|
+
},
|
|
19
|
+
'auth-mode': {
|
|
20
|
+
type: 'string',
|
|
21
|
+
default: 'local',
|
|
22
|
+
},
|
|
23
|
+
help: {
|
|
24
|
+
type: 'boolean',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
allowPositionals: true,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
if (values.help) {
|
|
31
|
+
console.log(`
|
|
32
|
+
funny - Parallel Claude Code agent orchestration
|
|
33
|
+
|
|
34
|
+
Usage:
|
|
35
|
+
funny [options]
|
|
36
|
+
|
|
37
|
+
Options:
|
|
38
|
+
-p, --port <port> Server port (default: 3001)
|
|
39
|
+
-h, --host <host> Server host (default: 127.0.0.1)
|
|
40
|
+
--auth-mode <mode> Authentication mode: local | multi (default: local)
|
|
41
|
+
--help Show this help message
|
|
42
|
+
|
|
43
|
+
Examples:
|
|
44
|
+
funny # Start on http://127.0.0.1:3001
|
|
45
|
+
funny --port 8080 # Start on custom port
|
|
46
|
+
funny --auth-mode multi # Start in multi-user mode
|
|
47
|
+
|
|
48
|
+
Environment Variables:
|
|
49
|
+
PORT Server port
|
|
50
|
+
HOST Server host
|
|
51
|
+
AUTH_MODE Authentication mode (local or multi)
|
|
52
|
+
CORS_ORIGIN Custom CORS origins (comma-separated)
|
|
53
|
+
|
|
54
|
+
For more information, visit: https://github.com/anthropics/funny
|
|
55
|
+
`);
|
|
56
|
+
process.exit(0);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Set environment variables from CLI args
|
|
60
|
+
process.env.PORT = values.port;
|
|
61
|
+
process.env.HOST = values.host;
|
|
62
|
+
process.env.AUTH_MODE = values['auth-mode'];
|
|
63
|
+
|
|
64
|
+
// Resolve server entry point
|
|
65
|
+
const serverEntry = resolve(import.meta.dir, '../packages/server/dist/index.js');
|
|
66
|
+
const serverSrc = resolve(import.meta.dir, '../packages/server/src/index.ts');
|
|
67
|
+
|
|
68
|
+
// Check if built version exists, otherwise use source (for development)
|
|
69
|
+
if (existsSync(serverEntry)) {
|
|
70
|
+
console.log('[funny] Starting from built server...');
|
|
71
|
+
await import(serverEntry);
|
|
72
|
+
} else if (existsSync(serverSrc)) {
|
|
73
|
+
console.log('[funny] Built server not found, starting from source...');
|
|
74
|
+
console.log('[funny] Run "npm run build" for production use.');
|
|
75
|
+
await import(serverSrc);
|
|
76
|
+
} else {
|
|
77
|
+
console.error('[funny] Error: Server files not found.');
|
|
78
|
+
console.error('Please run "npm install" and "npm run build" first.');
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|