@cuongtran001/kanna 1.63.1 → 1.63.3
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 +5 -9
- package/dist/client/assets/{BoardsPage-mVdaRV1l.js → BoardsPage-AckCuswi.js} +1 -1
- package/dist/client/assets/BoardsRoutePage-DzKwKy3f.js +1 -0
- package/dist/client/assets/ChatPage-DsaH8CTz.js +93 -0
- package/dist/client/assets/{CronJobRow-mZDgZOsq.js → CronJobRow-Bx9gRqKW.js} +1 -1
- package/dist/client/assets/{CronJobsPage-BQYTTqIG.js → CronJobsPage-v0-2X1oX.js} +1 -1
- package/dist/client/assets/{FilePreviewSheet-BG7x42bT.js → FilePreviewSheet-B6SDxSD0.js} +2 -2
- package/dist/client/assets/{FlowSurface-Dc6Pe40O.js → FlowSurface-CLC-ZFar.js} +1 -1
- package/dist/client/assets/{GenUIBlock-DQ1FAYV2.js → GenUIBlock-CC79Ujro.js} +2 -2
- package/dist/client/assets/{KannaSocketProvider-DNcmJfoW.js → KannaSocketProvider-B2sHsWP5.js} +1 -1
- package/dist/client/assets/{LocalProjectsPage-DTYGi4cw.js → LocalProjectsPage-DYBkcEAm.js} +1 -1
- package/dist/client/assets/SettingsPage-CZqMkMRW.js +9 -0
- package/dist/client/assets/{StackBoardsRoutePage-Rg9heAp8.js → StackBoardsRoutePage-Clviz0hX.js} +1 -1
- package/dist/client/assets/{ToolCallMessage-CX01LIYK.js → ToolCallMessage-BfNbWGmc.js} +1 -1
- package/dist/client/assets/{VChartSurface-CPViuiRJ.js → VChartSurface-CUbxyBo3.js} +1 -1
- package/dist/client/assets/{WorkflowsPage-CxJhZK-y.js → WorkflowsPage-rengzb97.js} +1 -1
- package/dist/client/assets/{WorkflowsSection-0Qt0VjIb.js → WorkflowsSection-DuXdLsMO.js} +1 -1
- package/dist/client/assets/{chart-renderer-DTvjgTUY.js → chart-renderer-D7ukB2wg.js} +1 -1
- package/dist/client/assets/{chatSounds-03e825gY.js → chatSounds-BLg2xPDZ.js} +1 -1
- package/dist/client/assets/chevron-left-RbFvmeyK.js +1 -0
- package/dist/client/assets/{clipboard.adapter-wqfdW5oW.js → clipboard.adapter-CgdNwn-1.js} +1 -1
- package/dist/client/assets/{columnStyle-ulMmtOxb.js → columnStyle-CMCF0ds6.js} +1 -1
- package/dist/client/assets/{createScopedStore-BdgPJYn5.js → createScopedStore-BrD5NHWx.js} +1 -1
- package/dist/client/assets/{dist-DOdGYk49.js → dist-DNSTHlSo.js} +1 -1
- package/dist/client/assets/editor-icons-DY4uKeEY.js +1 -0
- package/dist/client/assets/{ellipsis-cPOVPqFO.js → ellipsis-OHg0x_x1.js} +1 -1
- package/dist/client/assets/{flow-kinds-Ci7hyYYJ.js → flow-kinds-Ki2DP9nP.js} +1 -1
- package/dist/client/assets/{folder-O6RMSd2V.js → folder-CnWzWIG5.js} +1 -1
- package/dist/client/assets/{formatters-wSVyvDFZ.js → formatters-BGORekd-.js} +1 -1
- package/dist/client/assets/{genui-B-C_12wk.js → genui-C9i6j0XZ.js} +1 -1
- package/dist/client/assets/{globe-CJeLPEEK.js → globe-BjR1tyE4.js} +1 -1
- package/dist/client/assets/{host-0t0cdS1h.js → host-D9tJwZXl.js} +1 -1
- package/dist/client/assets/index-CesRxZ0X.js +26 -0
- package/dist/client/assets/index-CxDE9VOy.css +1 -0
- package/dist/client/assets/{info-CFDoDIFy.js → info-DNYekoE-.js} +1 -1
- package/dist/client/assets/{input-CSOou2Ke.js → input-DgW9uRZN.js} +1 -1
- package/dist/client/assets/{lexicalToReact-BnB8UCaU.js → lexicalToReact-CZvp9Pgz.js} +3 -3
- package/dist/client/assets/{log-DFhobdvS.js → log-DnEvbp3E.js} +1 -1
- package/dist/client/assets/{monitor-Dz3yjPhP.js → monitor-qbWfUdBG.js} +1 -1
- package/dist/client/assets/{pencil-Bt12fSgV.js → pencil-C965rrpd.js} +1 -1
- package/dist/client/assets/{pendingActionsStore-B_FYCH16.js → pendingActionsStore-CxhI19V9.js} +1 -1
- package/dist/client/assets/{play-BwOyLfLF.js → play-uofLR7yT.js} +1 -1
- package/dist/client/assets/{plus-s5_Ks732.js → plus-D4CI6rj1.js} +1 -1
- package/dist/client/assets/{popover-CN6KN-Pv.js → popover-Bc646hKn.js} +1 -1
- package/dist/client/assets/{pushClient-Fj8srGZa.js → pushClient-CxnHu9h4.js} +1 -1
- package/dist/client/assets/runDetached-DfQXHAaY.js +1 -0
- package/dist/client/assets/{segmented-control-Dgl0BpK9.js → segmented-control-CKGX29Kl.js} +1 -1
- package/dist/client/assets/{select-PbwoBhm-.js → select-BjeajpVt.js} +1 -1
- package/dist/client/assets/{settings-header-button-eDLLqJ7N.js → settings-header-button-BYvHR6Xl.js} +1 -1
- package/dist/client/assets/{sidebarPendingActions-BahCtzQw.js → sidebarPendingActions-xgMTnfRY.js} +1 -1
- package/dist/client/assets/{square-pen-B85EVyLP.js → square-pen-DmppQdTd.js} +1 -1
- package/dist/client/assets/{state-mark-BitecvKK.js → state-mark-C3kEL1hX.js} +1 -1
- package/dist/client/assets/{status-pill-BqnLSrIr.js → status-pill-Bo1Nb6HX.js} +1 -1
- package/dist/client/assets/{terminal-Cj5AmSMz.js → terminal-DfCF-J4p.js} +1 -1
- package/dist/client/assets/{timer.adapter-g84UDqc_.js → timer.adapter-C2RhP4d6.js} +1 -1
- package/dist/client/assets/{tools-oiti76TK.js → tools-t5T_3UBg.js} +1 -1
- package/dist/client/assets/{triangle-alert-DluPUJcc.js → triangle-alert-CYQhobyY.js} +1 -1
- package/dist/client/assets/useAppGlobalState-DUa3pkCF.js +1 -0
- package/dist/client/assets/useKannaState-FcieR5qb.js +5 -0
- package/dist/client/assets/useTheme-D9sKDPEm.js +1 -0
- package/dist/client/index.html +35 -35
- package/package.json +2 -2
- package/src/server/agent-coordinator-types.ts +0 -6
- package/src/server/agent-coordinator.ts +6 -45
- package/src/server/agent.compaction.test.ts +1 -13
- package/src/server/agent.oauth-account-info.test.ts +0 -3
- package/src/server/agent.oauth-release.test.ts +0 -2
- package/src/server/agent.oauth-rotation.test.ts +0 -9
- package/src/server/agent.oauth-token-share-cap.test.ts +0 -1
- package/src/server/agent.openrouter-model.test.ts +0 -2
- package/src/server/agent.openrouter-watchdog.test.ts +0 -3
- package/src/server/agent.sdk-workflow-register.test.ts +2 -64
- package/src/server/agent.test.ts +1 -319
- package/src/server/app-settings.test.ts +14 -17
- package/src/server/app-settings.ts +22 -37
- package/src/server/auto-continue/e2e.test.ts +0 -1
- package/src/server/background-task-output-registry.test.ts +1 -1
- package/src/server/background-task-output-registry.ts +1 -1
- package/src/server/claude-cancel-handler.test.ts +0 -58
- package/src/server/claude-cancel-handler.ts +1 -17
- package/src/server/claude-harness-stream.test.ts +134 -0
- package/src/server/{claude-pty/jsonl-path.test.ts → claude-projects-path.adapter.test.ts} +1 -19
- package/src/server/{claude-pty/jsonl-path.adapter.ts → claude-projects-path.adapter.ts} +0 -11
- package/src/server/claude-send-command.test.ts +0 -1
- package/src/server/claude-session-config-helpers.test.ts +1 -90
- package/src/server/claude-session-config-helpers.ts +1 -38
- package/src/server/claude-session-error-handler.test.ts +0 -1
- package/src/server/claude-session-lifecycle.test.ts +2 -36
- package/src/server/claude-session-lifecycle.ts +2 -8
- package/src/server/claude-session-runner.test.ts +8 -36
- package/src/server/claude-session-runner.ts +1 -26
- package/src/server/claude-session-spawner.test.ts +5 -64
- package/src/server/claude-session-spawner.ts +49 -115
- package/src/server/claude-session-start.test.ts +1 -14
- package/src/server/claude-session-start.ts +0 -8
- package/src/server/claude-session-state-queries.test.ts +1 -2
- package/src/server/claude-session-state.test.ts +0 -1
- package/src/server/claude-session-state.ts +0 -4
- package/src/server/claude-subagent-wiring.test.ts +2 -68
- package/src/server/claude-subagent-wiring.ts +3 -50
- package/src/server/claude-turn-starter-types.ts +0 -3
- package/src/server/claude-turn-starter.test.ts +0 -28
- package/src/server/claude-turn-starter.ts +0 -5
- package/src/server/event-store.test.ts +0 -2
- package/src/server/events.ts +1 -2
- package/src/server/harness-types.ts +1 -2
- package/src/server/import-subagent-drill.e2e.test.ts +1 -1
- package/src/server/imported-subagents-dir.test.ts +1 -1
- package/src/server/imported-subagents-dir.ts +1 -1
- package/src/server/kanna-mcp.test.ts +0 -75
- package/src/server/kanna-mcp.ts +1 -47
- package/src/server/server.test.ts +5 -7
- package/src/server/server.ts +2 -18
- package/src/server/subagent-orchestrator.test.ts +0 -1
- package/src/server/subagent-provider-run.test.ts +48 -10
- package/src/server/subagent-provider-run.ts +12 -3
- package/src/server/tool-callback.test.ts +1 -1
- package/src/server/ws-router-agent-ctrl.test.ts +0 -45
- package/src/server/ws-router-agent-ctrl.ts +1 -31
- package/src/server/ws-router-broadcast.ts +0 -27
- package/src/server/ws-router-defaults.test.ts +2 -3
- package/src/server/ws-router-defaults.ts +2 -3
- package/src/server/ws-router-envelope.ts +0 -15
- package/src/server/ws-router-observability.test.ts +1 -1
- package/src/server/ws-router-settings.test.ts +2 -2
- package/src/server/ws-router.test.ts +2 -2
- package/src/server/ws-router.ts +0 -8
- package/src/shared/app-settings-types.ts +9 -20
- package/src/shared/claude-api-error-classification.ts +1 -1
- package/src/shared/protocol.ts +1 -11
- package/dist/client/assets/BoardsRoutePage-Cz6irKOB.js +0 -1
- package/dist/client/assets/ChatPage-Di9Mm9dW.js +0 -93
- package/dist/client/assets/SettingsPage-1Ka-lzSx.js +0 -9
- package/dist/client/assets/chevron-left-BdNUIJTA.js +0 -1
- package/dist/client/assets/editor-icons-99dE-E7-.js +0 -1
- package/dist/client/assets/index-C-UYaDk6.css +0 -1
- package/dist/client/assets/index-GJyusOM5.js +0 -26
- package/dist/client/assets/runDetached-AJ-JDygc.js +0 -1
- package/dist/client/assets/useAppGlobalState-w8KX_7Yj.js +0 -1
- package/dist/client/assets/useKannaState-QABuA8Rf.js +0 -5
- package/dist/client/assets/useTheme-E3vVm1KS.js +0 -1
- package/src/server/agent.pty-rotation.test.ts +0 -322
- package/src/server/claude-pty/auth.test.ts +0 -38
- package/src/server/claude-pty/auth.ts +0 -17
- package/src/server/claude-pty/claude-session-registry.adapter.ts +0 -68
- package/src/server/claude-pty/claude-session-registry.test.ts +0 -149
- package/src/server/claude-pty/driver.test.ts +0 -1153
- package/src/server/claude-pty/driver.ts +0 -829
- package/src/server/claude-pty/env.test.ts +0 -79
- package/src/server/claude-pty/env.ts +0 -20
- package/src/server/claude-pty/jsonl-to-event.test.ts +0 -882
- package/src/server/claude-pty/jsonl-to-event.ts +0 -357
- package/src/server/claude-pty/parity-matrix.test.ts +0 -437
- package/src/server/claude-pty/pid-registry.adapter.ts +0 -164
- package/src/server/claude-pty/pid-registry.test.ts +0 -178
- package/src/server/claude-pty/preflight/binary-fingerprint.adapter.ts +0 -20
- package/src/server/claude-pty/preflight/binary-fingerprint.test.ts +0 -32
- package/src/server/claude-pty/pty-instance-registry.test.ts +0 -208
- package/src/server/claude-pty/pty-instance-registry.ts +0 -172
- package/src/server/claude-pty/pty-memory-sampler.adapter.test.ts +0 -103
- package/src/server/claude-pty/pty-memory-sampler.adapter.ts +0 -86
- package/src/server/claude-pty/pty-process.adapter.ts +0 -60
- package/src/server/claude-pty/pty-process.test.ts +0 -49
- package/src/server/claude-pty/resolve-binary.adapter.ts +0 -106
- package/src/server/claude-pty/resolve-binary.test.ts +0 -118
- package/src/server/claude-pty/runtime-dir.adapter.ts +0 -19
- package/src/server/claude-pty/sandbox/detect.adapter.ts +0 -17
- package/src/server/claude-pty/sandbox/detect.test.ts +0 -17
- package/src/server/claude-pty/sandbox/platform.test.ts +0 -35
- package/src/server/claude-pty/sandbox/platform.ts +0 -27
- package/src/server/claude-pty/sandbox/preflight-io.adapter.ts +0 -14
- package/src/server/claude-pty/sandbox/preflight.test.ts +0 -69
- package/src/server/claude-pty/sandbox/preflight.ts +0 -44
- package/src/server/claude-pty/sandbox/profile-linux.adapter.ts +0 -63
- package/src/server/claude-pty/sandbox/profile-linux.test.ts +0 -90
- package/src/server/claude-pty/sandbox/profile-macos.adapter.ts +0 -72
- package/src/server/claude-pty/sandbox/profile-macos.test.ts +0 -68
- package/src/server/claude-pty/sandbox/wrap.adapter.ts +0 -58
- package/src/server/claude-pty/sandbox/wrap.test.ts +0 -82
- package/src/server/claude-pty/settings-writer.adapter.ts +0 -23
- package/src/server/claude-pty/settings-writer.test.ts +0 -22
- package/src/server/claude-pty/smoke-test-io.adapter.ts +0 -28
- package/src/server/claude-pty/smoke-test.test.ts +0 -199
- package/src/server/claude-pty/smoke-test.ts +0 -182
- package/src/server/claude-pty/tui-control.test.ts +0 -300
- package/src/server/claude-pty/tui-control.ts +0 -174
- package/src/server/claude-pty/tui-source.adapter.test.ts +0 -374
- package/src/server/claude-pty/tui-source.adapter.ts +0 -294
- package/src/server/http-server.adapter.test.ts +0 -18
- package/src/server/http-server.adapter.ts +0 -39
- package/src/server/kanna-mcp-http.test.ts +0 -274
- package/src/server/kanna-mcp-http.ts +0 -194
- package/src/server/kanna-mcp-tools/ask-user-question.test.ts +0 -108
- package/src/server/kanna-mcp-tools/ask-user-question.ts +0 -55
- package/src/server/kanna-mcp-tools/exit-plan-mode.test.ts +0 -61
- package/src/server/kanna-mcp-tools/exit-plan-mode.ts +0 -49
- package/src/server/mcp-zod-compat.adapter.ts +0 -20
- package/src/shared/pty-instance.ts +0 -43
- /package/src/server/{claude-pty/output-ring.test.ts → output-ring.test.ts} +0 -0
- /package/src/server/{claude-pty/output-ring.ts → output-ring.ts} +0 -0
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
12
|
-
<em>
|
|
12
|
+
<em>OAuth token pooling, multi-provider chat (Claude + Codex + OpenRouter), subagent orchestration, custom MCP servers, a workflow status panel, durable tool-approval protocol, in-app self-update, and more.</em>
|
|
13
13
|
</p>
|
|
14
14
|
|
|
15
15
|
<p align="center">
|
|
@@ -41,12 +41,11 @@ Kanna (`@cuongtran001/kanna`) is a clean web UI for the Claude Code and Codex CL
|
|
|
41
41
|
|
|
42
42
|
**Headline features:**
|
|
43
43
|
|
|
44
|
-
- **Subscription-billing PTY driver** (`KANNA_CLAUDE_DRIVER=pty`) — runs the `claude` CLI under a pseudo-terminal so Pro/Max plans are charged instead of API rates. Parses the on-disk transcript JSONL as the sole event source, with HarnessEvent parity with the SDK driver, a cached per-spawn smoke-test gate, and failure-mode parity.
|
|
45
44
|
- **OAuth token pool** — register multiple Claude OAuth tokens; Kanna rotates across them per chat with automatic fallover on rate-limit and an explicit disabled state.
|
|
46
45
|
- **Multi-provider chat** — switch between Claude, Codex (OpenAI), and OpenRouter from the composer with per-provider model + reasoning-effort controls and Codex fast mode. OpenRouter populates its model picker live from the public catalog (tool-capable models).
|
|
47
46
|
- **Subagent orchestration** — first-class subagent CRUD, `@agent/` mentions, parallel runs, live activity labels, MCP progress notifications, and `mcp__kanna__delegate_subagent` so the main agent itself can delegate — including **keep-alive multi-turn** sessions (`send_subagent_message` / `close_subagent`) and **background** runs that report back as a fresh turn.
|
|
48
|
-
- **Custom MCP servers** — register your own `stdio` / `http` / `sse` / `ws` MCP servers from Settings (with OAuth 2.1 for network transports); they merge into
|
|
49
|
-
- **Workflow status panel** — read-only per-chat panel surfacing Claude Code's native Workflow tool runs (live status, drill-in progress, token totals) via disk-watch
|
|
47
|
+
- **Custom MCP servers** — register your own `stdio` / `http` / `sse` / `ws` MCP servers from Settings (with OAuth 2.1 for network transports); they merge into every Claude session and their tools surface as `mcp__<name>__<tool>`.
|
|
48
|
+
- **Workflow status panel** — read-only per-chat panel surfacing Claude Code's native Workflow tool runs (live status, drill-in progress, token totals) via disk-watch.
|
|
50
49
|
- **Agent self-scheduled wake** — `mcp__kanna__schedule_wakeup` lets the agent re-enter the chat to harvest long-running background work, with a runaway-loop cap.
|
|
51
50
|
- **Durable tool-approval protocol** (`KANNA_MCP_TOOL_CALLBACKS=1`) — pending `AskUserQuestion` / `ExitPlanMode` / built-in shims survive server restart and replay to the client on reconnect.
|
|
52
51
|
- **Cloudflare `expose_port` MCP tool** — agent-callable port exposure with always-ask or auto-expose modes, replacing bash-output sniffing.
|
|
@@ -82,8 +81,7 @@ That's it. Kanna opens in your browser at [`localhost:3210`](http://localhost:32
|
|
|
82
81
|
- **Multi-provider support** — switch between Claude, Codex (OpenAI), and OpenRouter from the chat input, with per-provider model selection, reasoning-effort controls, and Codex fast mode
|
|
83
82
|
- **OpenRouter** — set an OpenRouter API key in Settings; the model picker populates live from OpenRouter's catalog (tool-capable models), routed through its Anthropic-compatible endpoint
|
|
84
83
|
- **OAuth token pool** — register multiple Claude OAuth tokens; Kanna rotates across them per chat
|
|
85
|
-
- **
|
|
86
|
-
- **Custom MCP servers** — register `stdio` / `http` / `sse` / `ws` MCP servers from Settings (OAuth 2.1 for network transports); merged into both drivers
|
|
84
|
+
- **Custom MCP servers** — register `stdio` / `http` / `sse` / `ws` MCP servers from Settings (OAuth 2.1 for network transports); merged into every Claude session
|
|
87
85
|
|
|
88
86
|
**Chat & transcript**
|
|
89
87
|
|
|
@@ -163,7 +161,6 @@ flowchart LR
|
|
|
163
161
|
WS --> RM
|
|
164
162
|
Agent --> ES
|
|
165
163
|
Agent -.spawn.-> SpA
|
|
166
|
-
Agent -.spawn.-> PtyA
|
|
167
164
|
ES -.fs.-> FsA
|
|
168
165
|
Diff -.fs+spawn.-> SpA
|
|
169
166
|
Diff -.fs.-> FsA
|
|
@@ -181,7 +178,7 @@ flowchart LR
|
|
|
181
178
|
end
|
|
182
179
|
|
|
183
180
|
subgraph External["External processes"]
|
|
184
|
-
CC["Claude Agent SDK / claude CLI
|
|
181
|
+
CC["Claude Agent SDK / claude CLI"]
|
|
185
182
|
CX["Codex App Server"]
|
|
186
183
|
FS["Local FS<br/>~/.kanna/data/, project dirs"]
|
|
187
184
|
end
|
|
@@ -399,7 +396,6 @@ src/
|
|
|
399
396
|
│ ├── ws-router.ts WebSocket routing & subscriptions
|
|
400
397
|
│ ├── agent.ts AgentCoordinator (multi-provider turns)
|
|
401
398
|
│ ├── codex-app-server.ts Codex App Server JSON-RPC client
|
|
402
|
-
│ ├── claude-pty/ PTY driver (subscription billing)
|
|
403
399
|
│ ├── oauth-pool/ Claude OAuth token rotation
|
|
404
400
|
│ ├── provider-catalog.ts provider/model/effort normalization
|
|
405
401
|
│ ├── openrouter-models.ts live OpenRouter catalog (tool-capable models)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{o as e}from"./rolldown-runtime-C0FnF6B9.js";import{t}from"./react-DiVRNtpo.js";import{t as n}from"./jsx-runtime-BdxMnOeJ.js";import{c as r,i,m as a,t as o}from"./log-
|
|
1
|
+
import{o as e}from"./rolldown-runtime-C0FnF6B9.js";import{t}from"./react-DiVRNtpo.js";import{t as n}from"./jsx-runtime-BdxMnOeJ.js";import{c as r,i,m as a,t as o}from"./log-DnEvbp3E.js";import{a as s,c,i as l,n as u,r as d,s as f,t as p}from"./pendingActionsStore-CxhI19V9.js";import{t as m}from"./ellipsis-OHg0x_x1.js";import{t as h}from"./plus-D4CI6rj1.js";import{t as g}from"./input-DgW9uRZN.js";import{n as _,r as v,t as y}from"./popover-Bc646hKn.js";import{o as b,r as x,s as S,t as C}from"./columnStyle-CMCF0ds6.js";var w=e(t(),1),T=[],E=r()(e=>({templates:T,templatesStatus:`loading`,openMenuId:null,picking:!1,renamingId:null,error:null,setTemplates:t=>e({templates:Array.isArray(t)?t:[],templatesStatus:`ready`}),beginTemplatesLoad:()=>e({templatesStatus:`loading`}),failTemplatesLoad:()=>e({templatesStatus:`failed`}),openMenu:t=>e({openMenuId:t}),closeMenu:()=>e({openMenuId:null}),openPicker:()=>e({picking:!0,error:null}),closePicker:()=>e({picking:!1}),startRename:t=>e({renamingId:t,picking:!1,openMenuId:null}),stopRename:()=>e({renamingId:null}),setError:t=>e({error:t})}));function D(e){return e.templates}var O=e(n(),1),k=[`board.update`,`board.duplicate`,`board.saveAsTemplate`,`board.archive`];function A(e){return l(t=>k.some(n=>t.inFlight[p(n,e)]===!0))}function j({ownerKind:e,ownerId:t,ownerName:n,socket:r,onOpenBoard:c}){let l=x(e,t),f=S(b(l)),m=E(D),g=E(e=>e.picking),_=E(e=>e.renamingId),v=E(e=>e.error),y=E(e=>e.templatesStatus),C=p(`board.create`,l),T=d(C),{openPicker:k,closePicker:A,startRename:j,stopRename:N,setError:P,setTemplates:I}=E.getState();(0,w.useEffect)(()=>r.subscribe({type:`boards`,ownerKind:e,ownerId:t},e=>{S.getState().setBoards(x(e.ownerKind,e.ownerId),e.boards)}),[e,t,r]),(0,w.useEffect)(()=>{let e=!1,t=E.getState();return t.templatesStatus!==`ready`&&t.beginTemplatesLoad(),r.command({type:`board.templates.list`}).then(t=>{e||I(t)},a(t=>{o.error(i,`board.templates.list failed`,t),e||E.getState().failTemplatesLoad()})),()=>{e=!0}},[r,I]);let L=(0,w.useCallback)(async e=>{try{return await r.command(e),P(null),!0}catch(e){return P(e instanceof Error?e.message:`That did not work.`),!1}},[r,P]),R=(0,w.useCallback)(n=>{u(C,async()=>{await L({type:`board.create`,ownerKind:e,ownerId:t,title:n?n.name:`Untitled board`,templateId:n?.id??null})&&A()})},[A,C,e,t,L]),z=(0,w.useCallback)((e,t)=>{N();let n=t.trim();n!==``&&u(p(`board.update`,e),()=>L({type:`board.update`,boardId:e,title:n}))},[L,N]),B=g||f.length===0;return(0,O.jsxs)(`div`,{className:`flex min-h-0 min-w-0 flex-1 flex-col bg-background`,children:[(0,O.jsxs)(`header`,{className:`flex items-end justify-between gap-4 border-b border-border px-6 py-4`,children:[(0,O.jsxs)(`div`,{className:`min-w-0`,children:[(0,O.jsx)(`h1`,{className:`text-lg font-medium leading-tight tracking-[-0.01em] text-foreground`,children:`Boards`}),(0,O.jsxs)(`p`,{className:`truncate text-13 text-muted-foreground`,children:[n,f.length>0?(0,O.jsxs)(`span`,{className:`tabular-nums`,children:[` · `,f.length,` boards`]}):null]})]}),f.length>0?(0,O.jsxs)(s,{size:`sm`,onClick:k,pending:T,children:[(0,O.jsx)(h,{className:`size-3.5`}),`New board`]}):null]}),v?(0,O.jsx)(`p`,{className:`border-b border-border px-6 py-2 text-13 text-destructive-text`,children:v}):null,(0,O.jsxs)(`div`,{className:`min-h-0 flex-1 overflow-y-auto`,children:[B?(0,O.jsx)(F,{templates:m,templatesStatus:y,creating:T,firstRun:f.length===0,onPick:R,onCancel:A}):null,f.length>0?(0,O.jsx)(`ul`,{className:`px-4 py-1`,children:f.map(e=>(0,O.jsx)(M,{board:e,renaming:_===e.id,onOpen:c,onStartRename:j,onRename:z,onCancelRename:N,onCommand:L},e.id))}):null]})]})}function M({board:e,renaming:t,onOpen:n,onStartRename:r,onRename:i,onCancelRename:a,onCommand:o}){let s=A(e.id),c=(0,w.useCallback)(()=>n(e.id),[e.id,n]),l=(0,w.useCallback)(t=>{t.key===`Enter`&&i(e.id,t.currentTarget.value),t.key===`Escape`&&a()},[e.id,a,i]),u=(0,w.useCallback)(t=>i(e.id,t.currentTarget.value),[e.id,i]);return(0,O.jsxs)(`li`,{"aria-busy":s||void 0,className:`group grid grid-cols-[1fr_auto_auto] items-center gap-5 border-b border-border px-3 py-3 last:border-b-0 hover:bg-secondary`,children:[(0,O.jsx)(`div`,{className:`min-w-0`,children:t?(0,O.jsx)(g,{autoFocus:!0,defaultValue:e.title,onKeyDown:l,onBlur:u,className:`h-7 max-w-sm`,"aria-label":`Board name`}):(0,O.jsxs)(`button`,{type:`button`,onClick:c,className:`block w-full text-left`,children:[(0,O.jsx)(`span`,{className:`block truncate text-15 font-semibold tracking-[-0.005em] text-foreground`,children:e.title}),e.description?(0,O.jsx)(`span`,{className:`mt-0.5 block truncate text-13 text-muted-foreground`,children:e.description}):null]})}),(0,O.jsxs)(`div`,{className:`flex items-center gap-4 text-xs text-muted-foreground`,children:[(0,O.jsxs)(`span`,{children:[(0,O.jsx)(`b`,{className:`font-medium tabular-nums text-foreground`,children:e.columnCount}),` columns`]}),(0,O.jsxs)(`span`,{children:[(0,O.jsx)(`b`,{className:`font-medium tabular-nums text-foreground`,children:e.cardCount}),` cards`]})]}),(0,O.jsx)(N,{board:e,pending:s,onStartRename:r,onCommand:o})]})}function N({board:e,pending:t,onStartRename:n,onCommand:r}){let i=E(t=>t.openMenuId===e.id),{openMenu:a,closeMenu:o}=E.getState(),s=(0,w.useCallback)(t=>{t?a(e.id):o()},[e.id,o,a]),l=(0,w.useCallback)(()=>{o(),n(e.id)},[e.id,o,n]),d=(0,w.useCallback)(()=>{o(),u(p(`board.duplicate`,e.id),()=>r({type:`board.duplicate`,boardId:e.id,title:`${e.title} copy`}))},[e.id,e.title,o,r]),h=(0,w.useCallback)(()=>{o(),u(p(`board.saveAsTemplate`,e.id),()=>r({type:`board.saveAsTemplate`,boardId:e.id,name:e.title}))},[e.id,e.title,o,r]),g=(0,w.useCallback)(()=>{o(),u(p(`board.archive`,e.id),()=>r({type:`board.archive`,boardId:e.id}))},[e.id,o,r]);return(0,O.jsxs)(y,{open:i,onOpenChange:s,children:[(0,O.jsx)(v,{asChild:!0,children:(0,O.jsx)(`button`,{type:`button`,"aria-label":`Actions for ${e.title}`,disabled:t,"aria-busy":t||void 0,className:c(`rounded-md px-1.5 py-1 text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100 data-[state=open]:opacity-100`,t&&`opacity-100`),children:t?(0,O.jsx)(f,{className:`size-4`}):(0,O.jsx)(m,{className:`size-4`})})}),(0,O.jsxs)(_,{align:`end`,className:`w-56 p-1`,children:[(0,O.jsx)(P,{onClick:l,children:`Rename`}),(0,O.jsx)(P,{onClick:d,children:`Duplicate structure`}),(0,O.jsx)(P,{onClick:h,children:`Save as template`}),(0,O.jsx)(`div`,{className:`my-1 h-px bg-border`}),(0,O.jsx)(P,{onClick:g,tone:`destructive`,children:`Archive`})]})]})}function P({onClick:e,children:t,tone:n}){return(0,O.jsx)(`button`,{type:`button`,onClick:e,className:c(`flex w-full items-center rounded-sm px-2 py-1.5 text-left text-xs font-medium hover:bg-secondary`,n===`destructive`&&`text-destructive-text`),children:t})}function F({templates:e,templatesStatus:t,creating:n,firstRun:r,onPick:i,onCancel:a}){let o=(0,w.useCallback)(()=>i(null),[i]);return(0,O.jsxs)(`div`,{className:`px-6 py-8`,children:[r?(0,O.jsxs)(O.Fragment,{children:[(0,O.jsx)(`h2`,{className:`text-15 font-semibold text-foreground`,children:`No boards yet.`}),(0,O.jsx)(`p`,{className:`mt-1 max-w-[58ch] text-sm text-muted-foreground`,children:`A board turns issues into work your agents can pick up. Start from a shape, or import an existing tracker.`})]}):(0,O.jsx)(`h2`,{className:`text-15 font-semibold text-foreground`,children:`Start from a shape`}),(0,O.jsxs)(`div`,{className:`mt-4 max-w-xl rounded-lg border border-border`,"aria-busy":n||void 0,children:[e.map(e=>(0,O.jsx)(I,{template:e,disabled:n,onPick:i},e.id)),t===`loading`?(0,O.jsxs)(`p`,{role:`status`,className:`flex items-center gap-2 px-3.5 py-2.5 text-xs text-muted-foreground`,children:[(0,O.jsx)(f,{}),`Loading templates…`]}):null,t===`failed`?(0,O.jsx)(`p`,{className:`px-3.5 py-2.5 text-xs text-muted-foreground`,children:`Couldn't load templates.`}):null,(0,O.jsx)(`button`,{type:`button`,onClick:o,disabled:n,className:`flex w-full items-center border-t border-border px-3.5 py-2.5 text-left hover:bg-secondary disabled:pointer-events-none disabled:opacity-60`,children:(0,O.jsxs)(`span`,{children:[(0,O.jsx)(`span`,{className:`block text-sm font-medium text-foreground`,children:`Empty board`}),(0,O.jsx)(`span`,{className:`block text-xs text-muted-foreground`,children:`Name your own columns`})]})})]}),n?(0,O.jsxs)(`p`,{role:`status`,className:`mt-3 flex items-center gap-2 text-xs text-muted-foreground`,children:[(0,O.jsx)(f,{}),`Creating board…`]}):null,r?null:(0,O.jsx)(s,{variant:`ghost`,size:`sm`,className:`mt-3`,onClick:a,children:`Cancel`})]})}function I({template:e,disabled:t,onPick:n}){let r=(0,w.useCallback)(()=>n(e),[n,e]),i=e.definition.columns;return(0,O.jsxs)(`button`,{type:`button`,onClick:r,disabled:t,className:`flex w-full items-center gap-3 border-b border-border px-3.5 py-2.5 text-left last:border-b-0 hover:bg-secondary disabled:pointer-events-none disabled:opacity-60`,children:[(0,O.jsxs)(`span`,{className:`min-w-0`,children:[(0,O.jsx)(`span`,{className:`block text-sm font-medium text-foreground`,children:e.name}),(0,O.jsx)(`span`,{className:`block truncate text-xs text-muted-foreground`,children:i.map(e=>e.title).join(` · `)})]}),(0,O.jsx)(`span`,{"aria-hidden":!0,className:`ml-auto flex shrink-0 gap-1`,children:i.map((t,n)=>(0,O.jsx)(`span`,{className:c(`size-1.5 rounded-full`,t.colorToken?C[t.colorToken]:`bg-muted-icon`)},`${e.id}-${String(n)}`))})]})}export{j as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{o as e}from"./rolldown-runtime-C0FnF6B9.js";import{t}from"./react-DiVRNtpo.js";import{c as n,l as r,u as i}from"./chunk-OB3PAWPO-mARpRU1A.js";import{t as a}from"./jsx-runtime-BdxMnOeJ.js";import{a as o}from"./formatters-BGORekd-.js";import{t as s}from"./BoardsPage-AckCuswi.js";var c=e(t(),1),l=e(a(),1);function u(){let e=r(),t=n(),{projectId:a=``}=i(),u=[...e.sidebarData.starredProjectGroups,...e.sidebarData.projectGroups].find(e=>e.groupKey===a),d=u?o(u.localPath):`Project`,f=(0,c.useCallback)(e=>{t(`/boards/${a}/${e}`)},[t,a]);return(0,l.jsx)(`div`,{className:`relative flex min-h-0 min-w-0 flex-1 flex-col`,children:(0,l.jsx)(s,{ownerKind:`project`,ownerId:a,ownerName:d,socket:e.socket,onOpenBoard:f})})}export{u as BoardsRoutePage};
|