tabby-tabbyspaces 0.0.1 → 0.2.0

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.
Files changed (78) hide show
  1. package/.claude/settings.local.json +29 -2
  2. package/.github/workflows/ci.yml +26 -0
  3. package/.github/workflows/claude-code-review.yml +44 -0
  4. package/.github/workflows/claude.yml +81 -0
  5. package/.github/workflows/release.yml +30 -0
  6. package/CHANGELOG.md +92 -20
  7. package/CLAUDE.md +196 -15
  8. package/CONTRIBUTING.md +3 -1
  9. package/README.md +80 -61
  10. package/RELEASE.md +91 -0
  11. package/TODO.md +77 -0
  12. package/dist/build-config.d.ts +3 -3
  13. package/dist/components/deleteConfirmModal.component.d.ts +7 -0
  14. package/dist/components/deleteConfirmModal.component.d.ts.map +1 -0
  15. package/dist/components/paneEditor.component.d.ts +9 -13
  16. package/dist/components/paneEditor.component.d.ts.map +1 -1
  17. package/dist/components/splitPreview.component.d.ts +50 -35
  18. package/dist/components/splitPreview.component.d.ts.map +1 -1
  19. package/dist/components/workspaceEditor.component.d.ts +61 -28
  20. package/dist/components/workspaceEditor.component.d.ts.map +1 -1
  21. package/dist/components/workspaceList.component.d.ts +56 -27
  22. package/dist/components/workspaceList.component.d.ts.map +1 -1
  23. package/dist/index.d.ts +6 -6
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +1 -1
  26. package/dist/index.js.LICENSE.txt +1 -1
  27. package/dist/index.js.map +1 -1
  28. package/dist/models/workspace.model.d.ts +118 -76
  29. package/dist/models/workspace.model.d.ts.map +1 -1
  30. package/dist/package.json +26 -0
  31. package/dist/providers/config.provider.d.ts +8 -8
  32. package/dist/providers/settings.provider.d.ts +7 -7
  33. package/dist/providers/settings.provider.d.ts.map +1 -1
  34. package/dist/providers/toolbar.provider.d.ts +23 -12
  35. package/dist/providers/toolbar.provider.d.ts.map +1 -1
  36. package/dist/services/startupCommand.service.d.ts +28 -0
  37. package/dist/services/startupCommand.service.d.ts.map +1 -0
  38. package/dist/services/workspaceBackground.service.d.ts +38 -0
  39. package/dist/services/workspaceBackground.service.d.ts.map +1 -0
  40. package/dist/services/workspaceEditor.service.d.ts +46 -24
  41. package/dist/services/workspaceEditor.service.d.ts.map +1 -1
  42. package/docs/DESIGN.md +57 -0
  43. package/docs/SESSION-2026-01-14-S1-DESIGN.md +134 -0
  44. package/docs/marketing_status.md +92 -0
  45. package/mockups/index.html +162 -0
  46. package/mockups/s1-tight-sharp.html +522 -0
  47. package/mockups/shared/base.css +216 -0
  48. package/mockups/v06-tabbed.html +643 -0
  49. package/package.json +3 -7
  50. package/screenshots/editor.png +0 -0
  51. package/screenshots/pane-edit.png +0 -0
  52. package/scripts/build-dev.js +2 -1
  53. package/scripts/build-prod.js +40 -0
  54. package/src/components/deleteConfirmModal.component.ts +23 -0
  55. package/src/components/paneEditor.component.pug +27 -43
  56. package/src/components/paneEditor.component.scss +37 -85
  57. package/src/components/paneEditor.component.ts +6 -16
  58. package/src/components/splitPreview.component.pug +36 -5
  59. package/src/components/splitPreview.component.scss +78 -45
  60. package/src/components/splitPreview.component.ts +83 -18
  61. package/src/components/workspaceEditor.component.pug +162 -74
  62. package/src/components/workspaceEditor.component.scss +261 -108
  63. package/src/components/workspaceEditor.component.ts +294 -31
  64. package/src/components/workspaceList.component.pug +32 -41
  65. package/src/components/workspaceList.component.scss +89 -74
  66. package/src/components/workspaceList.component.ts +181 -44
  67. package/src/index.ts +6 -0
  68. package/src/models/workspace.model.ts +113 -8
  69. package/src/providers/settings.provider.ts +2 -2
  70. package/src/providers/toolbar.provider.ts +113 -13
  71. package/src/services/startupCommand.service.ts +140 -0
  72. package/src/services/workspaceBackground.service.ts +167 -0
  73. package/src/services/workspaceEditor.service.ts +134 -65
  74. package/src/styles/_index.scss +3 -0
  75. package/src/styles/_mixins.scss +180 -0
  76. package/src/styles/_variables.scss +67 -0
  77. package/RELEASE_PLAN.md +0 -161
  78. package/screenshots/workspace-edit.png +0 -0
