chatdeck 0.1.0__py3-none-any.whl
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.
- chatdeck/__init__.py +2 -0
- chatdeck/__main__.py +3 -0
- chatdeck/autostart.py +91 -0
- chatdeck/cli.py +152 -0
- chatdeck/config.py +34 -0
- chatdeck/demo.py +141 -0
- chatdeck/desktop.py +93 -0
- chatdeck/hooks.py +131 -0
- chatdeck/server.py +345 -0
- chatdeck/static/index.html +342 -0
- chatdeck/static/logo-192.png +0 -0
- chatdeck/static/logo-512.png +0 -0
- chatdeck/static/logo.ico +0 -0
- chatdeck/static/logo.svg +13 -0
- chatdeck/terminals.py +218 -0
- chatdeck/transcripts.py +216 -0
- chatdeck/usage.py +96 -0
- chatdeck/windows/bubble.ps1 +303 -0
- chatdeck/windows/focus_wt.ps1 +68 -0
- chatdeck/windows/start.ps1 +35 -0
- chatdeck-0.1.0.dist-info/METADATA +164 -0
- chatdeck-0.1.0.dist-info/RECORD +26 -0
- chatdeck-0.1.0.dist-info/WHEEL +5 -0
- chatdeck-0.1.0.dist-info/entry_points.txt +2 -0
- chatdeck-0.1.0.dist-info/licenses/LICENSE +21 -0
- chatdeck-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Brings the Windows Terminal tab titled $env:DASH_MARK to the front, on any virtual desktop, and
|
|
2
|
+
# optionally types $env:DASH_TYPE into it.
|
|
3
|
+
# Used by terminals.py; set $env:DASH_VDLIB to VirtualDesktopLib.cs to switch desktops reliably.
|
|
4
|
+
$m = $env:DASH_MARK; $lib = $env:DASH_VDLIB
|
|
5
|
+
Add-Type -AssemblyName UIAutomationClient, UIAutomationTypes
|
|
6
|
+
Add-Type @'
|
|
7
|
+
using System; using System.Text; using System.Runtime.InteropServices; using System.Collections.Generic;
|
|
8
|
+
public static class F {
|
|
9
|
+
delegate bool P(IntPtr h, IntPtr l);
|
|
10
|
+
[DllImport("user32.dll")] static extern bool EnumWindows(P cb, IntPtr l);
|
|
11
|
+
[DllImport("user32.dll", CharSet=CharSet.Unicode)] static extern int GetWindowText(IntPtr h, StringBuilder s, int n);
|
|
12
|
+
[DllImport("user32.dll", CharSet=CharSet.Unicode)] static extern int GetClassName(IntPtr h, StringBuilder s, int n);
|
|
13
|
+
[DllImport("user32.dll")] static extern bool IsIconic(IntPtr h);
|
|
14
|
+
[DllImport("user32.dll")] static extern bool ShowWindow(IntPtr h, int c);
|
|
15
|
+
[DllImport("user32.dll")] static extern bool SetForegroundWindow(IntPtr h);
|
|
16
|
+
[DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow();
|
|
17
|
+
[DllImport("user32.dll")] static extern void keybd_event(byte k, byte s, uint f, UIntPtr e);
|
|
18
|
+
[DllImport("dwmapi.dll")] static extern int DwmGetWindowAttribute(IntPtr h, int a, out int v, int s);
|
|
19
|
+
public static List<IntPtr> Terminals() { var r = new List<IntPtr>();
|
|
20
|
+
EnumWindows((h, l) => { var c = new StringBuilder(64); GetClassName(h, c, 64);
|
|
21
|
+
if (c.ToString() == "CASCADIA_HOSTING_WINDOW_CLASS") r.Add(h); return true; }, IntPtr.Zero); return r; }
|
|
22
|
+
public static string Title(IntPtr h) { var t = new StringBuilder(512); GetWindowText(h, t, 512); return t.ToString(); }
|
|
23
|
+
public static bool Cloaked(IntPtr h) { int v; DwmGetWindowAttribute(h, 14, out v, 4); return v != 0; } // on another virtual desktop
|
|
24
|
+
public static bool Raise(IntPtr h) {
|
|
25
|
+
if (IsIconic(h)) ShowWindow(h, 9);
|
|
26
|
+
keybd_event(0x12, 0, 0, UIntPtr.Zero); keybd_event(0x12, 0, 2, UIntPtr.Zero); // Alt tap lets us take focus
|
|
27
|
+
return SetForegroundWindow(h);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
'@
|
|
31
|
+
$vd = $false
|
|
32
|
+
function Show($h) {
|
|
33
|
+
if ([F]::Cloaked($h) -and $lib -and (Test-Path $lib)) {
|
|
34
|
+
if (-not $script:vd) { Add-Type -Path $lib; $script:vd = $true }
|
|
35
|
+
[VirtualDesktop.Desktop]::FromWindow($h).MakeVisible(); Start-Sleep -Milliseconds 250
|
|
36
|
+
}
|
|
37
|
+
[F]::Raise($h) | Out-Null
|
|
38
|
+
}
|
|
39
|
+
$A = [System.Windows.Automation.AutomationElement]
|
|
40
|
+
$tabCond = New-Object System.Windows.Automation.PropertyCondition($A::ControlTypeProperty, [System.Windows.Automation.ControlType]::TabItem)
|
|
41
|
+
function Tab($h) { # the tab carrying the mark, if this window's tabs are readable (not on another desktop)
|
|
42
|
+
foreach ($t in $A::FromHandle($h).FindAll([System.Windows.Automation.TreeScope]::Descendants, $tabCond)) { if ($t.Current.Name -eq $m) { return $t } }
|
|
43
|
+
}
|
|
44
|
+
function Done($h) {
|
|
45
|
+
# With $env:DASH_TYPE set, type that text into the chat and press Enter - but only once the chat's
|
|
46
|
+
# terminal really is the window in front, so keystrokes never land anywhere else.
|
|
47
|
+
if ($env:DASH_TYPE) {
|
|
48
|
+
Start-Sleep -Milliseconds 400
|
|
49
|
+
if ([F]::GetForegroundWindow() -ne $h) { "notfront"; exit }
|
|
50
|
+
Add-Type -AssemblyName System.Windows.Forms
|
|
51
|
+
[System.Windows.Forms.SendKeys]::SendWait($env:DASH_TYPE + "{ENTER}")
|
|
52
|
+
}
|
|
53
|
+
"ok"; exit
|
|
54
|
+
}
|
|
55
|
+
for ($i = 0; $i -lt 6; $i++) { # the terminal takes a moment to pick up the new title
|
|
56
|
+
$wins = [F]::Terminals()
|
|
57
|
+
foreach ($h in $wins) { if ([F]::Title($h) -eq $m) { Show $h; Done $h } }
|
|
58
|
+
foreach ($h in $wins) { if (-not [F]::Cloaked($h)) { $t = Tab $h; if ($t) {
|
|
59
|
+
$t.GetCurrentPattern([System.Windows.Automation.SelectionItemPattern]::Pattern).Select(); Show $h; Done $h } } }
|
|
60
|
+
Start-Sleep -Milliseconds 250
|
|
61
|
+
}
|
|
62
|
+
# Last resort: a background tab in a window on another desktop. Those tabs can only be read once
|
|
63
|
+
# the window is on screen, so visit each such window, then go back if the chat isn't there.
|
|
64
|
+
$back = [F]::GetForegroundWindow()
|
|
65
|
+
foreach ($h in $wins) { if ([F]::Cloaked($h)) { Show $h; Start-Sleep -Milliseconds 300; $t = Tab $h; if ($t) {
|
|
66
|
+
$t.GetCurrentPattern([System.Windows.Automation.SelectionItemPattern]::Pattern).Select(); Done $h } } }
|
|
67
|
+
if ($back -ne [IntPtr]::Zero) { Show $back }
|
|
68
|
+
"missing"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# chatdeck launcher for Windows (written by `chatdeck autostart on`): starts the chatdeck server
|
|
2
|
+
# in WSL if it isn't running, then the corner bubble and tray icon. With -Open it also opens the
|
|
3
|
+
# full dashboard window, or brings it forward if it's already open.
|
|
4
|
+
param([switch]$Open)
|
|
5
|
+
$Port = __PORT__
|
|
6
|
+
$Distro = "__DISTRO__"
|
|
7
|
+
$Cmd = "__CMD__"
|
|
8
|
+
$Url = "http://127.0.0.1:$Port/"
|
|
9
|
+
[System.Net.WebRequest]::DefaultWebProxy = $null
|
|
10
|
+
function Up { try { (Invoke-WebRequest -UseBasicParsing -TimeoutSec 2 $Url).Content -match "<title>chatdeck</title>" } catch { $false } }
|
|
11
|
+
|
|
12
|
+
if (-not (Up)) {
|
|
13
|
+
# A login shell, so the server finds `claude` on the same PATH as in a terminal.
|
|
14
|
+
Start-Process wsl.exe -ArgumentList "-d $Distro -- bash -lc ""$Cmd serve --port $Port""" -WindowStyle Hidden
|
|
15
|
+
for ($i = 0; $i -lt 60 -and -not (Up); $i++) { Start-Sleep -Milliseconds 500 }
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
Start-Process powershell.exe -WindowStyle Hidden -ArgumentList "-NoProfile", "-WindowStyle", "Hidden", "-ExecutionPolicy", "Bypass",
|
|
19
|
+
"-File", "$PSScriptRoot\bubble.ps1", "-Port", "$Port"
|
|
20
|
+
|
|
21
|
+
if ($Open) {
|
|
22
|
+
Add-Type -Namespace Chatdeck -Name W -MemberDefinition @'
|
|
23
|
+
[DllImport("user32.dll", CharSet=CharSet.Unicode)] public static extern IntPtr FindWindow(string c, string t);
|
|
24
|
+
[DllImport("user32.dll")] public static extern bool SetForegroundWindow(IntPtr h);
|
|
25
|
+
[DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr h, int c);
|
|
26
|
+
'@
|
|
27
|
+
$h = [Chatdeck.W]::FindWindow("Chrome_WidgetWin_1", "chatdeck")
|
|
28
|
+
if ($h -ne [IntPtr]::Zero) { [Chatdeck.W]::ShowWindow($h, 9) | Out-Null; [Chatdeck.W]::SetForegroundWindow($h) | Out-Null }
|
|
29
|
+
else {
|
|
30
|
+
$b = @("$env:ProgramFiles\Google\Chrome\Application\chrome.exe", "${env:ProgramFiles(x86)}\Google\Chrome\Application\chrome.exe",
|
|
31
|
+
"$env:LOCALAPPDATA\Google\Chrome\Application\chrome.exe", "${env:ProgramFiles(x86)}\Microsoft\Edge\Application\msedge.exe") |
|
|
32
|
+
Where-Object { Test-Path $_ } | Select-Object -First 1
|
|
33
|
+
if ($b) { Start-Process $b -ArgumentList "--app=$Url", "--window-size=520,900" } else { Start-Process $Url }
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: chatdeck
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A local dashboard for your Claude Code chats: what's running, what needs you, and what it costs.
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/Abdifatah09/chatdeck
|
|
7
|
+
Project-URL: Issues, https://github.com/Abdifatah09/chatdeck/issues
|
|
8
|
+
Keywords: claude,claude-code,dashboard,ai,cli
|
|
9
|
+
Classifier: Environment :: Console
|
|
10
|
+
Classifier: Environment :: Web Environment
|
|
11
|
+
Classifier: Operating System :: MacOS
|
|
12
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Requires-Python: >=3.9
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
License-File: LICENSE
|
|
17
|
+
Dynamic: license-file
|
|
18
|
+
|
|
19
|
+
# chatdeck
|
|
20
|
+
|
|
21
|
+
A local dashboard for your Claude Code chats: see which chats are running and which need you,
|
|
22
|
+
read and search old chats, track usage against your plan limits, and clean up transcripts.
|
|
23
|
+
Python 3.9+ standard library only, no dependencies.
|
|
24
|
+
|
|
25
|
+

|
|
26
|
+
|
|
27
|
+
## Features
|
|
28
|
+
|
|
29
|
+
- **Running now** – every live session with its context size and cost. Sessions stuck on a
|
|
30
|
+
permission prompt or a question get an amber **Waiting for you** badge and an optional chime.
|
|
31
|
+
**Open** jumps to the chat's terminal tab, **Rename** runs `/rename` in it so Claude names it after what it's about (double-click the name to type your own), and big chats get a
|
|
32
|
+
**Compact** button that runs `/compact`.
|
|
33
|
+
- **Saved chats** – read any chat without resuming it, search across all messages,
|
|
34
|
+
rename (so you know what's in it), export to Markdown, resume in a terminal, delete.
|
|
35
|
+
- **Usage** – tokens today and this week, top projects, 24h cost, and your 5-hour and weekly
|
|
36
|
+
limits with a forecast of when you'd hit them at the current pace.
|
|
37
|
+
- **Cleanup** – delete empty chats or chats older than 7, 30 or 90 days. Shows disk usage.
|
|
38
|
+
Running chats are never deleted.
|
|
39
|
+
- **By project** view: one section per project (git repo, including its worktrees and subfolders)
|
|
40
|
+
with its running and saved chats, and a **New chat** button that starts Claude Code in that project. Sort by recent, size, cost or messages. Light and dark themes.
|
|
41
|
+
Keyboard shortcuts: `/` search, `j`/`k` move, `Enter` read, `r` resume, `e` rename, `x` select, `Del` delete, `?` help.
|
|
42
|
+
- **Windows corner button and tray icon** – pop the dashboard up from the corner of the screen.
|
|
43
|
+
|
|
44
|
+
## Install
|
|
45
|
+
|
|
46
|
+
```sh
|
|
47
|
+
pipx install chatdeck # once it's on PyPI; until then:
|
|
48
|
+
pipx install git+https://github.com/Abdifatah09/chatdeck
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
No pip? Clone the repo and run `./install.sh`. It puts a `chatdeck` command in `~/.local/bin`
|
|
52
|
+
that runs straight from the clone.
|
|
53
|
+
|
|
54
|
+
## Try it first
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
chatdeck demo
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
opens chatdeck on a set of made-up chats (in a temporary folder, deleted when you stop it with Ctrl+C),
|
|
61
|
+
so you can click around without touching your own. The screenshots here are from the demo.
|
|
62
|
+
|
|
63
|
+
## Use
|
|
64
|
+
|
|
65
|
+
```sh
|
|
66
|
+
chatdeck # start the dashboard and open it
|
|
67
|
+
chatdeck setup # add the Claude Code hooks for plan limits and "waiting for you"
|
|
68
|
+
chatdeck autostart on # start it at login (Windows via WSL, macOS, Linux)
|
|
69
|
+
chatdeck bubble # Windows: the corner button and tray icon
|
|
70
|
+
chatdeck demo # try it with made-up chats
|
|
71
|
+
chatdeck stop # stop the background server
|
|
72
|
+
chatdeck uninstall # take the hooks and autostart out again
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
`chatdeck setup` keeps your existing status line: it saves the usage data first, then runs
|
|
76
|
+
yours, so your status line looks the same. `chatdeck uninstall` puts it back, and your previous
|
|
77
|
+
settings are backed up in `~/.chatdeck/backups`.
|
|
78
|
+
|
|
79
|
+
## Privacy and security
|
|
80
|
+
|
|
81
|
+
- Everything stays on your machine. chatdeck reads the transcripts Claude Code already writes to
|
|
82
|
+
`~/.claude/projects` and sends nothing anywhere: no accounts, no telemetry, no network calls
|
|
83
|
+
except to itself.
|
|
84
|
+
- The server binds to 127.0.0.1 only. Every API call needs a token that changes each run, sent in a
|
|
85
|
+
custom header, so other websites open in your browser can't call it.
|
|
86
|
+
- It only changes things you ask it to: deleting a chat removes its transcript (running chats are
|
|
87
|
+
never deleted), renaming adds a title line to it, and Rename and Compact on a running chat type
|
|
88
|
+
`/rename` or `/compact` into that chat's terminal, only while it's idle.
|
|
89
|
+
- `chatdeck setup` edits `~/.claude/settings.json` and backs it up first; `chatdeck uninstall` undoes it.
|
|
90
|
+
|
|
91
|
+
## See it in action
|
|
92
|
+
|
|
93
|
+
| Find any chat by what was said in it | Every project in one place |
|
|
94
|
+
|---|---|
|
|
95
|
+
|  |  |
|
|
96
|
+
|
|
97
|
+
| Keyboard only: `j`/`k`, `Enter`, `e` to rename, `?` for help | Running chats, at a glance |
|
|
98
|
+
|---|---|
|
|
99
|
+
|  |  |
|
|
100
|
+
|
|
101
|
+
## Screenshots
|
|
102
|
+
|
|
103
|
+

|
|
104
|
+
|
|
105
|
+
| By project | Reading a chat |
|
|
106
|
+
|---|---|
|
|
107
|
+
|  |  |
|
|
108
|
+
|
|
109
|
+
| Light theme | The Windows pop-up |
|
|
110
|
+
|---|---|
|
|
111
|
+
|  |  |
|
|
112
|
+
|
|
113
|
+
## Windows corner button and tray icon
|
|
114
|
+
|
|
115
|
+
A small always-on-top button sits in the bottom-left corner of the screen. Click it and the
|
|
116
|
+
dashboard pops up above it; click again, or anywhere else, and it tucks away. The badge counts
|
|
117
|
+
running chats and turns amber, with a pulsing ring, when one is waiting for you. Drag it to move
|
|
118
|
+
it; right-click to hide it or for more. The same badge sits in the notification area by the
|
|
119
|
+
clock, where a click pops the dashboard up in the bottom-right corner. It needs Chrome or Edge.
|
|
120
|
+
Start it with `chatdeck bubble`, or let `chatdeck autostart on` start it at login.
|
|
121
|
+
|
|
122
|
+
## Terminals
|
|
123
|
+
|
|
124
|
+
**Resume**, **Open** and **Agents view** open or find a terminal for you:
|
|
125
|
+
|
|
126
|
+
| Platform | Opens chats in | Open on a running chat |
|
|
127
|
+
|---|---|---|
|
|
128
|
+
| WSL | Windows Terminal (a new window each time) | finds its tab on any virtual desktop and switches to it |
|
|
129
|
+
| macOS | Terminal, or iTerm2 if you run the dashboard from it | finds its tab by tty |
|
|
130
|
+
| Linux | gnome-terminal, konsole, kitty, alacritty, wezterm, xfce4-terminal, tilix, foot or xterm | finds its window with `wmctrl` or `xdotool` (X11) |
|
|
131
|
+
|
|
132
|
+
When no terminal can be opened, the dashboard copies the command to paste instead.
|
|
133
|
+
Finding a running chat works by briefly giving its tab a unique title, so it doesn't work for
|
|
134
|
+
tabs whose title is locked (Windows Terminal's `suppressApplicationTitle`).
|
|
135
|
+
|
|
136
|
+
## Settings
|
|
137
|
+
|
|
138
|
+
Settings live in `~/.chatdeck/config.json`, and environment variables override them:
|
|
139
|
+
|
|
140
|
+
- `port` / `CHATDECK_PORT`: default 47123
|
|
141
|
+
- `terminal` / `CHATDECK_TERMINAL`: which terminal to use, e.g. `kitty` or `iterm`
|
|
142
|
+
- `tabs` / `CHATDECK_TABS` (WSL): `true` opens chats as tabs in your last Windows Terminal window instead of a new window each
|
|
143
|
+
- `vdlib` / `CHATDECK_VDLIB` (WSL): Windows path to [VirtualDesktopLib.cs](https://github.com/MScholtes/VirtualDesktop),
|
|
144
|
+
which makes switching to a chat on another virtual desktop reliable
|
|
145
|
+
- `CHATDECK_DIR`: where chatdeck keeps its data, default `~/.chatdeck`
|
|
146
|
+
|
|
147
|
+
## Tests
|
|
148
|
+
|
|
149
|
+
```sh
|
|
150
|
+
python3 -m unittest discover -s tests
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Screenshots and videos
|
|
154
|
+
|
|
155
|
+
Everything in `docs/` is recorded from `chatdeck demo` by a script, so it can be redone after UI changes
|
|
156
|
+
(needs Node; uses Segoe UI from `/mnt/c/Windows/Fonts` when run under WSL):
|
|
157
|
+
|
|
158
|
+
```sh
|
|
159
|
+
cd scripts/promo && npm install && npx playwright-core install chromium-headless-shell
|
|
160
|
+
npm run record # or just some: npm run record -- shots tour search projects keyboard
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
It writes the README screenshots to `docs/` and the GIFs, MP4s, framed screenshots and a 1280×640
|
|
164
|
+
social preview card to `docs/media/`.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
chatdeck/__init__.py,sha256=naiHQ5__Xp-CLtjKv2NWz_2wEw5fZbvWEKH0XniAy1A,79
|
|
2
|
+
chatdeck/__main__.py,sha256=bYt9eEaoRQWdejEHFD8REx9jxVEdZptECFsV7F49Ink,30
|
|
3
|
+
chatdeck/autostart.py,sha256=NjZtpNRYA48uCa_91AH80ktW0m2-m13AjtliLuvA8pU,5144
|
|
4
|
+
chatdeck/cli.py,sha256=bAjLmm1dSul18cjWUknidE-oHZmLa1kA2zCQyg8_uOM,7135
|
|
5
|
+
chatdeck/config.py,sha256=n8bjCfk9T-59EFeMzxUx3oiynPEm_vDBeHcgI5soTMM,1034
|
|
6
|
+
chatdeck/demo.py,sha256=B1fRshU4JW4bz6cEUG5-_RwFVqhR6O9vRrN6OvN1w5I,9906
|
|
7
|
+
chatdeck/desktop.py,sha256=HowVaaHvZW5GaAd2RBPwDJ57Qu_p_LUGweeoHYmMfg0,4669
|
|
8
|
+
chatdeck/hooks.py,sha256=KSBbqVpVHXWE-2AoscQaIpzhFfMOTjC_G94oeLxVTuI,5578
|
|
9
|
+
chatdeck/server.py,sha256=39TubZww5zeD4cD9hDwxbOnSBf_s78iNB63QPIMwZV8,18396
|
|
10
|
+
chatdeck/terminals.py,sha256=Ado3dn9OjoGo49NxyEd1YxpbK7FmAp2h-b02VKSRrAQ,9431
|
|
11
|
+
chatdeck/transcripts.py,sha256=bFoD53CluwSHzrRHSFzj_TWlU4zDzDVJHLBROSiJLMU,10158
|
|
12
|
+
chatdeck/usage.py,sha256=Hu7tmj0dJl8iNQtYwkw6BJhDU_K38oFqcoaImdPNfsA,4739
|
|
13
|
+
chatdeck/static/index.html,sha256=g7IUn3Rsblq5IzPvHUnIrbWz-w1UZCJx93NkZ5ssvEk,38412
|
|
14
|
+
chatdeck/static/logo-192.png,sha256=Dp9ZJJYHiG6GwTKX9vMCI69nn0Jr0jQowYvGjOumBXM,11287
|
|
15
|
+
chatdeck/static/logo-512.png,sha256=4_-BdCcVR5gqEBZvk5l6au_4w9Pv8cZmG0Sv2Rshsno,58695
|
|
16
|
+
chatdeck/static/logo.ico,sha256=qyXoiqBNwKAOkrDybrROQvIeEReKUhdQ7dv7Y1gId3A,21571
|
|
17
|
+
chatdeck/static/logo.svg,sha256=KVp6I1TbkePvfcG8ZMJ6OyNCG4QGBzk5a-7PN-DrkCo,740
|
|
18
|
+
chatdeck/windows/bubble.ps1,sha256=3KU5xGk4Ndz8zJ7ET4ULrMzJXr6L7DMCtgK0jlNy8ZM,18033
|
|
19
|
+
chatdeck/windows/focus_wt.ps1,sha256=5jg0slyKmKiRc98NI7L8iofbVxS1mpkmitbrc7OMLqk,4222
|
|
20
|
+
chatdeck/windows/start.ps1,sha256=8fOiuPPnOEeKFw6H4jp6UA1vmgSDn0HSFO7PkZTfnuo,2052
|
|
21
|
+
chatdeck-0.1.0.dist-info/licenses/LICENSE,sha256=MHNkmlUcd8LMZnGi58S4nAzCkH42kbjr2A0DxsLikWQ,1066
|
|
22
|
+
chatdeck-0.1.0.dist-info/METADATA,sha256=Vuhp42c0KiBR0sTcgW9wdWgQoqT2QFh9hSixZ4ebO48,8709
|
|
23
|
+
chatdeck-0.1.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
|
|
24
|
+
chatdeck-0.1.0.dist-info/entry_points.txt,sha256=b8jWrnNWd27e6Y8wookIN-9J1F4HWKp-GAUG46UudPo,47
|
|
25
|
+
chatdeck-0.1.0.dist-info/top_level.txt,sha256=LnJ9TcoohY4YMngg38zawhZVxAO6QB_9d3VHGQhglaU,9
|
|
26
|
+
chatdeck-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Abdifatah
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
chatdeck
|