@jinion/cli 0.0.0-stage → 0.4.524
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +249 -0
- package/bin/jinion.js +15 -0
- package/dist/app/activity.js +50 -0
- package/dist/app/activity.js.map +1 -0
- package/dist/app/announcements.js +21 -0
- package/dist/app/announcements.js.map +1 -0
- package/dist/app/api.js +26 -0
- package/dist/app/api.js.map +1 -0
- package/dist/app/app.js +99 -0
- package/dist/app/app.js.map +1 -0
- package/dist/app/aside.js +52 -0
- package/dist/app/aside.js.map +1 -0
- package/dist/app/claude-notes.js +19 -0
- package/dist/app/claude-notes.js.map +1 -0
- package/dist/app/dialogs.js +43 -0
- package/dist/app/dialogs.js.map +1 -0
- package/dist/app/keys.js +79 -0
- package/dist/app/keys.js.map +1 -0
- package/dist/app/prompt-area.js +56 -0
- package/dist/app/prompt-area.js.map +1 -0
- package/dist/app/release-notes.js +20 -0
- package/dist/app/release-notes.js.map +1 -0
- package/dist/app/settings-file.js +7 -0
- package/dist/app/settings-file.js.map +1 -0
- package/dist/app/shortcuts.js +31 -0
- package/dist/app/shortcuts.js.map +1 -0
- package/dist/app/sidebar.js +50 -0
- package/dist/app/sidebar.js.map +1 -0
- package/dist/app/status-line.js +29 -0
- package/dist/app/status-line.js.map +1 -0
- package/dist/app/task-line.js +19 -0
- package/dist/app/task-line.js.map +1 -0
- package/dist/app/updates.js +17 -0
- package/dist/app/updates.js.map +1 -0
- package/dist/app/use-screen.js +24 -0
- package/dist/app/use-screen.js.map +1 -0
- package/dist/app/views.js +68 -0
- package/dist/app/views.js.map +1 -0
- package/dist/main.js +124 -0
- package/dist/main.js.map +1 -0
- package/dist/panels/account/account-picker.js +118 -0
- package/dist/panels/account/account-picker.js.map +1 -0
- package/dist/panels/account/describe.js +14 -0
- package/dist/panels/account/describe.js.map +1 -0
- package/dist/panels/account/sign-in-view.js +8 -0
- package/dist/panels/account/sign-in-view.js.map +1 -0
- package/dist/panels/account/use-sign-in.js +46 -0
- package/dist/panels/account/use-sign-in.js.map +1 -0
- package/dist/panels/context.js +55 -0
- package/dist/panels/context.js.map +1 -0
- package/dist/panels/diff/change-list.js +48 -0
- package/dist/panels/diff/change-list.js.map +1 -0
- package/dist/panels/diff/current-view.js +47 -0
- package/dist/panels/diff/current-view.js.map +1 -0
- package/dist/panels/diff/diff-panel.js +22 -0
- package/dist/panels/diff/diff-panel.js.map +1 -0
- package/dist/panels/diff/file-diff.js +19 -0
- package/dist/panels/diff/file-diff.js.map +1 -0
- package/dist/panels/diff/views.js +29 -0
- package/dist/panels/diff/views.js.map +1 -0
- package/dist/panels/feedback.js +67 -0
- package/dist/panels/feedback.js.map +1 -0
- package/dist/panels/help.js +79 -0
- package/dist/panels/help.js.map +1 -0
- package/dist/panels/map.js +80 -0
- package/dist/panels/map.js.map +1 -0
- package/dist/panels/mcp.js +129 -0
- package/dist/panels/mcp.js.map +1 -0
- package/dist/panels/memory.js +55 -0
- package/dist/panels/memory.js.map +1 -0
- package/dist/panels/mode.js +36 -0
- package/dist/panels/mode.js.map +1 -0
- package/dist/panels/model.js +20 -0
- package/dist/panels/model.js.map +1 -0
- package/dist/panels/onboarding/claude-setup-panel.js +68 -0
- package/dist/panels/onboarding/claude-setup-panel.js.map +1 -0
- package/dist/panels/onboarding/onboarding-panel.js +56 -0
- package/dist/panels/onboarding/onboarding-panel.js.map +1 -0
- package/dist/panels/onboarding/use-onboarding.js +65 -0
- package/dist/panels/onboarding/use-onboarding.js.map +1 -0
- package/dist/panels/profile.js +31 -0
- package/dist/panels/profile.js.map +1 -0
- package/dist/panels/release-notes.js +60 -0
- package/dist/panels/release-notes.js.map +1 -0
- package/dist/panels/resume.js +52 -0
- package/dist/panels/resume.js.map +1 -0
- package/dist/panels/rewind/changes.js +20 -0
- package/dist/panels/rewind/changes.js.map +1 -0
- package/dist/panels/rewind/rewind-panel.js +93 -0
- package/dist/panels/rewind/rewind-panel.js.map +1 -0
- package/dist/panels/sign-in/sign-in-panel.js +56 -0
- package/dist/panels/sign-in/sign-in-panel.js.map +1 -0
- package/dist/panels/sign-in/use-jinion-sign-in.js +69 -0
- package/dist/panels/sign-in/use-jinion-sign-in.js.map +1 -0
- package/dist/panels/statusline.js +94 -0
- package/dist/panels/statusline.js.map +1 -0
- package/dist/panels/tasks/output.js +23 -0
- package/dist/panels/tasks/output.js.map +1 -0
- package/dist/panels/tasks/task-output.js +29 -0
- package/dist/panels/tasks/task-output.js.map +1 -0
- package/dist/panels/tasks/tasks-panel.js +75 -0
- package/dist/panels/tasks/tasks-panel.js.map +1 -0
- package/dist/panels/terminal-setup.js +41 -0
- package/dist/panels/terminal-setup.js.map +1 -0
- package/dist/panels/usage/section.js +16 -0
- package/dist/panels/usage/section.js.map +1 -0
- package/dist/panels/usage/stats-view.js +52 -0
- package/dist/panels/usage/stats-view.js.map +1 -0
- package/dist/panels/usage/usage-panel.js +68 -0
- package/dist/panels/usage/usage-panel.js.map +1 -0
- package/dist/panels/usage/usage-view.js +51 -0
- package/dist/panels/usage/usage-view.js.map +1 -0
- package/dist/prompt/attachments.js +91 -0
- package/dist/prompt/attachments.js.map +1 -0
- package/dist/prompt/draft.js +24 -0
- package/dist/prompt/draft.js.map +1 -0
- package/dist/prompt/images.js +84 -0
- package/dist/prompt/images.js.map +1 -0
- package/dist/prompt/pasted-path.js +19 -0
- package/dist/prompt/pasted-path.js.map +1 -0
- package/dist/prompt/use-prompt.js +62 -0
- package/dist/prompt/use-prompt.js.map +1 -0
- package/dist/serve.js +38 -0
- package/dist/serve.js.map +1 -0
- package/dist/state/session.js +93 -0
- package/dist/state/session.js.map +1 -0
- package/dist/status/data.js +39 -0
- package/dist/status/data.js.map +1 -0
- package/dist/status/git.js +18 -0
- package/dist/status/git.js.map +1 -0
- package/dist/status/items.js +8 -0
- package/dist/status/items.js.map +1 -0
- package/dist/status/line.js +25 -0
- package/dist/status/line.js.map +1 -0
- package/dist/status/saved.js +8 -0
- package/dist/status/saved.js.map +1 -0
- package/dist/status/segment.js +2 -0
- package/dist/status/segment.js.map +1 -0
- package/dist/status/segments/conversation.js +71 -0
- package/dist/status/segments/conversation.js.map +1 -0
- package/dist/status/segments/git.js +33 -0
- package/dist/status/segments/git.js.map +1 -0
- package/dist/status/segments/identity.js +71 -0
- package/dist/status/segments/identity.js.map +1 -0
- package/dist/status/segments/index.js +27 -0
- package/dist/status/segments/index.js.map +1 -0
- package/dist/status/segments/usage.js +61 -0
- package/dist/status/segments/usage.js.map +1 -0
- package/dist/terminal/apple-terminal.js +65 -0
- package/dist/terminal/apple-terminal.js.map +1 -0
- package/dist/ui/banner.js +36 -0
- package/dist/ui/banner.js.map +1 -0
- package/dist/ui/entries/changes-card.js +27 -0
- package/dist/ui/entries/changes-card.js.map +1 -0
- package/dist/ui/entries/entry-view.js +82 -0
- package/dist/ui/entries/entry-view.js.map +1 -0
- package/dist/ui/entries/status-entries.js +33 -0
- package/dist/ui/entries/status-entries.js.map +1 -0
- package/dist/ui/entries/tools/agent-view.js +39 -0
- package/dist/ui/entries/tools/agent-view.js.map +1 -0
- package/dist/ui/entries/tools/mcp-view.js +10 -0
- package/dist/ui/entries/tools/mcp-view.js.map +1 -0
- package/dist/ui/entries/tools/result-preview.js +19 -0
- package/dist/ui/entries/tools/result-preview.js.map +1 -0
- package/dist/ui/entries/tools/search.js +42 -0
- package/dist/ui/entries/tools/search.js.map +1 -0
- package/dist/ui/entries/tools/shell-footer.js +36 -0
- package/dist/ui/entries/tools/shell-footer.js.map +1 -0
- package/dist/ui/entries/tools/tool-view.js +47 -0
- package/dist/ui/entries/tools/tool-view.js.map +1 -0
- package/dist/ui/entries/tools/web.js +41 -0
- package/dist/ui/entries/tools/web.js.map +1 -0
- package/dist/ui/modes.js +13 -0
- package/dist/ui/modes.js.map +1 -0
- package/dist/ui/task-marks.js +7 -0
- package/dist/ui/task-marks.js.map +1 -0
- package/dist/ui/use-async.js +17 -0
- package/dist/ui/use-async.js.map +1 -0
- package/dist/ui/use-map-overview.js +27 -0
- package/dist/ui/use-map-overview.js.map +1 -0
- package/dist/ui/use-pager.js +25 -0
- package/dist/ui/use-pager.js.map +1 -0
- package/dist/ui/use-project-files.js +18 -0
- package/dist/ui/use-project-files.js.map +1 -0
- package/dist/ui/use-workdir.js +9 -0
- package/dist/ui/use-workdir.js.map +1 -0
- package/dist/update/updater.js +68 -0
- package/dist/update/updater.js.map +1 -0
- package/dist/update/versions.js +31 -0
- package/dist/update/versions.js.map +1 -0
- package/package.json +35 -3
- package/README.md +0 -3
|
@@ -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,80 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Panel, Text, useInput, usePanel, useTheme } from '@jinion/tui';
|
|
3
|
+
import { useSetAtom } from 'jotai';
|
|
4
|
+
import { rulesRequest } from '@jinion/core/map/rules-request';
|
|
5
|
+
import { grouped, percent, plural } from '@jinion/core/lib/format';
|
|
6
|
+
import { draftAtom } from '../prompt/draft.js';
|
|
7
|
+
import { useMapOverview } from '../ui/use-map-overview.js';
|
|
8
|
+
import { PAGER_HINTS, usePager } from '../ui/use-pager.js';
|
|
9
|
+
const CHROME_ROWS = 6;
|
|
10
|
+
/** What the project map read: what the project is built with, how it is written, how it looks and what it offers. */
|
|
11
|
+
export function MapPanel() {
|
|
12
|
+
const theme = useTheme();
|
|
13
|
+
const { close } = usePanel();
|
|
14
|
+
const setDraft = useSetAtom(draftAtom);
|
|
15
|
+
const map = useMapOverview();
|
|
16
|
+
const overview = map.state === 'ready' ? map.overview : undefined;
|
|
17
|
+
const lines = overview ? linesOf(overview, theme) : [];
|
|
18
|
+
const pager = usePager(lines.length, { chrome: CHROME_ROWS });
|
|
19
|
+
useInput((input, key) => {
|
|
20
|
+
if (key.escape)
|
|
21
|
+
return close();
|
|
22
|
+
if (input === 'a' && overview?.unheld) {
|
|
23
|
+
setDraft(rulesRequest(overview.unheld));
|
|
24
|
+
return close();
|
|
25
|
+
}
|
|
26
|
+
pager.scroll(key);
|
|
27
|
+
});
|
|
28
|
+
const hints = [...(pager.range ? PAGER_HINTS : []), ...(overview?.unheld ? [['a', 'add the rules']] : []), ['Esc', 'close']];
|
|
29
|
+
return (_jsx(Panel, { title: "Project map", subtitle: pager.range, grow: true, hints: hints, children: map.state === 'reading' ? (_jsx(Text, { color: theme.muted, children: "Still reading the project. This takes a moment the first time." })) : map.state === 'none' ? (_jsx(Text, { color: theme.muted, children: "There is no map of this project." })) : (lines.slice(pager.top, pager.top + pager.view).map(({ key, node }) => (_jsx(Text, { wrap: "truncate-end", children: node }, key)))) }));
|
|
30
|
+
}
|
|
31
|
+
/** One row each, so the pager scrolls by rows: a heading, then its lines, a blank row between sections. */
|
|
32
|
+
function linesOf(overview, theme) {
|
|
33
|
+
const { built, pieces, habits, unheld, look, undecided } = overview;
|
|
34
|
+
const sections = [];
|
|
35
|
+
const muted = (text) => _jsx(Text, { color: theme.muted, children: text });
|
|
36
|
+
if (built.length > 0)
|
|
37
|
+
sections.push(['Built with', [built.join(', ')]]);
|
|
38
|
+
if (habits.length > 0) {
|
|
39
|
+
sections.push([
|
|
40
|
+
'How it is written',
|
|
41
|
+
habits.map(({ text, count, total }) => (_jsxs(_Fragment, { children: [text.replaceAll('`', ''), " ", muted(`${percent(count, total)} of ${grouped(total)}`)] }))),
|
|
42
|
+
]);
|
|
43
|
+
}
|
|
44
|
+
if (unheld) {
|
|
45
|
+
sections.push([
|
|
46
|
+
`Rules ${unheld.linter} doesn't have yet`,
|
|
47
|
+
[
|
|
48
|
+
...unheld.rules.map(({ name, option }) => (_jsxs(_Fragment, { children: [name, option && muted(` ${option}`)] }))),
|
|
49
|
+
muted('Press a to ask the agent to add them.'),
|
|
50
|
+
],
|
|
51
|
+
]);
|
|
52
|
+
}
|
|
53
|
+
const looks = [];
|
|
54
|
+
if (look.tokens) {
|
|
55
|
+
const groups = look.tokens.groups.map(({ name, count }) => `${name} ${count}`).join(', ');
|
|
56
|
+
looks.push(_jsxs(_Fragment, { children: [plural(look.tokens.count, 'design token'), " ", muted(`in ${look.tokens.home}: ${groups}`)] }));
|
|
57
|
+
}
|
|
58
|
+
for (const family of look.families) {
|
|
59
|
+
const members = family.members.map(({ name, uses }) => `${name} ${uses}`).join(', ');
|
|
60
|
+
looks.push(_jsxs(_Fragment, { children: [family.name, " ", muted(`${members}${family.more > 0 ? `, +${family.more}` : ''}`)] }));
|
|
61
|
+
}
|
|
62
|
+
if (look.loose)
|
|
63
|
+
looks.push(muted(`${plural(look.loose.colors, 'color')} written out in ${plural(look.loose.files, 'file')} rather than taken from a token`));
|
|
64
|
+
if (undecided)
|
|
65
|
+
looks.push(muted('Nothing yet: the project has no component or styled markup, so its look is still to be decided.'));
|
|
66
|
+
if (looks.length > 0)
|
|
67
|
+
sections.push(['How it looks', looks]);
|
|
68
|
+
if (pieces.count > 0) {
|
|
69
|
+
sections.push([
|
|
70
|
+
`${plural(pieces.count, 'piece')} its files offer each other, in ${plural(pieces.files, 'file')}`,
|
|
71
|
+
pieces.folders.map(({ folder, names, more }) => (_jsxs(_Fragment, { children: [folder, "/ ", muted(`${names.join(', ')}${more > 0 ? `, and ${more} more` : ''}`)] }))),
|
|
72
|
+
]);
|
|
73
|
+
}
|
|
74
|
+
return sections.flatMap(([title, rows], index) => [
|
|
75
|
+
...(index > 0 ? [{ key: `${title}:gap`, node: ' ' }] : []),
|
|
76
|
+
{ key: title, node: _jsx(Text, { bold: true, children: title }) },
|
|
77
|
+
...rows.map((node, row) => ({ key: `${title}:${row}`, node })),
|
|
78
|
+
]);
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=map.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"map.js","sourceRoot":"","sources":["../../src/panels/map.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAgB,MAAM,aAAa,CAAC;AACtF,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAEnC,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE3D,MAAM,WAAW,GAAG,CAAC,CAAC;AAEtB,qHAAqH;AACrH,MAAM,UAAU,QAAQ;IACtB,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,MAAM,EAAE,KAAK,EAAE,GAAG,QAAQ,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;IAEvC,MAAM,GAAG,GAAG,cAAc,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IAClE,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACvD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;IAE9D,QAAQ,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtB,IAAI,GAAG,CAAC,MAAM;YAAE,OAAO,KAAK,EAAE,CAAC;QAE/B,IAAI,KAAK,KAAK,GAAG,IAAI,QAAQ,EAAE,MAAM,EAAE,CAAC;YACtC,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YAExC,OAAO,KAAK,EAAE,CAAC;QACjB,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;IAEH,MAAM,KAAK,GAAc,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAE,CAAC,CAAC,GAAG,EAAE,eAAe,CAAC,CAAe,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;IAEvJ,OAAO,CACL,KAAC,KAAK,IAAC,KAAK,EAAC,aAAa,EAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,QAAC,KAAK,EAAE,KAAK,YAChE,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CACzB,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,+EAAuE,CAChG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,CACzB,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,iDAAyC,CAClE,CAAC,CAAC,CAAC,CACF,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CACpE,KAAC,IAAI,IAAW,IAAI,EAAC,cAAc,YAChC,IAAI,IADI,GAAG,CAEP,CACR,CAAC,CACH,GACK,CACT,CAAC;AACJ,CAAC;AAOD,2GAA2G;AAC3G,SAAS,OAAO,CAAC,QAAyB,EAAE,KAAkC;IAC5E,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC;IACpE,MAAM,QAAQ,GAA4B,EAAE,CAAC;IAC7C,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,YAAG,IAAI,GAAQ,CAAC;IAExE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAExE,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,QAAQ,CAAC,IAAI,CAAC;YACZ,mBAAmB;YACnB,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CACrC,8BACG,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,OAAG,KAAK,CAAC,GAAG,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,IACjF,CACJ,CAAC;SACH,CAAC,CAAC;IACL,CAAC;IAED,IAAI,MAAM,EAAE,CAAC;QACX,QAAQ,CAAC,IAAI,CAAC;YACZ,SAAS,MAAM,CAAC,MAAM,mBAAmB;YACzC;gBACE,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CACxC,8BACG,IAAI,EACJ,MAAM,IAAI,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC,IAC7B,CACJ,CAAC;gBACF,KAAK,CAAC,uCAAuC,CAAC;aAC/C;SACF,CAAC,CAAC;IACL,CAAC;IAED,MAAM,KAAK,GAAgB,EAAE,CAAC;IAE9B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,IAAI,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE1F,KAAK,CAAC,IAAI,CACR,8BACG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,cAAc,CAAC,OAAG,KAAK,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC,IACtF,CACJ,CAAC;IACJ,CAAC;IAED,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAErF,KAAK,CAAC,IAAI,CACR,8BACG,MAAM,CAAC,IAAI,OAAG,KAAK,CAAC,GAAG,OAAO,GAAG,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAC9E,CACJ,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,CAAC,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,mBAAmB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,iCAAiC,CAAC,CAAC,CAAC;IAC7J,IAAI,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,iGAAiG,CAAC,CAAC,CAAC;IACpI,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC,CAAC;IAE7D,IAAI,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;QACrB,QAAQ,CAAC,IAAI,CAAC;YACZ,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,mCAAmC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE;YACjG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAC9C,8BACG,MAAM,QAAI,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAC7E,CACJ,CAAC;SACH,CAAC,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;QAChD,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,KAAC,IAAI,IAAC,IAAI,kBAAE,KAAK,GAAQ,EAAE;QAC/C,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,IAAI,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;KAC/D,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, ChoiceList, Panel, Text, useChoiceList, useInput, useTheme } from '@jinion/tui';
|
|
3
|
+
import { plural } from '@jinion/core/lib/format';
|
|
4
|
+
import { useEffect, useState } from 'react';
|
|
5
|
+
import { useApi } from '../../app/api.js';
|
|
6
|
+
import { useAsync } from '../../ui/use-async.js';
|
|
7
|
+
/** Onboarding's last step, in the prompt's place: what works already from Claude Code, its notes in one key, and what stays behind. */
|
|
8
|
+
export function ClaudeSetupPanel() {
|
|
9
|
+
const api = useApi();
|
|
10
|
+
const theme = useTheme();
|
|
11
|
+
const setup = useAsync(() => api.request('setup/claude', {}), []);
|
|
12
|
+
const [importing, setImporting] = useState(false);
|
|
13
|
+
const found = setup.state === 'done' ? setup.value : undefined;
|
|
14
|
+
const fresh = found ? found.notes.user + found.notes.project : 0;
|
|
15
|
+
const empty = found !== undefined && !anything(found);
|
|
16
|
+
const choices = fresh > 0 ? ['import', 'skip'] : ['continue'];
|
|
17
|
+
const done = () => api.act(api.request('setup/claude-done', {}));
|
|
18
|
+
const bring = async () => {
|
|
19
|
+
setImporting(true);
|
|
20
|
+
const { added } = await api.request('memory/import', {});
|
|
21
|
+
api.act(api.inSession('session/notice', { text: `Brought in ${plural(added, 'note')} from Claude Code. The agent sees them from the next conversation on.`, tone: 'success' }));
|
|
22
|
+
done();
|
|
23
|
+
};
|
|
24
|
+
const list = useChoiceList({
|
|
25
|
+
keys: choices,
|
|
26
|
+
mode: 'single',
|
|
27
|
+
isActive: found !== undefined && !importing,
|
|
28
|
+
onCancel: done,
|
|
29
|
+
onSubmit: ([choice]) => (choice === 'import' ? void bring().catch(done) : done()),
|
|
30
|
+
});
|
|
31
|
+
// Someone who never used Claude Code has nothing to bring, so the step isn't shown.
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
if (empty || setup.state === 'failed')
|
|
34
|
+
done();
|
|
35
|
+
}, [empty, setup.state]);
|
|
36
|
+
useInput((input, key) => {
|
|
37
|
+
if (key.ctrl && input === 'c')
|
|
38
|
+
api.quit();
|
|
39
|
+
});
|
|
40
|
+
if (!found || empty) {
|
|
41
|
+
return (_jsx(Panel, { title: "Bring your setup from Claude Code", children: _jsx(Text, { color: theme.muted, children: "Looking at your Claude Code setup\u2026" }) }));
|
|
42
|
+
}
|
|
43
|
+
const works = [
|
|
44
|
+
found.login && `Claude Code's login${found.login.email ? `, as ${found.login.email}` : ''}${found.login.plan ? ` (${found.login.plan})` : ''}`,
|
|
45
|
+
found.skills > 0 && plural(found.skills, 'skill'),
|
|
46
|
+
found.plugins > 0 && plural(found.plugins, 'plugin'),
|
|
47
|
+
found.mcpServers > 0 && plural(found.mcpServers, 'MCP server'),
|
|
48
|
+
found.instructions && "This project's CLAUDE.md",
|
|
49
|
+
].filter((line) => typeof line === 'string');
|
|
50
|
+
return (_jsxs(Panel, { title: "Bring your setup from Claude Code", header: _jsx(Text, { color: theme.muted, children: "Most of it already works in Jinion." }), hints: [['Enter', 'continue'], ...(choices.length > 1 ? [['Up/Down', 'move']] : []), ['Esc', 'not now']], children: [works.length > 0 && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Works already" }), works.map((line) => (_jsxs(Text, { children: [_jsx(Text, { color: theme.success, children: "+" }), " ", line] }, line)))] })), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { bold: true, children: "Your notes" }), _jsx(Text, { children: notesLine(found) })] }), _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { bold: true, children: "Stays behind" }), _jsx(Text, { color: theme.muted, children: "Permission rules, hooks and conversations stay in Claude Code. Jinion asks for permission its own way." })] }), _jsx(Box, { marginTop: 1, flexDirection: "column", children: importing ? (_jsx(Text, { color: theme.muted, children: "Bringing in your notes\u2026" })) : (_jsx(ChoiceList, { list: list, limit: choices.length, choices: fresh > 0
|
|
51
|
+
? [
|
|
52
|
+
{ key: 'import', label: _jsxs(Text, { children: ["Bring in ", plural(fresh, 'note')] }) },
|
|
53
|
+
{ key: 'skip', label: _jsx(Text, { children: "Not now" }), description: 'Later, /memory import brings them in' },
|
|
54
|
+
]
|
|
55
|
+
: [{ key: 'continue', label: _jsx(Text, { children: "Continue" }) }] })) })] }));
|
|
56
|
+
}
|
|
57
|
+
function anything(setup) {
|
|
58
|
+
return setup.login !== undefined || setup.skills + setup.plugins + setup.mcpServers + setup.notes.user + setup.notes.project + setup.notes.already > 0 || setup.instructions;
|
|
59
|
+
}
|
|
60
|
+
function notesLine({ notes }) {
|
|
61
|
+
const fresh = notes.user + notes.project;
|
|
62
|
+
const already = notes.already > 0 ? `, ${notes.already} already here` : '';
|
|
63
|
+
if (fresh === 0)
|
|
64
|
+
return notes.already > 0 ? 'They are all here already.' : 'Claude Code keeps no notes for you yet.';
|
|
65
|
+
const where = [notes.user > 0 && `${notes.user} for every project`, notes.project > 0 && `${notes.project} for this one`].filter(Boolean).join(', ');
|
|
66
|
+
return `${plural(fresh, 'note')} to bring in: ${where}${already}. Only these need a step; the rest above works as it is.`;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=claude-setup-panel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-setup-panel.js","sourceRoot":"","sources":["../../../src/panels/onboarding/claude-setup-panel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, ChoiceList, Panel, PromptInput, Text, useChoiceList, useInput, useTheme } from '@jinion/tui';
|
|
3
|
+
import { useApi } from '../../app/api.js';
|
|
4
|
+
import { useOnboarding } from './use-onboarding.js';
|
|
5
|
+
/** In the prompt's place once someone signed in, until their account is active. */
|
|
6
|
+
export function OnboardingPanel() {
|
|
7
|
+
const api = useApi();
|
|
8
|
+
const theme = useTheme();
|
|
9
|
+
const onboarding = useOnboarding();
|
|
10
|
+
const { questions, step } = onboarding;
|
|
11
|
+
const question = step.kind === 'question' ? questions?.[step.index] : undefined;
|
|
12
|
+
useInput((input, key) => {
|
|
13
|
+
if (key.ctrl && input === 'c')
|
|
14
|
+
return api.quit();
|
|
15
|
+
if (key.escape)
|
|
16
|
+
onboarding.back();
|
|
17
|
+
});
|
|
18
|
+
if (step.kind === 'code' || !questions) {
|
|
19
|
+
return (_jsxs(Panel, { title: "You\u2019re almost in", header: _jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: theme.muted, children: "Jinion is invite-only during the beta. Enter the invite code you were given." }), _jsx(Text, { color: theme.muted, children: "While you use it, Jinion sends how your turns go and the errors it hits, never your conversations. /telemetry turns this off." })] }), hints: [
|
|
20
|
+
['Enter', 'continue'],
|
|
21
|
+
['Ctrl+C', 'quit'],
|
|
22
|
+
], children: [step.kind === 'code' && step.problem && _jsx(Text, { color: theme.error, children: step.problem }), step.kind === 'code' && step.checking ? (_jsx(Text, { color: theme.muted, children: "Checking your invite\u2026" })) : (_jsxs(Box, { children: [_jsx(Text, { color: theme.muted, children: "invite code: " }), _jsx(PromptInput, { value: step.kind === 'code' ? step.code : '', onChange: onboarding.typeCode, onSubmit: onboarding.checkCode, placeholder: "JIN-XXXX-XXXX", paddingX: 0 })] }))] }));
|
|
23
|
+
}
|
|
24
|
+
if (step.kind === 'finishing' || !question) {
|
|
25
|
+
return (_jsx(Panel, { title: "You\u2019re almost in", children: _jsx(Text, { color: theme.muted, children: "Setting up your account\u2026" }) }));
|
|
26
|
+
}
|
|
27
|
+
return (_jsxs(Panel, { title: "A few questions", subtitle: `${step.index + 1} of ${questions.length}`, header: _jsx(Text, { color: theme.muted, children: "They help us make Jinion better for you." }), hints: hintsOf(question), children: [_jsxs(Text, { bold: true, children: [question.prompt, !question.required && _jsx(Text, { color: theme.muted, children: " (optional)" })] }), question.hint && _jsx(Text, { color: theme.muted, children: question.hint }), step.problem && _jsx(Text, { color: theme.error, children: step.problem }), _jsx(Box, { marginTop: 1, flexDirection: "column", children: question.kind === 'text' ? (_jsxs(Box, { children: [_jsx(Text, { color: theme.muted, children: '> ' }), _jsx(PromptInput, { value: String(onboarding.answers[question.id] ?? ''), onChange: (value) => onboarding.typeAnswer(question, value), onSubmit: (value) => onboarding.answer(question, step.index, value.trim()), placeholder: question.required ? 'Your answer' : 'Your answer, or Enter to skip', paddingX: 0 })] })) : (_jsx(Options, { question: question, chosen: onboarding.answers[question.id], onAnswer: (value) => onboarding.answer(question, step.index, value) }, question.id)) })] }));
|
|
28
|
+
}
|
|
29
|
+
/** One of the options for `choice`, any of them for `choices`; keyed by its question, so each starts afresh. */
|
|
30
|
+
function Options({ question, chosen, onAnswer }) {
|
|
31
|
+
const multiple = question.kind === 'choices';
|
|
32
|
+
const list = useChoiceList({
|
|
33
|
+
keys: question.options,
|
|
34
|
+
mode: multiple ? 'multiple' : 'single',
|
|
35
|
+
initialFocus: typeof chosen === 'string' ? chosen : undefined,
|
|
36
|
+
initialChecked: Array.isArray(chosen) ? chosen : [],
|
|
37
|
+
onCancel: () => { },
|
|
38
|
+
onSubmit: (picked) => onAnswer(multiple ? picked : (picked[0] ?? '')),
|
|
39
|
+
});
|
|
40
|
+
return _jsx(ChoiceList, { list: list, limit: question.options.length, choices: question.options.map((option) => ({ key: option, label: option })) });
|
|
41
|
+
}
|
|
42
|
+
function hintsOf(question) {
|
|
43
|
+
if (question.kind === 'choices') {
|
|
44
|
+
return [
|
|
45
|
+
['Space', 'pick'],
|
|
46
|
+
['Enter', 'continue'],
|
|
47
|
+
['Esc', 'back'],
|
|
48
|
+
];
|
|
49
|
+
}
|
|
50
|
+
return [
|
|
51
|
+
['Enter', 'continue'],
|
|
52
|
+
...(question.kind === 'choice' ? [['Up/Down', 'move']] : []),
|
|
53
|
+
['Esc', 'back'],
|
|
54
|
+
];
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=onboarding-panel.js.map
|