@corenel/ui-kit 0.1.0
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/dist/host.d.ts +26 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +27 -0
- package/dist/host.js.map +1 -0
- package/dist/icons.d.ts +75 -0
- package/dist/icons.d.ts.map +1 -0
- package/dist/icons.js +109 -0
- package/dist/icons.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/languages.d.ts +28 -0
- package/dist/languages.d.ts.map +1 -0
- package/dist/languages.js +29 -0
- package/dist/languages.js.map +1 -0
- package/dist/monacoColorize.d.ts +7 -0
- package/dist/monacoColorize.d.ts.map +1 -0
- package/dist/monacoColorize.js +143 -0
- package/dist/monacoColorize.js.map +1 -0
- package/dist/prmdLanguage.d.ts +12 -0
- package/dist/prmdLanguage.d.ts.map +1 -0
- package/dist/prmdLanguage.js +218 -0
- package/dist/prmdLanguage.js.map +1 -0
- package/dist/templateRefs.d.ts +69 -0
- package/dist/templateRefs.d.ts.map +1 -0
- package/dist/templateRefs.js +238 -0
- package/dist/templateRefs.js.map +1 -0
- package/dist/theme.d.ts +15 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +81 -0
- package/dist/theme.js.map +1 -0
- package/dist/ui-helpers.d.ts +4 -0
- package/dist/ui-helpers.d.ts.map +1 -0
- package/dist/ui-helpers.js +168 -0
- package/dist/ui-helpers.js.map +1 -0
- package/dist/usage.d.ts +43 -0
- package/dist/usage.d.ts.map +1 -0
- package/dist/usage.js +114 -0
- package/dist/usage.js.map +1 -0
- package/package.json +50 -0
package/dist/theme.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
const LS = 'prompd.web.theme';
|
|
2
|
+
export function getTheme() {
|
|
3
|
+
try {
|
|
4
|
+
return localStorage.getItem(LS) === 'light' ? 'light' : 'dark';
|
|
5
|
+
}
|
|
6
|
+
catch {
|
|
7
|
+
return 'dark';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export function applyTheme(t) {
|
|
11
|
+
document.documentElement.dataset.theme = t;
|
|
12
|
+
}
|
|
13
|
+
export function setTheme(t) {
|
|
14
|
+
try {
|
|
15
|
+
localStorage.setItem(LS, t);
|
|
16
|
+
}
|
|
17
|
+
catch { /* ignore */ }
|
|
18
|
+
applyTheme(t);
|
|
19
|
+
// Let theme-sensitive UI (e.g. the file-tree's light/dark icon variants) react.
|
|
20
|
+
try {
|
|
21
|
+
window.dispatchEvent(new Event('prompd:theme-changed'));
|
|
22
|
+
}
|
|
23
|
+
catch { /* SSR/no-window */ }
|
|
24
|
+
}
|
|
25
|
+
export function initTheme() {
|
|
26
|
+
applyTheme(getTheme());
|
|
27
|
+
applyEditorControls(getEditorControls());
|
|
28
|
+
}
|
|
29
|
+
const LS_EC = 'prompd.web.editorControls';
|
|
30
|
+
export function getEditorControls() {
|
|
31
|
+
try {
|
|
32
|
+
const v = localStorage.getItem(LS_EC);
|
|
33
|
+
return v === 'labels' || v === 'icons' ? v : 'auto';
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return 'auto';
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export function applyEditorControls(v) {
|
|
40
|
+
document.documentElement.dataset.editorControls = v;
|
|
41
|
+
}
|
|
42
|
+
export function setEditorControls(v) {
|
|
43
|
+
try {
|
|
44
|
+
localStorage.setItem(LS_EC, v);
|
|
45
|
+
}
|
|
46
|
+
catch { /* ignore */ }
|
|
47
|
+
applyEditorControls(v);
|
|
48
|
+
}
|
|
49
|
+
const LS_COMP = 'prompd.web.compression';
|
|
50
|
+
export function getCompression() {
|
|
51
|
+
try {
|
|
52
|
+
const v = localStorage.getItem(LS_COMP);
|
|
53
|
+
return v === 'off' || v === 'conservative' || v === 'aggressive' ? v : 'balanced';
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return 'balanced';
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export function setCompression(v) {
|
|
60
|
+
try {
|
|
61
|
+
localStorage.setItem(LS_COMP, v);
|
|
62
|
+
}
|
|
63
|
+
catch { /* ignore */ }
|
|
64
|
+
}
|
|
65
|
+
/* Show/hide the in-app help chat (? button by Settings). */
|
|
66
|
+
const LS_HELP = 'prompd.web.showHelp';
|
|
67
|
+
export function getShowHelp() {
|
|
68
|
+
try {
|
|
69
|
+
return localStorage.getItem(LS_HELP) !== '0';
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export function setShowHelp(v) {
|
|
76
|
+
try {
|
|
77
|
+
localStorage.setItem(LS_HELP, v ? '1' : '0');
|
|
78
|
+
}
|
|
79
|
+
catch { /* ignore */ }
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=theme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.js","sourceRoot":"","sources":["../theme.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-helpers.d.ts","sourceRoot":"","sources":["../ui-helpers.ts"],"names":[],"mappings":"AAwCA,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAwC3C;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEhD;AAwBD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CA6BpD"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/* Prompd editor UI helpers (presentation only).
|
|
2
|
+
* - mdToHtml: small markdown -> HTML renderer for the preview/output panes
|
|
3
|
+
* - estimateTokens: rough token count for the cost/usage display
|
|
4
|
+
* - highlightPrmd: syntax highlighter for the source editor (YAML + markdown + jinja)
|
|
5
|
+
*
|
|
6
|
+
* NOTE: parsing (.prmd/.md frontmatter + params) and compilation (Nunjucks) live
|
|
7
|
+
* in @prompd/core — the real engine, shared with the CLI and backend.
|
|
8
|
+
* This module is purely the editor's rendering/highlighting layer.
|
|
9
|
+
*/
|
|
10
|
+
/* ============================================================ MARKDOWN */
|
|
11
|
+
/** Sanitize a markdown link target. Returns a safe href, or null to drop the link
|
|
12
|
+
* to plain text. Only http(s)/mailto/tel and relative URLs are allowed; scripting
|
|
13
|
+
* schemes (javascript:, data:, vbscript:) are refused. Control chars/whitespace are
|
|
14
|
+
* stripped first so a smuggled scheme ("java\tscript:") can't slip past the check —
|
|
15
|
+
* browsers ignore those characters when resolving the URL. */
|
|
16
|
+
function safeHref(raw) {
|
|
17
|
+
const u = raw.replace(/[\u0000-\u0020\u007F]+/g, '');
|
|
18
|
+
const scheme = /^([a-z][a-z0-9+.-]*):/i.exec(u);
|
|
19
|
+
if (scheme)
|
|
20
|
+
return /^(https?|mailto|tel)$/i.test(scheme[1]) ? u : null;
|
|
21
|
+
return u; // no scheme -> relative path/anchor/query, safe
|
|
22
|
+
}
|
|
23
|
+
function inlineMd(s) {
|
|
24
|
+
return s
|
|
25
|
+
.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')
|
|
26
|
+
.replace(/`([^`]+)`/g, '<code>$1</code>')
|
|
27
|
+
.replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>')
|
|
28
|
+
.replace(/(^|[^*])\*([^*]+)\*/g, '$1<em>$2</em>')
|
|
29
|
+
// The label is already &<>-escaped above; the href is scheme-checked and its
|
|
30
|
+
// quotes escaped so a crafted URL can't break out of the attribute (XSS).
|
|
31
|
+
.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_m, text, url) => {
|
|
32
|
+
const href = safeHref(url);
|
|
33
|
+
return href
|
|
34
|
+
? `<a href="${href.replace(/"/g, '"')}" rel="noopener noreferrer">${text}</a>`
|
|
35
|
+
: text;
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
export function mdToHtml(md) {
|
|
39
|
+
const lines = md.split('\n');
|
|
40
|
+
let html = '';
|
|
41
|
+
let i = 0;
|
|
42
|
+
while (i < lines.length) {
|
|
43
|
+
const line = lines[i];
|
|
44
|
+
if (/^```/.test(line)) {
|
|
45
|
+
const buf = [];
|
|
46
|
+
i++;
|
|
47
|
+
while (i < lines.length && !/^```/.test(lines[i])) {
|
|
48
|
+
buf.push(lines[i]);
|
|
49
|
+
i++;
|
|
50
|
+
}
|
|
51
|
+
i++;
|
|
52
|
+
html += `<pre class="md-pre"><code>${buf.join('\n').replace(/&/g, '&').replace(/</g, '<')}</code></pre>`;
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (/^#{1,6}\s/.test(line)) {
|
|
56
|
+
const lvl = line.match(/^#+/)[0].length;
|
|
57
|
+
html += `<h${lvl} class="md-h md-h${lvl}">${inlineMd(line.replace(/^#+\s/, ''))}</h${lvl}>`;
|
|
58
|
+
i++;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (/^\s*([-*])\s+/.test(line)) {
|
|
62
|
+
const items = [];
|
|
63
|
+
while (i < lines.length && /^\s*([-*])\s+/.test(lines[i])) {
|
|
64
|
+
items.push(inlineMd(lines[i].replace(/^\s*[-*]\s+/, '')));
|
|
65
|
+
i++;
|
|
66
|
+
}
|
|
67
|
+
html += '<ul class="md-ul">' + items.map((t) => `<li>${t}</li>`).join('') + '</ul>';
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (/^\s*\d+\.\s+/.test(line)) {
|
|
71
|
+
const items = [];
|
|
72
|
+
while (i < lines.length && /^\s*\d+\.\s+/.test(lines[i])) {
|
|
73
|
+
items.push(inlineMd(lines[i].replace(/^\s*\d+\.\s+/, '')));
|
|
74
|
+
i++;
|
|
75
|
+
}
|
|
76
|
+
html += '<ol class="md-ol">' + items.map((t) => `<li>${t}</li>`).join('') + '</ol>';
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (/^\s*>\s?/.test(line)) {
|
|
80
|
+
html += `<blockquote class="md-bq">${inlineMd(line.replace(/^\s*>\s?/, ''))}</blockquote>`;
|
|
81
|
+
i++;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (/^\s*(---|\*\*\*)\s*$/.test(line)) {
|
|
85
|
+
html += '<hr class="md-hr">';
|
|
86
|
+
i++;
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (line.trim() === '') {
|
|
90
|
+
i++;
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
const buf = [line];
|
|
94
|
+
i++;
|
|
95
|
+
while (i < lines.length && lines[i].trim() !== '' && !/^(#{1,6}\s|\s*([-*])\s|\s*\d+\.\s|\s*>|```)/.test(lines[i])) {
|
|
96
|
+
buf.push(lines[i]);
|
|
97
|
+
i++;
|
|
98
|
+
}
|
|
99
|
+
html += `<p class="md-p">${inlineMd(buf.join(' '))}</p>`;
|
|
100
|
+
}
|
|
101
|
+
return html;
|
|
102
|
+
}
|
|
103
|
+
export function estimateTokens(s) {
|
|
104
|
+
return Math.max(1, Math.round((s || '').length / 4));
|
|
105
|
+
}
|
|
106
|
+
/* ============================================================ HIGHLIGHT */
|
|
107
|
+
function esc(s) {
|
|
108
|
+
return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
109
|
+
}
|
|
110
|
+
function hlYaml(text) {
|
|
111
|
+
let s = esc(text);
|
|
112
|
+
s = s.replace(/^(\s*(?:-\s*)?)([A-Za-z_][\w-]*)(:)/, (_m, pre, key, c) => `${pre}<span class=k>${key}</span><span class=p>${c}</span>`);
|
|
113
|
+
s = s.replace(/("[^"]*"|'[^']*')/g, '<span class=s>$1</span>');
|
|
114
|
+
s = s.replace(/(\[|\])/g, '<span class=b>$1</span>');
|
|
115
|
+
return s;
|
|
116
|
+
}
|
|
117
|
+
function hlMd(text) {
|
|
118
|
+
let s = esc(text);
|
|
119
|
+
if (/^\s*#{1,6}\s/.test(text))
|
|
120
|
+
return `<span class=h>${s}</span>`;
|
|
121
|
+
s = s.replace(/(\*\*[^*]+\*\*)/g, '<span class=bo>$1</span>');
|
|
122
|
+
s = s.replace(/(`[^`]+`)/g, '<span class=c>$1</span>');
|
|
123
|
+
s = s.replace(/^(\s*(?:[-*]|\d+\.)\s)/, '<span class=li>$1</span>');
|
|
124
|
+
return s;
|
|
125
|
+
}
|
|
126
|
+
export function highlightPrmd(source) {
|
|
127
|
+
const lines = source.split('\n');
|
|
128
|
+
let s1 = -1;
|
|
129
|
+
let s2 = -1;
|
|
130
|
+
for (let i = 0; i < lines.length; i++) {
|
|
131
|
+
if (lines[i].trim() === '---') {
|
|
132
|
+
if (s1 === -1)
|
|
133
|
+
s1 = i;
|
|
134
|
+
else {
|
|
135
|
+
s2 = i;
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
else if (s1 === -1 && lines[i].trim() !== '')
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
const jinjaRe = /(\{\{.*?\}\}|\{%.*?%\}|\{#.*?#\})/g;
|
|
143
|
+
const out = lines.map((line, idx) => {
|
|
144
|
+
const inFm = s1 !== -1 && idx > s1 && (s2 === -1 || idx < s2);
|
|
145
|
+
const isFence = (idx === s1 || idx === s2) && line.trim() === '---';
|
|
146
|
+
if (isFence)
|
|
147
|
+
return `<span class=fence>${esc(line)}</span>`;
|
|
148
|
+
let res = '';
|
|
149
|
+
let last = 0;
|
|
150
|
+
let m;
|
|
151
|
+
jinjaRe.lastIndex = 0;
|
|
152
|
+
while ((m = jinjaRe.exec(line))) {
|
|
153
|
+
if (m.index > last)
|
|
154
|
+
res += inFm ? hlYaml(line.slice(last, m.index)) : hlMd(line.slice(last, m.index));
|
|
155
|
+
const raw = m[0];
|
|
156
|
+
const cls = raw.startsWith('{{') ? 'jv' : raw.startsWith('{#') ? 'jc' : 'jt';
|
|
157
|
+
res += `<span class=${cls}>${esc(raw)}</span>`;
|
|
158
|
+
last = jinjaRe.lastIndex;
|
|
159
|
+
}
|
|
160
|
+
if (last < line.length)
|
|
161
|
+
res += inFm ? hlYaml(line.slice(last)) : hlMd(line.slice(last));
|
|
162
|
+
if (res === '')
|
|
163
|
+
res = '';
|
|
164
|
+
return res;
|
|
165
|
+
});
|
|
166
|
+
return out.join('\n');
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=ui-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-helpers.js","sourceRoot":"","sources":["../ui-helpers.ts"],"names":[],"mappings":"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"}
|
package/dist/usage.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export interface UsageRecord {
|
|
2
|
+
id: string;
|
|
3
|
+
ts: number;
|
|
4
|
+
surface: 'editor' | 'agent' | 'inline' | 'workflow';
|
|
5
|
+
provider: string;
|
|
6
|
+
model: string;
|
|
7
|
+
modelLabel: string;
|
|
8
|
+
/** Our pre-run token estimate for the prompt (null when not applicable). */
|
|
9
|
+
inEst: number | null;
|
|
10
|
+
/** Provider-reported tokens. */
|
|
11
|
+
inTok: number;
|
|
12
|
+
outTok: number;
|
|
13
|
+
/** USD cost for the run. */
|
|
14
|
+
cost: number;
|
|
15
|
+
}
|
|
16
|
+
export interface UsageTotals {
|
|
17
|
+
runs: number;
|
|
18
|
+
inTok: number;
|
|
19
|
+
outTok: number;
|
|
20
|
+
cost: number;
|
|
21
|
+
}
|
|
22
|
+
/** Wire the "currently anonymous?" signal (App boot). */
|
|
23
|
+
export declare function setAnonResolver(fn: () => boolean): void;
|
|
24
|
+
/** Free anon actions consumed so far (read by the free-quota guards). */
|
|
25
|
+
export declare function anonRunCount(): number;
|
|
26
|
+
/** Reset the anon trial (e.g. after sign-in, if a host wants to). */
|
|
27
|
+
export declare function resetAnonRuns(): void;
|
|
28
|
+
/** Count an anon action that doesn't go through recordUsage (e.g. a workflow run). */
|
|
29
|
+
export declare function bumpAnonRun(): void;
|
|
30
|
+
export declare function recordUsage(rec: Omit<UsageRecord, 'id' | 'ts'>): void;
|
|
31
|
+
export declare function getUsage(): UsageRecord[];
|
|
32
|
+
export declare function clearUsage(): void;
|
|
33
|
+
export declare function totals(since?: number): UsageTotals;
|
|
34
|
+
/** Reactive view: all records + session (since page load) and lifetime totals. */
|
|
35
|
+
export declare function useUsage(): {
|
|
36
|
+
records: UsageRecord[];
|
|
37
|
+
session: UsageTotals;
|
|
38
|
+
lifetime: UsageTotals;
|
|
39
|
+
};
|
|
40
|
+
/** USD formatter — sub-cent precision so cheap runs are still legible. */
|
|
41
|
+
export declare function fmtCost(usd: number): string;
|
|
42
|
+
export declare function fmtTok(n: number): string;
|
|
43
|
+
//# sourceMappingURL=usage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../usage.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;CAAE;AAkC3F,yDAAyD;AACzD,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,OAAO,GAAG,IAAI,CAAuB;AAC/E,yEAAyE;AACzE,wBAAgB,YAAY,IAAI,MAAM,CAAqB;AAC3D,qEAAqE;AACrE,wBAAgB,aAAa,IAAI,IAAI,CAA+F;AAMpI,sFAAsF;AACtF,wBAAgB,WAAW,IAAI,IAAI,CAA+B;AAElE,wBAAgB,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC,GAAG,IAAI,CAMrE;AAED,wBAAgB,QAAQ,IAAI,WAAW,EAAE,CAAoB;AAE7D,wBAAgB,UAAU,IAAI,IAAI,CAIjC;AAED,wBAAgB,MAAM,CAAC,KAAK,SAAI,GAAG,WAAW,CAO7C;AAED,kFAAkF;AAClF,wBAAgB,QAAQ,IAAI;IAAE,OAAO,EAAE,WAAW,EAAE,CAAC;IAAC,OAAO,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,WAAW,CAAA;CAAE,CAIlG;AAED,0EAA0E;AAC1E,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAK3C;AAED,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAIxC"}
|
package/dist/usage.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/* Usage ledger — records real token usage + cost per run so you can verify the
|
|
2
|
+
* estimate against what the provider actually billed.
|
|
3
|
+
*
|
|
4
|
+
* Each run stores our pre-flight estimate (inEst) next to the provider's reported
|
|
5
|
+
* prompt/completion tokens (inTok/outTok) and the computed cost. Persisted to
|
|
6
|
+
* localStorage; a small reactive store drives the topbar meter. */
|
|
7
|
+
import { useEffect, useReducer } from 'react';
|
|
8
|
+
const LS = 'prompd.web.usage.v1';
|
|
9
|
+
const CAP = 300;
|
|
10
|
+
const sessionStart = Date.now();
|
|
11
|
+
function load() {
|
|
12
|
+
try {
|
|
13
|
+
const raw = localStorage.getItem(LS);
|
|
14
|
+
if (!raw)
|
|
15
|
+
return [];
|
|
16
|
+
const parsed = JSON.parse(raw);
|
|
17
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
let records = load();
|
|
24
|
+
const listeners = new Set();
|
|
25
|
+
function notify() { listeners.forEach((fn) => fn()); }
|
|
26
|
+
function persist() {
|
|
27
|
+
try {
|
|
28
|
+
localStorage.setItem(LS, JSON.stringify(records));
|
|
29
|
+
}
|
|
30
|
+
catch { /* ignore quota */ }
|
|
31
|
+
}
|
|
32
|
+
/* ---- anonymous run counter ----
|
|
33
|
+
* A single device-local count of LLM actions taken while signed OUT, the source
|
|
34
|
+
* the free-quota guards read (the API guard is authoritative; this is the UX
|
|
35
|
+
* hint). Kept in its OWN key so clearing usage history doesn't reset the trial.
|
|
36
|
+
* The host injects an "am I anonymous" resolver at boot; recordUsage (and the
|
|
37
|
+
* manual bumpAnonRun, for paths that don't record usage) increments it when anon. */
|
|
38
|
+
const ANON_LS = 'prompd.web.anonRuns.v1';
|
|
39
|
+
let anonRuns = (() => { try {
|
|
40
|
+
return Number(localStorage.getItem(ANON_LS)) || 0;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return 0;
|
|
44
|
+
} })();
|
|
45
|
+
let anonResolver = null;
|
|
46
|
+
/** Wire the "currently anonymous?" signal (App boot). */
|
|
47
|
+
export function setAnonResolver(fn) { anonResolver = fn; }
|
|
48
|
+
/** Free anon actions consumed so far (read by the free-quota guards). */
|
|
49
|
+
export function anonRunCount() { return anonRuns; }
|
|
50
|
+
/** Reset the anon trial (e.g. after sign-in, if a host wants to). */
|
|
51
|
+
export function resetAnonRuns() { anonRuns = 0; try {
|
|
52
|
+
localStorage.setItem(ANON_LS, '0');
|
|
53
|
+
}
|
|
54
|
+
catch { /* ignore */ } notify(); }
|
|
55
|
+
function maybeBumpAnon() {
|
|
56
|
+
if (!anonResolver || !anonResolver())
|
|
57
|
+
return;
|
|
58
|
+
anonRuns += 1;
|
|
59
|
+
try {
|
|
60
|
+
localStorage.setItem(ANON_LS, String(anonRuns));
|
|
61
|
+
}
|
|
62
|
+
catch { /* ignore */ }
|
|
63
|
+
}
|
|
64
|
+
/** Count an anon action that doesn't go through recordUsage (e.g. a workflow run). */
|
|
65
|
+
export function bumpAnonRun() { maybeBumpAnon(); notify(); }
|
|
66
|
+
export function recordUsage(rec) {
|
|
67
|
+
const full = { ...rec, id: `u${Date.now().toString(36)}${Math.floor(Math.random() * 1e4).toString(36)}`, ts: Date.now() };
|
|
68
|
+
records = [full, ...records].slice(0, CAP);
|
|
69
|
+
maybeBumpAnon();
|
|
70
|
+
persist();
|
|
71
|
+
notify();
|
|
72
|
+
}
|
|
73
|
+
export function getUsage() { return records; }
|
|
74
|
+
export function clearUsage() {
|
|
75
|
+
records = [];
|
|
76
|
+
persist();
|
|
77
|
+
notify();
|
|
78
|
+
}
|
|
79
|
+
export function totals(since = 0) {
|
|
80
|
+
let runs = 0, inTok = 0, outTok = 0, cost = 0;
|
|
81
|
+
for (const r of records) {
|
|
82
|
+
if (r.ts < since)
|
|
83
|
+
continue;
|
|
84
|
+
runs += 1;
|
|
85
|
+
inTok += r.inTok;
|
|
86
|
+
outTok += r.outTok;
|
|
87
|
+
cost += r.cost;
|
|
88
|
+
}
|
|
89
|
+
return { runs, inTok, outTok, cost };
|
|
90
|
+
}
|
|
91
|
+
/** Reactive view: all records + session (since page load) and lifetime totals. */
|
|
92
|
+
export function useUsage() {
|
|
93
|
+
const [, force] = useReducer((x) => x + 1, 0);
|
|
94
|
+
useEffect(() => { listeners.add(force); return () => { listeners.delete(force); }; }, []);
|
|
95
|
+
return { records, session: totals(sessionStart), lifetime: totals() };
|
|
96
|
+
}
|
|
97
|
+
/** USD formatter — sub-cent precision so cheap runs are still legible. */
|
|
98
|
+
export function fmtCost(usd) {
|
|
99
|
+
if (!usd)
|
|
100
|
+
return '$0';
|
|
101
|
+
if (usd < 0.01)
|
|
102
|
+
return `$${usd.toFixed(4)}`;
|
|
103
|
+
if (usd < 1)
|
|
104
|
+
return `$${usd.toFixed(3)}`;
|
|
105
|
+
return `$${usd.toFixed(2)}`;
|
|
106
|
+
}
|
|
107
|
+
export function fmtTok(n) {
|
|
108
|
+
if (n >= 1000000)
|
|
109
|
+
return `${(n / 1000000).toFixed(2)}M`;
|
|
110
|
+
if (n >= 1000)
|
|
111
|
+
return `${(n / 1000).toFixed(1)}K`;
|
|
112
|
+
return String(n);
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=usage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../usage.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@corenel/ui-kit",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Corenel shared UI primitives — icons, theme, token-usage helpers, small UI helpers, monaco colorizer. Consumed by @corenel/web-ui and the prompd app alike.",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": "./index.ts",
|
|
8
|
+
"./*": "./*.ts",
|
|
9
|
+
"./icons": "./icons.tsx",
|
|
10
|
+
"./host": "./host.tsx"
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc -p tsconfig.build.json",
|
|
14
|
+
"prepublishOnly": "tsc -p tsconfig.build.json"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@corenel/protocol": "workspace:*"
|
|
18
|
+
},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"monaco-editor": "*",
|
|
21
|
+
"react": "^18.3.1"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"typescript": "^5.9.3"
|
|
25
|
+
},
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"default": "./dist/index.js"
|
|
32
|
+
},
|
|
33
|
+
"./*": {
|
|
34
|
+
"types": "./dist/*.d.ts",
|
|
35
|
+
"default": "./dist/*.js"
|
|
36
|
+
},
|
|
37
|
+
"./icons": {
|
|
38
|
+
"types": "./dist/icons.d.ts",
|
|
39
|
+
"default": "./dist/icons.js"
|
|
40
|
+
},
|
|
41
|
+
"./host": {
|
|
42
|
+
"types": "./dist/host.d.ts",
|
|
43
|
+
"default": "./dist/host.js"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"files": [
|
|
48
|
+
"dist"
|
|
49
|
+
]
|
|
50
|
+
}
|