@@ -9,7 +9,34 @@
9
9
  "WebFetch(domain:github.com)",
10
10
  "Bash(npm run build:dev:*)",
11
11
  "Bash(wc:*)",
12
- "Bash(tree:*)"
12
+ "WebFetch(domain:docs.tabby.sh)",
13
+ "WebFetch(domain:raw.githubusercontent.com)",
14
+ "WebFetch(domain:api.github.com)",
15
+ "Bash(ls -la \"C:\\\\Users\\\\halil\\\\tabbyspaces\\\\dist\"\" | grep -E \"package)",
16
+ "Bash(.json \")",
17
+ "Bash(dir /s /b \"C:\\\\Users\\\\halil\\\\AppData\\\\Local\\\\Programs\\\\tabby\")",
18
+ "WebFetch(domain:localhost)",
19
+ "Bash(curl:*)",
20
+ "mcp__tabby__query",
21
+ "mcp__tabby__execute_js",
22
+ "Bash(start \"\" \"C:\\\\Program Files \\(x86\\)\\\\Tabby\\\\Tabby.exe\" --remote-debugging-port=9222)",
23
+ "mcp__tabby__list_targets",
24
+ "Bash(tree:*)",
25
+ "Bash(dir \"C:\\\\Users\\\\halil\\\\tabbyspaces\\\\node_modules\" /B)",
26
+ "Bash(findstr:*)",
27
+ "mcp__tabby__screenshot",
28
+ "Bash(python:*)",
29
+ "Bash(cmd /c \"dir /A %APPDATA%\\\\tabby\\\\plugins\\\\node_modules\")",
30
+ "Bash(cmd /c \"dir %APPDATA%\\\\tabby\\\\plugins\")",
31
+ "Bash(git log:*)",
32
+ "Bash(ls -la \"C:\\\\Users\\\\halil\\\\tabbyspaces\\\\screenshots\"\" 2>nul || echo \"Directory not found \")",
33
+ "Bash(dir:*)",
34
+ "Bash(cmd.exe /c start \"\" \"C:\\\\Program Files \\(x86\\)\\\\Tabby\\\\Tabby.exe\" --remote-debugging-port=9222)",
35
+ "Bash(ls:*)"
13
36
  ]
14
- }
37
+ },
38
+ "enableAllProjectMcpServers": true,
39
+ "enabledMcpjsonServers": [
40
+ "tabby"
41
+ ]
15
42
  }
