@fatdoge/wtree 0.1.9 → 0.1.10

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.
@@ -0,0 +1 @@
1
+ *,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.fixed{position:fixed}.inset-0{top:0;right:0;bottom:0;left:0}.z-50{z-index:50}.order-1{order:1}.order-2{order:2}.col-span-12{grid-column:span 12 / span 12}.col-span-2{grid-column:span 2 / span 2}.col-span-3{grid-column:span 3 / span 3}.col-span-5{grid-column:span 5 / span 5}.mx-auto{margin-left:auto;margin-right:auto}.mb-0\.5{margin-bottom:.125rem}.mb-4{margin-bottom:1rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-10{height:2.5rem}.h-4{height:1rem}.h-full{height:100%}.max-h-\[520px\]{max-height:520px}.w-4{width:1rem}.w-full{width:100%}.min-w-0{min-width:0px}.max-w-md{max-width:28rem}.max-w-screen-xl{max-width:1280px}.shrink-0{flex-shrink:0}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-t{border-top-width:1px}.border-slate-100{--tw-border-opacity: 1;border-color:rgb(241 245 249 / var(--tw-border-opacity, 1))}.border-slate-200{--tw-border-opacity: 1;border-color:rgb(226 232 240 / var(--tw-border-opacity, 1))}.border-slate-300{--tw-border-opacity: 1;border-color:rgb(203 213 225 / var(--tw-border-opacity, 1))}.bg-indigo-600{--tw-bg-opacity: 1;background-color:rgb(79 70 229 / var(--tw-bg-opacity, 1))}.bg-rose-100{--tw-bg-opacity: 1;background-color:rgb(255 228 230 / var(--tw-bg-opacity, 1))}.bg-rose-600{--tw-bg-opacity: 1;background-color:rgb(225 29 72 / var(--tw-bg-opacity, 1))}.bg-slate-100{--tw-bg-opacity: 1;background-color:rgb(241 245 249 / var(--tw-bg-opacity, 1))}.bg-slate-50{--tw-bg-opacity: 1;background-color:rgb(248 250 252 / var(--tw-bg-opacity, 1))}.bg-slate-900\/50{background-color:#0f172a80}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.pt-2{padding-top:.5rem}.text-right{text-align:right}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-\[11px\]{font-size:11px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.text-emerald-600{--tw-text-opacity: 1;color:rgb(5 150 105 / var(--tw-text-opacity, 1))}.text-rose-600{--tw-text-opacity: 1;color:rgb(225 29 72 / var(--tw-text-opacity, 1))}.text-slate-400{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity, 1))}.text-slate-500{--tw-text-opacity: 1;color:rgb(100 116 139 / var(--tw-text-opacity, 1))}.text-slate-600{--tw-text-opacity: 1;color:rgb(71 85 105 / var(--tw-text-opacity, 1))}.text-slate-700{--tw-text-opacity: 1;color:rgb(51 65 85 / var(--tw-text-opacity, 1))}.text-slate-900{--tw-text-opacity: 1;color:rgb(15 23 42 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}:root{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Noto Sans,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";line-height:1.5;font-weight:400;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}html,body,#root{height:100%}body{--tw-bg-opacity: 1;background-color:rgb(248 250 252 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(15 23 42 / var(--tw-text-opacity, 1))}body:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(2 6 23 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(226 232 240 / var(--tw-text-opacity, 1))}.placeholder\:text-slate-400::-moz-placeholder{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity, 1))}.placeholder\:text-slate-400::placeholder{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity, 1))}.hover\:bg-indigo-700:hover{--tw-bg-opacity: 1;background-color:rgb(67 56 202 / var(--tw-bg-opacity, 1))}.hover\:bg-rose-700:hover{--tw-bg-opacity: 1;background-color:rgb(190 18 60 / var(--tw-bg-opacity, 1))}.hover\:bg-slate-100:hover{--tw-bg-opacity: 1;background-color:rgb(241 245 249 / var(--tw-bg-opacity, 1))}.hover\:bg-slate-200:hover{--tw-bg-opacity: 1;background-color:rgb(226 232 240 / var(--tw-bg-opacity, 1))}.hover\:bg-slate-50:hover{--tw-bg-opacity: 1;background-color:rgb(248 250 252 / var(--tw-bg-opacity, 1))}.hover\:text-slate-600:hover{--tw-text-opacity: 1;color:rgb(71 85 105 / var(--tw-text-opacity, 1))}.hover\:text-slate-900:hover{--tw-text-opacity: 1;color:rgb(15 23 42 / var(--tw-text-opacity, 1))}.focus\:border-indigo-500:focus{--tw-border-opacity: 1;border-color:rgb(99 102 241 / var(--tw-border-opacity, 1))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-1:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-indigo-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(99 102 241 / var(--tw-ring-opacity, 1))}.focus\:ring-slate-400:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(148 163 184 / var(--tw-ring-opacity, 1))}.focus\:ring-offset-2:focus{--tw-ring-offset-width: 2px}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.dark\:border-slate-700:is(.dark *){--tw-border-opacity: 1;border-color:rgb(51 65 85 / var(--tw-border-opacity, 1))}.dark\:border-slate-800:is(.dark *){--tw-border-opacity: 1;border-color:rgb(30 41 59 / var(--tw-border-opacity, 1))}.dark\:border-slate-800\/50:is(.dark *){border-color:#1e293b80}.dark\:bg-black\/50:is(.dark *){background-color:#00000080}.dark\:bg-indigo-500:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(99 102 241 / var(--tw-bg-opacity, 1))}.dark\:bg-rose-500:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(244 63 94 / var(--tw-bg-opacity, 1))}.dark\:bg-rose-500\/10:is(.dark *){background-color:#f43f5e1a}.dark\:bg-slate-800:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(30 41 59 / var(--tw-bg-opacity, 1))}.dark\:bg-slate-900:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(15 23 42 / var(--tw-bg-opacity, 1))}.dark\:bg-slate-900\/60:is(.dark *){background-color:#0f172a99}.dark\:bg-slate-950:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(2 6 23 / var(--tw-bg-opacity, 1))}.dark\:text-emerald-400:is(.dark *){--tw-text-opacity: 1;color:rgb(52 211 153 / var(--tw-text-opacity, 1))}.dark\:text-rose-400:is(.dark *){--tw-text-opacity: 1;color:rgb(251 113 133 / var(--tw-text-opacity, 1))}.dark\:text-slate-100:is(.dark *){--tw-text-opacity: 1;color:rgb(241 245 249 / var(--tw-text-opacity, 1))}.dark\:text-slate-200:is(.dark *){--tw-text-opacity: 1;color:rgb(226 232 240 / var(--tw-text-opacity, 1))}.dark\:text-slate-300:is(.dark *){--tw-text-opacity: 1;color:rgb(203 213 225 / var(--tw-text-opacity, 1))}.dark\:text-slate-400:is(.dark *){--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity, 1))}.dark\:text-slate-500:is(.dark *){--tw-text-opacity: 1;color:rgb(100 116 139 / var(--tw-text-opacity, 1))}.dark\:placeholder\:text-slate-500:is(.dark *)::-moz-placeholder{--tw-text-opacity: 1;color:rgb(100 116 139 / var(--tw-text-opacity, 1))}.dark\:placeholder\:text-slate-500:is(.dark *)::placeholder{--tw-text-opacity: 1;color:rgb(100 116 139 / var(--tw-text-opacity, 1))}.dark\:hover\:bg-indigo-600:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(79 70 229 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-rose-600:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(225 29 72 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-slate-700:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(51 65 85 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-slate-800:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(30 41 59 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-slate-900\/40:hover:is(.dark *){background-color:#0f172a66}.dark\:hover\:text-slate-100:hover:is(.dark *){--tw-text-opacity: 1;color:rgb(241 245 249 / var(--tw-text-opacity, 1))}.dark\:hover\:text-slate-200:hover:is(.dark *){--tw-text-opacity: 1;color:rgb(226 232 240 / var(--tw-text-opacity, 1))}.dark\:focus\:border-indigo-500:focus:is(.dark *){--tw-border-opacity: 1;border-color:rgb(99 102 241 / var(--tw-border-opacity, 1))}.dark\:focus\:ring-indigo-500:focus:is(.dark *){--tw-ring-opacity: 1;--tw-ring-color: rgb(99 102 241 / var(--tw-ring-opacity, 1))}.dark\:focus\:ring-slate-700:focus:is(.dark *){--tw-ring-opacity: 1;--tw-ring-color: rgb(51 65 85 / var(--tw-ring-opacity, 1))}@media(min-width:640px){.sm\:w-auto{width:auto}.sm\:flex-row{flex-direction:row}.sm\:justify-end{justify-content:flex-end}}@media(min-width:768px){.md\:mt-0{margin-top:0}.md\:block{display:block}.md\:inline{display:inline}.md\:grid{display:grid}.md\:hidden{display:none}.md\:grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.md\:justify-end{justify-content:flex-end}.md\:border-b-0{border-bottom-width:0px}.md\:py-2{padding-top:.5rem;padding-bottom:.5rem}}@media(min-width:1024px){.lg\:order-1{order:1}.lg\:order-2{order:2}.lg\:col-span-3{grid-column:span 3 / span 3}.lg\:col-span-5{grid-column:span 5 / span 5}.lg\:col-span-6{grid-column:span 6 / span 6}.lg\:col-span-7{grid-column:span 7 / span 7}.lg\:col-span-9{grid-column:span 9 / span 9}.lg\:mb-0{margin-bottom:0}}
package/dist/index.html CHANGED
@@ -5,8 +5,8 @@
5
5
  <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>TreeLab - Git Worktree Manager</title>
8
- <script type="module" crossorigin src="/assets/index-AspflbWf.js"></script>
9
- <link rel="stylesheet" crossorigin href="/assets/index-DXiZ6dVD.css">
8
+ <script type="module" crossorigin src="/assets/index-C78PMV-C.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-CR9jga1C.css">
10
10
  </head>
11
11
  <body>
12
12
  <div id="root"></div>
File without changes
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fatdoge/wtree",
3
3
  "private": false,
4
- "version": "0.1.9",
4
+ "version": "0.1.10",
5
5
  "description": "CLI + UI tool for managing git worktrees",
6
6
  "keywords": [
7
7
  "git",
@@ -37,19 +37,6 @@
37
37
  "README.md",
38
38
  "LICENSE"
39
39
  ],
40
- "scripts": {
41
- "client:dev": "vite",
42
- "build:ui": "vite build",
43
- "build:cli": "tsc -p tsconfig.node.json",
44
- "build": "pnpm run build:cli && pnpm run build:ui",
45
- "lint": "eslint .",
46
- "preview": "vite preview",
47
- "check": "tsc --noEmit && tsc -p tsconfig.node.json --noEmit",
48
- "server:dev": "nodemon",
49
- "dev": "concurrently \"pnpm run client:dev\" \"pnpm run server:dev\"",
50
- "wtree": "tsx api/cli/wtree.ts",
51
- "test": "vitest run"
52
- },
53
40
  "dependencies": {
54
41
  "@vitejs/plugin-react": "^4.4.1",
55
42
  "autoprefixer": "^10.4.21",
@@ -68,6 +55,7 @@
68
55
  "react-i18next": "^16.5.7",
69
56
  "react-router-dom": "^7.3.0",
70
57
  "serve-static": "^2.2.1",
58
+ "sonner": "^2.0.7",
71
59
  "tailwind-merge": "^3.0.2",
72
60
  "tailwindcss": "^3.4.17",
73
61
  "vite": "^6.3.5",
@@ -94,5 +82,18 @@
94
82
  "typescript": "~5.8.3",
95
83
  "typescript-eslint": "^8.30.1",
96
84
  "vitest": "^2.1.9"
85
+ },
86
+ "scripts": {
87
+ "client:dev": "vite",
88
+ "build:ui": "vite build",
89
+ "build:cli": "tsc -p tsconfig.node.json",
90
+ "build": "pnpm run build:cli && pnpm run build:ui",
91
+ "lint": "eslint .",
92
+ "preview": "vite preview",
93
+ "check": "tsc --noEmit && tsc -p tsconfig.node.json --noEmit",
94
+ "server:dev": "nodemon",
95
+ "dev": "concurrently \"pnpm run client:dev\" \"pnpm run server:dev\"",
96
+ "wtree": "tsx api/cli/wtree.ts",
97
+ "test": "vitest run"
97
98
  }
98
- }
99
+ }
package/src/App.tsx CHANGED
@@ -4,7 +4,7 @@ import Worktrees from "@/pages/Worktrees";
4
4
  import CreateWorktree from "@/pages/CreateWorktree";
