@rune-kit/rune 2.1.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/LICENSE +21 -0
- package/README.md +357 -0
- package/agents/.gitkeep +0 -0
- package/agents/architect.md +29 -0
- package/agents/asset-creator.md +11 -0
- package/agents/audit.md +11 -0
- package/agents/autopsy.md +11 -0
- package/agents/brainstorm.md +11 -0
- package/agents/browser-pilot.md +11 -0
- package/agents/coder.md +29 -0
- package/agents/completion-gate.md +11 -0
- package/agents/constraint-check.md +11 -0
- package/agents/context-engine.md +11 -0
- package/agents/cook.md +11 -0
- package/agents/db.md +11 -0
- package/agents/debug.md +11 -0
- package/agents/dependency-doctor.md +11 -0
- package/agents/deploy.md +11 -0
- package/agents/design.md +11 -0
- package/agents/docs-seeker.md +11 -0
- package/agents/fix.md +11 -0
- package/agents/hallucination-guard.md +11 -0
- package/agents/incident.md +11 -0
- package/agents/integrity-check.md +11 -0
- package/agents/journal.md +11 -0
- package/agents/launch.md +11 -0
- package/agents/logic-guardian.md +11 -0
- package/agents/marketing.md +11 -0
- package/agents/onboard.md +11 -0
- package/agents/perf.md +11 -0
- package/agents/plan.md +11 -0
- package/agents/preflight.md +11 -0
- package/agents/problem-solver.md +11 -0
- package/agents/rescue.md +11 -0
- package/agents/research.md +11 -0
- package/agents/researcher.md +29 -0
- package/agents/review-intake.md +11 -0
- package/agents/review.md +11 -0
- package/agents/reviewer.md +28 -0
- package/agents/safeguard.md +11 -0
- package/agents/sast.md +11 -0
- package/agents/scanner.md +28 -0
- package/agents/scope-guard.md +11 -0
- package/agents/scout.md +11 -0
- package/agents/sentinel.md +11 -0
- package/agents/sequential-thinking.md +11 -0
- package/agents/session-bridge.md +11 -0
- package/agents/skill-forge.md +11 -0
- package/agents/skill-router.md +11 -0
- package/agents/surgeon.md +11 -0
- package/agents/team.md +11 -0
- package/agents/test.md +11 -0
- package/agents/trend-scout.md +11 -0
- package/agents/verification.md +11 -0
- package/agents/video-creator.md +11 -0
- package/agents/watchdog.md +11 -0
- package/agents/worktree.md +11 -0
- package/commands/.gitkeep +0 -0
- package/commands/rune.md +168 -0
- package/compiler/__tests__/openclaw-adapter.test.js +140 -0
- package/compiler/__tests__/parser.test.js +55 -0
- package/compiler/adapters/antigravity.js +59 -0
- package/compiler/adapters/claude.js +37 -0
- package/compiler/adapters/cursor.js +67 -0
- package/compiler/adapters/generic.js +60 -0
- package/compiler/adapters/index.js +45 -0
- package/compiler/adapters/openclaw.js +150 -0
- package/compiler/adapters/windsurf.js +60 -0
- package/compiler/bin/rune.js +288 -0
- package/compiler/doctor.js +153 -0
- package/compiler/emitter.js +240 -0
- package/compiler/parser.js +208 -0
- package/compiler/transformer.js +69 -0
- package/compiler/transforms/branding.js +27 -0
- package/compiler/transforms/cross-references.js +29 -0
- package/compiler/transforms/frontmatter.js +38 -0
- package/compiler/transforms/hooks.js +68 -0
- package/compiler/transforms/subagents.js +36 -0
- package/compiler/transforms/tool-names.js +60 -0
- package/contexts/dev.md +34 -0
- package/contexts/research.md +43 -0
- package/contexts/review.md +55 -0
- package/extensions/ai-ml/PACK.md +517 -0
- package/extensions/analytics/PACK.md +557 -0
- package/extensions/backend/PACK.md +678 -0
- package/extensions/chrome-ext/PACK.md +995 -0
- package/extensions/content/PACK.md +381 -0
- package/extensions/devops/PACK.md +520 -0
- package/extensions/ecommerce/PACK.md +280 -0
- package/extensions/gamedev/PACK.md +393 -0
- package/extensions/mobile/PACK.md +273 -0
- package/extensions/saas/PACK.md +805 -0
- package/extensions/security/PACK.md +536 -0
- package/extensions/trading/PACK.md +597 -0
- package/extensions/ui/PACK.md +947 -0
- package/package.json +47 -0
- package/skills/.gitkeep +0 -0
- package/skills/adversary/SKILL.md +271 -0
- package/skills/asset-creator/SKILL.md +157 -0
- package/skills/audit/SKILL.md +466 -0
- package/skills/autopsy/SKILL.md +200 -0
- package/skills/ba/SKILL.md +279 -0
- package/skills/brainstorm/SKILL.md +266 -0
- package/skills/browser-pilot/SKILL.md +168 -0
- package/skills/completion-gate/SKILL.md +151 -0
- package/skills/constraint-check/SKILL.md +165 -0
- package/skills/context-engine/SKILL.md +176 -0
- package/skills/cook/SKILL.md +636 -0
- package/skills/db/SKILL.md +256 -0
- package/skills/debug/SKILL.md +240 -0
- package/skills/dependency-doctor/SKILL.md +235 -0
- package/skills/deploy/SKILL.md +174 -0
- package/skills/design/DESIGN-REFERENCE.md +365 -0
- package/skills/design/SKILL.md +462 -0
- package/skills/doc-processor/SKILL.md +254 -0
- package/skills/docs/SKILL.md +336 -0
- package/skills/docs-seeker/SKILL.md +166 -0
- package/skills/fix/SKILL.md +192 -0
- package/skills/git/SKILL.md +285 -0
- package/skills/hallucination-guard/SKILL.md +204 -0
- package/skills/incident/SKILL.md +241 -0
- package/skills/integrity-check/SKILL.md +169 -0
- package/skills/journal/SKILL.md +190 -0
- package/skills/launch/SKILL.md +330 -0
- package/skills/logic-guardian/SKILL.md +240 -0
- package/skills/marketing/SKILL.md +229 -0
- package/skills/mcp-builder/SKILL.md +311 -0
- package/skills/onboard/SKILL.md +298 -0
- package/skills/perf/SKILL.md +297 -0
- package/skills/plan/SKILL.md +520 -0
- package/skills/preflight/SKILL.md +231 -0
- package/skills/problem-solver/SKILL.md +284 -0
- package/skills/rescue/SKILL.md +434 -0
- package/skills/research/SKILL.md +122 -0
- package/skills/review/SKILL.md +354 -0
- package/skills/review-intake/SKILL.md +222 -0
- package/skills/safeguard/SKILL.md +188 -0
- package/skills/sast/SKILL.md +190 -0
- package/skills/scaffold/SKILL.md +276 -0
- package/skills/scope-guard/SKILL.md +150 -0
- package/skills/scout/SKILL.md +232 -0
- package/skills/sentinel/SKILL.md +320 -0
- package/skills/sentinel-env/SKILL.md +226 -0
- package/skills/sequential-thinking/SKILL.md +234 -0
- package/skills/session-bridge/SKILL.md +287 -0
- package/skills/skill-forge/SKILL.md +317 -0
- package/skills/skill-router/SKILL.md +267 -0
- package/skills/surgeon/SKILL.md +203 -0
- package/skills/team/SKILL.md +397 -0
- package/skills/test/SKILL.md +271 -0
- package/skills/trend-scout/SKILL.md +145 -0
- package/skills/verification/SKILL.md +201 -0
- package/skills/video-creator/SKILL.md +201 -0
- package/skills/watchdog/SKILL.md +166 -0
- package/skills/worktree/SKILL.md +140 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SKILL.md Parser
|
|
3
|
+
*
|
|
4
|
+
* Parses SKILL.md files into a structured intermediate representation (IR).
|
|
5
|
+
* Extracts frontmatter, cross-references, tool references, HARD-GATE blocks, and sections.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const CROSS_REF_PATTERN = /`?rune:([a-z][\w-]*)`?/g;
|
|
9
|
+
const TOOL_REF_PATTERN = /`(Read|Write|Edit|Glob|Grep|Bash|TodoWrite|Skill|Agent)`/g;
|
|
10
|
+
const HARD_GATE_PATTERN = /<HARD-GATE>([\s\S]*?)<\/HARD-GATE>/g;
|
|
11
|
+
const SECTION_PATTERN = /^## (.+)$/gm;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Parse YAML-like frontmatter from SKILL.md
|
|
15
|
+
* Handles nested metadata block
|
|
16
|
+
*/
|
|
17
|
+
function parseFrontmatter(content) {
|
|
18
|
+
// Normalize line endings to \n for cross-platform compatibility
|
|
19
|
+
const normalized = content.replace(/\r\n/g, '\n');
|
|
20
|
+
const match = normalized.match(/^---\n([\s\S]*?)\n---/);
|
|
21
|
+
if (!match) return { frontmatter: {}, body: normalized };
|
|
22
|
+
|
|
23
|
+
const raw = match[1];
|
|
24
|
+
const body = normalized.slice(match[0].length).trim();
|
|
25
|
+
const frontmatter = {};
|
|
26
|
+
|
|
27
|
+
let currentIndent = null;
|
|
28
|
+
let nestedKey = null;
|
|
29
|
+
const nestedObj = {};
|
|
30
|
+
|
|
31
|
+
for (const line of raw.split('\n')) {
|
|
32
|
+
const trimmed = line.trim();
|
|
33
|
+
if (!trimmed) continue;
|
|
34
|
+
|
|
35
|
+
// Detect nested block (e.g., metadata:)
|
|
36
|
+
if (/^\w+:\s*$/.test(trimmed)) {
|
|
37
|
+
nestedKey = trimmed.replace(':', '').trim();
|
|
38
|
+
frontmatter[nestedKey] = {};
|
|
39
|
+
currentIndent = 'nested';
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (currentIndent === 'nested' && line.startsWith(' ')) {
|
|
44
|
+
const kvMatch = trimmed.match(/^(\w+):\s*(.+)$/);
|
|
45
|
+
if (kvMatch) {
|
|
46
|
+
let value = kvMatch[2].replace(/^["']|["']$/g, '');
|
|
47
|
+
frontmatter[nestedKey][kvMatch[1]] = value;
|
|
48
|
+
}
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Top-level key-value
|
|
53
|
+
currentIndent = null;
|
|
54
|
+
nestedKey = null;
|
|
55
|
+
const kvMatch = trimmed.match(/^(\w[\w-]*):\s*(.+)$/);
|
|
56
|
+
if (kvMatch) {
|
|
57
|
+
let value = kvMatch[2].replace(/^["']|["']$/g, '');
|
|
58
|
+
frontmatter[kvMatch[1]] = value;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return { frontmatter, body };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Extract all rune:<name> cross-references from body
|
|
67
|
+
*/
|
|
68
|
+
function extractCrossRefs(body) {
|
|
69
|
+
const refs = [];
|
|
70
|
+
const lines = body.split('\n');
|
|
71
|
+
|
|
72
|
+
for (let i = 0; i < lines.length; i++) {
|
|
73
|
+
const line = lines[i];
|
|
74
|
+
let match;
|
|
75
|
+
const regex = new RegExp(CROSS_REF_PATTERN.source, 'g');
|
|
76
|
+
|
|
77
|
+
while ((match = regex.exec(line)) !== null) {
|
|
78
|
+
refs.push({
|
|
79
|
+
raw: match[0],
|
|
80
|
+
skillName: match[1],
|
|
81
|
+
line: i + 1,
|
|
82
|
+
context: line.trim(),
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return refs;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Extract all Claude Code tool references from body
|
|
92
|
+
*/
|
|
93
|
+
function extractToolRefs(body) {
|
|
94
|
+
const refs = [];
|
|
95
|
+
const lines = body.split('\n');
|
|
96
|
+
|
|
97
|
+
for (let i = 0; i < lines.length; i++) {
|
|
98
|
+
const line = lines[i];
|
|
99
|
+
let match;
|
|
100
|
+
const regex = new RegExp(TOOL_REF_PATTERN.source, 'g');
|
|
101
|
+
|
|
102
|
+
while ((match = regex.exec(line)) !== null) {
|
|
103
|
+
refs.push({
|
|
104
|
+
raw: match[0],
|
|
105
|
+
toolName: match[1],
|
|
106
|
+
line: i + 1,
|
|
107
|
+
context: line.trim(),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return refs;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Extract HARD-GATE blocks
|
|
117
|
+
*/
|
|
118
|
+
function extractHardGates(body) {
|
|
119
|
+
const gates = [];
|
|
120
|
+
let match;
|
|
121
|
+
const regex = new RegExp(HARD_GATE_PATTERN.source, 'gs');
|
|
122
|
+
|
|
123
|
+
while ((match = regex.exec(body)) !== null) {
|
|
124
|
+
gates.push(match[1].trim());
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return gates;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Extract ## sections as a Map<sectionName, content>
|
|
132
|
+
*/
|
|
133
|
+
function extractSections(body) {
|
|
134
|
+
const sections = new Map();
|
|
135
|
+
const lines = body.split('\n');
|
|
136
|
+
let currentSection = null;
|
|
137
|
+
let currentContent = [];
|
|
138
|
+
|
|
139
|
+
for (const line of lines) {
|
|
140
|
+
const sectionMatch = line.match(/^## (.+)$/);
|
|
141
|
+
if (sectionMatch) {
|
|
142
|
+
if (currentSection) {
|
|
143
|
+
sections.set(currentSection, currentContent.join('\n').trim());
|
|
144
|
+
}
|
|
145
|
+
currentSection = sectionMatch[1];
|
|
146
|
+
currentContent = [];
|
|
147
|
+
} else if (currentSection) {
|
|
148
|
+
currentContent.push(line);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (currentSection) {
|
|
153
|
+
sections.set(currentSection, currentContent.join('\n').trim());
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return sections;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Parse a SKILL.md file content into structured IR
|
|
161
|
+
*
|
|
162
|
+
* @param {string} content - raw SKILL.md content
|
|
163
|
+
* @param {string} [filePath] - optional file path for error reporting
|
|
164
|
+
* @returns {ParsedSkill}
|
|
165
|
+
*/
|
|
166
|
+
export function parseSkill(content, filePath = '') {
|
|
167
|
+
const { frontmatter, body } = parseFrontmatter(content);
|
|
168
|
+
|
|
169
|
+
const metadata = frontmatter.metadata || {};
|
|
170
|
+
|
|
171
|
+
return {
|
|
172
|
+
name: frontmatter.name || '',
|
|
173
|
+
description: frontmatter.description || '',
|
|
174
|
+
layer: metadata.layer || 'L2',
|
|
175
|
+
model: metadata.model || 'sonnet',
|
|
176
|
+
group: metadata.group || 'general',
|
|
177
|
+
contextFork: frontmatter.context === 'fork',
|
|
178
|
+
agentType: frontmatter.agent || null,
|
|
179
|
+
body,
|
|
180
|
+
crossRefs: extractCrossRefs(body),
|
|
181
|
+
toolRefs: extractToolRefs(body),
|
|
182
|
+
hardGates: extractHardGates(body),
|
|
183
|
+
sections: extractSections(body),
|
|
184
|
+
filePath,
|
|
185
|
+
frontmatter,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Parse a PACK.md extension file (same format, slightly different metadata)
|
|
191
|
+
*/
|
|
192
|
+
export function parsePack(content, filePath = '') {
|
|
193
|
+
const { frontmatter, body } = parseFrontmatter(content);
|
|
194
|
+
|
|
195
|
+
return {
|
|
196
|
+
name: frontmatter.name || '',
|
|
197
|
+
description: frontmatter.description || '',
|
|
198
|
+
version: frontmatter.version || '1.0.0',
|
|
199
|
+
layer: 'L4',
|
|
200
|
+
body,
|
|
201
|
+
crossRefs: extractCrossRefs(body),
|
|
202
|
+
toolRefs: extractToolRefs(body),
|
|
203
|
+
hardGates: extractHardGates(body),
|
|
204
|
+
sections: extractSections(body),
|
|
205
|
+
filePath,
|
|
206
|
+
frontmatter,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transform Pipeline
|
|
3
|
+
*
|
|
4
|
+
* Applies all transforms in order to convert a parsed skill into platform-specific output.
|
|
5
|
+
* Pipeline: frontmatter → cross-refs → tool-names → subagents → hooks → branding
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { transformCrossReferences } from './transforms/cross-references.js';
|
|
9
|
+
import { transformToolNames } from './transforms/tool-names.js';
|
|
10
|
+
import { transformFrontmatter } from './transforms/frontmatter.js';
|
|
11
|
+
import { transformSubagents } from './transforms/subagents.js';
|
|
12
|
+
import { generateHookConstraints } from './transforms/hooks.js';
|
|
13
|
+
import { addBranding } from './transforms/branding.js';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Run the full transform pipeline on a parsed skill
|
|
17
|
+
*
|
|
18
|
+
* @param {object} parsedSkill - output from parser.parseSkill()
|
|
19
|
+
* @param {object} adapter - platform adapter
|
|
20
|
+
* @returns {{ header: string, body: string, footer: string }}
|
|
21
|
+
*/
|
|
22
|
+
export function transformSkill(parsedSkill, adapter) {
|
|
23
|
+
// For Claude Code, return body unchanged
|
|
24
|
+
if (adapter.name === 'claude') {
|
|
25
|
+
return {
|
|
26
|
+
header: '',
|
|
27
|
+
body: parsedSkill.body,
|
|
28
|
+
footer: '',
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
let body = parsedSkill.body;
|
|
33
|
+
|
|
34
|
+
// 1. Rewrite cross-references (rune:cook → platform-native)
|
|
35
|
+
body = transformCrossReferences(body, adapter);
|
|
36
|
+
|
|
37
|
+
// 2. Rewrite tool names (Read, Edit, Bash → generic)
|
|
38
|
+
body = transformToolNames(body, adapter);
|
|
39
|
+
|
|
40
|
+
// 3. Convert subagent/parallel instructions to sequential
|
|
41
|
+
body = transformSubagents(body, adapter);
|
|
42
|
+
|
|
43
|
+
// 4. Platform-specific post-processing
|
|
44
|
+
body = adapter.postProcess(body);
|
|
45
|
+
|
|
46
|
+
// 5. Generate header (platform-specific frontmatter/preamble)
|
|
47
|
+
const header = adapter.generateHeader(parsedSkill);
|
|
48
|
+
|
|
49
|
+
// 6. Generate hook constraints section
|
|
50
|
+
const hookConstraints = generateHookConstraints(parsedSkill, adapter);
|
|
51
|
+
|
|
52
|
+
// 7. Inject hook constraints after the first heading
|
|
53
|
+
if (hookConstraints) {
|
|
54
|
+
const firstHeadingEnd = body.indexOf('\n## ');
|
|
55
|
+
if (firstHeadingEnd !== -1) {
|
|
56
|
+
// Insert before the first ## section
|
|
57
|
+
const titleSection = body.substring(0, firstHeadingEnd);
|
|
58
|
+
const rest = body.substring(firstHeadingEnd);
|
|
59
|
+
body = titleSection + hookConstraints + rest;
|
|
60
|
+
} else {
|
|
61
|
+
body = body + hookConstraints;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// 8. Generate footer (branding + CTA)
|
|
66
|
+
const footer = adapter.generateFooter();
|
|
67
|
+
|
|
68
|
+
return { header, body, footer };
|
|
69
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Branding Transform
|
|
3
|
+
*
|
|
4
|
+
* Adds Rune attribution footer to compiled skill files.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const DEFAULT_FOOTER = [
|
|
8
|
+
'',
|
|
9
|
+
'---',
|
|
10
|
+
'> **Rune Skill Mesh** — 49 skills, 170+ connections',
|
|
11
|
+
'> Source: https://github.com/rune-kit/rune',
|
|
12
|
+
'> For the full experience with subagents, hooks, adaptive routing, and mesh analytics — use Rune as a Claude Code plugin.',
|
|
13
|
+
].join('\n');
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Add branding footer to skill output
|
|
17
|
+
*
|
|
18
|
+
* @param {string} body - transformed skill body
|
|
19
|
+
* @param {object} adapter - platform adapter
|
|
20
|
+
* @returns {string} body with footer
|
|
21
|
+
*/
|
|
22
|
+
export function addBranding(body, adapter) {
|
|
23
|
+
if (adapter.name === 'claude') return body;
|
|
24
|
+
|
|
25
|
+
const footer = adapter.generateFooter ? adapter.generateFooter() : DEFAULT_FOOTER;
|
|
26
|
+
return body + '\n' + footer;
|
|
27
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-Reference Transform
|
|
3
|
+
*
|
|
4
|
+
* Rewrites `rune:<name>` references to platform-native format.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const CROSS_REF_PATTERN = /`rune:([a-z][\w-]*)`/g;
|
|
8
|
+
const BARE_REF_PATTERN = /(?<!`)rune:([a-z][\w-]*)(?!`)/g;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Transform cross-references in skill body using the platform adapter
|
|
12
|
+
*
|
|
13
|
+
* @param {string} body - skill markdown body
|
|
14
|
+
* @param {object} adapter - platform adapter with transformReference method
|
|
15
|
+
* @returns {string} transformed body
|
|
16
|
+
*/
|
|
17
|
+
export function transformCrossReferences(body, adapter) {
|
|
18
|
+
// First pass: backtick-wrapped references (`rune:cook`)
|
|
19
|
+
let result = body.replace(CROSS_REF_PATTERN, (match, skillName) => {
|
|
20
|
+
return adapter.transformReference(skillName, match);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// Second pass: bare references (rune:cook without backticks)
|
|
24
|
+
result = result.replace(BARE_REF_PATTERN, (match, skillName) => {
|
|
25
|
+
return adapter.transformReference(skillName, match);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Frontmatter Transform
|
|
3
|
+
*
|
|
4
|
+
* Strips or rewrites Claude Code-specific frontmatter directives.
|
|
5
|
+
* - context: fork → removed on non-Claude platforms
|
|
6
|
+
* - agent: general-purpose → removed on non-Claude platforms
|
|
7
|
+
* - model: → removed or converted to comment
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Strip Claude Code-specific frontmatter lines from raw content
|
|
12
|
+
*
|
|
13
|
+
* @param {string} content - full SKILL.md content (with frontmatter)
|
|
14
|
+
* @param {object} adapter - platform adapter
|
|
15
|
+
* @returns {string} content with cleaned frontmatter
|
|
16
|
+
*/
|
|
17
|
+
export function transformFrontmatter(content, adapter) {
|
|
18
|
+
if (adapter.name === 'claude') return content;
|
|
19
|
+
|
|
20
|
+
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
21
|
+
if (!match) return content;
|
|
22
|
+
|
|
23
|
+
const frontmatterBlock = match[1];
|
|
24
|
+
const afterFrontmatter = content.slice(match[0].length);
|
|
25
|
+
|
|
26
|
+
// Remove Claude Code-specific directives
|
|
27
|
+
const cleaned = frontmatterBlock
|
|
28
|
+
.split('\n')
|
|
29
|
+
.filter(line => {
|
|
30
|
+
const trimmed = line.trim();
|
|
31
|
+
if (trimmed.startsWith('context:')) return false;
|
|
32
|
+
if (trimmed.startsWith('agent:')) return false;
|
|
33
|
+
return true;
|
|
34
|
+
})
|
|
35
|
+
.join('\n');
|
|
36
|
+
|
|
37
|
+
return `---\n${cleaned}\n---${afterFrontmatter}`;
|
|
38
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook Constraint Inlining
|
|
3
|
+
*
|
|
4
|
+
* Converts Claude Code hook behaviors into inline MUST/NEVER instructions.
|
|
5
|
+
* These get injected as a "Platform Constraints" section.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const HOOK_CONSTRAINTS = [
|
|
9
|
+
{
|
|
10
|
+
id: 'secrets-scan',
|
|
11
|
+
instruction: 'MUST NOT: Never run commands containing hardcoded secrets, API keys, or tokens. Scan all shell commands for secret patterns before execution.',
|
|
12
|
+
relevantTools: ['Bash'],
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
id: 'auto-format',
|
|
16
|
+
instruction: 'MUST: After editing JS/TS files, ensure code follows project formatting conventions (Prettier/ESLint).',
|
|
17
|
+
relevantTools: ['Edit', 'Write'],
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: 'typecheck',
|
|
21
|
+
instruction: 'MUST: After editing .ts/.tsx files, verify TypeScript compilation succeeds (no type errors).',
|
|
22
|
+
relevantTools: ['Edit', 'Write'],
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: 'context-watch',
|
|
26
|
+
instruction: 'SHOULD: Monitor your context usage. If working on a long task, summarize progress before context fills up.',
|
|
27
|
+
relevantTools: [],
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: 'pre-compact',
|
|
31
|
+
instruction: 'MUST: Before summarizing/compacting context, save important decisions and progress to project files.',
|
|
32
|
+
relevantTools: [],
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: 'post-session',
|
|
36
|
+
instruction: 'SHOULD: Before ending, save architectural decisions and progress to .rune/ directory for future sessions.',
|
|
37
|
+
relevantTools: [],
|
|
38
|
+
},
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Generate inline hook constraints section for non-Claude platforms
|
|
43
|
+
*
|
|
44
|
+
* @param {object} parsedSkill - parsed skill IR
|
|
45
|
+
* @param {object} adapter - platform adapter
|
|
46
|
+
* @returns {string} constraints section to inject, or empty string
|
|
47
|
+
*/
|
|
48
|
+
export function generateHookConstraints(parsedSkill, adapter) {
|
|
49
|
+
if (adapter.name === 'claude') return '';
|
|
50
|
+
|
|
51
|
+
// Filter to relevant constraints based on tool usage in this skill
|
|
52
|
+
const skillToolNames = parsedSkill.toolRefs.map(r => r.toolName);
|
|
53
|
+
const relevant = HOOK_CONSTRAINTS.filter(h =>
|
|
54
|
+
h.relevantTools.length === 0 || h.relevantTools.some(t => skillToolNames.includes(t))
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
if (relevant.length === 0) return '';
|
|
58
|
+
|
|
59
|
+
const lines = [
|
|
60
|
+
'',
|
|
61
|
+
'## Platform Constraints',
|
|
62
|
+
'',
|
|
63
|
+
...relevant.map(h => `- ${h.instruction}`),
|
|
64
|
+
'',
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
return lines.join('\n');
|
|
68
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subagent Transform
|
|
3
|
+
*
|
|
4
|
+
* Converts parallel agent/subagent execution instructions to sequential workflow.
|
|
5
|
+
* On non-Claude platforms, there is no multi-agent support.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const PARALLEL_PATTERNS = [
|
|
9
|
+
{ pattern: /Launch (\d+) parallel agents?/gi, replace: 'Execute the following $1 steps sequentially' },
|
|
10
|
+
{ pattern: /as independent Task agents?/gi, replace: 'one at a time' },
|
|
11
|
+
{ pattern: /PARALLEL EXECUTION:/gi, replace: 'SEQUENTIAL EXECUTION:' },
|
|
12
|
+
{ pattern: /Run these? (?:as )?parallel (?:sub)?agents?/gi, replace: 'Run these steps in order' },
|
|
13
|
+
{ pattern: /spawn (?:a )?(?:sub)?agent/gi, replace: 'execute the workflow' },
|
|
14
|
+
{ pattern: /in a separate (?:sub)?agent/gi, replace: 'as the next step' },
|
|
15
|
+
{ pattern: /Launch (?:a )?background agent/gi, replace: 'Execute in the background' },
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Transform subagent/parallel execution instructions to sequential
|
|
20
|
+
*
|
|
21
|
+
* @param {string} body - skill markdown body
|
|
22
|
+
* @param {object} adapter - platform adapter
|
|
23
|
+
* @returns {string} transformed body
|
|
24
|
+
*/
|
|
25
|
+
export function transformSubagents(body, adapter) {
|
|
26
|
+
if (adapter.name === 'claude') return body;
|
|
27
|
+
|
|
28
|
+
let result = body;
|
|
29
|
+
for (const { pattern, replace } of PARALLEL_PATTERNS) {
|
|
30
|
+
result = result.replace(pattern, replace);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return adapter.transformSubagentInstruction
|
|
34
|
+
? adapter.transformSubagentInstruction(result)
|
|
35
|
+
: result;
|
|
36
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Name Transform
|
|
3
|
+
*
|
|
4
|
+
* Rewrites Claude Code-specific tool names to platform-generic language.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// "Use `Tool` to ..." or "Use `Tool` for ..." → contextual rewrite
|
|
8
|
+
const TOOL_INSTRUCTION_TO_PATTERN = /Use `(Read|Write|Edit|Glob|Grep|Bash|TodoWrite|Skill|Agent)` (?:to |for )/gi;
|
|
9
|
+
|
|
10
|
+
// "Use `Tool`:" or "Use `Tool`." → direct tool usage
|
|
11
|
+
const TOOL_INSTRUCTION_DIRECT_PATTERN = /Use `(Read|Write|Edit|Glob|Grep|Bash|TodoWrite|Skill|Agent)`(?=\s*[:.])/gi;
|
|
12
|
+
|
|
13
|
+
// Standalone `Tool` reference in any context
|
|
14
|
+
const TOOL_REF_PATTERN = /`(Read|Write|Edit|Glob|Grep|Bash|TodoWrite|Skill|Agent)`/g;
|
|
15
|
+
|
|
16
|
+
// Action verbs for direct patterns (no "to" suffix)
|
|
17
|
+
const DIRECT_ACTION = {
|
|
18
|
+
Read: 'Read the relevant files',
|
|
19
|
+
Write: 'Create the files',
|
|
20
|
+
Edit: 'Edit the files',
|
|
21
|
+
Glob: 'Find files by pattern',
|
|
22
|
+
Grep: 'Search file contents',
|
|
23
|
+
Bash: 'Run in the terminal',
|
|
24
|
+
TodoWrite: 'Track progress',
|
|
25
|
+
Skill: 'Follow the skill rules',
|
|
26
|
+
Agent: 'Execute the workflow',
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Transform tool name references in skill body
|
|
31
|
+
*
|
|
32
|
+
* @param {string} body - skill markdown body
|
|
33
|
+
* @param {object} adapter - platform adapter with transformToolName method
|
|
34
|
+
* @returns {string} transformed body
|
|
35
|
+
*/
|
|
36
|
+
export function transformToolNames(body, adapter) {
|
|
37
|
+
// Skip passthrough adapter
|
|
38
|
+
if (adapter.name === 'claude') return body;
|
|
39
|
+
|
|
40
|
+
// First: "Use `Tool` to/for ..." patterns
|
|
41
|
+
let result = body.replace(TOOL_INSTRUCTION_TO_PATTERN, (match, toolName) => {
|
|
42
|
+
const mapped = adapter.transformToolName(toolName);
|
|
43
|
+
if (mapped === toolName) return match;
|
|
44
|
+
return mapped.charAt(0).toUpperCase() + mapped.slice(1) + ' to ';
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Second: "Use `Tool`:" or "Use `Tool`." patterns
|
|
48
|
+
result = result.replace(TOOL_INSTRUCTION_DIRECT_PATTERN, (match, toolName) => {
|
|
49
|
+
return DIRECT_ACTION[toolName] || match;
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// Third: standalone `Tool` references
|
|
53
|
+
result = result.replace(TOOL_REF_PATTERN, (match, toolName) => {
|
|
54
|
+
const mapped = adapter.transformToolName(toolName);
|
|
55
|
+
if (mapped === toolName) return match;
|
|
56
|
+
return mapped;
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
return result;
|
|
60
|
+
}
|
package/contexts/dev.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Development Mode
|
|
2
|
+
|
|
3
|
+
Behavioral context for active coding sessions. Prioritize action over analysis.
|
|
4
|
+
|
|
5
|
+
## Principles
|
|
6
|
+
|
|
7
|
+
- **Code first, explain after** — show working code, not paragraphs about what you'll do
|
|
8
|
+
- **Working → Right → Clean** — get it running, make it correct, then refine
|
|
9
|
+
- **Bias toward action** — if the path is 80% clear, start coding rather than analyzing further
|
|
10
|
+
|
|
11
|
+
## Tool Priority
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
HIGH: Edit, Write, Bash (run tests/build)
|
|
15
|
+
MEDIUM: Read (targeted files), Grep (specific patterns)
|
|
16
|
+
LOW: Glob (broad search), WebSearch (external docs)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Behavioral Rules
|
|
20
|
+
|
|
21
|
+
1. Read the file BEFORE editing — never guess at existing code
|
|
22
|
+
2. Run tests after every meaningful change
|
|
23
|
+
3. If stuck for >2 iterations on the same error, switch strategy:
|
|
24
|
+
- Try a different approach rather than debugging deeper
|
|
25
|
+
- Use `rune:debug` for structured root cause analysis
|
|
26
|
+
4. Keep explanations to 1-2 sentences between code blocks
|
|
27
|
+
5. Commit working increments — don't batch everything into one giant change
|
|
28
|
+
|
|
29
|
+
## Anti-Patterns
|
|
30
|
+
|
|
31
|
+
- Lengthy analysis before writing a single line of code
|
|
32
|
+
- Reading 10+ files "for context" when 2-3 would suffice
|
|
33
|
+
- Explaining what you're about to do instead of doing it
|
|
34
|
+
- Over-engineering the first pass (violates Working → Right → Clean)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Research Mode
|
|
2
|
+
|
|
3
|
+
Behavioral context for investigation, exploration, and understanding. Prioritize breadth and accuracy over speed.
|
|
4
|
+
|
|
5
|
+
## Principles
|
|
6
|
+
|
|
7
|
+
- **Read widely before concluding** — check 3+ sources before forming an opinion
|
|
8
|
+
- **Map before moving** — understand the full landscape before recommending a path
|
|
9
|
+
- **Evidence over intuition** — every claim should reference a file, doc, or search result
|
|
10
|
+
|
|
11
|
+
## Tool Priority
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
HIGH: Grep, Glob, Read, WebSearch, WebFetch
|
|
15
|
+
MEDIUM: Bash (non-destructive: git log, dependency checks)
|
|
16
|
+
LOW: Edit, Write (only for saving findings)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Investigation Framework
|
|
20
|
+
|
|
21
|
+
1. **Define the question** — what exactly are we trying to learn?
|
|
22
|
+
2. **Internal scan** — search the codebase first (Grep, Glob, Read)
|
|
23
|
+
3. **External lookup** — check docs, changelogs, GitHub issues (WebSearch, WebFetch)
|
|
24
|
+
4. **Cross-reference** — validate findings against 2+ sources
|
|
25
|
+
5. **Synthesize** — present findings with confidence levels:
|
|
26
|
+
- **Confirmed**: found in code/docs, verified
|
|
27
|
+
- **Likely**: strong evidence but not 100% confirmed
|
|
28
|
+
- **Uncertain**: limited evidence, needs more investigation
|
|
29
|
+
|
|
30
|
+
## Behavioral Rules
|
|
31
|
+
|
|
32
|
+
1. Never modify code in research mode — read-only exploration
|
|
33
|
+
2. Present findings in structured format (tables, bullet points)
|
|
34
|
+
3. Include file paths and line numbers for all code references
|
|
35
|
+
4. Flag contradictions between sources rather than picking one silently
|
|
36
|
+
5. Estimate scope/effort when the research is for planning purposes
|
|
37
|
+
|
|
38
|
+
## Anti-Patterns
|
|
39
|
+
|
|
40
|
+
- Jumping to a solution after reading one file
|
|
41
|
+
- Modifying code "while we're here" during research
|
|
42
|
+
- Presenting opinions as facts without evidence trail
|
|
43
|
+
- Stopping research early because the first answer looks plausible
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Review Mode
|
|
2
|
+
|
|
3
|
+
Behavioral context for evaluating code quality, correctness, and security. Prioritize thoroughness and constructive feedback.
|
|
4
|
+
|
|
5
|
+
## Principles
|
|
6
|
+
|
|
7
|
+
- **Read everything in scope** — review the full diff, not just highlighted sections
|
|
8
|
+
- **Severity matters** — distinguish blockers from suggestions, label clearly
|
|
9
|
+
- **Constructive over critical** — pair every issue with a concrete fix or alternative
|
|
10
|
+
|
|
11
|
+
## Tool Priority
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
HIGH: Read (full files), Grep (pattern search), Bash (git diff)
|
|
15
|
+
MEDIUM: Glob (find related files), WebSearch (verify best practices)
|
|
16
|
+
LOW: Edit, Write (only for review notes/reports)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Review Dimensions
|
|
20
|
+
|
|
21
|
+
Check each dimension systematically:
|
|
22
|
+
|
|
23
|
+
| Dimension | What to Check |
|
|
24
|
+
|-----------|--------------|
|
|
25
|
+
| **Correctness** | Logic errors, off-by-one, null handling, async/await misuse |
|
|
26
|
+
| **Security** | OWASP patterns, secret exposure, input validation |
|
|
27
|
+
| **Performance** | N+1 queries, unnecessary re-renders, missing indexes |
|
|
28
|
+
| **Maintainability** | Naming clarity, function length, coupling, duplication |
|
|
29
|
+
| **Completeness** | Error handling, edge cases, loading/error states, tests |
|
|
30
|
+
| **Conventions** | Project patterns, naming style, file organization |
|
|
31
|
+
|
|
32
|
+
## Severity Scale
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
BLOCK — Must fix before merge (bugs, security, data loss risk)
|
|
36
|
+
HIGH — Should fix before merge (logic issues, missing validation)
|
|
37
|
+
MEDIUM — Fix soon (code quality, minor performance)
|
|
38
|
+
LOW — Nice to have (style preference, minor improvements)
|
|
39
|
+
PRAISE — Highlight good patterns worth replicating
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Behavioral Rules
|
|
43
|
+
|
|
44
|
+
1. Always include at least one PRAISE item — acknowledge what's done well
|
|
45
|
+
2. Group findings by file, then by severity (BLOCK first)
|
|
46
|
+
3. Show the problematic code AND the suggested fix side-by-side
|
|
47
|
+
4. Check git blame for context — is this new code or existing?
|
|
48
|
+
5. Verify the fix actually works before suggesting it
|
|
49
|
+
|
|
50
|
+
## Anti-Patterns
|
|
51
|
+
|
|
52
|
+
- Drive-by "LGTM" without reading the code
|
|
53
|
+
- Nitpicking style while missing logic bugs
|
|
54
|
+
- Suggesting rewrites when the code is correct and readable
|
|
55
|
+
- Reviewing only the files explicitly mentioned, ignoring related changes
|