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.
- package/.env +7 -0
- package/apps/dashboard/app/api/claude/[workItemId]/message/route.ts +124 -48
- package/apps/dashboard/app/api/claude/[workItemId]/route.ts +171 -58
- package/apps/dashboard/app/api/claude/sessions/[sessionId]/message/route.ts +161 -10
- package/apps/dashboard/app/api/tests/run/stream/route.ts +13 -1
- package/apps/dashboard/app/api/usage/route.ts +17 -0
- package/apps/dashboard/app/api/work/[id]/route.ts +35 -0
- package/apps/dashboard/app/api/work/[id]/status/route.ts +43 -1
- package/apps/dashboard/app/connect-claude/page.tsx +24 -0
- package/apps/dashboard/app/decision/[id]/page.tsx +14 -14
- package/apps/dashboard/app/demo/gates/page.tsx +42 -42
- package/apps/dashboard/app/design-system/page.tsx +868 -0
- package/apps/dashboard/app/globals.css +6 -2
- package/apps/dashboard/app/install-claude/page.tsx +9 -7
- package/apps/dashboard/app/layout.tsx +17 -5
- package/apps/dashboard/app/login/page.tsx +250 -0
- package/apps/dashboard/app/page.tsx +11 -9
- package/apps/dashboard/app/settings/page.tsx +4 -2
- package/apps/dashboard/app/signup/page.tsx +245 -0
- package/apps/dashboard/app/subscribe/page.tsx +11 -0
- package/apps/dashboard/app/welcome/page.tsx +24 -1
- package/apps/dashboard/app/work/[id]/page.tsx +34 -50
- package/apps/dashboard/components/AppShell.tsx +95 -55
- package/apps/dashboard/components/CardMenu.tsx +56 -13
- package/apps/dashboard/components/ClaudePanel.tsx +301 -582
- package/apps/dashboard/components/ClaudePanelInput.tsx +23 -14
- package/apps/dashboard/components/ConnectClaudeScreen.tsx +210 -0
- package/apps/dashboard/components/CopyableId.tsx +3 -3
- package/apps/dashboard/components/DetailReviewActions.tsx +109 -0
- package/apps/dashboard/components/DragContext.tsx +75 -65
- package/apps/dashboard/components/DraggableCard.tsx +6 -46
- package/apps/dashboard/components/DropZone.tsx +2 -2
- package/apps/dashboard/components/EditableDetailDescription.tsx +1 -1
- package/apps/dashboard/components/EditableTitle.tsx +26 -6
- package/apps/dashboard/components/ElapsedTimer.tsx +54 -0
- package/apps/dashboard/components/EpicGroup.tsx +329 -0
- package/apps/dashboard/components/GateCard.tsx +100 -16
- package/apps/dashboard/components/GateChoiceCard.tsx +15 -17
- package/apps/dashboard/components/InstallClaudeScreen.tsx +140 -51
- package/apps/dashboard/components/JettyLoader.tsx +38 -0
- package/apps/dashboard/components/KanbanBoard.tsx +147 -766
- package/apps/dashboard/components/KanbanCard.tsx +506 -0
- package/apps/dashboard/components/LazyMarkdown.tsx +12 -0
- package/apps/dashboard/components/MainNav.tsx +20 -54
- package/apps/dashboard/components/MessageBlock.tsx +391 -0
- package/apps/dashboard/components/ModeStartCard.tsx +15 -15
- package/apps/dashboard/components/OnboardingWelcome.tsx +214 -0
- package/apps/dashboard/components/PlaceholderCard.tsx +11 -21
- package/apps/dashboard/components/ProjectSwitcher.tsx +36 -8
- package/apps/dashboard/components/PrototypeTimeline.tsx +25 -25
- package/apps/dashboard/components/RealTimeKanbanWrapper.tsx +265 -301
- package/apps/dashboard/components/RealTimeTestsWrapper.tsx +97 -74
- package/apps/dashboard/components/ReviewFooter.tsx +141 -0
- package/apps/dashboard/components/SessionList.tsx +19 -18
- package/apps/dashboard/components/SubscribeContent.tsx +206 -0
- package/apps/dashboard/components/TestTree.tsx +15 -14
- package/apps/dashboard/components/TipCard.tsx +177 -0
- package/apps/dashboard/components/Toast.tsx +5 -5
- package/apps/dashboard/components/TypeIcon.tsx +56 -0
- package/apps/dashboard/components/UpgradeBanner.tsx +30 -0
- package/apps/dashboard/components/WaveCompletionAnimation.tsx +61 -62
- package/apps/dashboard/components/WelcomeScreen.tsx +25 -27
- package/apps/dashboard/components/WorkItemHeader.tsx +4 -4
- package/apps/dashboard/components/WorkItemTree.tsx +9 -28
- package/apps/dashboard/components/settings/AccountSection.tsx +169 -0
- package/apps/dashboard/components/settings/EnvVarsSection.tsx +54 -79
- package/apps/dashboard/components/settings/GeneralSection.tsx +26 -31
- package/apps/dashboard/components/settings/SettingsLayout.tsx +4 -4
- package/apps/dashboard/components/ui/Button.tsx +104 -0
- package/apps/dashboard/components/ui/Input.tsx +78 -0
- package/apps/dashboard/contexts/ClaudeSessionContext.tsx +408 -105
- package/apps/dashboard/contexts/ConnectionStatusContext.tsx +25 -4
- package/apps/dashboard/contexts/UsageContext.tsx +155 -0
- package/apps/dashboard/contexts/usageHelpers.js +9 -0
- package/apps/dashboard/electron/ipc-handlers.js +281 -88
- package/apps/dashboard/electron/main.js +691 -131
- package/apps/dashboard/electron/preload.js +25 -4
- package/apps/dashboard/electron/session-manager.js +163 -0
- package/apps/dashboard/electron-builder.config.js +3 -5
- package/apps/dashboard/hooks/useKanbanAnimation.ts +29 -0
- package/apps/dashboard/hooks/useKanbanUndo.ts +83 -0
- package/apps/dashboard/lib/backlog-parser.ts +50 -0
- package/apps/dashboard/lib/claude-process-manager.ts +50 -11
- package/apps/dashboard/lib/constants.ts +43 -0
- package/apps/dashboard/lib/db-bridge.ts +33 -0
- package/apps/dashboard/lib/db.ts +136 -20
- package/apps/dashboard/lib/kanban-utils.ts +70 -0
- package/apps/dashboard/lib/run-migrations.js +27 -2
- package/apps/dashboard/lib/session-state-machine.ts +3 -0
- package/apps/dashboard/lib/session-stream-manager.ts +144 -38
- package/apps/dashboard/lib/shadows.ts +7 -0
- package/apps/dashboard/lib/tests.ts +3 -1
- package/apps/dashboard/lib/utils.ts +6 -0
- package/apps/dashboard/next.config.js +35 -14
- package/apps/dashboard/package.json +6 -3
- package/apps/dashboard/public/bug-icon.svg +9 -0
- package/apps/dashboard/public/buoy-icon.svg +9 -0
- package/apps/dashboard/public/fonts/Satoshi-Variable.woff2 +0 -0
- package/apps/dashboard/public/fonts/Satoshi-VariableItalic.woff2 +0 -0
- package/apps/dashboard/public/in-flight-seagull.svg +9 -0
- package/apps/dashboard/public/jetty-icon-loading-alt.svg +11 -0
- package/apps/dashboard/public/jetty-icon-loading.svg +11 -0
- package/apps/dashboard/public/jettypod_logo.png +0 -0
- package/apps/dashboard/public/pier-icon.svg +14 -0
- package/apps/dashboard/public/star-icon.svg +9 -0
- package/apps/dashboard/public/wrench-icon.svg +9 -0
- package/apps/dashboard/scripts/upload-to-r2.js +89 -0
- package/apps/dashboard/scripts/ws-server.js +191 -0
- package/apps/dashboard/tsconfig.tsbuildinfo +1 -0
- package/apps/update-server/package.json +16 -0
- package/apps/update-server/schema.sql +31 -0
- package/apps/update-server/src/index.ts +1085 -0
- package/apps/update-server/tsconfig.json +16 -0
- package/apps/update-server/wrangler.toml +35 -0
- package/cucumber.js +9 -3
- package/docs/COMMAND_REFERENCE.md +34 -0
- package/hooks/post-checkout +32 -75
- package/hooks/post-merge +111 -10
- package/jest.setup.js +1 -0
- package/jettypod.js +54 -116
- package/lib/chore-taxonomy.js +33 -10
- package/lib/database.js +36 -16
- package/lib/db-watcher.js +1 -1
- package/lib/git-hooks/pre-commit +1 -1
- package/lib/jettypod-backup.js +27 -4
- package/lib/migrations/027-plan-at-creation-column.js +33 -0
- package/lib/migrations/028-ready-for-review-column.js +27 -0
- package/lib/migrations/029-remove-autoincrement.js +307 -0
- package/lib/migrations/029-rename-corrupted-to-cleaned.js +149 -0
- package/lib/migrations/index.js +47 -4
- package/lib/schema.js +13 -6
- package/lib/seed-onboarding.js +101 -69
- package/lib/update-command/index.js +9 -175
- package/lib/work-commands/index.js +129 -16
- package/lib/work-tracking/index.js +86 -46
- package/lib/worktree-diagnostics.js +16 -16
- package/lib/worktree-facade.js +1 -1
- package/lib/worktree-manager.js +8 -8
- package/lib/worktree-reconciler.js +5 -5
- package/package.json +9 -2
- package/scripts/ndjson-to-cucumber-json.js +152 -0
- package/scripts/postinstall.js +25 -0
- package/skills-templates/bug-mode/SKILL.md +39 -28
- package/skills-templates/bug-planning/SKILL.md +25 -29
- package/skills-templates/chore-mode/SKILL.md +131 -68
- package/skills-templates/chore-mode/verification.js +51 -10
- package/skills-templates/chore-planning/SKILL.md +47 -18
- package/skills-templates/epic-planning/SKILL.md +68 -48
- package/skills-templates/external-transition/SKILL.md +47 -47
- package/skills-templates/feature-planning/SKILL.md +83 -73
- package/skills-templates/production-mode/SKILL.md +49 -49
- package/skills-templates/request-routing/SKILL.md +27 -14
- package/skills-templates/simple-improvement/SKILL.md +68 -44
- package/skills-templates/speed-mode/SKILL.md +209 -128
- package/skills-templates/stable-mode/SKILL.md +105 -94
- package/templates/bdd-guidance.md +139 -0
- package/templates/bdd-scaffolding/wait.js +18 -0
- package/templates/bdd-scaffolding/world.js +19 -0
- package/.jettypod-backup/work.db +0 -0
- package/apps/dashboard/app/access-code/page.tsx +0 -110
- package/lib/discovery-checkpoint.js +0 -123
- package/skills-templates/project-discovery/SKILL.md +0 -372
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cucumber World configuration.
|
|
3
|
+
* Provides per-scenario state via `this` in step definitions.
|
|
4
|
+
* Use this instead of module-level let/var for test state.
|
|
5
|
+
*
|
|
6
|
+
* Place at: features/support/world.js
|
|
7
|
+
*/
|
|
8
|
+
const { setWorldConstructor } = require('@cucumber/cucumber');
|
|
9
|
+
|
|
10
|
+
class TestWorld {
|
|
11
|
+
constructor() {
|
|
12
|
+
// Per-scenario state — automatically reset between scenarios.
|
|
13
|
+
// Add properties here or in step definitions via this.propName = value
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
setWorldConstructor(TestWorld);
|
|
18
|
+
|
|
19
|
+
module.exports = { TestWorld };
|
package/.jettypod-backup/work.db
DELETED
|
Binary file
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { useState } from 'react';
|
|
4
|
-
import Image from 'next/image';
|
|
5
|
-
|
|
6
|
-
export default function AccessCodePage() {
|
|
7
|
-
const [code, setCode] = useState('');
|
|
8
|
-
const [error, setError] = useState<string | null>(null);
|
|
9
|
-
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
10
|
-
|
|
11
|
-
const handleSubmit = async (e: React.FormEvent) => {
|
|
12
|
-
e.preventDefault();
|
|
13
|
-
setError(null);
|
|
14
|
-
|
|
15
|
-
if (!code.trim()) {
|
|
16
|
-
setError('Please enter an access code.');
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
if (!window.electronAPI?.isElectron) {
|
|
21
|
-
setError('Access code validation is only available in the desktop app.');
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
setIsSubmitting(true);
|
|
26
|
-
|
|
27
|
-
try {
|
|
28
|
-
const result = await window.electronAPI.access.validate(code.trim());
|
|
29
|
-
|
|
30
|
-
if (!result.success) {
|
|
31
|
-
setError(result.error || 'Invalid access code.');
|
|
32
|
-
setIsSubmitting(false);
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Access granted - navigate to main app
|
|
37
|
-
window.location.href = '/';
|
|
38
|
-
} catch (err) {
|
|
39
|
-
setError(err instanceof Error ? err.message : 'Failed to validate access code.');
|
|
40
|
-
setIsSubmitting(false);
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
return (
|
|
45
|
-
<div className="flex flex-col items-center justify-center min-h-screen bg-white dark:bg-zinc-900 p-8">
|
|
46
|
-
<div className="max-w-md w-full space-y-8">
|
|
47
|
-
{/* Logo */}
|
|
48
|
-
<div className="flex flex-col items-center space-y-4">
|
|
49
|
-
<Image
|
|
50
|
-
src="/jettypod_wordmark.png"
|
|
51
|
-
alt="JettyPod"
|
|
52
|
-
width={160}
|
|
53
|
-
height={40}
|
|
54
|
-
priority
|
|
55
|
-
/>
|
|
56
|
-
<h1 className="text-2xl font-semibold text-zinc-900 dark:text-zinc-100 text-center">
|
|
57
|
-
Enter Access Code
|
|
58
|
-
</h1>
|
|
59
|
-
<p className="text-zinc-500 dark:text-zinc-400 text-center">
|
|
60
|
-
Enter your access code to get started with JettyPod.
|
|
61
|
-
</p>
|
|
62
|
-
</div>
|
|
63
|
-
|
|
64
|
-
{/* Error */}
|
|
65
|
-
{error && (
|
|
66
|
-
<div className="bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 text-red-700 dark:text-red-400 px-4 py-3 rounded-lg text-sm">
|
|
67
|
-
{error}
|
|
68
|
-
</div>
|
|
69
|
-
)}
|
|
70
|
-
|
|
71
|
-
{/* Form */}
|
|
72
|
-
<form onSubmit={handleSubmit} className="pt-4 space-y-4">
|
|
73
|
-
<input
|
|
74
|
-
type="text"
|
|
75
|
-
value={code}
|
|
76
|
-
onChange={(e) => setCode(e.target.value)}
|
|
77
|
-
placeholder="Access code"
|
|
78
|
-
autoFocus
|
|
79
|
-
disabled={isSubmitting}
|
|
80
|
-
className="w-full px-4 py-3 rounded-xl border border-zinc-300 dark:border-zinc-600 bg-white dark:bg-zinc-800 text-zinc-900 dark:text-zinc-100 placeholder-zinc-400 dark:placeholder-zinc-500 focus:outline-none focus:ring-2 focus:ring-zinc-400 dark:focus:ring-zinc-500 disabled:opacity-50"
|
|
81
|
-
data-testid="access-code-input"
|
|
82
|
-
/>
|
|
83
|
-
<button
|
|
84
|
-
type="submit"
|
|
85
|
-
disabled={isSubmitting}
|
|
86
|
-
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 disabled:opacity-50 disabled:pointer-events-none"
|
|
87
|
-
style={{
|
|
88
|
-
cursor: isSubmitting ? 'default' : 'pointer',
|
|
89
|
-
background: 'linear-gradient(145deg, #ffffff 0%, #faf9f7 10%, #f0f4f4 35%, #c8d9da 55%, #819D9F 90%)',
|
|
90
|
-
color: '#3d4d4e',
|
|
91
|
-
boxShadow: `
|
|
92
|
-
0 1px 1px rgba(0, 0, 0, 0.02),
|
|
93
|
-
0 2px 4px rgba(0, 0, 0, 0.03),
|
|
94
|
-
0 6px 12px rgba(0, 0, 0, 0.05),
|
|
95
|
-
0 12px 24px rgba(0, 0, 0, 0.06),
|
|
96
|
-
0 20px 40px rgba(129, 157, 159, 0.2),
|
|
97
|
-
0 32px 64px rgba(129, 157, 159, 0.18),
|
|
98
|
-
inset 0 2px 4px rgba(255, 255, 255, 1),
|
|
99
|
-
inset 0 -2px 4px rgba(129, 157, 159, 0.05)
|
|
100
|
-
`,
|
|
101
|
-
}}
|
|
102
|
-
data-testid="access-code-submit"
|
|
103
|
-
>
|
|
104
|
-
{isSubmitting ? 'Validating...' : 'Continue'}
|
|
105
|
-
</button>
|
|
106
|
-
</form>
|
|
107
|
-
</div>
|
|
108
|
-
</div>
|
|
109
|
-
);
|
|
110
|
-
}
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
const config = require('./config');
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Update discovery checkpoint with current progress
|
|
5
|
-
* @param {number} step - Current discovery step (1-7)
|
|
6
|
-
* @param {Object} data - Checkpoint data (user_journey, ux_approach, epics_created)
|
|
7
|
-
*/
|
|
8
|
-
function updateCheckpoint(step, data = {}) {
|
|
9
|
-
const currentConfig = config.read();
|
|
10
|
-
|
|
11
|
-
// Ensure project_discovery exists
|
|
12
|
-
if (!currentConfig.project_discovery) {
|
|
13
|
-
currentConfig.project_discovery = config.getDefaultProjectDiscovery();
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// Update checkpoint
|
|
17
|
-
currentConfig.project_discovery.checkpoint = {
|
|
18
|
-
step,
|
|
19
|
-
user_journey: data.user_journey || currentConfig.project_discovery.checkpoint?.user_journey || null,
|
|
20
|
-
ux_approach: data.ux_approach || currentConfig.project_discovery.checkpoint?.ux_approach || null,
|
|
21
|
-
epics_created: data.epics_created !== undefined ? data.epics_created : (currentConfig.project_discovery.checkpoint?.epics_created || false)
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
// Update status to in_progress if not already completed
|
|
25
|
-
if (currentConfig.project_discovery.status === 'not_started') {
|
|
26
|
-
currentConfig.project_discovery.status = 'in_progress';
|
|
27
|
-
currentConfig.project_discovery.started_date = new Date().toISOString();
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
config.write(currentConfig);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Get current discovery checkpoint
|
|
35
|
-
* @returns {Object|null} Checkpoint data or null if not started
|
|
36
|
-
*/
|
|
37
|
-
function getCheckpoint() {
|
|
38
|
-
const currentConfig = config.read();
|
|
39
|
-
|
|
40
|
-
if (!currentConfig.project_discovery || currentConfig.project_discovery.status === 'not_started') {
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return currentConfig.project_discovery.checkpoint || null;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Clear discovery checkpoint (when discovery is completed)
|
|
49
|
-
*/
|
|
50
|
-
function clearCheckpoint() {
|
|
51
|
-
const currentConfig = config.read();
|
|
52
|
-
|
|
53
|
-
if (currentConfig.project_discovery) {
|
|
54
|
-
currentConfig.project_discovery.checkpoint = config.getDefaultProjectDiscovery().checkpoint;
|
|
55
|
-
config.write(currentConfig);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Get human-readable description of current checkpoint step
|
|
61
|
-
* @param {number} step - Step number
|
|
62
|
-
* @returns {string} Step description
|
|
63
|
-
*/
|
|
64
|
-
function getStepDescription(step) {
|
|
65
|
-
const steps = {
|
|
66
|
-
1: 'Starting discovery - define user journey',
|
|
67
|
-
2: 'User journey defined - present UX approaches',
|
|
68
|
-
3: 'UX approach selected - build prototypes',
|
|
69
|
-
4: 'Prototypes tested - break into epics',
|
|
70
|
-
5: 'Epics created - choose tech stack',
|
|
71
|
-
6: 'Tech stack chosen - record decision',
|
|
72
|
-
7: 'Discovery complete'
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
return steps[step] || 'Unknown step';
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Generate a formatted resume message for displaying when resuming discovery
|
|
80
|
-
* @param {Object} checkpoint - Checkpoint object with step, user_journey, ux_approach, epics_created
|
|
81
|
-
* @returns {string|null} Formatted resume message or null if no checkpoint
|
|
82
|
-
*/
|
|
83
|
-
function generateResumeMessage(checkpoint) {
|
|
84
|
-
if (!checkpoint) {
|
|
85
|
-
return null;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const stepDesc = getStepDescription(checkpoint.step);
|
|
89
|
-
|
|
90
|
-
let lines = [
|
|
91
|
-
'━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
|
|
92
|
-
'🔄 RESUMING PROJECT DISCOVERY',
|
|
93
|
-
'━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━',
|
|
94
|
-
'',
|
|
95
|
-
`📍 Resuming from Step ${checkpoint.step}: ${stepDesc}`,
|
|
96
|
-
''
|
|
97
|
-
];
|
|
98
|
-
|
|
99
|
-
if (checkpoint.user_journey) {
|
|
100
|
-
lines.push(`📝 User Journey: "${checkpoint.user_journey}"`);
|
|
101
|
-
}
|
|
102
|
-
if (checkpoint.ux_approach) {
|
|
103
|
-
lines.push(`🎨 UX Approach: "${checkpoint.ux_approach}"`);
|
|
104
|
-
}
|
|
105
|
-
if (checkpoint.epics_created) {
|
|
106
|
-
lines.push(`✅ Epics: Already created`);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
lines.push('');
|
|
110
|
-
lines.push('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
111
|
-
lines.push('');
|
|
112
|
-
lines.push('Continuing where you left off...');
|
|
113
|
-
|
|
114
|
-
return lines.join('\n');
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
module.exports = {
|
|
118
|
-
updateCheckpoint,
|
|
119
|
-
getCheckpoint,
|
|
120
|
-
clearCheckpoint,
|
|
121
|
-
getStepDescription,
|
|
122
|
-
generateResumeMessage
|
|
123
|
-
};
|
|
@@ -1,372 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: project-discovery
|
|
3
|
-
description: "Guide new project planning from blank slate to epics. Auto-activates when project has no implementation code. Walks user through journey exploration, UX approach selection, optional prototyping, epic breakdown, and tech stack selection."
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Project Discovery Skill
|
|
7
|
-
|
|
8
|
-
Guides users through planning a new project from blank slate to epics. Auto-activates when a blank project (no implementation code) is detected.
|
|
9
|
-
|
|
10
|
-
## Instructions
|
|
11
|
-
|
|
12
|
-
When this skill is activated, you are guiding a user through planning a brand new project. Follow this structured approach:
|
|
13
|
-
|
|
14
|
-
### Step 1: Check for Resume (Checkpoint)
|
|
15
|
-
|
|
16
|
-
**First, check if there's an existing checkpoint** from a previous session:
|
|
17
|
-
|
|
18
|
-
```javascript
|
|
19
|
-
try {
|
|
20
|
-
const checkpoint = require('./lib/discovery-checkpoint');
|
|
21
|
-
const data = checkpoint.getCheckpoint();
|
|
22
|
-
if (data && data.step > 1) {
|
|
23
|
-
// Resume from checkpoint - display resume message
|
|
24
|
-
const resumeMessage = checkpoint.generateResumeMessage(data);
|
|
25
|
-
console.log(resumeMessage);
|
|
26
|
-
// Then skip to appropriate step based on data.step
|
|
27
|
-
}
|
|
28
|
-
} catch (e) {
|
|
29
|
-
// No checkpoint - start fresh
|
|
30
|
-
}
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
**If resuming from checkpoint:**
|
|
34
|
-
|
|
35
|
-
Use `generateResumeMessage(checkpoint)` from `lib/discovery-checkpoint.js` to display:
|
|
36
|
-
|
|
37
|
-
```
|
|
38
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
39
|
-
🔄 RESUMING PROJECT DISCOVERY
|
|
40
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
41
|
-
|
|
42
|
-
📍 Resuming from Step [step]: [step description]
|
|
43
|
-
|
|
44
|
-
📝 User Journey: "[user_journey]" (if exists)
|
|
45
|
-
🎨 UX Approach: "[ux_approach]" (if exists)
|
|
46
|
-
✅ Epics: Already created (if epics_created)
|
|
47
|
-
|
|
48
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
49
|
-
|
|
50
|
-
Continuing where you left off...
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
Then skip to the appropriate step based on `checkpoint.step`.
|
|
54
|
-
|
|
55
|
-
**If starting fresh:** Continue to Step 2.
|
|
56
|
-
|
|
57
|
-
---
|
|
58
|
-
|
|
59
|
-
### Step 2: Greet and Explore User Goal
|
|
60
|
-
|
|
61
|
-
**Your FIRST words to the user must be:**
|
|
62
|
-
|
|
63
|
-
> 👋 Hey there. It looks like you're kicking off a new project. I'm going to use JettyPod to guide you through building and shipping high quality code.
|
|
64
|
-
>
|
|
65
|
-
> And FYI, JettyPod is fully set up in your project for all future Claude Code sessions.
|
|
66
|
-
>
|
|
67
|
-
> **Ready to do this?**
|
|
68
|
-
|
|
69
|
-
**WAIT FOR USER RESPONSE.**
|
|
70
|
-
|
|
71
|
-
After they respond affirmatively, continue with:
|
|
72
|
-
|
|
73
|
-
> Awesome!
|
|
74
|
-
>
|
|
75
|
-
> Here is how we are going to kick things off:
|
|
76
|
-
>
|
|
77
|
-
> 1. I'll help you explore some prototypes to define what users actually do in your product
|
|
78
|
-
> 2. We'll choose a tech stack that fits
|
|
79
|
-
> 3. I'll break the project into phases so you have a clear plan
|
|
80
|
-
>
|
|
81
|
-
> Let's start simple: What do users DO in this product? Walk me through it.
|
|
82
|
-
>
|
|
83
|
-
> If that's not clear yet, what are you trying to help them accomplish?
|
|
84
|
-
|
|
85
|
-
**WAIT FOR USER RESPONSE.**
|
|
86
|
-
|
|
87
|
-
---
|
|
88
|
-
|
|
89
|
-
### Step 3: Explore User Journey
|
|
90
|
-
|
|
91
|
-
After user responds with their goal, ask about the user journey:
|
|
92
|
-
|
|
93
|
-
> Do you have a clear picture of how users will accomplish this? Like, what's the flow from opening your product to getting value from it?
|
|
94
|
-
>
|
|
95
|
-
> If yes, walk me through it. If not, I can suggest some user journey ideas based on what you've described.
|
|
96
|
-
|
|
97
|
-
**If user wants journey suggestions, present exactly 3 journey options:**
|
|
98
|
-
|
|
99
|
-
```
|
|
100
|
-
Here are 3 different ways users could accomplish [their goal]:
|
|
101
|
-
|
|
102
|
-
**Journey Option 1: [Simple/Direct approach name]**
|
|
103
|
-
- **Flow**: [Step-by-step user actions]
|
|
104
|
-
- **Pros**: ✅ [2-3 advantages - fast, familiar, low friction]
|
|
105
|
-
- **Cons**: ❌ [2-3 trade-offs - limitations, constraints]
|
|
106
|
-
|
|
107
|
-
**Journey Option 2: [Balanced approach name]**
|
|
108
|
-
- **Flow**: [Step-by-step user actions]
|
|
109
|
-
- **Pros**: ✅ [2-3 advantages - good balance]
|
|
110
|
-
- **Cons**: ❌ [2-3 trade-offs]
|
|
111
|
-
|
|
112
|
-
**Journey Option 3: [Advanced/Guided approach name]**
|
|
113
|
-
- **Flow**: [Step-by-step user actions]
|
|
114
|
-
- **Pros**: ✅ [2-3 advantages - powerful, guided]
|
|
115
|
-
- **Cons**: ❌ [2-3 trade-offs - complexity, learning curve]
|
|
116
|
-
|
|
117
|
-
**Additional journey patterns considered:**
|
|
118
|
-
- *Alternative 1*: [Brief] - Not recommended because [reason]
|
|
119
|
-
- *Alternative 2*: [Brief] - Not recommended because [reason]
|
|
120
|
-
|
|
121
|
-
Which journey resonates with you? Or do you want to describe your own?
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
**WAIT FOR USER RESPONSE.**
|
|
125
|
-
|
|
126
|
-
**After user picks/describes journey, save checkpoint:**
|
|
127
|
-
|
|
128
|
-
```javascript
|
|
129
|
-
try {
|
|
130
|
-
const checkpoint = require('./lib/discovery-checkpoint');
|
|
131
|
-
checkpoint.updateCheckpoint(2, { user_journey: "[their chosen/described journey]" });
|
|
132
|
-
} catch (e) {
|
|
133
|
-
// Checkpoint module optional - skip if not available
|
|
134
|
-
}
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
---
|
|
138
|
-
|
|
139
|
-
### Step 4: Explore UX Approach
|
|
140
|
-
|
|
141
|
-
**Present exactly 3 UX approaches** (NOT tech stacks - focus on what it FEELS LIKE to use):
|
|
142
|
-
|
|
143
|
-
Adapt to their workflow. Example patterns:
|
|
144
|
-
- Command-Line Workflow vs Visual Dashboard vs Conversational AI
|
|
145
|
-
- Template Selection vs Drag-and-Drop Editor vs Code-First
|
|
146
|
-
- Linear Document vs Networked Notes vs Canvas-Based
|
|
147
|
-
|
|
148
|
-
```
|
|
149
|
-
**Option 1: [Simple approach]**
|
|
150
|
-
- **Pros**: ✅ [2-3 advantages]
|
|
151
|
-
- **Cons**: ❌ [2-3 trade-offs]
|
|
152
|
-
- **Experience**: [What it feels like to use]
|
|
153
|
-
|
|
154
|
-
**Option 2: [Balanced approach]**
|
|
155
|
-
- **Pros**: ✅ [2-3 advantages]
|
|
156
|
-
- **Cons**: ❌ [2-3 trade-offs]
|
|
157
|
-
- **Experience**: [What it feels like to use]
|
|
158
|
-
|
|
159
|
-
**Option 3: [Advanced approach]**
|
|
160
|
-
- **Pros**: ✅ [2-3 advantages]
|
|
161
|
-
- **Cons**: ❌ [2-3 trade-offs]
|
|
162
|
-
- **Experience**: [What it feels like to use]
|
|
163
|
-
|
|
164
|
-
**Additional approaches considered but not recommended:**
|
|
165
|
-
- *Alternative 1*: [Brief] - Not selected because [reason]
|
|
166
|
-
- *Alternative 2*: [Brief] - Not selected because [reason]
|
|
167
|
-
- *Alternative 3*: [Brief] - Not selected because [reason]
|
|
168
|
-
|
|
169
|
-
**Would you like me to create working prototypes of these experiences?**
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
**WAIT FOR USER RESPONSE.**
|
|
173
|
-
|
|
174
|
-
---
|
|
175
|
-
|
|
176
|
-
### Step 4B: Optional Prototyping
|
|
177
|
-
|
|
178
|
-
**If user wants prototypes:**
|
|
179
|
-
|
|
180
|
-
For each prototype approach, run:
|
|
181
|
-
```bash
|
|
182
|
-
jettypod project prototype start <approach-name>
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
This creates a worktree at `.jettypod-work/project-prototype-<approach>/`. Build the prototype using **absolute paths**:
|
|
186
|
-
- `<worktree_path>/prototypes/<approach>/` for prototype files
|
|
187
|
-
- Focus on demonstrating the FEEL, not production code
|
|
188
|
-
- Use whatever tech is FASTEST to show the experience
|
|
189
|
-
|
|
190
|
-
After building, commit and merge:
|
|
191
|
-
```bash
|
|
192
|
-
cd <worktree_path>
|
|
193
|
-
git add .
|
|
194
|
-
git commit -m "Add project prototype: <approach>"
|
|
195
|
-
jettypod project prototype merge
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
Repeat for each approach. Each merge lands the prototype on main in `/prototypes/`.
|
|
199
|
-
|
|
200
|
-
**After building prototypes, offer to open them:**
|
|
201
|
-
|
|
202
|
-
> Want me to open these in your browser so you can try them out?
|
|
203
|
-
|
|
204
|
-
If yes, use: `open prototypes/<approach>/index.html`
|
|
205
|
-
|
|
206
|
-
**After ANY prototype modifications or tweaks, always ask:**
|
|
207
|
-
|
|
208
|
-
> Got it - I've updated the prototype.
|
|
209
|
-
>
|
|
210
|
-
> Do you feel like you have enough clarity on the basic user journey now? Like, do you know what users will DO to get value from this?
|
|
211
|
-
>
|
|
212
|
-
> If yes, let's break this down into phases and start building the real thing.
|
|
213
|
-
> If no, what else do you want to explore with the prototype?
|
|
214
|
-
|
|
215
|
-
**Important:** Prototypes are for learning and answering questions, not for building production features. Don't let users iterate endlessly - help them move forward once they have clarity on the user journey.
|
|
216
|
-
|
|
217
|
-
---
|
|
218
|
-
|
|
219
|
-
### Step 5: Epic Breakdown
|
|
220
|
-
|
|
221
|
-
**After user picks UX approach winner, save checkpoint:**
|
|
222
|
-
|
|
223
|
-
```javascript
|
|
224
|
-
try {
|
|
225
|
-
const checkpoint = require('./lib/discovery-checkpoint');
|
|
226
|
-
checkpoint.updateCheckpoint(4, { ux_approach: "[chosen option]" });
|
|
227
|
-
} catch (e) {
|
|
228
|
-
// Checkpoint module optional - skip if not available
|
|
229
|
-
}
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
**Propose epic breakdown:**
|
|
233
|
-
|
|
234
|
-
> Based on what you described, here's how I'd break this into epics.
|
|
235
|
-
>
|
|
236
|
-
> **Quick context:** Epics are phase-level chunks of work that each contain several features. For example, an epic might be "User Authentication" which includes features like "Email/password login", "Password reset", and "Social login".
|
|
237
|
-
>
|
|
238
|
-
> Here's what I'm thinking:
|
|
239
|
-
>
|
|
240
|
-
> **Epic 1: [Name]** - [What it covers - specific capabilities]
|
|
241
|
-
> **Epic 2: [Name]** - [What it covers]
|
|
242
|
-
> **Epic 3: [Name]** - [What it covers]
|
|
243
|
-
>
|
|
244
|
-
> Sound right?
|
|
245
|
-
|
|
246
|
-
**WAIT FOR USER RESPONSE.**
|
|
247
|
-
|
|
248
|
-
After user confirms (with any adjustments), create the epics:
|
|
249
|
-
|
|
250
|
-
```bash
|
|
251
|
-
jettypod work create epic "[Epic Name]" "[Description]"
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
After creating all epics, display:
|
|
255
|
-
|
|
256
|
-
> ✅ Epics created and added to your backlog.
|
|
257
|
-
|
|
258
|
-
**Save checkpoint:**
|
|
259
|
-
|
|
260
|
-
```javascript
|
|
261
|
-
try {
|
|
262
|
-
const checkpoint = require('./lib/discovery-checkpoint');
|
|
263
|
-
checkpoint.updateCheckpoint(5, { epics_created: true });
|
|
264
|
-
} catch (e) {
|
|
265
|
-
// Checkpoint module optional - skip if not available
|
|
266
|
-
}
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
---
|
|
270
|
-
|
|
271
|
-
### Step 6: Tech Stack Selection
|
|
272
|
-
|
|
273
|
-
**Present exactly 3 tech stack options** appropriate for the UX approach they chose:
|
|
274
|
-
|
|
275
|
-
```
|
|
276
|
-
Now let's pick the tech stack. Based on [their chosen UX approach], here are 3 options:
|
|
277
|
-
|
|
278
|
-
**Option 1: [Tech stack name]**
|
|
279
|
-
- **Pros**: ✅ [2-3 advantages - why this is good for their use case]
|
|
280
|
-
- **Cons**: ❌ [2-3 trade-offs - limitations or costs]
|
|
281
|
-
- **What you'll get**: [What development will feel like, deployment complexity, learning curve]
|
|
282
|
-
|
|
283
|
-
**Option 2: [Tech stack name]**
|
|
284
|
-
- **Pros**: ✅ [2-3 advantages]
|
|
285
|
-
- **Cons**: ❌ [2-3 trade-offs]
|
|
286
|
-
- **What you'll get**: [Development experience, deployment, learning curve]
|
|
287
|
-
|
|
288
|
-
**Option 3: [Tech stack name]**
|
|
289
|
-
- **Pros**: ✅ [2-3 advantages]
|
|
290
|
-
- **Cons**: ❌ [2-3 trade-offs]
|
|
291
|
-
- **What you'll get**: [Development experience, deployment, learning curve]
|
|
292
|
-
|
|
293
|
-
**Other options considered:**
|
|
294
|
-
- *Alternative 1*: [Brief] - Not recommended because [reason]
|
|
295
|
-
- *Alternative 2*: [Brief] - Not recommended because [reason]
|
|
296
|
-
|
|
297
|
-
Which tech stack fits best for you?
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
**Important:** If they're building a web application, use shadcn/ui as the default component library (don't ask - just use it when building UI).
|
|
301
|
-
|
|
302
|
-
**WAIT FOR USER RESPONSE.**
|
|
303
|
-
|
|
304
|
-
**Save checkpoint:**
|
|
305
|
-
|
|
306
|
-
```javascript
|
|
307
|
-
try {
|
|
308
|
-
const checkpoint = require('./lib/discovery-checkpoint');
|
|
309
|
-
checkpoint.updateCheckpoint(6, {});
|
|
310
|
-
} catch (e) {
|
|
311
|
-
// Checkpoint module optional - skip if not available
|
|
312
|
-
}
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
---
|
|
316
|
-
|
|
317
|
-
### Step 7: Confirm Rationale and Complete Discovery
|
|
318
|
-
|
|
319
|
-
**Propose the rationale to the user first:**
|
|
320
|
-
|
|
321
|
-
> I'm going to record this decision:
|
|
322
|
-
>
|
|
323
|
-
> Winner: prototypes/[path]
|
|
324
|
-
> Rationale: [experience] with [tech] because [reason]
|
|
325
|
-
>
|
|
326
|
-
> Does this capture why you chose this approach? (You can edit the rationale if needed)
|
|
327
|
-
|
|
328
|
-
**WAIT FOR USER RESPONSE.**
|
|
329
|
-
|
|
330
|
-
**After user confirms, record the decision:**
|
|
331
|
-
|
|
332
|
-
```bash
|
|
333
|
-
jettypod project discover complete --winner="prototypes/[path]" --rationale="[user's confirmed/edited rationale]"
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
---
|
|
337
|
-
|
|
338
|
-
### Step 8: Educational Transition
|
|
339
|
-
|
|
340
|
-
**After recording decision, provide this educational transition:**
|
|
341
|
-
|
|
342
|
-
> 🎉 Project discovery complete! You've got your epics defined and we know what we're building.
|
|
343
|
-
>
|
|
344
|
-
> **Here's how we'll build this, one piece at a time:**
|
|
345
|
-
>
|
|
346
|
-
> We're entering a repeatable workflow that you'll use for the rest of this project. Think of it like Russian nesting dolls:
|
|
347
|
-
>
|
|
348
|
-
> 📦 **Epic** = A big capability (like "User Authentication" or "Real-time Collaboration")
|
|
349
|
-
> └─ ✨ **Feature** = Something users actually do (like "Email/password login" or "Live cursor tracking")
|
|
350
|
-
> └─ 🔧 **Chore** = Technical tasks to build that feature (like "Create login form" or "Hash passwords")
|
|
351
|
-
>
|
|
352
|
-
> **Two phases for everything you build:**
|
|
353
|
-
>
|
|
354
|
-
> 1️⃣ **Discovery Phase** - Figure out what to build
|
|
355
|
-
> - We'll explore 2-3 different approaches
|
|
356
|
-
> - You pick the winner
|
|
357
|
-
> - We write test scenarios
|
|
358
|
-
> - **You only do this once per feature**
|
|
359
|
-
>
|
|
360
|
-
> 2️⃣ **Implementation Phase** - Build it in 3 modes
|
|
361
|
-
> - **Speed Mode**: Prove it works (happy path only, ~2 hours)
|
|
362
|
-
> - **Stable Mode**: Make it dependable (error handling, edge cases - this is where features live)
|
|
363
|
-
> - **Production Mode**: Safe for customers (security, scale, compliance - only needed if customers use it)
|
|
364
|
-
>
|
|
365
|
-
> **We won't talk about modes yet** - you'll learn those when you start implementing. Right now, focus on discovery.
|
|
366
|
-
>
|
|
367
|
-
> **Next step: Plan your first epic**
|
|
368
|
-
>
|
|
369
|
-
> Pick one epic to start with (usually the foundational one). Then tell me:
|
|
370
|
-
> "Let's plan [epic name]"
|
|
371
|
-
|
|
372
|
-
**Discovery is complete.** Wait for user to choose which epic to plan next.
|