paneful 0.6.0 → 0.6.1

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 CHANGED
@@ -37,6 +37,40 @@ paneful --list # List all projects
37
37
  paneful --kill my-project # Kill a project by name
38
38
  ```
39
39
 
40
+ ## Features
41
+
42
+ ### Drag & Drop Projects
43
+
44
+ Drag a folder from Finder into the sidebar to create a new project with the path pre-filled.
45
+
46
+ ### Drag Files into Terminals
47
+
48
+ Drag files from Finder or your editor (VS Code, Cursor) into a terminal pane to paste their paths as shell-escaped arguments.
49
+
50
+ ### Favourites
51
+
52
+ Save a workspace layout as a favourite — name, layout preset, and per-pane commands. Launch any favourite with a click to instantly recreate the setup. Managed from the star icon in the toolbar and the favourites section in the sidebar.
53
+
54
+ ### Editor Sync
55
+
56
+ Automatically switches the active project based on which editor window is in focus. Works with VS Code, Cursor, Zed, and Windsurf on macOS. Toggle via the monitor icon in the sidebar header.
57
+
58
+ Requires:
59
+ 1. Terminal app added to **System Settings > Privacy & Security > Accessibility**
60
+ 2. Editor window title includes the folder name (default in VS Code/Cursor)
61
+
62
+ ### Resizable Sidebar
63
+
64
+ Drag the right edge of the sidebar to resize it. Width persists across sessions.
65
+
66
+ ### Auto-Reorganize
67
+
68
+ Press `Cmd+R` or click the dashboard icon in the toolbar to automatically pick the best layout for your current pane count.
69
+
70
+ ### Update Notifications
71
+
72
+ Paneful checks for newer versions on npm and shows a notification in the sidebar when an update is available.
73
+
40
74
  ## Keyboard Shortcuts
41
75
 
42
76
  | Shortcut | Action |
@@ -327,9 +327,9 @@ WARNING: This link could potentially be dangerous`)){const o=window.open();if(o)
327
327
  transition-colors duration-150
328
328
  group-hover:bg-accent/60
329
329
  group-active:bg-accent
330
- `})]})}function zo({node:e,projectId:t,cwd:r,path:i=[]}){if(e.type==="leaf")return A.jsx(N_,{terminalId:e.terminalId,projectId:t,cwd:r});const n=e.direction==="vertical",h=`${e.ratio*100}%`,m=`${(1-e.ratio)*100}%`;return A.jsxs("div",{className:`flex ${n?"flex-row":"flex-col"} h-full w-full`,children:[A.jsx("div",{style:{flexBasis:h,minWidth:0,minHeight:0,overflow:"hidden"},className:"flex",children:A.jsx(zo,{node:e.first,projectId:t,cwd:r,path:[...i,0]})}),A.jsx(H_,{projectId:t,path:i,direction:e.direction}),A.jsx("div",{style:{flexBasis:m,minWidth:0,minHeight:0,overflow:"hidden"},className:"flex",children:A.jsx(zo,{node:e.second,projectId:t,cwd:r,path:[...i,1]})})]})}function F_(){const[e,t]=Q.useState(null);return Q.useEffect(()=>{let r=!1;return fetch("https://dummyjson.com/quotes/random").then(i=>i.json()).then(i=>{!r&&(i!=null&&i.quote)&&t({text:i.quote,author:i.author})}).catch(()=>{}),()=>{r=!0}},[]),e}function z_({onNewTerminal:e,projectName:t}){const r=F_();return A.jsx("div",{className:"h-full w-full flex items-center justify-center bg-[var(--surface-0)]",children:A.jsxs("div",{className:"flex flex-col items-center gap-6 text-center max-w-lg px-8",children:[A.jsx("div",{className:"w-16 h-16 rounded-2xl bg-[var(--surface-2)] border border-[var(--border)] flex items-center justify-center",children:A.jsx(Ha,{size:28,className:"text-[var(--text-muted)]"})}),A.jsxs("div",{children:[A.jsx("h2",{className:"text-lg font-medium text-[var(--text-primary)] mb-1",children:t??"No project selected"}),A.jsx("p",{className:"text-sm text-[var(--text-muted)]",children:t?"This project has no active terminals.":"Create a project to get started."})]}),t&&A.jsxs("button",{onClick:e,className:`
330
+ `})]})}function zo({node:e,projectId:t,cwd:r,path:i=[]}){if(e.type==="leaf")return A.jsx(N_,{terminalId:e.terminalId,projectId:t,cwd:r});const n=e.direction==="vertical",h=`${e.ratio*100}%`,m=`${(1-e.ratio)*100}%`;return A.jsxs("div",{className:`flex ${n?"flex-row":"flex-col"} h-full w-full`,children:[A.jsx("div",{style:{flexBasis:h,minWidth:0,minHeight:0,overflow:"hidden"},className:"flex",children:A.jsx(zo,{node:e.first,projectId:t,cwd:r,path:[...i,0]})}),A.jsx(H_,{projectId:t,path:i,direction:e.direction}),A.jsx("div",{style:{flexBasis:m,minWidth:0,minHeight:0,overflow:"hidden"},className:"flex",children:A.jsx(zo,{node:e.second,projectId:t,cwd:r,path:[...i,1]})})]})}function F_(){const[e,t]=Q.useState(null);return Q.useEffect(()=>{let r=!1;return Math.random()<.5?fetch("https://dummyjson.com/quotes/random").then(n=>n.json()).then(n=>{!r&&(n!=null&&n.quote)&&t({text:n.quote,attribution:n.author})}).catch(()=>{}):fetch("https://uselessfacts.jsph.pl/api/v2/facts/random?language=en").then(n=>n.json()).then(n=>{!r&&(n!=null&&n.text)&&t({text:n.text})}).catch(()=>{}),()=>{r=!0}},[]),e}function z_({onNewTerminal:e,projectName:t}){const r=F_();return A.jsx("div",{className:"h-full w-full flex items-center justify-center bg-[var(--surface-0)]",children:A.jsxs("div",{className:"flex flex-col items-center gap-6 text-center max-w-lg px-8",children:[A.jsx("div",{className:"w-16 h-16 rounded-2xl bg-[var(--surface-2)] border border-[var(--border)] flex items-center justify-center",children:A.jsx(Ha,{size:28,className:"text-[var(--text-muted)]"})}),A.jsxs("div",{children:[A.jsx("h2",{className:"text-lg font-medium text-[var(--text-primary)] mb-1",children:t??"No project selected"}),A.jsx("p",{className:"text-sm text-[var(--text-muted)]",children:t?"This project has no active terminals.":"Create a project to get started."})]}),t&&A.jsxs("button",{onClick:e,className:`
331
331
  flex items-center gap-2 px-4 py-2
332
332
  bg-accent hover:bg-accent/80
333
333
  text-white text-sm font-medium
334
334
  rounded-lg transition-colors
335
- `,children:[A.jsx(Na,{size:16}),"New Terminal"]}),r&&A.jsxs("div",{className:"mt-4 max-w-sm",children:[A.jsxs("p",{className:"text-sm italic text-[var(--text-muted)] leading-relaxed",children:['"',r.text,'"']}),A.jsxs("p",{className:"text-xs text-[var(--text-muted)]/60 mt-2",children:["— ",r.author]})]})]})})}function W_(){Yp(),Zp();const e=me(u=>u.activeProjectId),t=me(u=>u.activeProjectId?u.projects[u.activeProjectId]:null),r=ie(u=>e?u.getLayout(e):null),i=ne(u=>u.focusedTerminalId),n=ne(u=>u.setFocusedTerminal),h=me(u=>u.addTerminalToProject),m=Q.useCallback(u=>{if(!e||!t)return;const f=crypto.randomUUID(),g=Se(r),d=i??g[0];d?ie.getState().addPaneToProject(e,d,f,u):ie.getState().setLayout(e,{type:"leaf",terminalId:f}),h(e,f),n(f)},[e,t,r,i,h,n]),a=Q.useCallback(()=>{m("vertical")},[m]);return A.jsxs("div",{className:"flex h-screen w-screen overflow-hidden bg-[var(--surface-0)]",children:[A.jsx(E_,{}),A.jsxs("div",{className:"flex-1 flex flex-col min-w-0",children:[A.jsx(M_,{onNewPane:m}),A.jsx("div",{className:"flex-1 min-h-0 min-w-0",children:r?A.jsx(zo,{node:r,projectId:e,cwd:(t==null?void 0:t.cwd)??"/"},e):A.jsx(z_,{onNewTerminal:a,projectName:t==null?void 0:t.name})})]})]})}Hn.createRoot(document.getElementById("root")).render(A.jsx(pc.StrictMode,{children:A.jsx(W_,{})}));
335
+ `,children:[A.jsx(Na,{size:16}),"New Terminal"]}),r&&A.jsxs("div",{className:"mt-4 max-w-sm",children:[A.jsxs("p",{className:"text-sm italic text-[var(--text-muted)] leading-relaxed",children:['"',r.text,'"']}),r.attribution&&A.jsxs("p",{className:"text-xs text-[var(--text-muted)]/60 mt-2",children:["— ",r.attribution]})]})]})})}function W_(){Yp(),Zp();const e=me(u=>u.activeProjectId),t=me(u=>u.activeProjectId?u.projects[u.activeProjectId]:null),r=ie(u=>e?u.getLayout(e):null),i=ne(u=>u.focusedTerminalId),n=ne(u=>u.setFocusedTerminal),h=me(u=>u.addTerminalToProject),m=Q.useCallback(u=>{if(!e||!t)return;const f=crypto.randomUUID(),g=Se(r),d=i??g[0];d?ie.getState().addPaneToProject(e,d,f,u):ie.getState().setLayout(e,{type:"leaf",terminalId:f}),h(e,f),n(f)},[e,t,r,i,h,n]),a=Q.useCallback(()=>{m("vertical")},[m]);return A.jsxs("div",{className:"flex h-screen w-screen overflow-hidden bg-[var(--surface-0)]",children:[A.jsx(E_,{}),A.jsxs("div",{className:"flex-1 flex flex-col min-w-0",children:[A.jsx(M_,{onNewPane:m}),A.jsx("div",{className:"flex-1 min-h-0 min-w-0",children:r?A.jsx(zo,{node:r,projectId:e,cwd:(t==null?void 0:t.cwd)??"/"},e):A.jsx(z_,{onNewTerminal:a,projectName:t==null?void 0:t.name})})]})]})}Hn.createRoot(document.getElementById("root")).render(A.jsx(pc.StrictMode,{children:A.jsx(W_,{})}));
@@ -8,7 +8,7 @@
8
8
  <link rel="icon" type="image/png" sizes="192x192" href="/icon-192.png" />
9
9
  <link rel="apple-touch-icon" href="/icon-192.png" />
10
10
  <title>Paneful</title>
11
- <script type="module" crossorigin src="/assets/index-ARHWxBCC.js"></script>
11
+ <script type="module" crossorigin src="/assets/index-Dl99eb4x.js"></script>
12
12
  <link rel="stylesheet" crossorigin href="/assets/index-BzkRN-9o.css">
13
13
  </head>
14
14
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "paneful",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "Browser-based terminal multiplexer with tmux-style pane management",
5
5
  "type": "module",
6
6
  "bin": {