jettypod 4.4.115 → 4.4.118
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 +25 -9
- package/apps/dashboard/app/api/claude/sessions/[sessionId]/message/route.ts +7 -3
- 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/connect-claude/page.tsx +24 -0
- package/apps/dashboard/app/install-claude/page.tsx +8 -6
- package/apps/dashboard/app/login/page.tsx +229 -0
- package/apps/dashboard/app/page.tsx +5 -3
- package/apps/dashboard/app/settings/page.tsx +2 -0
- package/apps/dashboard/app/subscribe/page.tsx +11 -0
- package/apps/dashboard/app/welcome/page.tsx +23 -0
- package/apps/dashboard/components/AppShell.tsx +51 -9
- package/apps/dashboard/components/CardMenu.tsx +14 -5
- package/apps/dashboard/components/ClaudePanel.tsx +65 -9
- package/apps/dashboard/components/ConnectClaudeScreen.tsx +223 -0
- package/apps/dashboard/components/DragContext.tsx +73 -64
- package/apps/dashboard/components/DraggableCard.tsx +6 -46
- package/apps/dashboard/components/GateCard.tsx +21 -0
- package/apps/dashboard/components/InstallClaudeScreen.tsx +132 -30
- package/apps/dashboard/components/KanbanBoard.tsx +173 -56
- package/apps/dashboard/components/PlaceholderCard.tsx +9 -19
- package/apps/dashboard/components/ProjectSwitcher.tsx +28 -0
- package/apps/dashboard/components/RealTimeKanbanWrapper.tsx +34 -3
- package/apps/dashboard/components/RealTimeTestsWrapper.tsx +30 -2
- package/apps/dashboard/components/SubscribeContent.tsx +191 -0
- package/apps/dashboard/components/TipCard.tsx +176 -0
- package/apps/dashboard/components/UpgradeBanner.tsx +29 -0
- package/apps/dashboard/components/WelcomeScreen.tsx +14 -4
- package/apps/dashboard/components/settings/AccountSection.tsx +163 -0
- package/apps/dashboard/contexts/ClaudeSessionContext.tsx +292 -29
- package/apps/dashboard/contexts/UsageContext.tsx +131 -0
- package/apps/dashboard/contexts/usageHelpers.js +9 -0
- package/apps/dashboard/electron/ipc-handlers.js +220 -114
- package/apps/dashboard/electron/main.js +415 -37
- package/apps/dashboard/electron/preload.js +23 -4
- package/apps/dashboard/electron/session-manager.js +141 -0
- package/apps/dashboard/electron-builder.config.js +3 -5
- package/apps/dashboard/lib/claude-process-manager.ts +6 -4
- package/apps/dashboard/lib/db-bridge.ts +32 -0
- package/apps/dashboard/lib/db.ts +159 -13
- package/apps/dashboard/lib/session-state-machine.ts +3 -0
- package/apps/dashboard/lib/session-stream-manager.ts +76 -13
- package/apps/dashboard/lib/tests.ts +3 -1
- package/apps/dashboard/next.config.js +19 -14
- package/apps/dashboard/package.json +3 -1
- package/apps/dashboard/scripts/upload-to-r2.js +89 -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 +1074 -0
- package/apps/update-server/tsconfig.json +16 -0
- package/apps/update-server/wrangler.toml +35 -0
- package/docs/bdd-guidance.md +390 -0
- package/jettypod.js +5 -4
- package/lib/migrations/027-plan-at-creation-column.js +31 -0
- package/lib/migrations/028-ready-for-review-column.js +27 -0
- package/lib/schema.js +3 -1
- package/lib/seed-onboarding.js +100 -68
- package/lib/work-commands/index.js +43 -13
- package/lib/work-tracking/index.js +46 -27
- package/package.json +1 -1
- package/skills-templates/bug-mode/SKILL.md +5 -11
- package/skills-templates/request-routing/SKILL.md +24 -11
- package/skills-templates/simple-improvement/SKILL.md +35 -19
- package/skills-templates/stable-mode/SKILL.md +5 -6
- 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
package/lib/seed-onboarding.js
CHANGED
|
@@ -11,118 +11,150 @@ const ONBOARDING_EPIC = {
|
|
|
11
11
|
description: 'Get your project set up and planned. Work through these chores one at a time — each one is a short conversation.'
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
+
const TONE = `HOW TO RESPOND:
|
|
15
|
+
You are a collaborator, not an AI assistant. You're a knowledgeable partner having a real conversation.
|
|
16
|
+
- Do NOT open with a summary or recap of what you've been asked to do
|
|
17
|
+
- Do NOT list steps or outline a plan before starting
|
|
18
|
+
- Do NOT say "I'll help you with...", "Let me guide you through...", or "Great question!"
|
|
19
|
+
- Do NOT use headers, bullet lists, or formatted option blocks in your first message
|
|
20
|
+
- DO jump straight into conversation like a person who just sat down across the table
|
|
21
|
+
- DO ask one question at a time, then actually listen to the response
|
|
22
|
+
- DO keep responses short — a few sentences, not paragraphs
|
|
23
|
+
- DO respond naturally to what the user says, adapting your follow-ups accordingly`;
|
|
24
|
+
|
|
14
25
|
const ONBOARDING_CHORES = [
|
|
15
26
|
{
|
|
16
27
|
title: 'Align on the user journey',
|
|
17
|
-
description:
|
|
28
|
+
description: `${TONE}
|
|
29
|
+
|
|
30
|
+
YOUR ROLE: Help the user articulate what their product does and how people will use it.
|
|
18
31
|
|
|
19
|
-
|
|
20
|
-
Open with: "What do users DO in this product? Walk me through the flow from opening it to getting value from it."
|
|
32
|
+
CONVERSATION FLOW:
|
|
21
33
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
- Journey 3: [Advanced/Guided approach] with flow, pros, cons
|
|
34
|
+
1. OPEN — Jump straight in. Something like:
|
|
35
|
+
"So — what are you building? Walk me through what happens when someone opens this thing up."
|
|
36
|
+
(Adapt to context. Be casual. No preamble.)
|
|
26
37
|
|
|
27
|
-
|
|
38
|
+
2. LISTEN AND DIG — Based on what they say, ask natural follow-ups. One at a time:
|
|
39
|
+
- "And then what? What happens after [thing they mentioned]?"
|
|
40
|
+
- "How do they find that the first time?"
|
|
41
|
+
- "What's the moment where it clicks — like, this is actually useful?"
|
|
42
|
+
Don't rush this. Let them think. Some people need 2-3 exchanges to articulate their vision.
|
|
28
43
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
-
|
|
44
|
+
3. IF THEY'RE VAGUE — Don't present a formatted options list. Talk through possibilities naturally:
|
|
45
|
+
"I could see this going a few ways. You could do [approach A] — really simple, users just [action]. Or something more like [approach B] where they [different flow]. What feels closer?"
|
|
46
|
+
If they're really stuck, describe 2-3 directions conversationally and ask what resonates.
|
|
32
47
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
48
|
+
4. CONFIRM — Once the journey is clear, reflect it back casually:
|
|
49
|
+
"Cool, so basically: user shows up, [does X], then [does Y], and the payoff is [Z]. That feel right?"
|
|
50
|
+
Wait for them to confirm or adjust.
|
|
36
51
|
|
|
37
|
-
|
|
52
|
+
5. RECORD — After they confirm, run:
|
|
53
|
+
jettypod work epic-implement <onboarding-epic-id> --aspect="User Journey" --decision="<summary of chosen journey>" --rationale="<why this flow>"
|
|
54
|
+
|
|
55
|
+
6. HAND OFF — Say something like: "Nice. Close this chat and start the next chore in your backlog to keep going."`
|
|
38
56
|
},
|
|
39
57
|
{
|
|
40
58
|
title: 'Explore UX approaches',
|
|
41
|
-
description:
|
|
59
|
+
description: `${TONE}
|
|
60
|
+
|
|
61
|
+
YOUR ROLE: Help the user decide how their product should FEEL to use. This is about the experience, not the tech.
|
|
42
62
|
|
|
43
|
-
CONTEXT
|
|
44
|
-
Read the user journey decision first:
|
|
63
|
+
CONTEXT: Read the user journey decision first:
|
|
45
64
|
jettypod decisions --epic=<onboarding-epic-id>
|
|
46
65
|
|
|
47
|
-
|
|
48
|
-
Open with: "Based on your user journey: [quote decision]. Now let's figure out how it should feel to use."
|
|
66
|
+
CONVERSATION FLOW:
|
|
49
67
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
- Option 3: [Advanced approach] — pros, cons, what it feels like
|
|
68
|
+
1. OPEN — Reference what they already decided and pivot naturally:
|
|
69
|
+
"So last time you said users would [brief journey recap]. Now I'm curious — what should that actually feel like? Like, when someone [key action], are you imagining something minimal and fast, or more guided and hand-holdy?"
|
|
70
|
+
(Use their actual words from the decision. Don't be generic.)
|
|
54
71
|
|
|
55
|
-
|
|
72
|
+
2. EXPLORE THROUGH CONVERSATION — Don't dump three formatted options. Talk through directions:
|
|
73
|
+
"One direction would be something really stripped down — [describe the feel]. That works well when [context]. But you could also go more toward [different feel] where [description]. The trade-off is [honest assessment]."
|
|
74
|
+
Let them react. Follow their energy.
|
|
56
75
|
|
|
57
|
-
|
|
58
|
-
|
|
76
|
+
3. GET SPECIFIC — Once a direction emerges, push on it:
|
|
77
|
+
"OK so if we go that route, the main screen would probably be [description]. Does that feel right or is that too [much/little]?"
|
|
59
78
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
79
|
+
4. OFFER PROTOTYPES (if it would help) — If they're torn or want to see it:
|
|
80
|
+
"Want me to throw together a quick prototype of that? Nothing fancy — just enough to feel it out."
|
|
81
|
+
If yes, use: jettypod project prototype start <approach-name>
|
|
82
|
+
Build a minimal throwaway prototype, then: jettypod project prototype merge
|
|
83
|
+
After they try it: "What did you think? Does that feel like the right direction, or should we adjust?"
|
|
64
84
|
|
|
65
|
-
|
|
66
|
-
|
|
85
|
+
5. CONFIRM — Lock in the winner:
|
|
86
|
+
"Alright, so the feel is [description]. I'll record that."
|
|
67
87
|
|
|
68
|
-
|
|
88
|
+
6. RECORD — Run:
|
|
89
|
+
jettypod work epic-implement <onboarding-epic-id> --aspect="UX Approach" --decision="<chosen approach>" --rationale="<why>"
|
|
90
|
+
|
|
91
|
+
7. HAND OFF — "Close this chat and start the next chore from your backlog."`
|
|
69
92
|
},
|
|
70
93
|
{
|
|
71
94
|
title: 'Choose a tech stack',
|
|
72
|
-
description:
|
|
95
|
+
description: `${TONE}
|
|
96
|
+
|
|
97
|
+
YOUR ROLE: Help the user pick the right tech stack based on what they're building and how it should feel.
|
|
73
98
|
|
|
74
|
-
CONTEXT
|
|
75
|
-
Read previous decisions first:
|
|
99
|
+
CONTEXT: Read previous decisions first:
|
|
76
100
|
jettypod decisions --epic=<onboarding-epic-id>
|
|
77
101
|
|
|
78
|
-
|
|
79
|
-
Open with: "You're building [journey] with a [UX approach] experience. Let's pick the tech stack."
|
|
102
|
+
CONVERSATION FLOW:
|
|
80
103
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
104
|
+
1. OPEN — Connect the dots from previous decisions:
|
|
105
|
+
"You're building [journey] and you want it to feel [UX approach]. That actually narrows down the tech quite a bit."
|
|
106
|
+
Then lead with your honest take:
|
|
107
|
+
"I'd probably go with [recommendation] for this. Here's why — [reason]."
|
|
108
|
+
(Have an opinion. Don't just present options neutrally.)
|
|
85
109
|
|
|
86
|
-
|
|
110
|
+
2. HAVE A REAL DISCUSSION — After giving your take, open it up:
|
|
111
|
+
"That said — do you have a preference? Are you already comfortable with something, or is there a stack you've been wanting to try?"
|
|
112
|
+
Respond to what they say. If they push back, engage with it honestly:
|
|
113
|
+
"Yeah, [their preference] could work. The main thing you'd lose is [trade-off]. The main thing you'd gain is [benefit]. Honestly, either would be fine for this."
|
|
87
114
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
- A winner chosen with rationale
|
|
115
|
+
3. IF THEY WANT OPTIONS — Talk through 2-3 stacks conversationally, not as formatted comparison blocks:
|
|
116
|
+
"[Stack A] would be the fastest to get going — you'd have [benefit] out of the box. [Stack B] is more flexible but you'd need to wire up [thing] yourself. And then there's [Stack C] which is honestly overkill here unless you specifically want [thing]."
|
|
91
117
|
|
|
92
|
-
|
|
93
|
-
|
|
118
|
+
4. LAND ON A DECISION — Once they choose:
|
|
119
|
+
"Solid choice. [One sentence of genuine validation — why it fits their specific project, not generic praise]."
|
|
94
120
|
|
|
95
|
-
|
|
121
|
+
5. RECORD — Run:
|
|
122
|
+
jettypod work epic-implement <onboarding-epic-id> --aspect="Tech Stack" --decision="<chosen stack>" --rationale="<why>"
|
|
123
|
+
|
|
124
|
+
6. HAND OFF — "One more chore left — close this chat and start it from your backlog."`
|
|
96
125
|
},
|
|
97
126
|
{
|
|
98
127
|
title: 'Break the project into epics',
|
|
99
|
-
description:
|
|
128
|
+
description: `${TONE}
|
|
129
|
+
|
|
130
|
+
YOUR ROLE: Break the project into buildable phases (epics) based on everything they've decided.
|
|
100
131
|
|
|
101
|
-
CONTEXT
|
|
102
|
-
Read all previous decisions first:
|
|
132
|
+
CONTEXT: Read all previous decisions first:
|
|
103
133
|
jettypod decisions --epic=<onboarding-epic-id>
|
|
104
134
|
|
|
105
|
-
|
|
106
|
-
Open with: "You're building [journey] as a [UX approach] experience using [tech stack]. Let's break this into phases."
|
|
135
|
+
CONVERSATION FLOW:
|
|
107
136
|
|
|
108
|
-
|
|
137
|
+
1. OPEN — Bring it all together and jump straight to the breakdown:
|
|
138
|
+
"Alright — you're building [journey], it should feel [UX approach], and you're using [tech stack]. Let me suggest how to break this into phases."
|
|
139
|
+
Then just propose the epics conversationally:
|
|
140
|
+
"I'd start with [Epic 1] — that's the foundation, stuff like [examples]. Then [Epic 2] which covers [what]. And then [Epic 3] for [what]."
|
|
141
|
+
(Don't over-explain what an epic is. Keep it natural.)
|
|
109
142
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
- Epic 2: [Name] — what it covers
|
|
113
|
-
- Epic 3: [Name] — what it covers
|
|
143
|
+
2. QUICK CONTEXT (only if needed) — If they seem unsure about the structure:
|
|
144
|
+
"Each of these is a phase. Inside each one we'll define specific features — things users can actually do. You don't need to think about that yet though."
|
|
114
145
|
|
|
115
|
-
|
|
146
|
+
3. GET FEEDBACK — After proposing:
|
|
147
|
+
"Does that breakdown make sense? Anything you'd add, cut, or reorder?"
|
|
148
|
+
Adjust based on their input. Don't be precious about your proposal.
|
|
116
149
|
|
|
117
|
-
|
|
118
|
-
|
|
150
|
+
4. CREATE — Once they confirm, create each epic:
|
|
151
|
+
jettypod work create epic "<title>" "<description>"
|
|
152
|
+
Do this for each one.
|
|
119
153
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
- A recommendation for which epic to start first
|
|
154
|
+
5. RECOMMEND A STARTING POINT:
|
|
155
|
+
"If I were you, I'd start with [Epic name] — [brief reason, like 'everything else depends on it' or 'it's the quickest win to get something real']."
|
|
123
156
|
|
|
124
|
-
|
|
125
|
-
Tell the user: "Your project is planned! Pick an epic from the backlog and tell Claude 'Let's plan [epic name]' to start building."`
|
|
157
|
+
6. CLOSE — "Your project is planned. Pick an epic from the backlog and tell Claude 'Let's plan [epic name]' to start building."`
|
|
126
158
|
}
|
|
127
159
|
];
|
|
128
160
|
|
|
@@ -1902,20 +1902,50 @@ async function mergeWork(options = {}) {
|
|
|
1902
1902
|
`Test worktrees (tests/* branches) merge BDD scenarios without completing the feature.`
|
|
1903
1903
|
));
|
|
1904
1904
|
} else {
|
|
1905
|
-
// Chore or bug worktree
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
[completedAt, currentWork.id],
|
|
1912
|
-
(err) => {
|
|
1905
|
+
// Chore or bug worktree
|
|
1906
|
+
// Check if this is a standalone kanban-visible item (no parent or parent is epic)
|
|
1907
|
+
let isStandalone = !currentWork.parent_id;
|
|
1908
|
+
if (!isStandalone && currentWork.parent_id) {
|
|
1909
|
+
const parentItem = await new Promise((resolve, reject) => {
|
|
1910
|
+
db.get('SELECT type FROM work_items WHERE id = ?', [currentWork.parent_id], (err, row) => {
|
|
1913
1911
|
if (err) return reject(err);
|
|
1914
|
-
resolve();
|
|
1915
|
-
}
|
|
1916
|
-
);
|
|
1917
|
-
|
|
1918
|
-
|
|
1912
|
+
resolve(row);
|
|
1913
|
+
});
|
|
1914
|
+
});
|
|
1915
|
+
isStandalone = parentItem && parentItem.type === 'epic';
|
|
1916
|
+
}
|
|
1917
|
+
|
|
1918
|
+
if (isStandalone) {
|
|
1919
|
+
// Standalone item: set ready_for_review instead of marking done
|
|
1920
|
+
// Keep status as in_progress so it stays in the In Flight column
|
|
1921
|
+
// User accepts/rejects via the kanban board
|
|
1922
|
+
await new Promise((resolve, reject) => {
|
|
1923
|
+
db.run(
|
|
1924
|
+
`UPDATE work_items SET ready_for_review = 1 WHERE id = ?`,
|
|
1925
|
+
[currentWork.id],
|
|
1926
|
+
(err) => {
|
|
1927
|
+
if (err) return reject(err);
|
|
1928
|
+
resolve();
|
|
1929
|
+
}
|
|
1930
|
+
);
|
|
1931
|
+
});
|
|
1932
|
+
console.log(`✅ ${currentWork.type.charAt(0).toUpperCase() + currentWork.type.slice(1)} #${currentWork.id} ready for review`);
|
|
1933
|
+
} else {
|
|
1934
|
+
// Chore/bug under a feature: mark as done (feature handles the accept flow)
|
|
1935
|
+
console.log(`Marking ${currentWork.type} as done...`);
|
|
1936
|
+
const completedAt = new Date().toISOString();
|
|
1937
|
+
await new Promise((resolve, reject) => {
|
|
1938
|
+
db.run(
|
|
1939
|
+
`UPDATE work_items SET status = 'done', completed_at = ? WHERE id = ?`,
|
|
1940
|
+
[completedAt, currentWork.id],
|
|
1941
|
+
(err) => {
|
|
1942
|
+
if (err) return reject(err);
|
|
1943
|
+
resolve();
|
|
1944
|
+
}
|
|
1945
|
+
);
|
|
1946
|
+
});
|
|
1947
|
+
console.log(`✅ ${currentWork.type.charAt(0).toUpperCase() + currentWork.type.slice(1)} #${currentWork.id} marked as done`);
|
|
1948
|
+
}
|
|
1919
1949
|
}
|
|
1920
1950
|
|
|
1921
1951
|
// Mark worktree as merged but DON'T delete it yet
|
|
@@ -256,6 +256,22 @@ function create(type, title, description = '', parentId = null, mode = null, nee
|
|
|
256
256
|
}
|
|
257
257
|
|
|
258
258
|
function continueWithValidatedParent(epicId) {
|
|
259
|
+
// Read current plan from auth.json for usage tracking
|
|
260
|
+
let planAtCreation = null;
|
|
261
|
+
try {
|
|
262
|
+
const os = require('os');
|
|
263
|
+
const path = require('path');
|
|
264
|
+
const fs = require('fs');
|
|
265
|
+
const authPath = path.join(os.homedir(), 'Library', 'Application Support', 'jettypod', 'auth.json');
|
|
266
|
+
if (fs.existsSync(authPath)) {
|
|
267
|
+
const authData = JSON.parse(fs.readFileSync(authPath, 'utf8'));
|
|
268
|
+
planAtCreation = authData?.user?.plan || 'free';
|
|
269
|
+
} else {
|
|
270
|
+
planAtCreation = 'free';
|
|
271
|
+
}
|
|
272
|
+
} catch {
|
|
273
|
+
planAtCreation = 'free';
|
|
274
|
+
}
|
|
259
275
|
|
|
260
276
|
// Only features have modes - they start with mode=NULL (no mode until implementation starts)
|
|
261
277
|
// Epics, chores, and bugs don't have modes (always NULL)
|
|
@@ -282,8 +298,8 @@ function create(type, title, description = '', parentId = null, mode = null, nee
|
|
|
282
298
|
// Set phase for features (discovery when mode=NULL, implementation when mode is set, NULL for everything else)
|
|
283
299
|
const phase = type === 'feature' ? (mode ? 'implementation' : 'discovery') : null;
|
|
284
300
|
|
|
285
|
-
const sql = `INSERT INTO work_items (type, title, description, parent_id, epic_id, mode, needs_discovery, phase, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`;
|
|
286
|
-
db.run(sql, [type, title, description, parentId, epicId, mode, needsDiscovery ? 1 : 0, phase, 'backlog'], function(err) {
|
|
301
|
+
const sql = `INSERT INTO work_items (type, title, description, parent_id, epic_id, mode, needs_discovery, phase, status, plan_at_creation) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`;
|
|
302
|
+
db.run(sql, [type, title, description, parentId, epicId, mode, needsDiscovery ? 1 : 0, phase, 'backlog', planAtCreation], function(err) {
|
|
287
303
|
if (err) {
|
|
288
304
|
return reject(err);
|
|
289
305
|
}
|
|
@@ -776,31 +792,19 @@ function updateStatus(id, status) {
|
|
|
776
792
|
return resolve();
|
|
777
793
|
}
|
|
778
794
|
|
|
779
|
-
//
|
|
795
|
+
// Items under epics: set ready_for_review and keep in_progress for accept/reject
|
|
780
796
|
if (parent.type === 'epic') {
|
|
781
|
-
//
|
|
782
|
-
db.
|
|
783
|
-
'
|
|
784
|
-
[
|
|
785
|
-
(err
|
|
797
|
+
// Set ready_for_review on the item and revert to in_progress
|
|
798
|
+
db.run(
|
|
799
|
+
'UPDATE work_items SET ready_for_review = 1, status = ?, completed_at = NULL WHERE id = ?',
|
|
800
|
+
['in_progress', item.id],
|
|
801
|
+
(err) => {
|
|
786
802
|
if (err) {
|
|
787
|
-
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
const allDone = children.every(child => child.status === 'done');
|
|
791
|
-
if (allDone) {
|
|
792
|
-
const epicCompletedAt = new Date().toISOString();
|
|
793
|
-
db.run('UPDATE work_items SET status = ?, completed_at = ? WHERE id = ?', ['done', epicCompletedAt, parent.id], (err) => {
|
|
794
|
-
if (err) {
|
|
795
|
-
console.error(`Failed to auto-close epic: ${err.message}`);
|
|
796
|
-
} else {
|
|
797
|
-
console.log(`✓ Epic #${parent.id} also completed (all children done)`);
|
|
798
|
-
}
|
|
799
|
-
resolve();
|
|
800
|
-
});
|
|
803
|
+
console.error(`Failed to set ready_for_review: ${err.message}`);
|
|
801
804
|
} else {
|
|
802
|
-
|
|
805
|
+
console.log(`✓ Work item #${item.id} ready for review`);
|
|
803
806
|
}
|
|
807
|
+
resolve();
|
|
804
808
|
}
|
|
805
809
|
);
|
|
806
810
|
}
|
|
@@ -838,12 +842,12 @@ function updateStatus(id, status) {
|
|
|
838
842
|
}
|
|
839
843
|
|
|
840
844
|
if (featureComplete) {
|
|
841
|
-
|
|
842
|
-
db.run('UPDATE work_items SET
|
|
845
|
+
// Set ready_for_review instead of auto-closing — let user accept/reject
|
|
846
|
+
db.run('UPDATE work_items SET ready_for_review = 1 WHERE id = ?', [parent.id], (err) => {
|
|
843
847
|
if (err) {
|
|
844
|
-
console.error(`Failed to
|
|
848
|
+
console.error(`Failed to set ready_for_review: ${err.message}`);
|
|
845
849
|
} else {
|
|
846
|
-
console.log(`✓ Feature #${parent.id}
|
|
850
|
+
console.log(`✓ Feature #${parent.id} ready for review (all ${featureMode} mode chores done)`);
|
|
847
851
|
}
|
|
848
852
|
resolve();
|
|
849
853
|
});
|
|
@@ -860,6 +864,21 @@ function updateStatus(id, status) {
|
|
|
860
864
|
resolve();
|
|
861
865
|
}
|
|
862
866
|
});
|
|
867
|
+
} else if (status === 'done' && !item.parent_id) {
|
|
868
|
+
// Standalone item (no parent) marked done via CLI
|
|
869
|
+
// Set ready_for_review and revert to in_progress so user can accept/reject via kanban
|
|
870
|
+
db.run(
|
|
871
|
+
'UPDATE work_items SET ready_for_review = 1, status = ?, completed_at = NULL WHERE id = ?',
|
|
872
|
+
['in_progress', item.id],
|
|
873
|
+
(err) => {
|
|
874
|
+
if (err) {
|
|
875
|
+
console.error(`Failed to set ready_for_review: ${err.message}`);
|
|
876
|
+
} else {
|
|
877
|
+
console.log(`✓ Work item #${item.id} ready for review`);
|
|
878
|
+
}
|
|
879
|
+
resolve();
|
|
880
|
+
}
|
|
881
|
+
);
|
|
863
882
|
} else {
|
|
864
883
|
resolve();
|
|
865
884
|
}
|
package/package.json
CHANGED
|
@@ -342,13 +342,10 @@ jettypod work cleanup <bug-id>
|
|
|
342
342
|
|
|
343
343
|
---
|
|
344
344
|
|
|
345
|
-
### Step 5:
|
|
345
|
+
### Step 5: Completion
|
|
346
346
|
|
|
347
|
-
**
|
|
348
|
-
|
|
349
|
-
```bash
|
|
350
|
-
jettypod work status <bug-id> done
|
|
351
|
-
```
|
|
347
|
+
**The merge command automatically sets the bug as ready for review.**
|
|
348
|
+
It will appear with accept/reject buttons on the kanban board. Do NOT call `jettypod work status <bug-id> done` — that bypasses the review gate.
|
|
352
349
|
|
|
353
350
|
**Emit gate signal:**
|
|
354
351
|
|
|
@@ -387,7 +384,7 @@ Before ending bug-mode skill, ensure:
|
|
|
387
384
|
- [ ] Fix committed with descriptive message
|
|
388
385
|
- [ ] Bug merged to main
|
|
389
386
|
- [ ] Worktree cleaned up
|
|
390
|
-
- [ ] Bug
|
|
387
|
+
- [ ] Bug merged (review gate set automatically by merge command)
|
|
391
388
|
|
|
392
389
|
---
|
|
393
390
|
|
|
@@ -403,7 +400,4 @@ cd <main-repo> # Change to main repo
|
|
|
403
400
|
jettypod work cleanup <bug-id> # Clean up worktree
|
|
404
401
|
```
|
|
405
402
|
|
|
406
|
-
|
|
407
|
-
```bash
|
|
408
|
-
jettypod work status <bug-id> done
|
|
409
|
-
```
|
|
403
|
+
**⚠️ Do NOT mark bug as done manually — the merge command sets the review gate automatically.**
|
|
@@ -35,7 +35,7 @@ From the user's request, identify work type and complexity signals:
|
|
|
35
35
|
| refactor, rename, move, clean up, upgrade, migrate, infrastructure | chore-planning |
|
|
36
36
|
| add, build, create, implement, new feature, capability, workflow | feature-planning |
|
|
37
37
|
| epic, initiative, project, roadmap, multi-feature | epic-planning |
|
|
38
|
-
| tweak, change, update, adjust +
|
|
38
|
+
| tweak, change, update, adjust + PURELY COSMETIC (text, color, spacing, copy only) | simple-improvement |
|
|
39
39
|
|
|
40
40
|
**Complexity signals:**
|
|
41
41
|
| Signal | Indicates |
|
|
@@ -46,6 +46,8 @@ From the user's request, identify work type and complexity signals:
|
|
|
46
46
|
| Has edge cases to consider (validation, failures, states) | Higher complexity |
|
|
47
47
|
| Could fail in interesting ways | Higher complexity |
|
|
48
48
|
| Needs error handling design | Higher complexity |
|
|
49
|
+
| Adds or changes behavior (tracking, counting, filtering, sorting, state) | Higher complexity — NOT simple-improvement |
|
|
50
|
+
| Creates new capabilities (even small ones) | Higher complexity — NOT simple-improvement |
|
|
49
51
|
|
|
50
52
|
### Step 2: Gather Context (Silent - No Questions)
|
|
51
53
|
|
|
@@ -101,14 +103,14 @@ Are there edge cases to consider?
|
|
|
101
103
|
│ (The speed→stable split helps: make it work, then handle edge cases)
|
|
102
104
|
│
|
|
103
105
|
▼
|
|
104
|
-
Is this
|
|
105
|
-
(
|
|
106
|
-
|
|
106
|
+
Is this PURELY COSMETIC?
|
|
107
|
+
(Only changes text, copy, color, spacing, or static visual appearance?)
|
|
108
|
+
(Does NOT add/change any behavior, logic, tracking, data, or capabilities?)
|
|
109
|
+
├─► Yes → simple-improvement
|
|
107
110
|
│
|
|
108
111
|
▼
|
|
109
|
-
|
|
110
|
-
(
|
|
111
|
-
└─► Yes → simple-improvement
|
|
112
|
+
Default → chore-planning
|
|
113
|
+
(When in doubt, route to chore-planning, NEVER to simple-improvement)
|
|
112
114
|
```
|
|
113
115
|
|
|
114
116
|
## Route Definitions
|
|
@@ -120,7 +122,7 @@ Is this truly atomic?
|
|
|
120
122
|
| **epic-planning** | Large initiative spanning multiple features | Break down → plan features |
|
|
121
123
|
| **feature-planning** | New behavior needing UX exploration OR has edge cases worth sequencing | UX exploration → BDD → speed → stable → production |
|
|
122
124
|
| **chore-planning** | Substantial technical work, clear implementation | speed → stable → production |
|
|
123
|
-
| **simple-improvement** |
|
|
125
|
+
| **simple-improvement** | PURELY COSMETIC: text, copy, color, spacing changes only. No behavior change. | Direct implementation |
|
|
124
126
|
|
|
125
127
|
## Routing Examples
|
|
126
128
|
|
|
@@ -170,11 +172,22 @@ Is this truly atomic?
|
|
|
170
172
|
**→ simple-improvement**
|
|
171
173
|
- "Change the button text from 'Submit' to 'Save'"
|
|
172
174
|
- "Make the error message more descriptive"
|
|
173
|
-
- "Add a loading spinner to the save button"
|
|
174
175
|
- "Change the header color to blue"
|
|
175
|
-
- "
|
|
176
|
+
- "Update the placeholder text in the search box"
|
|
177
|
+
- "Increase the font size of the title"
|
|
176
178
|
|
|
177
|
-
*(
|
|
179
|
+
*(PURELY COSMETIC: only text, copy, color, spacing, or static visual changes. Zero behavior change.)*
|
|
180
|
+
|
|
181
|
+
**⚠️ NOT simple-improvement (common mistakes):**
|
|
182
|
+
- "Add a loading spinner to the save button" → **chore-planning** (adds behavior: state tracking, show/hide logic)
|
|
183
|
+
- "Add a tooltip to the settings icon" → **chore-planning** (adds behavior: hover state, positioning)
|
|
184
|
+
- "Track work item counts" → **feature-planning** (adds behavior: counting, state, display logic)
|
|
185
|
+
- "Add sorting to the list" → **feature-planning** (adds behavior: sort logic, state, UI interaction)
|
|
186
|
+
- "Show a count next to the tab" → **chore-planning** (adds behavior: data fetching, count computation)
|
|
187
|
+
- "Add a confirmation dialog" → **feature-planning** (adds behavior: modal state, user interaction, edge cases)
|
|
188
|
+
- "Make the sidebar collapsible" → **feature-planning** (adds behavior: toggle state, animation, persistence)
|
|
189
|
+
|
|
190
|
+
*(If it adds ANY new behavior — even "small" behavior — it is NOT a simple improvement.)*
|
|
178
191
|
|
|
179
192
|
## Stating Your Routing Decision
|
|
180
193
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: simple-improvement
|
|
3
|
-
description: Guide implementation of
|
|
3
|
+
description: Guide implementation of PURELY COSMETIC changes. Invoked by request-routing ONLY for text, copy, color, and spacing changes that add zero new behavior. (project)
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Simple Improvement Skill
|
|
@@ -18,24 +18,39 @@ description: Guide implementation of simple improvements to existing functionali
|
|
|
18
18
|
└─────────────────────────────────────────────────────────────────────┘
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
Lightweight workflow for
|
|
21
|
+
Lightweight workflow for PURELY COSMETIC changes. Bypasses the full speed/stable mode progression because these changes have zero behavior impact.
|
|
22
22
|
|
|
23
23
|
## When to Use
|
|
24
24
|
|
|
25
|
-
This skill is invoked by request-routing
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
25
|
+
This skill is invoked by request-routing ONLY for **purely cosmetic changes**:
|
|
26
|
+
- Text/copy changes (button labels, headings, descriptions, placeholder text)
|
|
27
|
+
- Color changes (background, text color, border color)
|
|
28
|
+
- Spacing/sizing changes (padding, margin, font size, width)
|
|
29
|
+
- Static visual appearance (border radius, opacity, font weight)
|
|
30
|
+
|
|
31
|
+
**The litmus test:** Could a non-developer make this change with a find-and-replace in a design tool? If yes, it's simple. If no, it's not.
|
|
30
32
|
|
|
31
33
|
## When NOT to Use
|
|
32
34
|
|
|
33
|
-
Route back to request-routing for:
|
|
34
|
-
|
|
35
|
+
**If it adds or changes ANY behavior, it is NOT a simple improvement.** Route back to request-routing for:
|
|
36
|
+
|
|
37
|
+
- Adding interactive elements (tooltips, spinners, modals, collapsibles)
|
|
38
|
+
- Adding tracking/counting/state (counters, badges, progress indicators)
|
|
39
|
+
- Adding data fetching or computation
|
|
40
|
+
- Adding conditional logic (show/hide, enable/disable)
|
|
41
|
+
- Adding user interactions (hover effects with logic, drag-and-drop, sorting)
|
|
42
|
+
- New functionality of ANY size
|
|
35
43
|
- Changes requiring new data models
|
|
36
44
|
- Complex logic changes
|
|
37
45
|
- Features needing error handling design
|
|
38
46
|
|
|
47
|
+
**Common misroutes — these are NOT simple improvements:**
|
|
48
|
+
- "Add a loading spinner" → has state (loading/not loading), show/hide logic
|
|
49
|
+
- "Show item count" → needs data query, computation, display logic
|
|
50
|
+
- "Add a tooltip" → hover detection, positioning, content logic
|
|
51
|
+
- "Make sidebar collapsible" → toggle state, persistence, animation
|
|
52
|
+
- "Add sorting" → sort logic, state management, UI interaction
|
|
53
|
+
|
|
39
54
|
---
|
|
40
55
|
|
|
41
56
|
## Instructions
|
|
@@ -71,6 +86,8 @@ Scan the user's description for these patterns:
|
|
|
71
86
|
|
|
72
87
|
| Signal | Keywords/Patterns |
|
|
73
88
|
|--------|-------------------|
|
|
89
|
+
| New behavior | "add", "track", "count", "show", "display", "when", "toggle", "sort", "filter" |
|
|
90
|
+
| State management | "loading", "spinner", "collapse", "expand", "hover", "active", "selected" |
|
|
74
91
|
| New data models | "new table", "add column", "database", "schema" |
|
|
75
92
|
| New API | "new endpoint", "API", "new route" |
|
|
76
93
|
| Complex logic | "if/else", "conditional", "depends on", multiple "and" clauses |
|
|
@@ -78,16 +95,19 @@ Scan the user's description for these patterns:
|
|
|
78
95
|
| Architectural changes | "refactor", "restructure", "new system" |
|
|
79
96
|
|
|
80
97
|
❌ **Route back to request-routing if ANY complexity signal detected:**
|
|
98
|
+
- Any new behavior (even "small" behavior like a spinner or tooltip)
|
|
99
|
+
- Any state management (loading, toggle, hover, selection)
|
|
81
100
|
- New database tables/columns needed
|
|
82
101
|
- New API endpoints required
|
|
83
102
|
- Complex conditional logic
|
|
84
103
|
- Multiple interconnected changes
|
|
85
104
|
- Need for error handling design
|
|
86
105
|
|
|
87
|
-
✅ **Continue if the change is:**
|
|
106
|
+
✅ **Continue ONLY if the change is:**
|
|
107
|
+
- Purely cosmetic (text, color, spacing, static visual appearance)
|
|
88
108
|
- Single file or 2-3 related files
|
|
89
|
-
- Modifying existing
|
|
90
|
-
-
|
|
109
|
+
- Modifying existing static values (not adding logic)
|
|
110
|
+
- Zero new behavior, zero new state
|
|
91
111
|
- No architectural decisions needed
|
|
92
112
|
|
|
93
113
|
**If too complex:**
|
|
@@ -309,11 +329,8 @@ Need help? Run: git status (in worktree) to see conflict status
|
|
|
309
329
|
|
|
310
330
|
Do NOT attempt to auto-resolve conflicts - let the user handle them manually.
|
|
311
331
|
|
|
312
|
-
**
|
|
313
|
-
|
|
314
|
-
```bash
|
|
315
|
-
jettypod work status <feature-id> done
|
|
316
|
-
```
|
|
332
|
+
**The merge command automatically sets the feature as ready for review.**
|
|
333
|
+
It will appear with accept/reject buttons on the kanban board. Do NOT call `jettypod work status <feature-id> done` — that bypasses the review gate.
|
|
317
334
|
|
|
318
335
|
**Emit gate signal:**
|
|
319
336
|
|
|
@@ -367,6 +384,5 @@ jettypod work merge <chore-id> # Bash call 2
|
|
|
367
384
|
# Cleanup
|
|
368
385
|
jettypod work cleanup <chore-id>
|
|
369
386
|
|
|
370
|
-
#
|
|
371
|
-
jettypod work status <feature-id> done
|
|
387
|
+
# ⚠️ Do NOT mark feature done manually — merge sets the review gate automatically
|
|
372
388
|
```
|