@redplanethq/corebrain 2.8.5 → 2.8.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/assets/assets/AppIcon.icns +0 -0
  2. package/dist/commands/coding/read.d.ts +0 -1
  3. package/dist/commands/coding/read.d.ts.map +1 -1
  4. package/dist/commands/coding/read.js +0 -11
  5. package/dist/commands/coding/read.js.map +1 -1
  6. package/dist/commands/gateway/start.d.ts.map +1 -1
  7. package/dist/commands/gateway/start.js +32 -2
  8. package/dist/commands/gateway/start.js.map +1 -1
  9. package/dist/server/tools/coding-tools.d.ts.map +1 -1
  10. package/dist/server/tools/coding-tools.js +0 -6
  11. package/dist/server/tools/coding-tools.js.map +1 -1
  12. package/dist/tui/chat.d.ts.map +1 -1
  13. package/dist/tui/chat.js +130 -46
  14. package/dist/tui/chat.js.map +1 -1
  15. package/dist/tui/components/dashboard-view.d.ts +20 -0
  16. package/dist/tui/components/dashboard-view.d.ts.map +1 -0
  17. package/dist/tui/components/dashboard-view.js +147 -0
  18. package/dist/tui/components/dashboard-view.js.map +1 -0
  19. package/dist/tui/components/status-line.d.ts +16 -0
  20. package/dist/tui/components/status-line.d.ts.map +1 -0
  21. package/dist/tui/components/status-line.js +38 -0
  22. package/dist/tui/components/status-line.js.map +1 -0
  23. package/dist/tui/components/widgets-view.d.ts +33 -0
  24. package/dist/tui/components/widgets-view.d.ts.map +1 -0
  25. package/dist/tui/components/widgets-view.js +270 -0
  26. package/dist/tui/components/widgets-view.js.map +1 -0
  27. package/dist/tui/hooks/use-conversation.d.ts +2 -0
  28. package/dist/tui/hooks/use-conversation.d.ts.map +1 -1
  29. package/dist/tui/hooks/use-conversation.js +18 -2
  30. package/dist/tui/hooks/use-conversation.js.map +1 -1
  31. package/dist/tui/utils/stream.d.ts +7 -1
  32. package/dist/tui/utils/stream.d.ts.map +1 -1
  33. package/dist/tui/utils/stream.js +16 -1
  34. package/dist/tui/utils/stream.js.map +1 -1
  35. package/dist/tui/utils/widget-loader.d.ts +4 -0
  36. package/dist/tui/utils/widget-loader.d.ts.map +1 -0
  37. package/dist/tui/utils/widget-loader.js +55 -0
  38. package/dist/tui/utils/widget-loader.js.map +1 -0
  39. package/dist/types/config.d.ts +12 -0
  40. package/dist/types/config.d.ts.map +1 -1
  41. package/package.json +3 -2
