@kolbo/mcp 1.82.5 → 1.82.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/package.json +1 -1
- package/src/apps/index.js +5 -0
- package/src/apps/theme.js +2 -0
- package/src/apps/widgets/plans.js +14 -104
package/package.json
CHANGED
package/src/apps/index.js
CHANGED
|
@@ -97,6 +97,11 @@ const WIDGET_CSP = {
|
|
|
97
97
|
connectDomains: [
|
|
98
98
|
'https://api.kolbo.ai',
|
|
99
99
|
],
|
|
100
|
+
// Nested iframes. Empty/omitted → frame-src 'none' and the live pricing
|
|
101
|
+
// embed inside the upgrade card is a blank box.
|
|
102
|
+
frameDomains: [
|
|
103
|
+
'https://app.kolbo.ai',
|
|
104
|
+
],
|
|
100
105
|
};
|
|
101
106
|
|
|
102
107
|
/** Register all Kolbo widget resources on an McpServer. */
|
package/src/apps/theme.js
CHANGED
|
@@ -183,6 +183,8 @@ html.k-peek-fs .k-peek img, html.k-peek-fs .k-peek video { max-height: calc(100v
|
|
|
183
183
|
.k-pack-head { margin: 14px 0 6px; font-size: 11px; font-weight: 700; letter-spacing: 0.04em;
|
|
184
184
|
text-transform: uppercase; color: var(--text-faint); }
|
|
185
185
|
.k-pack-row { margin-bottom: 6px; }
|
|
186
|
+
.k-pricing-frame { display: block; width: 100%; height: 560px; border: 0; border-radius: 12px;
|
|
187
|
+
background: #0f0f0f; }
|
|
186
188
|
/* Visual DNA chips: the character's face, so you can see WHICH DNA is locked in. */
|
|
187
189
|
.k-dna-face { width: 18px; height: 18px; border-radius: 999px; object-fit: cover; margin-left: -3px; background: var(--border-strong); }
|
|
188
190
|
.k-dna-stack .k-dna-stack-item { display: inline-flex; }
|
|
@@ -6,11 +6,11 @@ const { widgetPage } = require('../html');
|
|
|
6
6
|
* Plans / upgrade widget — shown by `show_plans`, and by any generation the
|
|
7
7
|
* server refused for credits.
|
|
8
8
|
*
|
|
9
|
-
* The
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
9
|
+
* The live pricing UI lives on app.kolbo.ai. This card iframes
|
|
10
|
+
* `/pricing/embed` (same PlanList / PricingCard as the site) so a price or
|
|
11
|
+
* perk change does not require an MCP republish. Buy/Subscribe on that page
|
|
12
|
+
* open https://app.kolbo.ai/pricing in a new tab — Stripe and the user's
|
|
13
|
+
* session must not run inside a third-party host iframe.
|
|
14
14
|
*
|
|
15
15
|
* structuredContent contract:
|
|
16
16
|
* {
|
|
@@ -19,8 +19,8 @@ const { widgetPage } = require('../html');
|
|
|
19
19
|
* balance, required, shortfall, // when reason === 'insufficient_credits'
|
|
20
20
|
* current_plan: { key, name },
|
|
21
21
|
* plans: [{ key, name, interval, credits, price, original_price,
|
|
22
|
-
* discount_percent, promo_text, currency }],
|
|
23
|
-
* credit_packs: [
|
|
22
|
+
* discount_percent, promo_text, currency, top_up_discount }],
|
|
23
|
+
* credit_packs: [{ …, subscriber_price, is_subscriber }],
|
|
24
24
|
* pricing_url
|
|
25
25
|
* }
|
|
26
26
|
*/
|
|
@@ -35,10 +35,6 @@ const BODY = `
|
|
|
35
35
|
</div>
|
|
36
36
|
<div class="k-body">
|
|
37
37
|
<div class="k-error" id="notice" style="display:none"></div>
|
|
38
|
-
<div class="k-plan-toggle" id="toggle" style="display:none">
|
|
39
|
-
<button type="button" class="k-toggle-btn" data-interval="month">Monthly</button>
|
|
40
|
-
<button type="button" class="k-toggle-btn" data-interval="year">Annual</button>
|
|
41
|
-
</div>
|
|
42
38
|
<div id="stage"></div>
|
|
43
39
|
<div class="k-actions" id="actions"></div>
|
|
44
40
|
</div>
|
|
@@ -50,7 +46,7 @@ const BODY = `
|
|
|
50
46
|
|
|
51
47
|
const SCRIPT = `
|
|
52
48
|
var state = null;
|
|
53
|
-
var
|
|
49
|
+
var PRICING_EMBED = 'https://app.kolbo.ai/pricing/embed';
|
|
54
50
|
|
|
55
51
|
el('logo').innerHTML = KOLBO_LOGO + '<span>Kolbo</span>';
|
|
56
52
|
el('kolbo-link').onclick = function (e) { e.preventDefault(); window.kolbo.openLink('https://app.kolbo.ai'); };
|
|
@@ -58,17 +54,6 @@ el('kolbo-link').onclick = function (e) { e.preventDefault(); window.kolbo.openL
|
|
|
58
54
|
function pricingUrl() {
|
|
59
55
|
return (state && state.pricing_url) || 'https://app.kolbo.ai/pricing';
|
|
60
56
|
}
|
|
61
|
-
function money(amount, currency) {
|
|
62
|
-
if (amount == null) return '';
|
|
63
|
-
var sym = String(currency || 'usd').toLowerCase() === 'usd' ? '$' : '';
|
|
64
|
-
var n = Math.round(Number(amount) * 100) / 100;
|
|
65
|
-
return sym + n + (sym ? '' : ' ' + String(currency || '').toUpperCase());
|
|
66
|
-
}
|
|
67
|
-
function perMonthNote(plan) {
|
|
68
|
-
if (plan.interval !== 'year' || plan.price == null) return '';
|
|
69
|
-
var monthly = Math.round((Number(plan.price) / 12) * 100) / 100;
|
|
70
|
-
return money(monthly, plan.currency) + '/mo, billed annually';
|
|
71
|
-
}
|
|
72
57
|
|
|
73
58
|
function boot(sc) {
|
|
74
59
|
if (!sc) return;
|
|
@@ -90,86 +75,12 @@ function boot(sc) {
|
|
|
90
75
|
: 'That generation needs more credits than you have left.');
|
|
91
76
|
}
|
|
92
77
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if (
|
|
97
|
-
el('toggle').style.display = '';
|
|
98
|
-
if (!intervals[interval]) interval = intervals.year ? 'year' : 'month';
|
|
99
|
-
} else {
|
|
100
|
-
interval = intervals.year ? 'year' : 'month';
|
|
101
|
-
}
|
|
102
|
-
wireToggle();
|
|
103
|
-
render();
|
|
104
|
-
window.kolbo.notifySize();
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function wireToggle() {
|
|
108
|
-
Array.prototype.forEach.call(document.querySelectorAll('.k-toggle-btn'), function (b) {
|
|
109
|
-
b.onclick = function () { interval = b.getAttribute('data-interval'); render(); window.kolbo.notifySize(); };
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function render() {
|
|
114
|
-
Array.prototype.forEach.call(document.querySelectorAll('.k-toggle-btn'), function (b) {
|
|
115
|
-
b.classList.toggle('active', b.getAttribute('data-interval') === interval);
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
var plans = (state.plans || []).filter(function (p) { return p.interval === interval; });
|
|
119
|
-
// Cheapest first so the ladder reads left-to-right. A zero-price plan is not
|
|
120
|
-
// an upgrade path, so it never takes a card slot.
|
|
121
|
-
plans = plans.filter(function (p) { return Number(p.price) > 0; });
|
|
122
|
-
plans.sort(function (a, b) { return (a.price || 0) - (b.price || 0); });
|
|
123
|
-
|
|
124
|
-
var current = state.current_plan && state.current_plan.key;
|
|
125
|
-
var html = plans.length
|
|
126
|
-
? '<div class="k-plan-grid">' + plans.map(function (p) { return planCard(p, current); }).join('') + '</div>'
|
|
127
|
-
: '<div class="k-empty">Plan details are on the pricing page</div>';
|
|
128
|
-
|
|
129
|
-
var packs = (state.credit_packs || []).filter(function (p) { return Number(p.price) > 0; });
|
|
130
|
-
if (packs.length) {
|
|
131
|
-
packs.sort(function (a, b) { return (a.price || 0) - (b.price || 0); });
|
|
132
|
-
html += '<div class="k-pack-head">One-time credit packs</div>' +
|
|
133
|
-
packs.slice(0, 4).map(function (p) {
|
|
134
|
-
return '<div class="k-audio-row k-pack-row"><div class="k-audio-meta">' +
|
|
135
|
-
'<div class="k-audio-title">' + esc(p.name || '') + '</div>' +
|
|
136
|
-
(p.credits != null ? '<div class="k-audio-sub">' + esc(String(p.credits)) + ' credits</div>' : '') +
|
|
137
|
-
'</div><span class="k-chip">' + esc(money(p.price, p.currency)) + '</span></div>';
|
|
138
|
-
}).join('');
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
el('stage').innerHTML = html;
|
|
142
|
-
Array.prototype.forEach.call(el('stage').querySelectorAll('[data-buy]'), function (b) {
|
|
143
|
-
b.onclick = function () { window.kolbo.openLink(pricingUrl()); };
|
|
144
|
-
});
|
|
78
|
+
el('stage').innerHTML = '<iframe class="k-pricing-frame" src="' + PRICING_EMBED +
|
|
79
|
+
'" title="Kolbo plans" referrerpolicy="no-referrer-when-downgrade"></iframe>';
|
|
80
|
+
var frame = el('stage').querySelector('iframe');
|
|
81
|
+
if (frame) frame.onload = function () { window.kolbo.notifySize(); };
|
|
145
82
|
renderActions();
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
function planCard(p, currentKey) {
|
|
149
|
-
var isCurrent = currentKey && p.key === currentKey;
|
|
150
|
-
var badges = '';
|
|
151
|
-
if (p.discount_percent) badges += '<span class="k-plan-badge">' + esc(String(p.discount_percent)) + '% OFF</span>';
|
|
152
|
-
if (isCurrent) badges += '<span class="k-plan-badge current">Current</span>';
|
|
153
|
-
|
|
154
|
-
var price = '<span class="k-plan-price">' + esc(money(p.price, p.currency)) + '</span>';
|
|
155
|
-
if (p.original_price && p.original_price > p.price) {
|
|
156
|
-
price = '<span class="k-plan-was">' + esc(money(p.original_price, p.currency)) + '</span> ' + price;
|
|
157
|
-
}
|
|
158
|
-
var note = perMonthNote(p);
|
|
159
|
-
|
|
160
|
-
return '<div class="k-plan' + (isCurrent ? ' current' : '') + '">' +
|
|
161
|
-
'<div class="k-plan-top"><span class="k-plan-name">' + esc(p.name || p.key || '') + '</span>' + badges + '</div>' +
|
|
162
|
-
(p.credits != null
|
|
163
|
-
? '<div class="k-plan-credits">' + ICONS.sparkle + ' ' + esc(String(p.credits)) + ' credits' +
|
|
164
|
-
(p.interval === 'month' ? '/mo' : p.interval === 'year' ? '/yr' : '') + '</div>'
|
|
165
|
-
: '') +
|
|
166
|
-
'<div class="k-plan-pricing">' + price + '</div>' +
|
|
167
|
-
(note ? '<div class="k-plan-note">' + esc(note) + '</div>' : '') +
|
|
168
|
-
(p.promo_text ? '<div class="k-plan-note">' + esc(p.promo_text) + '</div>' : '') +
|
|
169
|
-
(isCurrent
|
|
170
|
-
? '<button class="k-btn" disabled>Your plan</button>'
|
|
171
|
-
: '<button class="k-btn primary" data-buy="' + esc(p.key || '') + '">Get ' + esc(p.name || 'plan') + '</button>') +
|
|
172
|
-
'</div>';
|
|
83
|
+
window.kolbo.notifySize();
|
|
173
84
|
}
|
|
174
85
|
|
|
175
86
|
function renderActions() {
|
|
@@ -184,8 +95,7 @@ window.kolbo.onToolResult(function (result) {
|
|
|
184
95
|
});
|
|
185
96
|
window.kolbo.onToolInput(function () {
|
|
186
97
|
if (state) return;
|
|
187
|
-
el('stage').innerHTML = '<div class="k-
|
|
188
|
-
+ '<div class="k-skel square" style="min-height:120px"></div></div>';
|
|
98
|
+
el('stage').innerHTML = '<div class="k-skel square" style="min-height:240px"></div>';
|
|
189
99
|
window.kolbo.notifySize();
|
|
190
100
|
});
|
|
191
101
|
window.kolbo.ready(function (ctx) {
|