@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,118 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { Box, ChoiceList, choiceIndent, Panel, PromptInput, Text, useChoiceList, useInput, usePanel, useTheme } from '@jinion/tui';
|
|
4
|
+
import { useAtomValue } from 'jotai';
|
|
5
|
+
import { limitsKey } from '@jinion/core/agent/usage';
|
|
6
|
+
import { useApi } from '../../app/api.js';
|
|
7
|
+
import { accountAtom, agentAtom, seenLimitsAtom } from '../../state/session.js';
|
|
8
|
+
import { describeAccount } from './describe.js';
|
|
9
|
+
import { SignInView } from './sign-in-view.js';
|
|
10
|
+
import { useSignIn } from './use-sign-in.js';
|
|
11
|
+
const ADD = '+add';
|
|
12
|
+
export function AccountPicker({ signIn: initial }) {
|
|
13
|
+
const api = useApi();
|
|
14
|
+
const theme = useTheme();
|
|
15
|
+
const { close } = usePanel();
|
|
16
|
+
const current = useAtomValue(accountAtom);
|
|
17
|
+
const seen = useAtomValue(seenLimitsAtom);
|
|
18
|
+
const agent = useAtomValue(agentAtom).name;
|
|
19
|
+
const [list, setList] = useState();
|
|
20
|
+
const [naming, setNaming] = useState();
|
|
21
|
+
const [removing, setRemoving] = useState();
|
|
22
|
+
const refresh = () => api.request('accounts/list', {}).then(setList, () => setList([]));
|
|
23
|
+
const login = useSignIn((name, signedIn) => {
|
|
24
|
+
if (signedIn)
|
|
25
|
+
choices.setFocus(name);
|
|
26
|
+
void refresh();
|
|
27
|
+
});
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
void refresh();
|
|
30
|
+
if (initial)
|
|
31
|
+
login.start(initial);
|
|
32
|
+
}, []);
|
|
33
|
+
const choices = useChoiceList({
|
|
34
|
+
keys: [...(list ?? []).map((account) => account.name), ADD],
|
|
35
|
+
mode: 'single',
|
|
36
|
+
initialFocus: current,
|
|
37
|
+
isActive: !login.signing && naming === undefined,
|
|
38
|
+
onCancel: close,
|
|
39
|
+
onSubmit: ([name]) => {
|
|
40
|
+
if (name === ADD)
|
|
41
|
+
return setNaming('');
|
|
42
|
+
const account = list?.find((candidate) => candidate.name === name);
|
|
43
|
+
if (!account)
|
|
44
|
+
return;
|
|
45
|
+
if (!account.signedIn)
|
|
46
|
+
return login.start(account.name);
|
|
47
|
+
close();
|
|
48
|
+
if (account.name !== current)
|
|
49
|
+
api.act(api.request('accounts/select', { name: account.name }));
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
useInput((input) => {
|
|
53
|
+
const account = list?.find((candidate) => candidate.name === choices.focus);
|
|
54
|
+
if (!account || removing?.running)
|
|
55
|
+
return;
|
|
56
|
+
const { name } = account;
|
|
57
|
+
if (input === 'l')
|
|
58
|
+
return login.start(name);
|
|
59
|
+
if (input !== 'd')
|
|
60
|
+
return setRemoving(undefined);
|
|
61
|
+
const refused = account.own
|
|
62
|
+
? `${agent}'s own login stays; l signs in again`
|
|
63
|
+
: name === current
|
|
64
|
+
? 'in use; switch to another account first'
|
|
65
|
+
: undefined;
|
|
66
|
+
if (refused || removing?.name !== name)
|
|
67
|
+
return setRemoving({ name, refused });
|
|
68
|
+
setRemoving({ name, running: true });
|
|
69
|
+
const removed = api.request('accounts/remove', { name });
|
|
70
|
+
api.act(removed);
|
|
71
|
+
void removed.finally(async () => {
|
|
72
|
+
await refresh();
|
|
73
|
+
setRemoving(undefined);
|
|
74
|
+
});
|
|
75
|
+
}, { isActive: !login.signing && naming === undefined });
|
|
76
|
+
useInput((_, key) => {
|
|
77
|
+
if (!key.escape)
|
|
78
|
+
return;
|
|
79
|
+
if (login.signing)
|
|
80
|
+
login.cancel();
|
|
81
|
+
else
|
|
82
|
+
setNaming(undefined);
|
|
83
|
+
}, { isActive: login.signing !== undefined || naming !== undefined });
|
|
84
|
+
if (login.signing)
|
|
85
|
+
return _jsx(SignInView, { signing: login.signing, onType: login.type, onSend: login.send });
|
|
86
|
+
const rows = [
|
|
87
|
+
...(list ?? []).map((account) => ({
|
|
88
|
+
key: account.name,
|
|
89
|
+
label: account.name,
|
|
90
|
+
description: describeAccount(account, seen[limitsKey(agent, account.name)]),
|
|
91
|
+
aside: removing?.name === account.name ? (_jsx(Text, { color: removing.refused ? theme.warning : theme.error, children: removing.refused ?? (removing.running ? 'signing out…' : 'press d again to remove') })) : account.name === current ? ('current') : undefined,
|
|
92
|
+
})),
|
|
93
|
+
{
|
|
94
|
+
key: ADD,
|
|
95
|
+
label: 'Add an account',
|
|
96
|
+
description: 'Signs another login in, in the browser',
|
|
97
|
+
editor: naming !== undefined ? (_jsxs(Box, { paddingLeft: choiceIndent(choices), children: [_jsx(Text, { color: theme.muted, children: "name: " }), _jsx(PromptInput, { value: naming, onChange: setNaming, onSubmit: (value) => {
|
|
98
|
+
const name = value.trim();
|
|
99
|
+
setNaming(undefined);
|
|
100
|
+
if (name)
|
|
101
|
+
login.start(name);
|
|
102
|
+
}, placeholder: "e.g. work or personal", paddingX: 0 })] })) : undefined,
|
|
103
|
+
},
|
|
104
|
+
];
|
|
105
|
+
return (_jsx(Panel, { title: "Account", subtitle: agent, hints: naming !== undefined
|
|
106
|
+
? [
|
|
107
|
+
['Enter', 'sign in'],
|
|
108
|
+
['Esc', 'back'],
|
|
109
|
+
]
|
|
110
|
+
: [
|
|
111
|
+
['Enter', 'switch'],
|
|
112
|
+
['l', 'sign in again'],
|
|
113
|
+
['d', 'remove'],
|
|
114
|
+
['Up/Down', 'move'],
|
|
115
|
+
['Esc', 'close'],
|
|
116
|
+
], children: list === undefined ? _jsx(Text, { color: theme.muted, children: "Asking who is signed in\u2026" }) : _jsx(ChoiceList, { list: choices, choices: rows, limit: 6 }) }));
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=account-picker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-picker.js","sourceRoot":"","sources":["../../../src/panels/account/account-picker.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { accountLabel } from '@jinion/core/agent/accounts';
|
|
2
|
+
import { ago } from '@jinion/core/lib/format';
|
|
3
|
+
export function describeAccount(account, seen) {
|
|
4
|
+
if (!account.signedIn)
|
|
5
|
+
return 'Not signed in; press enter to sign in';
|
|
6
|
+
// The email is in the label for a personal plan; a shared one shows it next to the organization.
|
|
7
|
+
const shared = account.plan === 'Team' || account.plan === 'Enterprise';
|
|
8
|
+
const who = [accountLabel(account), shared ? account.email : undefined].filter(Boolean).join(' · ');
|
|
9
|
+
if (!seen)
|
|
10
|
+
return who;
|
|
11
|
+
const left = seen.windows.map((window) => `${window.label} ${Math.round((1 - window.used) * 100)}% left`).join(' · ');
|
|
12
|
+
return `${who} · ${left} ${ago(seen.at)}`;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=describe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"describe.js","sourceRoot":"","sources":["../../../src/panels/account/describe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAqB,MAAM,6BAA6B,CAAC;AAC9E,OAAO,EAAE,GAAG,EAAE,MAAM,yBAAyB,CAAC;AAG9C,MAAM,UAAU,eAAe,CAAC,OAAqB,EAAE,IAA2B;IAChF,IAAI,CAAC,OAAO,CAAC,QAAQ;QAAE,OAAO,uCAAuC,CAAC;IAEtE,iGAAiG;IACjG,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY,CAAC;IACxE,MAAM,GAAG,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpG,IAAI,CAAC,IAAI;QAAE,OAAO,GAAG,CAAC;IAEtB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAEtH,OAAO,GAAG,GAAG,MAAM,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Panel, PromptInput, Text, useTheme } from '@jinion/tui';
|
|
3
|
+
export function SignInView({ signing, onType, onSend }) {
|
|
4
|
+
const theme = useTheme();
|
|
5
|
+
const { prompt } = signing;
|
|
6
|
+
return (_jsxs(Panel, { title: "Account", subtitle: signing.name, hints: prompt && !signing.sent ? [['Enter', 'send'], ['Esc', 'cancel']] : [['Esc', 'cancel']], children: [_jsxs(Text, { children: ["Signing in to ", _jsx(Text, { bold: true, children: signing.name }), ". 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 })] })), prompt && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [prompt.problem && _jsx(Text, { color: theme.error, children: prompt.problem }), signing.sent ? (_jsx(Text, { color: theme.muted, children: "Checking the code\u2026" })) : (_jsxs(Box, { children: [_jsxs(Text, { color: theme.muted, children: [prompt.text, ": "] }), _jsx(PromptInput, { value: signing.code, onChange: onType, onSubmit: onSend, placeholder: "code", paddingX: 0 })] }))] }))] }));
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=sign-in-view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sign-in-view.js","sourceRoot":"","sources":["../../../src/panels/account/sign-in-view.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGtE,MAAM,UAAU,UAAU,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAgF;IAClI,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IAEzB,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAE3B,OAAO,CACL,MAAC,KAAK,IAAC,KAAK,EAAC,SAAS,EAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,aAC1I,MAAC,IAAI,iCACW,KAAC,IAAI,IAAC,IAAI,kBAAE,OAAO,CAAC,IAAI,GAAQ,oCACzC,EACN,OAAO,CAAC,IAAI,IAAI,CACf,MAAC,IAAI,eACH,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,6CAAqC,EAC7D,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,IAAI,YAAG,OAAO,CAAC,IAAI,GAAQ,IACzC,CACR,EACA,MAAM,IAAI,CACT,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,SAAS,EAAE,CAAC,aACrC,MAAM,CAAC,OAAO,IAAI,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,YAAG,MAAM,CAAC,OAAO,GAAQ,EACnE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CACd,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,wCAA2B,CACpD,CAAC,CAAC,CAAC,CACF,MAAC,GAAG,eACF,MAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,aAAG,MAAM,CAAC,IAAI,UAAU,EAChD,KAAC,WAAW,IAAC,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAC,MAAM,EAAC,QAAQ,EAAE,CAAC,GAAI,IACpG,CACP,IACG,CACP,IACK,CACT,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { useEffect, useRef, useState } from 'react';
|
|
2
|
+
import { useApi } from '../../app/api.js';
|
|
3
|
+
/** Signing in runs in the core; its link and what to type come back as notifications while it waits. */
|
|
4
|
+
export function useSignIn(ended) {
|
|
5
|
+
const api = useApi();
|
|
6
|
+
const [signing, setSigning] = useState();
|
|
7
|
+
const current = useRef(undefined);
|
|
8
|
+
const update = (name, patch) => setSigning((now) => (now?.name === name ? { ...now, ...patch } : now));
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
const stopLink = api.client.on('accounts/sign-in-link', ({ name, url }) => update(name, { link: url }));
|
|
11
|
+
const stopPrompt = api.client.on('accounts/sign-in-prompt', ({ name, prompt, problem }) => {
|
|
12
|
+
const answer = (text) => api.act(api.request('accounts/sign-in-answer', { name, text }));
|
|
13
|
+
update(name, { prompt: { text: prompt, answer, problem }, code: '', sent: false });
|
|
14
|
+
});
|
|
15
|
+
return () => {
|
|
16
|
+
stopLink();
|
|
17
|
+
stopPrompt();
|
|
18
|
+
if (current.current)
|
|
19
|
+
api.act(api.request('accounts/sign-in-cancel', { name: current.current }));
|
|
20
|
+
};
|
|
21
|
+
}, []);
|
|
22
|
+
const start = (name) => {
|
|
23
|
+
current.current = name;
|
|
24
|
+
setSigning({ name, code: '', sent: false });
|
|
25
|
+
void api.request('accounts/sign-in', { name }).then(({ signedIn }) => finish(name, signedIn), () => finish(name, false));
|
|
26
|
+
};
|
|
27
|
+
const finish = (name, signedIn) => {
|
|
28
|
+
if (current.current === name)
|
|
29
|
+
current.current = undefined;
|
|
30
|
+
setSigning(undefined);
|
|
31
|
+
ended(name, signedIn);
|
|
32
|
+
};
|
|
33
|
+
return {
|
|
34
|
+
signing,
|
|
35
|
+
start,
|
|
36
|
+
cancel: () => current.current && api.act(api.request('accounts/sign-in-cancel', { name: current.current })),
|
|
37
|
+
type: (code) => signing && update(signing.name, { code }),
|
|
38
|
+
send: (code) => {
|
|
39
|
+
if (!code.trim() || !signing?.prompt)
|
|
40
|
+
return;
|
|
41
|
+
signing.prompt.answer(code);
|
|
42
|
+
update(signing.name, { sent: true });
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=use-sign-in.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-sign-in.js","sourceRoot":"","sources":["../../../src/panels/account/use-sign-in.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Panel, Text, useInput, usePanel, useTheme, Waffle } from '@jinion/tui';
|
|
3
|
+
import { useAtomValue } from 'jotai';
|
|
4
|
+
import { compact, percent } from '@jinion/core/lib/format';
|
|
5
|
+
import { useApi } from '../app/api.js';
|
|
6
|
+
import { agentAtom, modelNameAtom } from '../state/session.js';
|
|
7
|
+
import { useAsync } from '../ui/use-async.js';
|
|
8
|
+
export function ContextPanel() {
|
|
9
|
+
const api = useApi();
|
|
10
|
+
const theme = useTheme();
|
|
11
|
+
const { close } = usePanel();
|
|
12
|
+
const modelName = useAtomValue(modelNameAtom);
|
|
13
|
+
const { name, features } = useAtomValue(agentAtom);
|
|
14
|
+
const read = features.context;
|
|
15
|
+
const usage = useAsync(() => (read ? api.inSession('session/context', {}) : undefined), []);
|
|
16
|
+
const loaded = usage.state === 'done' ? usage.value : undefined;
|
|
17
|
+
useInput((_, key) => {
|
|
18
|
+
if (key.escape || key.return)
|
|
19
|
+
close();
|
|
20
|
+
});
|
|
21
|
+
return (_jsx(Panel, { title: "Context", subtitle: loaded && `${modelName} · ${compact(loaded.used)} of ${compact(loaded.window)} tokens · ${percent(loaded.used, loaded.window)}`, hints: [['Esc', 'close']], children: !read ? (_jsxs(Text, { color: theme.muted, children: [name, " doesn't say what fills its context."] })) : usage.state === 'failed' ? (_jsxs(Text, { color: theme.error, children: ["Couldn't ask ", name, " about its context: ", usage.error] })) : !loaded ? (_jsxs(Text, { color: theme.muted, children: ["Asking ", name, " what fills its context\u2026"] })) : (_jsx(ContextChart, { usage: loaded })) }));
|
|
22
|
+
}
|
|
23
|
+
function ContextChart({ usage }) {
|
|
24
|
+
const theme = useTheme();
|
|
25
|
+
const colorOf = colors(theme);
|
|
26
|
+
const shown = usage.categories.filter((category) => category.kind !== 'deferred' && category.tokens > 0);
|
|
27
|
+
const deferred = usage.categories.filter((category) => category.kind === 'deferred' && category.tokens > 0);
|
|
28
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Waffle, { legend: true, parts: shown.map((category) => ({
|
|
29
|
+
label: category.name,
|
|
30
|
+
value: category.tokens,
|
|
31
|
+
color: colorOf(category.name),
|
|
32
|
+
text: (_jsxs(Text, { color: theme.muted, children: [compact(category.tokens), " tokens \u00B7 ", percent(category.tokens, usage.window)] })),
|
|
33
|
+
})) }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: theme.muted, wrap: "truncate-end", children: usage.compactAt
|
|
34
|
+
? `Compacts on its own at ${compact(usage.compactAt)} tokens (${percent(usage.compactAt, usage.window)}); /compact does it now, with a focus if you give one.`
|
|
35
|
+
: "It doesn't compact on its own; /compact does it, with a focus if you give one." }), deferred.length > 0 && (_jsxs(Text, { color: theme.muted, wrap: "truncate-end", children: ["Listed by name and loaded when used, so they take no room yet:", ' ', deferred.map((category) => `${category.name.replace(/ \(deferred\)$/, '')} ${compact(category.tokens)}`).join(' · ')] }))] })] }));
|
|
36
|
+
}
|
|
37
|
+
/** Claude Code's categories in the colors they keep here; any other takes the next of the rest. */
|
|
38
|
+
function colors(theme) {
|
|
39
|
+
const known = {
|
|
40
|
+
'System prompt': theme.accent,
|
|
41
|
+
'System tools': theme.code,
|
|
42
|
+
'MCP server instructions': theme.syntax.variable,
|
|
43
|
+
'MCP tools': theme.syntax.variable,
|
|
44
|
+
'Custom agents': theme.status.cost,
|
|
45
|
+
'Memory files': theme.success,
|
|
46
|
+
Skills: theme.heading,
|
|
47
|
+
Messages: theme.syntax.string,
|
|
48
|
+
'Free space': theme.heat[0],
|
|
49
|
+
'Autocompact buffer': theme.border,
|
|
50
|
+
};
|
|
51
|
+
const rest = [theme.warning, theme.link, theme.diff.added, theme.error];
|
|
52
|
+
let next = 0;
|
|
53
|
+
return (name) => known[name] ?? rest[next++ % rest.length];
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/panels/context.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, ListRow, Panel, SelectList, Tabs, Text, useInput, useListNavigation, usePanel, useTheme, useWindowSize } from '@jinion/tui';
|
|
3
|
+
import { CHROME_ROWS } from './file-diff.js';
|
|
4
|
+
const TURNS_SHOWN = 3;
|
|
5
|
+
export function ChangeList({ views, active, onSwitch, onOpen }) {
|
|
6
|
+
const theme = useTheme();
|
|
7
|
+
const { close } = usePanel();
|
|
8
|
+
const { rows: height } = useWindowSize();
|
|
9
|
+
const view = views[active];
|
|
10
|
+
const rows = view.rows ?? [];
|
|
11
|
+
const groups = new Set(rows.map((row) => row.group?.label)).size;
|
|
12
|
+
const limit = Math.max(3, height - CHROME_ROWS - groups - (view.note ? 1 : 0));
|
|
13
|
+
const labelWidth = Math.min(60, Math.max(10, ...rows.map((row) => row.file.length)) + 2);
|
|
14
|
+
const [selected] = useListNavigation(rows.length, { wrap: false, pageSize: limit });
|
|
15
|
+
const hints = [
|
|
16
|
+
...(views.length > 1 ? [['Left/Right', 'turn']] : []),
|
|
17
|
+
['Enter', 'open'],
|
|
18
|
+
['Up/Down', 'move'],
|
|
19
|
+
['Esc', 'close'],
|
|
20
|
+
];
|
|
21
|
+
useInput((_, key) => {
|
|
22
|
+
if (key.escape)
|
|
23
|
+
return close();
|
|
24
|
+
if (key.leftArrow)
|
|
25
|
+
return onSwitch(-1);
|
|
26
|
+
if (key.rightArrow)
|
|
27
|
+
return onSwitch(1);
|
|
28
|
+
const row = rows[selected];
|
|
29
|
+
if (key.return && row)
|
|
30
|
+
onOpen(row);
|
|
31
|
+
});
|
|
32
|
+
return (_jsx(Panel, { title: "Changes", subtitle: view.subtitle, header: views.length > 1 ? _jsx(ViewBar, { views: views, active: active }) : undefined, grow: true, hints: hints, children: !view.rows ? (_jsx(Text, { color: theme.muted, children: view.empty })) : (_jsxs(_Fragment, { children: [_jsx(SelectList, { items: rows, selected: selected, limit: limit, empty: view.empty, renderItem: (row, state) => (_jsxs(Box, { flexDirection: "column", children: [row.group && (state.first || rows[state.index - 1]?.group?.label !== row.group.label) && (_jsxs(Text, { children: [_jsx(Text, { bold: true, children: row.group.label }), row.group.aside && _jsxs(Text, { color: theme.muted, children: [" ", row.group.aside] })] })), _jsx(ListRow, { selected: state.selected, labelWidth: labelWidth, label: `${row.group ? ' ' : ''}${row.file}`, description: _jsx(ChangeStats, { row: row }), aside: row.agent ? 'agent' : undefined })] })) }), view.note && _jsx(Text, { color: theme.muted, children: view.note })] })) }));
|
|
33
|
+
}
|
|
34
|
+
function ViewBar({ views, active }) {
|
|
35
|
+
const theme = useTheme();
|
|
36
|
+
const turns = views.length - 1;
|
|
37
|
+
const first = Math.min(Math.max(1, active - 1), Math.max(1, turns - TURNS_SHOWN + 1));
|
|
38
|
+
const shown = views.slice(first, first + TURNS_SHOWN);
|
|
39
|
+
const before = first - 1;
|
|
40
|
+
const after = turns - (first - 1) - shown.length;
|
|
41
|
+
return (_jsxs(Text, { children: [_jsx(Tabs, { tabs: ['Current'], active: active === 0 ? 0 : -1 }), _jsx(Text, { color: theme.muted, children: before > 0 ? ` ‹ ${before} ` : ' ' }), _jsx(Tabs, { tabs: shown.map((view) => view.label), active: active - first }), after > 0 && _jsx(Text, { color: theme.muted, children: ` ${after} more ›` })] }));
|
|
42
|
+
}
|
|
43
|
+
function ChangeStats({ row }) {
|
|
44
|
+
const theme = useTheme();
|
|
45
|
+
const kind = row.kind === 'untracked' || row.kind === 'added' ? 'new' : row.kind === 'modified' ? undefined : row.kind;
|
|
46
|
+
return (_jsxs(Text, { children: [kind && _jsxs(Text, { color: theme.muted, children: [kind, " "] }), row.binary ? (_jsx(Text, { color: theme.muted, children: "binary" })) : (_jsxs(_Fragment, { children: [row.insertions > 0 && _jsxs(Text, { color: theme.diff.added, children: ["+", row.insertions, " "] }), row.deletions > 0 && _jsxs(Text, { color: theme.diff.removed, children: ["-", row.deletions] })] }))] }));
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=change-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"change-list.js","sourceRoot":"","sources":["../../../src/panels/diff/change-list.tsx"],"names":[],"mappings":"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"}
|
|
@@ -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":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAgB,MAAM,aAAa,CAAC;AACnI,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAMvC,MAAM,OAAO,GAAW,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;AACtD,MAAM,OAAO,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AAElC,oIAAoI;AACpI,MAAM,UAAU,aAAa,CAAC,EAAE,KAAK,EAAsB;IACzD,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;IACrB,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,MAAM,EAAE,KAAK,EAAE,GAAG,QAAQ,EAAE,CAAC;IAE7B,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAO,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACpG,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IAErC,MAAM,IAAI,GAAG,CAAC,IAAU,EAAE,KAAK,GAAG,KAAK,EAAE,EAAE;QACzC,OAAO,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;QAE7B,GAAG,CAAC,SAAS,CAAC,kBAAkB,EAAE,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,CACzH,GAAG,EAAE;YACH,KAAK,EAAE,CAAC;YACR,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,gBAAgB,EAAE,EAAE,IAAI,EAAE,6CAA6C,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;QACnH,CAAC,EACD,CAAC,KAAc,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,qBAAqB,YAAY,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CACrG,CAAC;IACJ,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG,aAAa,CAAC;QACzB,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,IAAI,CAAC,IAAI,KAAK,MAAM;QAC9B,QAAQ,EAAE,KAAK;QACf,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAY,EAAE,CAAC,CAAC;KAC3G,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,aAAa,CAAC;QAC1B,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,IAAI,CAAC,IAAI,KAAK,OAAO;QAC/B,QAAQ,EAAE,KAAK;QACf,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;KACvF,CAAC,CAAC;IAEH,QAAQ,CACN,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;QACT,IAAI,GAAG,CAAC,MAAM;YAAE,KAAK,EAAE,CAAC;IAC1B,CAAC,EACD,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAC5D,CAAC;IAEF,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO;QACjC,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YAAE,OAAO;QAEnD,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACzE,CAAC,CAAC;IAEF,OAAO,CACL,MAAC,KAAK,IAAC,KAAK,EAAC,UAAU,EAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,aACzF,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,CACvB,8BACE,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,4CAAoC,EAC5D,KAAC,UAAU,IACT,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,OAAO,CAAC,MAAM,EACrB,OAAO,EAAE;4BACP,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,KAAC,IAAI,8BAAmB,EAAE;4BACjD,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,KAAC,IAAI,sCAAsB,EAAE,WAAW,EAAE,sCAAsC,EAAE;4BAC5G,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAC,IAAI,oCAAyB,EAAE;yBACvD,GACD,IACD,CACJ,EAEA,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,CACvB,8BACE,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,YACrB,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,8CAA8C,GACvJ,EACP,MAAC,GAAG,eACF,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,YAAG,IAAI,GAAQ,EACvC,KAAC,WAAW,IAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAC,sBAAsB,EAAC,QAAQ,EAAE,CAAC,GAAI,IACjH,IACL,CACJ,EAEA,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,CACxB,8BACE,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,6EAAqE,EAC7F,KAAC,UAAU,IACT,IAAI,EAAE,KAAK,EACX,KAAK,EAAE,OAAO,CAAC,MAAM,EACrB,OAAO,EAAE;4BACP;gCACE,GAAG,EAAE,OAAO;gCACZ,KAAK,EAAE,KAAC,IAAI,0BAAe;gCAC3B,WAAW,EAAE,qGAAqG;6BACnH;4BACD,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAC,IAAI,mCAAwB,EAAE;yBACtD,GACD,IACD,CACJ,EAEA,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,8BAAiB,EACpE,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,YAAG,IAAI,CAAC,OAAO,GAAQ,IACpE,CACT,CAAC;AACJ,CAAC;AAED,SAAS,OAAO,CAAC,IAAU;IACzB,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,CAAC,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC5E,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,CAAC,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;IAE1H,OAAO,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;AAC5B,CAAC"}
|