bingocode 1.1.110 → 1.1.112
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/package.json +1 -1
- package/src/manager/CliMenuManager.tsx +1234 -1238
- package/src/manager/CliMenuUi.tsx +9 -22
- package/src/manager/TopToolbar.tsx +111 -138
|
@@ -266,29 +266,16 @@ export const TopBar: React.FC<{
|
|
|
266
266
|
compactLogo: React.ReactNode;
|
|
267
267
|
toolbar?: React.ReactNode;
|
|
268
268
|
ip?: string;
|
|
269
|
-
}> = memo(({ ready, page, width = 80, height = 5, homeLogo, compactLogo, toolbar, ip }) =>
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
{/* Left Section: Welcome Text & IP */}
|
|
275
|
-
<Box flexDirection="column" width={20} marginRight={2}>
|
|
276
|
-
<Text bold color="cyan">{isHome ? 'Welcome Bingo\nCode' : 'Bingo Code'}</Text>
|
|
277
|
-
{ip ? (
|
|
278
|
-
<Box marginTop={1}>
|
|
279
|
-
<Text color="green">IP: {ip.replace(' ','\n ')}</Text>
|
|
280
|
-
</Box>
|
|
281
|
-
) : null}
|
|
282
|
-
</Box>
|
|
283
|
-
|
|
284
|
-
{/* Center/Right Section: Logo + Toolbar (Dynamic) */}
|
|
285
|
-
<Box flexGrow={1} flexDirection="column">
|
|
286
|
-
{toolbar}
|
|
287
|
-
</Box>
|
|
269
|
+
}> = memo(({ ready, page, width = 80, height = 5, homeLogo, compactLogo, toolbar, ip }) => (
|
|
270
|
+
<Panel width={width} height={height} borderStyle="round" paddingX={1} paddingY={0}>
|
|
271
|
+
<Box width={width - 2} flexDirection="row" justifyContent="space-between" alignItems="center">
|
|
272
|
+
<Box>
|
|
273
|
+
{ready ? (page === null ? homeLogo : compactLogo) : <FallbackTop ip={ip} />}
|
|
288
274
|
</Box>
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
275
|
+
{toolbar ? <Box>{toolbar}</Box> : <Box><Hint dim>{ready ? '' : '…'}</Hint></Box>}
|
|
276
|
+
</Box>
|
|
277
|
+
</Panel>
|
|
278
|
+
));
|
|
292
279
|
|
|
293
280
|
// InfoPair (Label fixed width for column alignment)
|
|
294
281
|
export const InfoPair: React.FC<{ label: string; value: string; labelColor?: string; valueColor?: string; labelWidth?: number }> = memo(({
|
|
@@ -1,138 +1,111 @@
|
|
|
1
|
-
//@C:M ID=M.UI.TopToolbar;K=M;V=1.
|
|
2
|
-
import React, { memo, useMemo } from 'react';
|
|
3
|
-
import { Box
|
|
4
|
-
import { Chip } from './CliMenuUi.tsx';
|
|
5
|
-
import { useTheme } from '../components/design-system/ThemeProvider.
|
|
6
|
-
import { getGlobalConfig, getCurrentProjectConfig } from '../utils/config.ts';
|
|
7
|
-
import { getCwd } from '../utils/cwd.js';
|
|
8
|
-
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
);
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
{animEnabled ? <AnimatedClawd /> : <Clawd pose={clawdPose} />}
|
|
113
|
-
</Box>
|
|
114
|
-
|
|
115
|
-
{/* Visual Window Grid (Mini-mascots 1/6 size) */}
|
|
116
|
-
<Box flexDirection="row" flexWrap="wrap" maxWidth={40}>
|
|
117
|
-
{Array.from({ length: windowCount }).map((_, i) => (
|
|
118
|
-
<MiniClawd key={i} />
|
|
119
|
-
))}
|
|
120
|
-
</Box>
|
|
121
|
-
</Box>
|
|
122
|
-
|
|
123
|
-
{/* Right: Status Info Chips (Vertical Stack) */}
|
|
124
|
-
<Box flexDirection="column" alignItems="flex-end">
|
|
125
|
-
<Chip label="Theme" value={themeLabel} tone="accent" />
|
|
126
|
-
<Chip label="Project" value={projectName || '—'} tone="info" />
|
|
127
|
-
<Chip
|
|
128
|
-
label="UI"
|
|
129
|
-
value={tipsEnabled ? 'Tips On' : 'Tips Off'}
|
|
130
|
-
tone={uiTone as any}
|
|
131
|
-
/>
|
|
132
|
-
{windowCount > 0 && <Chip label="Active" value={windowCount} tone="success" />}
|
|
133
|
-
</Box>
|
|
134
|
-
</Box>
|
|
135
|
-
);
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
export default TopToolbar;
|
|
1
|
+
//@C:M ID=M.UI.TopToolbar;K=M;V=1.2;P=top toolbar;D=CLI;M=cli;S=ui
|
|
2
|
+
import React, { memo, useMemo } from 'react';
|
|
3
|
+
import { Box } from 'ink';
|
|
4
|
+
import { Chip, ChipRow } from './CliMenuUi.tsx';
|
|
5
|
+
import { useTheme } from '../components/design-system/ThemeProvider.js';
|
|
6
|
+
import { getGlobalConfig, getCurrentProjectConfig, isPathTrusted, checkHasTrustDialogAccepted } from '../utils/config.ts';
|
|
7
|
+
import { getCwd } from '../utils/cwd.js';
|
|
8
|
+
// Update: Import respectively according to the new interface
|
|
9
|
+
import type { ClawdPose } from '../components/LogoV2/Clawd.tsx';
|
|
10
|
+
import { Clawd } from '../components/LogoV2/Clawd.tsx';
|
|
11
|
+
import { AnimatedClawd } from '../components/LogoV2/AnimatedClawd.tsx';
|
|
12
|
+
|
|
13
|
+
type Props = {
|
|
14
|
+
ready: boolean;
|
|
15
|
+
page: string | null;
|
|
16
|
+
animEnabled: boolean;
|
|
17
|
+
tipsEnabled: boolean;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
function basename(p: string) {
|
|
21
|
+
if (!p) return '';
|
|
22
|
+
const parts = p.split(/[/\\]/).filter(Boolean);
|
|
23
|
+
return parts[parts.length - 1] || p;
|
|
24
|
+
}
|
|
25
|
+
function ellipsisPath(p: string, keep = 2) {
|
|
26
|
+
if (!p) return '';
|
|
27
|
+
const parts = p.split(/[/\\]/).filter(Boolean);
|
|
28
|
+
if (parts.length <= keep) return p;
|
|
29
|
+
return '…/' + parts.slice(-keep).join('/');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
//@C:F ID=F.UI.TopToolbar;K=F;V=1.2;P=toolbar;D=CLI;M=cli;S=ui;In=Props;Out=JSX.Element
|
|
33
|
+
export const TopToolbar: React.FC<Props> = memo(({ ready, page, animEnabled, tipsEnabled }) => {
|
|
34
|
+
const [theme] = useTheme();
|
|
35
|
+
|
|
36
|
+
// Only read config and trust status when ready
|
|
37
|
+
const { cwd, trustAccepted, trustedPath, projectName } = useMemo(() => {
|
|
38
|
+
if (!ready) {
|
|
39
|
+
return { cwd: '', trustAccepted: undefined as undefined|boolean, trustedPath: undefined as undefined|boolean, projectName: '' };
|
|
40
|
+
}
|
|
41
|
+
const _cwd = getCwd();
|
|
42
|
+
const _trustAccepted = checkHasTrustDialogAccepted();
|
|
43
|
+
const _trustedPath = isPathTrusted(_cwd);
|
|
44
|
+
let _projectName = '';
|
|
45
|
+
try {
|
|
46
|
+
const prj = getCurrentProjectConfig();
|
|
47
|
+
_projectName = (prj && (prj.name || prj.projectName || prj.id)) || basename(_cwd);
|
|
48
|
+
} catch {
|
|
49
|
+
_projectName = basename(_cwd);
|
|
50
|
+
}
|
|
51
|
+
return { cwd: _cwd, trustAccepted: _trustAccepted, trustedPath: _trustedPath, projectName: _projectName };
|
|
52
|
+
}, [ready]);
|
|
53
|
+
|
|
54
|
+
const compact = page !== null;
|
|
55
|
+
const cwdShort = useMemo(() => ellipsisPath(cwd, compact ? 2 : 3), [cwd, compact]);
|
|
56
|
+
|
|
57
|
+
// Theme name
|
|
58
|
+
const themeLabel = String(theme || (ready ? (getGlobalConfig()?.theme ?? 'system') : '…'));
|
|
59
|
+
|
|
60
|
+
// Static Clawd pose
|
|
61
|
+
const clawdPose: ClawdPose = useMemo(() => {
|
|
62
|
+
if (!ready) return 'default';
|
|
63
|
+
if (page === null) return animEnabled ? 'arms-up' : 'default';
|
|
64
|
+
return tipsEnabled ? 'look-left' : 'look-right';
|
|
65
|
+
}, [ready, page, animEnabled, tipsEnabled]);
|
|
66
|
+
|
|
67
|
+
const uiTone = (String(theme) === 'dark') ? 'accent' : (String(theme) === 'highContrast' ? 'warning' : 'info');
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<Box flexDirection="column" minHeight={3}>
|
|
71
|
+
<ChipRow>
|
|
72
|
+
{/* Left: Clawd + Core Status */}
|
|
73
|
+
<Box>
|
|
74
|
+
<Box marginRight={2}>
|
|
75
|
+
{animEnabled ? <AnimatedClawd /> : <Clawd pose={clawdPose} />}
|
|
76
|
+
</Box>
|
|
77
|
+
|
|
78
|
+
<Chip label="Theme" value={themeLabel} tone="accent" />
|
|
79
|
+
<Chip label="Project" value={projectName || '—'} tone="info" />
|
|
80
|
+
<Chip label="CWD" value={cwdShort || '—'} tone="subtle" />
|
|
81
|
+
{trustedPath === undefined || trustAccepted === undefined ? (
|
|
82
|
+
<Chip label="Trust" value="…" tone="subtle" />
|
|
83
|
+
) : trustedPath && trustAccepted ? (
|
|
84
|
+
<Chip label="Trust" value="✅ Trusted" tone="success" />
|
|
85
|
+
) : (
|
|
86
|
+
<Chip label="Trust" value="🔒 Untrusted" tone="warning" />
|
|
87
|
+
)}
|
|
88
|
+
</Box>
|
|
89
|
+
|
|
90
|
+
{/* Right: UI Status merged display */}
|
|
91
|
+
<Box>
|
|
92
|
+
<Chip
|
|
93
|
+
label="UI"
|
|
94
|
+
value={`Anim ${animEnabled ? 'On' : 'Off'} · Tips ${tipsEnabled ? 'On' : 'Off'}`}
|
|
95
|
+
tone={uiTone as any}
|
|
96
|
+
/>
|
|
97
|
+
</Box>
|
|
98
|
+
</ChipRow>
|
|
99
|
+
|
|
100
|
+
{!compact && (
|
|
101
|
+
<ChipRow>
|
|
102
|
+
<Box>
|
|
103
|
+
<Chip label="Shortcuts" value="N New · R Resume · P Provider · G Theme · ? Help" tone="subtle" />
|
|
104
|
+
</Box>
|
|
105
|
+
</ChipRow>
|
|
106
|
+
)}
|
|
107
|
+
</Box>
|
|
108
|
+
);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
export default TopToolbar;
|