@rune-kit/rune 2.8.0 → 2.11.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/LICENSE +21 -21
- package/README.md +68 -34
- package/agents/adversary.md +27 -0
- package/agents/architect.md +19 -29
- package/agents/asset-creator.md +18 -4
- package/agents/audit.md +25 -4
- package/agents/autopsy.md +19 -4
- package/agents/ba.md +35 -0
- package/agents/brainstorm.md +31 -4
- package/agents/browser-pilot.md +21 -4
- package/agents/coder.md +21 -29
- package/agents/completion-gate.md +20 -4
- package/agents/constraint-check.md +18 -4
- package/agents/context-engine.md +22 -4
- package/agents/context-pack.md +32 -0
- package/agents/cook.md +41 -4
- package/agents/db.md +19 -4
- package/agents/debug.md +33 -4
- package/agents/dependency-doctor.md +20 -4
- package/agents/deploy.md +27 -4
- package/agents/design.md +22 -4
- package/agents/doc-processor.md +27 -0
- package/agents/docs-seeker.md +19 -4
- package/agents/docs.md +31 -0
- package/agents/fix.md +37 -4
- package/agents/git.md +29 -0
- package/agents/hallucination-guard.md +20 -4
- package/agents/incident.md +21 -4
- package/agents/integrity-check.md +18 -4
- package/agents/journal.md +19 -4
- package/agents/launch.md +32 -4
- package/agents/logic-guardian.md +26 -11
- package/agents/marketing.md +23 -4
- package/agents/mcp-builder.md +26 -0
- package/agents/neural-memory.md +30 -0
- package/agents/onboard.md +22 -4
- package/agents/perf.md +21 -4
- package/agents/plan.md +29 -4
- package/agents/preflight.md +22 -4
- package/agents/problem-solver.md +20 -4
- package/agents/rescue.md +23 -4
- package/agents/research.md +19 -4
- package/agents/researcher.md +19 -29
- package/agents/retro.md +32 -0
- package/agents/review-intake.md +20 -4
- package/agents/review.md +32 -4
- package/agents/reviewer.md +20 -28
- package/agents/safeguard.md +19 -4
- package/agents/sast.md +18 -4
- package/agents/scaffold.md +41 -0
- package/agents/scanner.md +19 -28
- package/agents/scope-guard.md +18 -4
- package/agents/scout.md +23 -4
- package/agents/sentinel-env.md +26 -0
- package/agents/sentinel.md +33 -4
- package/agents/sequential-thinking.md +20 -4
- package/agents/session-bridge.md +24 -4
- package/agents/skill-forge.md +22 -4
- package/agents/skill-router.md +26 -4
- package/agents/slides.md +24 -0
- package/agents/surgeon.md +19 -4
- package/agents/team.md +30 -4
- package/agents/test.md +36 -4
- package/agents/trend-scout.md +17 -4
- package/agents/verification.md +20 -4
- package/agents/video-creator.md +20 -4
- package/agents/watchdog.md +19 -4
- package/agents/worktree.md +17 -4
- package/commands/rune.md +168 -168
- package/compiler/__tests__/analytics.test.js +370 -0
- package/compiler/adapters/openclaw.js +2 -2
- package/compiler/analytics.js +385 -0
- package/compiler/bin/rune.js +68 -2
- package/compiler/dashboard.js +883 -0
- package/compiler/transforms/branding.js +1 -1
- package/contexts/dev.md +34 -34
- package/contexts/research.md +43 -43
- package/contexts/review.md +55 -55
- package/extensions/ai-ml/PACK.md +88 -88
- package/extensions/ai-ml/skills/ai-agents.md +172 -172
- package/extensions/ai-ml/skills/code-sandbox.md +187 -187
- package/extensions/ai-ml/skills/deep-research.md +146 -146
- package/extensions/ai-ml/skills/embedding-search.md +66 -66
- package/extensions/ai-ml/skills/fine-tuning-guide.md +74 -74
- package/extensions/ai-ml/skills/llm-architect.md +125 -125
- package/extensions/ai-ml/skills/llm-integration.md +64 -64
- package/extensions/ai-ml/skills/prompt-patterns.md +72 -72
- package/extensions/ai-ml/skills/rag-patterns.md +66 -66
- package/extensions/ai-ml/skills/web-extraction.md +114 -114
- package/extensions/analytics/PACK.md +92 -92
- package/extensions/analytics/skills/ab-testing.md +72 -72
- package/extensions/analytics/skills/dashboard-patterns.md +83 -83
- package/extensions/analytics/skills/data-validation.md +68 -68
- package/extensions/analytics/skills/funnel-analysis.md +81 -81
- package/extensions/analytics/skills/sql-patterns.md +57 -57
- package/extensions/analytics/skills/statistical-analysis.md +79 -79
- package/extensions/analytics/skills/tracking-setup.md +71 -71
- package/extensions/backend/PACK.md +104 -104
- package/extensions/backend/skills/api-patterns.md +84 -84
- package/extensions/backend/skills/async-pipeline.md +193 -193
- package/extensions/backend/skills/auth-patterns.md +97 -97
- package/extensions/backend/skills/background-jobs.md +133 -133
- package/extensions/backend/skills/caching-patterns.md +108 -108
- package/extensions/backend/skills/cli-generation.md +133 -133
- package/extensions/backend/skills/database-patterns.md +87 -87
- package/extensions/backend/skills/middleware-patterns.md +104 -104
- package/extensions/chrome-ext/PACK.md +93 -93
- package/extensions/chrome-ext/skills/cws-preflight.md +143 -143
- package/extensions/chrome-ext/skills/cws-publish.md +104 -104
- package/extensions/chrome-ext/skills/ext-ai-integration.md +251 -251
- package/extensions/chrome-ext/skills/ext-messaging.md +139 -139
- package/extensions/chrome-ext/skills/ext-storage.md +133 -133
- package/extensions/chrome-ext/skills/mv3-scaffold.md +164 -164
- package/extensions/content/PACK.md +96 -96
- package/extensions/content/skills/blog-patterns.md +88 -88
- package/extensions/content/skills/cms-integration.md +131 -131
- package/extensions/content/skills/content-scoring.md +107 -107
- package/extensions/content/skills/i18n.md +83 -83
- package/extensions/content/skills/mdx-authoring.md +137 -137
- package/extensions/content/skills/reference.md +1014 -1014
- package/extensions/content/skills/seo-patterns.md +67 -67
- package/extensions/content/skills/video-repurpose.md +153 -153
- package/extensions/devops/PACK.md +101 -101
- package/extensions/devops/skills/chaos-testing.md +67 -67
- package/extensions/devops/skills/ci-cd.md +75 -75
- package/extensions/devops/skills/docker.md +58 -58
- package/extensions/devops/skills/edge-serverless.md +163 -163
- package/extensions/devops/skills/infra-as-code.md +158 -158
- package/extensions/devops/skills/kubernetes.md +110 -110
- package/extensions/devops/skills/monitoring.md +57 -57
- package/extensions/devops/skills/server-setup.md +64 -64
- package/extensions/devops/skills/ssl-domain.md +42 -42
- package/extensions/ecommerce/PACK.md +116 -116
- package/extensions/ecommerce/skills/cart-system.md +79 -79
- package/extensions/ecommerce/skills/inventory-mgmt.md +102 -102
- package/extensions/ecommerce/skills/order-management.md +126 -126
- package/extensions/ecommerce/skills/payment-integration.md +472 -472
- package/extensions/ecommerce/skills/shopify-dev.md +69 -69
- package/extensions/ecommerce/skills/subscription-billing.md +93 -93
- package/extensions/ecommerce/skills/tax-compliance.md +117 -117
- package/extensions/gamedev/PACK.md +142 -142
- package/extensions/gamedev/skills/asset-pipeline.md +74 -74
- package/extensions/gamedev/skills/audio-system.md +129 -129
- package/extensions/gamedev/skills/camera-system.md +87 -87
- package/extensions/gamedev/skills/ecs.md +98 -98
- package/extensions/gamedev/skills/game-loops.md +72 -72
- package/extensions/gamedev/skills/input-system.md +199 -199
- package/extensions/gamedev/skills/multiplayer.md +180 -180
- package/extensions/gamedev/skills/particles.md +105 -105
- package/extensions/gamedev/skills/physics-engine.md +89 -89
- package/extensions/gamedev/skills/scene-management.md +146 -146
- package/extensions/gamedev/skills/threejs-patterns.md +90 -90
- package/extensions/gamedev/skills/webgl.md +71 -71
- package/extensions/mobile/PACK.md +106 -106
- package/extensions/mobile/skills/app-store-connect.md +152 -152
- package/extensions/mobile/skills/app-store-prep.md +66 -66
- package/extensions/mobile/skills/deep-linking.md +109 -109
- package/extensions/mobile/skills/flutter.md +60 -60
- package/extensions/mobile/skills/ios-build-pipeline.md +142 -142
- package/extensions/mobile/skills/native-bridge.md +66 -66
- package/extensions/mobile/skills/ota-updates.md +97 -97
- package/extensions/mobile/skills/push-notifications.md +111 -111
- package/extensions/mobile/skills/react-native.md +82 -82
- package/extensions/saas/PACK.md +116 -116
- package/extensions/saas/skills/billing-integration.md +200 -200
- package/extensions/saas/skills/feature-flags.md +130 -130
- package/extensions/saas/skills/multi-tenant.md +103 -103
- package/extensions/saas/skills/onboarding-flow.md +139 -139
- package/extensions/saas/skills/subscription-flow.md +95 -95
- package/extensions/saas/skills/team-management.md +144 -144
- package/extensions/security/PACK.md +99 -99
- package/extensions/security/skills/api-security.md +140 -140
- package/extensions/security/skills/compliance.md +68 -68
- package/extensions/security/skills/owasp-audit.md +64 -64
- package/extensions/security/skills/pentest-patterns.md +77 -77
- package/extensions/security/skills/secret-mgmt.md +65 -65
- package/extensions/security/skills/supply-chain.md +65 -65
- package/extensions/trading/PACK.md +80 -80
- package/extensions/trading/skills/chart-components.md +55 -55
- package/extensions/trading/skills/experiment-loop.md +125 -125
- package/extensions/trading/skills/fintech-patterns.md +47 -47
- package/extensions/trading/skills/indicator-library.md +58 -58
- package/extensions/trading/skills/quant-analysis.md +111 -111
- package/extensions/trading/skills/realtime-data.md +58 -58
- package/extensions/trading/skills/trade-logic.md +104 -104
- package/extensions/ui/PACK.md +130 -130
- package/extensions/ui/skills/a11y-audit.md +91 -91
- package/extensions/ui/skills/animation-patterns.md +127 -106
- package/extensions/ui/skills/component-patterns.md +100 -75
- package/extensions/ui/skills/design-decision.md +108 -108
- package/extensions/ui/skills/design-system.md +68 -68
- package/extensions/ui/skills/landing-patterns.md +155 -155
- package/extensions/ui/skills/palette-picker.md +173 -173
- package/extensions/ui/skills/react-health.md +90 -90
- package/extensions/ui/skills/type-system.md +125 -125
- package/extensions/ui/skills/web-vitals.md +153 -153
- package/extensions/zalo/PACK.md +145 -145
- package/extensions/zalo/skills/zalo-oa-mcp.md +317 -317
- package/extensions/zalo/skills/zalo-oa-messaging.md +429 -429
- package/extensions/zalo/skills/zalo-oa-setup.md +236 -236
- package/extensions/zalo/skills/zalo-oa-webhook.md +189 -189
- package/extensions/zalo/skills/zalo-personal-messaging.md +194 -194
- package/extensions/zalo/skills/zalo-personal-setup.md +153 -153
- package/extensions/zalo/skills/zalo-rate-guard.md +219 -219
- package/hooks/auto-format/index.cjs +48 -48
- package/hooks/context-watch/index.cjs +95 -68
- package/hooks/hooks.json +111 -111
- package/hooks/metrics-collector/index.cjs +86 -42
- package/hooks/post-session-reflect/index.cjs +189 -153
- package/hooks/pre-compact/index.cjs +95 -95
- package/hooks/run-hook.cmd +1 -1
- package/hooks/secrets-scan/index.cjs +100 -100
- package/hooks/session-start/index.cjs +71 -65
- package/hooks/typecheck/index.cjs +65 -65
- package/package.json +63 -63
- package/references/ui-pro-max-data/LICENSE-UI-PRO-MAX +21 -21
- package/references/ui-pro-max-data/charts.csv +26 -26
- package/references/ui-pro-max-data/colors.csv +161 -161
- package/references/ui-pro-max-data/styles.csv +68 -68
- package/references/ui-pro-max-data/typography.csv +74 -74
- package/references/ui-pro-max-data/ui-reasoning.csv +162 -162
- package/references/ui-pro-max-data/ux-guidelines.csv +99 -99
- package/skills/adversary/SKILL.md +283 -283
- package/skills/asset-creator/SKILL.md +157 -157
- package/skills/audit/SKILL.md +148 -2
- package/skills/autopsy/SKILL.md +335 -259
- package/skills/autopsy/references/repo-analysis-patterns.md +113 -0
- package/skills/ba/SKILL.md +72 -2
- package/skills/brainstorm/SKILL.md +342 -341
- package/skills/browser-pilot/SKILL.md +168 -168
- package/skills/constraint-check/SKILL.md +165 -165
- package/skills/context-engine/SKILL.md +404 -404
- package/skills/cook/SKILL.md +917 -834
- package/skills/cook/references/output-format.md +33 -0
- package/skills/db/SKILL.md +273 -272
- package/skills/debug/SKILL.md +465 -443
- package/skills/dependency-doctor/SKILL.md +265 -235
- package/skills/deploy/SKILL.md +274 -231
- package/skills/design/DESIGN-REFERENCE.md +365 -365
- package/skills/design/SKILL.md +589 -482
- package/skills/doc-processor/SKILL.md +254 -254
- package/skills/docs/SKILL.md +374 -373
- package/skills/docs-seeker/SKILL.md +177 -177
- package/skills/fix/SKILL.md +330 -308
- package/skills/git/SKILL.md +339 -339
- package/skills/graft/SKILL.md +352 -0
- package/skills/graft/references/challenge-framework.md +98 -0
- package/skills/graft/references/mode-decision.md +44 -0
- package/skills/hallucination-guard/SKILL.md +219 -219
- package/skills/incident/SKILL.md +254 -251
- package/skills/integrity-check/SKILL.md +169 -169
- package/skills/journal/SKILL.md +240 -238
- package/skills/launch/SKILL.md +344 -342
- package/skills/logic-guardian/SKILL.md +251 -251
- package/skills/marketing/SKILL.md +290 -245
- package/skills/mcp-builder/SKILL.md +425 -423
- package/skills/mcp-builder/references/auto-discovery-pattern.md +169 -0
- package/skills/neural-memory/SKILL.md +362 -362
- package/skills/onboard/SKILL.md +404 -403
- package/skills/perf/SKILL.md +346 -346
- package/skills/plan/SKILL.md +433 -370
- package/skills/plan/references/feature-map.md +84 -0
- package/skills/preflight/SKILL.md +415 -396
- package/skills/problem-solver/SKILL.md +380 -284
- package/skills/rescue/SKILL.md +474 -450
- package/skills/retro/SKILL.md +5 -1
- package/skills/review/SKILL.md +612 -535
- package/skills/review-intake/SKILL.md +249 -249
- package/skills/safeguard/SKILL.md +200 -200
- package/skills/sast/SKILL.md +190 -190
- package/skills/scaffold/SKILL.md +328 -286
- package/skills/scope-guard/SKILL.md +180 -162
- package/skills/scout/SKILL.md +263 -263
- package/skills/sentinel/SKILL.md +382 -353
- package/skills/sentinel-env/SKILL.md +254 -254
- package/skills/sequential-thinking/SKILL.md +234 -234
- package/skills/session-bridge/SKILL.md +543 -397
- package/skills/skill-forge/SKILL.md +581 -539
- package/skills/skill-router/{skill.md → SKILL.md} +30 -2
- package/skills/surgeon/SKILL.md +215 -215
- package/skills/team/SKILL.md +556 -514
- package/skills/test/SKILL.md +614 -587
- package/skills/trend-scout/SKILL.md +145 -145
- package/skills/verification/SKILL.md +326 -325
- package/skills/video-creator/SKILL.md +201 -201
- package/skills/watchdog/SKILL.md +168 -168
- package/skills/worktree/SKILL.md +140 -140
|
@@ -1,68 +1,95 @@
|
|
|
1
|
-
// Rune Context Watch Hook
|
|
2
|
-
// Lightweight tool call counter — detects context pressure and suggests rune:context-engine
|
|
3
|
-
// Runs as PreToolUse hook on Edit/Write (high-cost operations)
|
|
4
|
-
//
|
|
5
|
-
// H3 Intelligence: also tracks tool type distribution and session start timestamp
|
|
6
|
-
// for metrics aggregation at session end.
|
|
7
|
-
//
|
|
8
|
-
// Uses a temp file counter (survives across hook invocations within same session).
|
|
9
|
-
// Zero overhead: just reads/increments a number. No token cost.
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
} catch {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
//
|
|
42
|
-
state
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
if (
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
1
|
+
// Rune Context Watch Hook
|
|
2
|
+
// Lightweight tool call counter — detects context pressure and suggests rune:context-engine
|
|
3
|
+
// Runs as PreToolUse hook on Edit/Write (high-cost operations)
|
|
4
|
+
//
|
|
5
|
+
// H3 Intelligence: also tracks tool type distribution and session start timestamp
|
|
6
|
+
// for metrics aggregation at session end.
|
|
7
|
+
//
|
|
8
|
+
// Uses a temp file counter (survives across hook invocations within same session).
|
|
9
|
+
// Zero overhead: just reads/increments a number. No token cost.
|
|
10
|
+
//
|
|
11
|
+
// Data source: stdin JSON from Claude Code (not env vars)
|
|
12
|
+
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
const os = require('os');
|
|
16
|
+
|
|
17
|
+
// Counter file scoped to current working directory (hash of cwd)
|
|
18
|
+
const cwd = process.cwd();
|
|
19
|
+
const hash = Buffer.from(cwd).toString('base64url').slice(0, 16);
|
|
20
|
+
const counterFile = path.join(os.tmpdir(), `rune-context-watch-${hash}.json`);
|
|
21
|
+
|
|
22
|
+
// Thresholds
|
|
23
|
+
const FIRST_WARNING = 40;
|
|
24
|
+
const REPEAT_INTERVAL = 20;
|
|
25
|
+
const CRITICAL_THRESHOLD = 80;
|
|
26
|
+
|
|
27
|
+
// Read stdin JSON to get tool name (Claude Code passes hook data via stdin)
|
|
28
|
+
let stdinData = '';
|
|
29
|
+
process.stdin.setEncoding('utf-8');
|
|
30
|
+
process.stdin.on('data', chunk => { stdinData += chunk; });
|
|
31
|
+
process.stdin.on('end', () => {
|
|
32
|
+
let toolName = 'unknown';
|
|
33
|
+
try {
|
|
34
|
+
const parsed = JSON.parse(stdinData);
|
|
35
|
+
toolName = parsed.tool || parsed.tool_name || 'unknown';
|
|
36
|
+
} catch {
|
|
37
|
+
// Fallback to env var for backwards compatibility
|
|
38
|
+
toolName = process.env.CLAUDE_TOOL_NAME || 'unknown';
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Read current state
|
|
42
|
+
let state = { count: 0, lastWarning: 0, sessionStart: null, sessionId: null, toolCounts: {} };
|
|
43
|
+
try {
|
|
44
|
+
const raw = fs.readFileSync(counterFile, 'utf-8');
|
|
45
|
+
state = JSON.parse(raw);
|
|
46
|
+
// Ensure fields exist (upgrade from old format)
|
|
47
|
+
if (!state.toolCounts) state.toolCounts = {};
|
|
48
|
+
if (!state.sessionStart) state.sessionStart = new Date().toISOString();
|
|
49
|
+
if (!state.sessionId) {
|
|
50
|
+
const s = state.sessionStart;
|
|
51
|
+
state.sessionId = `s-${s.slice(0, 10).replace(/-/g, '')}-${s.slice(11, 19).replace(/:/g, '')}`;
|
|
52
|
+
}
|
|
53
|
+
} catch {
|
|
54
|
+
// First run or corrupted — start fresh
|
|
55
|
+
const now = new Date().toISOString();
|
|
56
|
+
state.sessionStart = now;
|
|
57
|
+
state.sessionId = `s-${now.slice(0, 10).replace(/-/g, '')}-${now.slice(11, 19).replace(/:/g, '')}`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Increment total and per-tool counters
|
|
61
|
+
state.count += 1;
|
|
62
|
+
state.toolCounts[toolName] = (state.toolCounts[toolName] || 0) + 1;
|
|
63
|
+
|
|
64
|
+
// Check thresholds
|
|
65
|
+
const count = state.count;
|
|
66
|
+
const sinceLast = count - state.lastWarning;
|
|
67
|
+
|
|
68
|
+
if (count >= CRITICAL_THRESHOLD && sinceLast >= REPEAT_INTERVAL) {
|
|
69
|
+
console.log(`\n🔴 [Rune context-watch] ${count} tool calls — context likely RED (>85%).`);
|
|
70
|
+
console.log(' RECOMMENDED: Invoke rune:context-engine for state save + /compact.');
|
|
71
|
+
console.log(' Risk: auto-compaction may lose critical decisions without state save.\n');
|
|
72
|
+
state.lastWarning = count;
|
|
73
|
+
} else if (count >= FIRST_WARNING && sinceLast >= REPEAT_INTERVAL) {
|
|
74
|
+
console.log(`\n🟡 [Rune context-watch] ${count} tool calls — context filling up.`);
|
|
75
|
+
console.log(' Consider invoking rune:context-engine at the next logical boundary.');
|
|
76
|
+
console.log(' Or run /compact manually if at a good stopping point.\n');
|
|
77
|
+
state.lastWarning = count;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Pass through stdin to stdout (required for PreToolUse hooks)
|
|
81
|
+
if (stdinData) process.stdout.write(stdinData);
|
|
82
|
+
|
|
83
|
+
// Persist
|
|
84
|
+
try {
|
|
85
|
+
fs.writeFileSync(counterFile, JSON.stringify(state));
|
|
86
|
+
} catch {
|
|
87
|
+
// Non-critical — counter resets next run
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
process.exit(0);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// Handle empty stdin (pipe closed immediately)
|
|
94
|
+
process.stdin.on('error', () => process.exit(0));
|
|
95
|
+
process.stdin.resume();
|
package/hooks/hooks.json
CHANGED
|
@@ -1,111 +1,111 @@
|
|
|
1
|
-
{
|
|
2
|
-
"hooks": {
|
|
3
|
-
"SessionStart": [
|
|
4
|
-
{
|
|
5
|
-
"matcher": "startup|resume|clear|compact",
|
|
6
|
-
"hooks": [
|
|
7
|
-
{
|
|
8
|
-
"type": "command",
|
|
9
|
-
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cjs\" session-start",
|
|
10
|
-
"async": false
|
|
11
|
-
}
|
|
12
|
-
]
|
|
13
|
-
}
|
|
14
|
-
],
|
|
15
|
-
"UserPromptSubmit": [
|
|
16
|
-
{
|
|
17
|
-
"matcher": ".*",
|
|
18
|
-
"hooks": [
|
|
19
|
-
{
|
|
20
|
-
"type": "command",
|
|
21
|
-
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cjs\" intent-router",
|
|
22
|
-
"async": true
|
|
23
|
-
}
|
|
24
|
-
]
|
|
25
|
-
}
|
|
26
|
-
],
|
|
27
|
-
"PreToolUse": [
|
|
28
|
-
{
|
|
29
|
-
"matcher": "Read|Write|Edit",
|
|
30
|
-
"hooks": [
|
|
31
|
-
{
|
|
32
|
-
"type": "command",
|
|
33
|
-
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cjs\" pre-tool-guard",
|
|
34
|
-
"async": false
|
|
35
|
-
}
|
|
36
|
-
]
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
"matcher": "Edit|Write",
|
|
40
|
-
"hooks": [
|
|
41
|
-
{
|
|
42
|
-
"type": "command",
|
|
43
|
-
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cjs\" context-watch",
|
|
44
|
-
"async": true
|
|
45
|
-
}
|
|
46
|
-
]
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
"matcher": "Bash",
|
|
50
|
-
"hooks": [
|
|
51
|
-
{
|
|
52
|
-
"type": "command",
|
|
53
|
-
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cjs\" secrets-scan",
|
|
54
|
-
"async": false
|
|
55
|
-
}
|
|
56
|
-
]
|
|
57
|
-
}
|
|
58
|
-
],
|
|
59
|
-
"PostToolUse": [
|
|
60
|
-
{
|
|
61
|
-
"matcher": "Edit|Write",
|
|
62
|
-
"hooks": [
|
|
63
|
-
{
|
|
64
|
-
"type": "command",
|
|
65
|
-
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cjs\" auto-format",
|
|
66
|
-
"async": true
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
"type": "command",
|
|
70
|
-
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cjs\" typecheck",
|
|
71
|
-
"async": true
|
|
72
|
-
}
|
|
73
|
-
]
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
"matcher": "Skill",
|
|
77
|
-
"hooks": [
|
|
78
|
-
{
|
|
79
|
-
"type": "command",
|
|
80
|
-
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cjs\" metrics-collector",
|
|
81
|
-
"async": true
|
|
82
|
-
}
|
|
83
|
-
]
|
|
84
|
-
}
|
|
85
|
-
],
|
|
86
|
-
"PreCompact": [
|
|
87
|
-
{
|
|
88
|
-
"matcher": ".*",
|
|
89
|
-
"hooks": [
|
|
90
|
-
{
|
|
91
|
-
"type": "command",
|
|
92
|
-
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cjs\" pre-compact",
|
|
93
|
-
"async": false
|
|
94
|
-
}
|
|
95
|
-
]
|
|
96
|
-
}
|
|
97
|
-
],
|
|
98
|
-
"Stop": [
|
|
99
|
-
{
|
|
100
|
-
"matcher": ".*",
|
|
101
|
-
"hooks": [
|
|
102
|
-
{
|
|
103
|
-
"type": "command",
|
|
104
|
-
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cjs\" post-session-reflect",
|
|
105
|
-
"async": false
|
|
106
|
-
}
|
|
107
|
-
]
|
|
108
|
-
}
|
|
109
|
-
]
|
|
110
|
-
}
|
|
111
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"SessionStart": [
|
|
4
|
+
{
|
|
5
|
+
"matcher": "startup|resume|clear|compact",
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "command",
|
|
9
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cjs\" session-start",
|
|
10
|
+
"async": false
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"UserPromptSubmit": [
|
|
16
|
+
{
|
|
17
|
+
"matcher": ".*",
|
|
18
|
+
"hooks": [
|
|
19
|
+
{
|
|
20
|
+
"type": "command",
|
|
21
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cjs\" intent-router",
|
|
22
|
+
"async": true
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"PreToolUse": [
|
|
28
|
+
{
|
|
29
|
+
"matcher": "Read|Write|Edit",
|
|
30
|
+
"hooks": [
|
|
31
|
+
{
|
|
32
|
+
"type": "command",
|
|
33
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cjs\" pre-tool-guard",
|
|
34
|
+
"async": false
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"matcher": "Edit|Write",
|
|
40
|
+
"hooks": [
|
|
41
|
+
{
|
|
42
|
+
"type": "command",
|
|
43
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cjs\" context-watch",
|
|
44
|
+
"async": true
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"matcher": "Bash",
|
|
50
|
+
"hooks": [
|
|
51
|
+
{
|
|
52
|
+
"type": "command",
|
|
53
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cjs\" secrets-scan",
|
|
54
|
+
"async": false
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
],
|
|
59
|
+
"PostToolUse": [
|
|
60
|
+
{
|
|
61
|
+
"matcher": "Edit|Write",
|
|
62
|
+
"hooks": [
|
|
63
|
+
{
|
|
64
|
+
"type": "command",
|
|
65
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cjs\" auto-format",
|
|
66
|
+
"async": true
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"type": "command",
|
|
70
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cjs\" typecheck",
|
|
71
|
+
"async": true
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"matcher": "Skill",
|
|
77
|
+
"hooks": [
|
|
78
|
+
{
|
|
79
|
+
"type": "command",
|
|
80
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cjs\" metrics-collector",
|
|
81
|
+
"async": true
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
],
|
|
86
|
+
"PreCompact": [
|
|
87
|
+
{
|
|
88
|
+
"matcher": ".*",
|
|
89
|
+
"hooks": [
|
|
90
|
+
{
|
|
91
|
+
"type": "command",
|
|
92
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cjs\" pre-compact",
|
|
93
|
+
"async": false
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
}
|
|
97
|
+
],
|
|
98
|
+
"Stop": [
|
|
99
|
+
{
|
|
100
|
+
"matcher": ".*",
|
|
101
|
+
"hooks": [
|
|
102
|
+
{
|
|
103
|
+
"type": "command",
|
|
104
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cjs\" post-session-reflect",
|
|
105
|
+
"async": false
|
|
106
|
+
}
|
|
107
|
+
]
|
|
108
|
+
}
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -1,42 +1,86 @@
|
|
|
1
|
-
// Rune Metrics Collector Hook
|
|
2
|
-
// PostToolUse on Skill — captures skill invocations for H3 mesh analytics
|
|
3
|
-
// Append-only JSONL to tmpdir. Flushed to .rune/metrics/ at session end.
|
|
4
|
-
// Async: true — never blocks skill execution.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
|
|
1
|
+
// Rune Metrics Collector Hook
|
|
2
|
+
// PostToolUse on Skill — captures skill invocations for H3 mesh analytics
|
|
3
|
+
// Append-only JSONL to tmpdir. Flushed to .rune/metrics/ at session end.
|
|
4
|
+
// Async: true — never blocks skill execution.
|
|
5
|
+
//
|
|
6
|
+
// Data source: stdin JSON from Claude Code (not env vars)
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const os = require('os');
|
|
11
|
+
|
|
12
|
+
const cwd = process.cwd();
|
|
13
|
+
const hash = Buffer.from(cwd).toString('base64url').slice(0, 16);
|
|
14
|
+
const metricsFile = path.join(os.tmpdir(), `rune-metrics-${hash}.jsonl`);
|
|
15
|
+
const watchFile = path.join(os.tmpdir(), `rune-context-watch-${hash}.json`);
|
|
16
|
+
|
|
17
|
+
// Read stdin JSON to get tool input (Claude Code passes hook data via stdin)
|
|
18
|
+
let stdinData = '';
|
|
19
|
+
process.stdin.setEncoding('utf-8');
|
|
20
|
+
process.stdin.on('data', chunk => { stdinData += chunk; });
|
|
21
|
+
process.stdin.on('end', () => {
|
|
22
|
+
let skillName = 'unknown';
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
const hookData = JSON.parse(stdinData);
|
|
26
|
+
// PostToolUse stdin: { tool: "Skill", tool_input: { skill: "rune:cook", ... }, tool_result: ... }
|
|
27
|
+
const toolInput = hookData.tool_input || {};
|
|
28
|
+
const raw = toolInput.skill || toolInput.name || '';
|
|
29
|
+
skillName = raw.replace(/^rune:/, '') || 'unknown';
|
|
30
|
+
} catch {
|
|
31
|
+
// Fallback: try env var for backwards compatibility
|
|
32
|
+
const toolInput = process.env.CLAUDE_TOOL_INPUT || '';
|
|
33
|
+
try {
|
|
34
|
+
const parsed = JSON.parse(toolInput);
|
|
35
|
+
const raw = parsed.skill || parsed.name || '';
|
|
36
|
+
skillName = raw.replace(/^rune:/, '');
|
|
37
|
+
} catch {
|
|
38
|
+
const match = toolInput.match(/(?:rune:)?([a-z][\w-]*)/i);
|
|
39
|
+
if (match) skillName = match[1];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (skillName && skillName !== 'unknown') {
|
|
44
|
+
const now = Date.now();
|
|
45
|
+
const ts = new Date(now).toISOString();
|
|
46
|
+
|
|
47
|
+
// Read session ID from context-watch state (shared tmpdir file)
|
|
48
|
+
let sessionId = null;
|
|
49
|
+
try {
|
|
50
|
+
const watchState = JSON.parse(fs.readFileSync(watchFile, 'utf-8'));
|
|
51
|
+
sessionId = watchState.sessionId || null;
|
|
52
|
+
} catch { /* no watch state yet */ }
|
|
53
|
+
|
|
54
|
+
// Compute duration since last skill event (approximate skill execution time)
|
|
55
|
+
let durationMs = null;
|
|
56
|
+
try {
|
|
57
|
+
const lines = fs.readFileSync(metricsFile, 'utf-8').trim().split('\n').filter(Boolean);
|
|
58
|
+
if (lines.length > 0) {
|
|
59
|
+
const last = JSON.parse(lines[lines.length - 1]);
|
|
60
|
+
durationMs = now - new Date(last.ts).getTime();
|
|
61
|
+
// Cap at 10 minutes — longer gaps are idle time, not skill duration
|
|
62
|
+
if (durationMs > 600000) durationMs = null;
|
|
63
|
+
}
|
|
64
|
+
} catch { /* first event or read error */ }
|
|
65
|
+
|
|
66
|
+
const entry = JSON.stringify({
|
|
67
|
+
ts,
|
|
68
|
+
skill: skillName,
|
|
69
|
+
event: 'invoke',
|
|
70
|
+
session_id: sessionId,
|
|
71
|
+
duration_ms: durationMs
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
fs.appendFileSync(metricsFile, entry + '\n');
|
|
76
|
+
} catch {
|
|
77
|
+
// Non-critical — metrics are best-effort
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
process.exit(0);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Handle empty stdin (pipe closed immediately)
|
|
85
|
+
process.stdin.on('error', () => process.exit(0));
|
|
86
|
+
process.stdin.resume();
|