Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .claude/settings.local.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
"Bash(git log:*)",
"Bash(ls -la \"C:\\\\Users\\\\halil\\\\tabbyspaces\\\\screenshots\"\" 2>nul || echo \"Directory not found \")",
"Bash(dir:*)",
"Bash(cmd.exe /c start \"\" \"C:\\\\Program Files \\(x86\\)\\\\Tabby\\\\Tabby.exe\" --remote-debugging-port=9222)"
"Bash(cmd.exe /c start \"\" \"C:\\\\Program Files \\(x86\\)\\\\Tabby\\\\Tabby.exe\" --remote-debugging-port=9222)",
"Bash(ls:*)"
Comment on lines 31 to +35
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.claude/settings.local.json contains local-machine command allowlists and absolute Windows paths. This looks like developer-local tooling config and is likely not intended to be tracked in the release branch. Consider removing it from the repo and adding .claude/ (or at least settings.local.json) to .gitignore, similar to how .mcp.json is handled.

Copilot uses AI. Check for mistakes.
]
},
"enableAllProjectMcpServers": true,
Expand Down
26 changes: 26 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: CI

on:
push:
branches: [dev]
pull_request:
branches: [main]
Comment on lines +3 to +7
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI is configured to run on pull_request only for main, but CONTRIBUTING says all PRs target dev. As written, PRs into dev won’t get CI checks (only pushes to the dev branch do). Consider changing pull_request.branches to include dev (and optionally main) so PRs are validated before merge.

Copilot uses AI. Check for mistakes.

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'

- name: Install dependencies
run: npm ci --legacy-peer-deps

- name: Build
run: npm run build
30 changes: 30 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Release

on:
push:
branches: [main]

jobs:
publish:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
registry-url: 'https://registry.npmjs.org'

- name: Install dependencies
run: npm ci --legacy-peer-deps

- name: Build
run: npm run build

- name: Publish to npm
run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
46 changes: 46 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,51 @@
# Changelog

## [0.2.0] - 2026-01-26

### Design

- **S1 "Tight & Sharp" UI redesign**
- Tab bar navigation replaces vertical workspace list
- Inline pane editor replaces modal overlay
- Section-based layout with uppercase titles
- Reorganized preview toolbar with icon buttons
- 2-column form grid in pane editor
- Refactor SCSS to modular DRY architecture
- Shared variables: spacing scale, border radius, colors, z-index
- Reusable mixins: flex-row, form-input, interactive-card, toolbar-btn
- All components migrated to use shared styles
- Add design system documentation (docs/DESIGN.md)
- Add HTML mockups for design exploration

### Reliability

- Improved duplicate workspace detection on Tabby restart
- Add workspaceId to recovery tokens
- Two-strategy detection (restored tabs + freshly opened)
- Better shell initialization with 2s timeout and error handling
- Wait for Tabby recovery before launching startup workspaces
- Type-safe workspace detection with proper type guards

### Bug Fixes

- Fix focus lost after workspace delete (NgbModal replaces native confirm)
- Fix split preview change detection (remove OnPush strategy)
- Fix race condition in shell initialization

### Infrastructure

- Add CI/CD workflows (GitHub Actions for build + release)
- Add dev branch workflow documentation

### Technical

- Code review cleanup and fixes
- Consistent use of deepClone helper
- Add deleteConfirmModal component
- Improve singleton service patterns

---

## [0.1.0] - 2026-01-13

