@slycode/slycode 0.2.22 → 0.2.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/dist/bridge/api.d.ts +2 -1
  2. package/dist/bridge/api.js +114 -1
  3. package/dist/bridge/api.js.map +1 -1
  4. package/dist/bridge/git-utils.d.ts +9 -0
  5. package/dist/bridge/git-utils.js +49 -0
  6. package/dist/bridge/git-utils.js.map +1 -0
  7. package/dist/bridge/index.js +8 -2
  8. package/dist/bridge/index.js.map +1 -1
  9. package/dist/bridge/response-store.d.ts +46 -0
  10. package/dist/bridge/response-store.js +95 -0
  11. package/dist/bridge/response-store.js.map +1 -0
  12. package/dist/bridge/session-manager.d.ts +33 -1
  13. package/dist/bridge/session-manager.js +185 -2
  14. package/dist/bridge/session-manager.js.map +1 -1
  15. package/dist/bridge/types.d.ts +37 -0
  16. package/dist/data/scaffold-templates/tutorial-project/documentation/kanban.json +1 -1
  17. package/dist/messaging/bridge-client.d.ts +4 -0
  18. package/dist/messaging/bridge-client.js +20 -1
  19. package/dist/messaging/bridge-client.js.map +1 -1
  20. package/dist/messaging/index.js +38 -10
  21. package/dist/messaging/index.js.map +1 -1
  22. package/dist/scripts/kanban.js +448 -2
  23. package/dist/store/actions/checkpoint.md +1 -1
  24. package/dist/store/actions/context.md +1 -1
  25. package/dist/store/actions/create-card.md +1 -1
  26. package/dist/store/actions/deep-design.md +13 -3
  27. package/dist/store/actions/design-requirements.md +11 -1
  28. package/dist/store/actions/explore.md +1 -1
  29. package/dist/store/actions/onboard.md +2 -4
  30. package/dist/store/actions/summarize.md +1 -1
  31. package/dist/store/skills/kanban/SKILL.md +77 -3
  32. package/dist/web/.next/BUILD_ID +1 -1
  33. package/dist/web/.next/app-path-routes-manifest.json +1 -0
  34. package/dist/web/.next/build-manifest.json +2 -2
  35. package/dist/web/.next/prerender-manifest.json +3 -3
  36. package/dist/web/.next/routes-manifest.json +6 -0
  37. package/dist/web/.next/server/app/_global-error.html +2 -2
  38. package/dist/web/.next/server/app/_global-error.rsc +1 -1
  39. package/dist/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  40. package/dist/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  41. package/dist/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  42. package/dist/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  43. package/dist/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  44. package/dist/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  45. package/dist/web/.next/server/app/_not-found.html +1 -1
  46. package/dist/web/.next/server/app/_not-found.rsc +10 -10
  47. package/dist/web/.next/server/app/_not-found.segments/_full.segment.rsc +10 -10
  48. package/dist/web/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  49. package/dist/web/.next/server/app/_not-found.segments/_index.segment.rsc +5 -5
  50. package/dist/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  51. package/dist/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  52. package/dist/web/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  53. package/dist/web/.next/server/app/api/changelog/route/app-paths-manifest.json +3 -0
  54. package/dist/web/.next/server/app/api/changelog/route/build-manifest.json +11 -0
  55. package/dist/web/.next/server/app/api/changelog/route/server-reference-manifest.json +4 -0
  56. package/dist/web/.next/server/app/api/changelog/route.js +7 -0
  57. package/dist/web/.next/server/app/api/changelog/route.js.map +5 -0
  58. package/dist/web/.next/server/app/api/changelog/route.js.nft.json +1 -0
  59. package/dist/web/.next/server/app/api/changelog/route_client-reference-manifest.js +2 -0
  60. package/dist/web/.next/server/app/api/cli-assets/assistant/route.js.nft.json +1 -1
  61. package/dist/web/.next/server/app/api/cli-assets/fix/route.js.nft.json +1 -1
  62. package/dist/web/.next/server/app/api/cli-assets/import/route.js.nft.json +1 -1
  63. package/dist/web/.next/server/app/api/cli-assets/route.js.nft.json +1 -1
  64. package/dist/web/.next/server/app/api/cli-assets/store/preview/route.js.nft.json +1 -1
  65. package/dist/web/.next/server/app/api/cli-assets/store/route.js.nft.json +1 -1
  66. package/dist/web/.next/server/app/api/cli-assets/sync/route.js.nft.json +1 -1
  67. package/dist/web/.next/server/app/api/cli-assets/updates/route.js.nft.json +1 -1
  68. package/dist/web/.next/server/app/api/dashboard/route.js.nft.json +1 -1
  69. package/dist/web/.next/server/app/api/file/route.js.nft.json +1 -1
  70. package/dist/web/.next/server/app/api/git-status/route.js.nft.json +1 -1
  71. package/dist/web/.next/server/app/api/kanban/route.js.nft.json +1 -1
  72. package/dist/web/.next/server/app/api/kanban/stream/route.js.nft.json +1 -1
  73. package/dist/web/.next/server/app/api/projects/[id]/route.js.nft.json +1 -1
  74. package/dist/web/.next/server/app/api/projects/reorder/route.js.nft.json +1 -1
  75. package/dist/web/.next/server/app/api/projects/route.js.nft.json +1 -1
  76. package/dist/web/.next/server/app/api/scheduler/route.js.nft.json +1 -1
  77. package/dist/web/.next/server/app/api/search/route.js.nft.json +1 -1
  78. package/dist/web/.next/server/app/api/sly-actions/invalidate/route.js.nft.json +1 -1
  79. package/dist/web/.next/server/app/api/sly-actions/route.js.nft.json +1 -1
  80. package/dist/web/.next/server/app/api/version-check/route.js.nft.json +1 -1
  81. package/dist/web/.next/server/app/page.js.nft.json +1 -1
  82. package/dist/web/.next/server/app/page_client-reference-manifest.js +1 -1
  83. package/dist/web/.next/server/app/project/[id]/page.js.nft.json +1 -1
  84. package/dist/web/.next/server/app/project/[id]/page_client-reference-manifest.js +1 -1
  85. package/dist/web/.next/server/app-paths-manifest.json +1 -0
  86. package/dist/web/.next/server/chunks/[root-of-the-server]__a259539f._.js +3 -0
  87. package/dist/web/.next/server/chunks/_next-internal_server_app_api_changelog_route_actions_d6e239bf.js +3 -0
  88. package/dist/web/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_18324462.js +1 -1
  89. package/dist/web/.next/server/chunks/src_lib_scheduler_ts_03988e3e._.js +1 -1
  90. package/dist/web/.next/server/chunks/src_lib_scheduler_ts_7120457c._.js +1 -1
  91. package/dist/web/.next/server/chunks/ssr/[root-of-the-server]__1f5fc489._.js +4 -3
  92. package/dist/web/.next/server/chunks/ssr/{[root-of-the-server]__077f472c._.js → [root-of-the-server]__6183d28c._.js} +1 -1
  93. package/dist/web/.next/server/chunks/ssr/[root-of-the-server]__bcbe4bf2._.js +4 -3
  94. package/dist/web/.next/server/chunks/ssr/src_components_Dashboard_tsx_efc4dc27._.js +1 -1
  95. package/dist/web/.next/server/chunks/ssr/src_components_c4135402._.js +1 -1
  96. package/dist/web/.next/server/chunks/ssr/src_contexts_VoiceContext_tsx_cfba7292._.js +1 -1
  97. package/dist/web/.next/server/pages/404.html +1 -1
  98. package/dist/web/.next/server/pages/500.html +2 -2
  99. package/dist/web/.next/server/server-reference-manifest.js +1 -1
  100. package/dist/web/.next/server/server-reference-manifest.json +1 -1
  101. package/dist/web/.next/static/chunks/293449b828207656.css +1 -0
  102. package/dist/web/.next/static/chunks/{f55f3c8c1a52f80c.js → 3859477038c381ad.js} +1 -1
  103. package/dist/web/.next/static/chunks/{8415039c5941cf5c.js → 3a5721af09d1c753.js} +4 -3
  104. package/dist/web/.next/static/chunks/{8fb2a99c64580de7.js → 98311243e9a5a0ec.js} +1 -1
  105. package/dist/web/.next/static/chunks/{b8e0c1aeea4a14bc.js → a47f36b030917d1f.js} +1 -1
  106. package/dist/web/.next/static/chunks/d60c422421920130.js +5 -0
  107. package/dist/web/.next/static/chunks/{4049cceee6a49323.js → fa78afe3ceed998b.js} +1 -1
  108. package/dist/web/src/app/api/changelog/route.ts +45 -0
  109. package/dist/web/src/app/api/kanban/route.ts +52 -12
  110. package/dist/web/src/components/ActivityFeed.tsx +3 -0
  111. package/dist/web/src/components/BranchTab.tsx +115 -0
  112. package/dist/web/src/components/ChangelogModal.tsx +234 -0
  113. package/dist/web/src/components/Dashboard.tsx +11 -0
  114. package/dist/web/src/components/GlobalClaudePanel.tsx +6 -0
  115. package/dist/web/src/components/ProjectKanban.tsx +38 -8
  116. package/dist/web/src/components/VersionUpdateToast.tsx +6 -4
  117. package/dist/web/src/components/VoiceControlBar.tsx +1 -1
  118. package/dist/web/src/lib/scheduler.ts +2 -1
  119. package/dist/web/src/lib/types.ts +24 -0
  120. package/dist/web/tsconfig.tsbuildinfo +1 -1
  121. package/package.json +1 -1
  122. package/templates/changelog.json +242 -0
  123. package/templates/kanban-seed.json +1 -1
  124. package/templates/store/actions/checkpoint.md +1 -1
  125. package/templates/store/actions/context.md +1 -1
  126. package/templates/store/actions/create-card.md +1 -1
  127. package/templates/store/actions/deep-design.md +13 -3
  128. package/templates/store/actions/design-requirements.md +11 -1
  129. package/templates/store/actions/explore.md +1 -1
  130. package/templates/store/actions/onboard.md +2 -4
  131. package/templates/store/actions/summarize.md +1 -1
  132. package/templates/store/skills/kanban/SKILL.md +77 -3
  133. package/templates/tutorial-project/documentation/kanban.json +1 -1
  134. package/templates/updates/actions/checkpoint.md +1 -1
  135. package/templates/updates/actions/context.md +1 -1
  136. package/templates/updates/actions/create-card.md +1 -1
  137. package/templates/updates/actions/deep-design.md +13 -3
  138. package/templates/updates/actions/design-requirements.md +11 -1
  139. package/templates/updates/actions/explore.md +1 -1
  140. package/templates/updates/actions/onboard.md +2 -4
  141. package/templates/updates/actions/summarize.md +1 -1
  142. package/templates/updates/skills/kanban/SKILL.md +77 -3
  143. package/dist/web/.next/static/chunks/18cfbdd7e977bb01.css +0 -1
  144. package/dist/web/.next/static/chunks/a0f5f9cdee8a22c1.js +0 -4
  145. /package/dist/web/.next/static/{b2V8jC3HBMi4vgm7Kie3H → aN-jqftQVvSm0qVskLybH}/_buildManifest.js +0 -0
  146. /package/dist/web/.next/static/{b2V8jC3HBMi4vgm7Kie3H → aN-jqftQVvSm0qVskLybH}/_clientMiddlewareManifest.json +0 -0
  147. /package/dist/web/.next/static/{b2V8jC3HBMi4vgm7Kie3H → aN-jqftQVvSm0qVskLybH}/_ssgManifest.js +0 -0
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { useState, useEffect, useRef, useCallback, useMemo } from 'react';
4
4
  import { useSearchParams, useRouter, usePathname } from 'next/navigation';
