jettypod 3.0.2 → 4.0.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.
@@ -142,7 +142,7 @@ function getTree(includeCompleted = false) {
142
142
 
143
143
  resolve(rootItems);
144
144
  } catch (err) {
145
- reject(new Error(`Failed to build work tree: ${err.message}`));
145
+ reject(new Error(`Failed to build backlog: ${err.message}`));
146
146
  }
147
147
  });
148
148
  });
@@ -499,7 +499,7 @@ function showItem(id) {
499
499
  console.log(`\n⚠️ DISCOVERY REQUIRED: This epic needs architectural decisions`);
500
500
  console.log(``);
501
501
  console.log(` 💬 Talk to Claude Code: "Let's do epic discovery for #${row.id}"`);
502
- console.log(` Or run: jettypod work epic-discover ${row.id}`);
502
+ console.log(` Or run: jettypod work epic-planning ${row.id}`);
503
503
  console.log(``);
504
504
  console.log(` Claude Code will guide you through:`);
505
505
  console.log(` • Suggesting 3 architectural options`);
@@ -611,7 +611,7 @@ async function main() {
611
611
  console.log(' • Identify architectural decisions (if needed)');
612
612
  console.log(' • Create features automatically');
613
613
  console.log('');
614
- console.log('Or run: jettypod work epic-discover ' + newId);
614
+ console.log('Or run: jettypod work epic-planning ' + newId);
615
615
  console.log('');
616
616
  console.log('💡 You can also plan later when ready');
617
617
  }
@@ -630,7 +630,7 @@ async function main() {
630
630
  console.log('Ask Claude Code:');
631
631
  console.log(` "Help me plan epic #${parentId}"`);
632
632
  console.log('');
633
- console.log(`Or run: jettypod work epic-discover ${parentId}`);
633
+ console.log(`Or run: jettypod work epic-planning ${parentId}`);
634
634
  }
635
635
  });
636
636
  }
