jettypod 4.4.116 → 4.4.120

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 (162) hide show
  1. package/.env +7 -0
  2. package/apps/dashboard/app/api/claude/[workItemId]/message/route.ts +124 -48
  3. package/apps/dashboard/app/api/claude/[workItemId]/route.ts +171 -58
  4. package/apps/dashboard/app/api/claude/sessions/[sessionId]/message/route.ts +161 -10
  5. package/apps/dashboard/app/api/tests/run/stream/route.ts +13 -1
  6. package/apps/dashboard/app/api/usage/route.ts +17 -0
  7. package/apps/dashboard/app/api/work/[id]/route.ts +35 -0
  8. package/apps/dashboard/app/api/work/[id]/status/route.ts +43 -1
  9. package/apps/dashboard/app/connect-claude/page.tsx +24 -0
  10. package/apps/dashboard/app/decision/[id]/page.tsx +14 -14
  11. package/apps/dashboard/app/demo/gates/page.tsx +42 -42
  12. package/apps/dashboard/app/design-system/page.tsx +868 -0
  13. package/apps/dashboard/app/globals.css +6 -2
  14. package/apps/dashboard/app/install-claude/page.tsx +9 -7
  15. package/apps/dashboard/app/layout.tsx +17 -5
  16. package/apps/dashboard/app/login/page.tsx +250 -0
  17. package/apps/dashboard/app/page.tsx +11 -9
  18. package/apps/dashboard/app/settings/page.tsx +4 -2
  19. package/apps/dashboard/app/signup/page.tsx +245 -0
  20. package/apps/dashboard/app/subscribe/page.tsx +11 -0
  21. package/apps/dashboard/app/welcome/page.tsx +24 -1
  22. package/apps/dashboard/app/work/[id]/page.tsx +34 -50
  23. package/apps/dashboard/components/AppShell.tsx +95 -55
  24. package/apps/dashboard/components/CardMenu.tsx +56 -13
  25. package/apps/dashboard/components/ClaudePanel.tsx +301 -582
  26. package/apps/dashboard/components/ClaudePanelInput.tsx +23 -14
  27. package/apps/dashboard/components/ConnectClaudeScreen.tsx +210 -0
  28. package/apps/dashboard/components/CopyableId.tsx +3 -3
  29. package/apps/dashboard/components/DetailReviewActions.tsx +109 -0
  30. package/apps/dashboard/components/DragContext.tsx +75 -65
  31. package/apps/dashboard/components/DraggableCard.tsx +6 -46
  32. package/apps/dashboard/components/DropZone.tsx +2 -2
  33. package/apps/dashboard/components/EditableDetailDescription.tsx +1 -1
  34. package/apps/dashboard/components/EditableTitle.tsx +26 -6
  35. package/apps/dashboard/components/ElapsedTimer.tsx +54 -0
  36. package/apps/dashboard/components/EpicGroup.tsx +329 -0
  37. package/apps/dashboard/components/GateCard.tsx +100 -16
  38. package/apps/dashboard/components/GateChoiceCard.tsx +15 -17
  39. package/apps/dashboard/components/InstallClaudeScreen.tsx +140 -51
  40. package/apps/dashboard/components/JettyLoader.tsx +38 -0
  41. package/apps/dashboard/components/KanbanBoard.tsx +147 -766
  42. package/apps/dashboard/components/KanbanCard.tsx +506 -0
  43. package/apps/dashboard/components/LazyMarkdown.tsx +12 -0
  44. package/apps/dashboard/components/MainNav.tsx +20 -54
  45. package/apps/dashboard/components/MessageBlock.tsx +391 -0
  46. package/apps/dashboard/components/ModeStartCard.tsx +15 -15
  47. package/apps/dashboard/components/OnboardingWelcome.tsx +214 -0
  48. package/apps/dashboard/components/PlaceholderCard.tsx +11 -21
  49. package/apps/dashboard/components/ProjectSwitcher.tsx +36 -8
  50. package/apps/dashboard/components/PrototypeTimeline.tsx +25 -25
  51. package/apps/dashboard/components/RealTimeKanbanWrapper.tsx +265 -301
  52. package/apps/dashboard/components/RealTimeTestsWrapper.tsx +97 -74
  53. package/apps/dashboard/components/ReviewFooter.tsx +141 -0
  54. package/apps/dashboard/components/SessionList.tsx +19 -18
  55. package/apps/dashboard/components/SubscribeContent.tsx +206 -0
  56. package/apps/dashboard/components/TestTree.tsx +15 -14
  57. package/apps/dashboard/components/TipCard.tsx +177 -0
  58. package/apps/dashboard/components/Toast.tsx +5 -5
  59. package/apps/dashboard/components/TypeIcon.tsx +56 -0
  60. package/apps/dashboard/components/UpgradeBanner.tsx +30 -0
  61. package/apps/dashboard/components/WaveCompletionAnimation.tsx +61 -62
  62. package/apps/dashboard/components/WelcomeScreen.tsx +25 -27
  63. package/apps/dashboard/components/WorkItemHeader.tsx +4 -4
  64. package/apps/dashboard/components/WorkItemTree.tsx +9 -28
  65. package/apps/dashboard/components/settings/AccountSection.tsx +169 -0
  66. package/apps/dashboard/components/settings/EnvVarsSection.tsx +54 -79
  67. package/apps/dashboard/components/settings/GeneralSection.tsx +26 -31
  68. package/apps/dashboard/components/settings/SettingsLayout.tsx +4 -4
  69. package/apps/dashboard/components/ui/Button.tsx +104 -0
  70. package/apps/dashboard/components/ui/Input.tsx +78 -0
  71. package/apps/dashboard/contexts/ClaudeSessionContext.tsx +408 -105
  72. package/apps/dashboard/contexts/ConnectionStatusContext.tsx +25 -4
  73. package/apps/dashboard/contexts/UsageContext.tsx +155 -0
  74. package/apps/dashboard/contexts/usageHelpers.js +9 -0
  75. package/apps/dashboard/electron/ipc-handlers.js +281 -88
  76. package/apps/dashboard/electron/main.js +691 -131
  77. package/apps/dashboard/electron/preload.js +25 -4
  78. package/apps/dashboard/electron/session-manager.js +163 -0
  79. package/apps/dashboard/electron-builder.config.js +3 -5
  80. package/apps/dashboard/hooks/useKanbanAnimation.ts +29 -0
  81. package/apps/dashboard/hooks/useKanbanUndo.ts +83 -0
  82. package/apps/dashboard/lib/backlog-parser.ts +50 -0
  83. package/apps/dashboard/lib/claude-process-manager.ts +50 -11
  84. package/apps/dashboard/lib/constants.ts +43 -0
  85. package/apps/dashboard/lib/db-bridge.ts +33 -0
  86. package/apps/dashboard/lib/db.ts +136 -20
  87. package/apps/dashboard/lib/kanban-utils.ts +70 -0
  88. package/apps/dashboard/lib/run-migrations.js +27 -2
  89. package/apps/dashboard/lib/session-state-machine.ts +3 -0
  90. package/apps/dashboard/lib/session-stream-manager.ts +144 -38
  91. package/apps/dashboard/lib/shadows.ts +7 -0
  92. package/apps/dashboard/lib/tests.ts +3 -1
  93. package/apps/dashboard/lib/utils.ts +6 -0
  94. package/apps/dashboard/next.config.js +35 -14
  95. package/apps/dashboard/package.json +6 -3
  96. package/apps/dashboard/public/bug-icon.svg +9 -0
  97. package/apps/dashboard/public/buoy-icon.svg +9 -0
  98. package/apps/dashboard/public/fonts/Satoshi-Variable.woff2 +0 -0
  99. package/apps/dashboard/public/fonts/Satoshi-VariableItalic.woff2 +0 -0
  100. package/apps/dashboard/public/in-flight-seagull.svg +9 -0
  101. package/apps/dashboard/public/jetty-icon-loading-alt.svg +11 -0
  102. package/apps/dashboard/public/jetty-icon-loading.svg +11 -0
  103. package/apps/dashboard/public/jettypod_logo.png +0 -0
  104. package/apps/dashboard/public/pier-icon.svg +14 -0
  105. package/apps/dashboard/public/star-icon.svg +9 -0
  106. package/apps/dashboard/public/wrench-icon.svg +9 -0
  107. package/apps/dashboard/scripts/upload-to-r2.js +89 -0
  108. package/apps/dashboard/scripts/ws-server.js +191 -0
  109. package/apps/dashboard/tsconfig.tsbuildinfo +1 -0
  110. package/apps/update-server/package.json +16 -0
  111. package/apps/update-server/schema.sql +31 -0
  112. package/apps/update-server/src/index.ts +1085 -0
  113. package/apps/update-server/tsconfig.json +16 -0
  114. package/apps/update-server/wrangler.toml +35 -0
  115. package/cucumber.js +9 -3
  116. package/docs/COMMAND_REFERENCE.md +34 -0
  117. package/hooks/post-checkout +32 -75
  118. package/hooks/post-merge +111 -10
  119. package/jest.setup.js +1 -0
  120. package/jettypod.js +54 -116
  121. package/lib/chore-taxonomy.js +33 -10
  122. package/lib/database.js +36 -16
  123. package/lib/db-watcher.js +1 -1
  124. package/lib/git-hooks/pre-commit +1 -1
  125. package/lib/jettypod-backup.js +27 -4
  126. package/lib/migrations/027-plan-at-creation-column.js +33 -0
  127. package/lib/migrations/028-ready-for-review-column.js +27 -0
  128. package/lib/migrations/029-remove-autoincrement.js +307 -0
  129. package/lib/migrations/029-rename-corrupted-to-cleaned.js +149 -0
  130. package/lib/migrations/index.js +47 -4
  131. package/lib/schema.js +13 -6
  132. package/lib/seed-onboarding.js +101 -69
  133. package/lib/update-command/index.js +9 -175
  134. package/lib/work-commands/index.js +129 -16
  135. package/lib/work-tracking/index.js +86 -46
  136. package/lib/worktree-diagnostics.js +16 -16
  137. package/lib/worktree-facade.js +1 -1
  138. package/lib/worktree-manager.js +8 -8
  139. package/lib/worktree-reconciler.js +5 -5
  140. package/package.json +9 -2
  141. package/scripts/ndjson-to-cucumber-json.js +152 -0
  142. package/scripts/postinstall.js +25 -0
  143. package/skills-templates/bug-mode/SKILL.md +39 -28
  144. package/skills-templates/bug-planning/SKILL.md +25 -29
  145. package/skills-templates/chore-mode/SKILL.md +131 -68
  146. package/skills-templates/chore-mode/verification.js +51 -10
  147. package/skills-templates/chore-planning/SKILL.md +47 -18
  148. package/skills-templates/epic-planning/SKILL.md +68 -48
  149. package/skills-templates/external-transition/SKILL.md +47 -47
  150. package/skills-templates/feature-planning/SKILL.md +83 -73
  151. package/skills-templates/production-mode/SKILL.md +49 -49
  152. package/skills-templates/request-routing/SKILL.md +27 -14
  153. package/skills-templates/simple-improvement/SKILL.md +68 -44
  154. package/skills-templates/speed-mode/SKILL.md +209 -128
  155. package/skills-templates/stable-mode/SKILL.md +105 -94
  156. package/templates/bdd-guidance.md +139 -0
  157. package/templates/bdd-scaffolding/wait.js +18 -0
  158. package/templates/bdd-scaffolding/world.js +19 -0
  159. package/.jettypod-backup/work.db +0 -0
  160. package/apps/dashboard/app/access-code/page.tsx +0 -110
  161. package/lib/discovery-checkpoint.js +0 -123
  162. package/skills-templates/project-discovery/SKILL.md +0 -372
