@rune-kit/rune 2.22.0 → 2.22.1
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/README.md
CHANGED
|
@@ -83,9 +83,9 @@ _Methodology: Claude Code CLI headless mode (`claude -p --output-format json`),
|
|
|
83
83
|
|
|
84
84
|
---
|
|
85
85
|
|
|
86
|
-
## What's New (v2.22.
|
|
86
|
+
## What's New (v2.22.1 — Convergence, Dogfooded)
|
|
87
87
|
|
|
88
|
-
> **v2.22.
|
|
88
|
+
> **v2.22.1 (2026-07-03):** Patch: tier-hook loader accepts PreCompact + SessionStart lifecycle events — required by Pro hooks v1.2.0 (context-reset). **v2.22.0:** The v2.21.0 gates went through a live-fire dogfood: fresh executor agents (zero author context) ran `converge` and `verification` Level 3.5 against a fixture with a dead Submit button, a handler-less Export button, a navigation-anchor decoy, and a declared placeholder. **Both gates caught the dead button with file:line evidence and zero false positives** — and the 16 ambiguities the executors reported became spec fixes: converge v0.2.0 adds a `deferred-debt` class (declared design debt can no longer force a false escalation), a `Plan Claims vs Reality` section (tasks marked `[x]` whose code doesn't exist — surfaced first-class), and derived story verdicts; verification v0.7.0 gets FAIL-dominates precedence, per-route reverse checks, and server/static entry-point exemptions. The dogfood fixture itself shipped as the seed of **`npm run eval`** — a behavioral eval harness that runs a fresh headless agent against fixture repos and asserts outcomes, because structural validation can't prove a skill makes an agent behave. Pro `autopilot` v1.6.0 now explicitly runs Phase 6.5 CONVERGE in autonomous mode.
|
|
89
89
|
|
|
90
90
|
### Previous (v2.21.0 — Convergence)
|
|
91
91
|
|
|
@@ -161,6 +161,21 @@ describe('validateManifest', () => {
|
|
|
161
161
|
});
|
|
162
162
|
assert.strictEqual(m.entries[0].matcher, null);
|
|
163
163
|
});
|
|
164
|
+
|
|
165
|
+
test('accepts PreCompact and SessionStart lifecycle events without matcher', () => {
|
|
166
|
+
// Pro hooks manifest v1.2.0 wires context-reset on both — Free must load it (was rejected pre-v2.22.1)
|
|
167
|
+
const m = validateManifest({
|
|
168
|
+
tier: 'pro',
|
|
169
|
+
entries: [
|
|
170
|
+
{ id: 'context-reset-precompact', event: 'PreCompact', command: 'node context-reset.cjs' },
|
|
171
|
+
{ id: 'context-reset-sessionstart', event: 'SessionStart', command: 'node context-reset.cjs' },
|
|
172
|
+
],
|
|
173
|
+
});
|
|
174
|
+
assert.strictEqual(m.entries.length, 2);
|
|
175
|
+
assert.strictEqual(m.entries[0].event, 'PreCompact');
|
|
176
|
+
assert.strictEqual(m.entries[0].matcher, null);
|
|
177
|
+
assert.strictEqual(m.entries[1].event, 'SessionStart');
|
|
178
|
+
});
|
|
164
179
|
});
|
|
165
180
|
|
|
166
181
|
describe('loadTierManifest + locateTierManifest', () => {
|
|
@@ -78,7 +78,18 @@ export function compareSemver(a, b) {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
/** Valid event names a manifest entry may declare. */
|
|
81
|
-
const VALID_EVENTS = new Set([
|
|
81
|
+
const VALID_EVENTS = new Set([
|
|
82
|
+
'UserPromptSubmit',
|
|
83
|
+
'PreToolUse',
|
|
84
|
+
'PostToolUse',
|
|
85
|
+
'Stop',
|
|
86
|
+
'statusLine',
|
|
87
|
+
'PreCompact',
|
|
88
|
+
'SessionStart',
|
|
89
|
+
]);
|
|
90
|
+
|
|
91
|
+
/** Lifecycle events where `matcher` is optional (PreCompact matches manual|auto, SessionStart matches startup|resume — both default to all when omitted). */
|
|
92
|
+
const MATCHER_OPTIONAL_EVENTS = new Set(['statusLine', 'Stop', 'PreCompact', 'SessionStart']);
|
|
82
93
|
|
|
83
94
|
/** Tier names must be simple lowercase identifiers. Blocks `../../etc` and similar traversal. */
|
|
84
95
|
const TIER_NAME_RE = /^[a-z][a-z0-9-]{0,31}$/;
|
|
@@ -178,7 +189,7 @@ export function validateManifest(manifest, source = '<memory>') {
|
|
|
178
189
|
if (raw.matcher !== undefined && typeof raw.matcher !== 'string') {
|
|
179
190
|
throw new Error(`${where}: 'matcher' must be a string if present`);
|
|
180
191
|
}
|
|
181
|
-
if (
|
|
192
|
+
if (!MATCHER_OPTIONAL_EVENTS.has(raw.event) && !raw.matcher) {
|
|
182
193
|
throw new Error(`${where}: '${raw.event}' requires a 'matcher' string (e.g. 'Edit|Write' or '.*')`);
|
|
183
194
|
}
|
|
184
195
|
if (raw.globs !== undefined && !Array.isArray(raw.globs)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rune-kit/rune",
|
|
3
|
-
"version": "2.22.
|
|
3
|
+
"version": "2.22.1",
|
|
4
4
|
"description": "65-skill mesh for AI coding assistants — runtime auto-discipline via native hooks (Claude/Cursor/Windsurf/Antigravity), 5-layer architecture, 204 connections + 43 signals, multi-platform compiler. converge (L3) scans spec vs code so dead-button/frontend-only implementations can't ship.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|