@hanzlaa/rcode 3.6.1 → 3.6.3

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.
@@ -105,7 +105,7 @@ description: >
105
105
  Sidebar entry — invokes the same workflow as /rihal-${cmdName}.
106
106
  triggers:
107
107
  ${triggers.map((t) => ` - "${t}"`).join('\n')}
108
- user-invocable: true
108
+ user-invocable: false
109
109
  generated: true
110
110
  generated-by: rcode-install-v${version}
111
111
  source: rihal/commands/${cmdName}.md
package/cli/install.js CHANGED
@@ -2051,7 +2051,9 @@ async function installInner(opts) {
2051
2051
  try {
2052
2052
  const { main: generateCommandSkills } = require(path.join(PACKAGE_ROOT, 'cli', 'generate-command-skills.cjs'));
2053
2053
  const stubsDir = path.join(opts.target, '.claude', 'skills');
2054
- const result = generateCommandSkills(PACKAGE_ROOT, stubsDir, readPackageVersion());
2054
+ const result = generateCommandSkills(PACKAGE_ROOT, stubsDir, readPackageVersion(), {
2055
+ skipGlobalDuplicates: true,
2056
+ });
2055
2057
  skillsInstalled += result.generated;
2056
2058
  } catch { /* non-fatal */ }
2057
2059
  console.log('');
package/dist/rcode.js CHANGED
@@ -16722,7 +16722,9 @@ ${BLOCK}`, { mode: 493 });
16722
16722
  try {
16723
16723
  const { main: generateCommandSkills } = require(path2.join(PACKAGE_ROOT2, "cli", "generate-command-skills.cjs"));
16724
16724
  const stubsDir = path2.join(opts.target, ".claude", "skills");
16725
- const result = generateCommandSkills(PACKAGE_ROOT2, stubsDir, readPackageVersion());
16725
+ const result = generateCommandSkills(PACKAGE_ROOT2, stubsDir, readPackageVersion(), {
16726
+ skipGlobalDuplicates: true
16727
+ });
16726
16728
  skillsInstalled2 += result.generated;
16727
16729
  } catch {
16728
16730
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hanzlaa/rcode",
3
- "version": "3.6.1",
3
+ "version": "3.6.3",
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": {
@@ -24,7 +24,7 @@ triggers:
24
24
  - "حقّق في الخطأ"
25
25
  - "أصلح الخطأ"
26
26
  - "تتبّع السبب"
27
- user-invocable: true
27
+ user-invocable: false
28
28
  ---
29
29
  @.rihal/references/karpathy-guidelines.md
30
30
 
@@ -32,7 +32,7 @@ triggers:
32
32
  - "ابحث عن إدخالات قديمة"
33
33
  - "هل بنك الذاكرة سليم"
34
34
  - "أصلح الذاكرة"
35
- user-invocable: true
35
+ user-invocable: false
36
36
  ---
37
37
  @.rihal/references/karpathy-guidelines.md
38
38
 
@@ -17,7 +17,7 @@ triggers:
17
17
  - "compress memory bank"
18
18
  - "memory bank ko compress karo"
19
19
  - "/rcode:memory-distill"
20
- user-invocable: true
20
+ user-invocable: false
21
21
  ---
22
22
  @.rihal/references/karpathy-guidelines.md
23
23
 
@@ -29,7 +29,7 @@ triggers:
29
29
  - "أنشئ بنك الذاكرة"
30
30
  - "ابدأ ذاكرة ريحال"
31
31
  - "إعداد بنك الذاكرة"
32
- user-invocable: true
32
+ user-invocable: false
33
33
  ---
34
34
  @.rihal/references/karpathy-guidelines.md
35
35
 
@@ -30,7 +30,7 @@ triggers:
30
30
  - "تذكّر هذا"
31
31
  - "حدّث بنك الذاكرة"
32
32
  - "سجّل هذا القرار"
33
- user-invocable: true
33
+ user-invocable: false
34
34
  ---
35
35
  @.rihal/references/karpathy-guidelines.md
36
36
 
@@ -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();