@@ -1,23 +1,78 @@
1
1
  'use client';
2
2
 
3
+ import { useState, useEffect } from 'react';
3
4
  import Image from 'next/image';
5
+ import { Button } from '@/components/ui/Button';
6
+
7
+ const statusMessages = [
8
+ "Downloading Claude Code...",
9
+ "Setting Up Environment...",
10
+ "Configuring Permissions...",
11
+ "Almost There...",
12
+ ];
4
13
 
5
14
  interface InstallClaudeScreenProps {
6
15
  onInstall: () => void;
7
16
  isInstalling: boolean;
8
- installProgress?: string;
17
+ isSuccess: boolean;
9
18
  }
10
19
 
11
20
  export function InstallClaudeScreen({
12
21
  onInstall,
13
22
  isInstalling,
14
- installProgress,
23
+ isSuccess,
15
24
  }: InstallClaudeScreenProps) {
25
+ const [messageIndex, setMessageIndex] = useState(0);
26
+ const [progress, setProgress] = useState(0);
27
+
28
+ useEffect(() => {
29
+ if (!isInstalling || isSuccess) return;
30
+ const interval = setInterval(() => {
31
+ setMessageIndex((prev) => (prev + 1) % statusMessages.length);
32
+ }, 2500);
33
+ return () => clearInterval(interval);
34
+ }, [isInstalling, isSuccess]);
35
+
36
+ useEffect(() => {
37
+ if (!isInstalling || isSuccess) return;
38
+ const interval = setInterval(() => {
39
+ setProgress((prev) => Math.min(prev + 2, 90));
40
+ }, 300);
41
+ return () => clearInterval(interval);
42
+ }, [isInstalling, isSuccess]);
43
+
44
+ useEffect(() => {
45
+ if (isSuccess) setProgress(100);
46
+ }, [isSuccess]);
47
+
16
48
  return (
17
49
  <div className="flex flex-col items-center justify-center min-h-screen bg-white dark:bg-zinc-900 p-8">
18
- <div className="max-w-md w-full space-y-8">
50
+ <style jsx>{`
51
+ @keyframes pulse {
52
+ 0%, 100% { opacity: 1; transform: scale(1); }
53
+ 50% { opacity: 0.5; transform: scale(1.1); }
54
+ }
55
+ @keyframes drawCheck {
56
+ to { stroke-dashoffset: 0; }
57
+ }
58
+ @keyframes fadeIn {
59
+ from { opacity: 0; transform: translateY(8px); }
60
+ to { opacity: 1; transform: translateY(0); }
61
+ }
62
+ .pulse-dot {
63
+ animation: pulse 1.5s ease-in-out infinite;
64
+ }
65
+ .checkmark-draw {
66
+ animation: drawCheck 0.6s ease-out forwards;
67
+ }
68
+ .fade-in {
69
+ animation: fadeIn 0.4s ease-out forwards;
70
+ }
71
+ `}</style>
72
+
73
+ <div className="max-w-md w-full space-y-10">
19
74
  {/* Logo */}
20
- <div className="flex flex-col items-center space-y-4">
75
+ <div className="flex flex-col items-center space-y-6">
21
76
  <Image
22
77
  src="/jettypod_wordmark.png"
23
78
  alt="JettyPod"
@@ -25,66 +80,100 @@ export function InstallClaudeScreen({
25
80
  height={40}
26
81
  priority
27
82
  />
28
- <h1 className="text-2xl font-semibold text-zinc-900 dark:text-zinc-100 text-center">
29
- Claude Code Required
30
- </h1>
31
- <p className="text-zinc-500 dark:text-zinc-400 text-center">
32
- JettyPod requires Claude Code to be installed.
33
- Click below to install it automatically.
34
- </p>
83
+ {!isInstalling && !isSuccess && (
84
+ <>
85
+ <h1 className="text-2xl font-semibold text-zinc-900 dark:text-zinc-100 text-center">
86
+ Claude Code Required
87
+ </h1>
88
+ <p className="text-zinc-500 dark:text-zinc-400 text-center">
89
+ JettyPod requires Claude Code to be installed.
90
+ Click below to install it automatically.
91
+ </p>
92
+ </>
93
+ )}
35
94
  </div>
36
95
 
37
- {/* Install Button or Progress */}
38
- <div className="pt-4">
39
- {isInstalling ? (
40
- <div className="space-y-4" data-testid="install-progress">
41
- <div className="w-full py-3 px-6 rounded-xl font-medium text-center bg-zinc-100 dark:bg-zinc-800 text-zinc-600 dark:text-zinc-300">
42
- Installing Claude Code...
96
+ {/* Install Button / Progress / Success */}
97
+ <div className="pt-6">
98
+ {isSuccess ? (
99
+ <div className="flex flex-col items-center space-y-8 fade-in" data-testid="install-success">
100
+ {/* Animated Checkmark */}
101
+ <div
102
+ className="w-20 h-20 rounded-full flex items-center justify-center"
103
+ style={{ backgroundColor: '#819D9F' }}
104
+ >
105
+ <svg width="40" height="40" viewBox="0 0 40 40" fill="none">
106
+ <polyline
107
+ points="10,20 18,28 30,12"
108
+ stroke="white"
109
+ strokeWidth="3"
110
+ strokeLinecap="round"
111
+ strokeLinejoin="round"
112
+ fill="none"
113
+ strokeDasharray="40"
114
+ strokeDashoffset="40"
115
+ className="checkmark-draw"
116
+ />
117
+ </svg>
118
+ </div>
119
+
120
+ <h2 className="text-2xl font-semibold text-zinc-900 dark:text-zinc-100 text-center">
121
+ Claude Code Installed
122
+ </h2>
123
+ <p className="text-zinc-500 dark:text-zinc-400 text-center">
124
+ Redirecting you to connect your account...
125
+ </p>
126
+ </div>
127
+ ) : isInstalling ? (
128
+ <div className="space-y-8" data-testid="install-progress">
129
+ {/* Pulse dot + status message */}
130
+ <div className="flex items-center justify-center space-x-4">
131
+ <div
132
+ className="w-3 h-3 rounded-full pulse-dot"
133
+ style={{ backgroundColor: '#819D9F' }}
134
+ />
135
+ <span className="text-zinc-600 dark:text-zinc-300 font-medium">
136
+ {statusMessages[messageIndex]}
137
+ </span>
138
+ </div>
139
+
140
+ {/* Progress bar */}
141
+ <div className="w-full h-1 bg-zinc-200 dark:bg-zinc-700 rounded-full overflow-hidden">
142
+ <div
143
+ className="h-full rounded-full transition-[width] duration-200 ease-out"
144
+ style={{
145
+ width: `${progress}%`,
146
+ background: 'linear-gradient(90deg, #c8d9da, #819D9F)',
147
+ }}
148
+ />
43
149
  </div>
44
- {installProgress && (
45
- <pre className="bg-zinc-100 dark:bg-zinc-800 p-4 rounded-lg text-sm text-zinc-600 dark:text-zinc-300 overflow-auto max-h-48">
46
- {installProgress}
47
- </pre>
48
- )}
49
150
  </div>
50
151
  ) : (
51
- <button
152
+ <Button
52
153
  onClick={onInstall}
53
- className="w-full py-3 px-6 rounded-xl font-medium transition-all duration-200 hover:-translate-y-1 hover:scale-[1.01] active:translate-y-0 active:scale-100"
54
- style={{
55
- cursor: 'pointer',
56
- background: 'linear-gradient(145deg, #ffffff 0%, #faf9f7 10%, #f0f4f4 35%, #c8d9da 55%, #819D9F 90%)',
57
- color: '#3d4d4e',
58
- boxShadow: `
59
- 0 1px 1px rgba(0, 0, 0, 0.02),
60
- 0 2px 4px rgba(0, 0, 0, 0.03),
61
- 0 6px 12px rgba(0, 0, 0, 0.05),
62
- 0 12px 24px rgba(0, 0, 0, 0.06),
63
- 0 20px 40px rgba(129, 157, 159, 0.2),
64
- 0 32px 64px rgba(129, 157, 159, 0.18),
65
- inset 0 2px 4px rgba(255, 255, 255, 1),
66
- inset 0 -2px 4px rgba(129, 157, 159, 0.05)
67
- `,
68
- }}
154
+ size="lg"
155
+ fullWidth
69
156
  data-testid="install-claude-button"
70
157
  >
71
158
  Install Claude Code
72
- </button>
159
+ </Button>
73
160
  )}
74
161
  </div>
75
162
 
76
- {/* Info Section */}
77
- <div className="pt-8 space-y-4">
78
- <div className="border border-zinc-200 dark:border-zinc-700 rounded-lg p-4 text-zinc-500 dark:text-zinc-400 text-sm">
79
- <p>
80
- <strong className="text-zinc-700 dark:text-zinc-300">What is Claude Code?</strong>
81
- </p>
82
- <p className="mt-2">
83
- Claude Code is an AI-powered coding assistant by Anthropic.
84
- JettyPod uses it to help you plan and build software.
85
- </p>
163
+ {/* Info Section - only show when idle */}
164
+ {!isInstalling && !isSuccess && (
165
+ <div className="pt-10 space-y-4">
166
+ <div className="rounded-lg p-6 text-zinc-500 dark:text-zinc-400 text-base">
167
+ <p>
168
+ <strong className="text-zinc-700 dark:text-zinc-300">What is Claude Code?</strong>
169
+ </p>
170
+ <p className="mt-2">
171
+ Claude Code is an AI-powered coding assistant by Anthropic.
172
+ JettyPod uses it to help you plan and build software.
173
+ </p>
174
+ </div>
86
175
  </div>
87
- </div>
176
+ )}
88
177
  </div>
89
178
  </div>
90
179
  );
@@ -0,0 +1,38 @@
1
+ 'use client';
2
+
3
+ import { useState, useEffect } from 'react';
4
+
5
+ interface JettyLoaderProps {
6
+ size?: number;
7
+ className?: string;
8
+ }
9
+
10
+ export function JettyLoader({ size = 48, className = '' }: JettyLoaderProps) {
11
+ const [showAlt, setShowAlt] = useState(false);
12
+
13
+ useEffect(() => {
14
+ const interval = setInterval(() => {
15
+ setShowAlt((prev) => !prev);
16
+ }, 500);
17
+ return () => clearInterval(interval);
18
+ }, []);
19
+
20
+ return (
21
+ <div className={className} style={{ width: size, height: size }}>
22
+ <img
23
+ src="/jetty-icon-loading.svg"
24
+ alt="Loading"
25
+ width={size}
26
+ height={size}
27
+ style={{ display: showAlt ? 'none' : 'block' }}
28
+ />
29
+ <img
30
+ src="/jetty-icon-loading-alt.svg"
31
+ alt="Loading"
32
+ width={size}
33
+ height={size}
34
+ style={{ display: showAlt ? 'block' : 'none' }}
35
+ />
36
+ </div>
37
+ );
38
+ }