@hanzlaa/rcode 3.6.1 → 3.6.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hanzlaa/rcode",
3
- "version": "3.6.1",
3
+ "version": "3.6.2",
4
4
  "description": "rcode — the AI team that never forgets. Persistent memory, specialist agents, and slash commands for AI IDEs. Works in Claude Code, Cursor, Gemini, VS Code, and Antigravity.",
5
5
  "main": "cli/index.js",
6
6
  "bin": {
@@ -157,7 +157,7 @@ export function App() {
157
157
  const r = await fetch('/api/state');
158
158
  if (!r.ok) return;
159
159
  const s = await r.json();
160
- if (s.lastScanned !== lastScannedRef.current) await fetchAndRerender();
160
+ if (s && s.lastScanned !== lastScannedRef.current) await fetchAndRerender();
161
161
  } catch { /* ignore */ }
162
162
  }, 30000);
163
163
  return () => clearInterval(id);
@@ -82,6 +82,7 @@ function connectWs(storyId) {
82
82
  ws.onmessage = e => {
83
83
  let m;
84
84
  try { m = JSON.parse(e.data); } catch { return; }
85
+ if (!m) return;
85
86
  if (m.t === 'o' || m.t === 'hist') {
86
87
  if (_term) _term.write(m.d);
87
88
  } else if (m.t === 's') {
@@ -110,6 +110,7 @@ export function orchElapsed(iso) {
110
110
  * @returns {Array<[string, string]>}
111
111
  */
112
112
  export function sprintHints(s) {
113
+ if (!s) return [];
113
114
  const stories = Array.isArray(s.stories) ? s.stories : [];
114
115
  const st = s.status || 'planned';
115
116
  const sid = s.id || '';
@@ -155,6 +156,7 @@ export function sprintHints(s) {
155
156
  * @returns {Array<[string, string]>}
156
157
  */
157
158
  export function phaseHints(p) {
159
+ if (!p) return [];
158
160
  const sps = Array.isArray(p.sprints) ? p.sprints : [];
159
161
  const st = p.status || 'planned';
160
162
  const pid = p.id || '';
@@ -53,7 +53,7 @@ function VelocityBars({ sprints }) {
53
53
 
54
54
  function PhaseDetail({ phase: p, S }) {
55
55
  const sps = Array.isArray(p.sprints) ? p.sprints : [];
56
- const stories = sps.flatMap(s => (Array.isArray(s.stories) ? s.stories : []));
56
+ const stories = sps.flatMap(s => (s && Array.isArray(s.stories) ? s.stories : []));
57
57
  const done = stories.filter(t => t.status === 'done' || t.status === 'completed').length;
58
58
  const running = runningInPhase(p);
59
59
  const hints = phaseHints(p);
@@ -158,7 +158,7 @@ export function PhasesView({ subId }) {
158
158
 
159
159
  const q = filter.toLowerCase();
160
160
  const filtered = q
161
- ? phases.filter(p => p.name.toLowerCase().includes(q) || String(p.id).includes(q))
161
+ ? phases.filter(p => (p.name || '').toLowerCase().includes(q) || String(p.id).includes(q))
162
162
  : phases;
163
163
 
164
164
  return html`
@@ -70,13 +70,13 @@ function PhaseNode({ phase: p, filterQuery, expandSignal }) {
70
70
  if (expandSignal && expandSignal.key > 0) setOpen(expandSignal.open);
71
71
  }, [expandSignal && expandSignal.key]);
72
72
  const sps = p.sprints || [];
73
- const pStories = sps.flatMap(s => s.stories || []);
73
+ const pStories = sps.flatMap(s => (s ? s.stories || [] : []));
74
74
  const pDone = pStories.filter(t => t.status === 'done' || t.status === 'completed').length;
75
75
  const pp = pctNum(pDone, pStories.length);
76
76
  const running = runningInPhase(p);
77
77
 
78
78
  // Filter: hide this node if query doesn't match phase name
79
- if (filterQuery && !p.name.toLowerCase().includes(filterQuery)) return null;
79
+ if (filterQuery && !(p.name || '').toLowerCase().includes(filterQuery)) return null;
80
80
 
81
81
  function handleDblClick(e) {
82
82
  e.stopPropagation();