@rune-kit/rune 2.2.1 → 2.2.2

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.
Files changed (65) hide show
  1. package/README.md +39 -13
  2. package/compiler/bin/rune.js +26 -4
  3. package/docs/ANTIGRAVITY-GAP-ANALYSIS.md +369 -0
  4. package/docs/ARCHITECTURE.md +332 -0
  5. package/docs/COMMUNITY-PACKS.md +109 -0
  6. package/docs/CONTRIBUTING-L4.md +215 -0
  7. package/docs/CROSS-IDE-ANALYSIS.md +164 -0
  8. package/docs/EXTENSION-TEMPLATE.md +108 -0
  9. package/docs/MESH-RULES.md +34 -0
  10. package/docs/MULTI-PLATFORM.md +804 -0
  11. package/docs/SKILL-DEPTH-AUDIT.md +191 -0
  12. package/docs/SKILL-TEMPLATE.md +72 -0
  13. package/docs/TRADE-MATRIX.md +327 -0
  14. package/docs/VERSIONING.md +91 -0
  15. package/docs/VISION.md +263 -0
  16. package/docs/assets/demo-subtitles.srt +215 -0
  17. package/docs/assets/end-card.html +276 -0
  18. package/docs/assets/mesh-diagram.html +654 -0
  19. package/docs/assets/thumbnail.html +295 -0
  20. package/docs/guides/cli.md +403 -0
  21. package/docs/guides/index.html +1346 -0
  22. package/docs/index.html +674 -0
  23. package/docs/references/claudekit-analysis.md +414 -0
  24. package/docs/references/voltagent-analysis.md +189 -0
  25. package/docs/script.js +277 -0
  26. package/docs/skills/index.html +832 -0
  27. package/docs/style.css +583 -0
  28. package/docs/video-demo-plan.md +172 -0
  29. package/extensions/ui/PACK.md +2 -0
  30. package/extensions/ui/skills/design-decision.md +10 -0
  31. package/extensions/ui/skills/palette-picker.md +11 -0
  32. package/hooks/.gitkeep +0 -0
  33. package/hooks/auto-format/index.cjs +48 -0
  34. package/hooks/context-watch/index.cjs +68 -0
  35. package/hooks/hooks.json +99 -0
  36. package/hooks/metrics-collector/index.cjs +42 -0
  37. package/hooks/post-session-reflect/index.cjs +153 -0
  38. package/hooks/pre-compact/index.cjs +95 -0
  39. package/hooks/pre-tool-guard/index.cjs +68 -0
  40. package/hooks/run-hook +17 -0
  41. package/hooks/run-hook.cjs +16 -0
  42. package/hooks/run-hook.cmd +1 -0
  43. package/hooks/secrets-scan/index.cjs +100 -0
  44. package/hooks/session-start/index.cjs +65 -0
  45. package/hooks/typecheck/index.cjs +65 -0
  46. package/package.json +9 -4
  47. package/references/ui-pro-max-data/LICENSE-UI-PRO-MAX +21 -0
  48. package/references/ui-pro-max-data/charts.csv +26 -0
  49. package/references/ui-pro-max-data/colors.csv +162 -0
  50. package/references/ui-pro-max-data/styles.csv +85 -0
  51. package/references/ui-pro-max-data/typography.csv +74 -0
  52. package/references/ui-pro-max-data/ui-reasoning.csv +162 -0
  53. package/references/ui-pro-max-data/ux-guidelines.csv +100 -0
  54. package/skills/ba/SKILL.md +10 -0
  55. package/skills/completion-gate/SKILL.md +34 -1
  56. package/skills/context-engine/SKILL.md +13 -0
  57. package/skills/cook/SKILL.md +71 -0
  58. package/skills/debug/SKILL.md +56 -1
  59. package/skills/design/SKILL.md +11 -0
  60. package/skills/fix/SKILL.md +26 -1
  61. package/skills/plan/SKILL.md +23 -6
  62. package/skills/review/SKILL.md +2 -0
  63. package/skills/skill-forge/SKILL.md +38 -3
  64. package/skills/test/SKILL.md +10 -1
  65. package/skills/verification/SKILL.md +60 -2
