genaicode 2.9.1 → 2.11.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.
@@ -0,0 +1,140 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useLayoutEffect, useRef, useState, } from 'react';
3
+ import { formatDuration, formatUsage, relativePath, shortId, toolLabel, toolSummary, turnFooter } from './format.js';
4
+ import { Markdown } from './markdown.js';
5
+ /**
6
+ * A presentational chat with a coding agent: it renders the `SessionState` it is given and
7
+ * reports what the user does through callbacks. It runs nothing, fetches nothing and holds no
8
+ * token; the host owns the `AgentSession`. Import `genaicode/react/styles.css` once.
9
+ */
10
+ export function AgentChat(props) {
11
+ const state = props.state ?? NO_SESSION;
12
+ const [draft, setDraft] = useState('');
13
+ const scroller = useRef(null);
14
+ const pinned = useRef(true);
15
+ const input = useRef(null);
16
+ const running = state?.status === 'running';
17
+ const now = useNow(running);
18
+ useLayoutEffect(() => {
19
+ const el = scroller.current;
20
+ if (el && pinned.current)
21
+ el.scrollTop = el.scrollHeight;
22
+ });
23
+ useLayoutEffect(() => {
24
+ const el = input.current;
25
+ if (!el)
26
+ return;
27
+ el.style.height = 'auto';
28
+ el.style.height = `${Math.min(200, el.scrollHeight)}px`;
29
+ }, [draft]);
30
+ const rootClass = ['gc-chat', props.className].filter(Boolean).join(' ');
31
+ const theme = props.theme && props.theme !== 'auto' ? props.theme : undefined;
32
+ const agentName = state.agent || 'the agent';
33
+ const send = () => {
34
+ if (!draft.trim() || props.disabled)
35
+ return;
36
+ pinned.current = true;
37
+ props.onSend(draft);
38
+ setDraft('');
39
+ };
40
+ const onKeyDown = (event) => {
41
+ if (event.key === 'Enter' && !event.shiftKey && !event.nativeEvent.isComposing) {
42
+ event.preventDefault();
43
+ send();
44
+ }
45
+ if (event.key === 'Escape' && running && props.onStop)
46
+ props.onStop();
47
+ };
48
+ // Notices sit after the turn that was last when they were posted.
49
+ const items = [];
50
+ const notices = [...(props.notices ?? [])].sort((a, b) => a.afterTurn - b.afterTurn);
51
+ const flush = (upTo) => {
52
+ while (notices.length && notices[0].afterTurn <= upTo) {
53
+ const notice = notices.shift();
54
+ items.push(_jsx("div", { className: `gc-notice${notice.tone === 'error' ? ' gc-err' : ''}`, children: notice.text }, `n${notice.id}`));
55
+ }
56
+ };
57
+ state.turns.forEach((turn, index) => {
58
+ flush(index);
59
+ items.push(_jsx(Turn, { turn: turn, now: now, cwd: state.cwd, pending: state.approvals, onApprove: props.onApprove, prompt: props.renderPrompt, toolName: props.formatToolName ?? toolLabel }, turn.id));
60
+ const after = props.renderAfterTurn?.(turn, index);
61
+ if (after !== undefined && after !== null && after !== false) {
62
+ items.push(_jsx("div", { className: "gc-after-turn", children: after }, `a${turn.id}`));
63
+ }
64
+ });
65
+ flush(Number.MAX_SAFE_INTEGER);
66
+ const placeholder = props.placeholder ??
67
+ (running
68
+ ? state.canSteer
69
+ ? 'Add to the running task…'
70
+ : 'Queue the next prompt…'
71
+ : `Ask ${agentName} to change something…`);
72
+ const usage = formatUsage(state.usage, state.costUsd);
73
+ const footer = props.renderFooter?.();
74
+ return (_jsxs("div", { className: rootClass, "data-theme": theme, "data-status": state.status, style: props.style, children: [props.header !== undefined ? (props.header) : (_jsxs("div", { className: "gc-header", children: [state.agent ? (_jsx("span", { className: "gc-avatar", "aria-hidden": "true", children: state.agent.slice(0, 2) })) : null, _jsx("b", { className: "gc-agent", children: state.agent || 'Agent' }), state.model ? _jsx("span", { className: "gc-model", children: state.model }) : null, running ? _jsx("span", { className: "gc-spin", role: "status", "aria-label": "Working" }) : null, _jsx("span", { className: "gc-spacer" }), state.sessionId ? _jsxs("span", { className: "gc-chip", children: ["session ", shortId(state.sessionId)] }) : null, usage ? _jsx("span", { className: "gc-chip", children: usage }) : null, props.headerExtras] })), _jsx("div", { className: "gc-scroll", ref: scroller, onScroll: (event) => {
75
+ const el = event.currentTarget;
76
+ pinned.current = el.scrollHeight - el.scrollTop - el.clientHeight < 80;
77
+ }, children: _jsxs("div", { className: "gc-thread", role: "log", "aria-live": "polite", children: [state.turns.length === 0
78
+ ? (props.emptyState ?? (_jsx("div", { className: "gc-empty", children: _jsxs("div", { className: "gc-empty-title", children: ["What should ", agentName, " work on?"] }) })))
79
+ : null, items, footer !== undefined && footer !== null && footer !== false ? (_jsx("div", { className: "gc-footer-slot", children: footer })) : null] }) }), _jsxs("div", { className: "gc-composer", children: [state.queued.length ? (_jsx("div", { className: "gc-queued", children: state.queued.map((prompt, i) => {
80
+ const shown = props.renderPrompt ? props.renderPrompt(prompt) : prompt;
81
+ return shown === null || shown === undefined || shown === false ? null : _jsxs("span", { children: ["\u23F8 ", shown] }, i);
82
+ }) })) : null, _jsxs("div", { className: "gc-box", children: [_jsx("textarea", { ref: input, rows: 1, autoFocus: props.autoFocus, value: draft, placeholder: placeholder, "aria-label": "Message", onChange: (event) => setDraft(event.target.value), onKeyDown: onKeyDown }), running && props.onStop ? (_jsx("button", { type: "button", className: "gc-btn gc-danger", onClick: () => props.onStop?.(), children: "Stop" })) : null, _jsx("button", { type: "button", className: "gc-btn gc-primary", disabled: !draft.trim() || props.disabled, onClick: send, children: running ? (state.canSteer ? 'Steer' : 'Queue') : 'Send' })] }), props.hint === null ? null : (_jsx("div", { className: "gc-hint", children: props.hint ?? `Enter to send · Shift+Enter for a new line${props.onStop ? ' · Esc stops' : ''}` }))] })] }));
83
+ }
84
+ const NO_SESSION = {
85
+ agent: '',
86
+ cwd: '',
87
+ status: 'idle',
88
+ turns: [],
89
+ queued: [],
90
+ approvals: [],
91
+ usage: {},
92
+ canSteer: false,
93
+ };
94
+ function useNow(active) {
95
+ const [now, setNow] = useState(() => Date.now());
96
+ useEffect(() => {
97
+ if (!active)
98
+ return;
99
+ setNow(Date.now());
100
+ const timer = setInterval(() => setNow(Date.now()), 500);
101
+ return () => clearInterval(timer);
102
+ }, [active]);
103
+ return now;
104
+ }
105
+ function Turn({ turn, now, cwd, pending, onApprove, prompt, toolName, }) {
106
+ const running = !turn.result;
107
+ const bad = turn.result && !turn.result.ok;
108
+ const shown = prompt ? prompt(turn.prompt, turn) : turn.prompt;
109
+ return (_jsxs("section", { className: "gc-turn", children: [shown === null || shown === undefined || shown === false ? null : _jsx("div", { className: "gc-prompt", children: shown }), turn.entries.length ? (_jsxs("div", { className: "gc-agent-row", children: [_jsx("div", { className: "gc-avatar", title: turn.agent, "aria-hidden": "true", children: turn.agent.slice(0, 2) }), _jsx("div", { className: "gc-steps", children: turn.entries.map((entry, i) => (_jsx(Entry, { entry: entry, agent: turn.agent, cwd: cwd, pending: pending, onApprove: onApprove, prompt: prompt, toolName: toolName }, i))) })] })) : null, running ? (_jsxs("div", { className: "gc-working", children: [_jsx("span", { className: "gc-spin" }), " ", turn.agent, " is working", _jsxs("span", { "aria-hidden": "true", children: ["\u00B7 ", formatDuration(now - turn.startedAt)] })] })) : (_jsxs("div", { className: `gc-turn-footer${bad ? ' gc-bad' : ''}`, children: [turnFooter(turn, now), " \u00B7 ", turn.agent] }))] }));
110
+ }
111
+ function Entry({ entry, agent, cwd, pending, onApprove, prompt, toolName, }) {
112
+ switch (entry.kind) {
113
+ case 'text':
114
+ return _jsx(Markdown, { text: entry.text, streaming: entry.streaming });
115
+ case 'tool':
116
+ return (_jsxs("details", { className: "gc-tool", children: [_jsxs("summary", { children: [_jsx("span", { className: `gc-state${entry.done ? (entry.isError ? ' gc-err' : ' gc-ok') : ''}`, children: entry.done ? entry.isError ? '✗' : '✓' : _jsx("span", { className: "gc-spin" }) }), _jsx("span", { className: "gc-tool-name", children: toolName(entry.name) }), _jsx("span", { className: "gc-tool-arg", children: toolSummary(entry.input, 200, cwd) })] }), _jsx("pre", { children: entry.output?.trim() || (entry.done ? 'No output.' : 'Running…') })] }));
117
+ case 'files':
118
+ return (_jsxs("div", { className: "gc-files", children: [_jsx("span", { children: "\u270E Edited" }), entry.paths.map((path) => (_jsx("code", { children: relativePath(path, cwd) }, path)))] }));
119
+ case 'approval': {
120
+ const what = entry.request.kind === 'command' ? 'run' : entry.request.kind === 'file-change' ? 'apply edits to' : 'do';
121
+ const subject = entry.request.summary ?? entry.request.id;
122
+ const waiting = pending.some((request) => request.id === entry.request.id);
123
+ if (entry.decision || !waiting) {
124
+ // Not pending and no decision: the turn ended (or was stopped) before an answer.
125
+ const label = entry.decision === 'approve' ? '✓ Approved' : entry.decision ? '✗ Denied' : '– Not answered';
126
+ return (_jsxs("div", { className: "gc-approval gc-done", children: [label, ": ", what, "\u00A0", _jsx("span", { className: "gc-what", children: subject })] }));
127
+ }
128
+ return (_jsxs("div", { className: "gc-approval", children: [_jsxs("div", { children: [_jsx("strong", { children: agent }), " wants to ", what, ":"] }), _jsx("div", { className: "gc-what", children: subject }), onApprove ? (_jsxs("div", { className: "gc-buttons", children: [_jsx("button", { type: "button", className: "gc-btn gc-primary", onClick: () => onApprove(entry.request.id, 'approve'), children: "Approve" }), _jsx("button", { type: "button", className: "gc-btn gc-danger", onClick: () => onApprove(entry.request.id, 'deny'), children: "Deny" })] })) : (_jsx("div", { className: "gc-waiting", children: "Waiting for approval\u2026" }))] }));
129
+ }
130
+ case 'input': {
131
+ const shown = prompt ? prompt(entry.text) : entry.text;
132
+ if (shown === null || shown === undefined || shown === false)
133
+ return null;
134
+ return (_jsxs("div", { className: "gc-prompt gc-steer", children: [_jsx("small", { children: "Sent while working" }), shown] }));
135
+ }
136
+ case 'error':
137
+ return _jsx("div", { className: "gc-error", children: entry.message });
138
+ }
139
+ }
140
+ //# sourceMappingURL=agent-chat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-chat.js","sourceRoot":"","sources":["../../src/react/agent-chat.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /** Display helpers shared by the chat front ends (`genaicode/react`, the terminal UI). No React here. */
2
+ import type { SessionTurn } from '../agents/session.js';
3
+ import type { TokenUsage } from '../core/types.js';
4
+ /** `path` relative to `cwd` when it is inside it. */
5
+ export declare function relativePath(path: string, cwd?: string): string;
6
+ /** The one argument worth showing for a tool call (its command, path, pattern...). */
7
+ export declare function toolSummary(input: unknown, width?: number, cwd?: string): string;
8
+ /** Friendlier names for the tool ids drivers report. */
9
+ export declare function toolLabel(name: string): string;
10
+ export declare function formatDuration(ms: number): string;
11
+ export declare function formatTokens(count: number): string;
12
+ export declare function formatUsage(usage: TokenUsage, costUsd?: number): string;
13
+ /** "done in 12s", "failed: …", or "working 4s" for a turn. */
14
+ export declare function turnFooter(turn: SessionTurn, now?: number): string;
15
+ export declare function shortId(id: string | undefined): string;
16
+ export declare function firstLine(text: string): string;
@@ -0,0 +1,95 @@
1
+ const INPUT_KEYS = ['command', 'cmd', 'file_path', 'filePath', 'path', 'pattern', 'query', 'url', 'description'];
2
+ /** `path` relative to `cwd` when it is inside it. */
3
+ export function relativePath(path, cwd) {
4
+ if (!cwd)
5
+ return path;
6
+ const base = cwd.endsWith('/') ? cwd : `${cwd}/`;
7
+ return path.startsWith(base) ? path.slice(base.length) : path;
8
+ }
9
+ /** The one argument worth showing for a tool call (its command, path, pattern...). */
10
+ export function toolSummary(input, width = 80, cwd) {
11
+ if (input === undefined || input === null)
12
+ return '';
13
+ let value = input;
14
+ if (typeof input === 'object' && !Array.isArray(input)) {
15
+ const record = input;
16
+ value = INPUT_KEYS.map((key) => record[key]).find((field) => typeof field === 'string' || Array.isArray(field));
17
+ if (value === undefined)
18
+ value = '';
19
+ }
20
+ const flat = (Array.isArray(value) ? value.join(' ') : typeof value === 'string' ? value : '')
21
+ .replace(/\s+/g, ' ')
22
+ .trim();
23
+ const shown = cwd ? flat.split(cwd.endsWith('/') ? cwd : `${cwd}/`).join('') : flat;
24
+ return shown.length > width ? `${shown.slice(0, width - 1)}…` : shown;
25
+ }
26
+ /** Friendlier names for the tool ids drivers report. */
27
+ export function toolLabel(name) {
28
+ const known = {
29
+ shell: 'Shell',
30
+ bash: 'Shell',
31
+ Bash: 'Shell',
32
+ read: 'Read',
33
+ write: 'Write',
34
+ edit: 'Edit',
35
+ grep: 'Search',
36
+ Grep: 'Search',
37
+ glob: 'Find',
38
+ Glob: 'Find',
39
+ todowrite: 'Plan',
40
+ TodoWrite: 'Plan',
41
+ webfetch: 'Fetch',
42
+ WebFetch: 'Fetch',
43
+ };
44
+ return known[name] ?? name;
45
+ }
46
+ export function formatDuration(ms) {
47
+ const seconds = Math.max(0, Math.round(ms / 1000));
48
+ if (seconds < 60)
49
+ return `${seconds}s`;
50
+ const minutes = Math.floor(seconds / 60);
51
+ return `${minutes}m ${String(seconds % 60).padStart(2, '0')}s`;
52
+ }
53
+ export function formatTokens(count) {
54
+ if (count < 1000)
55
+ return String(count);
56
+ if (count < 1_000_000)
57
+ return `${(count / 1000).toFixed(count < 10_000 ? 1 : 0)}k`;
58
+ return `${(count / 1_000_000).toFixed(1)}M`;
59
+ }
60
+ export function formatUsage(usage, costUsd) {
61
+ const parts = [];
62
+ const tokens = (usage.inputTokens ?? 0) + (usage.outputTokens ?? 0);
63
+ if (tokens)
64
+ parts.push(`${formatTokens(tokens)} tokens`);
65
+ if (costUsd !== undefined)
66
+ parts.push(`$${costUsd.toFixed(costUsd < 1 ? 3 : 2)}`);
67
+ return parts.join(' · ');
68
+ }
69
+ /** "done in 12s", "failed: …", or "working 4s" for a turn. */
70
+ export function turnFooter(turn, now = Date.now()) {
71
+ const took = formatDuration((turn.endedAt ?? now) - turn.startedAt);
72
+ if (!turn.result)
73
+ return `working ${took}`;
74
+ switch (turn.result.status) {
75
+ case 'completed':
76
+ return turn.result.ok ? `done in ${took}` : `finished with errors in ${took}`;
77
+ case 'aborted':
78
+ return `stopped after ${took}`;
79
+ case 'timeout':
80
+ return `timed out after ${took}`;
81
+ default:
82
+ return `failed after ${took}${turn.result.error ? `: ${firstLine(turn.result.error)}` : ''}`;
83
+ }
84
+ }
85
+ export function shortId(id) {
86
+ if (!id)
87
+ return '';
88
+ // Tails differ where prefixes often do not (opencode ids start with a timestamp).
89
+ return id.length > 12 ? `…${id.slice(-8)}` : id;
90
+ }
91
+ export function firstLine(text) {
92
+ const line = text.split('\n').find((part) => part.trim()) ?? '';
93
+ return line.length > 160 ? `${line.slice(0, 159)}…` : line;
94
+ }
95
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/react/format.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /** Render `text` as Markdown. `streaming` adds a blinking caret after it. */
2
+ export declare function Markdown({ text, streaming, className }: {
3
+ text: string;
4
+ streaming?: boolean;
5
+ className?: string;
6
+ }): import("react").JSX.Element;
@@ -0,0 +1,163 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // A small, safe Markdown subset for agent replies: paragraphs, headings, lists, quotes, fenced
3
+ // code, inline code, bold, italic and links. Everything is a React text node, so HTML in the
4
+ // text shows as text. Links must be http(s) or mailto and open in a new tab.
5
+ // Every repetition is bounded, so text full of unclosed markers stays linear to scan.
6
+ const INLINE = /(`[^`\n]{1,1000}`)|(\*\*[^*\n]{1,1000}\*\*)|(\*[^*\s][^*\n]{0,1000}\*)|(\[[^[\]\n]{1,500}\]\(((?:https?:\/\/|mailto:)[^)\s]{1,2000})\))|(https?:\/\/[^\s<>()]{0,2000}[^\s<>().,;:!?'"])/g;
7
+ function link(href, label, key) {
8
+ return (_jsx("a", { href: href, target: "_blank", rel: "noopener noreferrer", children: label }, key));
9
+ }
10
+ /** `links` is false inside a link label, so no <a> ends up inside another. */
11
+ function inline(text, links = true) {
12
+ const out = [];
13
+ let last = 0;
14
+ let key = 0;
15
+ for (const match of text.matchAll(INLINE)) {
16
+ const [token] = match;
17
+ const at = match.index ?? 0;
18
+ if (at > last)
19
+ out.push(text.slice(last, at));
20
+ if (match[1])
21
+ out.push(_jsx("code", { children: token.slice(1, -1) }, key++));
22
+ else if (match[2])
23
+ out.push(_jsx("strong", { children: inline(token.slice(2, -2), links) }, key++));
24
+ else if (match[3])
25
+ out.push(_jsx("em", { children: inline(token.slice(1, -1), links) }, key++));
26
+ else if (match[4]) {
27
+ const label = inline(token.slice(1, token.indexOf(']')), false);
28
+ out.push(links ? link(match[5], label, key++) : _jsx("span", { children: label }, key++));
29
+ }
30
+ else
31
+ out.push(links ? link(token, token, key++) : token);
32
+ last = at + token.length;
33
+ }
34
+ if (last < text.length)
35
+ out.push(text.slice(last));
36
+ return out;
37
+ }
38
+ // Block syntax is matched on trimmed lines, without regexes that backtrack over whitespace.
39
+ function fence(line) {
40
+ const t = line.trim();
41
+ const char = t[0];
42
+ if (char !== '`' && char !== '~')
43
+ return undefined;
44
+ let length = 0;
45
+ while (t[length] === char)
46
+ length += 1;
47
+ if (length < 3)
48
+ return undefined;
49
+ const marker = char.repeat(length);
50
+ const lang = t.slice(length).trim();
51
+ return { marker, lang: /^[\w+-]{1,40}$/.test(lang) ? lang : '' };
52
+ }
53
+ function heading(line) {
54
+ const t = line.trimStart();
55
+ let level = 0;
56
+ while (level < 7 && t[level] === '#')
57
+ level += 1;
58
+ if (level === 0 || level > 6 || (t[level] !== ' ' && t[level] !== '\t'))
59
+ return undefined;
60
+ return { level, text: t.slice(level).trim() };
61
+ }
62
+ /** The item's text, or undefined when `line` is not a list item. */
63
+ function item(line) {
64
+ const t = line.trimStart();
65
+ const marker = /^(?:[-*+]|\d{1,9}[.)])/.exec(t)?.[0];
66
+ if (!marker || (t[marker.length] !== ' ' && t[marker.length] !== '\t'))
67
+ return undefined;
68
+ return t.slice(marker.length).trimStart();
69
+ }
70
+ const isQuote = (line) => line.trimStart().startsWith('>');
71
+ const unquote = (line) => {
72
+ const t = line.trimStart().slice(1);
73
+ return t.startsWith(' ') ? t.slice(1) : t;
74
+ };
75
+ const isRule = (line) => /^(?:-{3,}|\*{3,}|_{3,})$/.test(line.replace(/[ \t]/g, ''));
76
+ /** Render `text` as Markdown. `streaming` adds a blinking caret after it. */
77
+ export function Markdown({ text, streaming, className }) {
78
+ return (_jsx("div", { className: ['gc-md', streaming ? 'gc-caret' : '', className ?? ''].filter(Boolean).join(' '), children: blocks(text.trimEnd().split('\n')) }));
79
+ }
80
+ // Deeper quotes render as plain text, so a reply full of '>' cannot exhaust the stack.
81
+ const MAX_QUOTE_DEPTH = 8;
82
+ function blocks(lines, depth = 0) {
83
+ const quote = (line) => depth < MAX_QUOTE_DEPTH && isQuote(line);
84
+ const out = [];
85
+ let i = 0;
86
+ let key = 0;
87
+ while (i < lines.length) {
88
+ const line = lines[i];
89
+ const open = fence(line);
90
+ if (open) {
91
+ const body = [];
92
+ i += 1;
93
+ // Closed by the same character, at least as many times, and nothing else on the line.
94
+ const closes = (text) => {
95
+ const t = text.trim();
96
+ return t.length >= open.marker.length && t === open.marker[0].repeat(t.length);
97
+ };
98
+ while (i < lines.length && !closes(lines[i]))
99
+ body.push(lines[i++]);
100
+ i += 1;
101
+ out.push(_jsx("pre", { children: _jsx("code", { className: open.lang ? `language-${open.lang}` : undefined, children: body.join('\n') }) }, key++));
102
+ continue;
103
+ }
104
+ if (!line.trim()) {
105
+ i += 1;
106
+ continue;
107
+ }
108
+ if (isRule(line)) {
109
+ out.push(_jsx("hr", {}, key++));
110
+ i += 1;
111
+ continue;
112
+ }
113
+ const title = heading(line);
114
+ if (title) {
115
+ // h1 in a reply would outrank the host page's own headings.
116
+ const Tag = `h${Math.min(6, title.level + 1)}`;
117
+ out.push(_jsx(Tag, { children: inline(title.text) }, key++));
118
+ i += 1;
119
+ continue;
120
+ }
121
+ if (quote(line)) {
122
+ const quoted = [];
123
+ while (i < lines.length && quote(lines[i]))
124
+ quoted.push(unquote(lines[i++]));
125
+ out.push(_jsx("blockquote", { children: blocks(quoted, depth + 1) }, key++));
126
+ continue;
127
+ }
128
+ if (item(line) !== undefined) {
129
+ const start = parseInt(line, 10);
130
+ const ordered = !Number.isNaN(start);
131
+ const items = [];
132
+ for (; i < lines.length; i += 1) {
133
+ const next = item(lines[i]);
134
+ // A list of the other kind starts a new list.
135
+ if (next !== undefined && items.length && Number.isNaN(parseInt(lines[i], 10)) === ordered)
136
+ break;
137
+ if (next !== undefined)
138
+ items.push(next);
139
+ // An indented line continues the item above it.
140
+ else if (lines[i].startsWith(' ') && lines[i].trim())
141
+ items[items.length - 1] += `\n${lines[i].trim()}`;
142
+ else
143
+ break;
144
+ }
145
+ const children = items.map((item, n) => _jsx("li", { children: inline(item) }, n));
146
+ out.push(ordered ? (_jsx("ol", { start: start !== 1 ? start : undefined, children: children }, key++)) : (_jsx("ul", { children: children }, key++)));
147
+ continue;
148
+ }
149
+ const para = [];
150
+ while (i < lines.length &&
151
+ lines[i].trim() &&
152
+ !fence(lines[i]) &&
153
+ !heading(lines[i]) &&
154
+ item(lines[i]) === undefined &&
155
+ !quote(lines[i]) &&
156
+ (para.length === 0 || !isRule(lines[i]))) {
157
+ para.push(lines[i++]);
158
+ }
159
+ out.push(_jsx("p", { children: inline(para.join('\n')) }, key++));
160
+ }
161
+ return out;
162
+ }
163
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/react/markdown.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * `genaicode/react`: the genaicode chat as a React component, for hosts that run their own
3
+ * `AgentSession` (from `genaicode/agents`) and stream its `SessionState` to the page.
4
+ *
5
+ * ```tsx
6
+ * import { AgentChat } from 'genaicode/react';
7
+ * import 'genaicode/react/styles.css';
8
+ *
9
+ * <AgentChat state={state} onSend={send} onStop={stop} onApprove={approve} />
10
+ * ```
11
+ *
12
+ * React (18 or newer) comes from the host; genaicode does not install it.
13
+ */
14
+ export { AgentChat } from './react/agent-chat.js';
15
+ export type { AgentChatProps, ChatNotice } from './react/agent-chat.js';
16
+ export { Markdown } from './react/markdown.js';
17
+ export { formatDuration, formatUsage, relativePath, shortId, toolLabel, toolSummary, turnFooter, } from './react/format.js';
18
+ export type { SessionEntry, SessionState, SessionTurn } from './agents/session.js';
19
+ export type { ApprovalDecision, ApprovalRequest } from './agents/types.js';
package/dist/react.js ADDED
@@ -0,0 +1,17 @@
1
+ /**
2
+ * `genaicode/react`: the genaicode chat as a React component, for hosts that run their own
3
+ * `AgentSession` (from `genaicode/agents`) and stream its `SessionState` to the page.
4
+ *
5
+ * ```tsx
6
+ * import { AgentChat } from 'genaicode/react';
7
+ * import 'genaicode/react/styles.css';
8
+ *
9
+ * <AgentChat state={state} onSend={send} onStop={stop} onApprove={approve} />
10
+ * ```
11
+ *
12
+ * React (18 or newer) comes from the host; genaicode does not install it.
13
+ */
14
+ export { AgentChat } from './react/agent-chat.js';
15
+ export { Markdown } from './react/markdown.js';
16
+ export { formatDuration, formatUsage, relativePath, shortId, toolLabel, toolSummary, turnFooter, } from './react/format.js';
17
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.js","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EACL,cAAc,EACd,WAAW,EACX,YAAY,EACZ,OAAO,EACP,SAAS,EACT,WAAW,EACX,UAAU,GACX,MAAM,mBAAmB,CAAC"}