@pennyfarthing/cyclist 10.3.1 → 11.0.0-alpha.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.
- package/dist/api/agent-load.d.ts +1 -2
- package/dist/api/agent-load.d.ts.map +1 -1
- package/dist/api/agent-load.js +2 -123
- package/dist/api/agent-load.js.map +1 -1
- package/dist/api/audit-log.d.ts +1 -17
- package/dist/api/audit-log.d.ts.map +1 -1
- package/dist/api/audit-log.js +2 -162
- package/dist/api/audit-log.js.map +1 -1
- package/dist/api/background-tasks.d.ts +1 -26
- package/dist/api/background-tasks.d.ts.map +1 -1
- package/dist/api/background-tasks.js +2 -55
- package/dist/api/background-tasks.js.map +1 -1
- package/dist/api/bell.d.ts +1 -18
- package/dist/api/bell.d.ts.map +1 -1
- package/dist/api/bell.js +2 -33
- package/dist/api/bell.js.map +1 -1
- package/dist/api/code-markers.d.ts +1 -8
- package/dist/api/code-markers.d.ts.map +1 -1
- package/dist/api/code-markers.js +2 -61
- package/dist/api/code-markers.js.map +1 -1
- package/dist/api/complexity.d.ts +1 -2
- package/dist/api/complexity.d.ts.map +1 -1
- package/dist/api/complexity.js +2 -46
- package/dist/api/complexity.js.map +1 -1
- package/dist/api/context.d.ts +1 -37
- package/dist/api/context.d.ts.map +1 -1
- package/dist/api/context.js +2 -143
- package/dist/api/context.js.map +1 -1
- package/dist/api/dead-code.d.ts +1 -2
- package/dist/api/dead-code.d.ts.map +1 -1
- package/dist/api/dead-code.js +2 -69
- package/dist/api/dead-code.js.map +1 -1
- package/dist/api/dependencies.d.ts +1 -2
- package/dist/api/dependencies.d.ts.map +1 -1
- package/dist/api/dependencies.js +2 -42
- package/dist/api/dependencies.js.map +1 -1
- package/dist/api/evaluation.d.ts +1 -19
- package/dist/api/evaluation.d.ts.map +1 -1
- package/dist/api/evaluation.js +2 -127
- package/dist/api/evaluation.js.map +1 -1
- package/dist/api/file-browser.d.ts +1 -8
- package/dist/api/file-browser.d.ts.map +1 -1
- package/dist/api/file-browser.js +2 -114
- package/dist/api/file-browser.js.map +1 -1
- package/dist/api/git.d.ts +1 -46
- package/dist/api/git.d.ts.map +1 -1
- package/dist/api/git.js +2 -354
- package/dist/api/git.js.map +1 -1
- package/dist/api/health-score.d.ts +1 -2
- package/dist/api/health-score.d.ts.map +1 -1
- package/dist/api/health-score.js +2 -46
- package/dist/api/health-score.js.map +1 -1
- package/dist/api/hook-request.d.ts +1 -40
- package/dist/api/hook-request.d.ts.map +1 -1
- package/dist/api/hook-request.js +2 -277
- package/dist/api/hook-request.js.map +1 -1
- package/dist/api/hotspots.d.ts +1 -2
- package/dist/api/hotspots.d.ts.map +1 -1
- package/dist/api/hotspots.js +2 -61
- package/dist/api/hotspots.js.map +1 -1
- package/dist/api/identity.d.ts +1 -16
- package/dist/api/identity.d.ts.map +1 -1
- package/dist/api/identity.js +2 -78
- package/dist/api/identity.js.map +1 -1
- package/dist/api/index.d.ts +1 -34
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +2 -44
- package/dist/api/index.js.map +1 -1
- package/dist/api/mode.d.ts +1 -22
- package/dist/api/mode.d.ts.map +1 -1
- package/dist/api/mode.js +2 -37
- package/dist/api/mode.js.map +1 -1
- package/dist/api/otlp.d.ts +1 -2
- package/dist/api/otlp.d.ts.map +1 -1
- package/dist/api/otlp.js +2 -46
- package/dist/api/otlp.js.map +1 -1
- package/dist/api/permissions.d.ts +1 -15
- package/dist/api/permissions.d.ts.map +1 -1
- package/dist/api/permissions.js +2 -66
- package/dist/api/permissions.js.map +1 -1
- package/dist/api/persona.d.ts +1 -8
- package/dist/api/persona.d.ts.map +1 -1
- package/dist/api/persona.js +2 -67
- package/dist/api/persona.js.map +1 -1
- package/dist/api/portrait.d.ts +1 -5
- package/dist/api/portrait.d.ts.map +1 -1
- package/dist/api/portrait.js +2 -27
- package/dist/api/portrait.js.map +1 -1
- package/dist/api/settings.d.ts +1 -53
- package/dist/api/settings.d.ts.map +1 -1
- package/dist/api/settings.js +2 -464
- package/dist/api/settings.js.map +1 -1
- package/dist/api/spans.d.ts +1 -16
- package/dist/api/spans.d.ts.map +1 -1
- package/dist/api/spans.js +2 -244
- package/dist/api/spans.js.map +1 -1
- package/dist/api/stats.d.ts +1 -12
- package/dist/api/stats.d.ts.map +1 -1
- package/dist/api/stats.js +2 -84
- package/dist/api/stats.js.map +1 -1
- package/dist/api/story.d.ts +1 -2
- package/dist/api/story.d.ts.map +1 -1
- package/dist/api/story.js +2 -14
- package/dist/api/story.js.map +1 -1
- package/dist/api/telemetry.d.ts +1 -18
- package/dist/api/telemetry.d.ts.map +1 -1
- package/dist/api/telemetry.js +2 -164
- package/dist/api/telemetry.js.map +1 -1
- package/dist/api/theme-agents.d.ts +1 -60
- package/dist/api/theme-agents.d.ts.map +1 -1
- package/dist/api/theme-agents.js +2 -213
- package/dist/api/theme-agents.js.map +1 -1
- package/dist/api/todos.d.ts +1 -32
- package/dist/api/todos.d.ts.map +1 -1
- package/dist/api/todos.js +2 -43
- package/dist/api/todos.js.map +1 -1
- package/dist/api/token-stats.d.ts +1 -7
- package/dist/api/token-stats.d.ts.map +1 -1
- package/dist/api/token-stats.js +2 -35
- package/dist/api/token-stats.js.map +1 -1
- package/dist/api/welcome.d.ts +1 -21
- package/dist/api/welcome.d.ts.map +1 -1
- package/dist/api/welcome.js +2 -34
- package/dist/api/welcome.js.map +1 -1
- package/dist/env.d.ts +6 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +10 -0
- package/dist/env.js.map +1 -0
- package/dist/focus.d.ts +53 -0
- package/dist/focus.d.ts.map +1 -0
- package/dist/focus.js +122 -0
- package/dist/focus.js.map +1 -0
- package/dist/menu-builder.d.ts.map +1 -1
- package/dist/menu-builder.js +0 -1
- package/dist/menu-builder.js.map +1 -1
- package/dist/public/css/react.css +1 -1
- package/dist/public/js/react/react.js +51 -59
- package/dist/server.d.ts +16 -85
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +38 -409
- package/dist/server.js.map +1 -1
- package/dist/sprint-data.d.ts +1 -1
- package/dist/sprint-data.d.ts.map +1 -1
- package/dist/sprint-data.js +29 -8
- package/dist/sprint-data.js.map +1 -1
- package/dist/websocket.d.ts +2 -0
- package/dist/websocket.d.ts.map +1 -1
- package/dist/websocket.js +45 -78
- package/dist/websocket.js.map +1 -1
- package/package.json +33 -35
- package/portraits/hogans-heroes/large/burkhalter-35312.png +0 -0
- package/portraits/hogans-heroes/large/carter-34352.png +0 -0
- package/portraits/hogans-heroes/large/hochstetter-45314.png +0 -0
- package/portraits/hogans-heroes/large/hogan-44541.png +0 -0
- package/portraits/hogans-heroes/large/kinch-35241.png +0 -0
- package/portraits/hogans-heroes/large/klink-23434.png +0 -0
- package/portraits/hogans-heroes/large/lebeau-45443.png +0 -0
- package/portraits/hogans-heroes/large/marya-53543.png +0 -0
- package/portraits/hogans-heroes/large/newkirk-54432.png +0 -0
- package/portraits/hogans-heroes/large/schultz-42453.png +0 -0
- package/portraits/hogans-heroes/large/underground-55131.png +0 -0
- package/portraits/hogans-heroes/medium/burkhalter-35312.png +0 -0
- package/portraits/hogans-heroes/medium/carter-34352.png +0 -0
- package/portraits/hogans-heroes/medium/hochstetter-45314.png +0 -0
- package/portraits/hogans-heroes/medium/hogan-44541.png +0 -0
- package/portraits/hogans-heroes/medium/kinch-35241.png +0 -0
- package/portraits/hogans-heroes/medium/klink-23434.png +0 -0
- package/portraits/hogans-heroes/medium/lebeau-45443.png +0 -0
- package/portraits/hogans-heroes/medium/marya-53543.png +0 -0
- package/portraits/hogans-heroes/medium/newkirk-54432.png +0 -0
- package/portraits/hogans-heroes/medium/schultz-42453.png +0 -0
- package/portraits/hogans-heroes/medium/underground-55131.png +0 -0
- package/portraits/monty-python/large/announcer-44441.png +0 -0
- package/portraits/monty-python/large/arguer-35412.png +0 -0
- package/portraits/monty-python/large/bicycle-repair-man-35241.png +0 -0
- package/portraits/monty-python/large/colonel-35423.png +0 -0
- package/portraits/monty-python/large/counsellor-45341.png +0 -0
- package/portraits/monty-python/large/gumbys-23524.png +0 -0
- package/portraits/monty-python/large/nudge-43533.png +0 -0
- package/portraits/monty-python/large/praline-45413.png +0 -0
- package/portraits/monty-python/large/silly-walks-55322.png +0 -0
- package/portraits/monty-python/large/wensleydale-54451.png +0 -0
- package/portraits/monty-python/large/xim-nez-43534.png +0 -0
- package/portraits/monty-python/medium/announcer-44441.png +0 -0
- package/portraits/monty-python/medium/arguer-35412.png +0 -0
- package/portraits/monty-python/medium/bicycle-repair-man-35241.png +0 -0
- package/portraits/monty-python/medium/colonel-35423.png +0 -0
- package/portraits/monty-python/medium/counsellor-45341.png +0 -0
- package/portraits/monty-python/medium/gumbys-23524.png +0 -0
- package/portraits/monty-python/medium/nudge-43533.png +0 -0
- package/portraits/monty-python/medium/praline-45413.png +0 -0
- package/portraits/monty-python/medium/silly-walks-55322.png +0 -0
- package/portraits/monty-python/medium/wensleydale-54451.png +0 -0
- package/portraits/monty-python/medium/xim-nez-43534.png +0 -0
- package/portraits/stephen-king/large/andy-55231.png +0 -0
- package/portraits/stephen-king/large/christine-25112.png +0 -0
- package/portraits/stephen-king/large/danny-53243.png +0 -0
- package/portraits/stephen-king/large/flagg-55311.png +0 -0
- package/portraits/stephen-king/large/gaunt-54421.png +0 -0
- package/portraits/stephen-king/large/jack-44224.png +0 -0
- package/portraits/stephen-king/large/johnny-44353.png +0 -0
- package/portraits/stephen-king/large/margaret-15415.png +0 -0
- package/portraits/stephen-king/large/paul-45233.png +0 -0
- package/portraits/stephen-king/large/pennywise-54411.png +0 -0
- package/portraits/stephen-king/large/roland-35121.png +0 -0
- package/portraits/stephen-king/medium/andy-55231.png +0 -0
- package/portraits/stephen-king/medium/christine-25112.png +0 -0
- package/portraits/stephen-king/medium/danny-53243.png +0 -0
- package/portraits/stephen-king/medium/flagg-55311.png +0 -0
- package/portraits/stephen-king/medium/gaunt-54421.png +0 -0
- package/portraits/stephen-king/medium/jack-44224.png +0 -0
- package/portraits/stephen-king/medium/johnny-44353.png +0 -0
- package/portraits/stephen-king/medium/margaret-15415.png +0 -0
- package/portraits/stephen-king/medium/paul-45233.png +0 -0
- package/portraits/stephen-king/medium/pennywise-54411.png +0 -0
- package/portraits/stephen-king/medium/roland-35121.png +0 -0
- package/src/public/App.tsx +21 -5
- package/src/public/components/BikeRackIndex.tsx +0 -1
- package/src/public/components/BikeRackWorkspace.tsx +86 -11
- package/src/public/components/DockviewWorkspace.tsx +19 -8
- package/src/public/components/StandalonePanel.tsx +1 -3
- package/src/public/components/panel-registry.ts +3 -1
- package/src/public/components/panels/AuditLogPanel.tsx +28 -4
- package/src/public/components/panels/GitPanel.tsx +1 -20
- package/src/public/components/panels/SettingsPanel.tsx +0 -1
- package/src/public/components/panels/SprintPanel.tsx +32 -1
- package/src/public/components/panels/index.ts +0 -2
- package/src/public/hooks/useFocusPanel.ts +137 -0
- package/src/public/hooks/useLayoutPersistence.ts +8 -5
- package/src/public/styles/dockview-theme.css +1 -84
- package/src/public/styles/tailwind.css +27 -32
- package/src/public/utils/slash-commands.ts +122 -98
- package/LICENSE +0 -14
- package/dist/hooks/cyclist-pretooluse-hook.d.ts +0 -60
- package/dist/hooks/cyclist-pretooluse-hook.d.ts.map +0 -1
- package/dist/hooks/cyclist-pretooluse-hook.js +0 -57
- package/dist/hooks/cyclist-pretooluse-hook.js.map +0 -1
- package/dist/hooks/pretooluse-hook.d.ts +0 -89
- package/dist/hooks/pretooluse-hook.d.ts.map +0 -1
- package/dist/hooks/pretooluse-hook.js +0 -235
- package/dist/hooks/pretooluse-hook.js.map +0 -1
- package/dist/notification-sound.d.ts +0 -59
- package/dist/notification-sound.d.ts.map +0 -1
- package/dist/notification-sound.js +0 -219
- package/dist/notification-sound.js.map +0 -1
- package/dist/plugin-loader.test.d.ts +0 -17
- package/dist/plugin-loader.test.d.ts.map +0 -1
- package/dist/plugin-loader.test.js +0 -407
- package/dist/plugin-loader.test.js.map +0 -1
- package/portraits/star-trek-tng/large/beverly-44352.png +0 -0
- package/portraits/star-trek-tng/large/data-55241.png +0 -0
- package/portraits/star-trek-tng/large/deanna-43353.png +0 -0
- package/portraits/star-trek-tng/large/geordi-54342.png +0 -0
- package/portraits/star-trek-tng/large/jean-luc-45342.png +0 -0
- package/portraits/star-trek-tng/large/kathryn-45332.png +0 -0
- package/portraits/star-trek-tng/large/miles-35342.png +0 -0
- package/portraits/star-trek-tng/large/q-53521.png +0 -0
- package/portraits/star-trek-tng/large/spock-45231.png +0 -0
- package/portraits/star-trek-tng/large/troi-44352.png +0 -0
- package/portraits/star-trek-tng/medium/beverly-44352.png +0 -0
- package/portraits/star-trek-tng/medium/data-55241.png +0 -0
- package/portraits/star-trek-tng/medium/deanna-43353.png +0 -0
- package/portraits/star-trek-tng/medium/geordi-54342.png +0 -0
- package/portraits/star-trek-tng/medium/jean-luc-45342.png +0 -0
- package/portraits/star-trek-tng/medium/kathryn-45332.png +0 -0
- package/portraits/star-trek-tng/medium/miles-35342.png +0 -0
- package/portraits/star-trek-tng/medium/q-53521.png +0 -0
- package/portraits/star-trek-tng/medium/spock-45231.png +0 -0
- package/portraits/star-trek-tng/medium/troi-44352.png +0 -0
- package/src/public/components/panels/TTYPanel.tsx +0 -299
- package/src/public/types/electron.d.ts +0 -18
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pennyfarthing/cyclist",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "11.0.0-alpha.0",
|
|
4
4
|
"description": "Visual terminal interface for Claude Code",
|
|
5
5
|
"author": "1898andCo",
|
|
6
6
|
"type": "module",
|
|
@@ -19,7 +19,37 @@
|
|
|
19
19
|
"src/public/",
|
|
20
20
|
"portraits/"
|
|
21
21
|
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"dev": "npm run build && concurrently -k -n tsc,preload,vite,electron -c blue,cyan,magenta,green \"tsc --watch --preserveWatchOutput\" \"tsc -p tsconfig.preload.json --watch --preserveWatchOutput\" \"vite build --watch\" \"electron dist/main.js\"",
|
|
24
|
+
"dev:cdp": "npm run build && concurrently -k -n tsc,preload,vite,electron -c blue,cyan,magenta,green \"tsc --watch --preserveWatchOutput\" \"tsc -p tsconfig.preload.json --watch --preserveWatchOutput\" \"vite build --watch\" \"electron --remote-debugging-port=9222 dist/main.js\"",
|
|
25
|
+
"dev:once": "npm run build && electron dist/main.js",
|
|
26
|
+
"dev:web": "CYCLIST_ELECTRON_MODE= CYCLIST_DEV_WEB=1 CYCLIST_PROJECT_DIR=${CYCLIST_PROJECT_DIR:-$PWD} tsx watch src/server.ts",
|
|
27
|
+
"dev:server": "tsx watch src/server.ts",
|
|
28
|
+
"dev:debug": "CYCLIST_DEV_WEB=1 OTEL_DEBUG=true CYCLIST_PROJECT_DIR=${CYCLIST_PROJECT_DIR:-$PWD} node --inspect src/server.ts",
|
|
29
|
+
"dev:debug-brk": "CYCLIST_DEV_WEB=1 OTEL_DEBUG=true CYCLIST_PROJECT_DIR=${CYCLIST_PROJECT_DIR:-$PWD} node --inspect-brk src/server.ts",
|
|
30
|
+
"dev:electron-debug": "npm run build && concurrently -k -n tsc,preload,vite,electron -c blue,cyan,magenta,green \"tsc --watch --preserveWatchOutput\" \"tsc -p tsconfig.preload.json --watch --preserveWatchOutput\" \"vite build --watch\" \"electron --inspect=9229 dist/main.js\"",
|
|
31
|
+
"dev:vite": "vite --config vite.config.ts",
|
|
32
|
+
"lint": "eslint src/",
|
|
33
|
+
"build": "npm run build:commands && tsc --build && tsc -p tsconfig.preload.json && npm run build:react",
|
|
34
|
+
"build:react": "vite build",
|
|
35
|
+
"build:commands": "node scripts/generate-slash-commands.js",
|
|
36
|
+
"build:electron": "npm run build && electron-builder -c.npmRebuild=false",
|
|
37
|
+
"start": "node dist/server.js",
|
|
38
|
+
"test": "vitest run",
|
|
39
|
+
"test:watch": "vitest",
|
|
40
|
+
"test:e2e": "playwright test",
|
|
41
|
+
"test:e2e:web": "playwright test --project=web-chromium",
|
|
42
|
+
"test:e2e:ui": "playwright test --ui",
|
|
43
|
+
"test:e2e:debug": "playwright test --debug",
|
|
44
|
+
"test:e2e:trace": "playwright show-trace",
|
|
45
|
+
"prepack": "./scripts/copy-portraits.sh",
|
|
46
|
+
"install:app": "./scripts/install-app.sh",
|
|
47
|
+
"install:cli": "./scripts/install-cli.sh",
|
|
48
|
+
"install:all": "npm run install:app && npm run install:cli"
|
|
49
|
+
},
|
|
22
50
|
"dependencies": {
|
|
51
|
+
"@pennyfarthing/core": "^10.4.0",
|
|
52
|
+
"@pennyfarthing/shared": "^10.4.0",
|
|
23
53
|
"@radix-ui/react-alert-dialog": "^1.1.15",
|
|
24
54
|
"@radix-ui/react-checkbox": "^1.3.3",
|
|
25
55
|
"@radix-ui/react-collapsible": "^1.1.12",
|
|
@@ -42,16 +72,11 @@
|
|
|
42
72
|
"electron-window-state": "^5.0.3",
|
|
43
73
|
"express": "^4.18.2",
|
|
44
74
|
"lucide-react": "^0.563.0",
|
|
45
|
-
"node-pty": "^1.1.0",
|
|
46
75
|
"react": "^19.2.4",
|
|
47
76
|
"react-dom": "^19.2.4",
|
|
48
77
|
"tailwind-merge": "^3.4.0",
|
|
49
78
|
"ws": "^8.19.0",
|
|
50
|
-
"
|
|
51
|
-
"xterm-addon-fit": "^0.8.0",
|
|
52
|
-
"yaml": "^2.8.2",
|
|
53
|
-
"@pennyfarthing/core": "^10.3.1",
|
|
54
|
-
"@pennyfarthing/shared": "^10.3.1"
|
|
79
|
+
"yaml": "^2.8.2"
|
|
55
80
|
},
|
|
56
81
|
"devDependencies": {
|
|
57
82
|
"@electron/rebuild": "^3.6.0",
|
|
@@ -159,32 +184,5 @@
|
|
|
159
184
|
],
|
|
160
185
|
"category": "Development"
|
|
161
186
|
}
|
|
162
|
-
},
|
|
163
|
-
"scripts": {
|
|
164
|
-
"dev": "npm run build && concurrently -k -n tsc,preload,vite,electron -c blue,cyan,magenta,green \"tsc --watch --preserveWatchOutput\" \"tsc -p tsconfig.preload.json --watch --preserveWatchOutput\" \"vite build --watch\" \"electron dist/main.js\"",
|
|
165
|
-
"dev:cdp": "npm run build && concurrently -k -n tsc,preload,vite,electron -c blue,cyan,magenta,green \"tsc --watch --preserveWatchOutput\" \"tsc -p tsconfig.preload.json --watch --preserveWatchOutput\" \"vite build --watch\" \"electron --remote-debugging-port=9222 dist/main.js\"",
|
|
166
|
-
"dev:once": "npm run build && electron dist/main.js",
|
|
167
|
-
"dev:web": "CYCLIST_ELECTRON_MODE= CYCLIST_DEV_WEB=1 CYCLIST_PROJECT_DIR=${CYCLIST_PROJECT_DIR:-$PWD} tsx watch src/server.ts",
|
|
168
|
-
"dev:server": "tsx watch src/server.ts",
|
|
169
|
-
"dev:debug": "CYCLIST_DEV_WEB=1 OTEL_DEBUG=true CYCLIST_PROJECT_DIR=${CYCLIST_PROJECT_DIR:-$PWD} node --inspect src/server.ts",
|
|
170
|
-
"dev:debug-brk": "CYCLIST_DEV_WEB=1 OTEL_DEBUG=true CYCLIST_PROJECT_DIR=${CYCLIST_PROJECT_DIR:-$PWD} node --inspect-brk src/server.ts",
|
|
171
|
-
"dev:electron-debug": "npm run build && concurrently -k -n tsc,preload,vite,electron -c blue,cyan,magenta,green \"tsc --watch --preserveWatchOutput\" \"tsc -p tsconfig.preload.json --watch --preserveWatchOutput\" \"vite build --watch\" \"electron --inspect=9229 dist/main.js\"",
|
|
172
|
-
"dev:vite": "vite --config vite.config.ts",
|
|
173
|
-
"lint": "eslint src/",
|
|
174
|
-
"build": "npm run build:commands && tsc --build && tsc -p tsconfig.preload.json && npm run build:react",
|
|
175
|
-
"build:react": "vite build",
|
|
176
|
-
"build:commands": "node scripts/generate-slash-commands.js",
|
|
177
|
-
"build:electron": "npm run build && electron-builder -c.npmRebuild=false",
|
|
178
|
-
"start": "node dist/server.js",
|
|
179
|
-
"test": "vitest run",
|
|
180
|
-
"test:watch": "vitest",
|
|
181
|
-
"test:e2e": "playwright test",
|
|
182
|
-
"test:e2e:web": "playwright test --project=web-chromium",
|
|
183
|
-
"test:e2e:ui": "playwright test --ui",
|
|
184
|
-
"test:e2e:debug": "playwright test --debug",
|
|
185
|
-
"test:e2e:trace": "playwright show-trace",
|
|
186
|
-
"install:app": "./scripts/install-app.sh",
|
|
187
|
-
"install:cli": "./scripts/install-cli.sh",
|
|
188
|
-
"install:all": "npm run install:app && npm run install:cli"
|
|
189
187
|
}
|
|
190
|
-
}
|
|
188
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/src/public/App.tsx
CHANGED
|
@@ -29,6 +29,13 @@ import ApprovalModal, { useApprovalModal } from './components/ApprovalModal';
|
|
|
29
29
|
import { subscribeToPermissionRequests, sendPermissionResponse, createApprovalResponse } from './components/ApprovalModal';
|
|
30
30
|
import type { ApprovalRequest, GrantScope } from './components/ApprovalModal';
|
|
31
31
|
|
|
32
|
+
// Environment discriminator injected by server.ts (ADR-0024)
|
|
33
|
+
declare global {
|
|
34
|
+
interface Window {
|
|
35
|
+
__CYCLIST_MODE__?: 'cyclist' | 'bikerack';
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
32
39
|
// Import all panel components
|
|
33
40
|
// Note: ProgressPanel split into Workflow/AC/Todo panels (MSSCI-14188)
|
|
34
41
|
import {
|
|
@@ -44,7 +51,6 @@ import {
|
|
|
44
51
|
DebugPanel,
|
|
45
52
|
SettingsPanel,
|
|
46
53
|
AuditLogPanel,
|
|
47
|
-
TTYPanel,
|
|
48
54
|
} from './components/panels';
|
|
49
55
|
|
|
50
56
|
// =============================================================================
|
|
@@ -60,7 +66,6 @@ registerPanelComponent(PANEL_INVENTORY.CHANGED, ChangedPanel);
|
|
|
60
66
|
registerPanelComponent(PANEL_INVENTORY.DIFFS, DiffsPanel);
|
|
61
67
|
registerPanelComponent(PANEL_INVENTORY.DEBUG, DebugPanel);
|
|
62
68
|
registerPanelComponent(PANEL_INVENTORY.AUDIT_LOG, AuditLogPanel);
|
|
63
|
-
registerPanelComponent(PANEL_INVENTORY.TTY, TTYPanel);
|
|
64
69
|
|
|
65
70
|
// Right sidebar panels
|
|
66
71
|
// Note: ProgressPanel split into Workflow/AC/Todo panels (MSSCI-14188)
|
|
@@ -202,12 +207,13 @@ function RootErrorFallback(): React.ReactElement {
|
|
|
202
207
|
|
|
203
208
|
export default function App(): React.ReactElement {
|
|
204
209
|
// Detect route mode (computed before hooks, used after)
|
|
205
|
-
const isBikeRackIndex = window.
|
|
210
|
+
const isBikeRackIndex = window.__CYCLIST_MODE__ === 'bikerack';
|
|
206
211
|
const standalonePanelName = getStandalonePanelName();
|
|
207
212
|
|
|
208
213
|
// --- All hooks called unconditionally (React rules of hooks) ---
|
|
209
214
|
|
|
210
|
-
const
|
|
215
|
+
const layoutEndpoint = isBikeRackIndex ? '/api/settings/bikerack-layout' : '/api/settings/layout';
|
|
216
|
+
const { layout, isLoading, saveLayout } = useLayoutPersistence(layoutEndpoint);
|
|
211
217
|
|
|
212
218
|
// Set up reduced motion support
|
|
213
219
|
useReducedMotion();
|
|
@@ -268,6 +274,13 @@ export default function App(): React.ReactElement {
|
|
|
268
274
|
// BikeRack Dockview workspace (MSSCI-14877) — /bikerack renders Dockview layout
|
|
269
275
|
// No-op ClaudeContext: BikeRack has no Claude CLI subprocess, skip WebSocket
|
|
270
276
|
if (isBikeRackIndex) {
|
|
277
|
+
if (isLoading) {
|
|
278
|
+
return (
|
|
279
|
+
<div className="cyclist-loading" style={{ height: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
|
280
|
+
<div className="loading-spinner" aria-label="Loading layout..." />
|
|
281
|
+
</div>
|
|
282
|
+
);
|
|
283
|
+
}
|
|
271
284
|
const noop = () => () => {};
|
|
272
285
|
return (
|
|
273
286
|
<ClaudeContext.Provider value={{
|
|
@@ -277,7 +290,10 @@ export default function App(): React.ReactElement {
|
|
|
277
290
|
onMessage: noop, onComplete: noop, onError: noop,
|
|
278
291
|
onUserMessage: noop, onClear: noop,
|
|
279
292
|
}}>
|
|
280
|
-
<BikeRackWorkspace
|
|
293
|
+
<BikeRackWorkspace
|
|
294
|
+
initialLayout={layout ?? undefined}
|
|
295
|
+
onLayoutChange={saveLayout}
|
|
296
|
+
/>
|
|
281
297
|
</ClaudeContext.Provider>
|
|
282
298
|
);
|
|
283
299
|
}
|
|
@@ -25,7 +25,6 @@ const PANELS = [
|
|
|
25
25
|
{ id: 'audit', label: 'Audit', description: 'OTEL spans and logs' },
|
|
26
26
|
{ id: 'changed', label: 'Changed', description: 'Changed files' },
|
|
27
27
|
{ id: 'ac', label: 'AC', description: 'Acceptance criteria detail' },
|
|
28
|
-
{ id: 'tty', label: 'TTY', description: 'Terminal output' },
|
|
29
28
|
{ id: 'debug', label: 'Debug', description: 'Debug information' },
|
|
30
29
|
{ id: 'bikelane', label: 'BikeLane', description: 'Workflow visualization' },
|
|
31
30
|
{ id: 'settings', label: 'Settings', description: 'Theme, fonts, and display preferences' },
|
|
@@ -9,17 +9,20 @@
|
|
|
9
9
|
* Single Dockview group — users can freely rearrange panels.
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import React, { useCallback, useRef } from 'react';
|
|
12
|
+
import React, { useCallback, useRef, useEffect, useState } from 'react';
|
|
13
13
|
import {
|
|
14
14
|
DockviewReact,
|
|
15
15
|
DockviewReadyEvent,
|
|
16
16
|
DockviewApi,
|
|
17
17
|
IDockviewPanelProps,
|
|
18
|
+
SerializedDockview,
|
|
19
|
+
DockviewDefaultTab,
|
|
18
20
|
} from 'dockview-react';
|
|
19
21
|
import 'dockview-react/dist/styles/dockview.css';
|
|
20
22
|
import { ErrorBoundary } from './ErrorBoundary';
|
|
21
23
|
import { panelRegistry } from './panel-registry';
|
|
22
24
|
import PersonaHeader from './PersonaHeader.js';
|
|
25
|
+
import { useFocusPanel } from '../hooks/useFocusPanel.js';
|
|
23
26
|
import '../styles/dockview-theme.css';
|
|
24
27
|
|
|
25
28
|
// =============================================================================
|
|
@@ -94,12 +97,41 @@ function PanelAdapter({ params }: IDockviewPanelProps<PanelAdapterParams>): Reac
|
|
|
94
97
|
// BikeRackWorkspace Component
|
|
95
98
|
// =============================================================================
|
|
96
99
|
|
|
97
|
-
export
|
|
100
|
+
export interface BikeRackWorkspaceProps {
|
|
101
|
+
initialLayout?: SerializedDockview;
|
|
102
|
+
onLayoutChange?: (layout: SerializedDockview) => void;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function BikeRackWorkspace({
|
|
106
|
+
initialLayout,
|
|
107
|
+
onLayoutChange,
|
|
108
|
+
}: BikeRackWorkspaceProps): React.ReactElement {
|
|
98
109
|
const apiRef = useRef<DockviewApi | null>(null);
|
|
110
|
+
const [dockviewApi, setDockviewApi] = useState<DockviewApi | null>(null);
|
|
111
|
+
const saveTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
112
|
+
|
|
113
|
+
// Panel focus mode — stash/restore layout on /bc CLI events
|
|
114
|
+
useFocusPanel(dockviewApi);
|
|
99
115
|
|
|
100
116
|
const onReady = useCallback((event: DockviewReadyEvent) => {
|
|
101
117
|
const api = event.api;
|
|
102
118
|
apiRef.current = api;
|
|
119
|
+
setDockviewApi(api);
|
|
120
|
+
|
|
121
|
+
// Restore saved layout if available (must have actual panels, not just empty {})
|
|
122
|
+
if (initialLayout && initialLayout.grid && initialLayout.panels
|
|
123
|
+
&& Object.keys(initialLayout.panels).length > 0) {
|
|
124
|
+
try {
|
|
125
|
+
api.fromJSON(initialLayout);
|
|
126
|
+
// Verify panels were actually created
|
|
127
|
+
if (api.panels.length > 0) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
console.warn('[BikeRackWorkspace] Restored layout produced no panels, building default');
|
|
131
|
+
} catch (err) {
|
|
132
|
+
console.warn('[BikeRackWorkspace] Failed to restore layout, building default:', err);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
103
135
|
|
|
104
136
|
// Single group — all panels as tabs, user can rearrange freely
|
|
105
137
|
const first = api.addPanel({
|
|
@@ -118,23 +150,66 @@ export function BikeRackWorkspace(): React.ReactElement {
|
|
|
118
150
|
title: PANEL_TITLES[BIKERACK_PANELS[i]],
|
|
119
151
|
});
|
|
120
152
|
}
|
|
153
|
+
}, [initialLayout]);
|
|
154
|
+
|
|
155
|
+
// Subscribe to layout changes for persistence
|
|
156
|
+
const handleLayoutChange = useCallback(() => {
|
|
157
|
+
const api = apiRef.current;
|
|
158
|
+
if (!api || !onLayoutChange) return;
|
|
159
|
+
|
|
160
|
+
// Never save empty layouts — prevents corruption loop
|
|
161
|
+
if (api.panels.length === 0) return;
|
|
162
|
+
|
|
163
|
+
if (saveTimeoutRef.current) {
|
|
164
|
+
clearTimeout(saveTimeoutRef.current);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
saveTimeoutRef.current = setTimeout(() => {
|
|
168
|
+
const serialized = api.toJSON();
|
|
169
|
+
// Double-check: don't persist if serialization produced empty panels
|
|
170
|
+
if (serialized.panels && Object.keys(serialized.panels).length > 0) {
|
|
171
|
+
onLayoutChange(serialized);
|
|
172
|
+
}
|
|
173
|
+
}, 300);
|
|
174
|
+
}, [onLayoutChange]);
|
|
175
|
+
|
|
176
|
+
useEffect(() => {
|
|
177
|
+
const api = apiRef.current;
|
|
178
|
+
if (!api) return;
|
|
179
|
+
|
|
180
|
+
const disposables = [
|
|
181
|
+
api.onDidLayoutChange(() => handleLayoutChange()),
|
|
182
|
+
api.onDidAddPanel(() => handleLayoutChange()),
|
|
183
|
+
api.onDidRemovePanel(() => handleLayoutChange()),
|
|
184
|
+
];
|
|
185
|
+
|
|
186
|
+
return () => disposables.forEach(d => d.dispose());
|
|
187
|
+
}, [handleLayoutChange]);
|
|
188
|
+
|
|
189
|
+
// Cleanup on unmount
|
|
190
|
+
useEffect(() => {
|
|
191
|
+
return () => {
|
|
192
|
+
if (saveTimeoutRef.current) {
|
|
193
|
+
clearTimeout(saveTimeoutRef.current);
|
|
194
|
+
}
|
|
195
|
+
};
|
|
121
196
|
}, []);
|
|
122
197
|
|
|
123
|
-
|
|
198
|
+
// Memoize to prevent DockviewReact from reinitializing on re-render
|
|
199
|
+
const components = React.useMemo(() => ({ PanelAdapter }), []);
|
|
124
200
|
|
|
125
201
|
return (
|
|
126
202
|
<div className="cyclist-app cyclist-dockview" style={{ height: '100vh', width: '100vw', display: 'flex', flexDirection: 'column' }}>
|
|
127
203
|
<div data-testid="bikerack-portrait-anchor" style={{ flexShrink: 0 }}>
|
|
128
204
|
<PersonaHeader />
|
|
129
205
|
</div>
|
|
130
|
-
<
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
</div>
|
|
206
|
+
<DockviewReact
|
|
207
|
+
className="dockview-container"
|
|
208
|
+
onReady={onReady}
|
|
209
|
+
components={components}
|
|
210
|
+
defaultTabComponent={(props) => <DockviewDefaultTab {...props} hideClose />}
|
|
211
|
+
watermarkComponent={() => null}
|
|
212
|
+
/>
|
|
138
213
|
</div>
|
|
139
214
|
);
|
|
140
215
|
}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* - Theme integration via CSS custom properties
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
import React, { useEffect, useRef, useCallback, useState
|
|
16
|
+
import React, { useEffect, useRef, useCallback, useState } from 'react';
|
|
17
17
|
import { Button } from '@/components/ui/button';
|
|
18
18
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
|
|
19
19
|
import {
|
|
@@ -23,11 +23,13 @@ import {
|
|
|
23
23
|
DockviewApi,
|
|
24
24
|
IDockviewPanel,
|
|
25
25
|
SerializedDockview,
|
|
26
|
+
DockviewDefaultTab,
|
|
26
27
|
} from 'dockview-react';
|
|
27
28
|
import 'dockview-react/dist/styles/dockview.css';
|
|
28
29
|
import { ErrorBoundary } from './ErrorBoundary';
|
|
29
|
-
import { panelRegistry } from './panel-registry';
|
|
30
|
+
import { panelRegistry, type PanelComponent } from './panel-registry';
|
|
30
31
|
import { useResponsiveLayout, MIN_DIMENSIONS, SIDEBAR_WIDTHS } from '../hooks/useResponsiveLayout';
|
|
32
|
+
import { useFocusPanel } from '../hooks/useFocusPanel.js';
|
|
31
33
|
import '../styles/dockview-theme.css';
|
|
32
34
|
|
|
33
35
|
// =============================================================================
|
|
@@ -40,7 +42,6 @@ export const PANEL_INVENTORY = {
|
|
|
40
42
|
DIFFS: 'diffs',
|
|
41
43
|
DEBUG: 'debug',
|
|
42
44
|
AUDIT_LOG: 'audit-log',
|
|
43
|
-
TTY: 'tty',
|
|
44
45
|
// Center panel (sacred)
|
|
45
46
|
MESSAGE: 'message',
|
|
46
47
|
// Right sidebar panels
|
|
@@ -62,7 +63,7 @@ export type PanelId = typeof PANEL_INVENTORY[keyof typeof PANEL_INVENTORY];
|
|
|
62
63
|
/**
|
|
63
64
|
* Register a panel component by ID
|
|
64
65
|
*/
|
|
65
|
-
export function registerPanelComponent(id: string, component:
|
|
66
|
+
export function registerPanelComponent(id: string, component: PanelComponent): void {
|
|
66
67
|
panelRegistry.set(id, component);
|
|
67
68
|
}
|
|
68
69
|
|
|
@@ -81,7 +82,7 @@ export function getDockviewApi(): DockviewApi | null {
|
|
|
81
82
|
|
|
82
83
|
// Panel group definitions (needed for restore logic)
|
|
83
84
|
// Exported so layout persistence can merge missing panels
|
|
84
|
-
export const LEFT_SIDEBAR_PANELS = [PANEL_INVENTORY.CHANGED, PANEL_INVENTORY.DIFFS, PANEL_INVENTORY.DEBUG, PANEL_INVENTORY.AUDIT_LOG
|
|
85
|
+
export const LEFT_SIDEBAR_PANELS = [PANEL_INVENTORY.CHANGED, PANEL_INVENTORY.DIFFS, PANEL_INVENTORY.DEBUG, PANEL_INVENTORY.AUDIT_LOG] as const;
|
|
85
86
|
export const RIGHT_SIDEBAR_PANELS = [
|
|
86
87
|
PANEL_INVENTORY.SPRINT,
|
|
87
88
|
PANEL_INVENTORY.WORKFLOW,
|
|
@@ -98,7 +99,6 @@ const PANEL_TITLES: Record<string, string> = {
|
|
|
98
99
|
diffs: 'Diffs',
|
|
99
100
|
debug: 'Debug',
|
|
100
101
|
'audit-log': 'Audit Log',
|
|
101
|
-
tty: 'Terminal',
|
|
102
102
|
message: 'Message',
|
|
103
103
|
sprint: 'Sprint',
|
|
104
104
|
workflow: 'Workflow',
|
|
@@ -404,11 +404,15 @@ export function DockviewWorkspace({
|
|
|
404
404
|
onLayoutChange,
|
|
405
405
|
}: DockviewWorkspaceProps): React.ReactElement {
|
|
406
406
|
const apiRef = useRef<DockviewApi | null>(null);
|
|
407
|
+
const [dockviewApi, setDockviewApi] = useState<DockviewApi | null>(null);
|
|
407
408
|
const { isSmall, isBelowMinimum, sidebarWidth } = useResponsiveLayout();
|
|
408
409
|
const [isReady, setIsReady] = useState(false);
|
|
409
410
|
const [closedPanelsList, setClosedPanelsList] = useState<string[]>([]);
|
|
410
411
|
const [showRestoreMenu, setShowRestoreMenu] = useState(false);
|
|
411
412
|
const saveTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
413
|
+
// Panel focus mode — stash/restore layout on /bc CLI events
|
|
414
|
+
useFocusPanel(dockviewApi);
|
|
415
|
+
|
|
412
416
|
// Track if responsive effect should apply - skip on initial load to respect saved collapsed state
|
|
413
417
|
const hasAppliedInitialLayout = useRef(false);
|
|
414
418
|
const previousIsSmall = useRef<boolean | null>(null);
|
|
@@ -423,6 +427,7 @@ export function DockviewWorkspace({
|
|
|
423
427
|
const api = event.api;
|
|
424
428
|
apiRef.current = api;
|
|
425
429
|
dockviewApiRef = api;
|
|
430
|
+
setDockviewApi(api);
|
|
426
431
|
|
|
427
432
|
// Use native fromJSON if we have a saved layout, otherwise build default
|
|
428
433
|
if (initialLayout && initialLayout.grid && initialLayout.panels) {
|
|
@@ -526,6 +531,9 @@ export function DockviewWorkspace({
|
|
|
526
531
|
const api = apiRef.current;
|
|
527
532
|
if (!api || !onLayoutChange) return;
|
|
528
533
|
|
|
534
|
+
// Never save empty layouts — prevents corruption loop
|
|
535
|
+
if (api.panels.length === 0) return;
|
|
536
|
+
|
|
529
537
|
// Debounce saves
|
|
530
538
|
if (saveTimeoutRef.current) {
|
|
531
539
|
clearTimeout(saveTimeoutRef.current);
|
|
@@ -534,7 +542,10 @@ export function DockviewWorkspace({
|
|
|
534
542
|
saveTimeoutRef.current = setTimeout(() => {
|
|
535
543
|
// Use native Dockview toJSON for complete layout serialization
|
|
536
544
|
const serializedLayout = api.toJSON();
|
|
537
|
-
|
|
545
|
+
// Double-check: don't persist if serialization produced empty panels
|
|
546
|
+
if (serializedLayout.panels && Object.keys(serializedLayout.panels).length > 0) {
|
|
547
|
+
onLayoutChange(serializedLayout);
|
|
548
|
+
}
|
|
538
549
|
}, 300);
|
|
539
550
|
}, [onLayoutChange]);
|
|
540
551
|
|
|
@@ -659,7 +670,6 @@ export function DockviewWorkspace({
|
|
|
659
670
|
diffs: 'Diffs',
|
|
660
671
|
debug: 'Debug',
|
|
661
672
|
'audit-log': 'Audit Log',
|
|
662
|
-
tty: 'Terminal',
|
|
663
673
|
sprint: 'Sprint',
|
|
664
674
|
workflow: 'Workflow',
|
|
665
675
|
ac: 'AC',
|
|
@@ -728,6 +738,7 @@ export function DockviewWorkspace({
|
|
|
728
738
|
className="dockview-container"
|
|
729
739
|
onReady={onReady}
|
|
730
740
|
components={components}
|
|
741
|
+
defaultTabComponent={(props) => <DockviewDefaultTab {...props} hideClose />}
|
|
731
742
|
watermarkComponent={() => null}
|
|
732
743
|
/>
|
|
733
744
|
</div>
|
|
@@ -24,7 +24,6 @@ import {
|
|
|
24
24
|
AuditLogPanel,
|
|
25
25
|
ChangedPanel,
|
|
26
26
|
ACPanel,
|
|
27
|
-
TTYPanel,
|
|
28
27
|
DebugPanel,
|
|
29
28
|
BikeLanePanel,
|
|
30
29
|
SettingsPanel,
|
|
@@ -44,7 +43,6 @@ export const PANEL_REGISTRY: Record<string, React.ComponentType> = {
|
|
|
44
43
|
audit: AuditLogPanel,
|
|
45
44
|
changed: ChangedPanel,
|
|
46
45
|
ac: ACPanel,
|
|
47
|
-
tty: TTYPanel,
|
|
48
46
|
debug: DebugPanel,
|
|
49
47
|
bikelane: BikeLanePanel,
|
|
50
48
|
settings: SettingsPanel,
|
|
@@ -70,7 +68,7 @@ export function StandalonePanel(): React.ReactElement {
|
|
|
70
68
|
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100vh', width: '100vw', backgroundColor: 'var(--bg-primary, #1a1a2e)', color: 'var(--text-primary, #e4e4e7)' }}>
|
|
71
69
|
<h1>Panel not found</h1>
|
|
72
70
|
<p>
|
|
73
|
-
<a href="/
|
|
71
|
+
<a href="/" style={{ color: 'var(--accent, #818cf8)' }}>Back to BikeRack</a>
|
|
74
72
|
</p>
|
|
75
73
|
</div>
|
|
76
74
|
);
|