@jinion/cli 0.0.0-stage → 0.3.491

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 (171) hide show
  1. package/bin/jinion.js +4 -0
  2. package/dist/app/activity.js +50 -0
  3. package/dist/app/activity.js.map +1 -0
  4. package/dist/app/announcements.js +21 -0
  5. package/dist/app/announcements.js.map +1 -0
  6. package/dist/app/api.js +26 -0
  7. package/dist/app/api.js.map +1 -0
  8. package/dist/app/app.js +91 -0
  9. package/dist/app/app.js.map +1 -0
  10. package/dist/app/aside.js +52 -0
  11. package/dist/app/aside.js.map +1 -0
  12. package/dist/app/dialogs.js +43 -0
  13. package/dist/app/dialogs.js.map +1 -0
  14. package/dist/app/keys.js +79 -0
  15. package/dist/app/keys.js.map +1 -0
  16. package/dist/app/prompt-area.js +56 -0
  17. package/dist/app/prompt-area.js.map +1 -0
  18. package/dist/app/shortcuts.js +31 -0
  19. package/dist/app/shortcuts.js.map +1 -0
  20. package/dist/app/sidebar.js +50 -0
  21. package/dist/app/sidebar.js.map +1 -0
  22. package/dist/app/status-line.js +23 -0
  23. package/dist/app/status-line.js.map +1 -0
  24. package/dist/app/task-line.js +19 -0
  25. package/dist/app/task-line.js.map +1 -0
  26. package/dist/app/use-screen.js +24 -0
  27. package/dist/app/use-screen.js.map +1 -0
  28. package/dist/app/views.js +62 -0
  29. package/dist/app/views.js.map +1 -0
  30. package/dist/main.js +122 -0
  31. package/dist/main.js.map +1 -0
  32. package/dist/panels/account/account-picker.js +118 -0
  33. package/dist/panels/account/account-picker.js.map +1 -0
  34. package/dist/panels/account/describe.js +14 -0
  35. package/dist/panels/account/describe.js.map +1 -0
  36. package/dist/panels/account/sign-in-view.js +8 -0
  37. package/dist/panels/account/sign-in-view.js.map +1 -0
  38. package/dist/panels/account/use-sign-in.js +46 -0
  39. package/dist/panels/account/use-sign-in.js.map +1 -0
  40. package/dist/panels/context.js +55 -0
  41. package/dist/panels/context.js.map +1 -0
  42. package/dist/panels/diff/change-list.js +48 -0
  43. package/dist/panels/diff/change-list.js.map +1 -0
  44. package/dist/panels/diff/current-view.js +47 -0
  45. package/dist/panels/diff/current-view.js.map +1 -0
  46. package/dist/panels/diff/diff-panel.js +22 -0
  47. package/dist/panels/diff/diff-panel.js.map +1 -0
  48. package/dist/panels/diff/file-diff.js +19 -0
  49. package/dist/panels/diff/file-diff.js.map +1 -0
  50. package/dist/panels/diff/views.js +29 -0
  51. package/dist/panels/diff/views.js.map +1 -0
  52. package/dist/panels/feedback.js +67 -0
  53. package/dist/panels/feedback.js.map +1 -0
  54. package/dist/panels/help.js +79 -0
  55. package/dist/panels/help.js.map +1 -0
  56. package/dist/panels/mcp.js +129 -0
  57. package/dist/panels/mcp.js.map +1 -0
  58. package/dist/panels/memory.js +55 -0
  59. package/dist/panels/memory.js.map +1 -0
  60. package/dist/panels/mode.js +36 -0
  61. package/dist/panels/mode.js.map +1 -0
  62. package/dist/panels/model.js +20 -0
  63. package/dist/panels/model.js.map +1 -0
  64. package/dist/panels/onboarding/onboarding-panel.js +56 -0
  65. package/dist/panels/onboarding/onboarding-panel.js.map +1 -0
  66. package/dist/panels/onboarding/use-onboarding.js +65 -0
  67. package/dist/panels/onboarding/use-onboarding.js.map +1 -0
  68. package/dist/panels/profile.js +31 -0
  69. package/dist/panels/profile.js.map +1 -0
  70. package/dist/panels/resume.js +52 -0
  71. package/dist/panels/resume.js.map +1 -0
  72. package/dist/panels/rewind/changes.js +20 -0
  73. package/dist/panels/rewind/changes.js.map +1 -0
  74. package/dist/panels/rewind/rewind-panel.js +93 -0
  75. package/dist/panels/rewind/rewind-panel.js.map +1 -0
  76. package/dist/panels/sign-in/sign-in-panel.js +56 -0
  77. package/dist/panels/sign-in/sign-in-panel.js.map +1 -0
  78. package/dist/panels/sign-in/use-jinion-sign-in.js +69 -0
  79. package/dist/panels/sign-in/use-jinion-sign-in.js.map +1 -0
  80. package/dist/panels/statusline.js +94 -0
  81. package/dist/panels/statusline.js.map +1 -0
  82. package/dist/panels/tasks/output.js +23 -0
  83. package/dist/panels/tasks/output.js.map +1 -0
  84. package/dist/panels/tasks/task-output.js +29 -0
  85. package/dist/panels/tasks/task-output.js.map +1 -0
  86. package/dist/panels/tasks/tasks-panel.js +75 -0
  87. package/dist/panels/tasks/tasks-panel.js.map +1 -0
  88. package/dist/panels/terminal-setup.js +41 -0
  89. package/dist/panels/terminal-setup.js.map +1 -0
  90. package/dist/panels/usage/section.js +16 -0
  91. package/dist/panels/usage/section.js.map +1 -0
  92. package/dist/panels/usage/stats-view.js +52 -0
  93. package/dist/panels/usage/stats-view.js.map +1 -0
  94. package/dist/panels/usage/usage-panel.js +68 -0
  95. package/dist/panels/usage/usage-panel.js.map +1 -0
  96. package/dist/panels/usage/usage-view.js +51 -0
  97. package/dist/panels/usage/usage-view.js.map +1 -0
  98. package/dist/prompt/attachments.js +91 -0
  99. package/dist/prompt/attachments.js.map +1 -0
  100. package/dist/prompt/draft.js +24 -0
  101. package/dist/prompt/draft.js.map +1 -0
  102. package/dist/prompt/images.js +84 -0
  103. package/dist/prompt/images.js.map +1 -0
  104. package/dist/prompt/pasted-path.js +19 -0
  105. package/dist/prompt/pasted-path.js.map +1 -0
  106. package/dist/prompt/use-prompt.js +62 -0
  107. package/dist/prompt/use-prompt.js.map +1 -0
  108. package/dist/serve.js +38 -0
  109. package/dist/serve.js.map +1 -0
  110. package/dist/state/session.js +91 -0
  111. package/dist/state/session.js.map +1 -0
  112. package/dist/status/data.js +39 -0
  113. package/dist/status/data.js.map +1 -0
  114. package/dist/status/git.js +18 -0
  115. package/dist/status/git.js.map +1 -0
  116. package/dist/status/items.js +8 -0
  117. package/dist/status/items.js.map +1 -0
  118. package/dist/status/line.js +25 -0
  119. package/dist/status/line.js.map +1 -0
  120. package/dist/status/saved.js +8 -0
  121. package/dist/status/saved.js.map +1 -0
  122. package/dist/status/segment.js +2 -0
  123. package/dist/status/segment.js.map +1 -0
  124. package/dist/status/segments/conversation.js +71 -0
  125. package/dist/status/segments/conversation.js.map +1 -0
  126. package/dist/status/segments/git.js +33 -0
  127. package/dist/status/segments/git.js.map +1 -0
  128. package/dist/status/segments/identity.js +71 -0
  129. package/dist/status/segments/identity.js.map +1 -0
  130. package/dist/status/segments/index.js +27 -0
  131. package/dist/status/segments/index.js.map +1 -0
  132. package/dist/status/segments/usage.js +61 -0
  133. package/dist/status/segments/usage.js.map +1 -0
  134. package/dist/terminal/apple-terminal.js +68 -0
  135. package/dist/terminal/apple-terminal.js.map +1 -0
  136. package/dist/ui/banner.js +24 -0
  137. package/dist/ui/banner.js.map +1 -0
  138. package/dist/ui/entries/changes-card.js +27 -0
  139. package/dist/ui/entries/changes-card.js.map +1 -0
  140. package/dist/ui/entries/entry-view.js +82 -0
  141. package/dist/ui/entries/entry-view.js.map +1 -0
  142. package/dist/ui/entries/status-entries.js +33 -0
  143. package/dist/ui/entries/status-entries.js.map +1 -0
  144. package/dist/ui/entries/tools/agent-view.js +39 -0
  145. package/dist/ui/entries/tools/agent-view.js.map +1 -0
  146. package/dist/ui/entries/tools/mcp-view.js +10 -0
  147. package/dist/ui/entries/tools/mcp-view.js.map +1 -0
  148. package/dist/ui/entries/tools/result-preview.js +19 -0
  149. package/dist/ui/entries/tools/result-preview.js.map +1 -0
  150. package/dist/ui/entries/tools/search.js +42 -0
  151. package/dist/ui/entries/tools/search.js.map +1 -0
  152. package/dist/ui/entries/tools/shell-footer.js +36 -0
  153. package/dist/ui/entries/tools/shell-footer.js.map +1 -0
  154. package/dist/ui/entries/tools/tool-view.js +47 -0
  155. package/dist/ui/entries/tools/tool-view.js.map +1 -0
  156. package/dist/ui/entries/tools/web.js +41 -0
  157. package/dist/ui/entries/tools/web.js.map +1 -0
  158. package/dist/ui/modes.js +13 -0
  159. package/dist/ui/modes.js.map +1 -0
  160. package/dist/ui/task-marks.js +7 -0
  161. package/dist/ui/task-marks.js.map +1 -0
  162. package/dist/ui/use-async.js +17 -0
  163. package/dist/ui/use-async.js.map +1 -0
  164. package/dist/ui/use-pager.js +25 -0
  165. package/dist/ui/use-pager.js.map +1 -0
  166. package/dist/ui/use-project-files.js +18 -0
  167. package/dist/ui/use-project-files.js.map +1 -0
  168. package/dist/ui/use-workdir.js +9 -0
  169. package/dist/ui/use-workdir.js.map +1 -0
  170. package/package.json +34 -3
  171. package/README.md +0 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statusline.js","sourceRoot":"","sources":["../../src/panels/statusline.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { printable } from '@jinion/tui';
