@hanzlaa/rcode 3.4.10 → 3.4.11
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/digest.js +6 -1
- package/cli/index.js +1 -1
- package/cli/lib/fsutil.cjs +1 -1
- package/cli/lib/github.cjs +10 -3
- package/package.json +11 -11
- package/rihal/bin/rihal-tools.cjs +2 -2
- package/rihal/workflows/feature-drift.md +2 -2
- package/rihal/workflows/status.md +4 -1
package/cli/digest.js
CHANGED
|
@@ -12,7 +12,12 @@ const fs = require('fs');
|
|
|
12
12
|
const path = require('path');
|
|
13
13
|
|
|
14
14
|
function normalize(name) {
|
|
15
|
-
|
|
15
|
+
const stripped = name.replace(/^rihal-/, '');
|
|
16
|
+
// Reject path traversal attempts — names must be simple identifiers
|
|
17
|
+
if (stripped.includes('..') || stripped.includes('/') || stripped.includes('\\')) {
|
|
18
|
+
throw new Error(`Invalid agent name: '${name}'`);
|
|
19
|
+
}
|
|
20
|
+
return stripped;
|
|
16
21
|
}
|
|
17
22
|
|
|
18
23
|
function listAvailable(digestDir, agentsDir) {
|
package/cli/index.js
CHANGED
|
@@ -51,7 +51,7 @@ Usage:
|
|
|
51
51
|
|
|
52
52
|
📦 PROJECT
|
|
53
53
|
install Install Rihal Code into the current project
|
|
54
|
-
(sets up .rihal/, .claude/skills/, .claude/commands
|
|
54
|
+
(sets up .rihal/, .claude/skills/, .claude/commands/,
|
|
55
55
|
.cursor/rules/, .windsurf/rules/, .antigravity/agents/, AGENTS.md)
|
|
56
56
|
init Alias for install
|
|
57
57
|
update Refresh skill files (backs up .rihal/ state first)
|
package/cli/lib/fsutil.cjs
CHANGED
|
@@ -43,7 +43,7 @@ function writeFileAtomic(filePath, content, opts = {}) {
|
|
|
43
43
|
|
|
44
44
|
let fd;
|
|
45
45
|
try {
|
|
46
|
-
fd = fs.openSync(tmpPath, '
|
|
46
|
+
fd = fs.openSync(tmpPath, 'wx', mode ?? 0o644);
|
|
47
47
|
fs.writeSync(fd, content, 0, encoding);
|
|
48
48
|
// fsync the data to disk before rename — otherwise a crash between
|
|
49
49
|
// write() and rename() could leave the target renamed but with zero
|
package/cli/lib/github.cjs
CHANGED
|
@@ -18,6 +18,14 @@ const { execSync, spawnSync } = require('child_process');
|
|
|
18
18
|
|
|
19
19
|
// ---------- Utility: run gh commands safely ----------
|
|
20
20
|
|
|
21
|
+
function sanitizeGhOutput(text) {
|
|
22
|
+
if (!text) return '';
|
|
23
|
+
// Strip anything that looks like a token (ghp_*, ghs_*, github_pat_*)
|
|
24
|
+
return text
|
|
25
|
+
.replace(/\b(ghp_|ghs_|github_pat_)[A-Za-z0-9_]{10,}\b/g, '[REDACTED]')
|
|
26
|
+
.slice(0, 2000);
|
|
27
|
+
}
|
|
28
|
+
|
|
21
29
|
function runGh(args, { input = null, allowFailure = false } = {}) {
|
|
22
30
|
const result = spawnSync('gh', args, {
|
|
23
31
|
encoding: 'utf8',
|
|
@@ -26,9 +34,8 @@ function runGh(args, { input = null, allowFailure = false } = {}) {
|
|
|
26
34
|
});
|
|
27
35
|
|
|
28
36
|
if (result.status !== 0 && !allowFailure) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
);
|
|
37
|
+
const detail = sanitizeGhOutput(result.stderr || result.stdout || '(no output)');
|
|
38
|
+
throw new Error(`gh ${args.join(' ')} failed:\n${detail}`);
|
|
32
39
|
}
|
|
33
40
|
|
|
34
41
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hanzlaa/rcode",
|
|
3
|
-
"version": "3.4.
|
|
3
|
+
"version": "3.4.11",
|
|
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": {
|
|
@@ -8,15 +8,6 @@
|
|
|
8
8
|
"rihal": "dist/rcode.js",
|
|
9
9
|
"rihal-code": "dist/rcode.js"
|
|
10
10
|
},
|
|
11
|
-
"scripts": {
|
|
12
|
-
"dashboard": "node server/dashboard.js",
|
|
13
|
-
"test": "node --test",
|
|
14
|
-
"test:ci": "node --test --test-reporter=spec",
|
|
15
|
-
"postinstall": "node cli/postinstall.js",
|
|
16
|
-
"build:cli": "node scripts/build.cjs",
|
|
17
|
-
"build": "node scripts/build.cjs",
|
|
18
|
-
"dogfood": "bash scripts/dogfood-check.sh"
|
|
19
|
-
},
|
|
20
11
|
"files": [
|
|
21
12
|
"cli/",
|
|
22
13
|
"rihal/",
|
|
@@ -69,5 +60,14 @@
|
|
|
69
60
|
},
|
|
70
61
|
"publishConfig": {
|
|
71
62
|
"access": "public"
|
|
63
|
+
},
|
|
64
|
+
"scripts": {
|
|
65
|
+
"dashboard": "node server/dashboard.js",
|
|
66
|
+
"test": "node --test",
|
|
67
|
+
"test:ci": "node --test --test-reporter=spec",
|
|
68
|
+
"postinstall": "node cli/postinstall.js",
|
|
69
|
+
"build:cli": "node scripts/build.cjs",
|
|
70
|
+
"build": "node scripts/build.cjs",
|
|
71
|
+
"dogfood": "bash scripts/dogfood-check.sh"
|
|
72
72
|
}
|
|
73
|
-
}
|
|
73
|
+
}
|
|
@@ -4688,11 +4688,11 @@ function cmdProgress(args) {
|
|
|
4688
4688
|
byNum[num] = {
|
|
4689
4689
|
path: full,
|
|
4690
4690
|
dirName: entry,
|
|
4691
|
-
plan_count: files.filter(f =>
|
|
4691
|
+
plan_count: files.filter(f => /-SPRINT\.md$/i.test(f)).length,
|
|
4692
4692
|
summary_count: files.filter(f => /SUMMARY\.md$|-SUMMARY\.md$/.test(f)).length,
|
|
4693
4693
|
has_research: files.includes('RESEARCH.md'),
|
|
4694
4694
|
has_context: files.includes('CONTEXT.md'),
|
|
4695
|
-
has_verification: files.
|
|
4695
|
+
has_verification: files.some(f => /VERIFICATION\.md$/i.test(f)),
|
|
4696
4696
|
};
|
|
4697
4697
|
}
|
|
4698
4698
|
return byNum;
|
|
@@ -103,8 +103,8 @@ Auditor returns structured JSON:
|
|
|
103
103
|
**If `MODE=phase-status` (Phase 8 / #461):**
|
|
104
104
|
|
|
105
105
|
Spawn `rihal-docs-auditor` with `--mode=phase-status`. Pass:
|
|
106
|
-
- `roadmap_phases[]` — output of `node rihal/bin/rihal-tools.cjs roadmap list-phases` (post-#464 fix)
|
|
107
|
-
- `phase_dirs[]` — output of `node rihal/bin/rihal-tools.cjs init phase-op N` for each phase number, OR a direct walk of `.planning/phases/*` that captures: dir name, presence of `*-SUMMARY.md`, `*-SPRINT.md`, `*-PLAN.md`, `*-CONTEXT.md`, `*-RESEARCH.md`, `*-VERIFICATION.md`
|
|
106
|
+
- `roadmap_phases[]` — output of `node .rihal/bin/rihal-tools.cjs roadmap list-phases` (post-#464 fix)
|
|
107
|
+
- `phase_dirs[]` — output of `node .rihal/bin/rihal-tools.cjs init phase-op N` for each phase number, OR a direct walk of `.planning/phases/*` that captures: dir name, presence of `*-SUMMARY.md`, `*-SPRINT.md`, `*-PLAN.md`, `*-CONTEXT.md`, `*-RESEARCH.md`, `*-VERIFICATION.md`
|
|
108
108
|
- For each phase, the most recent commit hash that touches files in `${phase_dir}/` (used as a freshness signal)
|
|
109
109
|
|
|
110
110
|
Auditor returns structured JSON:
|
|
@@ -58,12 +58,15 @@ the weighted bar as the primary progress indicator to avoid a misleading `0/N (0
|
|
|
58
58
|
For each entry in `SNAPSHOT.phases[]`:
|
|
59
59
|
|
|
60
60
|
- `▶` if `phase.number === SNAPSHOT.current_phase`
|
|
61
|
-
- `✓` if `phase.disk.summary_count > 0` AND
|
|
61
|
+
- `✓` if `phase.disk.summary_count > 0` AND `phase.disk.summary_count >= phase.disk.plan_count` AND `phase.disk.has_verification` (complete + verified; if VERIFICATION.md absent, use `◎` and label "complete-unverified")
|
|
62
|
+
- `◎` if `phase.disk.summary_count > 0` AND `phase.disk.summary_count >= phase.disk.plan_count` AND NOT `phase.disk.has_verification` (work done, awaiting verification)
|
|
62
63
|
- `◆` if `phase.disk.plan_count > phase.disk.summary_count` (executing — has plans, not all summarized)
|
|
63
64
|
- `◇` if `phase.disk.has_context && !phase.disk.plan_count` (discussing — CONTEXT.md exists but no plan yet)
|
|
64
65
|
- `◈` if `phase.disk.has_research && !phase.disk.plan_count` (researched — RESEARCH.md but no plan)
|
|
65
66
|
- `○` otherwise (planned — no artifacts on disk)
|
|
66
67
|
|
|
68
|
+
**Edge case — summary without sprint:** If `summary_count > 0` AND `plan_count === 0`, treat as `◎ complete-unverified` (sprint was archived or the phase used an older single-file workflow; summary is evidence of completed work).
|
|
69
|
+
|
|
67
70
|
```
|
|
68
71
|
Phases:
|
|
69
72
|
▶ [04] Component compaction — executing (1/3 plans)
|