@@ -756,13 +756,176 @@ async function main() {
756
756
  console.log('Legend: ⊕ = collapsed ⊖ = expanded');
757
757
  console.log('');
758
758
  console.log('Commands:');
759
- console.log(' jettypod work tree --expand=1 Show details for item #1');
760
- console.log(' jettypod work tree --expand=1,2,3 Show details for multiple items');
761
- console.log(' jettypod work tree --expand-all Show all details');
762
- console.log(' jettypod work tree Collapse all (default)');
759
+ console.log(' jettypod backlog --expand=1 Show details for item #1');
760
+ console.log(' jettypod backlog --expand=1,2,3 Show details for multiple items');
761
+ console.log(' jettypod backlog --expand-all Show all details');
762
+ console.log(' jettypod backlog Collapse all (default)');
763
763
  console.log('');
764
764
  } catch (err) {
765
- console.error(`Error displaying work tree: ${err.message}`);
765
+ console.error(`Error displaying backlog: ${err.message}`);
766
+ process.exit(1);
767
+ }
768
+ break;
769
+ }
770
+
771
+ case 'backlog': {
772
+ try {
773
+ const filter = args[0]; // undefined, 'all', or 'completed'
774
+
775
+ // For 'all' and 'completed' filters, use old simple display
776
+ if (filter === 'all' || filter === 'completed') {
777
+ let items;
778
+ if (filter === 'all') {
779
+ items = await getTree(true);
780
+ } else {
781
+ items = await new Promise((resolve, reject) => {
782
+ db.all(`SELECT * FROM work_items WHERE status IN ('done', 'cancelled') ORDER BY parent_id, id`, [], (err, rows) => {
783
+ if (err) {
784
+ return reject(new Error(`Failed to fetch completed items: ${err.message}`));
785
+ }
786
+
787
+ if (!rows || rows.length === 0) {
788
+ return resolve([]);
789
+ }
790
+
791
+ const itemsById = {};
792
+ const rootItems = [];
793
+
794
+ rows.forEach(item => {
795
+ itemsById[item.id] = item;
796
+ item.children = [];
797
+ });
798
+
799
+ rows.forEach(item => {
800
+ if (item.parent_id && itemsById[item.parent_id]) {
801
+ itemsById[item.parent_id].children.push(item);
802
+ } else if (!item.parent_id) {
803
+ rootItems.push(item);
804
+ }
805
+ });
806
+
807
+ resolve(rootItems);
808
+ });
809
+ });
810
+ }
811
+
812
+ if (items.length === 0) {
813
+ console.log('No items found.');
814
+ } else {
815
+ const expandedIds = new Set();
816
+ items.forEach(item => {
817
+ if (item.type === 'epic') {
818
+ expandedIds.add(item.id);
819
+ }
820
+ });
821
+ printTree(items, '', true, expandedIds);
822
+ }
823
+ console.log('');
824
+ } else {
825
+ // Default: show three-section view (active work, recently completed, backlog)
826
+ const currentWork = getCurrentWork();
827
+
828
+ // Show active work at top if exists
829
+ if (currentWork) {
830
+ const emoji = TYPE_EMOJIS[currentWork.type] || '📋';
831
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
832
+ console.log('🎯 ACTIVE WORK');
833
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
834
+ console.log(`${emoji} [#${currentWork.id}] ${currentWork.title}`);
835
+ if (currentWork.epic_title && currentWork.epic_id !== currentWork.id && currentWork.parent_id === currentWork.epic_id) {
836
+ console.log(`└─ Epic: 🎯 #${currentWork.epic_id} ${currentWork.epic_title}`);
837
+ } else if (currentWork.parent_title) {
838
+ const parentEmoji = TYPE_EMOJIS[currentWork.parent_type] || '📋';
839
+ console.log(`└─ Part of: ${parentEmoji} #${currentWork.parent_id} ${currentWork.parent_title}`);
840
+ } else if (currentWork.epic_title && currentWork.epic_id !== currentWork.id) {
841
+ console.log(`└─ Epic: 🎯 #${currentWork.epic_id} ${currentWork.epic_title}`);
842
+ }
843
+ console.log('');
844
+ }
845
+
846
+ // Show recently completed items
847
+ const recentlyCompleted = await new Promise((resolve, reject) => {
848
+ db.all(`
849
+ SELECT w.id, w.title, w.type, w.mode,
850
+ p.title as parent_title, p.id as parent_id, p.type as parent_type
851
+ FROM work_items w
852
+ LEFT JOIN work_items p ON w.parent_id = p.id
853
+ WHERE w.status = 'done'
854
+ ORDER BY w.id DESC
855
+ LIMIT 3
856
+ `, [], async (err, rows) => {
857
+ if (err) reject(err);
858
+ else {
859
+ // Add epic info to each item
860
+ for (const row of rows || []) {
861
+ const epic = await findEpic(row.id);
862
+ if (epic) {
863
+ row.epic_id = epic.id;
864
+ row.epic_title = epic.title;
865
+ }
866
+ }
867
+ resolve(rows || []);
868
+ }
869
+ });
870
+ });
871
+
872
+ if (recentlyCompleted.length > 0) {
873
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
874
+ console.log('✅ RECENTLY COMPLETED');
875
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
876
+ recentlyCompleted.forEach(item => {
877
+ const emoji = TYPE_EMOJIS[item.type] || '📋';
878
+ let modeIndicator = '';
879
+ if (item.type === 'feature') {
880
+ if (item.phase === 'discovery') {
881
+ modeIndicator = ' [🔍 discovery]';
882
+ } else if (item.mode) {
883
+ modeIndicator = ` [${item.mode}]`;
884
+ }
885
+ } else if (item.mode) {
886
+ modeIndicator = ` [${item.mode}]`;
887
+ }
888
+ console.log(`${emoji} [${item.id}] ${item.title}${modeIndicator}`);
889
+ if (item.epic_title && item.epic_id !== item.id && item.parent_id === item.epic_id) {
890
+ console.log(` └─ Epic: 🎯 #${item.epic_id} ${item.epic_title}`);
891
+ } else if (item.parent_title) {
892
+ const parentEmoji = TYPE_EMOJIS[item.parent_type] || '📋';
893
+ console.log(` └─ Part of: ${parentEmoji} #${item.parent_id} ${item.parent_title}`);
894
+ } else if (item.epic_title && item.epic_id !== item.id) {
895
+ console.log(` └─ Epic: 🎯 #${item.epic_id} ${item.epic_title}`);
896
+ }
897
+ });
898
+ console.log('');
899
+ }
900
+
901
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
902
+ console.log('📋 BACKLOG');
903
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
904
+ const items = await getTree(false);
905
+
906
+ // Default: auto-expand all epics
907
+ const expandedIds = new Set();
908
+ items.forEach(item => {
909
+ if (item.type === 'epic') {
910
+ expandedIds.add(item.id);
911
+ }
912
+ });
913
+
914
+ printTree(items, '', true, expandedIds);
915
+
916
+ // Show legend and commands
917
+ console.log('');
918
+ console.log('Legend: ⊕ = collapsed ⊖ = expanded');
919
+ console.log('');
920
+ console.log('Commands:');
921
+ console.log(' jettypod backlog --expand=1 Show details for item #1');
922
+ console.log(' jettypod backlog --expand=1,2,3 Show details for multiple items');
923
+ console.log(' jettypod backlog --expand-all Show all details');
924
+ console.log(' jettypod backlog Collapse all (default)');
925
+ console.log('');
926
+ }
927
+ } catch (err) {
928
+ console.error(`Error displaying backlog: ${err.message}`);
766
929
  process.exit(1);
767
930
  }
768
931
  break;
@@ -809,7 +972,7 @@ async function main() {
809
972
  console.log('Example:');
810
973
  console.log(' jettypod work show 5');
811
974
  console.log('');
812
- console.log('💡 Tip: Use `jettypod work tree` to see all work items');
975
+ console.log('💡 Tip: Use `jettypod backlog` to see all work items');
813
976
  process.exit(1);
814
977
  }
815
978
 
@@ -967,12 +1130,12 @@ async function main() {
967
1130
  break;
968
1131
  }
969
1132
 
970
- case 'epic-discover': {
1133
+ case 'epic-planning': {
971
1134
  const epicId = parseInt(args[0]);
972
1135
 
973
1136
  if (!epicId || isNaN(epicId)) {
974
1137
  console.error('Error: Epic ID is required');
975
- console.log('Usage: jettypod work epic-discover <epic-id>');
1138
+ console.log('Usage: jettypod work epic-planning <epic-id>');
976
1139
  process.exit(1);
977
1140
  }
978
1141
 
@@ -1038,13 +1201,13 @@ async function main() {
1038
1201
  console.log('💬 Now ask Claude Code:');
1039
1202
  console.log(` "Help me with epic discovery for #${epicId}"`);
1040
1203
  console.log('');
1041
- console.log('Claude will use the epic-discover skill to guide you through:');
1204
+ console.log('Claude will use the epic-planning skill to guide you through:');
1042
1205
  console.log(' 1. Feature brainstorming');
1043
1206
  console.log(' 2. Architectural decisions (if needed)');
1044
1207
  console.log(' 3. Prototype validation (optional)');
1045
1208
  console.log(' 4. Feature creation');
1046
1209
  console.log('');
1047
- console.log('📋 The skill is at: .claude/skills/epic-discover/SKILL.md');
1210
+ console.log('📋 The skill is at: .claude/skills/epic-planning/SKILL.md');
1048
1211
  }
1049
1212
  );
1050
1213
  });