3
+ import { useApi } from '../../app/api.js';
4
+ const POLL_MS = 500;
5
+ /** The end of what task `id` wrote, read again while it runs; nothing for a task that writes none. */
6
+ export function useOutput(id, live) {
7
+ const api = useApi();
8
+ const [lines, setLines] = useState();
9
+ useEffect(() => {
10
+ if (id === undefined)
11
+ return;
12
+ let open = true;
13
+ const read = () => api.inSession('session/task-output', { task: id }).then((tail) => open && tail && setLines(printable(tail.join('\n')).split('\n')), () => { });
14
+ void read();
15
+ const timer = live ? setInterval(read, POLL_MS) : undefined;
16
+ return () => {
17
+ open = false;
18
+ clearInterval(timer);
19
+ };
20
+ }, [id, live]);
21
+ return lines;
22
+ }
23
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../../src/panels/tasks/output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,MAAM,OAAO,GAAG,GAAG,CAAC;AAEpB,sGAAsG;AACtG,MAAM,UAAU,SAAS,CAAC,EAAsB,EAAE,IAAa;IAC7D,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;IAErB,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,EAAY,CAAC;IAE/C,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,EAAE,KAAK,SAAS;YAAE,OAAO;QAE7B,IAAI,IAAI,GAAG,IAAI,CAAC;QAEhB,MAAM,IAAI,GAAG,GAAG,EAAE,CAChB,GAAG,CAAC,SAAS,CAAC,qBAAqB,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,CACrD,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI,IAAI,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAC1E,GAAG,EAAE,GAAE,CAAC,CACT,CAAC;QAEJ,KAAK,IAAI,EAAE,CAAC;QAEZ,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAE5D,OAAO,GAAG,EAAE;YACV,IAAI,GAAG,KAAK,CAAC;YACb,aAAa,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC;IAEf,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Panel, printable, Text, useInput, usePanel, useTheme } from '@jinion/tui';
3
+ import { useAtomValue } from 'jotai';
4
+ import { useApi } from '../../app/api.js';
5
+ import { tasksAtom } from '../../state/session.js';
6
+ import { firstLine } from '@jinion/core/lib/text';
7
+ import { PAGER_HINTS, usePager } from '../../ui/use-pager.js';
8
+ import { useOutput } from './output.js';
9
+ const CHROME_ROWS = 6;
10
+ export function TaskOutput({ id }) {
11
+ const api = useApi();
12
+ const theme = useTheme();
13
+ const { close } = usePanel();
14
+ const task = useAtomValue(tasksAtom).find((candidate) => candidate.id === id);
15
+ const lines = useOutput(id, task?.status === 'running') ?? [];
16
+ const pager = usePager(lines.length, { chrome: CHROME_ROWS, follow: true });
17
+ useInput((input, key) => {
18
+ if (key.escape)
19
+ return close();
20
+ if (input === 'x' && task?.status === 'running')
21
+ return api.act(api.inSession('session/stop-task', { task: task.id }));
22
+ pager.scroll(key);
23
+ });
24
+ if (!task)
25
+ return null;
26
+ const hints = [...PAGER_HINTS, ...(task.status === 'running' ? [['x', 'stop']] : []), ['Esc', 'back']];
27
+ return (_jsx(Panel, { title: "Output", subtitle: [printable(firstLine(task.title)), pager.range].filter(Boolean).join(' · '), grow: true, hints: hints, children: lines.length === 0 ? (_jsx(Text, { color: theme.muted, children: "No output yet." })) : (lines.slice(pager.top, pager.top + pager.view).map((line, index) => (_jsx(Text, { wrap: "truncate-end", children: line || ' ' }, pager.top + index)))) }));
28
+ }
29
+ //# sourceMappingURL=task-output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-output.js","sourceRoot":"","sources":["../../../src/panels/tasks/task-output.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, ChoiceList, choiceIndent, Panel, printable, StatusMark, Text, useAnimation, useChoiceList, useInput, usePanel, usePanels, useTheme, } from '@jinion/tui';
3
+ import { useAtomValue } from 'jotai';
4
+ import { backgroundTasksAtom } from '../../state/session.js';
5
+ import { useApi } from '../../app/api.js';
6
+ import { elapsed, plural } from '@jinion/core/lib/format';
7
+ import { firstLine } from '@jinion/core/lib/text';
8
+ import { TASK_MARKS } from '../../ui/task-marks.js';
9
+ import { useOutput } from './output.js';
10
+ import { TaskOutput } from './task-output.js';
11
+ const VISIBLE = 8;
12
+ const TAIL_LINES = 6;
13
+ export function TasksPanel() {
14
+ const api = useApi();
15
+ const theme = useTheme();
16
+ const { close } = usePanel();
17
+ const panels = usePanels();
18
+ const tasks = useAtomValue(backgroundTasksAtom);
19
+ useAnimation({ interval: 1000 });
20
+ const list = useChoiceList({
21
+ keys: tasks.map((task) => task.id),
22
+ mode: 'single',
23
+ onCancel: close,
24
+ onSubmit: ([id]) => {
25
+ const task = tasks.find((candidate) => candidate.id === id);
26
+ if (task?.output)
27
+ panels.open({ id: 'task-output', placement: 'fullscreen', element: _jsx(TaskOutput, { id: task.id }) });
28
+ },
29
+ });
30
+ const focused = tasks.find((task) => task.id === list.focus);
31
+ const choices = tasks.map((task) => ({
32
+ key: task.id,
33
+ label: (_jsxs(Text, { wrap: "truncate-end", children: [_jsx(StatusMark, { status: TASK_MARKS[task.status] }), " ", task.kind === 'agent' && _jsx(Text, { color: theme.muted, children: "Agent \u00B7 " }), printable(firstLine(task.title))] })),
34
+ aside: _jsx(TaskTime, { task: task }),
35
+ editor: _jsx(TaskDetails, { task: task, indent: choiceIndent(list) }),
36
+ }));
37
+ const hints = [
38
+ ...(focused?.output ? [['Enter', 'output']] : []),
39
+ ...(focused?.status === 'running' ? [['x', 'stop']] : []),
40
+ ['Up/Down', 'move'],
41
+ ['Esc', 'close'],
42
+ ];
43
+ const running = tasks.filter((task) => task.status === 'running').length;
44
+ useInput((input) => {
45
+ if (input === 'x' && focused?.status === 'running')
46
+ api.act(api.inSession('session/stop-task', { task: focused.id }));
47
+ });
48
+ return (_jsx(Panel, { title: "Background tasks", subtitle: tasks.length > 0 ? `${running} running` : undefined, hints: hints, children: _jsx(ChoiceList, { list: list, choices: choices, limit: VISIBLE, empty: "Nothing runs in the background. The agent starts commands there that keep running, like a dev server, and ctrl+b sends the command it waits for there." }) }));
49
+ }
50
+ function TaskTime({ task }) {
51
+ const theme = useTheme();
52
+ const took = elapsed((task.endedAt ?? Date.now()) - task.startedAt);
53
+ switch (task.status) {
54
+ case 'running':
55
+ return _jsx(Text, { color: theme.muted, children: took });
56
+ case 'completed':
57
+ return _jsxs(Text, { color: theme.muted, children: ["done in ", took] });
58
+ case 'failed':
59
+ return _jsxs(Text, { color: theme.error, children: ["failed after ", took] });
60
+ case 'stopped':
61
+ return _jsxs(Text, { color: theme.muted, children: ["stopped after ", took] });
62
+ }
63
+ }
64
+ function TaskDetails({ task, indent }) {
65
+ const theme = useTheme();
66
+ const lines = useOutput(task.output === undefined ? undefined : task.id, task.status === 'running');
67
+ if (task.kind === 'agent') {
68
+ return (_jsx(Box, { paddingLeft: indent, marginBottom: 1, children: _jsxs(Text, { color: theme.muted, wrap: "truncate-end", children: [plural(task.calls ?? 0, 'tool call'), task.lastCall && ` · ${task.lastCall}`] }) }));
69
+ }
70
+ if (!task.output)
71
+ return null;
72
+ const tail = lines?.slice(-TAIL_LINES) ?? [];
73
+ return (_jsx(Box, { flexDirection: "column", paddingLeft: indent, marginBottom: 1, children: tail.length === 0 ? (_jsx(Text, { color: theme.muted, children: lines ? 'No output yet.' : 'Reading the output…' })) : (tail.map((line, index) => (_jsx(Text, { color: theme.muted, wrap: "truncate-end", children: line || ' ' }, index)))) }));
74
+ }
75
+ //# sourceMappingURL=tasks-panel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks-panel.js","sourceRoot":"","sources":["../../../src/panels/tasks/tasks-panel.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect } from 'react';
3
+ import { ChoiceList, Panel, Text, useChoiceList, useInput, usePanel, useTheme } from '@jinion/tui';
4
+ import { errorMessage } from '@jinion/core/lib/errors';
5
+ import { useApi } from '../app/api.js';
6
+ import { inAppleTerminal, profilesWithoutMeta, rememberTerminalSetupOffered, turnOnOptionAsMeta } from '../terminal/apple-terminal.js';
7
+ import { useAsync } from '../ui/use-async.js';
8
+ const CHOICES = ['turn-on', 'not-now'];
9
+ export function TerminalSetupPanel() {
10
+ const api = useApi();
11
+ const theme = useTheme();
12
+ const { close } = usePanel();
13
+ const apple = inAppleTerminal();
14
+ const off = useAsync(() => (apple ? profilesWithoutMeta() : Promise.resolve([])), []);
15
+ const asking = off.state === 'done' && off.value.length > 0;
16
+ const list = useChoiceList({
17
+ keys: CHOICES,
18
+ mode: 'single',
19
+ isActive: asking,
20
+ onCancel: close,
21
+ onSubmit: ([choice]) => {
22
+ close();
23
+ if (choice !== 'turn-on')
24
+ return;
25
+ const notice = (text, tone) => api.act(api.inSession('session/notice', { text, tone }));
26
+ turnOnOptionAsMeta().then(() => notice('Done. Open a new Terminal window and Option+Delete will delete whole words.', 'muted'), (error) => notice(`Couldn’t update Terminal’s settings: ${errorMessage(error)}`, 'warning'));
27
+ },
28
+ });
29
+ // However it ends, it is offered once.
30
+ useEffect(() => rememberTerminalSetupOffered(), []);
31
+ useInput((_, key) => {
32
+ if (key.escape)
33
+ close();
34
+ }, { isActive: !asking });
35
+ const hints = asking ? [['Enter', 'continue'], ['Up/Down', 'move'], ['Esc', 'not now']] : [['Esc', 'close']];
36
+ return (_jsx(Panel, { title: "Terminal setup", subtitle: apple ? 'Terminal' : undefined, hints: hints, children: !apple ? (_jsx(Text, { color: theme.muted, children: "This only works in Terminal.app. In iTerm2, go to Settings \u2192 Profiles \u2192 Keys and set Left Option key to Esc+." })) : off.state === 'pending' ? (_jsx(Text, { color: theme.muted, children: "Checking your Terminal settings\u2026" })) : off.state === 'failed' ? (_jsxs(Text, { color: theme.error, children: ["Couldn\u2019t read your Terminal settings: ", off.error] })) : off.value.length === 0 ? (_jsx(Text, { color: theme.muted, children: "You\u2019re all set. Option+Delete already deletes whole words." })) : (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.muted, children: "In Terminal, Option+Delete only deletes one character. Jinion can turn on \u201CUse Option as Meta key\u201D for you so it deletes whole words, like everywhere else on your Mac. Option won\u2019t type special characters like \u00A9 in Terminal after that." }), _jsx(ChoiceList, { list: list, limit: CHOICES.length, choices: [
37
+ { key: 'turn-on', label: _jsx(Text, { children: "Turn it on" }) },
38
+ { key: 'not-now', label: _jsx(Text, { children: "Not now" }), description: 'You can do this later with /terminal-setup' },
39
+ ] })] })) }));
40
+ }
41
+ //# sourceMappingURL=terminal-setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-setup.js","sourceRoot":"","sources":["../../src/panels/terminal-setup.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text, useTheme } from '@jinion/tui';
3
+ import { compact } from '@jinion/core/lib/format';
4
+ export function Section({ title, aside, children }) {
5
+ const theme = useTheme();
6
+ return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Text, { wrap: "truncate-end", children: [_jsx(Text, { bold: true, children: title }), aside && _jsxs(Text, { color: theme.muted, children: [" ", aside] })] }), children] }));
7
+ }
8
+ export function tokenLine(tokens) {
9
+ const parts = [`${compact(tokens.input)} in`, `${compact(tokens.output)} out`, `${compact(tokens.cacheRead)} cache read`, `${compact(tokens.cacheWrite)} cache write`];
10
+ const split = tokens.input + tokens.output + tokens.cacheRead + tokens.cacheWrite;
11
+ if (!tokens.summarized)
12
+ return parts.join(' · ');
13
+ const summarized = `${compact(tokens.summarized)} from a summary of older days`;
14
+ return split > 0 ? `${parts.join(' · ')} · ${summarized}` : summarized;
15
+ }
16
+ //# sourceMappingURL=section.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"section.js","sourceRoot":"","sources":["../../../src/panels/usage/section.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAElD,MAAM,UAAU,OAAO,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAA0D;IACxG,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IAEzB,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,YAAY,EAAE,CAAC,aACzC,MAAC,IAAI,IAAC,IAAI,EAAC,cAAc,aACvB,KAAC,IAAI,IAAC,IAAI,kBAAE,KAAK,GAAQ,EACxB,KAAK,IAAI,MAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,kBAAI,KAAK,IAAQ,IAC9C,EACN,QAAQ,IACL,CACP,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,MAAmB;IAC3C,MAAM,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;IACvK,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC;IAClF,IAAI,CAAC,MAAM,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAEjD,MAAM,UAAU,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,+BAA+B,CAAC;IAEhF,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,UAAU,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC;AACzE,CAAC"}
@@ -0,0 +1,52 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useMemo, useState } from 'react';
3
+ import { BarList, Box, dayKey, Heatmap, parseDay, StatGrid, Text, useDayCursor, useInput, useTheme, useWindowSize } from '@jinion/tui';
4
+ import { useAtomValue } from 'jotai';
5
+ import { compact, grouped, plural, shortDate, span } from '@jinion/core/lib/format';
6
+ import { RANGES, totalOf, usageStats } from '@jinion/core/usage/stats';
7
+ import { agentAtom } from '../../state/session.js';
8
+ import { tokenLine } from './section.js';
9
+ const SHARE_BAR = 16;
10
+ const STATS_ROWS = 30;
11
+ export function StatsView({ history, progress, error, available }) {
12
+ const backend = useAtomValue(agentAtom);
13
+ const theme = useTheme();
14
+ const { rows } = useWindowSize();
15
+ const [range, setRange] = useState('all');
16
+ const today = new Date();
17
+ const [day] = useDayCursor(today, { earliest: history?.days[0]?.date });
18
+ const stats = useMemo(() => history && usageStats(history, range), [history, range]);
19
+ const values = useMemo(() => Object.fromEntries((history?.days ?? []).map((item) => [item.date, item.messages])), [history]);
20
+ useInput((input) => {
21
+ if (input === 'r')
22
+ setRange((current) => RANGES[(RANGES.findIndex((candidate) => candidate.range === current) + 1) % RANGES.length].range);
23
+ });
24
+ if (!available)
25
+ return _jsxs(Text, { color: theme.muted, children: [backend.name, " keeps no history of its use."] });
26
+ if (error)
27
+ return _jsxs(Text, { color: theme.error, children: ["Couldn't read the history: ", error] });
28
+ if (!history || !stats) {
29
+ const [done = 0, total = 0] = progress ?? [];
30
+ return (_jsxs(Text, { color: theme.muted, children: ["Reading ", backend.name, "'s conversations on this machine\u2026", total > 0 && ` ${grouped(done)} of ${grouped(total)}`] }));
31
+ }
32
+ const picked = history.days.find((item) => item.date === day);
33
+ const models = stats.models.slice(0, Math.max(1, Math.floor((rows - STATS_ROWS) / 2)));
34
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { children: RANGES.map((option, index) => (_jsxs(Text, { children: [index > 0 && _jsx(Text, { color: theme.muted, children: " \u00B7 " }), option.range === range ? (_jsx(Text, { color: theme.accent, bold: true, children: option.label })) : (_jsx(Text, { color: theme.muted, children: option.label }))] }, option.range))) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Heatmap, { values: values, end: today, selected: day, legend: true }), _jsxs(Text, { children: [shortDate(parseDay(day)), day === dayKey(today) && _jsx(Text, { color: theme.muted, children: " (today)" }), _jsxs(Text, { color: theme.muted, children: [' · ', picked && picked.messages > 0
35
+ ? `${plural(picked.messages, 'message')} · ${plural(picked.sessions, 'session')} · ${compact(Object.values(picked.models).reduce((sum, tokens) => sum + totalOf(tokens), 0))} tokens`
36
+ : 'nothing'] })] })] }), stats.activeDays === 0 ? (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: theme.muted, children: "Nothing in this range yet." }) })) : (_jsxs(_Fragment, { children: [_jsx(Box, { marginTop: 1, children: _jsx(StatGrid, { stats: [
37
+ { label: 'Favorite model', value: _jsx(Text, { color: theme.accent, children: stats.models[0]?.name ?? '-' }) },
38
+ { label: 'Tokens', value: _jsx(Text, { color: theme.accent, children: compact(stats.tokens.total) }) },
39
+ { label: 'Sessions', value: grouped(stats.sessions) },
40
+ { label: 'Longest session', value: stats.longestSession ? span(stats.longestSession.ms) : '-' },
41
+ { label: 'Active days', value: grouped(stats.activeDays), detail: `of ${grouped(stats.spanDays)}` },
42
+ { label: 'Longest streak', value: plural(stats.longestStreak, 'day') },
43
+ { label: 'Most active day', value: stats.mostActive ? shortDate(parseDay(stats.mostActive.date)) : '-' },
44
+ { label: 'Current streak', value: plural(stats.currentStreak, 'day') },
45
+ ] }) }), _jsx(Text, { color: theme.muted, children: tokenLine(stats.tokens) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(BarList, { width: SHARE_BAR, bars: models.map((model) => ({
46
+ label: model.name,
47
+ value: model.share,
48
+ text: (_jsxs(Text, { children: [`${(model.share * 100).toFixed(1)}%`.padStart(6), _jsxs(Text, { color: theme.muted, children: [" ", compact(model.total)] })] })),
49
+ detail: tokenLine(model.tokens),
50
+ })) }), stats.models.length > models.length && _jsxs(Text, { color: theme.muted, children: ["\u2026 ", plural(stats.models.length - models.length, 'more model')] })] })] }))] }));
51
+ }
52
+ //# sourceMappingURL=stats-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats-view.js","sourceRoot":"","sources":["../../../src/panels/usage/stats-view.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useState } from 'react';
3
+ import { Panel, Tabs, useInput, usePanel, useTabs } from '@jinion/tui';
4
+ import { errorMessage } from '@jinion/core/lib/errors';
5
+ import { useAtomValue } from 'jotai';
6
+ import { useApi } from '../../app/api.js';
7
+ import { agentAtom } from '../../state/session.js';
8
+ import { StatsView } from './stats-view.js';
9
+ import { UsageView } from './usage-view.js';
10
+ const TABS = ['Usage', 'Stats'];
11
+ const HINTS = {
12
+ usage: [
13
+ ['Tab', 'stats'],
14
+ ['d/w', 'last day or week'],
15
+ ['Esc', 'close'],
16
+ ],
17
+ stats: [
18
+ ['Tab', 'usage'],
19
+ ['Arrows', 'pick a day'],
20
+ ['r', 'range'],
21
+ ['Esc', 'close'],
22
+ ],
23
+ };
24
+ export function UsagePanel({ tab = 'usage' }) {
25
+ const agent = useAtomValue(agentAtom);
26
+ const { close } = usePanel();
27
+ const [active] = useTabs(TABS.length, { initial: tab === 'stats' ? 1 : 0, arrows: false });
28
+ const loaded = useUsage(agent.features);
29
+ useInput((_, key) => {
30
+ if (key.escape)
31
+ close();
32
+ });
33
+ return (_jsx(Panel, { title: "Usage", subtitle: agent.name, header: _jsx(Tabs, { tabs: [...TABS], active: active }), grow: true, hints: HINTS[active === 0 ? 'usage' : 'stats'], children: active === 0 ? (_jsx(UsageView, { usage: loaded.usage, error: loaded.usageError, available: agent.features.usage })) : (_jsx(StatsView, { history: loaded.history, progress: loaded.progress, error: loaded.historyError, available: agent.features.history })) }));
34
+ }
35
+ /** Both tabs load at once, so switching shows what is already there. */
36
+ function useUsage(features) {
37
+ const api = useApi();
38
+ const [usage, setUsage] = useState();
39
+ const [usageError, setUsageError] = useState();
40
+ const [history, setHistory] = useState();
41
+ const [progress, setProgress] = useState();
42
+ const [historyError, setHistoryError] = useState();
43
+ useEffect(() => {
44
+ let open = true;
45
+ const failed = (set) => (error) => open && set(errorMessage(error));
46
+ // The limits come quickly; what adds to them takes a look through the week's conversations.
47
+ if (features.usage) {
48
+ api
49
+ .request('usage/limits', { drivers: false })
50
+ .then((quick) => {
51
+ if (!open)
52
+ return;
53
+ setUsage(quick);
54
+ return api.request('usage/limits', { drivers: true }).then((full) => open && setUsage(full));
55
+ })
56
+ .catch(failed(setUsageError));
57
+ }
58
+ const stopProgress = api.client.on('usage/history-progress', ({ done, total }) => open && setProgress([done, total]));
59
+ if (features.history)
60
+ api.request('usage/history', {}).then((days) => open && setHistory(days), failed(setHistoryError));
61
+ return () => {
62
+ open = false;
63
+ stopProgress();
64
+ };
65
+ }, []);
66
+ return { usage, usageError, history, progress, historyError };
67
+ }
68
+ //# sourceMappingURL=usage-panel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-panel.js","sourceRoot":"","sources":["../../../src/panels/usage/usage-panel.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { BarList, Box, Meter, Text, useInput, useTheme } from '@jinion/tui';
4
+ import { useAtomValue } from 'jotai';
5
+ import { grouped, money, plural, resetTime, span } from '@jinion/core/lib/format';
6
+ import { agentAtom, identityAtom } from '../../state/session.js';
7
+ import { Section, tokenLine } from './section.js';
8
+ const LIMIT_BAR = 28;
9
+ const SHARE_BAR = 16;
10
+ const TRAITS = {
11
+ subagents: ['Subagent-heavy', 'each subagent makes requests of its own'],
12
+ 'long-context': ['Long context', 'requests past 150k tokens; /clear between tasks keeps them small'],
13
+ 'cache-misses': ['Cache misses', 'requests that missed the prompt cache, e.g. after an hour away'],
14
+ parallel: ['Parallel', 'while four or more sessions ran at once'],
15
+ scheduled: ['Scheduled', 'from scheduled or looping sessions'],
16
+ };
17
+ const SOURCE_KINDS = { skill: 'skill', agent: 'subagent', plugin: 'plugin', mcp: 'MCP' };
18
+ export function UsageView({ usage, error, available }) {
19
+ const backend = useAtomValue(agentAtom);
20
+ const theme = useTheme();
21
+ const plan = useAtomValue(identityAtom)?.plan;
22
+ const [window, setWindow] = useState('day');
23
+ useInput((input) => {
24
+ if (input === 'd')
25
+ setWindow('day');
26
+ if (input === 'w')
27
+ setWindow('week');
28
+ });
29
+ if (!available)
30
+ return _jsxs(Text, { color: theme.muted, children: [backend.name, " doesn't report its usage."] });
31
+ if (error)
32
+ return _jsxs(Text, { color: theme.error, children: ["Couldn't ask ", backend.name, " for its usage: ", error] });
33
+ if (!usage)
34
+ return _jsxs(Text, { color: theme.muted, children: ["Asking ", backend.name, " for its usage\u2026"] });
35
+ const { session, limits, extra, drivers } = usage;
36
+ const labelWidth = Math.max(0, ...limits.map((limit) => limit.label.length)) + 2;
37
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Section, { title: "Plan limits", aside: plan, children: [limits.length === 0 ? (_jsx(Text, { color: theme.muted, children: "This login has no plan limits, e.g. an API key." })) : (limits.map((limit) => (_jsxs(Text, { children: [limit.label.padEnd(labelWidth), _jsx(Meter, { value: limit.used, width: LIMIT_BAR }), " ", `${Math.round(limit.used * 100)}%`.padStart(4), limit.resetsAt !== undefined && _jsxs(Text, { color: theme.muted, children: [" resets ", resetTime(limit.resetsAt)] })] }, limit.label)))), extra && (_jsxs(Text, { color: theme.muted, children: ["Extra usage ", money(extra.used, extra.currency), extra.limit !== undefined && ` of ${money(extra.limit, extra.currency)}`, " this month"] }))] }), session && (_jsx(Section, { title: "This session", aside: `${money(session.cost)} · ${span(session.apiMs)} waiting on the model · ${span(session.wallMs)} in all · +${grouped(session.linesAdded)} -${grouped(session.linesRemoved)} lines`, children: session.models.length === 0 ? (_jsx(Text, { color: theme.muted, children: "No requests yet." })) : (session.models.map((model, _, models) => (_jsxs(Text, { wrap: "truncate-end", children: [model.name.padEnd(Math.max(...models.map((other) => other.name.length)) + 2), _jsx(Text, { color: theme.muted, children: tokenLine(model).padEnd(Math.max(...models.map((other) => tokenLine(other).length)) + 2) }), money(model.cost)] }, model.name)))) })), _jsx(Section, { title: `What adds to your limits · last ${window === 'day' ? '24 hours' : '7 days'}`, children: _jsx(Drivers, { drivers: drivers?.[window], loading: !drivers }) })] }));
38
+ }
39
+ function Drivers({ drivers, loading }) {
40
+ const theme = useTheme();
41
+ if (loading)
42
+ return _jsx(Text, { color: theme.muted, children: "Looking through this week's conversations on this machine\u2026" });
43
+ if (!drivers || drivers.requests === 0)
44
+ return _jsx(Text, { color: theme.muted, children: "Nothing in this time on this machine." });
45
+ return (_jsxs(_Fragment, { children: [_jsxs(Text, { color: theme.muted, children: [plural(drivers.requests, 'request'), " in ", plural(drivers.sessions, 'session'), " on this machine, roughly. The traits overlap, so they don't add up."] }), _jsx(Box, { marginTop: 1, children: _jsx(BarList, { width: SHARE_BAR, bars: drivers.traits.map(({ trait, share }) => ({
46
+ label: TRAITS[trait][0],
47
+ value: share,
48
+ text: (_jsxs(Text, { children: [`${Math.round(share * 100)}%`.padStart(4), _jsxs(Text, { color: theme.muted, children: [" ", TRAITS[trait][1]] })] })),
49
+ })) }) }), drivers.sources.length > 0 && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { wrap: "truncate-end", children: [_jsx(Text, { color: theme.muted, children: "Most used: " }), drivers.sources.slice(0, 5).map((source, index) => (_jsxs(Text, { children: [index > 0 && _jsx(Text, { color: theme.muted, children: " \u00B7 " }), source.name, _jsxs(Text, { color: theme.muted, children: [' ', SOURCE_KINDS[source.kind], " ", Math.round(source.share * 100), "%"] })] }, `${source.kind}:${source.name}`)))] }) }))] }));
50
+ }
51
+ //# sourceMappingURL=usage-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-view.js","sourceRoot":"","sources":["../../../src/panels/usage/usage-view.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ import { realpathSync } from 'node:fs';
2
+ import { basename, isAbsolute, relative } from 'node:path';
3
+ import { createContext, useContext } from 'react';
4
+ import { PastedFiles, PastedImages, PastedTexts } from '@jinion/tui/chat';
5
+ import { attachmentKind } from '@jinion/core/attachments/kinds';
6
+ import { errorMessage } from '@jinion/core/lib/errors';
7
+ import { clipboardImage, imageFromPaste } from './images.js';
8
+ import { pastedFile } from './pasted-path.js';
9
+ /**
10
+ * What was pasted into the prompt, shown there as placeholders. Kept for the whole run, so a message recalled from
11
+ * history still carries its pastes, images and files.
12
+ */
13
+ export class Attachments {
14
+ host;
15
+ texts = new PastedTexts();
16
+ images = new PastedImages();
17
+ files = new PastedFiles();
18
+ constructor(host) {
19
+ this.host = host;
20
+ }
21
+ /**
22
+ * `text` as typed, with what goes to the agent when the pastes in it make that differ: pasted text in full, images,
23
+ * and each file as `[File #1]`, numbered in the order they stand, with its id for the core to say what it is.
24
+ */
25
+ async submission(text) {
26
+ const files = this.files.in(text);
27
+ await Promise.all(files.map(({ file }) => file.settled));
28
+ // A file the core didn't take stays in the message as it was typed.
29
+ const sent = files.filter(({ file }) => file.id !== undefined);
30
+ const expanded = sent.reduce((prompt, { placeholder }, index) => prompt.replaceAll(placeholder, `[File #${index + 1}]`), this.texts.expand(text));
31
+ const images = this.images.in(text);
32
+ if (expanded === text && images.length === 0)
33
+ return { text };
34
+ return { text, prompt: { text: expanded, images }, ...(sent.length > 0 && { attachments: sent.map(({ file }) => file.id) }) };
35
+ }
36
+ /** A pasted path goes in as the image it names, or as the file, when that is one the agent is better handed. */
37
+ pastePath(text) {
38
+ try {
39
+ const image = imageFromPaste(text);
40
+ if (image)
41
+ return this.images.add(image);
42
+ const path = pastedFile(text);
43
+ return path && this.goesAlong(path) ? this.attach(path) : undefined;
44
+ }
45
+ catch (error) {
46
+ this.host.notice(errorMessage(error), 'warning');
47
+ return undefined;
48
+ }
49
+ }
50
+ async pasteClipboard() {
51
+ try {
52
+ const image = await clipboardImage();
53
+ if (image)
54
+ return this.images.add(image);
55
+ this.host.notice('There is no image on the clipboard. Text pastes with your terminal’s paste, e.g. cmd+v.', 'muted');
56
+ }
57
+ catch (error) {
58
+ this.host.notice(errorMessage(error), 'warning');
59
+ }
60
+ return undefined;
61
+ }
62
+ /**
63
+ * A file from outside where the session works is attached, and so is a recording, a PDF or a workbook from inside,
64
+ * which the core makes readable. Any other file of the project stays the path it is: the agent reads and changes
65
+ * it where it is, not a copy of it.
66
+ */
67
+ goesAlong(path) {
68
+ // By where both really are: a folder reached through a link, as a temporary one on macOS, is named two ways.
69
+ const file = realpathSync(path);
70
+ const inside = this.host.folders().some((folder) => {
71
+ const from = relative(realpathSync(folder), file);
72
+ return !from.startsWith('..') && !isAbsolute(from);
73
+ });
74
+ return !inside || attachmentKind(path) !== 'file';
75
+ }
76
+ attach(path) {
77
+ const file = { settled: Promise.resolve() };
78
+ file.settled = this.host.attach(basename(path), path).then((attachment) => {
79
+ file.id = attachment.id;
80
+ }, (error) => this.host.notice(errorMessage(error), 'warning'));
81
+ return this.files.add(basename(path), file);
82
+ }
83
+ }
84
+ export const AttachmentsContext = createContext(undefined);
85
+ export function useAttachments() {
86
+ const attachments = useContext(AttachmentsContext);
87
+ if (!attachments)
88
+ throw new Error('useAttachments() must be called inside <App>.');
89
+ return attachments;
90
+ }
91
+ //# sourceMappingURL=attachments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../src/prompt/attachments.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { atom } from 'jotai';
2
+ import { shownAtom } from '../state/session.js';
3
+ /** Each session's draft. It is the client's: the core only puts text in it, e.g. the message a rewind went back to. */
4
+ export const draftsAtom = atom({});
5
+ /** The sessions whose draft holds their queued messages, taken back to edit; sent, it goes back in the queue. */
6
+ export const requeuesAtom = atom({});
7
+ /** The draft of the session the user looks at. */
8
+ export const draftAtom = atom((get) => get(draftsAtom)[get(shownAtom).id] ?? '', (get, set, update) => {
9
+ const session = get(shownAtom).id;
10
+ const next = typeof update === 'function' ? update(get(draftsAtom)[session] ?? '') : update;
11
+ set(draftsAtom, (drafts) => ({ ...drafts, [session]: next }));
12
+ // An emptied draft no longer holds the queued messages.
13
+ if (next === '')
14
+ set(requeuesAtom, ({ [session]: _, ...rest }) => rest);
15
+ });
16
+ /** Whether the shown session's draft holds its queued messages. */
17
+ export const requeueAtom = atom((get) => get(requeuesAtom)[get(shownAtom).id] ?? false);
18
+ /** What was sent, in every session, for `up` to bring back. */
19
+ export const historyAtom = atom([]);
20
+ export function fillDraft(drafts, session, text, fill) {
21
+ const draft = fill === 'replace' ? text : [text, drafts[session]].filter(Boolean).join('\n');
22
+ return { ...drafts, [session]: draft };
23
+ }
24
+ //# sourceMappingURL=draft.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"draft.js","sourceRoot":"","sources":["../../src/prompt/draft.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAuB,MAAM,OAAO,CAAC;AAElD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD,uHAAuH;AACvH,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAyB,EAAE,CAAC,CAAC;AAE3D,iHAAiH;AACjH,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,CAA0B,EAAE,CAAC,CAAC;AAE9D,kDAAkD;AAClD,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,CAC3B,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,EACjD,CAAC,GAAG,EAAE,GAAG,EAAE,MAA8B,EAAE,EAAE;IAC3C,MAAM,OAAO,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;IAClC,MAAM,IAAI,GAAG,OAAO,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IAE5F,GAAG,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC9D,wDAAwD;IACxD,IAAI,IAAI,KAAK,EAAE;QAAE,GAAG,CAAC,YAAY,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;AAC1E,CAAC,CACF,CAAC;AAEF,mEAAmE;AACnE,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,CAAC;AAExF,+DAA+D;AAC/D,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAW,EAAE,CAAC,CAAC;AAE9C,MAAM,UAAU,SAAS,CAAC,MAA8B,EAAE,OAAe,EAAE,IAAY,EAAE,IAAgB;IACvG,MAAM,KAAK,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAE7F,OAAO,EAAE,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC;AACzC,CAAC"}