### Features
Expand Down
33 changes: 33 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,26 @@ src/
│ ├── config.provider.ts
│ ├── settings.provider.ts
│ └── toolbar.provider.ts
├── styles/ # Shared SCSS (modular DRY)
│ ├── _variables.scss # Spacing, radius, colors, z-index
│ └── _mixins.scss # Reusable patterns
└── components/ # Angular components (.ts, .pug, .scss)
├── workspaceList # Main settings UI
├── workspaceEditor # Single workspace editor
├── paneEditor # Pane configuration
└── splitPreview # Visual split preview
```

## Styles

Modular DRY SCSS architecture. All components load shared styles via `@use '../styles/index' as *;`.

- **Variables**: `$spacing-*`, `$radius-*`, `$color-*`, `$z-*`, `$transition-*`
- **Mixins**: Layout, form, card, and button patterns. See `src/styles/_mixins.scss` for the available mixins.
- **Theming**: Uses Tabby's `--theme-*` CSS variables

See `docs/DESIGN.md` for details.

## Build

```bash
Expand Down Expand Up @@ -291,6 +304,26 @@ await new Promise(r => setTimeout(r, 100));
return document.querySelectorAll('.preview-pane.selected').length;
```

## Angular Change Detection

**KRITIČNO**: NE koristi `OnPush` strategiju na komponentama koje primaju mutirane objekte.

### Pravilo
- **NE koristi `OnPush`** ako parent komponenta mutira objekte umesto da kreira nove reference
- Angular default strategija automatski detektuje sve promene
- `OnPush` je samo za leaf komponente koje emituju events bez lokalnog state-a

### Zašto
- `OnPush` osvežava view samo kada se `@Input` referenca promeni
- Mutacija objekta (npr. `workspace.root.children.push()`) NE menja referencu
- Bez nove reference, Angular ne zna da treba re-renderovati

### Komponente u ovom projektu
- `workspaceEditor` - **default CD** (mutira workspace)
- `workspaceList` - **default CD** (koristi `detectChanges()` za async operacije)
- `splitPreview` - **default CD** (prima mutirane objekte)
- `paneEditor` - može biti `OnPush` (samo emituje, nema mutacija)

## Known Issues

### YAML escape sequences in config.yaml
Expand Down
4 changes: 3 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ No hot reload. Tabby doesn't support it for plugins. Restart after each build.
2. Create a branch (`git checkout -b fix/thing`)
3. Make your changes
4. Test manually in Tabby
5. Submit PR with a clear description
5. Submit PR **to the `dev` branch** (not `main`)

CI will check that your code builds. `main` is for releases only.

No strict commit message format. Just be clear about what you changed and why.

Expand Down
45 changes: 27 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,26 @@ Visual workspace editor for [Tabby](https://tabby.sh). Create split-layout termi

![Workspace Editor](screenshots/editor.png)

## What it does
## Features

- Visual editor for split layouts (horizontal/vertical, nested, any depth)
- Per-pane configuration: profile, working directory, startup command, title
- One-click workspace launch from toolbar
- Launch on startup (auto-open workspaces when Tabby starts)
- Works with any shell (Bash, Zsh, PowerShell, Nushell, etc.)
- **Visual split editor** - Design layouts inline, not in modal dialogs. Split horizontally, vertically, nest to any depth
- **Layout toolbar** - Select a pane, then split, add adjacent panes, or delete with toolbar buttons
- **Per-pane configuration** - Set profile, working directory, and startup command for each pane
- **One-click launch** - Open workspaces instantly from the toolbar dropdown
- **Launch on startup** - Auto-open multiple workspaces when Tabby starts
- **Any shell** - Works with Bash, Zsh, PowerShell, Nushell, cmd, WSL, and any other shell Tabby supports

## Screenshots

| Editor with selected pane | Pane configuration |
|---------------------------|-------------------|
| ![Editor](screenshots/editor.png) | ![Pane Edit](screenshots/pane-edit.png) |

## About this project

This plugin was written 100% by [Claude Code](https://claude.ai/code).

Igor Halilović had the idea and provided product direction. He hates Angular so much (19 years of web dev, wrote his own TypeScript framework) that he didn't look at this code. Not once. He told Claude Code what he wanted, Claude Code built it.
Igor Halilovic had the idea and provided product direction. He hates Angular so much (19 years of web dev, wrote his own TypeScript framework) that he didn't look at this code. Not once. He told Claude Code what he wanted, Claude Code built it.

Human provides the *what* and *why*. AI handles the *how*.

Expand All @@ -25,7 +32,7 @@ Here's the fun part: to test this plugin, we built [tabby-mcp](https://github.co
## Install

**From Tabby Plugin Manager:**
Settings Plugins Search "tabbyspaces" Install
Settings > Plugins > Search "tabbyspaces" > Install

**Manual:**
```bash
Expand All @@ -35,17 +42,13 @@ npm install tabby-tabbyspaces

Restart Tabby after installation.

## Usage

1. Open Settings → TabbySpaces
2. Create a workspace
3. Design your split layout visually
4. Configure each pane (profile, cwd, startup command)
5. Save and launch from the toolbar

