@a5c-ai/agent-mux-tui 0.3.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 +71 -0
- package/dist/app.d.ts +9 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +97 -0
- package/dist/app.js.map +1 -0
- package/dist/bin/amux-tui.d.ts +3 -0
- package/dist/bin/amux-tui.d.ts.map +1 -0
- package/dist/bin/amux-tui.js +8 -0
- package/dist/bin/amux-tui.js.map +1 -0
- package/dist/event-stream.d.ts +14 -0
- package/dist/event-stream.d.ts.map +1 -0
- package/dist/event-stream.js +34 -0
- package/dist/event-stream.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin.d.ts +57 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +4 -0
- package/dist/plugin.js.map +1 -0
- package/dist/plugins/chat-view.d.ts +9 -0
- package/dist/plugins/chat-view.d.ts.map +1 -0
- package/dist/plugins/chat-view.js +35 -0
- package/dist/plugins/chat-view.js.map +1 -0
- package/dist/plugins/cost.d.ts +3 -0
- package/dist/plugins/cost.d.ts.map +1 -0
- package/dist/plugins/cost.js +16 -0
- package/dist/plugins/cost.js.map +1 -0
- package/dist/plugins/diff.d.ts +7 -0
- package/dist/plugins/diff.d.ts.map +1 -0
- package/dist/plugins/diff.js +42 -0
- package/dist/plugins/diff.js.map +1 -0
- package/dist/plugins/fallback.d.ts +7 -0
- package/dist/plugins/fallback.d.ts.map +1 -0
- package/dist/plugins/fallback.js +17 -0
- package/dist/plugins/fallback.js.map +1 -0
- package/dist/plugins/sessions-view.d.ts +3 -0
- package/dist/plugins/sessions-view.d.ts.map +1 -0
- package/dist/plugins/sessions-view.js +49 -0
- package/dist/plugins/sessions-view.js.map +1 -0
- package/dist/plugins/text-delta.d.ts +3 -0
- package/dist/plugins/text-delta.d.ts.map +1 -0
- package/dist/plugins/text-delta.js +19 -0
- package/dist/plugins/text-delta.js.map +1 -0
- package/dist/plugins/tool-call.d.ts +3 -0
- package/dist/plugins/tool-call.d.ts.map +1 -0
- package/dist/plugins/tool-call.js +24 -0
- package/dist/plugins/tool-call.js.map +1 -0
- package/dist/prompt-input.d.ts +7 -0
- package/dist/prompt-input.d.ts.map +1 -0
- package/dist/prompt-input.js +25 -0
- package/dist/prompt-input.js.map +1 -0
- package/dist/registry.d.ts +13 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +26 -0
- package/dist/registry.js.map +1 -0
- package/package.json +71 -0
package/README.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# @a5c-ai/agent-mux-tui
|
|
2
|
+
|
|
3
|
+
Ink-based TUI for agent-mux with a plugin-first architecture. Almost everything
|
|
4
|
+
(message renderers, tool-call cards, diff views, session manager, chat) ships
|
|
5
|
+
as a plugin. The host package only provides the Ink process, view router, and
|
|
6
|
+
the SDK-injected `TuiContext`.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm i -g @a5c-ai/agent-mux-tui
|
|
12
|
+
amux-tui
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Writing a plugin
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { definePlugin } from '@a5c-ai/agent-mux-tui/plugin';
|
|
19
|
+
import { Text } from 'ink';
|
|
20
|
+
import React from 'react';
|
|
21
|
+
|
|
22
|
+
export default definePlugin({
|
|
23
|
+
name: 'my-error-renderer',
|
|
24
|
+
register(ctx) {
|
|
25
|
+
ctx.registerEventRenderer({
|
|
26
|
+
id: 'error',
|
|
27
|
+
match: (ev) => ev.type === 'error',
|
|
28
|
+
component: ({ event }) =>
|
|
29
|
+
event.type === 'error' ? <Text color="red">{event.message}</Text> : null,
|
|
30
|
+
});
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Pass your plugins to `App`:
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
import { render } from 'ink';
|
|
39
|
+
import { App, builtinPlugins } from '@a5c-ai/agent-mux-tui';
|
|
40
|
+
import myPlugin from './my-plugin.js';
|
|
41
|
+
|
|
42
|
+
render(<App client={client} plugins={[...builtinPlugins, myPlugin]} />);
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Extension points
|
|
46
|
+
|
|
47
|
+
- `registerView` — top-level tab in the TUI (chat, sessions, config, …)
|
|
48
|
+
- `registerEventRenderer` — per-`AgentEvent` display component. The renderer
|
|
49
|
+
with `id: 'fallback'` is reserved for the built-in dim one-liner that
|
|
50
|
+
handles any unrecognized event type; other renderers take priority.
|
|
51
|
+
- `registerCommand` — global hotkey command
|
|
52
|
+
- `registerPromptHandler` — overrides the default `p` prompt dispatch. If any
|
|
53
|
+
plugin registers a prompt handler, it receives the prompt instead of
|
|
54
|
+
`client.run({ agent: defaultAgent, prompt })`.
|
|
55
|
+
|
|
56
|
+
All extension points get an injected `TuiContext` with:
|
|
57
|
+
- `client: AgentMuxClient` — the SDK client instance
|
|
58
|
+
- `eventStream: EventStream` — shared pub/sub of `AgentEvent`s. Views
|
|
59
|
+
subscribe to render streaming output; commands can push synthetic events
|
|
60
|
+
via `ctx.emit({ type: 'event', event })`.
|
|
61
|
+
|
|
62
|
+
## Running a prompt
|
|
63
|
+
|
|
64
|
+
Press `p` to open the prompt input, type your message, and press Enter.
|
|
65
|
+
Events from the resulting `client.run()` are pushed into the shared
|
|
66
|
+
`EventStream` and rendered by `chat-view` in registration-priority order
|
|
67
|
+
(specific renderers before the fallback).
|
|
68
|
+
|
|
69
|
+
The built-in plugins (`text-delta`, `thinking-delta`, `tool-call`,
|
|
70
|
+
`tool-error`, `cost`, `chat-view`, `sessions-view`, `fallback`) are all
|
|
71
|
+
implemented through these same extension points — use them as references.
|
package/dist/app.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AgentMuxClient } from '@a5c-ai/agent-mux';
|
|
2
|
+
import type { TuiPlugin } from './plugin.js';
|
|
3
|
+
export interface AppProps {
|
|
4
|
+
client: AgentMuxClient;
|
|
5
|
+
plugins: TuiPlugin[];
|
|
6
|
+
defaultAgent?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function App({ client, plugins, defaultAgent }: AppProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
//# sourceMappingURL=app.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,mBAAmB,CAAC;AAEpE,OAAO,KAAK,EAAE,SAAS,EAA+B,MAAM,aAAa,CAAC;AAI1E,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAQD,wBAAgB,GAAG,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,YAA4B,EAAE,EAAE,QAAQ,2CAkH9E"}
|
package/dist/app.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo, useState } from 'react';
|
|
3
|
+
import { Box, Text, useInput, useApp } from 'ink';
|
|
4
|
+
import { createRegistry, createContext, loadPlugins } from './registry.js';
|
|
5
|
+
import { EventStream } from './event-stream.js';
|
|
6
|
+
import { PromptInput } from './prompt-input.js';
|
|
7
|
+
function pickRenderers(renderers, ev) {
|
|
8
|
+
const specific = renderers.find((r) => r.id !== 'fallback' && r.match(ev));
|
|
9
|
+
if (specific)
|
|
10
|
+
return specific;
|
|
11
|
+
return renderers.find((r) => r.id === 'fallback');
|
|
12
|
+
}
|
|
13
|
+
export function App({ client, plugins, defaultAgent = 'claude-code' }) {
|
|
14
|
+
const { exit } = useApp();
|
|
15
|
+
const [status, setStatus] = useState('');
|
|
16
|
+
const [activeId, setActiveId] = useState('chat');
|
|
17
|
+
const [promptMode, setPromptMode] = useState(false);
|
|
18
|
+
const { registry, stream } = useMemo(() => {
|
|
19
|
+
const r = createRegistry();
|
|
20
|
+
const s = new EventStream();
|
|
21
|
+
const ctx = createContext(client, r, (ev) => {
|
|
22
|
+
if (ev.type === 'status')
|
|
23
|
+
setStatus(ev.message);
|
|
24
|
+
if (ev.type === 'view:switch')
|
|
25
|
+
setActiveId(ev.id);
|
|
26
|
+
}, s);
|
|
27
|
+
void loadPlugins(plugins, ctx);
|
|
28
|
+
return { registry: r, stream: s };
|
|
29
|
+
}, [client, plugins]);
|
|
30
|
+
useInput((input, key) => {
|
|
31
|
+
if (promptMode)
|
|
32
|
+
return; // PromptInput owns keys while open
|
|
33
|
+
if (input === 'q' || (key.ctrl && input === 'c')) {
|
|
34
|
+
exit();
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (input === 'p') {
|
|
38
|
+
setPromptMode(true);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
for (const v of registry.views) {
|
|
42
|
+
if (v.hotkey && input === v.hotkey)
|
|
43
|
+
setActiveId(v.id);
|
|
44
|
+
}
|
|
45
|
+
for (const c of registry.commands) {
|
|
46
|
+
if (input === c.hotkey) {
|
|
47
|
+
void c.run({
|
|
48
|
+
client,
|
|
49
|
+
eventStream: stream,
|
|
50
|
+
registerView: () => { },
|
|
51
|
+
registerEventRenderer: () => { },
|
|
52
|
+
registerCommand: () => { },
|
|
53
|
+
registerPromptHandler: () => { },
|
|
54
|
+
emit: (e) => {
|
|
55
|
+
if (e.type === 'status')
|
|
56
|
+
setStatus(e.message);
|
|
57
|
+
if (e.type === 'event')
|
|
58
|
+
stream.push(e.event);
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
const active = registry.views.find((v) => v.id === activeId) ?? registry.views[0];
|
|
65
|
+
const ActiveView = active?.component;
|
|
66
|
+
// Inject renderers+stream into whichever view is active by using a thin wrapper.
|
|
67
|
+
const ViewWithRenderers = ActiveView
|
|
68
|
+
? (props) => {
|
|
69
|
+
const Wrapped = ActiveView;
|
|
70
|
+
return _jsx(Wrapped, { ...props, renderers: registry.renderers });
|
|
71
|
+
}
|
|
72
|
+
: undefined;
|
|
73
|
+
async function handlePromptSubmit(prompt) {
|
|
74
|
+
setPromptMode(false);
|
|
75
|
+
if (!prompt.trim())
|
|
76
|
+
return;
|
|
77
|
+
setStatus(`Dispatching to ${defaultAgent}…`);
|
|
78
|
+
// If a plugin registered a prompt handler, it wins.
|
|
79
|
+
if (registry.promptHandlers.length > 0) {
|
|
80
|
+
for (const h of registry.promptHandlers)
|
|
81
|
+
await h(prompt);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
const handle = client.run({ agent: defaultAgent, prompt });
|
|
86
|
+
for await (const ev of handle) {
|
|
87
|
+
stream.push(ev);
|
|
88
|
+
}
|
|
89
|
+
setStatus('Run complete.');
|
|
90
|
+
}
|
|
91
|
+
catch (e) {
|
|
92
|
+
setStatus(`Error: ${e.message}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { children: registry.views.map((v) => (_jsxs(Text, { color: v.id === active?.id ? 'green' : 'gray', children: ["[", v.hotkey ?? '?', "] ", v.title, ' '] }, v.id))) }), _jsx(Box, { borderStyle: "single", flexDirection: "column", paddingX: 1, children: ViewWithRenderers ? (_jsx(ViewWithRenderers, { client: client, active: true, eventStream: stream })) : (_jsx(Text, { dimColor: true, children: "No views registered." })) }), promptMode ? (_jsx(PromptInput, { onSubmit: handlePromptSubmit, onCancel: () => setPromptMode(false) })) : (_jsx(Box, { children: _jsx(Text, { dimColor: true, children: status || 'p: prompt · q: quit' }) }))] }));
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=app.js.map
|
package/dist/app.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"amux-tui.d.ts","sourceRoot":"","sources":["../../src/bin/amux-tui.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { render } from 'ink';
|
|
4
|
+
import { createClient } from '@a5c-ai/agent-mux';
|
|
5
|
+
import { App, builtinPlugins } from '../index.js';
|
|
6
|
+
const client = createClient();
|
|
7
|
+
render(_jsx(App, { client: client, plugins: builtinPlugins }));
|
|
8
|
+
//# sourceMappingURL=amux-tui.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"amux-tui.js","sourceRoot":"","sources":["../../src/bin/amux-tui.tsx"],"names":[],"mappings":";;AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,GAAG,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;AAC9B,MAAM,CAAC,KAAC,GAAG,IAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAI,CAAC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { AgentEvent } from '@a5c-ai/agent-mux';
|
|
2
|
+
export type EventSubscriber = (event: AgentEvent) => void;
|
|
3
|
+
export type Unsubscribe = () => void;
|
|
4
|
+
export declare class EventStream {
|
|
5
|
+
private subscribers;
|
|
6
|
+
private buffer;
|
|
7
|
+
private maxBuffer;
|
|
8
|
+
constructor(maxBuffer?: number);
|
|
9
|
+
subscribe(fn: EventSubscriber): Unsubscribe;
|
|
10
|
+
push(event: AgentEvent): void;
|
|
11
|
+
snapshot(): readonly AgentEvent[];
|
|
12
|
+
clear(): void;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=event-stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-stream.d.ts","sourceRoot":"","sources":["../src/event-stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;AAC1D,MAAM,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC;AAErC,qBAAa,WAAW;IACtB,OAAO,CAAC,WAAW,CAAmC;IACtD,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,SAAS,CAAS;gBAEd,SAAS,SAAO;IAI5B,SAAS,CAAC,EAAE,EAAE,eAAe,GAAG,WAAW;IAO3C,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAY7B,QAAQ,IAAI,SAAS,UAAU,EAAE;IAIjC,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export class EventStream {
|
|
2
|
+
subscribers = new Set();
|
|
3
|
+
buffer = [];
|
|
4
|
+
maxBuffer;
|
|
5
|
+
constructor(maxBuffer = 1000) {
|
|
6
|
+
this.maxBuffer = maxBuffer;
|
|
7
|
+
}
|
|
8
|
+
subscribe(fn) {
|
|
9
|
+
this.subscribers.add(fn);
|
|
10
|
+
return () => {
|
|
11
|
+
this.subscribers.delete(fn);
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
push(event) {
|
|
15
|
+
this.buffer.push(event);
|
|
16
|
+
if (this.buffer.length > this.maxBuffer)
|
|
17
|
+
this.buffer.shift();
|
|
18
|
+
for (const fn of this.subscribers) {
|
|
19
|
+
try {
|
|
20
|
+
fn(event);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
// subscriber errors must not break the stream
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
snapshot() {
|
|
28
|
+
return this.buffer.slice();
|
|
29
|
+
}
|
|
30
|
+
clear() {
|
|
31
|
+
this.buffer = [];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=event-stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-stream.js","sourceRoot":"","sources":["../src/event-stream.ts"],"names":[],"mappings":"AAKA,MAAM,OAAO,WAAW;IACd,WAAW,GAAyB,IAAI,GAAG,EAAE,CAAC;IAC9C,MAAM,GAAiB,EAAE,CAAC;IAC1B,SAAS,CAAS;IAE1B,YAAY,SAAS,GAAG,IAAI;QAC1B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED,SAAS,CAAC,EAAmB;QAC3B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzB,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC9B,CAAC,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,KAAiB;QACpB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS;YAAE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAC7D,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAClC,IAAI,CAAC;gBACH,EAAE,CAAC,KAAK,CAAC,CAAC;YACZ,CAAC;YAAC,MAAM,CAAC;gBACP,8CAA8C;YAChD,CAAC;QACH,CAAC;IACH,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;IACnB,CAAC;CACF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { App } from './app.js';
|
|
2
|
+
export { createRegistry, createContext, loadPlugins } from './registry.js';
|
|
3
|
+
export type { Registry } from './registry.js';
|
|
4
|
+
export { EventStream } from './event-stream.js';
|
|
5
|
+
export type { EventSubscriber, Unsubscribe } from './event-stream.js';
|
|
6
|
+
export { PromptInput } from './prompt-input.js';
|
|
7
|
+
export * from './plugin.js';
|
|
8
|
+
import type { TuiPlugin } from './plugin.js';
|
|
9
|
+
export declare const builtinPlugins: TuiPlugin[];
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC3E,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,cAAc,aAAa,CAAC;AAS5B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAI7C,eAAO,MAAM,cAAc,EAAE,SAAS,EAQrC,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export { App } from './app.js';
|
|
2
|
+
export { createRegistry, createContext, loadPlugins } from './registry.js';
|
|
3
|
+
export { EventStream } from './event-stream.js';
|
|
4
|
+
export { PromptInput } from './prompt-input.js';
|
|
5
|
+
export * from './plugin.js';
|
|
6
|
+
import textDelta from './plugins/text-delta.js';
|
|
7
|
+
import toolCall from './plugins/tool-call.js';
|
|
8
|
+
import cost from './plugins/cost.js';
|
|
9
|
+
import chatView from './plugins/chat-view.js';
|
|
10
|
+
import sessionsView from './plugins/sessions-view.js';
|
|
11
|
+
import fallback from './plugins/fallback.js';
|
|
12
|
+
import diff from './plugins/diff.js';
|
|
13
|
+
// Order matters: specific renderers first, fallback LAST so it only matches
|
|
14
|
+
// when nothing else did (chat-view's pickRenderers enforces this).
|
|
15
|
+
export const builtinPlugins = [
|
|
16
|
+
textDelta,
|
|
17
|
+
toolCall,
|
|
18
|
+
diff,
|
|
19
|
+
cost,
|
|
20
|
+
chatView,
|
|
21
|
+
sessionsView,
|
|
22
|
+
fallback,
|
|
23
|
+
];
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE3E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,cAAc,aAAa,CAAC;AAE5B,OAAO,SAAS,MAAM,yBAAyB,CAAC;AAChD,OAAO,QAAQ,MAAM,wBAAwB,CAAC;AAC9C,OAAO,IAAI,MAAM,mBAAmB,CAAC;AACrC,OAAO,QAAQ,MAAM,wBAAwB,CAAC;AAC9C,OAAO,YAAY,MAAM,4BAA4B,CAAC;AACtD,OAAO,QAAQ,MAAM,uBAAuB,CAAC;AAC7C,OAAO,IAAI,MAAM,mBAAmB,CAAC;AAGrC,4EAA4E;AAC5E,mEAAmE;AACnE,MAAM,CAAC,MAAM,cAAc,GAAgB;IACzC,SAAS;IACT,QAAQ;IACR,IAAI;IACJ,IAAI;IACJ,QAAQ;IACR,YAAY;IACZ,QAAQ;CACT,CAAC"}
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { ComponentType } from 'react';
|
|
2
|
+
import type { AgentMuxClient, AgentEvent, RunHandle } from '@a5c-ai/agent-mux';
|
|
3
|
+
import type { EventStream } from './event-stream.js';
|
|
4
|
+
export type PromptHandler = (prompt: string) => void | Promise<void>;
|
|
5
|
+
export interface TuiContext {
|
|
6
|
+
client: AgentMuxClient;
|
|
7
|
+
eventStream: EventStream;
|
|
8
|
+
registerView(view: TuiView): void;
|
|
9
|
+
registerEventRenderer(renderer: EventRenderer): void;
|
|
10
|
+
registerCommand(cmd: TuiCommand): void;
|
|
11
|
+
registerPromptHandler(handler: PromptHandler): void;
|
|
12
|
+
emit(event: TuiInternalEvent): void;
|
|
13
|
+
}
|
|
14
|
+
export interface TuiView {
|
|
15
|
+
id: string;
|
|
16
|
+
title: string;
|
|
17
|
+
hotkey?: string;
|
|
18
|
+
component: ComponentType<TuiViewProps>;
|
|
19
|
+
}
|
|
20
|
+
export interface TuiViewProps {
|
|
21
|
+
client: AgentMuxClient;
|
|
22
|
+
active: boolean;
|
|
23
|
+
eventStream: EventStream;
|
|
24
|
+
}
|
|
25
|
+
export interface EventRenderer {
|
|
26
|
+
id: string;
|
|
27
|
+
match(ev: AgentEvent): boolean;
|
|
28
|
+
component: ComponentType<{
|
|
29
|
+
event: AgentEvent;
|
|
30
|
+
}>;
|
|
31
|
+
}
|
|
32
|
+
export interface TuiCommand {
|
|
33
|
+
id: string;
|
|
34
|
+
hotkey: string;
|
|
35
|
+
label: string;
|
|
36
|
+
run(ctx: TuiContext): void | Promise<void>;
|
|
37
|
+
}
|
|
38
|
+
export type TuiInternalEvent = {
|
|
39
|
+
type: 'view:switch';
|
|
40
|
+
id: string;
|
|
41
|
+
} | {
|
|
42
|
+
type: 'run:attach';
|
|
43
|
+
handle: RunHandle;
|
|
44
|
+
} | {
|
|
45
|
+
type: 'status';
|
|
46
|
+
message: string;
|
|
47
|
+
} | {
|
|
48
|
+
type: 'event';
|
|
49
|
+
event: AgentEvent;
|
|
50
|
+
};
|
|
51
|
+
export interface TuiPlugin {
|
|
52
|
+
name: string;
|
|
53
|
+
version?: string;
|
|
54
|
+
register(ctx: TuiContext): void | Promise<void>;
|
|
55
|
+
}
|
|
56
|
+
export declare function definePlugin(plugin: TuiPlugin): TuiPlugin;
|
|
57
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAErE,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,cAAc,CAAC;IACvB,WAAW,EAAE,WAAW,CAAC;IACzB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,qBAAqB,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;IACrD,eAAe,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CAAC;IACvC,qBAAqB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC;IACpD,IAAI,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC;IAC/B,SAAS,EAAE,aAAa,CAAC;QAAE,KAAK,EAAE,UAAU,CAAA;KAAE,CAAC,CAAC;CACjD;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5C;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,CAAC;AAEzC,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,CAEzD"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAsDA,MAAM,UAAU,YAAY,CAAC,MAAiB;IAC5C,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type EventRenderer, type TuiViewProps } from '../plugin.js';
|
|
2
|
+
interface ChatViewInnerProps extends TuiViewProps {
|
|
3
|
+
renderers: EventRenderer[];
|
|
4
|
+
}
|
|
5
|
+
declare function ChatViewInner({ eventStream, renderers }: ChatViewInnerProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
declare const _default: import("../plugin.js").TuiPlugin;
|
|
7
|
+
export default _default;
|
|
8
|
+
export { ChatViewInner };
|
|
9
|
+
//# sourceMappingURL=chat-view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-view.d.ts","sourceRoot":"","sources":["../../src/plugins/chat-view.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAgB,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAEnF,UAAU,kBAAmB,SAAQ,YAAY;IAC/C,SAAS,EAAE,aAAa,EAAE,CAAC;CAC5B;AAED,iBAAS,aAAa,CAAC,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE,kBAAkB,2CA4BpE;;AAED,wBAYG;AAEH,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { Box, Text } from 'ink';
|
|
4
|
+
import { definePlugin } from '../plugin.js';
|
|
5
|
+
function ChatViewInner({ eventStream, renderers }) {
|
|
6
|
+
const [events, setEvents] = useState(() => [...eventStream.snapshot()]);
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
return eventStream.subscribe((ev) => {
|
|
9
|
+
setEvents((prev) => [...prev, ev]);
|
|
10
|
+
});
|
|
11
|
+
}, [eventStream]);
|
|
12
|
+
if (events.length === 0) {
|
|
13
|
+
return (_jsx(Box, { flexDirection: "column", children: _jsx(Text, { dimColor: true, children: "No messages yet. Press `p` to run a prompt." }) }));
|
|
14
|
+
}
|
|
15
|
+
const specific = renderers.filter((r) => r.id !== 'fallback');
|
|
16
|
+
const fallback = renderers.find((r) => r.id === 'fallback');
|
|
17
|
+
return (_jsx(Box, { flexDirection: "column", children: events.slice(-200).map((ev, i) => {
|
|
18
|
+
const r = specific.find((x) => x.match(ev)) ?? fallback;
|
|
19
|
+
const Comp = r?.component;
|
|
20
|
+
return Comp ? _jsx(Comp, { event: ev }, i) : null;
|
|
21
|
+
}) }));
|
|
22
|
+
}
|
|
23
|
+
export default definePlugin({
|
|
24
|
+
name: 'builtin:chat-view',
|
|
25
|
+
register(ctx) {
|
|
26
|
+
ctx.registerView({
|
|
27
|
+
id: 'chat',
|
|
28
|
+
title: 'Chat',
|
|
29
|
+
hotkey: '1',
|
|
30
|
+
component: (props) => (_jsx(ChatViewInner, { ...props, renderers: [] })),
|
|
31
|
+
});
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
export { ChatViewInner };
|
|
35
|
+
//# sourceMappingURL=chat-view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-view.js","sourceRoot":"","sources":["../../src/plugins/chat-view.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEhC,OAAO,EAAE,YAAY,EAAyC,MAAM,cAAc,CAAC;AAMnF,SAAS,aAAa,CAAC,EAAE,WAAW,EAAE,SAAS,EAAsB;IACnE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAe,GAAG,EAAE,CAAC,CAAC,GAAG,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IACtF,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,WAAW,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE;YAClC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAElB,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,CACL,KAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,YACzB,KAAC,IAAI,IAAC,QAAQ,kEAAmD,GAC7D,CACP,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,UAAU,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,UAAU,CAAC,CAAC;IAE5D,OAAO,CACL,KAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,YACxB,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE;YAChC,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,QAAQ,CAAC;YACxD,MAAM,IAAI,GAAG,CAAC,EAAE,SAAS,CAAC;YAC1B,OAAO,IAAI,CAAC,CAAC,CAAC,KAAC,IAAI,IAAS,KAAK,EAAE,EAAE,IAAZ,CAAC,CAAe,CAAC,CAAC,CAAC,IAAI,CAAC;QACnD,CAAC,CAAC,GACE,CACP,CAAC;AACJ,CAAC;AAED,eAAe,YAAY,CAAC;IAC1B,IAAI,EAAE,mBAAmB;IACzB,QAAQ,CAAC,GAAG;QACV,GAAG,CAAC,YAAY,CAAC;YACf,EAAE,EAAE,MAAM;YACV,KAAK,EAAE,MAAM;YACb,MAAM,EAAE,GAAG;YACX,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CACpB,KAAC,aAAa,OAAK,KAAK,EAAE,SAAS,EAAE,EAAE,GAAI,CAC5C;SACF,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC;AAEH,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost.d.ts","sourceRoot":"","sources":["../../src/plugins/cost.tsx"],"names":[],"mappings":";AAIA,wBAiBG"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Text } from 'ink';
|
|
3
|
+
import { definePlugin } from '../plugin.js';
|
|
4
|
+
export default definePlugin({
|
|
5
|
+
name: 'builtin:cost',
|
|
6
|
+
register(ctx) {
|
|
7
|
+
ctx.registerEventRenderer({
|
|
8
|
+
id: 'cost',
|
|
9
|
+
match: (ev) => ev.type === 'cost',
|
|
10
|
+
component: ({ event }) => event.type === 'cost' ? (_jsxs(Text, { color: "yellow", children: ["$", event.cost.totalUsd !== undefined
|
|
11
|
+
? event.cost.totalUsd.toFixed(4)
|
|
12
|
+
: '?'] })) : null,
|
|
13
|
+
});
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
//# sourceMappingURL=cost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost.js","sourceRoot":"","sources":["../../src/plugins/cost.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,eAAe,YAAY,CAAC;IAC1B,IAAI,EAAE,cAAc;IACpB,QAAQ,CAAC,GAAG;QACV,GAAG,CAAC,qBAAqB,CAAC;YACxB,EAAE,EAAE,MAAM;YACV,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,KAAK,MAAM;YACjC,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CACvB,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CACtB,MAAC,IAAI,IAAC,KAAK,EAAC,QAAQ,kBAEjB,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS;wBAChC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;wBAChC,CAAC,CAAC,GAAG,IACF,CACR,CAAC,CAAC,CAAC,IAAI;SACX,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { AgentEvent } from '@a5c-ai/agent-mux';
|
|
2
|
+
export declare function DiffRenderer({ event }: {
|
|
3
|
+
event: AgentEvent;
|
|
4
|
+
}): import("react/jsx-runtime").JSX.Element | null;
|
|
5
|
+
declare const _default: import("../plugin.js").TuiPlugin;
|
|
6
|
+
export default _default;
|
|
7
|
+
//# sourceMappingURL=diff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/plugins/diff.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGpD,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,UAAU,CAAA;CAAE,kDAiC5D;;AAED,wBASG"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
import { definePlugin } from '../plugin.js';
|
|
4
|
+
export function DiffRenderer({ event }) {
|
|
5
|
+
if (event.type !== 'file_patch')
|
|
6
|
+
return null;
|
|
7
|
+
const lines = event.diff.split('\n');
|
|
8
|
+
let adds = 0;
|
|
9
|
+
let dels = 0;
|
|
10
|
+
for (const line of lines) {
|
|
11
|
+
if (line.startsWith('+') && !line.startsWith('+++'))
|
|
12
|
+
adds++;
|
|
13
|
+
else if (line.startsWith('-') && !line.startsWith('---'))
|
|
14
|
+
dels++;
|
|
15
|
+
}
|
|
16
|
+
return (_jsxs(Box, { flexDirection: "column", marginY: 0, children: [_jsxs(Text, { children: [_jsxs(Text, { color: "magenta", children: ["\u25C6 ", event.path] }), ' ', _jsxs(Text, { color: "green", children: ["+", adds] }), ' ', _jsxs(Text, { color: "red", children: ["-", dels] })] }), lines.map((line, i) => {
|
|
17
|
+
if (line.startsWith('+++') || line.startsWith('---')) {
|
|
18
|
+
return _jsx(Text, { dimColor: true, children: line }, i);
|
|
19
|
+
}
|
|
20
|
+
if (line.startsWith('@@')) {
|
|
21
|
+
return _jsx(Text, { color: "cyan", children: line }, i);
|
|
22
|
+
}
|
|
23
|
+
if (line.startsWith('+')) {
|
|
24
|
+
return _jsx(Text, { color: "green", children: line }, i);
|
|
25
|
+
}
|
|
26
|
+
if (line.startsWith('-')) {
|
|
27
|
+
return _jsx(Text, { color: "red", children: line }, i);
|
|
28
|
+
}
|
|
29
|
+
return _jsx(Text, { children: line }, i);
|
|
30
|
+
})] }));
|
|
31
|
+
}
|
|
32
|
+
export default definePlugin({
|
|
33
|
+
name: 'builtin:diff',
|
|
34
|
+
register(ctx) {
|
|
35
|
+
ctx.registerEventRenderer({
|
|
36
|
+
id: 'file-patch',
|
|
37
|
+
match: (ev) => ev.type === 'file_patch',
|
|
38
|
+
component: DiffRenderer,
|
|
39
|
+
});
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
//# sourceMappingURL=diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/plugins/diff.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEhC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,UAAU,YAAY,CAAC,EAAE,KAAK,EAAyB;IAC3D,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY;QAAE,OAAO,IAAI,CAAC;IAC7C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;YAAE,IAAI,EAAE,CAAC;aACvD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;YAAE,IAAI,EAAE,CAAC;IACnE,CAAC;IACD,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,OAAO,EAAE,CAAC,aACpC,MAAC,IAAI,eACH,MAAC,IAAI,IAAC,KAAK,EAAC,SAAS,wBAAI,KAAK,CAAC,IAAI,IAAQ,EAAC,GAAG,EAC/C,MAAC,IAAI,IAAC,KAAK,EAAC,OAAO,kBAAG,IAAI,IAAQ,EAAC,GAAG,EACtC,MAAC,IAAI,IAAC,KAAK,EAAC,KAAK,kBAAG,IAAI,IAAQ,IAC3B,EACN,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;gBACrB,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;oBACrD,OAAO,KAAC,IAAI,IAAS,QAAQ,kBAAE,IAAI,IAAjB,CAAC,CAAwB,CAAC;gBAC9C,CAAC;gBACD,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC1B,OAAO,KAAC,IAAI,IAAS,KAAK,EAAC,MAAM,YAAE,IAAI,IAArB,CAAC,CAA4B,CAAC;gBAClD,CAAC;gBACD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;oBACzB,OAAO,KAAC,IAAI,IAAS,KAAK,EAAC,OAAO,YAAE,IAAI,IAAtB,CAAC,CAA6B,CAAC;gBACnD,CAAC;gBACD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;oBACzB,OAAO,KAAC,IAAI,IAAS,KAAK,EAAC,KAAK,YAAE,IAAI,IAApB,CAAC,CAA2B,CAAC;gBACjD,CAAC;gBACD,OAAO,KAAC,IAAI,cAAU,IAAI,IAAR,CAAC,CAAe,CAAC;YACrC,CAAC,CAAC,IACE,CACP,CAAC;AACJ,CAAC;AAED,eAAe,YAAY,CAAC;IAC1B,IAAI,EAAE,cAAc;IACpB,QAAQ,CAAC,GAAG;QACV,GAAG,CAAC,qBAAqB,CAAC;YACxB,EAAE,EAAE,YAAY;YAChB,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,KAAK,YAAY;YACvC,SAAS,EAAE,YAAY;SACxB,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { AgentEvent } from '@a5c-ai/agent-mux';
|
|
2
|
+
export declare function FallbackRenderer({ event }: {
|
|
3
|
+
event: AgentEvent;
|
|
4
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
declare const _default: import("../plugin.js").TuiPlugin;
|
|
6
|
+
export default _default;
|
|
7
|
+
//# sourceMappingURL=fallback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fallback.d.ts","sourceRoot":"","sources":["../../src/plugins/fallback.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGpD,wBAAgB,gBAAgB,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,UAAU,CAAA;CAAE,2CAMhE;;AAED,wBASG"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Text } from 'ink';
|
|
3
|
+
import { definePlugin } from '../plugin.js';
|
|
4
|
+
export function FallbackRenderer({ event }) {
|
|
5
|
+
return (_jsxs(Text, { dimColor: true, children: ["\u00B7 ", event.type] }));
|
|
6
|
+
}
|
|
7
|
+
export default definePlugin({
|
|
8
|
+
name: 'builtin:fallback',
|
|
9
|
+
register(ctx) {
|
|
10
|
+
ctx.registerEventRenderer({
|
|
11
|
+
id: 'fallback',
|
|
12
|
+
match: () => true,
|
|
13
|
+
component: FallbackRenderer,
|
|
14
|
+
});
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
//# sourceMappingURL=fallback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fallback.js","sourceRoot":"","sources":["../../src/plugins/fallback.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAE3B,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,UAAU,gBAAgB,CAAC,EAAE,KAAK,EAAyB;IAC/D,OAAO,CACL,MAAC,IAAI,IAAC,QAAQ,8BACT,KAAK,CAAC,IAAI,IACR,CACR,CAAC;AACJ,CAAC;AAED,eAAe,YAAY,CAAC;IAC1B,IAAI,EAAE,kBAAkB;IACxB,QAAQ,CAAC,GAAG;QACV,GAAG,CAAC,qBAAqB,CAAC;YACxB,EAAE,EAAE,UAAU;YACd,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI;YACjB,SAAS,EAAE,gBAAgB;SAC5B,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions-view.d.ts","sourceRoot":"","sources":["../../src/plugins/sessions-view.tsx"],"names":[],"mappings":";AAwCA,wBAUG"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { Box, Text } from 'ink';
|
|
4
|
+
import { definePlugin } from '../plugin.js';
|
|
5
|
+
function SessionsView({ client, active }) {
|
|
6
|
+
const [sessions, setSessions] = useState([]);
|
|
7
|
+
const [error, setError] = useState(null);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
if (!active)
|
|
10
|
+
return;
|
|
11
|
+
(async () => {
|
|
12
|
+
try {
|
|
13
|
+
const agents = ['claude-code', 'codex', 'gemini'];
|
|
14
|
+
const all = [];
|
|
15
|
+
for (const a of agents) {
|
|
16
|
+
try {
|
|
17
|
+
const list = await client.sessions.list(a);
|
|
18
|
+
for (const s of list)
|
|
19
|
+
all.push({ sessionId: s.sessionId, agent: a });
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// ignore per-agent listing errors
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
setSessions(all.slice(0, 20));
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
setError(String(e));
|
|
29
|
+
}
|
|
30
|
+
})();
|
|
31
|
+
}, [active, client]);
|
|
32
|
+
if (error)
|
|
33
|
+
return _jsx(Text, { color: "red", children: error });
|
|
34
|
+
if (sessions.length === 0)
|
|
35
|
+
return _jsx(Text, { dimColor: true, children: "No sessions found." });
|
|
36
|
+
return (_jsx(Box, { flexDirection: "column", children: sessions.map((s) => (_jsxs(Text, { children: [_jsx(Text, { color: "cyan", children: s.agent }), " ", s.sessionId] }, s.agent + ':' + s.sessionId))) }));
|
|
37
|
+
}
|
|
38
|
+
export default definePlugin({
|
|
39
|
+
name: 'builtin:sessions-view',
|
|
40
|
+
register(ctx) {
|
|
41
|
+
ctx.registerView({
|
|
42
|
+
id: 'sessions',
|
|
43
|
+
title: 'Sessions',
|
|
44
|
+
hotkey: '2',
|
|
45
|
+
component: SessionsView,
|
|
46
|
+
});
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
//# sourceMappingURL=sessions-view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions-view.js","sourceRoot":"","sources":["../../src/plugins/sessions-view.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,YAAY,EAAqB,MAAM,cAAc,CAAC;AAE/D,SAAS,YAAY,CAAC,EAAE,MAAM,EAAE,MAAM,EAAgB;IACpD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAyC,EAAE,CAAC,CAAC;IACrF,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IACxD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,CAAC,KAAK,IAAI,EAAE;YACV,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,CAAC,aAAa,EAAE,OAAO,EAAE,QAAQ,CAAU,CAAC;gBAC3D,MAAM,GAAG,GAA2C,EAAE,CAAC;gBACvD,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;oBACvB,IAAI,CAAC;wBACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;wBAC3C,KAAK,MAAM,CAAC,IAAI,IAAI;4BAAE,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;oBACvE,CAAC;oBAAC,MAAM,CAAC;wBACP,kCAAkC;oBACpC,CAAC;gBACH,CAAC;gBACD,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YAChC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YACtB,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;IACP,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACrB,IAAI,KAAK;QAAE,OAAO,KAAC,IAAI,IAAC,KAAK,EAAC,KAAK,YAAE,KAAK,GAAQ,CAAC;IACnD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAC,IAAI,IAAC,QAAQ,yCAA0B,CAAC;IAC3E,OAAO,CACL,KAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,YACxB,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACnB,MAAC,IAAI,eACH,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAAE,CAAC,CAAC,KAAK,GAAQ,OAAE,CAAC,CAAC,SAAS,KADvC,CAAC,CAAC,KAAK,GAAG,GAAG,GAAG,CAAC,CAAC,SAAS,CAE/B,CACR,CAAC,GACE,CACP,CAAC;AACJ,CAAC;AAED,eAAe,YAAY,CAAC;IAC1B,IAAI,EAAE,uBAAuB;IAC7B,QAAQ,CAAC,GAAG;QACV,GAAG,CAAC,YAAY,CAAC;YACf,EAAE,EAAE,UAAU;YACd,KAAK,EAAE,UAAU;YACjB,MAAM,EAAE,GAAG;YACX,SAAS,EAAE,YAAY;SACxB,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-delta.d.ts","sourceRoot":"","sources":["../../src/plugins/text-delta.tsx"],"names":[],"mappings":";AAIA,wBAoBG"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Text } from 'ink';
|
|
3
|
+
import { definePlugin } from '../plugin.js';
|
|
4
|
+
export default definePlugin({
|
|
5
|
+
name: 'builtin:text-delta',
|
|
6
|
+
register(ctx) {
|
|
7
|
+
ctx.registerEventRenderer({
|
|
8
|
+
id: 'text-delta',
|
|
9
|
+
match: (ev) => ev.type === 'text_delta',
|
|
10
|
+
component: ({ event }) => event.type === 'text_delta' ? _jsx(Text, { children: event.delta }) : null,
|
|
11
|
+
});
|
|
12
|
+
ctx.registerEventRenderer({
|
|
13
|
+
id: 'thinking-delta',
|
|
14
|
+
match: (ev) => ev.type === 'thinking_delta',
|
|
15
|
+
component: ({ event }) => event.type === 'thinking_delta' ? (_jsx(Text, { dimColor: true, italic: true, children: event.delta })) : null,
|
|
16
|
+
});
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
//# sourceMappingURL=text-delta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-delta.js","sourceRoot":"","sources":["../../src/plugins/text-delta.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,eAAe,YAAY,CAAC;IAC1B,IAAI,EAAE,oBAAoB;IAC1B,QAAQ,CAAC,GAAG;QACV,GAAG,CAAC,qBAAqB,CAAC;YACxB,EAAE,EAAE,YAAY;YAChB,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,KAAK,YAAY;YACvC,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CACvB,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,KAAC,IAAI,cAAE,KAAK,CAAC,KAAK,GAAQ,CAAC,CAAC,CAAC,IAAI;SAClE,CAAC,CAAC;QACH,GAAG,CAAC,qBAAqB,CAAC;YACxB,EAAE,EAAE,gBAAgB;YACpB,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,KAAK,gBAAgB;YAC3C,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CACvB,KAAK,CAAC,IAAI,KAAK,gBAAgB,CAAC,CAAC,CAAC,CAChC,KAAC,IAAI,IAAC,QAAQ,QAAC,MAAM,kBAClB,KAAK,CAAC,KAAK,GACP,CACR,CAAC,CAAC,CAAC,IAAI;SACX,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-call.d.ts","sourceRoot":"","sources":["../../src/plugins/tool-call.tsx"],"names":[],"mappings":";AAIA,wBAoCG"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
import { definePlugin } from '../plugin.js';
|
|
4
|
+
export default definePlugin({
|
|
5
|
+
name: 'builtin:tool-call',
|
|
6
|
+
register(ctx) {
|
|
7
|
+
ctx.registerEventRenderer({
|
|
8
|
+
id: 'tool-call-start',
|
|
9
|
+
match: (ev) => ev.type === 'tool_call_start',
|
|
10
|
+
component: ({ event }) => event.type === 'tool_call_start' ? (_jsx(Box, { children: _jsxs(Text, { color: "cyan", children: ["\u25B6 ", event.toolName] }) })) : null,
|
|
11
|
+
});
|
|
12
|
+
ctx.registerEventRenderer({
|
|
13
|
+
id: 'tool-result',
|
|
14
|
+
match: (ev) => ev.type === 'tool_result',
|
|
15
|
+
component: ({ event }) => event.type === 'tool_result' ? (_jsx(Box, { children: _jsxs(Text, { color: "green", children: ["\u2713 ", event.toolName, " (", event.durationMs, "ms)"] }) })) : null,
|
|
16
|
+
});
|
|
17
|
+
ctx.registerEventRenderer({
|
|
18
|
+
id: 'tool-error',
|
|
19
|
+
match: (ev) => ev.type === 'tool_error',
|
|
20
|
+
component: ({ event }) => event.type === 'tool_error' ? (_jsx(Box, { children: _jsxs(Text, { color: "red", children: ["\u2717 ", event.toolName, ": ", event.error] }) })) : null,
|
|
21
|
+
});
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
//# sourceMappingURL=tool-call.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-call.js","sourceRoot":"","sources":["../../src/plugins/tool-call.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,eAAe,YAAY,CAAC;IAC1B,IAAI,EAAE,mBAAmB;IACzB,QAAQ,CAAC,GAAG;QACV,GAAG,CAAC,qBAAqB,CAAC;YACxB,EAAE,EAAE,iBAAiB;YACrB,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,KAAK,iBAAiB;YAC5C,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CACvB,KAAK,CAAC,IAAI,KAAK,iBAAiB,CAAC,CAAC,CAAC,CACjC,KAAC,GAAG,cACF,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,wBAAI,KAAK,CAAC,QAAQ,IAAQ,GACxC,CACP,CAAC,CAAC,CAAC,IAAI;SACX,CAAC,CAAC;QACH,GAAG,CAAC,qBAAqB,CAAC;YACxB,EAAE,EAAE,aAAa;YACjB,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,KAAK,aAAa;YACxC,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CACvB,KAAK,CAAC,IAAI,KAAK,aAAa,CAAC,CAAC,CAAC,CAC7B,KAAC,GAAG,cACF,MAAC,IAAI,IAAC,KAAK,EAAC,OAAO,wBACd,KAAK,CAAC,QAAQ,QAAI,KAAK,CAAC,UAAU,WAChC,GACH,CACP,CAAC,CAAC,CAAC,IAAI;SACX,CAAC,CAAC;QACH,GAAG,CAAC,qBAAqB,CAAC;YACxB,EAAE,EAAE,YAAY;YAChB,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,KAAK,YAAY;YACvC,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CACvB,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,CAC5B,KAAC,GAAG,cACF,MAAC,IAAI,IAAC,KAAK,EAAC,KAAK,wBAAI,KAAK,CAAC,QAAQ,QAAI,KAAK,CAAC,KAAK,IAAQ,GACtD,CACP,CAAC,CAAC,CAAC,IAAI;SACX,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface PromptInputProps {
|
|
2
|
+
onSubmit: (value: string) => void;
|
|
3
|
+
onCancel: () => void;
|
|
4
|
+
label?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function PromptInput({ onSubmit, onCancel, label }: PromptInputProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=prompt-input.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-input.d.ts","sourceRoot":"","sources":["../src/prompt-input.tsx"],"names":[],"mappings":"AAGA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAkB,EAAE,EAAE,gBAAgB,2CA0BvF"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { Box, Text, useInput } from 'ink';
|
|
4
|
+
export function PromptInput({ onSubmit, onCancel, label = 'prompt> ' }) {
|
|
5
|
+
const [value, setValue] = useState('');
|
|
6
|
+
useInput((input, key) => {
|
|
7
|
+
if (key.escape) {
|
|
8
|
+
onCancel();
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
if (key.return) {
|
|
12
|
+
onSubmit(value);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (key.backspace || key.delete) {
|
|
16
|
+
setValue((v) => v.slice(0, -1));
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (input && !key.ctrl && !key.meta) {
|
|
20
|
+
setValue((v) => v + input);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: "cyan", children: label }), _jsx(Text, { children: value }), _jsx(Text, { color: "cyan", children: "\u258C" })] }));
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=prompt-input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-input.js","sourceRoot":"","sources":["../src/prompt-input.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAQ1C,MAAM,UAAU,WAAW,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,GAAG,UAAU,EAAoB;IACtF,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IACvC,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACf,QAAQ,EAAE,CAAC;YACX,OAAO;QACT,CAAC;QACD,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACf,QAAQ,CAAC,KAAK,CAAC,CAAC;YAChB,OAAO;QACT,CAAC;QACD,IAAI,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YAChC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAChC,OAAO;QACT,CAAC;QACD,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;YACpC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,CACL,MAAC,GAAG,eACF,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAAE,KAAK,GAAQ,EACjC,KAAC,IAAI,cAAE,KAAK,GAAQ,EACpB,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,uBAAS,IACvB,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { AgentMuxClient } from '@a5c-ai/agent-mux';
|
|
2
|
+
import type { EventStream } from './event-stream.js';
|
|
3
|
+
import type { EventRenderer, PromptHandler, TuiCommand, TuiContext, TuiInternalEvent, TuiPlugin, TuiView } from './plugin.js';
|
|
4
|
+
export interface Registry {
|
|
5
|
+
views: TuiView[];
|
|
6
|
+
renderers: EventRenderer[];
|
|
7
|
+
commands: TuiCommand[];
|
|
8
|
+
promptHandlers: PromptHandler[];
|
|
9
|
+
}
|
|
10
|
+
export declare function createRegistry(): Registry;
|
|
11
|
+
export declare function createContext(client: AgentMuxClient, registry: Registry, emit: (e: TuiInternalEvent) => void, eventStream: EventStream): TuiContext;
|
|
12
|
+
export declare function loadPlugins(plugins: TuiPlugin[], ctx: TuiContext): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,SAAS,EACT,OAAO,EACR,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,cAAc,EAAE,aAAa,EAAE,CAAC;CACjC;AAED,wBAAgB,cAAc,IAAI,QAAQ,CAEzC;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,cAAc,EACtB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,CAAC,CAAC,EAAE,gBAAgB,KAAK,IAAI,EACnC,WAAW,EAAE,WAAW,GACvB,UAAU,CAgBZ;AAED,wBAAsB,WAAW,CAC/B,OAAO,EAAE,SAAS,EAAE,EACpB,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,IAAI,CAAC,CAIf"}
|
package/dist/registry.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export function createRegistry() {
|
|
2
|
+
return { views: [], renderers: [], commands: [], promptHandlers: [] };
|
|
3
|
+
}
|
|
4
|
+
export function createContext(client, registry, emit, eventStream) {
|
|
5
|
+
return {
|
|
6
|
+
client,
|
|
7
|
+
eventStream,
|
|
8
|
+
registerView: (v) => registry.views.push(v),
|
|
9
|
+
registerEventRenderer: (r) => registry.renderers.push(r),
|
|
10
|
+
registerCommand: (c) => registry.commands.push(c),
|
|
11
|
+
registerPromptHandler: (h) => registry.promptHandlers.push(h),
|
|
12
|
+
emit: (e) => {
|
|
13
|
+
if (e.type === 'event') {
|
|
14
|
+
eventStream.push(e.event);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
emit(e);
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export async function loadPlugins(plugins, ctx) {
|
|
22
|
+
for (const p of plugins) {
|
|
23
|
+
await p.register(ctx);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAmBA,MAAM,UAAU,cAAc;IAC5B,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,MAAsB,EACtB,QAAkB,EAClB,IAAmC,EACnC,WAAwB;IAExB,OAAO;QACL,MAAM;QACN,WAAW;QACX,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3C,qBAAqB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QACxD,eAAe,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QACjD,qBAAqB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7D,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE;YACV,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBACvB,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;gBAC1B,OAAO;YACT,CAAC;YACD,IAAI,CAAC,CAAC,CAAC,CAAC;QACV,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,OAAoB,EACpB,GAAe;IAEf,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;AACH,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@a5c-ai/agent-mux-tui",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"description": "Extensible Ink-based TUI for agent-mux, with a plugin-first architecture",
|
|
7
|
+
"author": "a5c-ai",
|
|
8
|
+
"homepage": "https://github.com/a5c-ai/agent-mux#readme",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/a5c-ai/agent-mux.git",
|
|
12
|
+
"directory": "packages/tui"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/a5c-ai/agent-mux/issues"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"agent-mux",
|
|
19
|
+
"tui",
|
|
20
|
+
"ink",
|
|
21
|
+
"react",
|
|
22
|
+
"plugins"
|
|
23
|
+
],
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=20.9.0"
|
|
26
|
+
},
|
|
27
|
+
"bin": {
|
|
28
|
+
"amux-tui": "./dist/bin/amux-tui.js"
|
|
29
|
+
},
|
|
30
|
+
"main": "./dist/index.js",
|
|
31
|
+
"module": "./dist/index.js",
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
33
|
+
"exports": {
|
|
34
|
+
".": {
|
|
35
|
+
"import": {
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
37
|
+
"default": "./dist/index.js"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"./plugin": {
|
|
41
|
+
"import": {
|
|
42
|
+
"types": "./dist/plugin.d.ts",
|
|
43
|
+
"default": "./dist/plugin.js"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"files": [
|
|
48
|
+
"dist",
|
|
49
|
+
"README.md",
|
|
50
|
+
"LICENSE"
|
|
51
|
+
],
|
|
52
|
+
"publishConfig": {
|
|
53
|
+
"access": "public"
|
|
54
|
+
},
|
|
55
|
+
"scripts": {
|
|
56
|
+
"build": "tsc --build",
|
|
57
|
+
"start": "node ./dist/bin/amux-tui.js",
|
|
58
|
+
"dev": "npm run build && npm start",
|
|
59
|
+
"prepublishOnly": "npm run build",
|
|
60
|
+
"test": "vitest run --config ../../vitest.config.ts"
|
|
61
|
+
},
|
|
62
|
+
"dependencies": {
|
|
63
|
+
"@a5c-ai/agent-mux": "0.2.0",
|
|
64
|
+
"ink": "^5.0.1",
|
|
65
|
+
"react": "^18.3.1"
|
|
66
|
+
},
|
|
67
|
+
"devDependencies": {
|
|
68
|
+
"@types/react": "^18.3.3",
|
|
69
|
+
"ink-testing-library": "^4.0.0"
|
|
70
|
+
}
|
|
71
|
+
}
|