5
5
  import SettingsPage from "@/pages/SettingsPage";
6
6
  import HelpPage from "@/pages/HelpPage";
7
- import ToastHost from "@/components/ToastHost";
7
+ import { Toaster } from "sonner";
8
8
  import { useThemeStore } from "@/stores/themeStore";
9
9
 
10
10
  export default function App() {
@@ -16,7 +16,7 @@ export default function App() {
16
16
 
17
17
  return (
18
18
  <Router>
19
- <ToastHost />
19
+ <Toaster position="top-right" richColors theme="system" />
20
20
  <Routes>
21
21
  <Route path="/" element={<Worktrees />} />
22
22
  <Route path="/create" element={<CreateWorktree />} />
@@ -4,9 +4,9 @@ import { Link, useNavigate } from 'react-router-dom'
4
4
  import { useTranslation } from 'react-i18next'
5
5
  import Button from '@/components/Button'
6
6
  import Input from '@/components/Input'
7
- import { useToastStore } from '@/stores/toastStore'
8
7
  import { useWorktreeStore } from '@/stores/worktreeStore'
9
8
  import type { CreateWorktreeRequest } from '../../shared/wtui-types'
9
+ import { toast } from 'sonner'
10
10
 
11
11
  type Mode = 'existing' | 'new'
12
12
 
@@ -16,7 +16,6 @@ export default function CreateWorktree() {
16
16
  const create = useWorktreeStore((s) => s.create)
17
17
  const branches = useWorktreeStore((s) => s.branches)
18
18
  const fetchBranches = useWorktreeStore((s) => s.fetchBranches)
19
- const toast = useToastStore((s) => s.push)
20
19
 
21
20
  useEffect(() => {
22
21
  fetchBranches()
@@ -51,14 +50,14 @@ export default function CreateWorktree() {
51
50
  }
52
51
  const created = await create(payload)
53
52
  if (!created) {
54
- toast({ type: 'error', title: '创建失败' })
53
+ toast.error('创建失败')
55
54
  return
56
55
  }
57
56
  setResultPath(created.path)
58
- toast({ type: 'success', title: '创建成功' })
57
+ toast.success('创建成功')
59
58
  } catch (e: unknown) {
60
59
  const msg = e instanceof Error ? e.message : String(e)
61
- toast({ type: 'error', title: '创建失败', detail: msg })
60
+ toast.error('创建失败', { description: msg })
62
61
  } finally {
63
62
  setSubmitting(false)
64
63
  }
@@ -4,15 +4,14 @@ import { Link } from 'react-router-dom'
4
4
  import { useTranslation } from 'react-i18next'
5
5
  import Button from '@/components/Button'
6
6
  import Input from '@/components/Input'
7
- import { useToastStore } from '@/stores/toastStore'
8
7
  import { useWorktreeStore } from '@/stores/worktreeStore'
9
8
  import { useThemeStore } from '@/stores/themeStore'
10
9
  import { apiGet, apiPut } from '@/utils/api'
11
10
  import type { WtuiConfig } from '../../shared/wtui-types'
11
+ import { toast } from 'sonner'
12
12
 
13
13
  export default function SettingsPage() {
14
14
  const { t, i18n } = useTranslation()
15
- const toast = useToastStore((s) => s.push)
16
15
  const prune = useWorktreeStore((s) => s.prune)
17
16
  const { theme, setTheme } = useThemeStore()
18
17
  const [cfg, setCfg] = useState<WtuiConfig>({})
@@ -34,11 +33,11 @@ export default function SettingsPage() {
34
33
  const r = await apiPut<WtuiConfig, WtuiConfig>('/api/config', cfg)
35
34
  if (!r.ok) {
36
35
  const msg = (r as { ok: false; error: { message: string } }).error.message
37
- toast({ type: 'error', title: t('settings.toast.saveFailed'), detail: msg })
36
+ toast.error(t('settings.toast.saveFailed'), { description: msg })
38
37
  return
39
38
  }
40
39
  setCfg(r.data)
41
- toast({ type: 'success', title: t('settings.toast.saveSuccess') })
40
+ toast.success(t('settings.toast.saveSuccess'))
42
41
  } finally {
43
42
  setLoading(false)
44
43
  }
@@ -51,11 +50,11 @@ export default function SettingsPage() {
51
50
  const r = await apiPut<WtuiConfig, WtuiConfig>('/api/config', {})
52
51
  if (!r.ok) {
53
52
  const msg = (r as { ok: false; error: { message: string } }).error.message
54
- toast({ type: 'error', title: t('settings.toast.resetFailed', '重置失败'), detail: msg })
53
+ toast.error(t('settings.toast.resetFailed', '重置失败'), { description: msg })
55
54
  return
56
55
  }
57
56
  setCfg(r.data)
58
- toast({ type: 'info', title: t('settings.toast.resetSuccess', '已重置') })
57
+ toast.info(t('settings.toast.resetSuccess', '已重置'))
59
58
  } finally {
60
59
  setLoading(false)
61
60
  }
@@ -65,7 +64,11 @@ export default function SettingsPage() {
65
64
  setPruning(true)
66
65
  try {
67
66
  const ok = await prune()
68
- toast({ type: ok ? 'success' : 'error', title: ok ? t('settings.toast.pruneSuccess') : t('settings.toast.pruneFailed') })
67
+ if (ok) {
68
+ toast.success(t('settings.toast.pruneSuccess'))
69
+ } else {
70
+ toast.error(t('settings.toast.pruneFailed'))
71
+ }
69
72
  } finally {
70
73
  setPruning(false)
71
74
  }
@@ -4,8 +4,8 @@ import { Link } from 'react-router-dom'
4
4
  import { useTranslation } from 'react-i18next'
5
5
  import Button from '@/components/Button'
6
6
  import Modal from '@/components/Modal'
7
- import { useToastStore } from '@/stores/toastStore'
8
7
  import { useWorktreeStore } from '@/stores/worktreeStore'
8
+ import { toast } from 'sonner'
9
9
 
10
10
  function truncatePath(p: string) {
11
11
  if (p.length <= 70) return p
@@ -23,7 +23,6 @@ export default function Worktrees() {
23
23
  const open = useWorktreeStore((s) => s.open)
24
24
  const lock = useWorktreeStore((s) => s.lock)
25
25
  const unlock = useWorktreeStore((s) => s.unlock)
26
- const toast = useToastStore((s) => s.push)
27
26
 
28
27
  const [removeId, setRemoveId] = useState<string | null>(null)
29
28
  const [forceDelete, setForceDelete] = useState(false)
@@ -47,24 +46,20 @@ export default function Worktrees() {
47
46
  try {
48
47
  const res = await remove(removeId, forceDelete)
49
48
  if (res.success) {
50
- toast({ type: 'success', title: forceDelete ? t('worktrees.toast.forceDeleteSuccess') : t('worktrees.toast.deleteSuccess') })
49
+ toast.success(forceDelete ? t('worktrees.toast.forceDeleteSuccess') : t('worktrees.toast.deleteSuccess'))
51
50
  closeModal()
52
51
  } else {
53
52
  const msg = res.error || ''
54
53
  if (msg.toLowerCase().includes('force') || msg.includes('modified') || msg.includes('untracked')) {
55
54
  setForceDelete(true)
56
- toast({
57
- type: 'error',
58
- title: t('worktrees.toast.deleteFailed'),
59
- detail: t('worktrees.toast.deleteWarning'),
60
- })
55
+ toast.error(t('worktrees.toast.deleteFailed'), { description: t('worktrees.toast.deleteWarning') })
61
56
  } else {
62
- toast({ type: 'error', title: t('worktrees.toast.deleteFailed'), detail: msg })
57
+ toast.error(t('worktrees.toast.deleteFailed'), { description: msg })
63
58
  }
64
59
  }
65
60
  } catch (e: unknown) {
66
61
  const msg = e instanceof Error ? e.message : String(e)
67
- toast({ type: 'error', title: t('worktrees.toast.deleteFailed'), detail: msg })
62
+ toast.error(t('worktrees.toast.deleteFailed'), { description: msg })
68
63
  } finally {
69
64
  setIsDeleting(false)
70
65
  }
@@ -73,9 +68,9 @@ export default function Worktrees() {
73
68
  const onCopy = async (text: string) => {
74
69
  try {
75
70
  await navigator.clipboard.writeText(text)
76
- toast({ type: 'success', title: t('worktrees.toast.copySuccess') })
71
+ toast.success(t('worktrees.toast.copySuccess'))
77
72
  } catch {
78
- toast({ type: 'error', title: t('worktrees.toast.copyFailed') })
73
+ toast.error(t('worktrees.toast.copyFailed'))
79
74
  }
80
75
  }
81
76
 
@@ -177,10 +172,9 @@ export default function Worktrees() {
177
172
  onClick={(e) => {
178
173
  e.stopPropagation()
179
174
  open(wt.id).then((ok) =>
180
- toast({
181
- type: ok ? 'success' : 'error',
182
- title: ok ? t('worktrees.toast.folderSuccess') : t('worktrees.toast.folderFailed'),
183
- }),
175
+ ok
176
+ ? toast.success(t('worktrees.toast.folderSuccess'))
177
+ : toast.error(t('worktrees.toast.folderFailed')),
184
178
  )
185
179
  }}
186
180
  >
@@ -255,10 +249,7 @@ export default function Worktrees() {
255
249
  const msg = selected.isLocked ? t('worktrees.toast.unlockSuccess') : t('worktrees.toast.lockSuccess')
256
250
  const msgFail = selected.isLocked ? t('worktrees.toast.unlockFailed') : t('worktrees.toast.lockFailed')
257
251
  action(selected.id).then((ok) =>
258
- toast({
259
- type: ok ? 'success' : 'error',
260
- title: ok ? msg : msgFail,
261
- }),
252
+ ok ? toast.success(msg) : toast.error(msgFail),
262
253
  )
263
254
  }}
264
255
  >
@@ -271,10 +262,7 @@ export default function Worktrees() {
271
262
  size="sm"
272
263
  onClick={() =>
273
264
  open(selected.id, 'editor').then((ok) =>
274
- toast({
275
- type: ok ? 'success' : 'error',
276
- title: ok ? t('worktrees.toast.ideSuccess') : t('worktrees.toast.ideFailed'),
277
- }),
265
+ ok ? toast.success(t('worktrees.toast.ideSuccess')) : toast.error(t('worktrees.toast.ideFailed')),
278
266
  )
279
267
  }
280
268
  >
@@ -287,10 +275,7 @@ export default function Worktrees() {
287
275
  size="sm"
288
276
  onClick={() =>
289
277
  open(selected.id, 'folder').then((ok) =>
290
- toast({
291
- type: ok ? 'success' : 'error',
292
- title: ok ? t('worktrees.toast.folderSuccess') : t('worktrees.toast.folderFailed'),
293
- }),
278
+ ok ? toast.success(t('worktrees.toast.folderSuccess')) : toast.error(t('worktrees.toast.folderFailed')),
294
279
  )
295
280
  }
296
281
  >
@@ -351,4 +336,3 @@ export default function Worktrees() {
351
336
  </div>
352
337
  )
353
338
  }
354
-