@@ -0,0 +1,20 @@
1
+ import type { Component, TUI } from '@mariozechner/pi-tui';
2
+ export declare class DashboardView implements Component {
3
+ private baseUrl;
4
+ private apiKey;
5
+ private tui;
6
+ private onRender;
7
+ private container;
8
+ private headerText;
9
+ private bodyContainer;
10
+ private bodyChildren;
11
+ onCancel?: () => void;
12
+ constructor(baseUrl: string, apiKey: string, tui: TUI, onRender: () => void);
13
+ private addToBody;
14
+ private load;
15
+ private loadAndRenderWidget;
16
+ handleInput(data: string): void;
17
+ render(width: number): string[];
18
+ invalidate(): void;
19
+ }
20
+ //# sourceMappingURL=dashboard-view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-view.d.ts","sourceRoot":"","sources":["../../../src/tui/components/dashboard-view.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,SAAS,EAAE,GAAG,EAAC,MAAM,sBAAsB,CAAC;AAgDzD,qBAAa,aAAc,YAAW,SAAS;IAS7C,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,QAAQ;IAXjB,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,UAAU,CAAO;IACzB,OAAO,CAAC,aAAa,CAAY;IACjC,OAAO,CAAC,YAAY,CAAmB;IAEvC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;gBAGb,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,MAAM,IAAI;IAkB7B,OAAO,CAAC,SAAS;YAKH,IAAI;YAuBJ,mBAAmB;IA+EjC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAM/B,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAI/B,UAAU,IAAI,IAAI;CAGlB"}
@@ -0,0 +1,147 @@
1
+ import { Text, Spacer, Container, Loader, matchesKey, Key } from '@mariozechner/pi-tui';
2
+ import chalk from 'chalk';
3
+ import { loadWidgetBundle } from '../utils/widget-loader.js';
4
+ import { getPreferences } from '../../config/preferences.js';
5
+ /** Wraps a pi-tui Component in a unicode border box */
6
+ class BoxedComponent {
7
+ inner;
8
+ title;
9
+ constructor(inner, title) {
10
+ this.inner = inner;
11
+ this.title = title;
12
+ }
13
+ render(width) {
14
+ const innerWidth = Math.max(0, width - 4);
15
+ const innerLines = this.inner.render(innerWidth);
16
+ const titleStr = ` ${this.title} `;
17
+ const topFill = Math.max(0, width - 4 - titleStr.length);
18
+ const top = '┌─' + titleStr + '─'.repeat(topFill) + '─┐';
19
+ const bottom = '└' + '─'.repeat(width - 2) + '┘';
20
+ const lines = [top];
21
+ for (const line of innerLines) {
22
+ // strip ANSI to measure visible length
23
+ const visible = line.replace(/\x1b\[[0-9;]*m/g, '');
24
+ const pad = Math.max(0, innerWidth - visible.length);
25
+ lines.push('│ ' + line + ' '.repeat(pad) + ' │');
26
+ }
27
+ lines.push(bottom);
28
+ return lines;
29
+ }
30
+ handleInput(data) {
31
+ this.inner.handleInput?.(data);
32
+ }
33
+ invalidate() {
34
+ this.inner.invalidate?.();
35
+ }
36
+ }
37
+ export class DashboardView {
38
+ baseUrl;
39
+ apiKey;
40
+ tui;
41
+ onRender;
42
+ container;
43
+ headerText;
44
+ bodyContainer;
45
+ bodyChildren = [];
46
+ onCancel;
47
+ constructor(baseUrl, apiKey, tui, onRender) {
48
+ this.baseUrl = baseUrl;
49
+ this.apiKey = apiKey;
50
+ this.tui = tui;
51
+ this.onRender = onRender;
52
+ this.container = new Container();
53
+ this.headerText = new Text(chalk.bold('Dashboard') + chalk.dim(' Esc close'), 1, 0);
54
+ this.bodyContainer = new Container();
55
+ this.container.addChild(new Spacer(1));
56
+ this.container.addChild(this.headerText);
57
+ this.container.addChild(new Spacer(1));
58
+ this.container.addChild(this.bodyContainer);
59
+ this.load();
60
+ }
61
+ addToBody(child) {
62
+ this.bodyChildren.push(child);
63
+ this.bodyContainer.addChild(child);
64
+ }
65
+ async load() {
66
+ const prefs = getPreferences();
67
+ const overviewWidgets = prefs.widgets?.overview ?? [];
68
+ if (overviewWidgets.length === 0) {
69
+ this.addToBody(new Text(chalk.dim('No overview widgets configured. Use /widgets to select widgets.'), 1, 0));
70
+ this.onRender();
71
+ return;
72
+ }
73
+ for (const config of overviewWidgets) {
74
+ await this.loadAndRenderWidget(config);
75
+ }
76
+ }
77
+ async loadAndRenderWidget(config) {
78
+ const spinner = new Loader(this.tui, s => chalk.cyan(s), s => chalk.dim(s), `Loading ${config.widgetName}...`);
79
+ spinner.start();
80
+ this.addToBody(spinner);
81
+ this.onRender();
82
+ try {
83
+ const mod = await loadWidgetBundle(config.widgetUrl);
84
+ const bundleWidgets = mod.widgets;
85
+ const widget = bundleWidgets.find(w => w.slug === config.widgetSlug);
86
+ spinner.stop();
87
+ try {
88
+ this.bodyContainer.removeChild(spinner);
89
+ }
90
+ catch {
91
+ /* ignore */
92
+ }
93
+ this.bodyChildren = this.bodyChildren.filter(c => c !== spinner);
94
+ if (!widget) {
95
+ this.addToBody(new Text(chalk.dim(`Widget "${config.widgetSlug}" not found in bundle`), 0, 1));
96
+ this.onRender();
97
+ return;
98
+ }
99
+ const ctx = {
100
+ placement: 'tui',
101
+ pat: this.apiKey,
102
+ accounts: [
103
+ {
104
+ id: config.accountId,
105
+ slug: config.accountSlug,
106
+ name: config.accountName,
107
+ },
108
+ ],
109
+ baseUrl: this.baseUrl,
110
+ requestRender: this.onRender,
111
+ };
112
+ const component = (await widget.render(ctx));
113
+ if (component && typeof component.render === 'function') {
114
+ const boxed = new BoxedComponent(component, config.widgetName);
115
+ this.addToBody(boxed);
116
+ this.addToBody(new Spacer(1));
117
+ }
118
+ }
119
+ catch (err) {
120
+ spinner.stop();
121
+ try {
122
+ this.bodyContainer.removeChild(spinner);
123
+ }
124
+ catch {
125
+ /* ignore */
126
+ }
127
+ this.bodyChildren = this.bodyChildren.filter(c => c !== spinner);
128
+ const msg = err instanceof Error ? err.message : String(err);
129
+ this.addToBody(new Text(chalk.dim(`─ ${config.widgetName} `) +
130
+ chalk.red('Error: ') +
131
+ chalk.dim(msg), 0, 1));
132
+ }
133
+ this.onRender();
134
+ }
135
+ handleInput(data) {
136
+ if (matchesKey(data, Key.escape)) {
137
+ this.onCancel?.();
138
+ }
139
+ }
140
+ render(width) {
141
+ return this.container.render(width);
142
+ }
143
+ invalidate() {
144
+ this.container.invalidate?.();
145
+ }
146
+ }
147
+ //# sourceMappingURL=dashboard-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-view.js","sourceRoot":"","sources":["../../../src/tui/components/dashboard-view.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { Component } from '@mariozechner/pi-tui';
2
+ /**
3
+ * Single-row status bar rendered below the editor.
4
+ * Left side: incognito badge (when active).
5
+ * Right side: first line of the below-input widget (when loaded).
6
+ * Returns [] when neither is active (no visible space consumed).
7
+ */
8
+ export declare class StatusLine implements Component {
9
+ private _incognito;
10
+ private _widget;
11
+ setIncognito(val: boolean): void;
12
+ setWidget(widget: Component | null): void;
13
+ render(width: number): string[];
14
+ invalidate(): void;
15
+ }
16
+ //# sourceMappingURL=status-line.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-line.d.ts","sourceRoot":"","sources":["../../../src/tui/components/status-line.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,sBAAsB,CAAC;AAGpD;;;;;GAKG;AACH,qBAAa,UAAW,YAAW,SAAS;IAC3C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,OAAO,CAA0B;IAEzC,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI;IAIhC,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,GAAG,IAAI;IAIzC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAmB/B,UAAU,IAAI,IAAI;CAGlB"}
@@ -0,0 +1,38 @@
1
+ import { visibleWidth, truncateToWidth } from '@mariozechner/pi-tui';
2
+ import chalk from 'chalk';
3
+ /**
4
+ * Single-row status bar rendered below the editor.
5
+ * Left side: incognito badge (when active).
6
+ * Right side: first line of the below-input widget (when loaded).
7
+ * Returns [] when neither is active (no visible space consumed).
8
+ */
9
+ export class StatusLine {
10
+ _incognito = false;
11
+ _widget = null;
12
+ setIncognito(val) {
13
+ this._incognito = val;
14
+ }
15
+ setWidget(widget) {
16
+ this._widget = widget;
17
+ }
18
+ render(width) {
19
+ const left = this._incognito
20
+ ? chalk.bgHex('#3a2a00').hex('#ffcc44')(' ⊘ incognito ')
21
+ : '';
22
+ let right = '';
23
+ if (this._widget) {
24
+ const lines = this._widget.render(width);
25
+ right = lines[0] ?? '';
26
+ }
27
+ if (!left && !right)
28
+ return [];
29
+ const leftW = visibleWidth(left);
30
+ const rightW = visibleWidth(right);
31
+ const gap = Math.max(1, width - leftW - rightW);
32
+ return [truncateToWidth(left + ' '.repeat(gap) + right, width)];
33
+ }
34
+ invalidate() {
35
+ this._widget?.invalidate?.();
36
+ }
37
+ }
38
+ //# sourceMappingURL=status-line.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-line.js","sourceRoot":"","sources":["../../../src/tui/components/status-line.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAE,eAAe,EAAC,MAAM,sBAAsB,CAAC;AAEnE,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B;;;;;GAKG;AACH,MAAM,OAAO,UAAU;IACd,UAAU,GAAG,KAAK,CAAC;IACnB,OAAO,GAAqB,IAAI,CAAC;IAEzC,YAAY,CAAC,GAAY;QACxB,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;IACvB,CAAC;IAED,SAAS,CAAC,MAAwB;QACjC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,MAAM,CAAC,KAAa;QACnB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU;YAC3B,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,eAAe,CAAC;YACxD,CAAC,CAAC,EAAE,CAAC;QAEN,IAAI,KAAK,GAAG,EAAE,CAAC;QACf,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACzC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACxB,CAAC;QAED,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,CAAC;QAE/B,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC,CAAC;QAChD,OAAO,CAAC,eAAe,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;IACjE,CAAC;IAED,UAAU;QACT,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC;IAC9B,CAAC;CACD"}
@@ -0,0 +1,33 @@
1
+ import type { Component, TUI } from '@mariozechner/pi-tui';
2
+ export declare class WidgetsView implements Component {
3
+ private baseUrl;
4
+ private apiKey;
5
+ private tui;
6
+ private onRender;
7
+ private container;
8
+ private headerText;
9
+ private bodyContainer;
10
+ private bodyChildren;
11
+ private tab;
12
+ private overviewOptions;
13
+ private belowInputOptions;
14
+ private cursor;
15
+ private loading;
16
+ private selectedBelowInput;
17
+ private selectedOverview;
18
+ onCancel?: () => void;
19
+ constructor(baseUrl: string, apiKey: string, tui: TUI, onRender: () => void);
20
+ private key;
21
+ private currentOptions;
22
+ private updateHeader;
23
+ private clearBody;
24
+ private addToBody;
25
+ private rebuildList;
26
+ private toggleCurrent;
27
+ private saveAndClose;
28
+ private load;
29
+ handleInput(data: string): void;
30
+ render(width: number): string[];
31
+ invalidate(): void;
32
+ }
33
+ //# sourceMappingURL=widgets-view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widgets-view.d.ts","sourceRoot":"","sources":["../../../src/tui/components/widgets-view.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,SAAS,EAAE,GAAG,EAAC,MAAM,sBAAsB,CAAC;AAuBzD,qBAAa,WAAY,YAAW,SAAS;IAmB3C,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,QAAQ;IArBjB,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,UAAU,CAAO;IACzB,OAAO,CAAC,aAAa,CAAY;IACjC,OAAO,CAAC,YAAY,CAAmB;IAEvC,OAAO,CAAC,GAAG,CAAsB;IACjC,OAAO,CAAC,eAAe,CAAsB;IAC7C,OAAO,CAAC,iBAAiB,CAAsB;IAC/C,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,OAAO,CAAS;IAGxB,OAAO,CAAC,kBAAkB,CAAuB;IACjD,OAAO,CAAC,gBAAgB,CAA0B;IAElD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;gBAGb,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,MAAM,IAAI;IAwB7B,OAAO,CAAC,GAAG;IAIX,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,YAAY;IAkBpB,OAAO,CAAC,SAAS;IAWjB,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,WAAW;IAqDnB,OAAO,CAAC,aAAa;IAmBrB,OAAO,CAAC,YAAY;YAmCN,IAAI;IAqElB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IA4C/B,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAI/B,UAAU,IAAI,IAAI;CAGlB"}
@@ -0,0 +1,270 @@
1
+ import { Text, Spacer, Container, Loader, matchesKey, Key } from '@mariozechner/pi-tui';
2
+ import chalk from 'chalk';
3
+ import { fetchIntegrationAccounts } from '../utils/stream.js';
4
+ import { getPreferences, updatePreferences } from '../../config/preferences.js';
5
+ export class WidgetsView {
6
+ baseUrl;
7
+ apiKey;
8
+ tui;
9
+ onRender;
10
+ container;
11
+ headerText;
12
+ bodyContainer;
13
+ bodyChildren = [];
14
+ tab = 'below-input';
15
+ overviewOptions = [];
16
+ belowInputOptions = [];
17
+ cursor = 0;
18
+ loading = false;
19
+ // Keys are `${widgetSlug}:${accountId}`
20
+ selectedBelowInput = null;
21
+ selectedOverview = new Set();
22
+ onCancel;
23
+ constructor(baseUrl, apiKey, tui, onRender) {
24
+ this.baseUrl = baseUrl;
25
+ this.apiKey = apiKey;
26
+ this.tui = tui;
27
+ this.onRender = onRender;
28
+ this.container = new Container();
29
+ this.headerText = new Text('', 1, 0);
30
+ this.bodyContainer = new Container();
31
+ this.container.addChild(new Spacer(1));
32
+ this.container.addChild(this.headerText);
33
+ this.container.addChild(new Spacer(1));
34
+ this.container.addChild(this.bodyContainer);
35
+ // Load saved selections from config
36
+ const prefs = getPreferences();
37
+ const saved = prefs.widgets ?? {};
38
+ if (saved.belowInput) {
39
+ this.selectedBelowInput = `${saved.belowInput.widgetSlug}:${saved.belowInput.accountId}`;
40
+ }
41
+ for (const w of saved.overview ?? []) {
42
+ this.selectedOverview.add(`${w.widgetSlug}:${w.accountId}`);
43
+ }
44
+ this.load();
45
+ }
46
+ key(option) {
47
+ return `${option.meta.slug}:${option.account.id}`;
48
+ }
49
+ currentOptions() {
50
+ return this.tab === 'below-input'
51
+ ? this.belowInputOptions
52
+ : this.overviewOptions;
53
+ }
54
+ updateHeader() {
55
+ const overview = this.tab === 'overview'
56
+ ? chalk.bgWhite.black(' Overview ')
57
+ : chalk.dim(' Overview ');
58
+ const belowInput = this.tab === 'below-input'
59
+ ? chalk.bgWhite.black(' Below Input ')
60
+ : chalk.dim(' Below Input ');
61
+ this.headerText.setText(overview +
62
+ ' ' +
63
+ belowInput +
64
+ chalk.dim(' Tab · ↑↓ · Space toggle · Esc save'));
65
+ }
66
+ clearBody() {
67
+ for (const child of this.bodyChildren) {
68
+ try {
69
+ this.bodyContainer.removeChild(child);
70
+ }
71
+ catch {
72
+ // ignore
73
+ }
74
+ }
75
+ this.bodyChildren = [];
76
+ }
77
+ addToBody(child) {
78
+ this.bodyChildren.push(child);
79
+ this.bodyContainer.addChild(child);
80
+ }
81
+ rebuildList() {
82
+ this.clearBody();
83
+ const options = this.currentOptions();
84
+ if (options.length === 0) {
85
+ this.addToBody(new Text(chalk.dim('No TUI widgets available.'), 1, 0));
86
+ this.onRender();
87
+ return;
88
+ }
89
+ // Clamp cursor
90
+ this.cursor = Math.max(0, Math.min(this.cursor, options.length - 1));
91
+ for (let i = 0; i < options.length; i++) {
92
+ const opt = options[i];
93
+ const k = this.key(opt);
94
+ const isHighlighted = i === this.cursor;
95
+ const isSelected = this.tab === 'below-input'
96
+ ? this.selectedBelowInput === k
97
+ : this.selectedOverview.has(k);
98
+ const checkbox = isSelected
99
+ ? chalk.green('[x]')
100
+ : chalk.dim('[ ]');
101
+ const label = isHighlighted
102
+ ? chalk.bold.white(opt.meta.name) +
103
+ chalk.dim(' · ' + opt.account.integrationDefinition.name)
104
+ : chalk.white(opt.meta.name) +
105
+ chalk.dim(' · ' + opt.account.integrationDefinition.name);
106
+ const prefix = isHighlighted ? chalk.cyan('▶ ') : ' ';
107
+ this.addToBody(new Text(prefix + checkbox + ' ' + label, 0, 0));
108
+ if (isHighlighted && opt.meta.description) {
109
+ this.addToBody(new Text(chalk.dim(' ' + opt.meta.description), 0, 0));
110
+ }
111
+ }
112
+ this.onRender();
113
+ }
114
+ toggleCurrent() {
115
+ const options = this.currentOptions();
116
+ if (options.length === 0)
117
+ return;
118
+ const opt = options[this.cursor];
119
+ const k = this.key(opt);
120
+ if (this.tab === 'below-input') {
121
+ this.selectedBelowInput = this.selectedBelowInput === k ? null : k;
122
+ }
123
+ else {
124
+ if (this.selectedOverview.has(k)) {
125
+ this.selectedOverview.delete(k);
126
+ }
127
+ else {
128
+ this.selectedOverview.add(k);
129
+ }
130
+ }
131
+ this.rebuildList();
132
+ }
133
+ saveAndClose() {
134
+ // Map options by key for fast lookup
135
+ const allOptions = [
136
+ ...this.belowInputOptions,
137
+ ...this.overviewOptions,
138
+ ];
139
+ const byKey = new Map(allOptions.map(o => [this.key(o), o]));
140
+ const toConfig = (opt) => ({
141
+ widgetSlug: opt.meta.slug,
142
+ widgetName: opt.meta.name,
143
+ widgetUrl: opt.widgetUrl,
144
+ accountId: opt.account.id,
145
+ accountSlug: opt.account.integrationDefinition.slug,
146
+ accountName: opt.account.integrationDefinition.name,
147
+ });
148
+ let belowInput = null;
149
+ if (this.selectedBelowInput) {
150
+ const opt = byKey.get(this.selectedBelowInput);
151
+ if (opt)
152
+ belowInput = toConfig(opt);
153
+ }
154
+ const overview = [];
155
+ for (const k of this.selectedOverview) {
156
+ const opt = byKey.get(k);
157
+ if (opt)
158
+ overview.push(toConfig(opt));
159
+ }
160
+ updatePreferences({ widgets: { belowInput, overview } });
161
+ this.onCancel?.();
162
+ }
163
+ async load() {
164
+ if (this.loading)
165
+ return;
166
+ this.loading = true;
167
+ this.updateHeader();
168
+ const loaderComp = new Loader(this.tui, s => chalk.cyan(s), s => chalk.dim(s), 'Loading widgets...');
169
+ loaderComp.start();
170
+ this.addToBody(loaderComp);
171
+ this.onRender();
172
+ try {
173
+ const accounts = await fetchIntegrationAccounts(this.baseUrl, this.apiKey);
174
+ loaderComp.stop();
175
+ try {
176
+ this.bodyContainer.removeChild(loaderComp);
177
+ }
178
+ catch {
179
+ /* ignore */
180
+ }
181
+ this.bodyChildren = this.bodyChildren.filter(c => c !== loaderComp);
182
+ for (const account of accounts) {
183
+ const def = account.integrationDefinition;
184
+ if (!def.widgetUrl)
185
+ continue;
186
+ const spec = def.spec;
187
+ const widgets = spec?.widgets ?? [];
188
+ for (const w of widgets) {
189
+ if (!w.support.includes('tui'))
190
+ continue;
191
+ const option = {
192
+ meta: w,
193
+ account,
194
+ widgetUrl: def.widgetUrl,
195
+ };
196
+ if (w.tuiPlacement === 'below-input') {
197
+ this.belowInputOptions.push(option);
198
+ }
199
+ else {
200
+ this.overviewOptions.push(option);
201
+ }
202
+ }
203
+ }
204
+ this.loading = false;
205
+ this.rebuildList();
206
+ }
207
+ catch (err) {
208
+ loaderComp.stop();
209
+ try {
210
+ this.bodyContainer.removeChild(loaderComp);
211
+ }
212
+ catch {
213
+ /* ignore */
214
+ }
215
+ this.bodyChildren = this.bodyChildren.filter(c => c !== loaderComp);
216
+ const msg = err instanceof Error ? err.message : String(err);
217
+ this.addToBody(new Text(chalk.red('Error: ') + chalk.dim(msg), 1, 0));
218
+ this.loading = false;
219
+ this.onRender();
220
+ }
221
+ }
222
+ handleInput(data) {
223
+ if (matchesKey(data, Key.escape)) {
224
+ this.saveAndClose();
225
+ return;
226
+ }
227
+ if (matchesKey(data, Key.tab)) {
228
+ this.tab = this.tab === 'below-input' ? 'overview' : 'below-input';
229
+ this.cursor = 0;
230
+ this.updateHeader();
231
+ this.rebuildList();
232
+ return;
233
+ }
234
+ if (matchesKey(data, Key.up)) {
235
+ const opts = this.currentOptions();
236
+ if (this.cursor > 0) {
237
+ this.cursor--;
238
+ this.rebuildList();
239
+ }
240
+ else {
241
+ this.cursor = Math.max(0, opts.length - 1);
242
+ this.rebuildList();
243
+ }
244
+ return;
245
+ }
246
+ if (matchesKey(data, Key.down)) {
247
+ const opts = this.currentOptions();
248
+ if (this.cursor < opts.length - 1) {
249
+ this.cursor++;
250
+ this.rebuildList();
251
+ }
252
+ else {
253
+ this.cursor = 0;
254
+ this.rebuildList();
255
+ }
256
+ return;
257
+ }
258
+ if (data === ' ' || matchesKey(data, Key.enter)) {
259
+ this.toggleCurrent();
260
+ return;
261
+ }
262
+ }
263
+ render(width) {
264
+ return this.container.render(width);
265
+ }
266
+ invalidate() {
267
+ this.container.invalidate?.();
268
+ }
269
+ }
270
+ //# sourceMappingURL=widgets-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widgets-view.js","sourceRoot":"","sources":["../../../src/tui/components/widgets-view.ts"],"names":[],"mappings":"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"}
@@ -5,12 +5,14 @@ export interface ConversationCallbacks {
5
5
  onRerender?: () => void;
6
6
  onStepFinish?: () => void;
7
7
  onFinish?: () => void;
8
+ onAbort?: () => void;
8
9
  onError?: (err: Error) => void;
9
10
  }
10
11
  export interface Conversation {
11
12
  readonly conversationId: string | null;
12
13
  readonly incognito: boolean;
13
14
  send(message: string, callbacks: ConversationCallbacks): Promise<void>;
15
+ abort(): void;
14
16
  clear(): void;
15
17
  resume(id: string): void;
16
18
  toggleIncognito(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"use-conversation.d.ts","sourceRoot":"","sources":["../../../src/tui/hooks/use-conversation.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,YAAY,EAAC,MAAM,iCAAiC,CAAC;AAI7D,MAAM,WAAW,qBAAqB;IACrC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IACrE,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE,KAAK,IAAI,IAAI,CAAC;IACd,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,eAAe,IAAI,IAAI,CAAC;CACxB;AAOD,wBAAgB,kBAAkB,CACjC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACZ,YAAY,CAwKd"}
1
+ {"version":3,"file":"use-conversation.d.ts","sourceRoot":"","sources":["../../../src/tui/hooks/use-conversation.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,YAAY,EAAC,MAAM,iCAAiC,CAAC;AAI7D,MAAM,WAAW,qBAAqB;IACrC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IACrE,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE,KAAK,IAAI,IAAI,CAAC;IACd,KAAK,IAAI,IAAI,CAAC;IACd,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,eAAe,IAAI,IAAI,CAAC;CACxB;AAOD,wBAAgB,kBAAkB,CACjC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACZ,YAAY,CA2Ld"}
@@ -6,6 +6,7 @@ const CONTAINER_TOOLS = new Set(['gather_context', 'take_action']);
6
6
  export function createConversation(baseUrl, apiKey) {
7
7
  let conversationId = null;
8
8
  let incognito = false;
9
+ let activeAbortController = null;
9
10
  return {
10
11
  get conversationId() {
11
12
  return conversationId;
@@ -13,6 +14,10 @@ export function createConversation(baseUrl, apiKey) {
13
14
  get incognito() {
14
15
  return incognito;
15
16
  },
17
+ abort() {
18
+ activeAbortController?.abort();
19
+ activeAbortController = null;
20
+ },
16
21
  clear() {
17
22
  conversationId = null;
18
23
  },
@@ -23,7 +28,8 @@ export function createConversation(baseUrl, apiKey) {
23
28
  incognito = !incognito;
24
29
  },
25
30
  async send(message, callbacks) {
26
- console.log(incognito);
31
+ const controller = new AbortController();
32
+ activeAbortController = controller;
27
33
  try {
28
34
  if (!conversationId) {
29
35
  conversationId = await createConversationApi(baseUrl, apiKey, message, incognito);
@@ -31,7 +37,7 @@ export function createConversation(baseUrl, apiKey) {
31
37
  const activeTools = new Map();
32
38
  // The currently-running container tool (gather_context / take_action)
33
39
  let activeParent = null;
34
- for await (const event of streamConversation(baseUrl, apiKey, conversationId, message)) {
40
+ for await (const event of streamConversation(baseUrl, apiKey, conversationId, message, controller.signal)) {
35
41
  switch (event.type) {
36
42
  case 'text-delta': {
37
43
  callbacks.onTextDelta(event.delta);
@@ -131,6 +137,11 @@ export function createConversation(baseUrl, apiKey) {
131
137
  callbacks.onFinish?.();
132
138
  }
133
139
  catch (err) {
140
+ // Aborted by user — not an error
141
+ if (err instanceof Error && err.name === 'AbortError') {
142
+ callbacks.onAbort?.();
143
+ return;
144
+ }
134
145
  const message = err instanceof Error ? err.message : String(err);
135
146
  // undici throws "terminated" when the server closes the SSE connection normally
136
147
  if (message === 'terminated') {
@@ -139,6 +150,11 @@ export function createConversation(baseUrl, apiKey) {
139
150
  }
140
151
  callbacks.onError?.(err instanceof Error ? err : new Error(message));
141
152
  }
153
+ finally {
154
+ if (activeAbortController === controller) {
155
+ activeAbortController = null;
156
+ }
157
+ }
142
158
  },
143
159
  };
144
160
  }