5
- import type { ProjectWithBacklog, KanbanCard, KanbanStage, KanbanStages, BridgeStats, Priority } from '@/lib/types';
5
+ import type { ProjectWithBacklog, KanbanCard, KanbanStage, KanbanStages, BridgeStats, Priority, ChangedCard, CardChangeType } from '@/lib/types';
6
6
  import { connectionManager } from '@/lib/connection-manager';
7
7
  import { tabSync } from '@/lib/tab-sync';
8
8
  import { usePolling } from '@/hooks/usePolling';
@@ -85,6 +85,8 @@ export function ProjectKanban({ project, projectPath, showArchived = false, show
85
85
  const [activeCards, setActiveCards] = useState<Set<string>>(new Set());
86
86
  const prevActiveCardsRef = useRef<Set<string>>(new Set());
87
87
  const consumedCardParamRef = useRef<string | null>(null);
88
+ const editedCardIdsRef = useRef<Set<string>>(new Set());
89
+ const movedCardIdsRef = useRef<Set<string>>(new Set());
88
90
 
89
91
  // Context menu state
90
92
  const [contextMenu, setContextMenu] = useState<{ position: { x: number; y: number }; card: KanbanCard; stage: KanbanStage } | null>(null);
@@ -376,8 +378,8 @@ export function ProjectKanban({ project, projectPath, showArchived = false, show
376
378
  setSaveStatus('saving');
377
379
  isSavingRef.current = true;
378
380
  try {
379
- // Compute which cards actually changed vs the clean baseline
380
- const changedCardIds: string[] = [];
381
+ // Compute which cards actually changed vs the clean baseline, with typed changeset
382
+ const changedCards: ChangedCard[] = [];
381
383
  const baselineCards = new Map<string, string>();
382
384
  for (const stage of STAGE_ORDER) {
383
385
  for (const card of cleanBaselineRef.current[stage] || []) {
@@ -389,29 +391,51 @@ export function ProjectKanban({ project, projectPath, showArchived = false, show
389
391
  const baselineKey = baselineCards.get(card.id);
390
392
  const currentKey = JSON.stringify(card) + '|' + stage;
391
393
  if (baselineKey !== currentKey) {
392
- changedCardIds.push(card.id); // New, modified, or moved
394
+ if (editedCardIdsRef.current.has(card.id)) {
395
+ changedCards.push({ id: card.id, type: 'edit' }); // Edit wins over move
396
+ } else if (movedCardIdsRef.current.has(card.id)) {
397
+ changedCards.push({ id: card.id, type: 'move' });
398
+ }
399
+ // Untracked divergence (SSE timing, connection issues, normalizeOrder drift)
400
+ // — skip it. The server merge preserves disk truth for cards not in changedCards.
393
401
  }
394
402
  baselineCards.delete(card.id);
395
403
  }
396
404
  }
397
405
  // Cards in baseline but not in current = deleted
398
406
  for (const deletedId of baselineCards.keys()) {
399
- changedCardIds.push(deletedId);
407
+ changedCards.push({ id: deletedId, type: 'delete' });
400
408
  }
401
409
 
410
+ // Clear tracking refs after building payload
411
+ editedCardIdsRef.current.clear();
412
+ movedCardIdsRef.current.clear();
413
+
402
414
  const res = await fetch('/api/kanban', {
403
415
  method: 'POST',
404
416
  headers: { 'Content-Type': 'application/json' },
405
- body: JSON.stringify({ projectId: project.id, stages: stagesToSave, changedCardIds }),
417
+ body: JSON.stringify({ projectId: project.id, stages: stagesToSave, changedCards }),
406
418
  });
407
419
  if (res.ok) {
408
420
  const data = await res.json();
409
421
  lastSaveTimestampRef.current = data.last_updated;
410
- cleanBaselineRef.current = stagesToSave;
422
+ // Use server's merged+normalized stages as baseline (eliminates normalizeOrder drift)
423
+ const serverStages = data.stages;
424
+ if (serverStages) {
425
+ cleanBaselineRef.current = serverStages;
426
+ // Sync React state with server truth if no new user edits happened during save.
427
+ // Without this, baseline and stages diverge — cards the user never touched appear
428
+ // "changed" in the next save cycle and get reverted to stale frontend positions.
429
+ if (stagesEqual(stagesRef.current, stagesToSave)) {
430
+ setStages(serverStages);
431
+ }
432
+ } else {
433
+ cleanBaselineRef.current = stagesToSave;
434
+ }
411
435
  // Only clear dirty if stages haven't changed during the save.
412
436
  // If the user made edits while the save was in flight, stay dirty
413
437
  // so SSE/polling won't overwrite their pending changes.
414
- isDirtyRef.current = !stagesEqual(stagesRef.current, stagesToSave);
438
+ isDirtyRef.current = !stagesEqual(stagesRef.current, cleanBaselineRef.current);
415
439
  setSaveStatus('saved');
416
440
  // Notify other tabs immediately
417
441
  tabSync.broadcast('kanban-update', project.id);
@@ -544,6 +568,8 @@ export function ProjectKanban({ project, projectPath, showArchived = false, show
544
568
 
545
569
  if (!selectedStage) return;
546
570
 
571
+ editedCardIdsRef.current.add(updatedCard.id);
572
+
547
573
  // Update stages - selectedCard will be automatically derived from the updated stages
548
574
  setStages((prev) => ({
549
575
  ...prev,
@@ -577,6 +603,7 @@ export function ProjectKanban({ project, projectPath, showArchived = false, show
577
603
  };
578
604
 
579
605
  const handleMoveCard = (cardId: string, newStage: KanbanStage, insertIndex?: number) => {
606
+ movedCardIdsRef.current.add(cardId);
580
607
  setStages((prev) => {
581
608
  // Find which stage the card is currently in
582
609
  let sourceStage: KanbanStage | null = null;
@@ -695,6 +722,7 @@ export function ProjectKanban({ project, projectPath, showArchived = false, show
695
722
  checked: p === card.priority,
696
723
  disabled: p === card.priority,
697
724
  onClick: () => {
725
+ editedCardIdsRef.current.add(card.id);
698
726
  setStages((prev) => ({
699
727
  ...prev,
700
728
  [stage]: prev[stage].map((c) =>
@@ -731,6 +759,7 @@ export function ProjectKanban({ project, projectPath, showArchived = false, show
731
759
  disabled: !!card.automation,
732
760
  onClick: () => {
733
761
  if (card.automation) return;
762
+ editedCardIdsRef.current.add(card.id);
734
763
  setStages((prev) => ({
735
764
  ...prev,
736
765
  [stage]: prev[stage].map((c) =>
@@ -767,6 +796,7 @@ export function ProjectKanban({ project, projectPath, showArchived = false, show
767
796
  checked: p === card.priority,
768
797
  disabled: p === card.priority,
769
798
  onClick: () => {
799
+ editedCardIdsRef.current.add(card.id);
770
800
  setStages((prev) => ({
771
801
  ...prev,
772
802
  [stage]: prev[stage].map((c) =>
@@ -53,12 +53,14 @@ export function VersionUpdateToast() {
53
53
  />
54
54
  <span className="text-sm text-void-700 dark:text-void-300">
55
55
  SlyCode <span className="font-medium text-neon-blue-500 dark:text-neon-blue-400">v{info.latest}</span> available
56
- <span className="text-void-500 dark:text-void-400"> (current: v{info.current})</span>
57
56
  </span>
58
57
  </div>
59
- <code className="rounded bg-void-100 px-1.5 py-0.5 text-xs text-void-600 dark:bg-void-800 dark:text-void-400">
60
- slycode update
61
- </code>
58
+ <div className="flex items-center gap-1.5">
59
+ <span className="text-xs text-void-500 dark:text-void-400">run in terminal:</span>
60
+ <code className="rounded bg-void-100 px-1.5 py-0.5 text-xs text-void-600 dark:bg-void-800 dark:text-void-400">
61
+ slycode update
62
+ </code>
63
+ </div>
62
64
  <button
63
65
  onClick={handleDismiss}
64
66
  className="ml-1 rounded p-0.5 text-void-400 transition-colors hover:bg-void-200 hover:text-void-600 dark:text-void-500 dark:hover:bg-void-800 dark:hover:text-void-300"
@@ -45,7 +45,7 @@ export function VoiceControlBar({
45
45
  onClick={onRecord}
46
46
  disabled={disabled}
47
47
  className="rounded-md border border-void-400/30 bg-void-200/50 p-1.5 text-void-500 transition-all hover:border-red-400/40 hover:bg-red-400/10 hover:text-red-400 disabled:opacity-50 dark:border-void-500/25 dark:bg-void-700/50 dark:text-void-400 dark:hover:border-red-400/40 dark:hover:bg-red-400/10 dark:hover:text-red-400"
48
- title="Start recording (Ctrl+.)"
48
+ title="Start recording [Ctrl+.]"
49
49
  >
50
50
  <svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
51
51
  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m0 0H8m4 0h4m-4-8a3 3 0 01-3-3V5a3 3 0 116 0v6a3 3 0 01-3 3z" />
@@ -666,7 +666,8 @@ async function checkAutomations(): Promise<void> {
666
666
  result.error.includes('Session create failed') ||
667
667
  result.error.includes('Session stopped') ||
668
668
  result.error.includes('Input failed') ||
669
- result.error.includes('No automation config')
669
+ result.error.includes('No automation config') ||
670
+ result.error.includes('No activity detected')
670
671
  );
671
672
  if (isHardFailure) {
672
673
  await sendErrorNotification(card.title, result.error || 'Unknown error', result.sessionName);
@@ -128,6 +128,13 @@ export interface KanbanStages {
128
128
  done: KanbanCard[];
129
129
  }
130
130
 
131
+ export type CardChangeType = 'move' | 'edit' | 'create' | 'delete';
132
+
133
+ export interface ChangedCard {
134
+ id: string;
135
+ type: CardChangeType;
136
+ }
137
+
131
138
  export interface KanbanBoard {
132
139
  project_id: string;
133
140
  stages: KanbanStages;
@@ -163,6 +170,23 @@ export interface FeatureEntry {
163
170
  projectId?: string;
164
171
  }
165
172
 
173
+ // ============================================================================
174
+ // Changelog Types
175
+ // ============================================================================
176
+
177
+ export type ChangelogChangeType = 'feature' | 'bugfix' | 'improvement' | 'chore';
178
+
179
+ export interface ChangelogChange {
180
+ type: ChangelogChangeType;
181
+ description: string;
182
+ }
183
+
184
+ export interface ChangelogVersion {
185
+ version: string;
186
+ date: string; // YYYY-MM-DD
187
+ changes: ChangelogChange[];
188
+ }
189
+
166
190
  // ============================================================================
167
191
  // Questionnaire Types (per design doc section 3.3)
168
192
  // ============================================================================