@cascivo/ai 1.0.0 → 1.2.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/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  <!-- generated by scripts/readme/generate.ts — edit readme.body.md, not this file -->
2
2
 
3
3
  <div align="center">
4
- <a href="https://cascivo.com"><img src="https://cascivo.com/favicon.svg" width="72" height="72" alt="cascivo logo"></a>
4
+ <a href="https://cascivo.com"><img src="https://cascivo.com/logo-mark-img-accent.svg" width="72" height="72" alt="cascivo logo"></a>
5
5
  <h1>@cascivo/ai</h1>
6
6
  <p><strong>AI-native components for cascivo — StreamingText, AiLabel, Terminal, AiChat</strong></p>
7
7
 
@@ -105,4 +105,4 @@ pnpm add @cascivo/ai
105
105
 
106
106
  [cascivo.com](https://cascivo.com) · [Docs](https://cascivo.com/docs) · [Storybook](https://storybook.cascivo.com) · [GitHub](https://github.com/cascivo/cascivo) · AI agents: read [`llms.txt`](https://cascivo.com/llms.txt) (install steps + component index, plain text) or use [`@cascivo/mcp`](https://github.com/cascivo/cascivo/tree/main/packages/mcp) and [`registry.json`](https://github.com/cascivo/cascivo/blob/main/registry.json) · MIT
107
107
 
108
- <div align="center"><a href="https://cascivo.com"><img src="https://cascivo.com/favicon.svg" width="28" height="28" alt="cascivo"></a></div>
108
+ <div align="center"><a href="https://cascivo.com"><img src="https://cascivo.com/logo-mark-img.svg" width="28" height="28" alt="cascivo"></a></div>
package/dist/ai.css CHANGED
@@ -1,2 +1,2 @@
1
- @layer cascivo.component{._root_1vw7g_2{display:inline}._cursor_1vw7g_5{vertical-align:text-bottom;background:currentColor;width:2px;height:1em;margin-inline-start:1px;animation:1s step-end infinite _cascade-cursor-blink_1vw7g_1;display:inline-block}._root_5tg3n_2{align-items:center;gap:var(--cascivo-space-1);padding:var(--cascivo-space-1) var(--cascivo-space-2);border-radius:var(--cascivo-radius-indicator);font-size:var(--cascivo-font-size-xs);font-weight:500;line-height:1;display:inline-flex}._root_5tg3n_2[data-variant=generating]{background:var(--cascivo-color-surface-2);color:var(--cascivo-color-foreground-muted)}._root_5tg3n_2[data-variant=generating]:before{content:"";border-radius:var(--cascivo-radius-full);background:currentColor;block-size:.375rem;inline-size:.375rem;animation:1.5s ease-in-out infinite _cascade-ai-pulse_5tg3n_1}._root_5tg3n_2[data-variant=done]{background:var(--cascivo-color-success-subtle);color:var(--cascivo-color-success-foreground)}._root_5tg3n_2[data-variant=error]{background:var(--cascivo-color-destructive-subtle);color:var(--cascivo-color-destructive-foreground)}._root_1s9z8_2{color:oklch(90% .02 145);font-family:ui-monospace,Cascadia Code,Source Code Pro,monospace;font-size:var(--cascivo-font-size-sm,.875rem);padding:var(--cascivo-space-4);border-radius:var(--cascivo-radius-surface);background:oklch(12% .01 250);line-height:1.6;overflow-x:auto}._line_1s9z8_12{gap:var(--cascivo-space-2);display:flex}._prefix_1s9z8_16{color:oklch(70% .15 145);-webkit-user-select:none;user-select:none}._text_1s9z8_20{flex:1}._cursor_1s9z8_23{background:oklch(90% .02 145);width:8px;height:1em;animation:1s step-end infinite _cascade-cursor-blink_1s9z8_1;display:inline-block}._line_1s9z8_12[data-type=command] ._text_1s9z8_20{color:oklch(90% .1 250)}._line_1s9z8_12[data-type=error] ._text_1s9z8_20{color:oklch(75% .15 22)}._line_1s9z8_12[data-type=comment] ._text_1s9z8_20{color:oklch(60% .02 145)}._root_ilql2_2{background:var(--cascivo-color-background);border:1px solid var(--cascivo-border-default);border-radius:var(--cascivo-radius-surface);flex-direction:column;height:100%;min-height:400px;display:flex;overflow:hidden}._messages_ilql2_12{padding:var(--cascivo-space-4);gap:var(--cascivo-space-3);flex-direction:column;flex:1;display:flex;overflow-y:auto}._message_ilql2_12{gap:var(--cascivo-space-1);flex-direction:column;max-width:80%;display:flex}._message_ilql2_12[data-role=user]{align-self:flex-end;align-items:flex-end}._message_ilql2_12[data-role=assistant]{align-self:flex-start}._roleLabel_ilql2_33{font-size:var(--cascivo-font-size-xs,.75rem);color:var(--cascivo-color-foreground-muted);font-weight:500}._content_ilql2_38{padding:var(--cascivo-space-2) var(--cascivo-space-3);border-radius:var(--cascivo-radius-control);background:var(--cascivo-color-surface);line-height:1.5}._message_ilql2_12[data-role=user] ._content_ilql2_38{background:var(--cascivo-color-accent);color:var(--cascivo-color-accent-foreground)}._inputArea_ilql2_48{gap:var(--cascivo-space-2);padding:var(--cascivo-space-3);border-block-start:1px solid var(--cascivo-border-subtle);background:var(--cascivo-color-surface);display:flex}._textarea_ilql2_55{resize:none;border:1px solid var(--cascivo-border-default);border-radius:var(--cascivo-radius-control);padding:var(--cascivo-space-2) var(--cascivo-space-3);font:inherit;background:var(--cascivo-color-background);color:var(--cascivo-color-foreground);flex:1}._sendButton_ilql2_65{padding:var(--cascivo-space-2) var(--cascivo-space-4);background:var(--cascivo-color-accent);color:var(--cascivo-color-accent-foreground);border-radius:var(--cascivo-radius-control);font:inherit;cursor:pointer;border:none;font-weight:500}._sendButton_ilql2_65:disabled{opacity:.5;cursor:not-allowed}}@keyframes _cascade-cursor-blink_1vw7g_1{0%,to{opacity:1}50%{opacity:0}}@keyframes _cascade-ai-pulse_5tg3n_1{0%,to{opacity:1}50%{opacity:.6}}@keyframes _cascade-cursor-blink_1s9z8_1{0%,to{opacity:1}50%{opacity:0}}
1
+ @layer cascivo.component{._root_ajc1u_2{display:inline}._cursor_ajc1u_5{vertical-align:text-bottom;background:currentColor;width:2px;height:1em;margin-inline-start:1px;display:inline-block}@media (prefers-reduced-motion:no-preference){._cursor_ajc1u_5{animation:cascivo-blink var(--cascivo-duration-loop-fast) step-end infinite}}._root_tiibp_2{align-items:center;gap:var(--cascivo-space-1);padding:var(--cascivo-space-1) var(--cascivo-space-2);border-radius:var(--cascivo-radius-indicator);font-size:var(--cascivo-font-size-xs);font-weight:500;line-height:1;display:inline-flex}._root_tiibp_2[data-variant=generating]{background:var(--cascivo-color-surface-2);color:var(--cascivo-color-foreground-muted)}._root_tiibp_2[data-variant=generating]:before{content:"";border-radius:var(--cascivo-radius-full);background:currentColor;block-size:.375rem;inline-size:.375rem}@media (prefers-reduced-motion:no-preference){._root_tiibp_2[data-variant=generating]:before{animation:cascivo-pulse var(--cascivo-duration-loop) var(--cascivo-ease-in-out) infinite}}._root_tiibp_2[data-variant=done]{background:var(--cascivo-color-success-subtle);color:var(--cascivo-color-success-foreground)}._root_tiibp_2[data-variant=error]{background:var(--cascivo-color-destructive-subtle);color:var(--cascivo-color-destructive-foreground)}._root_131e4_2{color:oklch(90% .02 145);font-family:ui-monospace,Cascadia Code,Source Code Pro,monospace;font-size:var(--cascivo-font-size-sm,.875rem);padding:var(--cascivo-space-4);border-radius:var(--cascivo-radius-surface);background:oklch(12% .01 250);line-height:1.6;overflow-x:auto}._line_131e4_12{gap:var(--cascivo-space-2);display:flex}._prefix_131e4_16{color:oklch(70% .15 145);-webkit-user-select:none;user-select:none}._text_131e4_20{flex:1}._cursor_131e4_23{background:oklch(90% .02 145);width:8px;height:1em;display:inline-block}@media (prefers-reduced-motion:no-preference){._cursor_131e4_23{animation:cascivo-blink var(--cascivo-duration-loop-fast) step-end infinite}}._line_131e4_12[data-type=command] ._text_131e4_20{color:oklch(90% .1 250)}._line_131e4_12[data-type=error] ._text_131e4_20{color:oklch(75% .15 22)}._line_131e4_12[data-type=comment] ._text_131e4_20{color:oklch(60% .02 145)}._root_ilql2_2{background:var(--cascivo-color-background);border:1px solid var(--cascivo-border-default);border-radius:var(--cascivo-radius-surface);flex-direction:column;height:100%;min-height:400px;display:flex;overflow:hidden}._messages_ilql2_12{padding:var(--cascivo-space-4);gap:var(--cascivo-space-3);flex-direction:column;flex:1;display:flex;overflow-y:auto}._message_ilql2_12{gap:var(--cascivo-space-1);flex-direction:column;max-width:80%;display:flex}._message_ilql2_12[data-role=user]{align-self:flex-end;align-items:flex-end}._message_ilql2_12[data-role=assistant]{align-self:flex-start}._roleLabel_ilql2_33{font-size:var(--cascivo-font-size-xs,.75rem);color:var(--cascivo-color-foreground-muted);font-weight:500}._content_ilql2_38{padding:var(--cascivo-space-2) var(--cascivo-space-3);border-radius:var(--cascivo-radius-control);background:var(--cascivo-color-surface);line-height:1.5}._message_ilql2_12[data-role=user] ._content_ilql2_38{background:var(--cascivo-color-accent);color:var(--cascivo-color-accent-foreground)}._inputArea_ilql2_48{gap:var(--cascivo-space-2);padding:var(--cascivo-space-3);border-block-start:1px solid var(--cascivo-border-subtle);background:var(--cascivo-color-surface);display:flex}._textarea_ilql2_55{resize:none;border:1px solid var(--cascivo-border-default);border-radius:var(--cascivo-radius-control);padding:var(--cascivo-space-2) var(--cascivo-space-3);font:inherit;background:var(--cascivo-color-background);color:var(--cascivo-color-foreground);flex:1}._sendButton_ilql2_65{padding:var(--cascivo-space-2) var(--cascivo-space-4);background:var(--cascivo-color-accent);color:var(--cascivo-color-accent-foreground);border-radius:var(--cascivo-radius-control);font:inherit;cursor:pointer;border:none;font-weight:500}._sendButton_ilql2_65:disabled{opacity:.5;cursor:not-allowed}}
2
2
  /*$vite$:1*/
package/dist/index.js CHANGED
@@ -1,188 +1,3 @@
1
1
  "use client";
2
2
  import './ai.css';
3
- import { useRef as e } from "react";
4
- import { useSignal as t, useSignalEffect as n, useSignals as r } from "@cascivo/core";
5
- import { jsx as i, jsxs as a } from "react/jsx-runtime";
6
- import { builtin as o, t as s } from "@cascivo/i18n";
7
- var c = {
8
- root: "_root_1vw7g_2",
9
- cursor: "_cursor_1vw7g_5",
10
- "cascade-cursor-blink": "_cascade-cursor-blink_1vw7g_1"
11
- };
12
- //#endregion
13
- //#region src/streaming-text.tsx
14
- function l({ text: o, speed: s = 2, onComplete: l, className: u }) {
15
- r();
16
- let d = t(""), f = e(l);
17
- return f.current = l, d.value = d.value.length > o.length ? "" : d.value, n(() => {
18
- let e = o;
19
- if (d.value === e) {
20
- f.current?.();
21
- return;
22
- }
23
- let t;
24
- function n() {
25
- let r = d.value;
26
- if (r.length >= e.length) {
27
- f.current?.();
28
- return;
29
- }
30
- d.value = e.slice(0, r.length + s), t = requestAnimationFrame(n);
31
- }
32
- return t = requestAnimationFrame(n), () => cancelAnimationFrame(t);
33
- }), /* @__PURE__ */ a("span", {
34
- className: [c.root, u].filter(Boolean).join(" "),
35
- children: [d.value, d.value !== o && /* @__PURE__ */ i("span", {
36
- className: c.cursor,
37
- "aria-hidden": "true"
38
- })]
39
- });
40
- }
41
- var u = {
42
- root: "_root_5tg3n_2",
43
- "cascade-ai-pulse": "_cascade-ai-pulse_5tg3n_1"
44
- };
45
- //#endregion
46
- //#region src/ai-label.tsx
47
- function d({ variant: e = "generating", className: t, ...n }) {
48
- r();
49
- let a = s(e === "generating" ? o.ai.generating : e === "done" ? o.ai.done : o.ai.error);
50
- return /* @__PURE__ */ i("span", {
51
- role: "status",
52
- "aria-label": a,
53
- "data-variant": e,
54
- className: [u.root, t].filter(Boolean).join(" "),
55
- ...n,
56
- children: a
57
- });
58
- }
59
- var f = {
60
- root: "_root_1s9z8_2",
61
- line: "_line_1s9z8_12",
62
- prefix: "_prefix_1s9z8_16",
63
- text: "_text_1s9z8_20",
64
- cursor: "_cursor_1s9z8_23",
65
- "cascade-cursor-blink": "_cascade-cursor-blink_1s9z8_1"
66
- };
67
- //#endregion
68
- //#region src/terminal.tsx
69
- function p({ lines: o, speed: s = 3, loop: c = !1, onComplete: l, className: u }) {
70
- r();
71
- let d = t(0), p = t(0), m = e(l);
72
- m.current = l, n(() => {
73
- if (o.length === 0) return;
74
- let e;
75
- function t() {
76
- let n = d.value, r = p.value;
77
- if (n >= o.length) {
78
- m.current?.(), c && (d.value = 0, p.value = 0);
79
- return;
80
- }
81
- r < o[n].text.length ? p.value = r + s : (d.value = n + 1, p.value = 0), e = requestAnimationFrame(t);
82
- }
83
- return e = requestAnimationFrame(t), () => cancelAnimationFrame(e);
84
- });
85
- let h = o.slice(0, d.value + 1).map((e, t) => {
86
- let n = t === d.value, r = n ? e.text.slice(0, p.value) : e.text;
87
- return /* @__PURE__ */ a("div", {
88
- className: f.line,
89
- "data-type": e.type ?? "output",
90
- children: [
91
- e.prefix && /* @__PURE__ */ i("span", {
92
- className: f.prefix,
93
- children: e.prefix
94
- }),
95
- /* @__PURE__ */ i("span", {
96
- className: f.text,
97
- children: r
98
- }),
99
- n && d.value < o.length && /* @__PURE__ */ i("span", {
100
- className: f.cursor,
101
- "aria-hidden": "true"
102
- })
103
- ]
104
- }, t);
105
- });
106
- return /* @__PURE__ */ i("div", {
107
- role: "log",
108
- "aria-live": "polite",
109
- "aria-label": "Terminal output",
110
- className: [f.root, u].filter(Boolean).join(" "),
111
- children: h
112
- });
113
- }
114
- var m = {
115
- root: "_root_ilql2_2",
116
- messages: "_messages_ilql2_12",
117
- message: "_message_ilql2_12",
118
- roleLabel: "_roleLabel_ilql2_33",
119
- content: "_content_ilql2_38",
120
- inputArea: "_inputArea_ilql2_48",
121
- textarea: "_textarea_ilql2_55",
122
- sendButton: "_sendButton_ilql2_65"
123
- };
124
- //#endregion
125
- //#region src/ai-chat.tsx
126
- function h({ messages: n, onSend: c, isStreaming: u = !1, streamingText: d, className: f }) {
127
- r();
128
- let p = t(""), h = e(null);
129
- function g() {
130
- let e = p.value.trim();
131
- e && (c(e), p.value = "");
132
- }
133
- function _(e) {
134
- e.key === "Enter" && !e.shiftKey && (e.preventDefault(), g());
135
- }
136
- return /* @__PURE__ */ a("div", {
137
- className: [m.root, f].filter(Boolean).join(" "),
138
- children: [/* @__PURE__ */ a("div", {
139
- ref: h,
140
- className: m.messages,
141
- role: "log",
142
- "aria-live": "polite",
143
- children: [n.filter((e) => e.role !== "system").map((e) => /* @__PURE__ */ a("div", {
144
- className: m.message,
145
- "data-role": e.role,
146
- children: [/* @__PURE__ */ i("span", {
147
- className: m.roleLabel,
148
- children: e.role === "user" ? s(o.ai.you) : s(o.ai.assistant)
149
- }), /* @__PURE__ */ i("div", {
150
- className: m.content,
151
- children: e.content
152
- })]
153
- }, e.id)), u && d !== void 0 && /* @__PURE__ */ a("div", {
154
- className: m.message,
155
- "data-role": "assistant",
156
- children: [/* @__PURE__ */ i("span", {
157
- className: m.roleLabel,
158
- children: s(o.ai.assistant)
159
- }), /* @__PURE__ */ i("div", {
160
- className: m.content,
161
- children: /* @__PURE__ */ i(l, { text: d })
162
- })]
163
- })]
164
- }), /* @__PURE__ */ a("div", {
165
- className: m.inputArea,
166
- children: [/* @__PURE__ */ i("textarea", {
167
- className: m.textarea,
168
- placeholder: s(o.ai.placeholder),
169
- value: p.value,
170
- onChange: (e) => {
171
- p.value = e.target.value;
172
- },
173
- onKeyDown: _,
174
- rows: 1,
175
- "aria-label": s(o.ai.placeholder)
176
- }), /* @__PURE__ */ i("button", {
177
- type: "button",
178
- className: m.sendButton,
179
- onClick: g,
180
- disabled: u,
181
- "aria-label": s(o.ai.send),
182
- children: s(o.ai.send)
183
- })]
184
- })]
185
- });
186
- }
187
- //#endregion
188
- export { h as AiChat, d as AiLabel, l as StreamingText, p as Terminal };
3
+ import{useRef as e}from"react";import{useSignal as t,useSignalEffect as n,useSignals as r}from"@cascivo/core";import{jsx as i,jsxs as a}from"react/jsx-runtime";import{builtin as o,t as s}from"@cascivo/i18n";var c={root:`_root_ajc1u_2`,cursor:`_cursor_ajc1u_5`};function StreamingText({text:o,speed:s=2,onComplete:l,className:u}){r();let d=t(``),f=e(l);return f.current=l,d.value=d.value.length>o.length?``:d.value,n(()=>{let e=o;if(d.value===e){f.current?.();return}let t;function tick(){let n=d.value;if(n.length>=e.length){f.current?.();return}d.value=e.slice(0,n.length+s),t=requestAnimationFrame(tick)}return t=requestAnimationFrame(tick),()=>cancelAnimationFrame(t)}),a(`span`,{className:[c.root,u].filter(Boolean).join(` `),children:[d.value,d.value!==o&&i(`span`,{className:c.cursor,"aria-hidden":`true`})]})}var l={root:`_root_tiibp_2`};function AiLabel({variant:e=`generating`,className:t,...n}){r();let a=s(e===`generating`?o.ai.generating:e===`done`?o.ai.done:o.ai.error);return i(`span`,{role:`status`,"aria-label":a,"data-variant":e,className:[l.root,t].filter(Boolean).join(` `),...n,children:a})}var u={root:`_root_131e4_2`,line:`_line_131e4_12`,prefix:`_prefix_131e4_16`,text:`_text_131e4_20`,cursor:`_cursor_131e4_23`};function Terminal({lines:o,speed:s=3,loop:c=!1,onComplete:l,className:d}){r();let f=t(0),p=t(0),m=e(l);m.current=l,n(()=>{if(o.length===0)return;let e;function tick(){let t=f.value,n=p.value;if(t>=o.length){m.current?.(),c&&(f.value=0,p.value=0);return}n<o[t].text.length?p.value=n+s:(f.value=t+1,p.value=0),e=requestAnimationFrame(tick)}return e=requestAnimationFrame(tick),()=>cancelAnimationFrame(e)});let h=o.slice(0,f.value+1).map((e,t)=>{let n=t===f.value,r=n?e.text.slice(0,p.value):e.text;return a(`div`,{className:u.line,"data-type":e.type??`output`,children:[e.prefix&&i(`span`,{className:u.prefix,children:e.prefix}),i(`span`,{className:u.text,children:r}),n&&f.value<o.length&&i(`span`,{className:u.cursor,"aria-hidden":`true`})]},t)});return i(`div`,{role:`log`,"aria-live":`polite`,"aria-label":`Terminal output`,className:[u.root,d].filter(Boolean).join(` `),children:h})}var d={root:`_root_ilql2_2`,messages:`_messages_ilql2_12`,message:`_message_ilql2_12`,roleLabel:`_roleLabel_ilql2_33`,content:`_content_ilql2_38`,inputArea:`_inputArea_ilql2_48`,textarea:`_textarea_ilql2_55`,sendButton:`_sendButton_ilql2_65`};function AiChat({messages:n,onSend:c,isStreaming:l=!1,streamingText:u,className:f}){r();let p=t(``),m=e(null);function handleSend(){let e=p.value.trim();e&&(c(e),p.value=``)}function handleKeyDown(e){e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),handleSend())}return a(`div`,{className:[d.root,f].filter(Boolean).join(` `),children:[a(`div`,{ref:m,className:d.messages,role:`log`,"aria-live":`polite`,children:[n.filter(e=>e.role!==`system`).map(e=>a(`div`,{className:d.message,"data-role":e.role,children:[i(`span`,{className:d.roleLabel,children:e.role===`user`?s(o.ai.you):s(o.ai.assistant)}),i(`div`,{className:d.content,children:e.content})]},e.id)),l&&u!==void 0&&a(`div`,{className:d.message,"data-role":`assistant`,children:[i(`span`,{className:d.roleLabel,children:s(o.ai.assistant)}),i(`div`,{className:d.content,children:i(StreamingText,{text:u})})]})]}),a(`div`,{className:d.inputArea,children:[i(`textarea`,{className:d.textarea,placeholder:s(o.ai.placeholder),value:p.value,onChange:e=>{p.value=e.target.value},onKeyDown:handleKeyDown,rows:1,"aria-label":s(o.ai.placeholder)}),i(`button`,{type:`button`,className:d.sendButton,onClick:handleSend,disabled:l,"aria-label":s(o.ai.send),children:s(o.ai.send)})]})]})}export{AiChat,AiLabel,StreamingText,Terminal};
@@ -1,187 +1 @@
1
- "use client";
2
- import { useRef as e } from "react";
3
- import { useSignal as t, useSignalEffect as n, useSignals as r } from "@cascivo/core";
4
- import { jsx as i, jsxs as a } from "react/jsx-runtime";
5
- import { builtin as o, t as s } from "@cascivo/i18n";
6
- var c = {
7
- root: "_root_1vw7g_2",
8
- cursor: "_cursor_1vw7g_5",
9
- "cascade-cursor-blink": "_cascade-cursor-blink_1vw7g_1"
10
- };
11
- //#endregion
12
- //#region src/streaming-text.tsx
13
- function l({ text: o, speed: s = 2, onComplete: l, className: u }) {
14
- r();
15
- let d = t(""), f = e(l);
16
- return f.current = l, d.value = d.value.length > o.length ? "" : d.value, n(() => {
17
- let e = o;
18
- if (d.value === e) {
19
- f.current?.();
20
- return;
21
- }
22
- let t;
23
- function n() {
24
- let r = d.value;
25
- if (r.length >= e.length) {
26
- f.current?.();
27
- return;
28
- }
29
- d.value = e.slice(0, r.length + s), t = requestAnimationFrame(n);
30
- }
31
- return t = requestAnimationFrame(n), () => cancelAnimationFrame(t);
32
- }), /* @__PURE__ */ a("span", {
33
- className: [c.root, u].filter(Boolean).join(" "),
34
- children: [d.value, d.value !== o && /* @__PURE__ */ i("span", {
35
- className: c.cursor,
36
- "aria-hidden": "true"
37
- })]
38
- });
39
- }
40
- var u = {
41
- root: "_root_5tg3n_2",
42
- "cascade-ai-pulse": "_cascade-ai-pulse_5tg3n_1"
43
- };
44
- //#endregion
45
- //#region src/ai-label.tsx
46
- function d({ variant: e = "generating", className: t, ...n }) {
47
- r();
48
- let a = s(e === "generating" ? o.ai.generating : e === "done" ? o.ai.done : o.ai.error);
49
- return /* @__PURE__ */ i("span", {
50
- role: "status",
51
- "aria-label": a,
52
- "data-variant": e,
53
- className: [u.root, t].filter(Boolean).join(" "),
54
- ...n,
55
- children: a
56
- });
57
- }
58
- var f = {
59
- root: "_root_1s9z8_2",
60
- line: "_line_1s9z8_12",
61
- prefix: "_prefix_1s9z8_16",
62
- text: "_text_1s9z8_20",
63
- cursor: "_cursor_1s9z8_23",
64
- "cascade-cursor-blink": "_cascade-cursor-blink_1s9z8_1"
65
- };
66
- //#endregion
67
- //#region src/terminal.tsx
68
- function p({ lines: o, speed: s = 3, loop: c = !1, onComplete: l, className: u }) {
69
- r();
70
- let d = t(0), p = t(0), m = e(l);
71
- m.current = l, n(() => {
72
- if (o.length === 0) return;
73
- let e;
74
- function t() {
75
- let n = d.value, r = p.value;
76
- if (n >= o.length) {
77
- m.current?.(), c && (d.value = 0, p.value = 0);
78
- return;
79
- }
80
- r < o[n].text.length ? p.value = r + s : (d.value = n + 1, p.value = 0), e = requestAnimationFrame(t);
81
- }
82
- return e = requestAnimationFrame(t), () => cancelAnimationFrame(e);
83
- });
84
- let h = o.slice(0, d.value + 1).map((e, t) => {
85
- let n = t === d.value, r = n ? e.text.slice(0, p.value) : e.text;
86
- return /* @__PURE__ */ a("div", {
87
- className: f.line,
88
- "data-type": e.type ?? "output",
89
- children: [
90
- e.prefix && /* @__PURE__ */ i("span", {
91
- className: f.prefix,
92
- children: e.prefix
93
- }),
94
- /* @__PURE__ */ i("span", {
95
- className: f.text,
96
- children: r
97
- }),
98
- n && d.value < o.length && /* @__PURE__ */ i("span", {
99
- className: f.cursor,
100
- "aria-hidden": "true"
101
- })
102
- ]
103
- }, t);
104
- });
105
- return /* @__PURE__ */ i("div", {
106
- role: "log",
107
- "aria-live": "polite",
108
- "aria-label": "Terminal output",
109
- className: [f.root, u].filter(Boolean).join(" "),
110
- children: h
111
- });
112
- }
113
- var m = {
114
- root: "_root_ilql2_2",
115
- messages: "_messages_ilql2_12",
116
- message: "_message_ilql2_12",
117
- roleLabel: "_roleLabel_ilql2_33",
118
- content: "_content_ilql2_38",
119
- inputArea: "_inputArea_ilql2_48",
120
- textarea: "_textarea_ilql2_55",
121
- sendButton: "_sendButton_ilql2_65"
122
- };
123
- //#endregion
124
- //#region src/ai-chat.tsx
125
- function h({ messages: n, onSend: c, isStreaming: u = !1, streamingText: d, className: f }) {
126
- r();
127
- let p = t(""), h = e(null);
128
- function g() {
129
- let e = p.value.trim();
130
- e && (c(e), p.value = "");
131
- }
132
- function _(e) {
133
- e.key === "Enter" && !e.shiftKey && (e.preventDefault(), g());
134
- }
135
- return /* @__PURE__ */ a("div", {
136
- className: [m.root, f].filter(Boolean).join(" "),
137
- children: [/* @__PURE__ */ a("div", {
138
- ref: h,
139
- className: m.messages,
140
- role: "log",
141
- "aria-live": "polite",
142
- children: [n.filter((e) => e.role !== "system").map((e) => /* @__PURE__ */ a("div", {
143
- className: m.message,
144
- "data-role": e.role,
145
- children: [/* @__PURE__ */ i("span", {
146
- className: m.roleLabel,
147
- children: e.role === "user" ? s(o.ai.you) : s(o.ai.assistant)
148
- }), /* @__PURE__ */ i("div", {
149
- className: m.content,
150
- children: e.content
151
- })]
152
- }, e.id)), u && d !== void 0 && /* @__PURE__ */ a("div", {
153
- className: m.message,
154
- "data-role": "assistant",
155
- children: [/* @__PURE__ */ i("span", {
156
- className: m.roleLabel,
157
- children: s(o.ai.assistant)
158
- }), /* @__PURE__ */ i("div", {
159
- className: m.content,
160
- children: /* @__PURE__ */ i(l, { text: d })
161
- })]
162
- })]
163
- }), /* @__PURE__ */ a("div", {
164
- className: m.inputArea,
165
- children: [/* @__PURE__ */ i("textarea", {
166
- className: m.textarea,
167
- placeholder: s(o.ai.placeholder),
168
- value: p.value,
169
- onChange: (e) => {
170
- p.value = e.target.value;
171
- },
172
- onKeyDown: _,
173
- rows: 1,
174
- "aria-label": s(o.ai.placeholder)
175
- }), /* @__PURE__ */ i("button", {
176
- type: "button",
177
- className: m.sendButton,
178
- onClick: g,
179
- disabled: u,
180
- "aria-label": s(o.ai.send),
181
- children: s(o.ai.send)
182
- })]
183
- })]
184
- });
185
- }
186
- //#endregion
187
- export { h as AiChat, d as AiLabel, l as StreamingText, p as Terminal };
1
+ "use client";import{useRef as e}from"react";import{useSignal as t,useSignalEffect as n,useSignals as r}from"@cascivo/core";import{jsx as i,jsxs as a}from"react/jsx-runtime";import{builtin as o,t as s}from"@cascivo/i18n";var c={root:`_root_ajc1u_2`,cursor:`_cursor_ajc1u_5`};function StreamingText({text:o,speed:s=2,onComplete:l,className:u}){r();let d=t(``),f=e(l);return f.current=l,d.value=d.value.length>o.length?``:d.value,n(()=>{let e=o;if(d.value===e){f.current?.();return}let t;function tick(){let n=d.value;if(n.length>=e.length){f.current?.();return}d.value=e.slice(0,n.length+s),t=requestAnimationFrame(tick)}return t=requestAnimationFrame(tick),()=>cancelAnimationFrame(t)}),a(`span`,{className:[c.root,u].filter(Boolean).join(` `),children:[d.value,d.value!==o&&i(`span`,{className:c.cursor,"aria-hidden":`true`})]})}var l={root:`_root_tiibp_2`};function AiLabel({variant:e=`generating`,className:t,...n}){r();let a=s(e===`generating`?o.ai.generating:e===`done`?o.ai.done:o.ai.error);return i(`span`,{role:`status`,"aria-label":a,"data-variant":e,className:[l.root,t].filter(Boolean).join(` `),...n,children:a})}var u={root:`_root_131e4_2`,line:`_line_131e4_12`,prefix:`_prefix_131e4_16`,text:`_text_131e4_20`,cursor:`_cursor_131e4_23`};function Terminal({lines:o,speed:s=3,loop:c=!1,onComplete:l,className:d}){r();let f=t(0),p=t(0),m=e(l);m.current=l,n(()=>{if(o.length===0)return;let e;function tick(){let t=f.value,n=p.value;if(t>=o.length){m.current?.(),c&&(f.value=0,p.value=0);return}n<o[t].text.length?p.value=n+s:(f.value=t+1,p.value=0),e=requestAnimationFrame(tick)}return e=requestAnimationFrame(tick),()=>cancelAnimationFrame(e)});let h=o.slice(0,f.value+1).map((e,t)=>{let n=t===f.value,r=n?e.text.slice(0,p.value):e.text;return a(`div`,{className:u.line,"data-type":e.type??`output`,children:[e.prefix&&i(`span`,{className:u.prefix,children:e.prefix}),i(`span`,{className:u.text,children:r}),n&&f.value<o.length&&i(`span`,{className:u.cursor,"aria-hidden":`true`})]},t)});return i(`div`,{role:`log`,"aria-live":`polite`,"aria-label":`Terminal output`,className:[u.root,d].filter(Boolean).join(` `),children:h})}var d={root:`_root_ilql2_2`,messages:`_messages_ilql2_12`,message:`_message_ilql2_12`,roleLabel:`_roleLabel_ilql2_33`,content:`_content_ilql2_38`,inputArea:`_inputArea_ilql2_48`,textarea:`_textarea_ilql2_55`,sendButton:`_sendButton_ilql2_65`};function AiChat({messages:n,onSend:c,isStreaming:l=!1,streamingText:u,className:f}){r();let p=t(``),m=e(null);function handleSend(){let e=p.value.trim();e&&(c(e),p.value=``)}function handleKeyDown(e){e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),handleSend())}return a(`div`,{className:[d.root,f].filter(Boolean).join(` `),children:[a(`div`,{ref:m,className:d.messages,role:`log`,"aria-live":`polite`,children:[n.filter(e=>e.role!==`system`).map(e=>a(`div`,{className:d.message,"data-role":e.role,children:[i(`span`,{className:d.roleLabel,children:e.role===`user`?s(o.ai.you):s(o.ai.assistant)}),i(`div`,{className:d.content,children:e.content})]},e.id)),l&&u!==void 0&&a(`div`,{className:d.message,"data-role":`assistant`,children:[i(`span`,{className:d.roleLabel,children:s(o.ai.assistant)}),i(`div`,{className:d.content,children:i(StreamingText,{text:u})})]})]}),a(`div`,{className:d.inputArea,children:[i(`textarea`,{className:d.textarea,placeholder:s(o.ai.placeholder),value:p.value,onChange:e=>{p.value=e.target.value},onKeyDown:handleKeyDown,rows:1,"aria-label":s(o.ai.placeholder)}),i(`button`,{type:`button`,className:d.sendButton,onClick:handleSend,disabled:l,"aria-label":s(o.ai.send),children:s(o.ai.send)})]})]})}export{AiChat,AiLabel,StreamingText,Terminal};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cascivo/ai",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "AI-native components for cascivo — StreamingText, AiLabel, Terminal, AiChat",
5
5
  "keywords": [
6
6
  "ai",
@@ -42,9 +42,9 @@
42
42
  "provenance": true
43
43
  },
44
44
  "dependencies": {
45
- "@cascivo/core": "^1.0.0",
46
- "@cascivo/i18n": "^1.0.0",
47
- "@cascivo/tokens": "^1.0.0"
45
+ "@cascivo/core": "^1.2.0",
46
+ "@cascivo/i18n": "^1.2.0",
47
+ "@cascivo/tokens": "^1.1.0"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@testing-library/jest-dom": "^6.9.1",