@rune-kit/rune 2.2.3 → 2.2.6
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/compiler/adapters/openclaw.js +63 -0
- package/compiler/emitter.js +10 -0
- package/docs/EXTENSION-TEMPLATE.md +18 -0
- package/docs/SKILL-TEMPLATE.md +31 -0
- package/docs/guides/index.html +84 -21
- package/docs/index.html +227 -30
- package/docs/script.js +206 -15
- package/docs/style.css +355 -59
- package/extensions/saas/PACK.md +13 -8
- package/extensions/saas/skills/billing-integration.md +82 -3
- package/package.json +1 -1
- package/skills/audit/SKILL.md +1 -0
- package/skills/ba/SKILL.md +54 -1
- package/skills/completion-gate/SKILL.md +67 -2
- package/skills/cook/SKILL.md +170 -2
- package/skills/debug/SKILL.md +48 -1
- package/skills/deploy/SKILL.md +46 -1
- package/skills/fix/SKILL.md +28 -1
- package/skills/git/SKILL.md +55 -1
- package/skills/hallucination-guard/SKILL.md +21 -6
- package/skills/journal/SKILL.md +51 -3
- package/skills/plan/SKILL.md +152 -4
- package/skills/preflight/SKILL.md +50 -1
- package/skills/research/SKILL.md +36 -8
- package/skills/retro/SKILL.md +314 -0
- package/skills/review/SKILL.md +1 -0
- package/skills/sentinel/SKILL.md +108 -3
- package/skills/sentinel-env/SKILL.md +31 -1
- package/skills/skill-forge/SKILL.md +85 -3
- package/skills/team/SKILL.md +61 -15
- package/skills/test/SKILL.md +105 -9
- package/skills/verification/SKILL.md +29 -1
package/docs/script.js
CHANGED
|
@@ -43,9 +43,9 @@
|
|
|
43
43
|
const dy = nodes[i].y - nodes[j].y;
|
|
44
44
|
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
45
45
|
if (dist < maxDist) {
|
|
46
|
-
const alpha = (1 - dist / maxDist) * 0.
|
|
47
|
-
ctx.strokeStyle = `rgba(
|
|
48
|
-
ctx.lineWidth = 0.
|
|
46
|
+
const alpha = (1 - dist / maxDist) * 0.5;
|
|
47
|
+
ctx.strokeStyle = `rgba(60, 85, 50, ${alpha})`;
|
|
48
|
+
ctx.lineWidth = 0.8;
|
|
49
49
|
ctx.beginPath();
|
|
50
50
|
ctx.moveTo(nodes[i].x, nodes[i].y);
|
|
51
51
|
ctx.lineTo(nodes[j].x, nodes[j].y);
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
|
|
57
57
|
// draw nodes
|
|
58
58
|
for (const n of nodes) {
|
|
59
|
-
ctx.fillStyle = 'rgba(
|
|
59
|
+
ctx.fillStyle = 'rgba(60, 85, 50, 0.7)';
|
|
60
60
|
ctx.beginPath();
|
|
61
61
|
ctx.arc(n.x, n.y, n.r, 0, Math.PI * 2);
|
|
62
62
|
ctx.fill();
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
});
|
|
99
99
|
}, { threshold: 0.1 });
|
|
100
100
|
|
|
101
|
-
document.querySelectorAll('.layer, .feature-card, .workflow-card, .compare-card, .ext-card, .install-card, .pricing-card, .stat').forEach(el => {
|
|
101
|
+
document.querySelectorAll('.layer, .feature-card, .workflow-card, .compare-card, .ext-card, .install-card, .pricing-card, .stat, .mesh-tier, .mesh-point').forEach(el => {
|
|
102
102
|
el.style.animationPlayState = 'paused';
|
|
103
103
|
observer.observe(el);
|
|
104
104
|
});
|
|
@@ -134,29 +134,57 @@
|
|
|
134
134
|
|
|
135
135
|
// ─── Payment Flow ───
|
|
136
136
|
const PAY_API = 'https://pay.theio.vn';
|
|
137
|
-
const BANK_ID = '
|
|
137
|
+
const BANK_ID = 'tpbank';
|
|
138
138
|
const BANK_ACCOUNT = '04162263666';
|
|
139
|
-
const ACCOUNT_NAME = 'NGUYEN
|
|
139
|
+
const ACCOUNT_NAME = 'NGUYEN VIET NAM';
|
|
140
|
+
|
|
141
|
+
// Launch promo: 50% off for 7 days
|
|
142
|
+
const PROMO = {
|
|
143
|
+
discount: 0.5,
|
|
144
|
+
endsAt: new Date('2026-03-25T23:59:59+07:00').getTime(),
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
function isPromoActive() {
|
|
148
|
+
return Date.now() < PROMO.endsAt;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function fmtVND(n) {
|
|
152
|
+
return n.toLocaleString('vi-VN') + ' VND';
|
|
153
|
+
}
|
|
140
154
|
|
|
141
155
|
const PRODUCT_INFO = {
|
|
142
156
|
'rune-pro': {
|
|
143
157
|
title: 'Get Rune Pro', titleShort: 'Rune Pro',
|
|
144
|
-
|
|
145
|
-
amountLabel: '1,190,000 VND (~$49 USD)',
|
|
158
|
+
basePrice: 1190000, baseIntl: 49,
|
|
146
159
|
btnClass: 'btn-pro',
|
|
147
160
|
},
|
|
148
161
|
'rune-biz': {
|
|
149
162
|
title: 'Get Rune Business', titleShort: 'Rune Business',
|
|
150
|
-
|
|
151
|
-
amountLabel: '3,590,000 VND (~$149 USD)',
|
|
163
|
+
basePrice: 3590000, baseIntl: 149,
|
|
152
164
|
btnClass: 'btn-biz',
|
|
153
165
|
},
|
|
154
166
|
};
|
|
155
167
|
|
|
168
|
+
function getProductPricing(key) {
|
|
169
|
+
const info = PRODUCT_INFO[key];
|
|
170
|
+
const promo = isPromoActive();
|
|
171
|
+
const price = promo ? Math.round(info.basePrice * (1 - PROMO.discount)) : info.basePrice;
|
|
172
|
+
const intl = promo ? Math.round(info.baseIntl * (1 - PROMO.discount)) : info.baseIntl;
|
|
173
|
+
return {
|
|
174
|
+
...info,
|
|
175
|
+
priceVN: fmtVND(price),
|
|
176
|
+
priceIntl: '$' + intl + ' USD',
|
|
177
|
+
amountLabel: fmtVND(price) + ' (~$' + intl + ' USD)',
|
|
178
|
+
promo,
|
|
179
|
+
originalVN: fmtVND(info.basePrice),
|
|
180
|
+
originalIntl: '$' + info.baseIntl + ' USD',
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
156
184
|
let payState = { product: null, orderCode: null, pollTimer: null };
|
|
157
185
|
|
|
158
186
|
function openPayment(product) {
|
|
159
|
-
const info =
|
|
187
|
+
const info = getProductPricing(product);
|
|
160
188
|
if (!info) return;
|
|
161
189
|
|
|
162
190
|
payState = { product, orderCode: null, pollTimer: null };
|
|
@@ -164,8 +192,17 @@ function openPayment(product) {
|
|
|
164
192
|
document.getElementById('pay-title').textContent = info.title;
|
|
165
193
|
document.getElementById('pay-title-2').textContent = info.title;
|
|
166
194
|
document.getElementById('pay-amount-2').textContent = info.amountLabel;
|
|
167
|
-
|
|
168
|
-
document.getElementById('pay-price-
|
|
195
|
+
|
|
196
|
+
const vnPriceEl = document.getElementById('pay-price-vn');
|
|
197
|
+
const intlPriceEl = document.getElementById('pay-price-intl');
|
|
198
|
+
if (info.promo) {
|
|
199
|
+
vnPriceEl.innerHTML = '<s style="opacity:.5">' + info.originalVN + '</s> ' + info.priceVN;
|
|
200
|
+
intlPriceEl.innerHTML = '<s style="opacity:.5">' + info.originalIntl + '</s> ' + info.priceIntl;
|
|
201
|
+
} else {
|
|
202
|
+
vnPriceEl.textContent = info.priceVN;
|
|
203
|
+
intlPriceEl.textContent = info.priceIntl;
|
|
204
|
+
}
|
|
205
|
+
|
|
169
206
|
document.getElementById('pay-github').value = '';
|
|
170
207
|
document.getElementById('pay-email').value = '';
|
|
171
208
|
document.getElementById('pay-error').hidden = true;
|
|
@@ -190,7 +227,7 @@ function closePayment() {
|
|
|
190
227
|
}
|
|
191
228
|
|
|
192
229
|
function showPayStep(n) {
|
|
193
|
-
for (let i = 1; i <=
|
|
230
|
+
for (let i = 1; i <= 5; i++) {
|
|
194
231
|
document.getElementById('pay-step-' + i).hidden = (i !== n);
|
|
195
232
|
}
|
|
196
233
|
}
|
|
@@ -200,6 +237,70 @@ function showVNPayment() {
|
|
|
200
237
|
document.getElementById('pay-github').focus();
|
|
201
238
|
}
|
|
202
239
|
|
|
240
|
+
function showIntlPayment() {
|
|
241
|
+
const info = getProductPricing(payState.product);
|
|
242
|
+
document.getElementById('pay-title-5').textContent = info.title;
|
|
243
|
+
document.getElementById('pay-amount-5').textContent = info.priceIntl;
|
|
244
|
+
document.getElementById('pay-intl-github').value = '';
|
|
245
|
+
document.getElementById('pay-intl-email').value = '';
|
|
246
|
+
document.getElementById('pay-intl-error').hidden = true;
|
|
247
|
+
|
|
248
|
+
const btn = document.getElementById('pay-intl-submit');
|
|
249
|
+
btn.className = 'btn ' + info.btnClass;
|
|
250
|
+
btn.style.width = '100%';
|
|
251
|
+
btn.style.marginTop = '16px';
|
|
252
|
+
|
|
253
|
+
showPayStep(5);
|
|
254
|
+
document.getElementById('pay-intl-github').focus();
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
async function startPolarCheckout() {
|
|
258
|
+
const github = document.getElementById('pay-intl-github').value.trim();
|
|
259
|
+
const email = document.getElementById('pay-intl-email').value.trim();
|
|
260
|
+
const errorEl = document.getElementById('pay-intl-error');
|
|
261
|
+
|
|
262
|
+
if (!github) {
|
|
263
|
+
errorEl.textContent = 'Please enter your GitHub username';
|
|
264
|
+
errorEl.hidden = false;
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (!/^[a-zA-Z0-9](?:[a-zA-Z0-9]|-(?=[a-zA-Z0-9])){0,38}$/.test(github)) {
|
|
269
|
+
errorEl.textContent = 'Invalid GitHub username format';
|
|
270
|
+
errorEl.hidden = false;
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
errorEl.hidden = true;
|
|
275
|
+
const btn = document.getElementById('pay-intl-submit');
|
|
276
|
+
btn.disabled = true;
|
|
277
|
+
btn.textContent = 'Redirecting to checkout...';
|
|
278
|
+
|
|
279
|
+
try {
|
|
280
|
+
const res = await fetch(PAY_API + '/checkout/polar', {
|
|
281
|
+
method: 'POST',
|
|
282
|
+
headers: { 'Content-Type': 'application/json' },
|
|
283
|
+
body: JSON.stringify({
|
|
284
|
+
product: payState.product,
|
|
285
|
+
githubUsername: github,
|
|
286
|
+
email: email || undefined,
|
|
287
|
+
}),
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
const data = await res.json();
|
|
291
|
+
if (!data.success || !data.url) throw new Error(data.error || 'Failed to create checkout');
|
|
292
|
+
|
|
293
|
+
// Redirect to Polar checkout page
|
|
294
|
+
window.location.href = data.url;
|
|
295
|
+
} catch (err) {
|
|
296
|
+
errorEl.textContent = err.message;
|
|
297
|
+
errorEl.hidden = false;
|
|
298
|
+
} finally {
|
|
299
|
+
btn.disabled = false;
|
|
300
|
+
btn.textContent = 'Pay with Card / PayPal';
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
203
304
|
async function createOrder() {
|
|
204
305
|
const github = document.getElementById('pay-github').value.trim();
|
|
205
306
|
const email = document.getElementById('pay-email').value.trim();
|
|
@@ -275,3 +376,93 @@ function startPolling(github) {
|
|
|
275
376
|
}
|
|
276
377
|
}, 5000);
|
|
277
378
|
}
|
|
379
|
+
|
|
380
|
+
// ─── Promo Countdown ───
|
|
381
|
+
(function initPromoCountdown() {
|
|
382
|
+
if (!isPromoActive()) return;
|
|
383
|
+
|
|
384
|
+
// Add "50% OFF" ribbon to Pro and Business cards
|
|
385
|
+
['.pricing-pro', '.pricing-biz'].forEach(sel => {
|
|
386
|
+
const card = document.querySelector(sel);
|
|
387
|
+
if (!card) return;
|
|
388
|
+
const ribbon = document.createElement('div');
|
|
389
|
+
ribbon.className = 'promo-ribbon';
|
|
390
|
+
ribbon.textContent = '50% OFF';
|
|
391
|
+
card.appendChild(ribbon);
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
// Update pricing cards with promo prices + save badge
|
|
395
|
+
const proCard = document.querySelector('.pricing-pro .pricing-price');
|
|
396
|
+
const bizCard = document.querySelector('.pricing-biz .pricing-price');
|
|
397
|
+
if (proCard) proCard.innerHTML = '<s style="opacity:.35;font-size:.55em">$49</s> $25<span class="pricing-period"> lifetime</span><br><span class="promo-save">Save $24</span>';
|
|
398
|
+
if (bizCard) bizCard.innerHTML = '<s style="opacity:.35;font-size:.55em">$149</s> $75<span class="pricing-period"> lifetime</span><br><span class="promo-save">Save $74</span>';
|
|
399
|
+
|
|
400
|
+
// Update "What's Included" values in Business card
|
|
401
|
+
document.querySelectorAll('.includes-value').forEach(el => {
|
|
402
|
+
if (el.textContent.includes('$49')) el.innerHTML = '<s>$49</s> $25 value';
|
|
403
|
+
if (el.textContent.includes('$100')) el.innerHTML = '<s>$100</s> $50 value';
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
// Update buttons
|
|
407
|
+
const proBtn = document.querySelector('.pricing-pro .btn-pro');
|
|
408
|
+
const bizBtn = document.querySelector('.pricing-biz .btn-biz');
|
|
409
|
+
if (proBtn) proBtn.innerHTML = 'Get Rune Pro — <s style="opacity:.6">$49</s> $25';
|
|
410
|
+
if (bizBtn) bizBtn.innerHTML = 'Get Rune Business — <s style="opacity:.6">$149</s> $75';
|
|
411
|
+
|
|
412
|
+
// Update comparison table
|
|
413
|
+
document.querySelectorAll('.table-price').forEach(el => {
|
|
414
|
+
if (el.textContent.includes('$49')) el.innerHTML = '<s style="opacity:.5">$49</s> $25';
|
|
415
|
+
if (el.textContent.includes('$149')) el.innerHTML = '<s style="opacity:.5">$149</s> $75';
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
// Create countdown banner (sticky bottom)
|
|
419
|
+
const banner = document.createElement('div');
|
|
420
|
+
banner.id = 'promo-banner';
|
|
421
|
+
banner.style.cssText = `
|
|
422
|
+
position:fixed;bottom:0;left:0;right:0;z-index:9999;
|
|
423
|
+
background:linear-gradient(135deg,#4a6843 0%,#5b7852 50%,#7a9e6e 100%);
|
|
424
|
+
color:#fff;text-align:center;padding:10px 16px;
|
|
425
|
+
font:600 14px/1.4 "Space Grotesk",sans-serif;
|
|
426
|
+
display:flex;align-items:center;justify-content:center;gap:16px;
|
|
427
|
+
box-shadow:0 -4px 20px rgba(91,120,82,.2);
|
|
428
|
+
`.replace(/\n\s+/g, '');
|
|
429
|
+
banner.innerHTML = ''
|
|
430
|
+
+ '<span style="font-size:18px">⚡</span>'
|
|
431
|
+
+ '<span><strong>Launch Week</strong> — 50% OFF all paid packs</span>'
|
|
432
|
+
+ '<span id="promo-timer" style="font-family:JetBrains Mono,monospace;font-weight:700;background:rgba(0,0,0,.2);padding:5px 12px;border-radius:6px;letter-spacing:.5px;min-width:150px"></span>'
|
|
433
|
+
+ '<a href="#pricing" style="background:#f5f0e8;color:#4a6843;text-decoration:none;font-weight:700;padding:6px 16px;border-radius:6px;font-size:13px;white-space:nowrap">Grab the deal →</a>';
|
|
434
|
+
document.body.appendChild(banner);
|
|
435
|
+
document.body.style.paddingBottom = '52px';
|
|
436
|
+
|
|
437
|
+
function tick() {
|
|
438
|
+
const diff = PROMO.endsAt - Date.now();
|
|
439
|
+
if (diff <= 0) { banner.remove(); document.body.style.paddingBottom = ''; return; }
|
|
440
|
+
const d = Math.floor(diff / 86400000);
|
|
441
|
+
const h = Math.floor((diff % 86400000) / 3600000);
|
|
442
|
+
const m = Math.floor((diff % 3600000) / 60000);
|
|
443
|
+
const s = Math.floor((diff % 60000) / 1000);
|
|
444
|
+
const timer = document.getElementById('promo-timer');
|
|
445
|
+
if (timer) timer.textContent = d + 'd ' + h + 'h ' + m + 'm ' + s + 's';
|
|
446
|
+
}
|
|
447
|
+
tick();
|
|
448
|
+
setInterval(tick, 1000);
|
|
449
|
+
})();
|
|
450
|
+
|
|
451
|
+
// ─── Polar Success Return ───
|
|
452
|
+
(function checkPolarReturn() {
|
|
453
|
+
const params = new URLSearchParams(window.location.search);
|
|
454
|
+
if (params.get('polar') === 'success') {
|
|
455
|
+
// Clean URL
|
|
456
|
+
window.history.replaceState({}, '', window.location.pathname);
|
|
457
|
+
// Show success message
|
|
458
|
+
const modal = document.getElementById('pay-modal');
|
|
459
|
+
if (modal) {
|
|
460
|
+
modal.hidden = false;
|
|
461
|
+
document.body.style.overflow = 'hidden';
|
|
462
|
+
document.getElementById('pay-success-user').textContent = 'you';
|
|
463
|
+
for (let i = 1; i <= 5; i++) {
|
|
464
|
+
document.getElementById('pay-step-' + i).hidden = (i !== 4);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
})();
|