@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,47 @@
1
+ import { resolve } from 'node:path';
2
+ import { useMemo } from 'react';
3
+ import { useAtomValue } from 'jotai';
4
+ import { plural } from '@jinion/core/lib/format';
5
+ import { useApi } from '../../app/api.js';
6
+ import { editTurnsAtom } from '../../state/session.js';
7
+ import { useAsync } from '../../ui/use-async.js';
8
+ import { useWorkdir } from '../../ui/use-workdir.js';
9
+ import { totals } from './views.js';
10
+ export function useCurrentView() {
11
+ const api = useApi();
12
+ const cwd = useWorkdir();
13
+ const turns = useAtomValue(editTurnsAtom);
14
+ const edited = useMemo(() => new Set(turns.flatMap((turn) => turn.edits.map((change) => resolve(cwd, change.path)))), [turns, cwd]);
15
+ const read = useAsync(() => api.inSession('git/changes', {}), []);
16
+ if (read.state !== 'done')
17
+ return { label: 'Current', empty: 'Looking for changes…' };
18
+ const repos = read.value;
19
+ if (repos.length === 0)
20
+ return { label: 'Current', rows: [], empty: 'There is no git repository here or in the folders below.' };
21
+ const [only] = repos;
22
+ const grouped = repos.length > 1 || only.repo.path !== '';
23
+ const what = (repo) => (repo.since ? `${repo.branch} · what it adds to ${repo.since.against}` : repo.branch);
24
+ const rows = repos.flatMap((repo) => repo.changes.map((change) => ({
25
+ key: change.absolute,
26
+ group: grouped ? { label: repo.repo.label, aside: what(repo) } : undefined,
27
+ file: change.file,
28
+ kind: change.kind,
29
+ insertions: change.insertions,
30
+ deletions: change.deletions,
31
+ binary: change.binary,
32
+ agent: edited.has(change.absolute),
33
+ where: `${repo.repo.path ? `${repo.repo.path}/` : ''}${change.file}`,
34
+ patch: () => api.inSession('git/diff', { file: change.absolute }),
35
+ })));
36
+ // Repositories without changes have no rows, so they are named under the list.
37
+ const clean = rows.length > 0 && grouped ? repos.filter((repo) => repo.changes.length === 0) : [];
38
+ const repositories = plural(repos.length, 'repository', 'repositories');
39
+ return {
40
+ label: 'Current',
41
+ rows,
42
+ subtitle: [grouped ? repositories : what(only), ...totals(rows)].filter(Boolean).join(' · '),
43
+ empty: `No changes since the last commit in ${grouped ? repositories : 'this repository'}.`,
44
+ note: clean.length > 0 ? `No changes in ${clean.map((repo) => repo.repo.label).join(', ')}.` : undefined,
45
+ };
46
+ }
47
+ //# sourceMappingURL=current-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"current-view.js","sourceRoot":"","sources":["../../../src/panels/diff/current-view.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { editTurnsAtom } from '../../state/session.js';
3
+ import { useState } from 'react';
4
+ import { useAtomValue } from 'jotai';
5
+ import { ChangeList } from './change-list.js';
6
+ import { useCurrentView } from './current-view.js';
7
+ import { FileDiff } from './file-diff.js';
8
+ import { turnView } from './views.js';
9
+ /** As in Claude Code, plus a view per turn with just its edits. */
10
+ export function DiffPanel({ turn, file }) {
11
+ const current = useCurrentView();
12
+ const turns = useAtomValue(editTurnsAtom);
13
+ // Kept by the turn's id, so a turn that ends while the panel is open doesn't move what is shown.
14
+ const [activeTurn, setActiveTurn] = useState(() => (turns.some((candidate) => candidate.id === turn) ? turn : undefined));
15
+ const views = [current, ...turns.map(turnView)];
16
+ const active = Math.max(0, views.findIndex((view) => view.turn === activeTurn));
17
+ const [open, setOpen] = useState(() => views[active]?.rows?.find((row) => row.file === file));
18
+ if (open)
19
+ return _jsx(FileDiff, { row: open, onBack: () => setOpen(undefined) });
20
+ return (_jsx(ChangeList, { views: views, active: active, onSwitch: (step) => setActiveTurn(views[Math.min(views.length - 1, Math.max(0, active + step))]?.turn), onOpen: setOpen }, active));
21
+ }
22
+ //# sourceMappingURL=diff-panel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff-panel.js","sourceRoot":"","sources":["../../../src/panels/diff/diff-panel.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAkB,MAAM,YAAY,CAAC;AAOtD,mEAAmE;AACnE,MAAM,UAAU,SAAS,CAAC,EAAE,IAAI,EAAE,IAAI,EAAkB;IACtD,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,MAAM,KAAK,GAAG,YAAY,CAAC,aAAa,CAAC,CAAC;IAE1C,iGAAiG;IACjG,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAE1H,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC;IAChF,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAwB,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC;IAErH,IAAI,IAAI;QAAE,OAAO,KAAC,QAAQ,IAAC,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,GAAI,CAAC;IAE3E,OAAO,CACL,KAAC,UAAU,IAET,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EACtG,MAAM,EAAE,OAAO,IAJV,MAAM,CAKX,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Diff, extension, Panel, parsePatch, Text, useInput, useTheme } from '@jinion/tui';
3
+ import { PAGER_HINTS, usePager } from '../../ui/use-pager.js';
4
+ import { useAsync } from '../../ui/use-async.js';
5
+ export const CHROME_ROWS = 8;
6
+ export function FileDiff({ row, onBack }) {
7
+ const theme = useTheme();
8
+ const read = useAsync(() => row.patch().catch(() => ''), [row]);
9
+ const patch = read.state === 'done' ? read.value : undefined;
10
+ const lines = patch ? parsePatch(patch).length : 0;
11
+ const pager = usePager(lines, { chrome: CHROME_ROWS });
12
+ useInput((_, key) => {
13
+ if (key.escape)
14
+ return onBack();
15
+ pager.scroll(key);
16
+ });
17
+ return (_jsx(Panel, { title: "Diff", subtitle: [row.where, pager.range].filter(Boolean).join(' · '), grow: true, hints: [...PAGER_HINTS, ['Esc', 'back']], children: patch === undefined ? (_jsx(Text, { color: theme.muted, children: "Reading the diff\u2026" })) : row.binary ? (_jsx(Text, { color: theme.muted, children: "A binary file; there are no lines to show." })) : lines === 0 ? (_jsx(Text, { color: theme.muted, children: "No line changes, e.g. only the file's mode changed." })) : (_jsx(Diff, { patch: patch, language: extension(row.file), window: { start: pager.top, rows: pager.view } })) }));
18
+ }
19
+ //# sourceMappingURL=file-diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-diff.js","sourceRoot":"","sources":["../../../src/panels/diff/file-diff.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC3F,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGjD,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC;AAE7B,MAAM,UAAU,QAAQ,CAAC,EAAE,GAAG,EAAE,MAAM,EAAsC;IAC1E,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IAEzB,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAChE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7D,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;IAEvD,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;QAClB,IAAI,GAAG,CAAC,MAAM;YAAE,OAAO,MAAM,EAAE,CAAC;QAEhC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,KAAC,KAAK,IAAC,KAAK,EAAC,MAAM,EAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,QAAC,KAAK,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,YAC9H,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CACrB,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,uCAA0B,CACnD,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CACf,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,2DAAmD,CAC5E,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAChB,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,oEAA4D,CACrF,CAAC,CAAC,CAAC,CACF,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,GAAI,CACtG,GACK,CACT,CAAC;AACJ,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { changedFiles } from '@jinion/core/conversation/edits';
2
+ import { plural } from '@jinion/core/lib/format';
3
+ import { firstFilledLine, truncate } from '@jinion/core/lib/text';
4
+ const TURN_LABEL = 24;
5
+ export function turnView(turn) {
6
+ const rows = changedFiles(turn.edits).map((file) => ({
7
+ key: file.path,
8
+ file: file.path,
9
+ kind: file.created ? 'added' : 'modified',
10
+ insertions: file.added,
11
+ deletions: file.removed,
12
+ where: file.path,
13
+ patch: async () => file.patch,
14
+ }));
15
+ const prompt = firstFilledLine(turn.prompt);
16
+ return {
17
+ label: truncate(prompt, TURN_LABEL),
18
+ turn: turn.id,
19
+ rows,
20
+ subtitle: [`“${truncate(prompt, 60)}”`, ...totals(rows)].join(' · '),
21
+ empty: '',
22
+ };
23
+ }
24
+ export function totals(rows) {
25
+ const insertions = rows.reduce((total, row) => total + row.insertions, 0);
26
+ const deletions = rows.reduce((total, row) => total + row.deletions, 0);
27
+ return [plural(rows.length, 'file'), `+${insertions} -${deletions}`];
28
+ }
29
+ //# sourceMappingURL=views.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"views.js","sourceRoot":"","sources":["../../../src/panels/diff/views.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAiB,MAAM,iCAAiC,CAAC;AAE9E,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAElE,MAAM,UAAU,GAAG,EAAE,CAAC;AAwBtB,MAAM,UAAU,QAAQ,CAAC,IAAc;IACrC,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CACvC,CAAC,IAAI,EAAa,EAAE,CAAC,CAAC;QACpB,GAAG,EAAE,IAAI,CAAC,IAAI;QACd,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU;QACzC,UAAU,EAAE,IAAI,CAAC,KAAK;QACtB,SAAS,EAAE,IAAI,CAAC,OAAO;QACvB,KAAK,EAAE,IAAI,CAAC,IAAI;QAChB,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,KAAK;KAC9B,CAAC,CACH,CAAC;IAEF,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAE5C,OAAO;QACL,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;QACnC,IAAI,EAAE,IAAI,CAAC,EAAE;QACb,IAAI;QACJ,QAAQ,EAAE,CAAC,IAAI,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;QACpE,KAAK,EAAE,EAAE;KACV,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,IAAiB;IACtC,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IAC1E,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IAExE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC,CAAC;AACvE,CAAC"}
@@ -0,0 +1,67 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { Box, ChoiceList, Panel, PromptInput, Text, useChoiceList, useInput, usePanel, useTheme } from '@jinion/tui';
4
+ import { errorMessage } from '@jinion/core/lib/errors';
5
+ import { useApi } from '../app/api.js';
6
+ const RATINGS = ['liked', 'disliked', 'note'];
7
+ const SHARING = ['share', 'keep'];
8
+ /** About the turn that begins with `entry`: a rating, a note, and whether its conversation goes along; about Jinion without one. */
9
+ export function FeedbackPanel({ entry }) {
10
+ const api = useApi();
11
+ const theme = useTheme();
12
+ const { close } = usePanel();
13
+ const [step, setStep] = useState(entry ? { kind: 'rate' } : { kind: 'note', rating: 'note' });
14
+ const [note, setNote] = useState('');
15
+ const send = (kind, share = false) => {
16
+ setStep({ kind: 'sending' });
17
+ api.inSession('session/feedback', { ...(entry && { entry }), kind, ...(note.trim() && { note: note.trim() }), share }).then(() => {
18
+ close();
19
+ api.act(api.inSession('session/notice', { text: 'Thanks for the feedback. We read every one.', tone: 'muted' }));
20
+ }, (error) => setStep({ kind: 'failed', problem: `Couldn’t send it: ${errorMessage(error)}` }));
21
+ };
22
+ const rate = useChoiceList({
23
+ keys: RATINGS,
24
+ mode: 'single',
25
+ isActive: step.kind === 'rate',
26
+ onCancel: close,
27
+ onSubmit: ([kind]) => (kind === 'liked' ? send('liked') : setStep({ kind: 'note', rating: kind })),
28
+ });
29
+ const share = useChoiceList({
30
+ keys: SHARING,
31
+ mode: 'single',
32
+ isActive: step.kind === 'share',
33
+ onCancel: close,
34
+ onSubmit: ([choice]) => step.kind === 'share' && send(step.rating, choice === 'share'),
35
+ });
36
+ useInput((_, key) => {
37
+ if (key.escape)
38
+ close();
39
+ }, { isActive: step.kind !== 'rate' && step.kind !== 'share' });
40
+ const submitNote = () => {
41
+ if (step.kind !== 'note')
42
+ return;
43
+ if (step.rating === 'note' && !note.trim())
44
+ return;
45
+ entry ? setStep({ kind: 'share', rating: step.rating }) : send('note');
46
+ };
47
+ return (_jsxs(Panel, { title: "Feedback", subtitle: entry ? 'The last answer' : 'Jinion', hints: hintsOf(step), children: [step.kind === 'rate' && (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.muted, children: "How did the last answer go?" }), _jsx(ChoiceList, { list: rate, limit: RATINGS.length, choices: [
48
+ { key: 'liked', label: _jsx(Text, { children: "It was good" }) },
49
+ { key: 'disliked', label: _jsx(Text, { children: "It wasn\u2019t good" }), description: 'Tell us what went wrong, if you like' },
50
+ { key: 'note', label: _jsx(Text, { children: "Just leave a note" }) },
51
+ ] })] })), step.kind === 'note' && (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.muted, children: step.rating === 'disliked' ? 'What went wrong? Enter to skip.' : entry ? 'What would you like to tell us?' : 'What would you like to tell us about Jinion?' }), _jsxs(Box, { children: [_jsx(Text, { color: theme.muted, children: '> ' }), _jsx(PromptInput, { value: note, onChange: setNote, onSubmit: submitNote, placeholder: "A sentence is plenty", paddingX: 0 })] })] })), step.kind === 'share' && (_jsxs(_Fragment, { children: [_jsx(Text, { color: theme.muted, children: "Send this conversation along? It helps us see what happened." }), _jsx(ChoiceList, { list: share, limit: SHARING.length, choices: [
52
+ {
53
+ key: 'share',
54
+ label: _jsx(Text, { children: "Send it" }),
55
+ description: 'Your message, the reply, and the names of the steps it took. Never file contents or command output.',
56
+ },
57
+ { key: 'keep', label: _jsx(Text, { children: "Just my feedback" }) },
58
+ ] })] })), step.kind === 'sending' && _jsx(Text, { color: theme.muted, children: "Sending\u2026" }), step.kind === 'failed' && _jsx(Text, { color: theme.error, children: step.problem })] }));
59
+ }
60
+ function hintsOf(step) {
61
+ if (step.kind === 'note')
62
+ return [['Enter', 'continue'], ['Esc', 'cancel']];
63
+ if (step.kind === 'rate' || step.kind === 'share')
64
+ return [['Enter', 'continue'], ['Up/Down', 'move'], ['Esc', 'cancel']];
65
+ return [['Esc', 'close']];
66
+ }
67
+ //# sourceMappingURL=feedback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback.js","sourceRoot":"","sources":["../../src/panels/feedback.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect } from 'react';
3
+ import { Box, ListRow, Panel, Prose, SelectList, Tabs, Text, useInput, useListNavigation, usePanel, useTabs, useTheme } from '@jinion/tui';
4
+ import { useAtomValue, useSetAtom } from 'jotai';
5
+ import { requiresArgument } from '@jinion/core/prompt/command-completion';
6
+ import { skillGroup, sortSkills } from '@jinion/core/prompt/skills';
7
+ import { useApi } from '../app/api.js';
8
+ import { SHORTCUTS } from '../app/shortcuts.js';
9
+ import { draftAtom } from '../prompt/draft.js';
10
+ import { skillsAtom } from '../state/session.js';
11
+ const SHORTCUT_COLUMNS = 3;
12
+ export function HelpPanel({ topic = '' }) {
13
+ const api = useApi();
14
+ const { close } = usePanel();
15
+ const skills = sortSkills(useAtomValue(skillsAtom));
16
+ const setDraft = useSetAtom(draftAtom);
17
+ const mention = (skill) => ({
18
+ label: `$${skill.name}`,
19
+ hint: skill.argumentHint,
20
+ description: skill.description,
21
+ aside: skillGroup(skill),
22
+ pick: () => setDraft(`$${skill.name} `),
23
+ });
24
+ const groups = [
25
+ {
26
+ label: 'Commands',
27
+ items: api.initialized.commands.map((command) => ({
28
+ label: `/${command.name}`,
29
+ hint: command.argumentHint,
30
+ description: command.description,
31
+ aside: command.aliases?.map((alias) => `/${alias}`).join(' '),
32
+ pick: () => requiresArgument(command) ? setDraft(`/${command.name} `) : api.act(api.inSession('session/submit', { text: `/${command.name}` })),
33
+ })),
34
+ },
35
+ { label: 'Skills', items: skills.filter((skill) => skill.source === 'skill').map(mention) },
36
+ { label: 'MCP prompts', items: skills.filter((skill) => skill.source === 'mcp').map(mention) },
37
+ ].filter((group) => group.items.length > 0);
38
+ const tabs = ['General', ...groups.map((group) => group.label)];
39
+ const [tab] = useTabs(tabs.length, {
40
+ initial: Math.max(0, tabs.findIndex((label) => label.toLowerCase().startsWith(topic.trim().toLowerCase() || '\0'))),
41
+ });
42
+ const items = tab === 0 ? [] : groups[tab - 1].items;
43
+ const [selected, setSelected] = useListNavigation(items.length, { isActive: tab > 0 });
44
+ const hints = tab === 0
45
+ ? [
46
+ ['Left/Right', 'switch tab'],
47
+ ['Esc', 'close'],
48
+ ]
49
+ : [
50
+ ['Enter', groups[tab - 1]?.label === 'Commands' ? 'run' : 'insert'],
51
+ ['Up/Down', 'move'],
52
+ ['Left/Right', 'switch tab'],
53
+ ['Esc', 'close'],
54
+ ];
55
+ useEffect(() => setSelected(0), [tab, setSelected]);
56
+ useInput((_, key) => {
57
+ if (key.escape)
58
+ return close();
59
+ const item = items[selected];
60
+ if (!key.return || !item)
61
+ return;
62
+ close();
63
+ item.pick();
64
+ });
65
+ return (_jsx(Panel, { title: "Help", header: _jsx(Tabs, { tabs: tabs, active: tab }), hints: hints, children: tab === 0 ? _jsx(General, {}) : _jsx(ItemList, { items: items, selected: selected }) }));
66
+ }
67
+ function General() {
68
+ const theme = useTheme();
69
+ const perColumn = Math.ceil(SHORTCUTS.length / SHORTCUT_COLUMNS);
70
+ const columns = Array.from({ length: SHORTCUT_COLUMNS }, (_, index) => SHORTCUTS.slice(index * perColumn, (index + 1) * perColumn));
71
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Prose, { children: "Jinion reads your codebase, edits files and runs commands, right from your terminal." }), _jsx(Text, { children: " " }), _jsx(Text, { bold: true, children: "Shortcuts" }), _jsx(Box, { children: columns.map((column, index) => (_jsx(Box, { flexDirection: "column", flexGrow: 1, flexBasis: 0, children: column.map(([keys, action]) => (_jsxs(Text, { wrap: "truncate-end", children: [_jsx(Text, { color: theme.selection, children: keys }), _jsxs(Text, { color: theme.muted, children: [" ", action] })] }, keys))) }, index))) }), _jsx(Text, { children: " " }), _jsxs(Text, { color: theme.muted, children: ["Docs and updates: ", _jsx(Text, { color: theme.link, children: "https://jinion.co" })] })] }));
72
+ }
73
+ function ItemList({ items, selected }) {
74
+ const theme = useTheme();
75
+ const width = (item) => item.label.length + (item.hint ? item.hint.length + 1 : 0);
76
+ const labelWidth = Math.min(32, Math.max(...items.map(width)));
77
+ return (_jsx(SelectList, { items: items, selected: selected, limit: 10, renderItem: (item, state) => (_jsx(ListRow, { selected: state.selected, labelWidth: labelWidth, label: _jsxs(Text, { children: [item.label, item.hint && _jsxs(Text, { color: theme.muted, children: [" ", item.hint] })] }), description: item.description, aside: item.aside })) }));
78
+ }
79
+ //# sourceMappingURL=help.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/panels/help.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,129 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useRef, useState } from 'react';
3
+ import { Box, ChoiceList, choiceIndent, Panel, Text, useChoiceList, useInput, usePanel, useTheme } from '@jinion/tui';
4
+ import { errorMessage } from '@jinion/core/lib/errors';
5
+ import { plural } from '@jinion/core/lib/format';
6
+ import { truncate } from '@jinion/core/lib/text';
7
+ import { useAtomValue } from 'jotai';
8
+ import { useApi } from '../app/api.js';
9
+ import { agentAtom } from '../state/session.js';
10
+ const VISIBLE = 10;
11
+ const LABEL_WIDTH = 18;
12
+ const TOOLS_SHOWN = 8;
13
+ const POLL_MS = 1_500;
14
+ /** Changes apply from the next turn, when the agent connects again. */
15
+ export function McpPanel() {
16
+ const api = useApi();
17
+ const agent = useAtomValue(agentAtom);
18
+ const theme = useTheme();
19
+ const { close } = usePanel();
20
+ const [servers, setServers] = useState();
21
+ const [failure, setFailure] = useState();
22
+ const [signing, setSigning] = useState();
23
+ // Bumped after a sign-in, so the list comes in again.
24
+ const [loads, setLoads] = useState(0);
25
+ // Servers the user toggled keep their check when the list comes in again.
26
+ const touched = useRef(new Set());
27
+ const signingName = useRef(undefined);
28
+ const list = useChoiceList({
29
+ keys: (servers ?? []).map((server) => server.name),
30
+ mode: 'multiple',
31
+ isActive: !signing,
32
+ onCancel: close,
33
+ onToggle: (name) => void touched.current.add(name),
34
+ onSubmit: (checked) => {
35
+ close();
36
+ api.act(api.request('mcp/save', { enabled: checked }));
37
+ },
38
+ });
39
+ const choices = (servers ?? []).map((server) => {
40
+ const checked = list.isChecked(server.name);
41
+ return {
42
+ key: server.name,
43
+ label: (_jsxs(Text, { children: [truncate(server.label, LABEL_WIDTH - 2).padEnd(LABEL_WIDTH), checked === server.enabled ? describe(server, theme) : _jsxs(Text, { color: theme.muted, children: [checked ? 'turns on' : 'turns off', " on save"] })] })),
44
+ aside: server.source,
45
+ editor: _jsx(Details, { server: server, indent: choiceIndent(list) }),
46
+ };
47
+ });
48
+ const on = servers?.filter((server) => list.isChecked(server.name)).length ?? 0;
49
+ const focused = servers?.find((server) => server.name === list.focus);
50
+ const canSignIn = focused?.status === 'needs-auth' && focused.signIn !== 'elsewhere';
51
+ useEffect(() => {
52
+ const stopLink = api.client.on('mcp/sign-in-link', ({ name, url }) => setSigning((now) => (now?.name === name ? { ...now, link: url } : now)));
53
+ return () => {
54
+ stopLink();
55
+ if (signingName.current)
56
+ api.act(api.request('mcp/sign-in-cancel', { name: signingName.current }));
57
+ };
58
+ }, []);
59
+ useEffect(() => {
60
+ let timer;
61
+ let open = true;
62
+ const load = () => api.request('mcp/servers', {}).then((next) => {
63
+ if (!open)
64
+ return;
65
+ setServers(next);
66
+ for (const server of next)
67
+ if (!touched.current.has(server.name))
68
+ list.setChecked(server.name, server.enabled);
69
+ if (next.some((server) => server.status === 'pending'))
70
+ timer = setTimeout(load, POLL_MS);
71
+ }, (error) => open && setFailure(errorMessage(error)));
72
+ void load();
73
+ return () => {
74
+ open = false;
75
+ clearTimeout(timer);
76
+ };
77
+ }, [loads]);
78
+ useInput((input) => {
79
+ if (input !== 'l' || !focused || !canSignIn)
80
+ return;
81
+ const { name, label } = focused;
82
+ signingName.current = name;
83
+ setSigning({ name, label });
84
+ void api
85
+ .request('mcp/sign-in', { name })
86
+ .catch(() => { })
87
+ .finally(() => {
88
+ if (signingName.current === name)
89
+ signingName.current = undefined;
90
+ setSigning(undefined);
91
+ setLoads((count) => count + 1);
92
+ });
93
+ }, { isActive: !signing });
94
+ useInput((_, key) => {
95
+ if (key.escape && signing)
96
+ api.act(api.request('mcp/sign-in-cancel', { name: signing.name }));
97
+ }, { isActive: signing !== undefined });
98
+ if (signing) {
99
+ return (_jsxs(Panel, { title: "MCP servers", subtitle: signing.label, hints: [['Esc', 'cancel']], children: [_jsxs(Text, { children: ["Signing in to ", _jsx(Text, { bold: true, children: signing.label }), ". Finish it in your browser."] }), signing.link && (_jsxs(Text, { children: [_jsx(Text, { color: theme.muted, children: "If the browser didn't open: " }), _jsx(Text, { color: theme.code, children: signing.link })] }))] }));
100
+ }
101
+ return (_jsx(Panel, { title: "MCP servers", subtitle: servers ? `${on} of ${servers.length} on` : undefined, header: _jsx(Text, { color: theme.muted, children: "Checked servers connect from the next turn. Their tools load when the agent needs them, so a server costs little context until it's used." }), hints: [
102
+ ['Space', 'on/off'],
103
+ ['Enter', 'save'],
104
+ ...(canSignIn ? [['l', 'sign in']] : []),
105
+ ['Up/Down', 'move'],
106
+ ['Esc', 'cancel'],
107
+ ], children: failure ? (_jsxs(Text, { color: theme.error, children: ["Couldn't list the servers: ", failure] })) : servers ? (_jsx(ChoiceList, { list: list, choices: choices, limit: VISIBLE, empty: "No MCP servers yet. Add them with `claude mcp add`, in ~/.jinion/mcp.json or in the project's .mcp.json." })) : (_jsxs(Text, { color: theme.muted, children: ["Asking ", agent.name, " about its servers\u2026"] })) }));
108
+ }
109
+ function describe(server, theme) {
110
+ switch (server.status) {
111
+ case 'connected':
112
+ return (_jsxs(Text, { children: [_jsx(Text, { color: theme.success, children: "connected" }), _jsxs(Text, { color: theme.muted, children: [" \u00B7 ", plural(server.tools.length, 'tool')] })] }));
113
+ case 'pending':
114
+ return _jsx(Text, { color: theme.muted, children: "connecting\u2026" });
115
+ case 'needs-auth':
116
+ return _jsx(Text, { color: theme.warning, children: "not signed in" });
117
+ case 'failed':
118
+ return _jsx(Text, { color: theme.error, children: "failed to connect" });
119
+ case 'off':
120
+ return _jsx(Text, { color: theme.muted, children: server.source === 'project' ? 'off until you turn it on (from .mcp.json)' : 'off' });
121
+ }
122
+ }
123
+ function Details({ server, indent }) {
124
+ const theme = useTheme();
125
+ const tools = server.tools.slice(0, TOOLS_SHOWN).join(', ');
126
+ const more = server.tools.length - TOOLS_SHOWN;
127
+ return (_jsxs(Box, { flexDirection: "column", paddingLeft: indent, marginBottom: 1, children: [server.target && (_jsx(Text, { color: theme.muted, wrap: "truncate-end", children: server.target })), server.error && _jsx(Text, { color: theme.error, children: server.error }), server.status === 'needs-auth' && server.signIn !== 'elsewhere' && (_jsxs(Text, { color: theme.muted, children: ["Press l to sign in to ", server.label, " in the browser."] })), tools && (_jsxs(Text, { wrap: "truncate-end", children: [tools, more > 0 && _jsxs(Text, { color: theme.muted, children: [" \u2026 ", more, " more"] })] }))] }));
128
+ }
129
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/panels/mcp.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useState } from 'react';
3
+ import { Box, ChoiceList, choiceIndent, Panel, Prose, Text, useChoiceList, useInput, usePanel, useTheme } from '@jinion/tui';
4
+ import { plural } from '@jinion/core/lib/format';
5
+ import { tildify } from '@jinion/core/lib/paths';
6
+ import { useApi } from '../app/api.js';
7
+ const PREVIEW_LINES = 12;
8
+ export function MemoryPanel() {
9
+ const api = useApi();
10
+ const theme = useTheme();
11
+ const { close } = usePanel();
12
+ const [notes, setNotes] = useState([]);
13
+ const [open, setOpen] = useState();
14
+ const [forgetting, setForgetting] = useState();
15
+ const refresh = () => api.request('memory/list', {}).then(setNotes, () => setNotes([]));
16
+ useEffect(() => void refresh(), []);
17
+ const keys = notes.map((memory) => `${memory.scope}/${memory.id}`);
18
+ const list = useChoiceList({
19
+ keys,
20
+ mode: 'single',
21
+ onCancel: close,
22
+ onSubmit: ([key]) => setOpen(open === key ? undefined : key),
23
+ });
24
+ const choices = notes.map((memory) => {
25
+ const key = `${memory.scope}/${memory.id}`;
26
+ const lines = memory.content.split('\n');
27
+ return {
28
+ key,
29
+ label: memory.title,
30
+ description: `${memory.scope} · ${memory.type} · ${memory.description}`,
31
+ aside: forgetting === key ? _jsx(Text, { color: theme.error, children: "press d again to forget" }) : memory.updated,
32
+ editor: open === key ? (_jsxs(Box, { flexDirection: "column", paddingLeft: choiceIndent(list), marginBottom: 1, children: [_jsx(Prose, { children: lines.slice(0, PREVIEW_LINES).join('\n') }), lines.length > PREVIEW_LINES && _jsxs(Text, { color: theme.muted, children: ["\u2026 ", lines.length - PREVIEW_LINES, " more lines"] }), _jsx(Text, { color: theme.muted, children: tildify(memory.path) })] })) : undefined,
33
+ };
34
+ });
35
+ useInput((input) => {
36
+ if (input !== 'd' || !list.focus)
37
+ return setForgetting(undefined);
38
+ if (forgetting !== list.focus)
39
+ return setForgetting(list.focus);
40
+ const memory = notes.find((note) => `${note.scope}/${note.id}` === list.focus);
41
+ setForgetting(undefined);
42
+ if (!memory)
43
+ return;
44
+ const forgotten = api.request('memory/forget', { scope: memory.scope, id: memory.id });
45
+ api.act(forgotten);
46
+ void forgotten.finally(refresh);
47
+ });
48
+ return (_jsx(Panel, { title: "Memory", subtitle: plural(notes.length, 'note'), hints: [
49
+ ['Enter', 'open'],
50
+ ['d', 'forget'],
51
+ ['Up/Down', 'move'],
52
+ ['Esc', 'close'],
53
+ ], children: _jsx(ChoiceList, { list: list, choices: choices, limit: 6, empty: "No notes yet. The agent saves them as it learns, /remember adds one, and /memory import brings in Claude Code's." }) }));
54
+ }
55
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/panels/memory.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { ChoiceList, Panel, Text, useChoiceList, usePanel, useTheme } from '@jinion/tui';
3
+ import { useAtomValue } from 'jotai';
4
+ import { MODES } from '@jinion/core/agent/modes';
5
+ import { useApi } from '../app/api.js';
6
+ import { agentAtom, modeAtom } from '../state/session.js';
7
+ import { modeColor } from '../ui/modes.js';
8
+ export function ModePicker() {
9
+ const api = useApi();
10
+ const theme = useTheme();
11
+ const { close } = usePanel();
12
+ const current = useAtomValue(modeAtom);
13
+ const { modes: available, name } = useAtomValue(agentAtom);
14
+ const list = useChoiceList({
15
+ keys: available,
16
+ mode: 'single',
17
+ initialFocus: current,
18
+ onCancel: close,
19
+ onSubmit: ([mode]) => {
20
+ close();
21
+ if (mode)
22
+ api.act(api.inSession('session/mode', { mode: mode }));
23
+ },
24
+ });
25
+ return (_jsx(Panel, { title: "Mode", subtitle: name, hints: [
26
+ ['Enter', 'select'],
27
+ ['Up/Down', 'move'],
28
+ ['Esc', 'cancel'],
29
+ ], children: _jsx(ChoiceList, { list: list, limit: available.length, choices: available.map((mode) => ({
30
+ key: mode,
31
+ label: _jsx(Text, { color: modeColor(theme, mode), children: MODES[mode].name }),
32
+ description: MODES[mode].description,
33
+ aside: mode === current ? 'current' : undefined,
34
+ })) }) }));
35
+ }
36
+ //# sourceMappingURL=mode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mode.js","sourceRoot":"","sources":["../../src/panels/mode.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACzF,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAErC,OAAO,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,MAAM,UAAU,UAAU;IACxB,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;IACrB,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,MAAM,EAAE,KAAK,EAAE,GAAG,QAAQ,EAAE,CAAC;IAC7B,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IAE3D,MAAM,IAAI,GAAG,aAAa,CAAC;QACzB,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,QAAQ;QACd,YAAY,EAAE,OAAO;QACrB,QAAQ,EAAE,KAAK;QACf,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE;YACnB,KAAK,EAAE,CAAC;YACR,IAAI,IAAI;gBAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,EAAE,IAAI,EAAE,IAAiB,EAAE,CAAC,CAAC,CAAC;QAChF,CAAC;KACF,CAAC,CAAC;IAEH,OAAO,CACL,KAAC,KAAK,IACJ,KAAK,EAAC,MAAM,EACZ,QAAQ,EAAE,IAAI,EACd,KAAK,EAAE;YACL,CAAC,OAAO,EAAE,QAAQ,CAAC;YACnB,CAAC,SAAS,EAAE,MAAM,CAAC;YACnB,CAAC,KAAK,EAAE,QAAQ,CAAC;SAClB,YAED,KAAC,UAAU,IACT,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,SAAS,CAAC,MAAM,EACvB,OAAO,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAChC,GAAG,EAAE,IAAI;gBACT,KAAK,EAAE,KAAC,IAAI,IAAC,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,YAAG,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,GAAQ;gBACrE,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW;gBACpC,KAAK,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;aAChD,CAAC,CAAC,GACH,GACI,CACT,CAAC;AACJ,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { usePanel } from '@jinion/tui';
3
+ import { ModelPanel } from '@jinion/tui/chat';
4
+ import { useAtomValue } from 'jotai';
5
+ import { useApi } from '../app/api.js';
6
+ import { agentAtom, agentsAtom, allModelsAtom, selectionAtom } from '../state/session.js';
7
+ /** Every backend's models, under its name; one of another backend moves the conversation there. */
8
+ export function ModelPicker() {
9
+ const api = useApi();
10
+ const { close } = usePanel();
11
+ const agents = useAtomValue(agentsAtom);
12
+ const models = useAtomValue(allModelsAtom);
13
+ const agent = useAtomValue(agentAtom);
14
+ const selection = useAtomValue(selectionAtom);
15
+ return (_jsx(ModelPanel, { groups: agents.map(({ name }) => ({ name, models: models[name] })), current: { ...selection, group: agent.name }, subtitle: agents.length > 1 ? undefined : agent.name, onSelect: (next, group) => {
16
+ close();
17
+ api.act(api.inSession('session/model', { selection: next, agent: group }));
18
+ }, onCancel: close }));
19
+ }
20
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/panels/model.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE1F,mGAAmG;AACnG,MAAM,UAAU,WAAW;IACzB,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,KAAK,EAAE,GAAG,QAAQ,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,YAAY,CAAC,aAAa,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IACtC,MAAM,SAAS,GAAG,YAAY,CAAC,aAAa,CAAC,CAAC;IAE9C,OAAO,CACL,KAAC,UAAU,IACT,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAClE,OAAO,EAAE,EAAE,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,EAC5C,QAAQ,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EACpD,QAAQ,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YACxB,KAAK,EAAE,CAAC;YACR,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QAC7E,CAAC,EACD,QAAQ,EAAE,KAAK,GACf,CACH,CAAC;AACJ,CAAC"}