@@ -1220,13 +1383,14 @@ async function main() {
1220
1383
 
1221
1384
  if (!featureId || isNaN(featureId)) {
1222
1385
  console.error('Error: Feature ID is required');
1223
- console.log('Usage: jettypod work implement <feature-id> [--prototypes="file1,file2"] [--winner="file.js"]');
1386
+ console.log('Usage: jettypod work implement <feature-id> [--prototypes="file1,file2"] [--winner="file.js"] [--rationale="why this approach"]');
1224
1387
  process.exit(1);
1225
1388
  }
1226
1389
 
1227
- // Parse optional --prototypes and --winner flags
1390
+ // Parse optional --prototypes, --winner, and --rationale flags
1228
1391
  const prototypesIndex = args.findIndex(a => a.startsWith('--prototypes='));
1229
1392
  const winnerIndex = args.findIndex(a => a.startsWith('--winner='));
1393
+ const rationaleIndex = args.findIndex(a => a.startsWith('--rationale='));
1230
1394
 
1231
1395
  const prototypes = prototypesIndex !== -1
1232
1396
  ? args[prototypesIndex].split('=')[1].replace(/^["']|["']$/g, '').split(',').map(p => p.trim())
@@ -1234,6 +1398,9 @@ async function main() {
1234
1398
  const winner = winnerIndex !== -1
1235
1399
  ? args[winnerIndex].split('=')[1].replace(/^["']|["']$/g, '')
1236
1400
  : null;
1401
+ const rationale = rationaleIndex !== -1
1402
+ ? args[rationaleIndex].split('=')[1].replace(/^["']|["']$/g, '')
1403
+ : null;
1237
1404
 
1238
1405
  db.get(`SELECT * FROM work_items WHERE id = ?`, [featureId], (err, feature) => {
1239
1406
  if (err) {
@@ -1254,21 +1421,14 @@ async function main() {
1254
1421
  process.exit(1);
1255
1422
  }
1256
1423
 
1257
- if (feature.phase !== 'discovery') {
1258
- console.error(`Error: Feature #${featureId} is not in discovery phase (current phase: ${feature.phase || 'implementation'})`);
1259
- console.log('');
1260
- console.log('Features can only be transitioned to implementation from discovery phase.');
1261
- process.exit(1);
1262
- }
1263
-
1264
- // Validate that BDD scenarios exist before transitioning
1424
+ // Validate that BDD scenarios exist
1265
1425
  if (!feature.scenario_file) {
1266
1426
  console.error(`Error: Feature #${featureId} has no BDD scenarios`);
1267
1427
  console.log('');
1268
1428
  console.log('Discovery is not complete without BDD scenarios.');
1269
1429
  console.log('');
1270
1430
  console.log('To complete discovery:');
1271
- console.log(' 1. Generate scenarios using feature-discover skill');
1431
+ console.log(' 1. Generate scenarios using feature-planning skill');
1272
1432
  console.log(' 2. Or manually create scenarios at features/[feature-name].feature');
1273
1433
  console.log(' 3. Then run: jettypod work implement');
1274
1434
  console.log('');
@@ -1294,13 +1454,30 @@ async function main() {
1294
1454
  process.exit(1);
1295
1455
  }
1296
1456
 
1297
- // Transition to implementation phase, set mode to speed
1457
+ // Determine if this is a transition or an update
1458
+ const isTransition = feature.phase === 'discovery';
1459
+ const isUpdate = feature.phase === 'implementation';
1460
+
1461
+ if (!isTransition && !isUpdate) {
1462
+ console.error(`Error: Feature #${featureId} has invalid phase: ${feature.phase}`);
1463
+ console.log('');
1464
+ console.log('Expected phase to be either "discovery" or "implementation"');
1465
+ process.exit(1);
1466
+ }
1467
+
1468
+ // Prepare values
1298
1469
  const prototypeFilesValue = prototypes.length > 0 ? JSON.stringify(prototypes) : null;
1299
1470
  const winnerValue = winner || null;
1471
+ const rationaleValue = rationale || null;
1472
+
1473
+ // Update query: if transitioning, set phase and mode; if updating, just update decision fields
1474
+ const updateSql = isTransition
1475
+ ? `UPDATE work_items SET phase = 'implementation', mode = 'speed', prototype_files = ?, discovery_winner = ?, discovery_rationale = ? WHERE id = ?`
1476
+ : `UPDATE work_items SET prototype_files = ?, discovery_winner = ?, discovery_rationale = ? WHERE id = ?`;
1300
1477
 
1301
1478
  db.run(
1302
- `UPDATE work_items SET phase = 'implementation', mode = 'speed', prototype_files = ?, discovery_winner = ? WHERE id = ?`,
1303
- [prototypeFilesValue, winnerValue, featureId],
1479
+ updateSql,
1480
+ [prototypeFilesValue, winnerValue, rationaleValue, featureId],
1304
1481
  (err) => {
1305
1482
  if (err) {
1306
1483
  console.error(`Error: ${err.message}`);
@@ -1309,7 +1486,11 @@ async function main() {
1309
1486
 
1310
1487
  console.log('');
1311
1488
  console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
1312
- console.log(`✅ Feature #${featureId} transitioned to Implementation Phase`);
1489
+ if (isTransition) {
1490
+ console.log(`✅ Feature #${featureId} transitioned to Implementation Phase`);
1491
+ } else {
1492
+ console.log(`✅ Feature #${featureId} discovery decision updated`);
1493
+ }
1313
1494
  console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
1314
1495
  console.log('');
1315
1496
  console.log(`Title: ${feature.title}`);
@@ -1321,6 +1502,9 @@ async function main() {
1321
1502
  if (winner) {
1322
1503
  console.log(`Winner: ${winner}`);
1323
1504
  }
1505
+ if (rationale) {
1506
+ console.log(`Rationale: ${rationale}`);
1507
+ }
1324
1508
  console.log('');
1325
1509
  console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
1326
1510
  console.log('🚀 Speed Mode: Prove It Works');
@@ -1414,14 +1598,14 @@ async function main() {
1414
1598
  console.log('💬 Now ask Claude Code:');
1415
1599
  console.log(` "Help me with feature discovery for #${featureId}"`);
1416
1600
  console.log('');
1417
- console.log('Claude will use the feature-discover skill to guide you through:');
1601
+ console.log('Claude will use the feature-planning skill to guide you through:');
1418
1602
  console.log(' 1. Suggesting 3 UX approaches');
1419
1603
  console.log(' 2. Optional prototyping');
1420
1604
  console.log(' 3. Choosing the winner');
1421
1605
  console.log(' 4. Generating BDD scenarios');
1422
1606
  console.log(' 5. Transitioning to implementation');
1423
1607
  console.log('');
1424
- console.log('📋 The skill is at: .claude/skills/feature-discover/SKILL.md');
1608
+ console.log('📋 The skill is at: .claude/skills/feature-planning/SKILL.md');
1425
1609
  }
1426
1610
  );
1427
1611
  } else {
@@ -1439,14 +1623,14 @@ async function main() {
1439
1623
  console.log('💬 Now ask Claude Code:');
1440
1624
  console.log(` "Help me with feature discovery for #${featureId}"`);
1441
1625
  console.log('');
1442
- console.log('Claude will use the feature-discover skill to guide you through:');
1626
+ console.log('Claude will use the feature-planning skill to guide you through:');
1443
1627
  console.log(' 1. Suggesting 3 UX approaches');
1444
1628
  console.log(' 2. Optional prototyping');
1445
1629
  console.log(' 3. Choosing the winner');
1446
1630
  console.log(' 4. Generating BDD scenarios');
1447
1631
  console.log(' 5. Transitioning to implementation');
1448
1632
  console.log('');
1449
- console.log('📋 The skill is at: .claude/skills/feature-discover/SKILL.md');
1633
+ console.log('📋 The skill is at: .claude/skills/feature-planning/SKILL.md');
1450
1634
  }
1451
1635
  });
1452
1636
  });
@@ -1461,11 +1645,9 @@ Commands:
1461
1645
  jettypod work create <type> <title> [desc] [--parent=ID]
1462
1646
  Types: epic, feature, bug, chore
1463
1647
 
1464
- jettypod work tree
1465
- Show hierarchical view (active items only)
1466
-
1467
- jettypod work completed
1468
- Show all completed work items
1648
+ jettypod backlog [filter]
1649
+ Show work items (active by default)
1650
+ Filters: all, completed
1469
1651
 
1470
1652
  jettypod work show <id>
1471
1653
  Show work item details
@@ -82,7 +82,7 @@ Feature: Mode defaults to discovery on work item creation
82
82
  And I create a feature "Speed Feature" with mode "speed" and parent epic
83
83
  And I create a bug "Stable Bug" with mode "stable" and parent epic
84
84
  And I create a chore "Test Chore" without mode and parent epic
85
- When I view the work tree
85
+ When I view the backlog
86
86
  Then I see the epic without mode indicator
87
87
  And I see the feature with mode "speed"
88
88
  And I see the bug with mode "stable"
package/jettypod.js CHANGED
@@ -138,7 +138,7 @@ Status: ${currentWork.status}
138
138
  Use JettyPod commands to track work:
139
139
  - jettypod work create <type> <title> [desc] [--parent=ID]
140
140
  - jettypod work start <id>
141
- - jettypod work tree
141
+ - jettypod backlog
142
142
  - jettypod decisions (view architectural and technical decisions)
143
143
 
144
144
  EPIC DISCOVERY DETECTION:
@@ -194,7 +194,7 @@ CONFIRMATION REQUIRED BEFORE TRANSITION:
194
194
  When user expresses intent to: prepare for production, launch to customers, accept external users, go live, deploy publicly, make it production-ready, or similar - you MUST:
195
195
 
196
196
  1. **STOP - First, check what will be created**:
197
- - Run \`jettypod work tree\` to count stable mode features
197
+ - Run \`jettypod backlog\` to count stable mode features
198
198
  - Each stable feature will get 3 production chores (Security, Scale, Compliance)
199
199
 
200
200
  2. **Ask for confirmation with specific impact**:
@@ -476,7 +476,7 @@ This splits your terminal so you can see both at once:
476
476
  │ terminal │ terminal │
477
477
  └────────────┴────────────┘
478
478
 
479
- In the right terminal, type \`jettypod work tree\` and press Enter - you'll see a visual tree of all your work."
479
+ In the right terminal, type \`jettypod backlog\` and press Enter - you'll see a visual tree of all your work."
480
480
 
481
481
  **CRITICAL: After creating all epics, save checkpoint by running:**
482
482
  try {
@@ -577,8 +577,8 @@ I'll help you:
577
577
 
578
578
  **Which epic should we start with?**"
579
579
 
580
- **CRITICAL: After user picks an epic, immediately invoke the epic-discover skill:**
581
- Use the Skill tool to invoke: epic-discover
580
+ **CRITICAL: After user picks an epic, immediately invoke the epic-planning skill:**
581
+ Use the Skill tool to invoke: epic-planning
582
582
 
583
583
  This ensures consistent epic planning workflow. DO NOT manually guide them - let the skill handle it.
584
584
 
@@ -1053,6 +1053,13 @@ switch (command) {
1053
1053
  }
1054
1054
  break;
1055
1055
 
1056
+ case 'backlog':
1057
+ // Backlog viewing - delegates to work tracking module
1058
+ const workTracking = require('./features/work-tracking/index.js');
1059
+ process.argv = ['node', 'work-tracking', 'backlog', ...args];
1060
+ workTracking.main();
1061
+ break;
1062
+
1056
1063
  case 'docs':
1057
1064
  const docsSubcommand = args[0];
1058
1065
 
@@ -1340,7 +1347,7 @@ switch (command) {
1340
1347
  }
1341
1348
 
1342
1349
  console.log(`✅ Created ${choresCreated} chores for external readiness`);
1343
- console.log(`\nRun 'jettypod work tree' to see all items`);
1350
+ console.log(`\nRun 'jettypod backlog' to see all items`);
1344
1351
  console.log(`Run 'jettypod work start <id>' to begin work`);
1345
1352
 
1346
1353
  } catch (err) {
@@ -1508,7 +1515,7 @@ switch (command) {
1508
1515
  console.log(' jettypod work create epic "Your First Epic" "Description"');
1509
1516
  console.log('');
1510
1517
  console.log('Then plan the features for that epic:');
1511
- console.log(' jettypod work epic-discover <epic-id>');
1518
+ console.log(' jettypod work epic-planning <epic-id>');
1512
1519
  console.log('');
1513
1520
  console.log('💡 Tip: Claude Code will help you brainstorm features for each epic');
1514
1521
 
@@ -1576,7 +1583,7 @@ CLAUDE.md has been generated with your current project context.
1576
1583
  Open Claude Code to start working.
1577
1584
 
1578
1585
  Quick commands:
1579
- jettypod work tree Show all work items
1586
+ jettypod backlog Show all work items
1580
1587
  jettypod project info Show project status
1581
1588
  `);
1582
1589
  }
@@ -0,0 +1,24 @@
1
+ // Migration: Add discovery_rationale field for feature discovery decisions
2
+ // Created: 2025-01-06
3
+ // Purpose: Track rationale for UX approach chosen during feature discovery
4
+ // Related: Feature-discover skill - records why an approach was selected
5
+
6
+ module.exports = {
7
+ id: '009-discovery-rationale-field',
8
+ description: 'Add discovery_rationale field for feature discovery decisions',
9
+
10
+ up: (db) => {
11
+ return new Promise((resolve, reject) => {
12
+ db.run(
13
+ `ALTER TABLE work_items ADD COLUMN discovery_rationale TEXT`,
14
+ (err) => {
15
+ if (err && !err.message.includes('duplicate column')) {
16
+ return reject(err);
17
+ }
18
+ console.log('Added discovery_rationale column to work_items');
19
+ resolve();
20
+ }
21
+ );
22
+ });
23
+ }
24
+ };