@hanzlaa/rcode 2.7.2 → 3.1.0
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/AGENTS.md +11 -1
- package/CONTRIBUTING.md +7 -0
- package/README.md +39 -20
- package/package.json +2 -2
- package/rihal/agents/rihal-advisor-researcher.md +1 -1
- package/rihal/agents/rihal-assumptions-analyzer.md +1 -1
- package/rihal/agents/rihal-codebase-mapper.md +1 -1
- package/rihal/agents/rihal-docs-auditor.md +3 -3
- package/rihal/agents/rihal-executor.md +10 -0
- package/rihal/agents/rihal-fatima.md +31 -101
- package/rihal/agents/rihal-haitham.md +125 -57
- package/rihal/agents/rihal-hanzla.md +23 -98
- package/rihal/agents/rihal-hussain-pm.md +33 -102
- package/rihal/agents/rihal-integration-checker.md +1 -1
- package/rihal/agents/rihal-mariam.md +26 -94
- package/rihal/agents/rihal-noor.md +2 -2
- package/rihal/agents/rihal-omar.md +112 -31
- package/rihal/agents/rihal-phase-researcher.md +1 -1
- package/rihal/agents/rihal-planner.md +25 -0
- package/rihal/agents/rihal-project-researcher.md +1 -1
- package/rihal/agents/rihal-research-synthesizer.md +1 -1
- package/rihal/agents/rihal-roadmapper.md +1 -1
- package/rihal/agents/rihal-sadiq.md +30 -95
- package/rihal/agents/rihal-sprint-checker.md +19 -1
- package/rihal/agents/rihal-verifier.md +1 -1
- package/rihal/agents/rihal-waleed.md +34 -98
- package/rihal/agents/rihal-yousef.md +111 -52
- package/rihal/commands/code-review.md +1 -1
- package/rihal/commands/memory-audit.md +10 -0
- package/rihal/commands/memory-distill.md +11 -0
- package/rihal/commands/memory-init.md +12 -0
- package/rihal/commands/memory-update.md +12 -0
- package/rihal/config/model-profiles.json +5 -5
- package/rihal/references/agent-shared-rules.md +81 -0
- package/rihal/references/karpathy-guidelines-full.md +1 -1
- package/rihal/references/no-unauthorized-git-ops.md +1 -1
- package/rihal/references/verb-dictionary.md +1 -1
- package/rihal/skills/actions/2-plan/rihal-frontend-design/SKILL.md +49 -139
- package/rihal/skills/actions/2-plan/rihal-frontend-design/references.md +79 -0
- package/rihal/skills/actions/4-implementation/rihal-browser-verify/SKILL.md +70 -0
- package/rihal/skills/actions/4-implementation/rihal-checkpoint-preview/SKILL.md +1 -1
- package/rihal/skills/actions/4-implementation/rihal-ci/SKILL.md +108 -0
- package/rihal/skills/actions/4-implementation/rihal-debug/SKILL.md +78 -0
- package/rihal/skills/actions/4-implementation/rihal-git-flow/SKILL.md +90 -0
- package/rihal/skills/actions/4-implementation/rihal-harden/SKILL.md +91 -0
- package/rihal/skills/actions/4-implementation/rihal-incremental/SKILL.md +50 -0
- package/rihal/skills/actions/4-implementation/rihal-migrate/SKILL.md +86 -0
- package/rihal/skills/actions/4-implementation/rihal-perf/SKILL.md +96 -0
- package/rihal/skills/actions/4-implementation/rihal-prove-it/SKILL.md +64 -0
- package/rihal/skills/actions/4-implementation/rihal-source-truth/SKILL.md +76 -0
- package/rihal/skills/actions/4-implementation/rihal-trim/SKILL.md +73 -0
- package/rihal/skills/agents/dalil-scout/SKILL.md +43 -125
- package/rihal/skills/agents/dalil-scout/references.md +67 -0
- package/rihal/skills/agents/fatima-qa/SKILL.md +21 -0
- package/rihal/skills/agents/hanzla-engineer/SKILL.md +22 -0
- package/rihal/skills/agents/hussain-pm/SKILL.md +21 -0
- package/rihal/skills/agents/majlis-council/SKILL.md +50 -144
- package/rihal/skills/agents/majlis-council/references.md +90 -0
- package/rihal/skills/agents/mariam-marketing/SKILL.md +19 -0
- package/rihal/skills/agents/raees-orchestrator/SKILL.md +56 -117
- package/rihal/skills/agents/raees-orchestrator/references.md +47 -0
- package/rihal/skills/agents/sadiq-analyst/SKILL.md +30 -0
- package/rihal/skills/agents/waleed-architect/SKILL.md +20 -0
- package/rihal/skills/core/rihal-advanced-elicitation/SKILL.md +36 -136
- package/rihal/skills/core/rihal-advanced-elicitation/references.md +101 -0
- package/rihal/skills/core/rihal-auth-audit/SKILL.md +93 -0
- package/rihal/skills/core/rihal-brainstorming/SKILL.md +5 -0
- package/rihal/skills/core/rihal-client-gate/SKILL.md +91 -0
- package/rihal/skills/core/rihal-clone-website/SKILL.md +30 -371
- package/rihal/skills/core/rihal-clone-website/references.md +213 -0
- package/rihal/skills/core/rihal-deploy-unify/SKILL.md +87 -0
- package/rihal/skills/core/rihal-distillator/SKILL.md +37 -187
- package/rihal/skills/core/rihal-distillator/references.md +118 -0
- package/rihal/skills/core/rihal-editorial-review-prose/SKILL.md +5 -0
- package/rihal/skills/core/rihal-editorial-review-structure/SKILL.md +45 -183
- package/rihal/skills/core/rihal-editorial-review-structure/references.md +110 -0
- package/rihal/skills/core/rihal-help/SKILL.md +6 -1
- package/rihal/skills/core/rihal-incident-record/SKILL.md +161 -0
- package/rihal/skills/core/rihal-index-docs/SKILL.md +5 -0
- package/rihal/skills/core/rihal-init/SKILL.md +5 -0
- package/rihal/skills/core/rihal-memory-audit/SKILL.md +88 -0
- package/rihal/skills/core/rihal-memory-distill/SKILL.md +87 -0
- package/rihal/skills/core/rihal-memory-init/SKILL.md +77 -0
- package/rihal/skills/core/rihal-memory-update/SKILL.md +73 -0
- package/rihal/skills/core/rihal-mvp-graduate/SKILL.md +116 -0
- package/rihal/skills/core/rihal-ocr-consistency/SKILL.md +106 -0
- package/rihal/skills/core/rihal-party-mode/SKILL.md +5 -0
- package/rihal/skills/core/rihal-rebrand/SKILL.md +133 -0
- package/rihal/skills/core/rihal-review-adversarial-general/SKILL.md +5 -0
- package/rihal/skills/core/rihal-review-edge-case-hunter/SKILL.md +5 -0
- package/rihal/skills/core/rihal-shard-doc/SKILL.md +5 -0
- package/rihal/skills/core/rihal-theme-system/SKILL.md +113 -0
- package/rihal/team.yaml +3 -22
- package/rihal/templates/memory/INDEX.md +46 -0
- package/rihal/templates/memory/change-records/.gitkeep +4 -0
- package/rihal/templates/memory/distillates/project.distillate.md +11 -0
- package/rihal/templates/memory/distillates/stack.distillate.md +11 -0
- package/rihal/templates/memory/incidents/known-issues.md +27 -0
- package/rihal/templates/memory/incidents/post-mortems/.gitkeep +3 -0
- package/rihal/templates/memory/milestones/archive/.gitkeep +2 -0
- package/rihal/templates/memory/milestones/current.md +39 -0
- package/rihal/templates/memory/people/stakeholders.md +25 -0
- package/rihal/templates/memory/people/team.md +35 -0
- package/rihal/templates/memory/project/decisions.md +32 -0
- package/rihal/templates/memory/project/glossary.md +16 -0
- package/rihal/templates/memory/project/stack.md +46 -0
- package/rihal/workflows/audit.md +3 -3
- package/rihal/workflows/code-review.md +32 -1
- package/rihal/workflows/council.md +1 -1
- package/rihal/workflows/discuss-phase-power.md +3 -3
- package/rihal/workflows/do.md +1 -1
- package/rihal/workflows/docs-update.md +4 -4
- package/rihal/workflows/execute.md +61 -5
- package/rihal/workflows/help.md +5 -5
- package/rihal/workflows/karpathy-audit.md +9 -9
- package/rihal/workflows/memory-audit.md +83 -0
- package/rihal/workflows/memory-distill.md +103 -0
- package/rihal/workflows/memory-init.md +102 -0
- package/rihal/workflows/memory-update.md +83 -0
- package/rihal/workflows/plan.md +66 -1
- package/server/dashboard.js +6 -1
- package/server/lib/api.js +8 -2
- package/server/lib/html/client.js +63 -0
- package/server/lib/html/shell.js +5 -0
- package/server/lib/scanner.js +76 -1
- package/rihal/agents/rihal-architect.md +0 -79
- package/rihal/agents/rihal-tech-writer.md +0 -80
- package/rihal/commands/check-implementation-readiness.md +0 -8
- package/rihal/commands/discuss-phase-power.md +0 -11
- package/rihal/commands/karpathy-audit.md +0 -12
- package/rihal/commands/new-project-research.md +0 -11
- package/rihal/commands/new-project-roadmap.md +0 -11
- package/rihal/commands/report.md +0 -10
- package/rihal/commands/review-adversarial.md +0 -8
- package/rihal/commands/review-edge-case-hunter.md +0 -8
|
@@ -507,11 +507,17 @@ Execute each selected wave in sequence. Within a wave: parallel if `PARALLELIZAT
|
|
|
507
507
|
</worktree_branch_check>
|
|
508
508
|
|
|
509
509
|
<parallel_execution>
|
|
510
|
-
You are running as a PARALLEL executor agent.
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
510
|
+
You are running as a PARALLEL executor agent. To avoid pre-commit hook
|
|
511
|
+
contention with other agents, acquire a file-based lock before each
|
|
512
|
+
commit and release it immediately after:
|
|
513
|
+
|
|
514
|
+
while ! mkdir .rihal/.commit-lock 2>/dev/null; do sleep 0.5; done
|
|
515
|
+
git commit -m "..." # hooks run normally
|
|
516
|
+
rmdir .rihal/.commit-lock
|
|
517
|
+
|
|
518
|
+
Hooks run as designed for every commit. AGENTS.md forbids --no-verify;
|
|
519
|
+
hook failures must be fixed at the source, not bypassed. The orchestrator
|
|
520
|
+
still validates state once after all agents complete.
|
|
515
521
|
</parallel_execution>
|
|
516
522
|
|
|
517
523
|
<execution_context>
|
|
@@ -1291,6 +1297,56 @@ Also: `/rihal:verify-work {X} ${Rihal_WS}` — manual testing first
|
|
|
1291
1297
|
Gap closure cycle: `/rihal:plan {X} --gaps ${Rihal_WS}` reads VERIFICATION.md → creates gap plans with `gap_closure: true` → user runs `/rihal:execute {X} --gaps-only ${Rihal_WS}` → verifier re-runs.
|
|
1292
1298
|
</step>
|
|
1293
1299
|
|
|
1300
|
+
<step name="uat_gate" priority="blocker">
|
|
1301
|
+
**UAT gate (added in v3.1.0 after #443 / #448):**
|
|
1302
|
+
|
|
1303
|
+
Before marking the phase complete, verify a passing VERIFICATION.md exists for this phase. Without it, the phase advances to `status: executed` (work done, awaiting verification) — not `status: complete`.
|
|
1304
|
+
|
|
1305
|
+
```bash
|
|
1306
|
+
VERIFICATION_FILE=$(ls "${PHASE_DIR}"/*-VERIFICATION.md 2>/dev/null | head -1)
|
|
1307
|
+
|
|
1308
|
+
if [ -z "$VERIFICATION_FILE" ]; then
|
|
1309
|
+
VERIFICATION_STATUS="missing"
|
|
1310
|
+
elif grep -q "^status:\s*pass\b" "$VERIFICATION_FILE" 2>/dev/null; then
|
|
1311
|
+
VERIFICATION_STATUS="pass"
|
|
1312
|
+
elif grep -q "^status:\s*fail\b" "$VERIFICATION_FILE" 2>/dev/null; then
|
|
1313
|
+
VERIFICATION_STATUS="fail"
|
|
1314
|
+
else
|
|
1315
|
+
VERIFICATION_STATUS="indeterminate"
|
|
1316
|
+
fi
|
|
1317
|
+
```
|
|
1318
|
+
|
|
1319
|
+
**If `VERIFICATION_STATUS` is `missing` or `indeterminate`:**
|
|
1320
|
+
|
|
1321
|
+
1. Mark the phase as `status: executed` (NOT `complete`) via:
|
|
1322
|
+
```bash
|
|
1323
|
+
node ".rihal/bin/rihal-tools.cjs" phase set-status "${PHASE_NUMBER}" executed
|
|
1324
|
+
```
|
|
1325
|
+
2. Print the mandatory UAT checklist:
|
|
1326
|
+
```
|
|
1327
|
+
⚠ Phase {X} EXECUTED but not yet verified.
|
|
1328
|
+
|
|
1329
|
+
The following acceptance criteria require human verification before
|
|
1330
|
+
the phase can advance to `status: complete`:
|
|
1331
|
+
|
|
1332
|
+
{list AC items from SPRINT.md}
|
|
1333
|
+
|
|
1334
|
+
Run /rihal:verify-work {X} to perform UAT and produce VERIFICATION.md.
|
|
1335
|
+
/rihal:next will refuse to advance until this gate passes.
|
|
1336
|
+
```
|
|
1337
|
+
3. STOP the workflow. Do NOT proceed to `update_roadmap`. Do NOT call `phase complete`.
|
|
1338
|
+
|
|
1339
|
+
**If `VERIFICATION_STATUS` is `fail`:**
|
|
1340
|
+
|
|
1341
|
+
1. Mark the phase as `status: executed` (so /rihal:plan --gaps can run a closure cycle).
|
|
1342
|
+
2. Surface the failed AC items.
|
|
1343
|
+
3. STOP. Don't mark complete on a failing verification.
|
|
1344
|
+
|
|
1345
|
+
**Only when `VERIFICATION_STATUS` is `pass`** — proceed to `update_roadmap` below.
|
|
1346
|
+
|
|
1347
|
+
The previous behaviour (printing "Next Up: /rihal:verify-work" without state-gating) caused phases to reach `status: complete` without any human-verified UAT — see #443 for the failure mode.
|
|
1348
|
+
</step>
|
|
1349
|
+
|
|
1294
1350
|
<step name="update_roadmap">
|
|
1295
1351
|
**Mark phase complete and update all tracking files:**
|
|
1296
1352
|
|
package/rihal/workflows/help.md
CHANGED
|
@@ -174,18 +174,18 @@ init → new-project → plan → execute → next → status → ship
|
|
|
174
174
|
| `/rihal:add-tests <n>` | Generate unit + E2E tests based on SPRINT/SUMMARY/CONTEXT. |
|
|
175
175
|
| `/rihal:audit-uat` | Cross-phase audit of all outstanding UAT items. |
|
|
176
176
|
| `/rihal:audit-fix` | Autonomous audit-to-fix pipeline — find, classify, fix, test, commit. |
|
|
177
|
-
| `/rihal:karpathy
|
|
177
|
+
| `/rihal:code-review --karpathy` | Audit recent code against Karpathy's 4 LLM coding principles. |
|
|
178
178
|
| `/rihal:ui-phase <n>` | Generate UI design contract (UI-SPEC.md) for frontend phases. |
|
|
179
179
|
| `/rihal:ui-review` | Retroactive 6-pillar visual audit of completed UI work. |
|
|
180
|
-
| `/rihal:review
|
|
181
|
-
| `/rihal:review
|
|
180
|
+
| `/rihal:code-review --attack` | Hostile-perspective report — vulnerabilities, race conditions, abuse. |
|
|
181
|
+
| `/rihal:code-review --edge-cases` | Enumerate edge cases by category and severity. |
|
|
182
182
|
| `/rihal:review` | Cross-AI peer review — invoke external AI CLIs to review plans. |
|
|
183
183
|
|
|
184
184
|
## Council variants & strategy power tools
|
|
185
185
|
|
|
186
186
|
| Command | Use |
|
|
187
187
|
|---------|-----|
|
|
188
|
-
| `/rihal:discuss-phase
|
|
188
|
+
| `/rihal:discuss-phase --power` | Bulk question generation with async UI for context-heavy phases. |
|
|
189
189
|
| `/rihal:chain <preset> <topic>` | Sequential agent pipeline (research → scope → build), typed artifacts. |
|
|
190
190
|
| `/rihal:brainstorm` | Guided brainstorming — pick a method, generate ideas systematically. |
|
|
191
191
|
| `/rihal:why <decision>` | Explain reasoning behind a decision, classification, or panel pick. |
|
|
@@ -213,7 +213,7 @@ init → new-project → plan → execute → next → status → ship
|
|
|
213
213
|
| `/rihal:create-epics-and-stories` | Parse a PRD into numbered epic + story files. |
|
|
214
214
|
| `/rihal:create-story` | Prepare a dev-ready STORY.md with full implementation context. |
|
|
215
215
|
| `/rihal:dev-story <file>` | Execute an approved STORY by writing tests + code per AC. |
|
|
216
|
-
|
|
|
216
|
+
| (internal) `check-implementation-readiness` | Guard called by `/rihal:plan` and `/rihal:execute` to verify PRD + architecture aligned before build. |
|
|
217
217
|
| `/rihal:create-architecture` | Write an Architecture Decision Record (ADR). |
|
|
218
218
|
| `/rihal:create-ux-design` | Realize a UX design that informs architecture and implementation. |
|
|
219
219
|
| `/rihal:correct-course` | Course-correct mid-sprint when major change is discovered. |
|
|
@@ -14,15 +14,15 @@ If `$ARGUMENTS` is empty or contains only `--help` or `-h`:
|
|
|
14
14
|
|
|
15
15
|
**Usage:**
|
|
16
16
|
```
|
|
17
|
-
/rihal:
|
|
18
|
-
/rihal:
|
|
17
|
+
/rihal:code-review --karpathy <phase> [--files=path1,path2]
|
|
18
|
+
/rihal:code-review --karpathy <git-ref>..HEAD
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
**Examples:**
|
|
22
22
|
```
|
|
23
|
-
/rihal:
|
|
24
|
-
/rihal:
|
|
25
|
-
/rihal:
|
|
23
|
+
/rihal:code-review --karpathy 03
|
|
24
|
+
/rihal:code-review --karpathy 02 --files=src/
|
|
25
|
+
/rihal:code-review --karpathy HEAD~5..HEAD
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
<process>
|
|
@@ -44,7 +44,7 @@ Parse: `phase_found`, `phase_dir`, `phase_number`, `padded_phase`.
|
|
|
44
44
|
|
|
45
45
|
If phase_found is false:
|
|
46
46
|
```
|
|
47
|
-
Error: Phase ${PHASE_ARG} not found. Try /rihal:
|
|
47
|
+
Error: Phase ${PHASE_ARG} not found. Try /rihal:code-review --karpathy HEAD~5..HEAD to audit recent commits instead.
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
If git ref format (contains ".." or has no digit at start):
|
|
@@ -343,7 +343,7 @@ Aggregate all findings into a structured report:
|
|
|
343
343
|
---
|
|
344
344
|
|
|
345
345
|
**Generated:** {date}
|
|
346
|
-
**Run:** /rihal:
|
|
346
|
+
**Run:** /rihal:code-review --karpathy {original_arguments}
|
|
347
347
|
```
|
|
348
348
|
|
|
349
349
|
Write report to stdout and optionally to file `{phase_dir}/{padded_phase}-KARPATHY-AUDIT.md` if phase mode.
|
|
@@ -375,7 +375,7 @@ Review the full report above. Use /rihal:code-review-fix to auto-fix some issues
|
|
|
375
375
|
**Next steps:**
|
|
376
376
|
```
|
|
377
377
|
View full report: {report file path}
|
|
378
|
-
Rerun: /rihal:
|
|
378
|
+
Rerun: /rihal:code-review --karpathy {arguments}
|
|
379
379
|
Auto-fix some issues: /rihal:code-review-fix {phase}
|
|
380
380
|
```
|
|
381
381
|
</step>
|
|
@@ -395,7 +395,7 @@ Auto-fix some issues: /rihal:code-review-fix {phase}
|
|
|
395
395
|
|
|
396
396
|
## On Error
|
|
397
397
|
|
|
398
|
-
- **Phase not found:** suggest `/rihal:
|
|
398
|
+
- **Phase not found:** suggest `/rihal:code-review --karpathy HEAD~5..HEAD` as the git-ref fallback.
|
|
399
399
|
- **No source files in diff:** report "no auditable changes in range" and STOP — do not invent findings.
|
|
400
400
|
- **karpathy-guidelines.md missing:** print "Reference doc missing. Run: npx @hanzlaa/rcode install ." and STOP.
|
|
401
401
|
- **Empty diff:** STOP gracefully, do not run principle checks against an empty input.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Workflow: rcode-memory-audit
|
|
2
|
+
|
|
3
|
+
Read-only audit of the Memory Bank. Produces a severity-tagged report. Never modifies files.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Inputs
|
|
8
|
+
|
|
9
|
+
None required. Optional `--severity {critical|warn|info}` to filter output.
|
|
10
|
+
|
|
11
|
+
## Preconditions
|
|
12
|
+
|
|
13
|
+
- `.rihal/memory/INDEX.md` exists
|
|
14
|
+
|
|
15
|
+
## Halt conditions
|
|
16
|
+
|
|
17
|
+
- Memory Bank not initialised → instruct to run `/rcode:memory-init` first
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Steps
|
|
22
|
+
|
|
23
|
+
### Step 1 — Catalogue files
|
|
24
|
+
|
|
25
|
+
Walk `.rihal/memory/` and build a list of every file plus its size and modification time. Include `.gitkeep` files for empty-subdir detection.
|
|
26
|
+
|
|
27
|
+
### Step 2 — Check 1: Stale milestone
|
|
28
|
+
|
|
29
|
+
Read `milestones/current.md`. Parse the "Target close" date. If `(today - target_close).days >= 30`, emit a `warn` finding.
|
|
30
|
+
|
|
31
|
+
### Step 3 — Check 2: Resolved issues lingering
|
|
32
|
+
|
|
33
|
+
For each entry in `incidents/known-issues.md`:
|
|
34
|
+
- Parse "Real fix planned for" field
|
|
35
|
+
- If it names a milestone that has been moved to `milestones/archive/`, emit a `warn` finding
|
|
36
|
+
|
|
37
|
+
### Step 4 — Check 3: Template placeholders unfilled
|
|
38
|
+
|
|
39
|
+
For each `*.md` file under `.rihal/memory/`:
|
|
40
|
+
- Count occurrences of `{{` literally (template placeholders)
|
|
41
|
+
- Count occurrences of `_(e.g.` (italicised template hints)
|
|
42
|
+
- If either is non-zero, emit an `info` finding listing the file and count
|
|
43
|
+
|
|
44
|
+
### Step 5 — Check 4: Stack vs decisions contradiction
|
|
45
|
+
|
|
46
|
+
For each decision entry in `project/decisions.md` that mentions a technology name:
|
|
47
|
+
- Extract candidate tech terms (proper nouns, capitalised + version)
|
|
48
|
+
- Search `project/stack.md` for the term
|
|
49
|
+
- If not found, emit a `critical` finding
|
|
50
|
+
|
|
51
|
+
### Step 6 — Check 5: Empty subdirectories
|
|
52
|
+
|
|
53
|
+
For `change-records/`, `incidents/post-mortems/`, `milestones/archive/`:
|
|
54
|
+
- If only file is `.gitkeep`, emit an `info` finding (not a problem, just visibility)
|
|
55
|
+
|
|
56
|
+
### Step 7 — Check 6: Distillate freshness
|
|
57
|
+
|
|
58
|
+
For each `distillates/*.distillate.md`:
|
|
59
|
+
- Read frontmatter `source-digest`
|
|
60
|
+
- Recompute digest of current source files (per `rcode-memory-distill` rules)
|
|
61
|
+
- If mismatch, emit a `warn` finding suggesting `/rcode:memory-distill`
|
|
62
|
+
|
|
63
|
+
### Step 8 — Render report
|
|
64
|
+
|
|
65
|
+
Group findings by severity (critical → warn → info), then by file within each severity group. For each finding, print:
|
|
66
|
+
- File path
|
|
67
|
+
- One-line description
|
|
68
|
+
- One-line `Fix:` suggestion (which skill to run, or manual action)
|
|
69
|
+
|
|
70
|
+
If `--severity` filter passed, hide findings below the threshold.
|
|
71
|
+
|
|
72
|
+
If zero findings: print `✓ Memory Bank is healthy. 0 findings.`
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Post-conditions
|
|
77
|
+
|
|
78
|
+
- No files modified
|
|
79
|
+
- Report printed to stdout
|
|
80
|
+
|
|
81
|
+
## Reversibility
|
|
82
|
+
|
|
83
|
+
Read-only — no state to revert.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Workflow: rcode-memory-distill
|
|
2
|
+
|
|
3
|
+
Regenerate Memory Bank distillates with lossless compression. Idempotent.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Inputs
|
|
8
|
+
|
|
9
|
+
- `--force` (optional) — regenerate even when source files are unchanged
|
|
10
|
+
- `--target {project|stack|all}` (optional, default `all`) — limit which distillate to regenerate
|
|
11
|
+
|
|
12
|
+
## Preconditions
|
|
13
|
+
|
|
14
|
+
- `.rihal/memory/` exists
|
|
15
|
+
- `.rihal/memory/distillates/` exists (created by `rcode-memory-init`)
|
|
16
|
+
|
|
17
|
+
## Halt conditions
|
|
18
|
+
|
|
19
|
+
- `.rihal/memory/` missing → instruct to run `/rcode:memory-init` first
|
|
20
|
+
- All sources empty (only template placeholders) → warn and exit; no point distilling empty content
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Steps
|
|
25
|
+
|
|
26
|
+
### Step 1 — Resolve source set
|
|
27
|
+
|
|
28
|
+
For `target = project`:
|
|
29
|
+
- `project/stack.md`, `project/decisions.md`, `project/glossary.md`
|
|
30
|
+
- `people/stakeholders.md`, `people/team.md`
|
|
31
|
+
- `milestones/current.md`
|
|
32
|
+
- `incidents/known-issues.md`
|
|
33
|
+
|
|
34
|
+
For `target = stack`:
|
|
35
|
+
- `project/stack.md` only
|
|
36
|
+
|
|
37
|
+
### Step 2 — Compute digest
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
digest = sha1(concat(file_path + ":" + mtime for each source file in sorted order))
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
If `--force` not passed and existing distillate's `source-digest:` matches, skip regeneration for that target.
|
|
44
|
+
|
|
45
|
+
### Step 3 — Compress per target
|
|
46
|
+
|
|
47
|
+
For each target's source set:
|
|
48
|
+
|
|
49
|
+
1. Read all source files
|
|
50
|
+
2. Extract: facts, decisions, constraints, relationships, named entities, dates
|
|
51
|
+
3. Produce a dense markdown document organised by topic (not by source file)
|
|
52
|
+
4. Strip overhead: pleasantries, redundant headings, examples that don't add new facts, template placeholders that weren't filled
|
|
53
|
+
5. Preserve: every concrete claim, every decision, every link, every name, every date
|
|
54
|
+
|
|
55
|
+
Compression target: ~30% of source token count. If output is larger, the source had a lot of substance and that's fine.
|
|
56
|
+
|
|
57
|
+
### Step 4 — Losslessness check
|
|
58
|
+
|
|
59
|
+
Walk each source file and confirm every "fact" (sentence containing a name, date, decision, or technical term) appears in the distillate either verbatim or via a directly-equivalent phrase. List any potential drops as warnings; user can `--force` past warnings if confident.
|
|
60
|
+
|
|
61
|
+
### Step 5 — Write output
|
|
62
|
+
|
|
63
|
+
For each target distillate, write:
|
|
64
|
+
|
|
65
|
+
```markdown
|
|
66
|
+
---
|
|
67
|
+
generated: true
|
|
68
|
+
do-not-edit: true
|
|
69
|
+
regenerate-with: /rcode:memory-distill
|
|
70
|
+
source-digest: <hash>
|
|
71
|
+
generated-at: <ISO datetime>
|
|
72
|
+
source-files:
|
|
73
|
+
- project/stack.md
|
|
74
|
+
- project/decisions.md
|
|
75
|
+
...
|
|
76
|
+
token-estimate: <approximate>
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
# Project Distillate — <project-name>
|
|
80
|
+
|
|
81
|
+
<compressed content>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Step 6 — Summary
|
|
85
|
+
|
|
86
|
+
Print per-target:
|
|
87
|
+
- Source file count
|
|
88
|
+
- Output token estimate
|
|
89
|
+
- Digest
|
|
90
|
+
- Skip notice (if no-op)
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Post-conditions
|
|
95
|
+
|
|
96
|
+
- `distillates/project.distillate.md` updated (if target includes project)
|
|
97
|
+
- `distillates/stack.distillate.md` updated (if target includes stack)
|
|
98
|
+
- Frontmatter `source-digest` matches the current source set
|
|
99
|
+
- No source files modified
|
|
100
|
+
|
|
101
|
+
## Reversibility
|
|
102
|
+
|
|
103
|
+
Distillates are derived artefacts. Reverting a regeneration: `git checkout .rihal/memory/distillates/`.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Workflow: rcode-memory-init
|
|
2
|
+
|
|
3
|
+
Bootstraps the rcode Memory Bank in the current project. Idempotent — re-running on an initialised project switches to a gap report instead of overwriting.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Inputs
|
|
8
|
+
|
|
9
|
+
- **Project root** — current working directory; must contain a `.rihal/` folder (created by `rcode install`)
|
|
10
|
+
- **Templates source** — `.rihal/templates/memory/` (copied from `rihal/templates/memory/` on install)
|
|
11
|
+
|
|
12
|
+
## Preconditions
|
|
13
|
+
|
|
14
|
+
- `.rihal/` exists (rcode is installed in this project)
|
|
15
|
+
- `.rihal/templates/memory/` exists (templates ship with rcode)
|
|
16
|
+
|
|
17
|
+
## Halt conditions
|
|
18
|
+
|
|
19
|
+
- `.rihal/` missing → ask user to run `npx @hanzlaa/rcode install` first, then halt.
|
|
20
|
+
- `.rihal/templates/memory/` missing → report bug, halt.
|
|
21
|
+
- User cancels at any question → leave `.rihal/memory/` partially populated (whatever was seeded) and exit cleanly.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Steps
|
|
26
|
+
|
|
27
|
+
### Step 1 — Detect existing Memory Bank
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
if [ -f ".rihal/memory/INDEX.md" ]; then
|
|
31
|
+
# Switch to gap-report mode
|
|
32
|
+
exit_with_gap_report
|
|
33
|
+
fi
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
If `INDEX.md` exists:
|
|
37
|
+
- List every file under `.rihal/memory/`
|
|
38
|
+
- For each, count non-template lines (lines that don't start with `<!--` or contain `_(...)_` placeholders)
|
|
39
|
+
- Print which files are empty / template-only and which are populated
|
|
40
|
+
- Suggest `/rcode:memory-update` for surgical edits and exit
|
|
41
|
+
|
|
42
|
+
### Step 2 — Copy templates
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
mkdir -p .rihal/memory
|
|
46
|
+
cp -R .rihal/templates/memory/. .rihal/memory/
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Preserves the directory structure. Includes `.gitkeep` files in empty subdirs.
|
|
50
|
+
|
|
51
|
+
### Step 3 — Substitute placeholders
|
|
52
|
+
|
|
53
|
+
Replace in every `*.md` file under `.rihal/memory/`:
|
|
54
|
+
- `{{PROJECT_NAME}}` → derived from `package.json` `name`, fallback to directory basename
|
|
55
|
+
- `{{INIT_DATE}}` → today's date in `YYYY-MM-DD` format
|
|
56
|
+
|
|
57
|
+
### Step 4 — Five init questions
|
|
58
|
+
|
|
59
|
+
Ask each via AskUserQuestion. Accept short answers; do not push for paragraphs.
|
|
60
|
+
|
|
61
|
+
**Q1.** What is the one-sentence project goal? *(saved to `milestones/current.md` → Goal)*
|
|
62
|
+
|
|
63
|
+
**Q2.** Primary stack — frontend / backend / database? *(parsed into `project/stack.md` Runtime table)*
|
|
64
|
+
|
|
65
|
+
**Q3.** What is the current milestone name? *(saved to `milestones/current.md` → Milestone Name; default `M1 — Initial`)*
|
|
66
|
+
|
|
67
|
+
**Q4.** Primary external stakeholder name and role? *(appended to `people/stakeholders.md`)*
|
|
68
|
+
|
|
69
|
+
**Q5.** Any known production issue you'd warn a new teammate about today? *(appended to `incidents/known-issues.md`; "none" is acceptable)*
|
|
70
|
+
|
|
71
|
+
### Step 5 — Update state.json
|
|
72
|
+
|
|
73
|
+
Add or update the `memory_bank` block in `.rihal/state.json`:
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"memory_bank": {
|
|
78
|
+
"initialised_at": "<ISO datetime>",
|
|
79
|
+
"version": 1
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Step 6 — Print summary
|
|
85
|
+
|
|
86
|
+
Show:
|
|
87
|
+
- File tree of `.rihal/memory/`
|
|
88
|
+
- Files seeded vs files still empty
|
|
89
|
+
- Suggested next command: `/rcode:memory-distill`
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Post-conditions
|
|
94
|
+
|
|
95
|
+
- `.rihal/memory/INDEX.md` exists with project name + date filled in
|
|
96
|
+
- 4–5 of the seeded files have user-supplied content
|
|
97
|
+
- `.rihal/state.json` records initialisation
|
|
98
|
+
- The Diwan dashboard `/memory` route now renders content (Phase 3 dashboard work)
|
|
99
|
+
|
|
100
|
+
## Reversibility
|
|
101
|
+
|
|
102
|
+
Removing a botched init: `rm -rf .rihal/memory/` and `git checkout -- .rihal/state.json`. No external side effects.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Workflow: rcode-memory-update
|
|
2
|
+
|
|
3
|
+
Append-only surgical update to a single Memory Bank file. Never rewrites, never deletes.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Inputs
|
|
8
|
+
|
|
9
|
+
- **content** — the thing to remember, in plain English
|
|
10
|
+
- **target** (optional) — explicit file path; if omitted, auto-detected from content
|
|
11
|
+
|
|
12
|
+
## Preconditions
|
|
13
|
+
|
|
14
|
+
- `.rihal/memory/` exists (run `/rcode:memory-init` first)
|
|
15
|
+
|
|
16
|
+
## Halt conditions
|
|
17
|
+
|
|
18
|
+
- `.rihal/memory/` missing → instruct user to init first
|
|
19
|
+
- User asks to *change* (not append) an existing entry → refuse, redirect to direct file edit
|
|
20
|
+
- Detected target file does not exist → report and halt (don't create new files in this workflow)
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Steps
|
|
25
|
+
|
|
26
|
+
### Step 1 — Auto-detect target
|
|
27
|
+
|
|
28
|
+
Match keywords in the user's content against this routing table:
|
|
29
|
+
|
|
30
|
+
| Signal | Target |
|
|
31
|
+
|---|---|
|
|
32
|
+
| "decision", "we chose", "ADR", "decided" | `project/decisions.md` |
|
|
33
|
+
| "bug", "issue", "broken", "workaround" | `incidents/known-issues.md` |
|
|
34
|
+
| "stakeholder", "client", "contact", "rep" | `people/stakeholders.md` |
|
|
35
|
+
| "milestone", "sprint", "phase", "blocker" | `milestones/current.md` |
|
|
36
|
+
| "stack", "framework", "library", "switched to" | `project/stack.md` |
|
|
37
|
+
| "term", "glossary", "what does X mean" | `project/glossary.md` |
|
|
38
|
+
| "team", "who owns", "engineer", "responsibility" | `people/team.md` |
|
|
39
|
+
| "change record", "deployment", "rollback" | `change-records/` (creates new file) |
|
|
40
|
+
|
|
41
|
+
If ambiguous, ask the user to pick from the top 2 candidates.
|
|
42
|
+
|
|
43
|
+
### Step 2 — Confirm with user
|
|
44
|
+
|
|
45
|
+
Show:
|
|
46
|
+
- Target file path
|
|
47
|
+
- Proposed entry, formatted to match the file's existing entry style
|
|
48
|
+
- A "Apply / cancel / edit format" choice
|
|
49
|
+
|
|
50
|
+
### Step 3 — Append
|
|
51
|
+
|
|
52
|
+
For appendable files (`decisions.md`, `known-issues.md`, `stakeholders.md`, `team.md`, `glossary.md`):
|
|
53
|
+
- Insert above the `<!-- Append new entries above this line -->` marker if present
|
|
54
|
+
- Otherwise append to end of file with a blank line separator
|
|
55
|
+
|
|
56
|
+
For `milestones/current.md`:
|
|
57
|
+
- Allow only field-level updates (Goal, Active phase, Blockers, Recent decisions)
|
|
58
|
+
- Replace the field's value, not the whole file
|
|
59
|
+
|
|
60
|
+
For `change-records/`:
|
|
61
|
+
- Create a new file `YYYYMMDD-NNN.md` where `NNN` is the next sequence number
|
|
62
|
+
- Use the change-record template format
|
|
63
|
+
|
|
64
|
+
### Step 4 — Stamp and verify
|
|
65
|
+
|
|
66
|
+
- Add `YYYY-MM-DD` date (today, ISO format) to every appended entry
|
|
67
|
+
- Print a diff preview (last 20 lines of the file) so the user can confirm the change landed
|
|
68
|
+
|
|
69
|
+
### Step 5 — Suggest distillate refresh
|
|
70
|
+
|
|
71
|
+
If the change was to `project/`, `milestones/current.md`, or `incidents/`, suggest `/rcode:memory-distill` to refresh distillates. Optional, not enforced.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Post-conditions
|
|
76
|
+
|
|
77
|
+
- Exactly one file changed (or one new change-record file created)
|
|
78
|
+
- File still parses as valid markdown
|
|
79
|
+
- No content removed
|
|
80
|
+
|
|
81
|
+
## Reversibility
|
|
82
|
+
|
|
83
|
+
`git diff .rihal/memory/` shows exactly one append — easy to revert with `git checkout`.
|
package/rihal/workflows/plan.md
CHANGED
|
@@ -999,7 +999,27 @@ Track `stall_reentry_count` (starts at 0; incremented each time "Adjust approach
|
|
|
999
999
|
|
|
1000
1000
|
**If iteration_count < 3:**
|
|
1001
1001
|
|
|
1002
|
-
|
|
1002
|
+
**Sprint-checker malfunction guard (BLOCKER-class — added in v3.1.0 after #440):**
|
|
1003
|
+
|
|
1004
|
+
Before parsing issues, verify the checker actually invoked tools. The checker MUST exhibit at least one of these evidence markers in its return:
|
|
1005
|
+
|
|
1006
|
+
- A YAML `issues:` block (even an empty one — `issues: []`)
|
|
1007
|
+
- A YAML `verified_files:` block listing files it read
|
|
1008
|
+
- At least one `path:` field in any block (e.g. `path: src/components/Foo.tsx:42`)
|
|
1009
|
+
- A summary line of the form `Verified N of M files` or `Checked N symbols`
|
|
1010
|
+
|
|
1011
|
+
If NONE of these evidence markers are present, the checker malfunctioned (returned narrative without invoking tools — see #440). BLOCK execution:
|
|
1012
|
+
|
|
1013
|
+
```
|
|
1014
|
+
Display: "Sprint-checker returned without evidence of tool use — likely
|
|
1015
|
+
malfunctioned (cf. issue #440). Refusing to advance the plan
|
|
1016
|
+
on unverified output. Re-run /rihal:plan or inspect the agent."
|
|
1017
|
+
Halt the workflow with a non-zero exit signal.
|
|
1018
|
+
```
|
|
1019
|
+
|
|
1020
|
+
Do NOT treat empty / narrative-only checker output as "plan approved". An empty checker output is a malfunction, not a pass.
|
|
1021
|
+
|
|
1022
|
+
Parse issue count from checker return: count BLOCKER + WARNING entries in the YAML issues block (structured output from rihal-sprint-checker). If the checker's return contains a populated YAML issues block with `issues: []` (i.e., the plan was approved with no issues AFTER actual checking), treat `issue_count` as 0 and skip the stall check — the plan passed. Proceed to step 13.
|
|
1003
1023
|
|
|
1004
1024
|
Display: `Revision iteration {N}/3 -- {blocker_count} blockers, {warning_count} warnings`
|
|
1005
1025
|
|
|
@@ -1064,6 +1084,51 @@ Display: `Max iterations reached. {N} issues remain:` + issue list
|
|
|
1064
1084
|
|
|
1065
1085
|
Offer: 1) Force proceed, 2) Provide guidance and retry, 3) Abandon
|
|
1066
1086
|
|
|
1087
|
+
## 12.5. Wave Parallelism File-Overlap Check (added in v3.1.0 after #442)
|
|
1088
|
+
|
|
1089
|
+
Before declaring plans ready, validate the wave-parallelism rule the planner declares: **same wave + overlapping `files_modified` = sequential, not parallel**. If two plans share `depends_on` (same wave) and both list the same file in `files_modified`, the planner should have marked the later one `sequential: true`. Catch the cases where it didn't.
|
|
1090
|
+
|
|
1091
|
+
```bash
|
|
1092
|
+
# For every pair of plans (A, B) with the same depends_on:
|
|
1093
|
+
# if files_modified(A) ∩ files_modified(B) is non-empty:
|
|
1094
|
+
# - the later plan (by sprint id) MUST declare sequential: true
|
|
1095
|
+
# - and must list the conflicting files in its frontmatter
|
|
1096
|
+
|
|
1097
|
+
node ".rihal/bin/rihal-tools.cjs" plan check-wave-overlaps "${PHASE_NUMBER}"
|
|
1098
|
+
```
|
|
1099
|
+
|
|
1100
|
+
The CLI helper returns a JSON report:
|
|
1101
|
+
|
|
1102
|
+
```json
|
|
1103
|
+
{
|
|
1104
|
+
"conflicts": [
|
|
1105
|
+
{
|
|
1106
|
+
"wave": 2,
|
|
1107
|
+
"plan_a": "96.2",
|
|
1108
|
+
"plan_b": "96.3",
|
|
1109
|
+
"shared_files": ["src/components/LeadDetailPanel.tsx", "src/styles/inbox.css"],
|
|
1110
|
+
"plan_b_sequential": false
|
|
1111
|
+
}
|
|
1112
|
+
]
|
|
1113
|
+
}
|
|
1114
|
+
```
|
|
1115
|
+
|
|
1116
|
+
**If `conflicts` is non-empty:**
|
|
1117
|
+
|
|
1118
|
+
1. For each conflict, edit the later plan's SPRINT.md frontmatter to add:
|
|
1119
|
+
```yaml
|
|
1120
|
+
sequential: true
|
|
1121
|
+
sequential_after: <plan_a id>
|
|
1122
|
+
conflicting_files: [<shared_files...>]
|
|
1123
|
+
```
|
|
1124
|
+
2. Recompute waves: the formerly-parallel plan now depends on the earlier one, so its wave is `max(waves of dependencies) + 1`.
|
|
1125
|
+
3. Re-run the checker to confirm the updated frontmatter.
|
|
1126
|
+
4. Display: `Wave parallelism: {N} conflict(s) auto-corrected to sequential.`
|
|
1127
|
+
|
|
1128
|
+
**If `conflicts` is empty:** Display `Wave parallelism: ✓ no file-overlap conflicts.` and proceed.
|
|
1129
|
+
|
|
1130
|
+
This closes the gap from #442 — the rule was stated in `rihal-planner.md` but not enforced. Now it's enforced automatically.
|
|
1131
|
+
|
|
1067
1132
|
## 13. Requirements Coverage Gate
|
|
1068
1133
|
|
|
1069
1134
|
After plans pass the checker (or checker is skipped), verify that all phase requirements are covered by at least one plan.
|
package/server/dashboard.js
CHANGED
|
@@ -24,7 +24,7 @@ const http = require('http');
|
|
|
24
24
|
const path = require('path');
|
|
25
25
|
|
|
26
26
|
const { scanState } = require('./lib/scanner');
|
|
27
|
-
const { handleApiState, handleApiFiles, handleApiFile, handleApiHierarchy } = require('./lib/api');
|
|
27
|
+
const { handleApiState, handleApiFiles, handleApiFile, handleApiHierarchy, handleApiMemory } = require('./lib/api');
|
|
28
28
|
const { renderHtml } = require('./lib/html/shell');
|
|
29
29
|
|
|
30
30
|
// ---------- Configuration ----------
|
|
@@ -62,6 +62,11 @@ const server = http.createServer((req, res) => {
|
|
|
62
62
|
return;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
if (url === '/api/memory') {
|
|
66
|
+
handleApiMemory(req, res, RIHAL_DIR);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
65
70
|
if (url === '/' || url === '/index.html') {
|
|
66
71
|
const state = scanState(RIHAL_DIR);
|
|
67
72
|
const html = renderHtml(state);
|
package/server/lib/api.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
const path = require('path');
|
|
6
|
-
const { scanState } = require('./scanner');
|
|
6
|
+
const { scanState, scanMemoryBank } = require('./scanner');
|
|
7
7
|
|
|
8
8
|
function handleApiState(req, res, rihalDir) {
|
|
9
9
|
const state = scanState(rihalDir);
|
|
@@ -120,4 +120,10 @@ function handleApiHierarchy(req, res, rihalDir) {
|
|
|
120
120
|
res.end(JSON.stringify(hierarchy, null, 2));
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
|
|
123
|
+
function handleApiMemory(req, res, rihalDir) {
|
|
124
|
+
const memory = scanMemoryBank(rihalDir);
|
|
125
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
126
|
+
res.end(JSON.stringify(memory, null, 2));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
module.exports = { handleApiState, handleApiFiles, handleApiFile, handleApiHierarchy, handleApiMemory };
|