@@ -0,0 +1,26 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [dev]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ build:
11
+ runs-on: ubuntu-latest
12
+
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - name: Setup Node.js
17
+ uses: actions/setup-node@v4
18
+ with:
19
+ node-version: '18'
20
+ cache: 'npm'
21
+
22
+ - name: Install dependencies
23
+ run: npm ci --legacy-peer-deps
24
+
25
+ - name: Build
26
+ run: npm run build
@@ -0,0 +1,44 @@
1
+ name: Claude Code Review
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, synchronize, ready_for_review, reopened]
6
+ # Optional: Only run on specific file changes
7
+ # paths:
8
+ # - "src/**/*.ts"
9
+ # - "src/**/*.tsx"
10
+ # - "src/**/*.js"
11
+ # - "src/**/*.jsx"
12
+
13
+ jobs:
14
+ claude-review:
15
+ # Only run for repository members to control costs
16
+ if: |
17
+ github.event.pull_request.author_association == 'OWNER' ||
18
+ github.event.pull_request.author_association == 'MEMBER' ||
19
+ github.event.pull_request.author_association == 'COLLABORATOR'
20
+
21
+ runs-on: ubuntu-latest
22
+ permissions:
23
+ contents: write
24
+ pull-requests: write
25
+ issues: read
26
+ id-token: write
27
+
28
+ steps:
29
+ - name: Checkout repository
30
+ uses: actions/checkout@v4
31
+ with:
32
+ fetch-depth: 0
33
+
34
+ - name: Run Claude Code Review
35
+ id: claude-review
36
+ uses: anthropics/claude-code-action@v1.0.0
37
+ with:
38
+ claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
39
+ prompt: >
40
+ Please review the changes in this pull request and leave a concise summary comment with any issues, suggestions, and potential bugs:
41
+ https://github.com/${{ github.repository }}/pull/${{ github.event.pull_request.number }}
42
+ # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
43
+ # or https://code.claude.com/docs/en/cli-reference for available options
44
+
@@ -0,0 +1,81 @@
1
+ name: Claude Code
2
+
3
+ on:
4
+ issue_comment:
5
+ types: [created]
6
+ pull_request_review_comment:
7
+ types: [created]
8
+ issues:
9
+ types: [opened]
10
+ pull_request_review:
11
+ types: [submitted]
12
+
13
+ jobs:
14
+ claude:
15
+ if: |
16
+ (
17
+ github.event_name == 'issue_comment' &&
18
+ contains(github.event.comment.body, '@claude') &&
19
+ (
20
+ github.event.comment.author_association == 'OWNER' ||
21
+ github.event.comment.author_association == 'MEMBER' ||
22
+ github.event.comment.author_association == 'COLLABORATOR'
23
+ )
24
+ ) ||
25
+ (
26
+ github.event_name == 'pull_request_review_comment' &&
27
+ contains(github.event.comment.body, '@claude') &&
28
+ (
29
+ github.event.comment.author_association == 'OWNER' ||
30
+ github.event.comment.author_association == 'MEMBER' ||
31
+ github.event.comment.author_association == 'COLLABORATOR'
32
+ )
33
+ ) ||
34
+ (
35
+ github.event_name == 'pull_request_review' &&
36
+ contains(github.event.review.body, '@claude') &&
37
+ (
38
+ github.event.review.author_association == 'OWNER' ||
39
+ github.event.review.author_association == 'MEMBER' ||
40
+ github.event.review.author_association == 'COLLABORATOR'
41
+ )
42
+ ) ||
43
+ (
44
+ github.event_name == 'issues' &&
45
+ (
46
+ contains(github.event.issue.body, '@claude') ||
47
+ contains(github.event.issue.title, '@claude')
48
+ ) &&
49
+ (
50
+ github.event.issue.author_association == 'OWNER' ||
51
+ github.event.issue.author_association == 'MEMBER' ||
52
+ github.event.issue.author_association == 'COLLABORATOR'
53
+ )
54
+ )
55
+ runs-on: ubuntu-latest
56
+ permissions:
57
+ contents: read
58
+ pull-requests: write
59
+ issues: write
60
+ id-token: write
61
+ actions: read # Required for Claude to read CI results on PRs
62
+ steps:
63
+ - name: Checkout repository
64
+ uses: actions/checkout@v4
65
+ with:
66
+ fetch-depth: 0
67
+
68
+ - name: Run Claude Code
69
+ id: claude
70
+ uses: anthropics/claude-code-action@v1.0.0
71
+ with:
72
+ claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
73
+
74
+ # Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
75
+ # prompt: 'Update the pull request description to include a summary of changes.'
76
+
77
+ # Optional: Add claude_args to customize behavior and configuration
78
+ # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
79
+ # or https://code.claude.com/docs/en/cli-reference for available options
80
+ # claude_args: '--allowed-tools Bash(gh pr:*)'
81
+
@@ -0,0 +1,30 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+
7
+ jobs:
8
+ publish:
9
+ runs-on: ubuntu-latest
10
+
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+
14
+ - name: Setup Node.js
15
+ uses: actions/setup-node@v4
16
+ with:
17
+ node-version: '18'
18
+ cache: 'npm'
19
+ registry-url: 'https://registry.npmjs.org'
20
+
21
+ - name: Install dependencies
22
+ run: npm ci --legacy-peer-deps
23
+
24
+ - name: Build
25
+ run: npm run build
26
+
27
+ - name: Publish to npm
28
+ run: npm publish --access public
29
+ env:
30
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/CHANGELOG.md CHANGED
@@ -1,20 +1,92 @@
1
- # Changelog
2
-
3
- ## [0.0.1] - 2026-01-03
4
-
5
- Initial release.
6
-
7
- ### Features
8
-
9
- - Workspace list with create, edit, duplicate, delete
10
- - Visual split-layout editor (horizontal/vertical, any nesting depth)
11
- - Pane configuration: base profile, working directory, startup command, custom title
12
- - Toolbar button for quick workspace launch
13
- - Default workspace option (launches on Tabby startup)
14
- - Icon and color customization per workspace
15
- - Hotkey support (planned)
16
-
17
- ### Technical
18
-
19
- - Full dev/prod build isolation for parallel development
20
- - Automatic Tabby profile generation from workspace config
1
+ # Changelog
2
+
3
+ ## [0.2.0] - 2026-01-26
4
+
5
+ ### Design
6
+
7
+ - **S1 "Tight & Sharp" UI redesign**
8
+ - Tab bar navigation replaces vertical workspace list
9
+ - Inline pane editor replaces modal overlay
10
+ - Section-based layout with uppercase titles
11
+ - Reorganized preview toolbar with icon buttons
12
+ - 2-column form grid in pane editor
13
+ - Refactor SCSS to modular DRY architecture
14
+ - Shared variables: spacing scale, border radius, colors, z-index
15
+ - Reusable mixins: flex-row, form-input, interactive-card, toolbar-btn
16
+ - All components migrated to use shared styles
17
+ - Add design system documentation (docs/DESIGN.md)
18
+ - Add HTML mockups for design exploration
19
+
20
+ ### Reliability
21
+
22
+ - Improved duplicate workspace detection on Tabby restart
23
+ - Add workspaceId to recovery tokens
24
+ - Two-strategy detection (restored tabs + freshly opened)
25
+ - Better shell initialization with 2s timeout and error handling
26
+ - Wait for Tabby recovery before launching startup workspaces
27
+ - Type-safe workspace detection with proper type guards
28
+
29
+ ### Bug Fixes
30
+
31
+ - Fix focus lost after workspace delete (NgbModal replaces native confirm)
32
+ - Fix split preview change detection (remove OnPush strategy)
33
+ - Fix race condition in shell initialization
34
+
35
+ ### Infrastructure
36
+
37
+ - Add CI/CD workflows (GitHub Actions for build + release)
38
+ - Add dev branch workflow documentation
39
+
40
+ ### Technical
41
+
42
+ - Code review cleanup and fixes
43
+ - Consistent use of deepClone helper
44
+ - Add deleteConfirmModal component
45
+ - Improve singleton service patterns
46
+
47
+ ---
48
+
49
+ ## [0.1.0] - 2026-01-13
50
+
51
+ ### Features
52
+
53
+ - Inline workspace editor (replaces modal dialog)
54
+ - Layout editing toolbar with pane selection system
55
+ - Startup command support per pane
56
+ - Launch on startup supports multiple workspaces
57
+ - Distinct icons for DEV vs PROD versions
58
+
59
+ ### Bug Fixes
60
+
61
+ - Fix delete/save race conditions with async/await
62
+ - Fix native split re-running startup command
63
+ - Fix async change detection and profile cleanup timing
64
+
65
+ ### UX Improvements
66
+
67
+ - Pane title format: shows base profile when no custom title
68
+ - Toolbar UI polish
69
+ - Settings panel max-width override (1024px)
70
+
71
+ ### Technical
72
+
73
+ - Remove profile persistence (cleaner architecture - no generated profiles)
74
+ - Watch mode for dev workflow (`npm run watch:dev`)
75
+
76
+ ---
77
+
78
+ ## [0.0.1] - 2026-01-03
79
+
80
+ Initial release.
81
+
82
+ ### Features
83
+
84
+ - Workspace list with create, edit, duplicate, delete
85
+ - Visual split-layout editor (horizontal/vertical, any nesting depth)
86
+ - Pane configuration: base profile, working directory, startup command, custom title
87
+ - Toolbar button for quick workspace launch
88
+ - Icon and color customization per workspace
89
+
90
+ ### Technical
91
+
92
+ - Full dev/prod build isolation for parallel development
package/CLAUDE.md CHANGED
@@ -2,6 +2,25 @@
2
2
 