### Pane configuration
## Quick Start

![Edit Pane](screenshots/pane-edit.png)
1. **Open settings** - Settings > TabbySpaces
2. **Create workspace** - Click "New Workspace", name it
3. **Design layout** - Click a pane to select it, use toolbar to split (horizontal/vertical)
4. **Configure panes** - Click a pane (or use its context menu) to set profile, cwd, startup command
5. **Save and launch** - Save changes, then click "Open" or use the toolbar dropdown

## Roadmap

Expand All @@ -66,6 +69,12 @@ Restart Tabby after installation.
- [Discussions](https://github.com/halilc4/tabbyspaces/discussions) - Questions, ideas, show your setup
- [Issues](https://github.com/halilc4/tabbyspaces/issues) - Bug reports

## Contributing

PRs welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for setup instructions.

All PRs go to the `dev` branch. CI checks the build automatically.

## License

MIT
5 changes: 5 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@
- [ ] List: add small layout preview
- [ ] Better input for command
- [ ] Better input for cwd
- [ ] Editor workspace + pane editor autosave
- [ ] Undo/redo for editor changes

### Bugs
- [~] Resize panes in Tabby reverts to original values (ratio problem) - WATCH: happens only on one workspace
- [ ] Layout preview responsive - nested splits don't adapt well to smaller sizes
- [ ] Launch on startup - Tabby remembers open tabs, check if we can detect if workspace is already open; if not, kill the feature
- [x] Tab titles are a mess - keep only workspace name or default to Tabby behavior (verify no caching/lookup by tab name)

### Other
- [ ] Update screenshots in README
Expand Down Expand Up @@ -60,6 +64,7 @@
- [x] Refactoring: Remove profile persistence, shell-aware CWD, dead code cleanup

### Bugs
- [x] Focus lost after deleting workspace (native confirm() steals focus from Electron) - fix: use NgbModal instead
- [x] Audit async functions - check if `detectChanges()` is missing after async operations that change state
- [x] Split pane runs command (in-memory profiles) - fix: clear profile.options.args after command execution
- [x] Pane editor modal bug - mouseup outside dialog closes modal. Dialog should close only on Esc or close/cancel/save button
Expand Down
57 changes: 57 additions & 0 deletions docs/DESIGN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Design System

TabbySpaces uses a modular DRY SCSS architecture.

## Structure

```
src/styles/
├── _index.scss # Entry point (imports all)
├── _variables.scss # Spacing, radius, colors, z-index, transitions
└── _mixins.scss # Reusable patterns (flex, inputs, buttons, overlays)
```

## Usage

All component SCSS files import shared styles:

```scss
@use '../styles/index' as *;

.my-component {
padding: $spacing-md;
border-radius: $radius-lg;
@include flex-center;
}
```

## Variables

@src/styles/_variables.scss

## Mixins

Key mixins available:

| Mixin | Purpose |
|-------|---------|
| `flex-center` | Center content with flexbox |
| `form-input($bg)` | Styled input field with focus state |
| `form-label` | Uppercase compact label (S1 design) |
| `toolbar-btn` | Small toolbar button with hover state |
| `btn-success` | Green success button |
| `btn-base` | Base button styling with flex layout |
| `btn-ghost` | Ghost button with border |
| `btn-primary` | Primary button with theme color |
| `icon-btn-sm($size)` | Small icon button with border |
| `full-overlay($z)` | Fixed fullscreen overlay |
| `dropdown-panel` | Dropdown with border/shadow |
| `text-ellipsis` | Truncate text with ellipsis |
Comment on lines 36 to 49
Copy link

Copilot AI Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mixin list here doesn't match what's actually defined in src/styles/_mixins.scss (e.g., flex-row/flex-col/flex-between/interactive-card/icon-btn-opacity are not present, while icon-btn-sm exists). Please update the table to reflect the real exported mixins to avoid misleading documentation.

Copilot uses AI. Check for mistakes.

## Theming

Plugin uses Tabby's CSS custom properties (`--theme-*`) for automatic theme support:
- `--theme-bg`, `--theme-bg-more`, `--theme-bg-more-more`
- `--theme-fg`, `--theme-fg-more`
- `--theme-border`, `--theme-primary`
- `--theme-success`, `--theme-danger`
Loading
Loading