package/docs/script.js ADDED
@@ -0,0 +1,277 @@
1
+ // ─── Mesh Canvas Animation ───
2
+ (function initMesh() {
3
+ const canvas = document.getElementById('mesh-canvas');
4
+ if (!canvas) return;
5
+ const ctx = canvas.getContext('2d');
6
+ let w, h, nodes, animId;
7
+
8
+ function resize() {
9
+ w = canvas.width = canvas.parentElement.offsetWidth;
10
+ h = canvas.height = canvas.parentElement.offsetHeight;
11
+ }
12
+
13
+ function createNodes(count) {
14
+ const arr = [];
15
+ for (let i = 0; i < count; i++) {
16
+ arr.push({
17
+ x: Math.random() * w,
18
+ y: Math.random() * h,
19
+ vx: (Math.random() - 0.5) * 0.4,
20
+ vy: (Math.random() - 0.5) * 0.4,
21
+ r: Math.random() * 2 + 1
22
+ });
23
+ }
24
+ return arr;
25
+ }
26
+
27
+ function draw() {
28
+ ctx.clearRect(0, 0, w, h);
29
+ const maxDist = 160;
30
+
31
+ // move nodes
32
+ for (const n of nodes) {
33
+ n.x += n.vx;
34
+ n.y += n.vy;
35
+ if (n.x < 0 || n.x > w) n.vx *= -1;
36
+ if (n.y < 0 || n.y > h) n.vy *= -1;
37
+ }
38
+
39
+ // draw connections
40
+ for (let i = 0; i < nodes.length; i++) {
41
+ for (let j = i + 1; j < nodes.length; j++) {
42
+ const dx = nodes[i].x - nodes[j].x;
43
+ const dy = nodes[i].y - nodes[j].y;
44
+ const dist = Math.sqrt(dx * dx + dy * dy);
45
+ if (dist < maxDist) {
46
+ const alpha = (1 - dist / maxDist) * 0.35;
47
+ ctx.strokeStyle = `rgba(16, 185, 129, ${alpha})`;
48
+ ctx.lineWidth = 0.6;
49
+ ctx.beginPath();
50
+ ctx.moveTo(nodes[i].x, nodes[i].y);
51
+ ctx.lineTo(nodes[j].x, nodes[j].y);
52
+ ctx.stroke();
53
+ }
54
+ }
55
+ }
56
+
57
+ // draw nodes
58
+ for (const n of nodes) {
59
+ ctx.fillStyle = 'rgba(16, 185, 129, 0.6)';
60
+ ctx.beginPath();
61
+ ctx.arc(n.x, n.y, n.r, 0, Math.PI * 2);
62
+ ctx.fill();
63
+ }
64
+
65
+ animId = requestAnimationFrame(draw);
66
+ }
67
+
68
+ function start() {
69
+ resize();
70
+ const density = Math.min(60, Math.floor((w * h) / 15000));
71
+ nodes = createNodes(density);
72
+ if (animId) cancelAnimationFrame(animId);
73
+ draw();
74
+ }
75
+
76
+ // respect reduced motion
77
+ if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
78
+ resize();
79
+ nodes = createNodes(30);
80
+ // draw one static frame
81
+ draw();
82
+ cancelAnimationFrame(animId);
83
+ return;
84
+ }
85
+
86
+ start();
87
+ window.addEventListener('resize', () => { start(); });
88
+ })();
89
+
90
+ // ─── Scroll-triggered animations ───
91
+ (function initScrollAnimations() {
92
+ const observer = new IntersectionObserver((entries) => {
93
+ entries.forEach(entry => {
94
+ if (entry.isIntersecting) {
95
+ entry.target.style.animationPlayState = 'running';
96
+ observer.unobserve(entry.target);
97
+ }
98
+ });
99
+ }, { threshold: 0.1 });
100
+
101
+ document.querySelectorAll('.layer, .feature-card, .workflow-card, .compare-card, .ext-card, .install-card, .pricing-card, .stat').forEach(el => {
102
+ el.style.animationPlayState = 'paused';
103
+ observer.observe(el);
104
+ });
105
+ })();
106
+
107
+ // ─── Counter animation ───
108
+ (function initCounters() {
109
+ const observer = new IntersectionObserver((entries) => {
110
+ entries.forEach(entry => {
111
+ if (entry.isIntersecting) {
112
+ const el = entry.target;
113
+ const target = parseInt(el.dataset.target, 10);
114
+ const duration = 1200;
115
+ const start = performance.now();
116
+
117
+ function tick(now) {
118
+ const elapsed = now - start;
119
+ const progress = Math.min(elapsed / duration, 1);
120
+ // ease out cubic
121
+ const eased = 1 - Math.pow(1 - progress, 3);
122
+ el.textContent = Math.round(target * eased);
123
+ if (progress < 1) requestAnimationFrame(tick);
124
+ }
125
+
126
+ requestAnimationFrame(tick);
127
+ observer.unobserve(el);
128
+ }
129
+ });
130
+ }, { threshold: 0.5 });
131
+
132
+ document.querySelectorAll('.stat-num[data-target]').forEach(el => observer.observe(el));
133
+ })();
134
+
135
+ // ─── Payment Flow ───
136
+ const PAY_API = 'https://pay.theio.vn';
137
+ const BANK_ID = 'vpbank';
138
+ const BANK_ACCOUNT = '04162263666';
139
+ const ACCOUNT_NAME = 'NGUYEN CONG';
140
+
141
+ const PRODUCT_INFO = {
142
+ 'rune-pro': {
143
+ title: 'Get Rune Pro', titleShort: 'Rune Pro',
144
+ priceVN: '1,190,000 VND', priceIntl: '$49 USD',
145
+ amountLabel: '1,190,000 VND (~$49 USD)',
146
+ btnClass: 'btn-pro',
147
+ },
148
+ 'rune-biz': {
149
+ title: 'Get Rune Business', titleShort: 'Rune Business',
150
+ priceVN: '3,590,000 VND', priceIntl: '$149 USD',
151
+ amountLabel: '3,590,000 VND (~$149 USD)',
152
+ btnClass: 'btn-biz',
153
+ },
154
+ };
155
+
156
+ let payState = { product: null, orderCode: null, pollTimer: null };
157
+
158
+ function openPayment(product) {
159
+ const info = PRODUCT_INFO[product];
160
+ if (!info) return;
161
+
162
+ payState = { product, orderCode: null, pollTimer: null };
163
+
164
+ document.getElementById('pay-title').textContent = info.title;
165
+ document.getElementById('pay-title-2').textContent = info.title;
166
+ document.getElementById('pay-amount-2').textContent = info.amountLabel;
167
+ document.getElementById('pay-price-vn').textContent = info.priceVN;
168
+ document.getElementById('pay-price-intl').textContent = info.priceIntl;
169
+ document.getElementById('pay-github').value = '';
170
+ document.getElementById('pay-email').value = '';
171
+ document.getElementById('pay-error').hidden = true;
172
+
173
+ const submitBtn = document.getElementById('pay-submit');
174
+ submitBtn.className = 'btn ' + info.btnClass;
175
+ submitBtn.style.width = '100%';
176
+ submitBtn.style.marginTop = '16px';
177
+
178
+ showPayStep(1);
179
+ document.getElementById('pay-modal').hidden = false;
180
+ document.body.style.overflow = 'hidden';
181
+ }
182
+
183
+ function closePayment() {
184
+ document.getElementById('pay-modal').hidden = true;
185
+ document.body.style.overflow = '';
186
+ if (payState.pollTimer) {
187
+ clearInterval(payState.pollTimer);
188
+ payState.pollTimer = null;
189
+ }
190
+ }
191
+
192
+ function showPayStep(n) {
193
+ for (let i = 1; i <= 4; i++) {
194
+ document.getElementById('pay-step-' + i).hidden = (i !== n);
195
+ }
196
+ }
197
+
198
+ function showVNPayment() {
199
+ showPayStep(2);
200
+ document.getElementById('pay-github').focus();
201
+ }
202
+
203
+ async function createOrder() {
204
+ const github = document.getElementById('pay-github').value.trim();
205
+ const email = document.getElementById('pay-email').value.trim();
206
+ const errorEl = document.getElementById('pay-error');
207
+
208
+ if (!github) {
209
+ errorEl.textContent = 'Please enter your GitHub username';
210
+ errorEl.hidden = false;
211
+ return;
212
+ }
213
+
214
+ if (!/^[a-zA-Z0-9](?:[a-zA-Z0-9]|-(?=[a-zA-Z0-9])){0,38}$/.test(github)) {
215
+ errorEl.textContent = 'Invalid GitHub username format';
216
+ errorEl.hidden = false;
217
+ return;
218
+ }
219
+
220
+ errorEl.hidden = true;
221
+ const submitBtn = document.getElementById('pay-submit');
222
+ submitBtn.disabled = true;
223
+ submitBtn.textContent = 'Creating order...';
224
+
225
+ try {
226
+ const res = await fetch(PAY_API + '/order/create', {
227
+ method: 'POST',
228
+ headers: { 'Content-Type': 'application/json' },
229
+ body: JSON.stringify({ product: payState.product, githubUsername: github, email: email || undefined }),
230
+ });
231
+
232
+ const data = await res.json();
233
+ if (!data.success) throw new Error(data.error || 'Failed to create order');
234
+
235
+ payState.orderCode = data.orderCode;
236
+
237
+ const qrUrl = `https://img.vietqr.io/image/${BANK_ID}-${BANK_ACCOUNT}-compact.png`
238
+ + `?amount=${data.amount}&addInfo=${encodeURIComponent(data.orderCode)}`
239
+ + `&accountName=${encodeURIComponent(ACCOUNT_NAME)}`;
240
+
241
+ document.getElementById('pay-qr-img').src = qrUrl;
242
+ document.getElementById('pay-detail-amount').textContent = data.amount.toLocaleString('vi-VN') + ' VND';
243
+ document.getElementById('pay-detail-code').textContent = data.orderCode;
244
+
245
+ showPayStep(3);
246
+ startPolling(github);
247
+ } catch (err) {
248
+ errorEl.textContent = err.message;
249
+ errorEl.hidden = false;
250
+ } finally {
251
+ submitBtn.disabled = false;
252
+ submitBtn.textContent = 'Continue to Payment';
253
+ }
254
+ }
255
+
256
+ function startPolling(github) {
257
+ if (payState.pollTimer) clearInterval(payState.pollTimer);
258
+
259
+ payState.pollTimer = setInterval(async () => {
260
+ try {
261
+ const res = await fetch(PAY_API + '/order/' + payState.orderCode);
262
+ const data = await res.json();
263
+
264
+ if (data.status === 'delivered') {
265
+ clearInterval(payState.pollTimer);
266
+ payState.pollTimer = null;
267
+ document.getElementById('pay-success-user').textContent = github;
268
+ showPayStep(4);
269
+ } else if (data.status === 'underpaid') {
270
+ document.getElementById('pay-status').innerHTML =
271
+ '<span style="color:var(--loss)">&#9888; Amount too low. Please transfer the exact amount.</span>';
272
+ }
273
+ } catch (_) {
274
+ // silent retry
275
+ }
276
+ }, 5000);
277
+ }