3
3
  Visual split-layout workspace editor for Tabby.
4
4
 
5
+ ## Git Workflow
6
+
7
+ - **main** - Stable releases only. Do not commit directly.
8
+ - **dev** - Active development. All work happens here.
9
+
10
+ ```bash
11
+ # Normal workflow
12
+ git checkout dev # Work on dev
13
+ # ... make changes ...
14
+ git commit
15
+
16
+ # Release workflow
17
+ git checkout main
18
+ git merge dev
19
+ git tag v0.x.0
20
+ git push --tags
21
+ git checkout dev # Back to work
22
+ ```
23
+
5
24
  ## Tech Stack
6
25
 
7
26
  - **Framework**: Angular 15 (Tabby uses Angular 15)
@@ -15,12 +34,36 @@ Visual split-layout workspace editor for Tabby.
15
34
  ```
16
35
  src/
17
36
  ├── index.ts # NgModule entry point
37
+ ├── build-config.ts # Build-time constants (CONFIG_KEY, DISPLAY_NAME)
18
38
  ├── models/ # TypeScript interfaces
39
+ │ └── workspace.model.ts
19
40
  ├── services/ # Business logic
20
- ├── providers/ # Tabby config/settings providers
41
+ ├── workspaceEditor.service.ts
42
+ │ └── startupCommand.service.ts
43
+ ├── providers/ # Tabby config/settings/toolbar providers
44
+ │ ├── config.provider.ts
45
+ │ ├── settings.provider.ts
46
+ │ └── toolbar.provider.ts
47
+ ├── styles/ # Shared SCSS (modular DRY)
48
+ │ ├── _variables.scss # Spacing, radius, colors, z-index
49
+ │ └── _mixins.scss # Reusable patterns
21
50
  └── components/ # Angular components (.ts, .pug, .scss)
51
+ ├── workspaceList # Main settings UI
52
+ ├── workspaceEditor # Single workspace editor
53
+ ├── paneEditor # Pane configuration
54
+ └── splitPreview # Visual split preview
22
55
  ```
