@hanzlaa/rcode 4.3.3 → 4.4.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/CONTRIBUTING.md +1 -1
- package/README.md +10 -4
- package/cli/doctor.js +21 -3
- package/cli/index.js +5 -1
- package/cli/install.js +2 -2
- package/cli/postinstall.js +1 -1
- package/cli/uninstall.js +48 -6
- package/dist/rcode.js +174 -170
- package/package.json +12 -22
- package/rcode/agents/rcode-codebase-mapper.md +12 -0
- package/rcode/agents/rcode-phase-researcher.md +13 -0
- package/rcode/agents/rcode-project-researcher.md +32 -0
- package/rcode/agents/rcode-roadmapper.md +15 -0
- package/rcode/agents/rules/planner/common-patterns.md +40 -0
- package/rcode/bin/lib/roadmap.cjs +184 -11
- package/rcode/bin/rcode-hooks.cjs +102 -151
- package/rcode/bin/rcode-tools.cjs +669 -55
- package/rcode/data/intent-table.json +87 -0
- package/rcode/modules/seo.yaml +22 -0
- package/rcode/references/project-types.yaml +75 -0
- package/rcode/skills/SKILLS_INDEX.md +17 -0
- package/rcode/skills/actions/4-implementation/rcode-herdr-orchestration/SKILL.md +4 -21
- package/rcode/skills/actions/4-implementation/rcode-herdr-orchestration/templates/heartbeat.sh +0 -0
- package/rcode/skills/actions/4-implementation/rcode-scaffold-project/SKILL.md +60 -1
- package/rcode/skills/core/rcode-init/scripts/__pycache__/rcode_init.cpython-38.pyc +0 -0
- package/rcode/skills/core/rcode-init/scripts/tests/__pycache__/test_rcode_init.cpython-38.pyc +0 -0
- package/rcode/skills/seo/module.yaml +20 -0
- package/rcode/skills/seo/on-page-seo-auditor/SKILL.md +308 -0
- package/rcode/skills/seo/on-page-seo-auditor/references/audit-example.md +109 -0
- package/rcode/skills/seo/on-page-seo-auditor/references/audit-templates.md +427 -0
- package/rcode/skills/seo/on-page-seo-auditor/references/bulk-audit-playbook.md +116 -0
- package/rcode/skills/seo/on-page-seo-auditor/references/scoring-rubric.md +525 -0
- package/rcode/skills/seo/rank-and-rent-local-seo/SKILL.md +94 -0
- package/rcode/skills/seo/rank-and-rent-local-seo/rules/city-matrix-and-pages.md +76 -0
- package/rcode/skills/seo/rank-and-rent-local-seo/rules/monetization.md +70 -0
- package/rcode/skills/seo/rank-and-rent-local-seo/rules/niche-selection.md +60 -0
- package/rcode/skills/seo/rank-and-rent-local-seo/rules/subniche-discovery.md +66 -0
- package/rcode/skills/seo/rank-and-rent-local-seo/templates/service-city-page.md +36 -0
- package/rcode/skills/seo/rank-and-rent-local-seo/templates/subniche-research-prompt.md +34 -0
- package/rcode/skills/seo/seo-audit/SKILL.md +412 -0
- package/rcode/skills/seo/seo-audit/evals/evals.json +136 -0
- package/rcode/skills/seo/seo-audit/references/ai-writing-detection.md +200 -0
- package/rcode/skills/seo/seo-content-factory/SKILL.md +130 -0
- package/rcode/skills/seo/seo-content-factory/rules/agents.md +80 -0
- package/rcode/skills/seo/seo-content-factory/rules/herdr-wave-mapping.md +80 -0
- package/rcode/skills/seo/seo-content-factory/rules/pipeline.md +102 -0
- package/rcode/skills/seo/seo-content-factory/rules/programmatic-pages.md +107 -0
- package/rcode/skills/seo/seo-content-factory/rules/quality-gates.md +68 -0
- package/rcode/skills/seo/seo-content-factory/rules/weekly-cadence.md +61 -0
- package/rcode/skills/seo/seo-content-factory/templates/BACKLOG.md +23 -0
- package/rcode/skills/seo/seo-content-factory/templates/agent-prompts/01-funnel-A1-A4.md +63 -0
- package/rcode/skills/seo/seo-content-factory/templates/agent-prompts/02-fanout-editorial-A5-A6-A8.md +28 -0
- package/rcode/skills/seo/seo-content-factory/templates/agent-prompts/03-fanout-programmatic-A7-A6-A8.md +25 -0
- package/rcode/skills/seo/seo-content-factory/templates/agent-prompts/04-loop-A9-A10.md +34 -0
- package/rcode/skills/seo/seo-content-factory/templates/article.mdx +39 -0
- package/rcode/skills/seo/seo-content-factory/templates/cluster.schema.json +52 -0
- package/rcode/skills/seo/seo-content-factory/templates/content-brief.md +51 -0
- package/rcode/skills/seo/seo-content-factory/templates/jsonld-builders.ts +49 -0
- package/rcode/skills/seo/seo-content-factory/templates/keywords.csv +13 -0
- package/rcode/skills/seo/seo-content-factory/templates/programmatic-page.tsx +58 -0
- package/rcode/skills/seo/seo-content-writer/SKILL.md +263 -0
- package/rcode/skills/seo/seo-content-writer/references/content-structure-templates.md +875 -0
- package/rcode/skills/seo/seo-content-writer/references/instructions-detail.md +239 -0
- package/rcode/skills/seo/seo-content-writer/references/seo-writing-checklist.md +250 -0
- package/rcode/skills/seo/seo-content-writer/references/title-formulas.md +339 -0
- package/rcode/skills/seo/seo-growth-orchestrator/SKILL.md +79 -0
- package/rcode/skills/seo/seo-growth-orchestrator/rules/backlinks.md +29 -0
- package/rcode/skills/seo/seo-growth-orchestrator/rules/content-engine.md +27 -0
- package/rcode/skills/seo/seo-growth-orchestrator/rules/dos-and-donts.md +40 -0
- package/rcode/skills/seo/seo-growth-orchestrator/rules/goals-protocol.md +34 -0
- package/rcode/skills/seo/seo-growth-orchestrator/rules/local-seo-stack.md +35 -0
- package/rcode/skills/seo/seo-growth-orchestrator/rules/mrr-sprint.md +27 -0
- package/rcode/skills/seo/seo-growth-orchestrator/rules/tools.md +19 -0
- package/rcode/skills/seo/seo-growth-orchestrator/templates/backlink-research.md +29 -0
- package/rcode/skills/seo/seo-growth-orchestrator/templates/goal-protocol.md +35 -0
- package/rcode/skills/seo/seo-growth-orchestrator/templates/local-citations.md +24 -0
- package/rcode/skills/seo/seo-growth-orchestrator/templates/local-city-pages.md +27 -0
- package/rcode/skills/seo/seo-growth-orchestrator/templates/local-gbp-categories.md +23 -0
- package/rcode/skills/seo/seo-growth-orchestrator/templates/local-gsc-goldmine.md +27 -0
- package/rcode/skills/seo/seo-growth-orchestrator/templates/local-review-mining.md +26 -0
- package/rcode/skills/seo/seo-growth-orchestrator/templates/mrr-30day-plan.md +19 -0
- package/rcode/skills/seo/seo-growth-orchestrator/templates/mrr-cut.md +13 -0
- package/rcode/skills/seo/seo-growth-orchestrator/templates/mrr-opportunity-finder.md +17 -0
- package/rcode/skills/seo/seo-growth-orchestrator/templates/mrr-role-model.md +18 -0
- package/rcode/skills/seo/seo-site-builder/SKILL.md +149 -0
- package/rcode/skills/seo/seo-site-builder/rules/01-niche-discovery.md +64 -0
- package/rcode/skills/seo/seo-site-builder/rules/02-deep-research.md +164 -0
- package/rcode/skills/seo/seo-site-builder/rules/03-keyword-strategy.md +82 -0
- package/rcode/skills/seo/seo-site-builder/rules/04-content-plan.md +173 -0
- package/rcode/skills/seo/seo-site-builder/rules/05-site-build.md +187 -0
- package/rcode/skills/seo/seo-site-builder/rules/06-yolo.md +127 -0
- package/rcode/skills/seo/seo-site-builder/templates/article-stub.mdx +62 -0
- package/rcode/skills/seo/seo-site-builder/templates/image-prompt.md +97 -0
- package/rcode/skills/seo/seo-site-builder/templates/keyword-export.md +45 -0
- package/rcode/skills/seo/seo-site-builder/templates/niche-scorecard.md +28 -0
- package/rcode/skills/seo/technical-seo-checker/SKILL.md +329 -0
- package/rcode/skills/seo/technical-seo-checker/references/bulk-audit-playbook.md +118 -0
- package/rcode/skills/seo/technical-seo-checker/references/ecommerce-platform-patterns.md +166 -0
- package/rcode/skills/seo/technical-seo-checker/references/http-status-codes.md +705 -0
- package/rcode/skills/seo/technical-seo-checker/references/llm-crawler-handling.md +257 -0
- package/rcode/skills/seo/technical-seo-checker/references/pre-migration-playbook.md +137 -0
- package/rcode/skills/seo/technical-seo-checker/references/robots-txt-reference.md +717 -0
- package/rcode/skills/seo/technical-seo-checker/references/technical-audit-example.md +169 -0
- package/rcode/skills/seo/technical-seo-checker/references/technical-audit-templates.md +436 -0
- package/rcode/templates/settings-hooks.json +4 -0
- package/rcode/workflows/do.md +16 -0
- package/rcode/workflows/execute-sprint.md +22 -0
- package/rcode/workflows/execute.md +17 -3
- package/rcode/workflows/new-milestone.md +21 -9
- package/rcode/workflows/new-project-create-roadmap.md +2 -0
- package/rcode/workflows/new-project-roadmap.md +2 -0
- package/rcode/workflows/new-project.md +3 -0
- package/rcode/workflows/plan.md +15 -2
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
* pre-compact — refresh HANDOFF.json before context compaction (#743)
|
|
11
11
|
* stop-verify — syntax-check files changed during the response (#744)
|
|
12
12
|
* cost-track — append per-response token usage to cost.jsonl (#745)
|
|
13
|
+
* stop — unified Stop hook: hedging-language detection (#744) + token logging (#745)
|
|
13
14
|
* compact-nudge — advise /rcode-trim or /clear after N Edit/Write calls (#749)
|
|
15
|
+
* pre-tool-use — stderr warning before large file reads to avoid context bloat (#749)
|
|
14
16
|
* prompt-router — nudge toward rcode commands for memory consistency (#892)
|
|
15
17
|
*
|
|
16
18
|
* All subcommands read stdin JSON from the hook execution context.
|
|
@@ -621,136 +623,15 @@ async function costTrack() {
|
|
|
621
623
|
}
|
|
622
624
|
}
|
|
623
625
|
|
|
624
|
-
//
|
|
625
|
-
//
|
|
626
|
-
//
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
// (Sprint 38.3).
|
|
634
|
-
//
|
|
635
|
-
// Order: first-match-wins, mirroring do.md's "Apply the first matching rule".
|
|
636
|
-
// More-specific keyword sets come before broad ones.
|
|
637
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
638
|
-
const INTENT_TABLE = [
|
|
639
|
-
// do.md: "Starting a new project, 'set up', 'initialize'" → /rcode-new-project
|
|
640
|
-
{
|
|
641
|
-
intent: 'new-project',
|
|
642
|
-
keywords: ['set up a new project', 'initialize a new project', 'start a new project', 'create a new project'],
|
|
643
|
-
command: '/rcode-new-project',
|
|
644
|
-
},
|
|
645
|
-
// do.md: "Mapping or analyzing an existing codebase" → /rcode-map-codebase
|
|
646
|
-
{
|
|
647
|
-
intent: 'map-codebase',
|
|
648
|
-
keywords: ['map the codebase', 'map this codebase', 'analyze the codebase', 'analyse the codebase', 'map existing codebase'],
|
|
649
|
-
command: '/rcode-map-codebase',
|
|
650
|
-
},
|
|
651
|
-
// do.md: "A bug, error, crash, failure, or something broken" → /rcode-debug
|
|
652
|
-
// 'error' alone is too broad (matches "what does this error mean?" etc.).
|
|
653
|
-
// Use multi-word forms that signal debug intent rather than a question.
|
|
654
|
-
{
|
|
655
|
-
intent: 'debug',
|
|
656
|
-
keywords: ['bug', 'getting an error', 'throwing an error', 'error in the', 'fix the error', 'debug this', 'crash', 'failure', 'broken', 'not working', 'fails', 'exception', 'traceback'],
|
|
657
|
-
command: '/rcode-debug',
|
|
658
|
-
},
|
|
659
|
-
// do.md: "Audit code quality, 'review changes', 'karpathy', 'check my diff', 'too complex'" → /rcode-review --karpathy
|
|
660
|
-
{
|
|
661
|
-
intent: 'audit-karpathy',
|
|
662
|
-
keywords: ['audit', 'review changes', 'check my diff', 'karpathy', 'too complex', 'complexity', 'code review'],
|
|
663
|
-
command: '/rcode-review --karpathy',
|
|
664
|
-
},
|
|
665
|
-
// do.md: "Make it simpler, 'be lazy', 'simplest solution', 'yagni', 'over-engineered'" → /rcode-lazy
|
|
666
|
-
// Generative simplicity lens (before code is written); /rcode-trim removes bloat after.
|
|
667
|
-
// 'simplify' alone is too broad (overlaps rcode-trim's existing-code territory) — use intent-bearing phrases.
|
|
668
|
-
{
|
|
669
|
-
intent: 'lazy',
|
|
670
|
-
keywords: ['be lazy', 'lazy mode', 'simplest solution', 'yagni', 'over-engineered', 'over-engineering', 'kam code likho'],
|
|
671
|
-
command: '/rcode-lazy',
|
|
672
|
-
},
|
|
673
|
-
// do.md: "Walk through a change, 'checkpoint', 'explain this diff', 'human review'" → /rcode-checkpoint-preview
|
|
674
|
-
{
|
|
675
|
-
intent: 'checkpoint',
|
|
676
|
-
keywords: ['checkpoint', 'explain this diff', 'human review', 'walk through the change', 'walk through this change'],
|
|
677
|
-
command: '/rcode-checkpoint-preview',
|
|
678
|
-
},
|
|
679
|
-
// do.md: "Brainstorm, generate ideas, 'explore options', 'what could we do'" → /rcode-brainstorm
|
|
680
|
-
{
|
|
681
|
-
intent: 'brainstorm',
|
|
682
|
-
keywords: ['brainstorm', 'generate ideas', 'explore options', 'what could we do', 'ideate', 'ideas for'],
|
|
683
|
-
command: '/rcode-brainstorm',
|
|
684
|
-
},
|
|
685
|
-
// do.md: "Exploring, researching, comparing, or 'how does X work'" → /rcode-research-phase
|
|
686
|
-
// 'research' alone fires on "based on my research..." (past-tense reference, not navigation intent).
|
|
687
|
-
// 'how does'/'how do' fire on any factual question — removed in favour of intent-bearing phrases.
|
|
688
|
-
{
|
|
689
|
-
intent: 'explore',
|
|
690
|
-
keywords: ['explore', 'research phase', 'do some research', 'comparing', 'investigate', 'look into', 'understand how'],
|
|
691
|
-
command: '/rcode-research-phase',
|
|
692
|
-
},
|
|
693
|
-
// do.md: "Scope unclear, 'which one', 'better UX', 'how should X look'" → /rcode-discuss-phase
|
|
694
|
-
{
|
|
695
|
-
intent: 'discuss',
|
|
696
|
-
keywords: ['which one', 'better ux', 'how should', 'still have confusion', 'conflicting', 'discuss the scope', 'design this', 'architect this'],
|
|
697
|
-
command: '/rcode-discuss-phase',
|
|
698
|
-
},
|
|
699
|
-
// do.md: "A complex task: refactoring, migration, multi-file architecture, system redesign,
|
|
700
|
-
// integrating a new system/service" → /rcode-add-phase
|
|
701
|
-
// 'integration'/'integrate' catch "let's do X integration", "integrate with Y" — feature-sized
|
|
702
|
-
// architectural work that belongs in a phase, not an ad-hoc edit (#907).
|
|
703
|
-
// Known mild false-positive: "run the integration tests" also matches → a harmless soft
|
|
704
|
-
// nudge toward /rcode-add-phase. Accepted: catching real integration work outweighs it,
|
|
705
|
-
// and no clean substring separates "X integration" from "integration test".
|
|
706
|
-
{
|
|
707
|
-
intent: 'add-phase',
|
|
708
|
-
keywords: ['refactor', 'migration', 'multi-file', 'system redesign', 'multi file', 'large refactor', 'architectural', 'integration', 'integrate'],
|
|
709
|
-
command: '/rcode-add-phase',
|
|
710
|
-
},
|
|
711
|
-
// do.md: "'Sprint planning', 'plan the sprint', 'next sprint'" → /rcode-sprint-planning
|
|
712
|
-
{
|
|
713
|
-
intent: 'sprint-planning',
|
|
714
|
-
keywords: ['sprint planning', 'plan the sprint', 'next sprint', 'what\'s in this sprint', "what's in this sprint"],
|
|
715
|
-
command: '/rcode-sprint-planning',
|
|
716
|
-
},
|
|
717
|
-
// do.md: "Executing a sprint, 'run the sprint', 'start sprint'" → /rcode-execute-sprint
|
|
718
|
-
{
|
|
719
|
-
intent: 'execute-sprint',
|
|
720
|
-
keywords: ['run the sprint', 'start sprint', 'execute sprint', 'work on sprint'],
|
|
721
|
-
command: '/rcode-execute-sprint',
|
|
722
|
-
},
|
|
723
|
-
// do.md: "Planning a specific phase, 'plan phase N'" → /rcode-plan
|
|
724
|
-
{
|
|
725
|
-
intent: 'plan',
|
|
726
|
-
keywords: ["let's plan", 'plan phase', 'plan this', 'let me plan', 'planning phase', 'create a plan', 'please plan', 'plan and think', 'scope this', 'scope the feature'],
|
|
727
|
-
command: '/rcode-plan',
|
|
728
|
-
},
|
|
729
|
-
// do.md: "'Create milestones', 'plan milestones', 'create roadmap'" → /rcode-new-milestone
|
|
730
|
-
{
|
|
731
|
-
intent: 'new-milestone',
|
|
732
|
-
keywords: ['create milestones', 'plan milestones', 'create roadmap', 'break project into milestones', 'new milestone', 'what milestones'],
|
|
733
|
-
command: '/rcode-new-milestone',
|
|
734
|
-
},
|
|
735
|
-
// do.md: "Break milestone into epics/stories, 'create stories', 'user stories', 'epics'" → /rcode-create-epics-and-stories
|
|
736
|
-
{
|
|
737
|
-
intent: 'epics-stories',
|
|
738
|
-
keywords: ['create epics', 'user stories', 'create stories', 'epics and stories', 'break into epics'],
|
|
739
|
-
command: '/rcode-create-epics-and-stories',
|
|
740
|
-
},
|
|
741
|
-
// do.md: "Drift / out-of-date / 'audit feature docs' / 'fill out existing PRD'" → /rcode-feature-drift
|
|
742
|
-
{
|
|
743
|
-
intent: 'feature-drift',
|
|
744
|
-
keywords: ['out of date', 'out-of-date', 'verify docs', 'audit feature docs', 'fill out existing', 'prd drift', 'docs vs code'],
|
|
745
|
-
command: '/rcode-feature-drift',
|
|
746
|
-
},
|
|
747
|
-
// do.md: "General audit / re-audit / extend / fill out / expand an existing artifact" → /rcode-audit
|
|
748
|
-
{
|
|
749
|
-
intent: 'audit',
|
|
750
|
-
keywords: ['re-audit', 'extend the audit', 'fill out the', 'expand the', 're audit'],
|
|
751
|
-
command: '/rcode-audit',
|
|
752
|
-
},
|
|
753
|
-
];
|
|
626
|
+
// INTENT_TABLE — keyword map for prompt-router (#892).
|
|
627
|
+
// Source of truth: rcode/workflows/do.md routing table (~285-320). First-match-wins.
|
|
628
|
+
// Loaded from data file to keep this file under 1000 lines (#896).
|
|
629
|
+
const INTENT_TABLE = JSON.parse(
|
|
630
|
+
require('fs').readFileSync(
|
|
631
|
+
require('path').join(__dirname, '..', 'data', 'intent-table.json'),
|
|
632
|
+
'utf8'
|
|
633
|
+
)
|
|
634
|
+
);
|
|
754
635
|
|
|
755
636
|
/**
|
|
756
637
|
* Inline flat-YAML parser — mirrors parseSimpleYaml in rcode-tools.cjs:91.
|
|
@@ -792,13 +673,8 @@ function readPromptNudgeToggle(cwd) {
|
|
|
792
673
|
}
|
|
793
674
|
|
|
794
675
|
/**
|
|
795
|
-
*
|
|
796
|
-
*
|
|
797
|
-
* Heuristic: fire when .rcode/state.json exists AND its mtime is older than
|
|
798
|
-
* the most recent git commit timestamp, OR when state.json is absent in a
|
|
799
|
-
* .planning/ project. This is cheap and best-effort — if any check fails the
|
|
800
|
-
* function returns true (treat as stale = fire). All I/O is wrapped in
|
|
801
|
-
* try/catch to preserve the fail-open contract.
|
|
676
|
+
* Returns true when state.json is older than the last commit, or absent in a .planning/ project.
|
|
677
|
+
* Fail-open: returns true on any I/O error so the nudge fires rather than silently skips.
|
|
802
678
|
*/
|
|
803
679
|
function isStateStaleFallbackTrue(cwd) {
|
|
804
680
|
try {
|
|
@@ -830,14 +706,9 @@ function isStateStaleFallbackTrue(cwd) {
|
|
|
830
706
|
}
|
|
831
707
|
|
|
832
708
|
/**
|
|
833
|
-
* prompt-router: Nudge
|
|
834
|
-
*
|
|
835
|
-
*
|
|
836
|
-
* cli/rcode-slash-router.cjs — NOT the async readInputJson() which rejects on
|
|
837
|
-
* bad JSON). Keyword-matches against INTENT_TABLE (derived from
|
|
838
|
-
* rcode/workflows/do.md lines ~285-320). On match, emits a one-line advisory
|
|
839
|
-
* via hookSpecificOutput.additionalContext. Gated by prompt_nudge config toggle.
|
|
840
|
-
* Always exits 0 with no output on any error or non-match.
|
|
709
|
+
* prompt-router: Nudge toward rcode commands for memory consistency (#892).
|
|
710
|
+
* Reads stdin synchronously (NOT async — rejects bad JSON). Keyword-matches INTENT_TABLE,
|
|
711
|
+
* emits additionalContext advisory. Gated by prompt_nudge config. Always exits 0.
|
|
841
712
|
*/
|
|
842
713
|
function promptRouter() {
|
|
843
714
|
try {
|
|
@@ -956,11 +827,7 @@ function promptRouter() {
|
|
|
956
827
|
|
|
957
828
|
/**
|
|
958
829
|
* compact-nudge: Advise /rcode-trim or /clear after N Edit/Write calls (#749).
|
|
959
|
-
*
|
|
960
|
-
* Triggered by the PreToolUse:Edit|Write hook. Maintains a per-session call
|
|
961
|
-
* counter in a temp file and, once the count crosses RCODE_NUDGE_THRESHOLD
|
|
962
|
-
* (default 50), prints an advisory to reclaim context budget. Purely
|
|
963
|
-
* advisory — always exits 0, never blocks a tool call.
|
|
830
|
+
* Maintains a per-session counter; warns at RCODE_NUDGE_THRESHOLD (default 50). Advisory only.
|
|
964
831
|
*/
|
|
965
832
|
async function compactNudge() {
|
|
966
833
|
try {
|
|
@@ -998,6 +865,84 @@ async function compactNudge() {
|
|
|
998
865
|
}
|
|
999
866
|
}
|
|
1000
867
|
|
|
868
|
+
/** Returns true when a Read/Bash targets known large planning files (RESEARCH/SUMMARY/ROADMAP). */
|
|
869
|
+
function shouldNudgeCompact(toolName, toolInput) {
|
|
870
|
+
if (toolName !== 'Read' && toolName !== 'Bash') return false;
|
|
871
|
+
const target = toolInput?.file_path || toolInput?.command || '';
|
|
872
|
+
return /RESEARCH\.md|SUMMARY\.md|ROADMAP\.md/.test(target);
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
/**
|
|
876
|
+
* pre-tool-use: Strategic compact nudge before large file reads (#749).
|
|
877
|
+
*
|
|
878
|
+
* Triggered by the PreToolUse hook (Read + Bash tool names). Checks whether
|
|
879
|
+
* the tool call targets a known large planning file and, if so, writes an
|
|
880
|
+
* advisory line to stderr so the executor sees it without being interrupted.
|
|
881
|
+
* Always exits 0 — never blocks the tool call.
|
|
882
|
+
*/
|
|
883
|
+
async function preToolUse() {
|
|
884
|
+
try {
|
|
885
|
+
const input = await readInputJson();
|
|
886
|
+
const toolName = input.tool_name || input.toolName || '';
|
|
887
|
+
const toolInput = input.tool_input || input.toolInput || {};
|
|
888
|
+
|
|
889
|
+
if (shouldNudgeCompact(toolName, toolInput)) {
|
|
890
|
+
process.stderr.write(
|
|
891
|
+
'[rcode] Context nearing limit — consider /compact before the next large file read\n'
|
|
892
|
+
);
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
process.exit(0);
|
|
896
|
+
} catch {
|
|
897
|
+
// Advisory hook must never break the session.
|
|
898
|
+
process.exit(0);
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
/**
|
|
903
|
+
* stop: Stop hook — hedging-language detection (#744) + token/cost logging (#745).
|
|
904
|
+
* Warns when response text suggests incomplete execution ("I'll implement this", etc.).
|
|
905
|
+
* Appends per-response token usage to ~/.rcode/logs/token-usage.jsonl.
|
|
906
|
+
* Rates: $3/M input, $15/M output (Sonnet 4.x approximation).
|
|
907
|
+
* Never blocks.
|
|
908
|
+
*/
|
|
909
|
+
async function stopHandler() {
|
|
910
|
+
try {
|
|
911
|
+
const input = await readInputJson();
|
|
912
|
+
const responseText = input?.response || '';
|
|
913
|
+
const HEDGING_PATTERNS = [
|
|
914
|
+
/I'll\s+implement\s+this/i,
|
|
915
|
+
/I\s+would\s+add/i,
|
|
916
|
+
/you\s+could\s+add/i,
|
|
917
|
+
/TODO:/,
|
|
918
|
+
];
|
|
919
|
+
const incomplete = HEDGING_PATTERNS.some((re) => re.test(responseText));
|
|
920
|
+
if (incomplete) {
|
|
921
|
+
process.stderr.write(
|
|
922
|
+
'[rcode] Stop hook: response contains hedging language — verify implementation is complete\n'
|
|
923
|
+
);
|
|
924
|
+
}
|
|
925
|
+
const usage = input?.usage;
|
|
926
|
+
if (usage && typeof usage === 'object') {
|
|
927
|
+
const logDir = path.join(os.homedir(), '.rcode', 'logs');
|
|
928
|
+
fs.mkdirSync(logDir, { recursive: true });
|
|
929
|
+
const entry = JSON.stringify({
|
|
930
|
+
ts: new Date().toISOString(),
|
|
931
|
+
input: usage.input_tokens || 0,
|
|
932
|
+
output: usage.output_tokens || 0,
|
|
933
|
+
cost_usd:
|
|
934
|
+
((usage.input_tokens || 0) * 3) / 1e6 +
|
|
935
|
+
((usage.output_tokens || 0) * 15) / 1e6,
|
|
936
|
+
});
|
|
937
|
+
fs.appendFileSync(path.join(logDir, 'token-usage.jsonl'), entry + '\n');
|
|
938
|
+
}
|
|
939
|
+
process.exit(0);
|
|
940
|
+
} catch (err) {
|
|
941
|
+
console.error(`Hook error: ${err.message}`);
|
|
942
|
+
process.exit(1);
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
|
|
1001
946
|
/**
|
|
1002
947
|
* Main entry point.
|
|
1003
948
|
*/
|
|
@@ -1026,15 +971,21 @@ async function main() {
|
|
|
1026
971
|
case 'cost-track':
|
|
1027
972
|
await costTrack();
|
|
1028
973
|
break;
|
|
974
|
+
case 'stop':
|
|
975
|
+
await stopHandler();
|
|
976
|
+
break;
|
|
1029
977
|
case 'compact-nudge':
|
|
1030
978
|
await compactNudge();
|
|
1031
979
|
break;
|
|
980
|
+
case 'pre-tool-use':
|
|
981
|
+
await preToolUse();
|
|
982
|
+
break;
|
|
1032
983
|
case 'prompt-router':
|
|
1033
984
|
promptRouter(); // synchronous — exits inside; never falls through to async path
|
|
1034
985
|
break;
|
|
1035
986
|
default:
|
|
1036
987
|
console.error(`Unknown subcommand: ${subcommand}`);
|
|
1037
|
-
console.error('Usage: rcode-hooks.cjs pre-edit|pre-workflow|post-commit|bash-guard|pre-compact|stop-verify|cost-track|compact-nudge|prompt-router');
|
|
988
|
+
console.error('Usage: rcode-hooks.cjs pre-edit|pre-workflow|post-commit|bash-guard|pre-compact|stop-verify|cost-track|stop|compact-nudge|pre-tool-use|prompt-router');
|
|
1038
989
|
process.exit(1);
|
|
1039
990
|
}
|
|
1040
991
|
}
|