@hanzlaa/rcode 3.4.32 → 3.4.33
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/cli/agent.js +3 -2
- package/dist/rcode.js +2 -1
- package/package.json +1 -1
- package/rihal/agents/rihal-cross-platform-auditor.md +15 -0
- package/rihal/agents/rihal-dep-auditor.md +15 -0
- package/rihal/agents/rihal-i18n-auditor.md +16 -0
- package/rihal/agents/rihal-observability-auditor.md +16 -0
- package/rihal/agents/rihal-phase-researcher.md +1 -1
- package/rihal/agents/rihal-planner.md +1 -1
- package/rihal/skills/actions/4-implementation/rihal-code-review/steps/step-02-review.md +7 -3
- package/rihal/skills/agents/majlis-council/SKILL.md +1 -1
- package/rihal/team.yaml +32 -0
- package/server/dashboard.js +1 -1
- package/server/lib/api.js +7 -0
- package/server/lib/html/client.js +2 -2
package/cli/agent.js
CHANGED
|
@@ -39,8 +39,9 @@ module.exports = function agent(args, { packageRoot }) {
|
|
|
39
39
|
process.exit(1);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
// Check claude binary is on PATH
|
|
43
|
-
const
|
|
42
|
+
// Check claude binary is on PATH (cross-platform: 'where' on Windows, 'which' elsewhere)
|
|
43
|
+
const whichCmd = process.platform === 'win32' ? 'where' : 'which';
|
|
44
|
+
const claudeCheck = spawnSync(whichCmd, ['claude'], { encoding: 'utf8' });
|
|
44
45
|
if (claudeCheck.status !== 0) {
|
|
45
46
|
console.error('Error: claude binary not found. Install Claude Code: https://claude.ai/code');
|
|
46
47
|
process.exit(1);
|
package/dist/rcode.js
CHANGED
|
@@ -18904,7 +18904,8 @@ var require_agent = __commonJS({
|
|
|
18904
18904
|
console.error(`Available: ${available}`);
|
|
18905
18905
|
process.exit(1);
|
|
18906
18906
|
}
|
|
18907
|
-
const
|
|
18907
|
+
const whichCmd = process.platform === "win32" ? "where" : "which";
|
|
18908
|
+
const claudeCheck = spawnSync(whichCmd, ["claude"], { encoding: "utf8" });
|
|
18908
18909
|
if (claudeCheck.status !== 0) {
|
|
18909
18910
|
console.error("Error: claude binary not found. Install Claude Code: https://claude.ai/code");
|
|
18910
18911
|
process.exit(1);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hanzlaa/rcode",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.33",
|
|
4
4
|
"description": "rcode — the memory bank for AI-driven SaaS teams. Persistent project context, distinctive engineering personas, and phase-based workflows. Built by Rihal. Works in Claude Code, Cursor, Gemini, VS Code, and Antigravity.",
|
|
5
5
|
"main": "cli/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rihal-cross-platform-auditor
|
|
3
|
+
description: |
|
|
4
|
+
Cross-platform portability auditor. Detects bash-isms, macOS-only flags
|
|
5
|
+
(BSD sed/awk), hardcoded absolute Unix paths in Node code, Windows path
|
|
6
|
+
separators, and CRLF line endings. Audit-only — never modifies scripts.
|
|
7
|
+
Activates: "cross-platform audit", "bash-isms", "macOS only",
|
|
8
|
+
"Windows compatibility", "portability check".
|
|
9
|
+
Do NOT use for: fixing scripts, frontend RTL, or translation.
|
|
10
|
+
tools: Read, Bash, Grep, Glob
|
|
11
|
+
color: yellow
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
@.rihal/references/response-style.md
|
|
15
|
+
@.rihal/skills/agents/rihal-cross-platform-auditor/SKILL.md
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rihal-dep-auditor
|
|
3
|
+
description: |
|
|
4
|
+
Dependency health auditor — scans for outdated packages, CVEs, unused
|
|
5
|
+
dependencies, loose version pins, and missing lock files. Audit-only:
|
|
6
|
+
never modifies package.json or runs installs.
|
|
7
|
+
Activates: "audit dependencies", "dep health", "CVE scan", "check packages",
|
|
8
|
+
"outdated deps", "loose pins", "lock file".
|
|
9
|
+
Do NOT use for: installing packages, updating deps, or security penetration testing.
|
|
10
|
+
tools: Read, Bash, Grep, Glob
|
|
11
|
+
color: yellow
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
@.rihal/references/response-style.md
|
|
15
|
+
@.rihal/skills/agents/rihal-dep-auditor/SKILL.md
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rihal-i18n-auditor
|
|
3
|
+
description: |
|
|
4
|
+
Internationalization and localization auditor. Detects hardcoded English
|
|
5
|
+
strings in workflow output, missing response_language pass-through to
|
|
6
|
+
subagents, AskUserQuestion with English-only prompts, and RTL/Arabic
|
|
7
|
+
layout gaps. Audit-only — never modifies string files.
|
|
8
|
+
Activates: "i18n audit", "translation check", "hardcoded strings",
|
|
9
|
+
"response_language missing", "RTL audit", "Arabic layout", "multilingual audit".
|
|
10
|
+
Do NOT use for: adding translations, RTL CSS (use rihal-haitham), content translation.
|
|
11
|
+
tools: Read, Bash, Grep, Glob
|
|
12
|
+
color: yellow
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
@.rihal/references/response-style.md
|
|
16
|
+
@.rihal/skills/agents/rihal-i18n-auditor/SKILL.md
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rihal-observability-auditor
|
|
3
|
+
description: |
|
|
4
|
+
Observability and silent-failure auditor. Detects unguarded rihal-tools
|
|
5
|
+
shell calls, Task() results that are never checked, bare 2>/dev/null
|
|
6
|
+
without fallback echo, INIT calls without .ok checks, and unstructured
|
|
7
|
+
console.log in production code. Audit-only — never adds instrumentation.
|
|
8
|
+
Activates: "observability audit", "silent failures", "unguarded calls",
|
|
9
|
+
"missing error handling", "tool call guard".
|
|
10
|
+
Do NOT use for: adding logging, instrumentation setup, or fixing error handlers.
|
|
11
|
+
tools: Read, Bash, Grep, Glob
|
|
12
|
+
color: yellow
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
@.rihal/references/response-style.md
|
|
16
|
+
@.rihal/skills/agents/rihal-observability-auditor/SKILL.md
|
|
@@ -8,7 +8,7 @@ color: cyan
|
|
|
8
8
|
|
|
9
9
|
@.rihal/references/response-style.md
|
|
10
10
|
@.rihal/references/karpathy-guidelines.md
|
|
11
|
-
|
|
11
|
+
@.rihal/brain/best-practices/no-theoretical-suggestions.md
|
|
12
12
|
@.rihal/references/researcher-shared.md
|
|
13
13
|
|
|
14
14
|
<role>
|
|
@@ -8,7 +8,7 @@ color: green
|
|
|
8
8
|
@.rihal/references/response-style.md
|
|
9
9
|
@.rihal/references/karpathy-guidelines-full.md
|
|
10
10
|
@.rihal/references/output-realism.md
|
|
11
|
-
|
|
11
|
+
@.rihal/brain/best-practices/no-theoretical-suggestions.md
|
|
12
12
|
@.rihal/references/planner-playbook.md
|
|
13
13
|
|
|
14
14
|
<role>
|
|
@@ -17,11 +17,15 @@ failed_layers: '' # set at runtime: comma-separated list of layers that failed o
|
|
|
17
17
|
|
|
18
18
|
2. Launch parallel subagents without conversation context. If subagents are not available, generate prompt files in `{implementation_artifacts}` — one per reviewer role below — and HALT. Ask the user to run each in a separate session (ideally a different LLM) and paste back the findings. When findings are pasted, resume from this point and proceed to step 3.
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
**Subagent mapping** (issue #720): the three reviewer roles below map to actual agents shipped in `.claude/agents/`. The skill names that used to be referenced here (`rihal-review-adversarial-general`, `rihal-review-edge-case-hunter`) are skills, not subagents, and `Task(subagent_type=...)` cannot reach them. Use the agents listed.
|
|
21
21
|
|
|
22
|
-
- **
|
|
22
|
+
- **Blind Hunter** — receives `{diff_output}` only. No spec, no context docs, no project access. Dispatch:
|
|
23
|
+
`Task(subagent_type="rihal-security-adversary", model="sonnet", prompt="<adversarial review of diff>")`. The security-adversary persona's cynical mindset is the right fit for an isolated diff-only review.
|
|
23
24
|
|
|
24
|
-
- **
|
|
25
|
+
- **Edge Case Hunter** — receives `{diff_output}` and read access to the project. Dispatch:
|
|
26
|
+
`Task(subagent_type="rihal-edge-case-hunter", model="sonnet", prompt="<enumerate edge cases for diff>")`.
|
|
27
|
+
|
|
28
|
+
- **Acceptance Auditor** (only if `{review_mode}` = `"full"`) — receives `{diff_output}`, the content of the file at `{spec_file}`, and any loaded context docs. Dispatch via `rihal-code-reviewer`. Its prompt:
|
|
25
29
|
> You are an Acceptance Auditor. Review this diff against the spec and context docs. Check for: violations of acceptance criteria, deviations from spec intent, missing implementation of specified behavior, contradictions between spec constraints and actual code. Output findings as a Markdown list. Each finding: one-line title, which AC/constraint it violates, and evidence from the diff.
|
|
26
30
|
|
|
27
31
|
3. **Subagent failure handling**: If any subagent fails, times out, or returns empty results, append the layer name to `{failed_layers}` (comma-separated) and proceed with findings from the remaining layers.
|
|
@@ -59,7 +59,7 @@ Majlis (مجلس) is the consulting council. Convenes specialists when a questio
|
|
|
59
59
|
| DM | Decision matrix — walk through a specific choice with pros/cons per agent | `rihal-majlis-decision` |
|
|
60
60
|
| CM | Crisis mode — rapid consultation during an incident | `rihal-majlis-crisis` |
|
|
61
61
|
|
|
62
|
-
##
|
|
62
|
+
## Workflow
|
|
63
63
|
|
|
64
64
|
1. **Frame the question** — restate clearly so every agent answers the same question.
|
|
65
65
|
2. **Determine the council** — identify which agents' domains are relevant (3 minimum, 12 maximum, 3-8 ideal).
|
package/rihal/team.yaml
CHANGED
|
@@ -520,3 +520,35 @@ tactical_agents:
|
|
|
520
520
|
role: Verifier
|
|
521
521
|
authority_level: quality
|
|
522
522
|
description: Verifies phase goal achievement goal-backward
|
|
523
|
+
|
|
524
|
+
- id: rihal-i18n-auditor
|
|
525
|
+
name: i18n Auditor
|
|
526
|
+
file_path: rihal/agents/rihal-i18n-auditor.md
|
|
527
|
+
skill_path: rihal/skills/agents/rihal-i18n-auditor
|
|
528
|
+
role: i18n Auditor
|
|
529
|
+
authority_level: quality
|
|
530
|
+
description: Detects hardcoded English strings, missing response_language threading, and RTL layout gaps
|
|
531
|
+
|
|
532
|
+
- id: rihal-cross-platform-auditor
|
|
533
|
+
name: Cross-Platform Auditor
|
|
534
|
+
file_path: rihal/agents/rihal-cross-platform-auditor.md
|
|
535
|
+
skill_path: rihal/skills/agents/rihal-cross-platform-auditor
|
|
536
|
+
role: Cross-Platform Auditor
|
|
537
|
+
authority_level: quality
|
|
538
|
+
description: Detects bash-isms, macOS-only flags, hardcoded Unix paths, and CRLF line endings
|
|
539
|
+
|
|
540
|
+
- id: rihal-dep-auditor
|
|
541
|
+
name: Dep Auditor
|
|
542
|
+
file_path: rihal/agents/rihal-dep-auditor.md
|
|
543
|
+
skill_path: rihal/skills/agents/rihal-dep-auditor
|
|
544
|
+
role: Dependency Health Auditor
|
|
545
|
+
authority_level: quality
|
|
546
|
+
description: Scans for outdated packages, CVEs, unused dependencies, and loose version pins
|
|
547
|
+
|
|
548
|
+
- id: rihal-observability-auditor
|
|
549
|
+
name: Observability Auditor
|
|
550
|
+
file_path: rihal/agents/rihal-observability-auditor.md
|
|
551
|
+
skill_path: rihal/skills/agents/rihal-observability-auditor
|
|
552
|
+
role: Observability Auditor
|
|
553
|
+
authority_level: quality
|
|
554
|
+
description: Detects unguarded shell calls, unchecked Task() results, and missing INIT .ok checks
|
package/server/dashboard.js
CHANGED
|
@@ -79,7 +79,7 @@ const server = http.createServer((req, res) => {
|
|
|
79
79
|
res.end('Not found');
|
|
80
80
|
});
|
|
81
81
|
|
|
82
|
-
server.listen(PORT, () => {
|
|
82
|
+
server.listen(PORT, '127.0.0.1', () => {
|
|
83
83
|
console.log(`\n🕌 Majlis (مجلس) — Rihal Code Dashboard`);
|
|
84
84
|
console.log(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);
|
|
85
85
|
console.log(` Mode: view-only`);
|
package/server/lib/api.js
CHANGED
|
@@ -132,6 +132,13 @@ function handleApiFile(req, res, projectRoot) {
|
|
|
132
132
|
if (!resolved.startsWith(projectRoot + path.sep) && resolved !== projectRoot) {
|
|
133
133
|
res.writeHead(403); res.end('Forbidden'); return;
|
|
134
134
|
}
|
|
135
|
+
// Dereference symlinks so a symlink outside projectRoot cannot bypass the guard
|
|
136
|
+
let realResolved;
|
|
137
|
+
try { realResolved = fs.realpathSync(resolved); }
|
|
138
|
+
catch { res.writeHead(404); res.end('File not found'); return; }
|
|
139
|
+
if (!realResolved.startsWith(projectRoot + path.sep) && realResolved !== projectRoot) {
|
|
140
|
+
res.writeHead(403); res.end('Forbidden'); return;
|
|
141
|
+
}
|
|
135
142
|
if (!resolved.endsWith('.md')) {
|
|
136
143
|
res.writeHead(403); res.end('Forbidden: only .md files'); return;
|
|
137
144
|
}
|
|
@@ -29,9 +29,9 @@ function chip(s) {
|
|
|
29
29
|
: s === 'blocked' ? 'blocked'
|
|
30
30
|
: s === 'planned' ? 'planned'
|
|
31
31
|
: s === 'todo' ? 'todo' : 'other';
|
|
32
|
-
return '<span class="status-chip ' + c + '">● ' + s + '</span>';
|
|
32
|
+
return '<span class="status-chip ' + c + '">● ' + esc(s) + '</span>';
|
|
33
33
|
}
|
|
34
|
-
function tag(t) { return '<span class="tag">' + t + '</span>'; }
|
|
34
|
+
function tag(t) { return '<span class="tag">' + esc(t) + '</span>'; }
|
|
35
35
|
function esc(s) { return String(s || '').replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"').replace(/'/g,'''); }
|
|
36
36
|
function pct(d, t) { return t > 0 ? Math.round(d/t*100) + '%' : '—'; }
|
|
37
37
|
function pctNum(d, t) { return t > 0 ? Math.round(d/t*100) : 0; }
|