23
56
 
57
+ ## Styles
58
+
59
+ Modular DRY SCSS architecture. All components load shared styles via `@use '../styles/index' as *;`.
60
+
61
+ - **Variables**: `$spacing-*`, `$radius-*`, `$color-*`, `$z-*`, `$transition-*`
62
+ - **Mixins**: Layout, form, card, and button patterns. See `src/styles/_mixins.scss` for the available mixins.
63
+ - **Theming**: Uses Tabby's `--theme-*` CSS variables
64
+
65
+ See `docs/DESIGN.md` for details.
66
+
24
67
  ## Build
25
68
 
26
69
  ```bash
@@ -37,7 +80,7 @@ Debug: `Ctrl+Shift+I` in Tabby opens DevTools.
37
80
  ### package.json (required)
38
81
  ```json
39
82
  {
40
- "keywords": ["tabby-plugin"],
83
+ "keywords": ["tabby", "tabby-plugin"],
41
84
  "main": "dist/index.js",
42
85
  "tabbyPlugin": {
43
86
  "name": "tabbyspaces",
@@ -79,20 +122,45 @@ export default class MyModule {}
79
122
 
80
123
  ## Data Model
81
124
 
82
- - `Workspace` - Main object with name, icon, color, root split
125
+ - `Workspace` - Main object with name, icon, color, root split, launchOnStartup
83
126
  - `WorkspaceSplit` - Recursive structure with orientation, ratios, children
84
- - `WorkspacePane` - Leaf node with profileId, cwd, startupCommand, title
127
+ - `WorkspacePane` - Leaf node with profileId (reference to existing Tabby profile), cwd, startupCommand, title
85
128
 
86
- ## Tabby Profile Generation
129
+ ### Workspace Fields
130
+ | Field | Type | Description |
131
+ |-------|------|-------------|
132
+ | `id` | string | UUID |
133
+ | `name` | string | Display name |
134
+ | `icon` | string | FontAwesome icon name (without fa- prefix) |
135
+ | `color` | string | Hex color |
136
+ | `root` | WorkspaceSplit | Root split node |
137
+ | `launchOnStartup` | boolean | Auto-open when Tabby starts (multiple allowed) |
87
138
 
88
- Plugin stores a simplified model in `config.store.tabbyspaces.workspaces` and auto-generates verbose Tabby `split-layout` profiles in `config.store.profiles`.
139
+ ## Architecture
89
140
 
90
- ## Nushell Startup Commands
141
+ ### Storage
142
+ Plugin stores workspaces in `config.store.tabbyspaces.workspaces`. No profiles are generated in `config.store.profiles`.
91
143
 
92
- For Nushell, startup commands are passed as:
93
- ```typescript
94
- options.args = ['-e', startupCommand]
95
- ```
144
+ ### Opening Workspaces
145
+ 1. Generate temporary `split-layout` recovery token from workspace model (includes `options.cwd`)
146
+ 2. Open via `ProfilesService.openNewTabForProfile()`
147
+ 3. `StartupCommandService` listens for `tabOpened$` events
148
+ 4. Match terminal tabs by pane ID (passed via `tabCustomTitle`)
149
+ 5. Send startup command via `sendInput()` (if defined)
150
+
151
+ ### CWD Handling
152
+ CWD is set via native `options.cwd` in the recovery token. The shell spawns directly in the target directory - no visible `cd` commands.
153
+
154
+ ### Profile Support
155
+ Plugin supports both user-defined profiles (`type: 'local'`) and built-in shells (`type: 'local:cmd'`, `'local:powershell'`, `'local:wsl'`, etc.). Profile lookup uses a two-stage approach:
156
+ 1. First checks user profiles in `config.store.profiles`
157
+ 2. Falls back to cached profiles from `profilesService.getProfiles()` (includes built-ins)
158
+
159
+ ### Launch on Startup
160
+ Workspaces with `launchOnStartup: true` are automatically opened when Tabby starts. Multiple workspaces can be marked. Logic is in `toolbar.provider.ts` constructor with 500ms delay to ensure Tabby is ready.
161
+
162
+ ### Migration
163
+ `cleanupOrphanedProfiles()` removes any leftover profiles from previous plugin versions (prefix `split-layout:tabbyspaces:`).
96
164
 
97
165
  ## References
98
166
 
@@ -111,10 +179,20 @@ Linux: ~/.config/tabby/plugins
111
179
 
112
180
  ### Production install
113
181
  ```bash
182
+ # Via Tabby Plugin Manager (Settings → Plugins → search "tabbyspaces")
183
+ # Or via npm:
114
184
  cd <plugins-folder>
115
185
  npm install tabby-tabbyspaces
116
186
  ```
117
187
 
188
+ ### Production uninstall
189
+ ```bash
190
+ # Via Tabby Plugin Manager
191
+ # Or via npm:
192
+ cd <plugins-folder>
193
+ npm uninstall tabby-tabbyspaces
194
+ ```
195
+
118
196
  ## Development
119
197
 
120
198
  ### Dev install (once)
@@ -122,16 +200,24 @@ npm install tabby-tabbyspaces
122
200
  npm run build:dev
123
201
  cd %APPDATA%\tabby\plugins
124
202
  npm install "<path-to-repo>/dist-dev"
203
+ # Restart Tabby
204
+ ```
205
+
206
+ ### Dev uninstall
207
+ ```bash
208
+ cd %APPDATA%\tabby\plugins
209
+ npm uninstall tabby-tabbyspaces-dev
210
+ # Restart Tabby
125
211
  ```
126
212
 
127
213
  ### Dev workflow (after install)
128
214
  ```bash
129
- npm run build:dev # Initial build (creates dist-dev/package.json)
215
+ npm run build:dev # Rebuild
130
216
  npm run watch:dev # Watch mode - rebuilds on file changes
131
- # restart Tabby after each rebuild
217
+ # Restart Tabby after each rebuild
132
218
  ```
133
219
 
134
- npm auto-creates symlinks for local packages, so each build is immediately available.
220
+ npm creates symlinks for local packages, so each build is immediately available.
135
221
 
136
222
  ### Dev vs Prod Isolation
137
223
 
@@ -140,13 +226,108 @@ npm auto-creates symlinks for local packages, so each build is immediately avail
140
226
  | Package | `tabby-tabbyspaces` | `tabby-tabbyspaces-dev` |
141
227
  | Config | `config.store.tabbyspaces` | `config.store.tabbyspaces_dev` |
142
228
  | Display | "TabbySpaces" | "TabbySpaces DEV" |
229
+ | Toolbar icon | Grid (4 squares) | ⚡ Bolt |
230
+ | Settings icon | `th-large` | `bolt` |
143
231
 
144
232
  Both plugins can be installed simultaneously.
145
233
 
234
+ ## CDP Debugging (via tabby-mcp)
235
+
236
+ Automatizovan način za testiranje plugina kroz Chrome DevTools Protocol.
237
+
238
+ ### Workflow
239
+ 1. **Pokreni Tabby** sa remote debugging:
240
+ ```bash
241
+ cmd.exe /c start "" "C:\Program Files (x86)\Tabby\Tabby.exe" --remote-debugging-port=9222
242
+ ```
243
+ 2. **Izlistaj targets** sa `mcp__tabby__list_targets`
244
+ 3. **Identifikuj target** - oba imaju isti URL, ali:
245
+ - Target 0 = Tvoj radni Tabby (Claude Code session)
246
+ - Target 1 = Debug Tabby instance (pokrenut sa --remote-debugging-port)
247
+ 4. **Debug** sa `query`, `execute_js`, `screenshot`
248
+
249
+ **VAŽNO:** Debug-uj NOVI Tabby instance (target 1), ne onaj u kojem radiš!
250
+
251
+ ### MCP Tools
252
+ | Tool | Opis |
253
+ |------|------|
254
+ | `mcp__tabby__list_targets` | Lista CDP targets sa index, title, URL, WebSocket |
255
+ | `mcp__tabby__query` | CSS selector → lista elemenata |
256
+ | `mcp__tabby__execute_js` | Izvrši JS (fresh scope, async/await support) |
257
+ | `mcp__tabby__screenshot` | Screenshot Tabby prozora |
258
+
259
+ ### Identifikacija DEV verzije
260
+
261
+ DEV verzija ima ⚡ bolt ikonicu (umesto grid-a):
262
+ - **Toolbar**: SVG bolt ikonica u gornjem desnom uglu
263
+ - **Settings sidebar**: FontAwesome `fa-bolt` pored "TabbySpaces DEV"
264
+
265
+ ```javascript
266
+ // Proveri da li je DEV verzija aktivna u settings
267
+ document.querySelector('.nav-link .fa-bolt') // DEV
268
+ document.querySelector('.nav-link .fa-th-large') // PROD
269
+ ```
270
+
271
+ ### CSS Selektori Reference
272
+
273
+ | Selektor | Element |
274
+ |----------|---------|
275
+ | `.preview-pane` | Pane u split preview-u |
276
+ | `.preview-pane.selected` | Selektovan pane |
277
+ | `.toolbar-btn` | Toolbar dugmad |
278
+ | `.toolbar-btn[title="Edit pane"]` | Specifično dugme po title-u |
279
+ | `.pane-editor-modal` | Edit pane modal |
280
+ | `.context-menu` | Context menu (desni klik) |
281
+ | `.workspace-item` | Workspace u listi |
282
+ | `.nav-link .fa-bolt` | DEV settings tab ikonica |
283
+ | `.nav-link .fa-th-large` | PROD settings tab ikonica |
284
+
285
+ ### Primeri
286
+ ```javascript
287
+ // Query elemente
288
+ mcp__tabby__query(target: 1, selector: '.preview-pane')
289
+
290
+ // Klikni na pane i proveri toolbar
291
+ document.querySelectorAll('.preview-pane')[0].click();
292
+ return Array.from(document.querySelectorAll('.toolbar-btn'))
293
+ .map(b => ({title: b.title, disabled: b.disabled}));
294
+
295
+ // Split pane i vrati novi count
296
+ const before = document.querySelectorAll('.preview-pane').length;
297
+ document.querySelectorAll('.preview-pane')[0].click();
298
+ document.querySelector('.toolbar-btn[title="Split Horizontal"]').click();
299
+ return { before, after: document.querySelectorAll('.preview-pane').length };
300
+
301
+ // Async primer - sačekaj Angular change detection
302
+ document.querySelectorAll('.preview-pane')[0].click();
303
+ await new Promise(r => setTimeout(r, 100));
304
+ return document.querySelectorAll('.preview-pane.selected').length;
305
+ ```
306
+
307
+ ## Angular Change Detection
308
+
309
+ **KRITIČNO**: NE koristi `OnPush` strategiju na komponentama koje primaju mutirane objekte.
310
+
311
+ ### Pravilo
312
+ - **NE koristi `OnPush`** ako parent komponenta mutira objekte umesto da kreira nove reference
313
+ - Angular default strategija automatski detektuje sve promene
314
+ - `OnPush` je samo za leaf komponente koje emituju events bez lokalnog state-a
315
+
316
+ ### Zašto
317
+ - `OnPush` osvežava view samo kada se `@Input` referenca promeni
318
+ - Mutacija objekta (npr. `workspace.root.children.push()`) NE menja referencu
319
+ - Bez nove reference, Angular ne zna da treba re-renderovati
320
+
321
+ ### Komponente u ovom projektu
322
+ - `workspaceEditor` - **default CD** (mutira workspace)
323
+ - `workspaceList` - **default CD** (koristi `detectChanges()` za async operacije)
324
+ - `splitPreview` - **default CD** (prima mutirane objekte)
325
+ - `paneEditor` - može biti `OnPush` (samo emituje, nema mutacija)
326
+
146
327
  ## Known Issues
147
328
 
148
329
  ### YAML escape sequences in config.yaml
149
- If a base profile in Tabby config uses double-quoted strings with wrong escape sequences (e.g., `\t` instead of `\\t`), the plugin will copy the corrupted path.
330
+ If a base profile in Tabby config uses double-quoted strings with wrong escape sequences (e.g., `\t` instead of `\\t`), shell detection will fail and CWD commands may not work correctly.
150
331
 
151
332
  ```yaml
152
333
  # WRONG - \t becomes TAB character
package/CONTRIBUTING.md CHANGED
@@ -49,7 +49,9 @@ No hot reload. Tabby doesn't support it for plugins. Restart after each build.
49
49
  2. Create a branch (`git checkout -b fix/thing`)
50
50
  3. Make your changes
51
51
  4. Test manually in Tabby
52
- 5. Submit PR with a clear description
52
+ 5. Submit PR **to the `dev` branch** (not `main`)
53
+
54
+ CI will check that your code builds. `main` is for releases only.
53
55
 
54
56
  No strict commit message format. Just be clear about what you changed and why.
55
57