mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-21 15:55:50 +00:00
更新大量 tsx 原始文件; 已经迁移 login panel; 部分 (#121)
* style(B1-1): 格式化 ink/buddy/cli/context/screens/tasks/services/keybindings/state (43 files) 纯格式化:移除分号、React Compiler import、import 多行展开。 修复了 Box.tsx 和 ScrollBox.tsx 中无效的 global.d.ts import。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style(B1-2): 格式化 commands (79 files) 纯格式化:移除分号、React Compiler import、import 多行展开。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style(B1-3): 格式化 components/messages,permissions,mcp,sandbox,shell (104 files) 纯格式化:移除分号、React Compiler import、import 多行展开。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style(B1-4): 格式化 components/PromptInput,FeedbackSurvey,tasks,agents,skills,design-system,wizard (73 files) 纯格式化:移除分号、React Compiler import、import 多行展开。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style(B1-5): 格式化 components其余 + hooks + tools (232 files) 纯格式化:移除分号、React Compiler import、import 多行展开。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style(B1-6): 格式化 main/entrypoints/utils/moreright (21 files) 纯格式化:移除分号、React Compiler import、import 多行展开。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: 更新 README,新增 Run.ps1/TODO.md,删除 V6.md - README.md: 大幅重写,更详细版本历史和配置示例 - Run.ps1: 新增 Windows 启动脚本 - TODO.md: 新增包完成清单 - V6.md: 删除(架构重构规划已不适用) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: 修复以前的问题 * fix: 修复 login 面板的问题 --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,25 +1,29 @@
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
import { getSentinelCategory } from '@ant/computer-use-mcp/sentinelApps';
|
||||
import type { CuPermissionRequest, CuPermissionResponse } from '@ant/computer-use-mcp/types';
|
||||
import { DEFAULT_GRANT_FLAGS } from '@ant/computer-use-mcp/types';
|
||||
import figures from 'figures';
|
||||
import * as React from 'react';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { Box, Text } from '../../../ink.js';
|
||||
import { execFileNoThrow } from '../../../utils/execFileNoThrow.js';
|
||||
import { plural } from '../../../utils/stringUtils.js';
|
||||
import type { OptionWithDescription } from '../../CustomSelect/select.js';
|
||||
import { Select } from '../../CustomSelect/select.js';
|
||||
import { Dialog } from '../../design-system/Dialog.js';
|
||||
import { getSentinelCategory } from '@ant/computer-use-mcp/sentinelApps'
|
||||
import type {
|
||||
CuPermissionRequest,
|
||||
CuPermissionResponse,
|
||||
} from '@ant/computer-use-mcp/types'
|
||||
import { DEFAULT_GRANT_FLAGS } from '@ant/computer-use-mcp/types'
|
||||
import figures from 'figures'
|
||||
import * as React from 'react'
|
||||
import { useMemo, useState } from 'react'
|
||||
import { Box, Text } from '../../../ink.js'
|
||||
import { execFileNoThrow } from '../../../utils/execFileNoThrow.js'
|
||||
import { plural } from '../../../utils/stringUtils.js'
|
||||
import type { OptionWithDescription } from '../../CustomSelect/select.js'
|
||||
import { Select } from '../../CustomSelect/select.js'
|
||||
import { Dialog } from '../../design-system/Dialog.js'
|
||||
|
||||
type ComputerUseApprovalProps = {
|
||||
request: CuPermissionRequest;
|
||||
onDone: (response: CuPermissionResponse) => void;
|
||||
};
|
||||
request: CuPermissionRequest
|
||||
onDone: (response: CuPermissionResponse) => void
|
||||
}
|
||||
|
||||
const DENY_ALL_RESPONSE: CuPermissionResponse = {
|
||||
granted: [],
|
||||
denied: [],
|
||||
flags: DEFAULT_GRANT_FLAGS
|
||||
};
|
||||
flags: DEFAULT_GRANT_FLAGS,
|
||||
}
|
||||
|
||||
/**
|
||||
* Two-panel dispatcher. When `request.tccState` is present, macOS permissions
|
||||
@@ -27,414 +31,271 @@ const DENY_ALL_RESPONSE: CuPermissionResponse = {
|
||||
* irrelevant — show a TCC panel that opens System Settings. Otherwise show the
|
||||
* app allowlist + grant-flags panel.
|
||||
*/
|
||||
export function ComputerUseApproval(t0) {
|
||||
const $ = _c(3);
|
||||
const {
|
||||
request,
|
||||
onDone
|
||||
} = t0;
|
||||
let t1;
|
||||
if ($[0] !== onDone || $[1] !== request) {
|
||||
t1 = request.tccState ? <ComputerUseTccPanel tccState={request.tccState} onDone={() => onDone(DENY_ALL_RESPONSE)} /> : <ComputerUseAppListPanel request={request} onDone={onDone} />;
|
||||
$[0] = onDone;
|
||||
$[1] = request;
|
||||
$[2] = t1;
|
||||
} else {
|
||||
t1 = $[2];
|
||||
}
|
||||
return t1;
|
||||
export function ComputerUseApproval({
|
||||
request,
|
||||
onDone,
|
||||
}: ComputerUseApprovalProps): React.ReactNode {
|
||||
return request.tccState ? (
|
||||
<ComputerUseTccPanel
|
||||
tccState={request.tccState}
|
||||
onDone={() => onDone(DENY_ALL_RESPONSE)}
|
||||
/>
|
||||
) : (
|
||||
<ComputerUseAppListPanel request={request} onDone={onDone} />
|
||||
)
|
||||
}
|
||||
|
||||
// ── TCC panel ─────────────────────────────────────────────────────────────
|
||||
|
||||
type TccOption = 'open_accessibility' | 'open_screen_recording' | 'retry';
|
||||
function ComputerUseTccPanel(t0) {
|
||||
const $ = _c(26);
|
||||
const {
|
||||
tccState,
|
||||
onDone
|
||||
} = t0;
|
||||
let opts;
|
||||
if ($[0] !== tccState.accessibility || $[1] !== tccState.screenRecording) {
|
||||
opts = [];
|
||||
type TccOption = 'open_accessibility' | 'open_screen_recording' | 'retry'
|
||||
|
||||
function ComputerUseTccPanel({
|
||||
tccState,
|
||||
onDone,
|
||||
}: {
|
||||
tccState: NonNullable<CuPermissionRequest['tccState']>
|
||||
onDone: () => void
|
||||
}): React.ReactNode {
|
||||
const options = useMemo<OptionWithDescription<TccOption>[]>(() => {
|
||||
const opts: OptionWithDescription<TccOption>[] = []
|
||||
if (!tccState.accessibility) {
|
||||
let t1;
|
||||
if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t1 = {
|
||||
label: "Open System Settings \u2192 Accessibility",
|
||||
value: "open_accessibility"
|
||||
};
|
||||
$[3] = t1;
|
||||
} else {
|
||||
t1 = $[3];
|
||||
}
|
||||
opts.push(t1);
|
||||
opts.push({
|
||||
label: 'Open System Settings → Accessibility',
|
||||
value: 'open_accessibility',
|
||||
})
|
||||
}
|
||||
if (!tccState.screenRecording) {
|
||||
let t1;
|
||||
if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t1 = {
|
||||
label: "Open System Settings \u2192 Screen Recording",
|
||||
value: "open_screen_recording"
|
||||
};
|
||||
$[4] = t1;
|
||||
} else {
|
||||
t1 = $[4];
|
||||
}
|
||||
opts.push(t1);
|
||||
opts.push({
|
||||
label: 'Open System Settings → Screen Recording',
|
||||
value: 'open_screen_recording',
|
||||
})
|
||||
}
|
||||
let t1;
|
||||
if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t1 = {
|
||||
label: "Try again",
|
||||
value: "retry"
|
||||
};
|
||||
$[5] = t1;
|
||||
} else {
|
||||
t1 = $[5];
|
||||
opts.push({ label: 'Try again', value: 'retry' })
|
||||
return opts
|
||||
}, [tccState.accessibility, tccState.screenRecording])
|
||||
|
||||
function onChange(value: TccOption): void {
|
||||
switch (value) {
|
||||
case 'open_accessibility':
|
||||
void execFileNoThrow(
|
||||
'open',
|
||||
[
|
||||
'x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility',
|
||||
],
|
||||
{ useCwd: false },
|
||||
)
|
||||
return
|
||||
case 'open_screen_recording':
|
||||
void execFileNoThrow(
|
||||
'open',
|
||||
[
|
||||
'x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture',
|
||||
],
|
||||
{ useCwd: false },
|
||||
)
|
||||
return
|
||||
case 'retry':
|
||||
// Resolve with deny-all — the model re-calls request_access, which
|
||||
// re-checks TCC and renders the app list if now granted.
|
||||
onDone()
|
||||
return
|
||||
}
|
||||
opts.push(t1);
|
||||
$[0] = tccState.accessibility;
|
||||
$[1] = tccState.screenRecording;
|
||||
$[2] = opts;
|
||||
} else {
|
||||
opts = $[2];
|
||||
}
|
||||
const options = opts;
|
||||
let t1;
|
||||
if ($[6] !== onDone) {
|
||||
t1 = function onChange(value) {
|
||||
switch (value) {
|
||||
case "open_accessibility":
|
||||
{
|
||||
execFileNoThrow("open", ["x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility"], {
|
||||
useCwd: false
|
||||
});
|
||||
return;
|
||||
}
|
||||
case "open_screen_recording":
|
||||
{
|
||||
execFileNoThrow("open", ["x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture"], {
|
||||
useCwd: false
|
||||
});
|
||||
return;
|
||||
}
|
||||
case "retry":
|
||||
{
|
||||
onDone();
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
$[6] = onDone;
|
||||
$[7] = t1;
|
||||
} else {
|
||||
t1 = $[7];
|
||||
}
|
||||
const onChange = t1;
|
||||
const t2 = tccState.accessibility ? `${figures.tick} granted` : `${figures.cross} not granted`;
|
||||
let t3;
|
||||
if ($[8] !== t2) {
|
||||
t3 = <Text>Accessibility:{" "}{t2}</Text>;
|
||||
$[8] = t2;
|
||||
$[9] = t3;
|
||||
} else {
|
||||
t3 = $[9];
|
||||
}
|
||||
const t4 = tccState.screenRecording ? `${figures.tick} granted` : `${figures.cross} not granted`;
|
||||
let t5;
|
||||
if ($[10] !== t4) {
|
||||
t5 = <Text>Screen Recording:{" "}{t4}</Text>;
|
||||
$[10] = t4;
|
||||
$[11] = t5;
|
||||
} else {
|
||||
t5 = $[11];
|
||||
}
|
||||
let t6;
|
||||
if ($[12] !== t3 || $[13] !== t5) {
|
||||
t6 = <Box flexDirection="column">{t3}{t5}</Box>;
|
||||
$[12] = t3;
|
||||
$[13] = t5;
|
||||
$[14] = t6;
|
||||
} else {
|
||||
t6 = $[14];
|
||||
}
|
||||
let t7;
|
||||
if ($[15] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t7 = <Text dimColor={true}>Grant the missing permissions in System Settings, then select "Try again". macOS may require you to restart Claude Code after granting Screen Recording.</Text>;
|
||||
$[15] = t7;
|
||||
} else {
|
||||
t7 = $[15];
|
||||
}
|
||||
let t8;
|
||||
if ($[16] !== onChange || $[17] !== onDone || $[18] !== options) {
|
||||
t8 = <Select options={options} onChange={onChange} onCancel={onDone} />;
|
||||
$[16] = onChange;
|
||||
$[17] = onDone;
|
||||
$[18] = options;
|
||||
$[19] = t8;
|
||||
} else {
|
||||
t8 = $[19];
|
||||
}
|
||||
let t9;
|
||||
if ($[20] !== t6 || $[21] !== t8) {
|
||||
t9 = <Box flexDirection="column" paddingX={1} paddingY={1} gap={1}>{t6}{t7}{t8}</Box>;
|
||||
$[20] = t6;
|
||||
$[21] = t8;
|
||||
$[22] = t9;
|
||||
} else {
|
||||
t9 = $[22];
|
||||
}
|
||||
let t10;
|
||||
if ($[23] !== onDone || $[24] !== t9) {
|
||||
t10 = <Dialog title="Computer Use needs macOS permissions" onCancel={onDone}>{t9}</Dialog>;
|
||||
$[23] = onDone;
|
||||
$[24] = t9;
|
||||
$[25] = t10;
|
||||
} else {
|
||||
t10 = $[25];
|
||||
}
|
||||
return t10;
|
||||
|
||||
return (
|
||||
<Dialog title="Computer Use needs macOS permissions" onCancel={onDone}>
|
||||
<Box flexDirection="column" paddingX={1} paddingY={1} gap={1}>
|
||||
<Box flexDirection="column">
|
||||
<Text>
|
||||
Accessibility:{' '}
|
||||
{tccState.accessibility
|
||||
? `${figures.tick} granted`
|
||||
: `${figures.cross} not granted`}
|
||||
</Text>
|
||||
<Text>
|
||||
Screen Recording:{' '}
|
||||
{tccState.screenRecording
|
||||
? `${figures.tick} granted`
|
||||
: `${figures.cross} not granted`}
|
||||
</Text>
|
||||
</Box>
|
||||
<Text dimColor>
|
||||
Grant the missing permissions in System Settings, then select
|
||||
"Try again". macOS may require you to restart Claude Code
|
||||
after granting Screen Recording.
|
||||
</Text>
|
||||
<Select options={options} onChange={onChange} onCancel={onDone} />
|
||||
</Box>
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
|
||||
// ── App allowlist panel ───────────────────────────────────────────────────
|
||||
|
||||
type AppListOption = 'allow_all' | 'deny';
|
||||
const SENTINEL_WARNING: Record<NonNullable<ReturnType<typeof getSentinelCategory>>, string> = {
|
||||
type AppListOption = 'allow_all' | 'deny'
|
||||
|
||||
const SENTINEL_WARNING: Record<
|
||||
NonNullable<ReturnType<typeof getSentinelCategory>>,
|
||||
string
|
||||
> = {
|
||||
shell: 'equivalent to shell access',
|
||||
filesystem: 'can read/write any file',
|
||||
system_settings: 'can change system settings'
|
||||
};
|
||||
function ComputerUseAppListPanel(t0) {
|
||||
const $ = _c(48);
|
||||
const {
|
||||
request,
|
||||
onDone
|
||||
} = t0;
|
||||
let t1;
|
||||
if ($[0] !== request.apps) {
|
||||
t1 = () => new Set(request.apps.flatMap(_temp));
|
||||
$[0] = request.apps;
|
||||
$[1] = t1;
|
||||
} else {
|
||||
t1 = $[1];
|
||||
}
|
||||
const [checked] = useState(t1);
|
||||
let t2;
|
||||
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t2 = ["clipboardRead", "clipboardWrite", "systemKeyCombos"];
|
||||
$[2] = t2;
|
||||
} else {
|
||||
t2 = $[2];
|
||||
}
|
||||
const ALL_FLAG_KEYS = t2;
|
||||
let t3;
|
||||
if ($[3] !== request.requestedFlags) {
|
||||
t3 = ALL_FLAG_KEYS.filter(k => request.requestedFlags[k]);
|
||||
$[3] = request.requestedFlags;
|
||||
$[4] = t3;
|
||||
} else {
|
||||
t3 = $[4];
|
||||
}
|
||||
const requestedFlagKeys = t3;
|
||||
const t4 = checked.size;
|
||||
let t5;
|
||||
if ($[5] !== checked.size) {
|
||||
t5 = plural(checked.size, "app");
|
||||
$[5] = checked.size;
|
||||
$[6] = t5;
|
||||
} else {
|
||||
t5 = $[6];
|
||||
}
|
||||
const t6 = `Allow for this session (${t4} ${t5})`;
|
||||
let t7;
|
||||
if ($[7] !== t6) {
|
||||
t7 = {
|
||||
label: t6,
|
||||
value: "allow_all"
|
||||
};
|
||||
$[7] = t6;
|
||||
$[8] = t7;
|
||||
} else {
|
||||
t7 = $[8];
|
||||
}
|
||||
let t8;
|
||||
if ($[9] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t8 = {
|
||||
label: <Text>Deny, and tell Claude what to do differently <Text bold={true}>(esc)</Text></Text>,
|
||||
value: "deny"
|
||||
};
|
||||
$[9] = t8;
|
||||
} else {
|
||||
t8 = $[9];
|
||||
}
|
||||
let t9;
|
||||
if ($[10] !== t7) {
|
||||
t9 = [t7, t8];
|
||||
$[10] = t7;
|
||||
$[11] = t9;
|
||||
} else {
|
||||
t9 = $[11];
|
||||
}
|
||||
const options = t9;
|
||||
let t10;
|
||||
if ($[12] !== checked || $[13] !== onDone || $[14] !== request.apps || $[15] !== requestedFlagKeys) {
|
||||
t10 = function respond(allow) {
|
||||
if (!allow) {
|
||||
onDone(DENY_ALL_RESPONSE);
|
||||
return;
|
||||
}
|
||||
const now = Date.now();
|
||||
const granted = request.apps.flatMap(a_0 => a_0.resolved && checked.has(a_0.resolved.bundleId) ? [{
|
||||
bundleId: a_0.resolved.bundleId,
|
||||
displayName: a_0.resolved.displayName,
|
||||
grantedAt: now
|
||||
}] : []);
|
||||
const denied = request.apps.filter(a_1 => !a_1.resolved || !checked.has(a_1.resolved.bundleId)).map(_temp2);
|
||||
const flags = {
|
||||
...DEFAULT_GRANT_FLAGS,
|
||||
...Object.fromEntries(requestedFlagKeys.map(_temp3))
|
||||
};
|
||||
onDone({
|
||||
granted,
|
||||
denied,
|
||||
flags
|
||||
});
|
||||
};
|
||||
$[12] = checked;
|
||||
$[13] = onDone;
|
||||
$[14] = request.apps;
|
||||
$[15] = requestedFlagKeys;
|
||||
$[16] = t10;
|
||||
} else {
|
||||
t10 = $[16];
|
||||
}
|
||||
const respond = t10;
|
||||
let t11;
|
||||
if ($[17] !== respond) {
|
||||
t11 = () => respond(false);
|
||||
$[17] = respond;
|
||||
$[18] = t11;
|
||||
} else {
|
||||
t11 = $[18];
|
||||
}
|
||||
let t12;
|
||||
if ($[19] !== request.reason) {
|
||||
t12 = request.reason ? <Text dimColor={true}>{request.reason}</Text> : null;
|
||||
$[19] = request.reason;
|
||||
$[20] = t12;
|
||||
} else {
|
||||
t12 = $[20];
|
||||
}
|
||||
let t13;
|
||||
if ($[21] !== checked || $[22] !== request.apps) {
|
||||
let t14;
|
||||
if ($[24] !== checked) {
|
||||
t14 = a_3 => {
|
||||
const resolved = a_3.resolved;
|
||||
if (!resolved) {
|
||||
return <Text key={a_3.requestedName} dimColor={true}>{" "}{figures.circle} {a_3.requestedName}{" "}<Text dimColor={true}>(not installed)</Text></Text>;
|
||||
}
|
||||
if (a_3.alreadyGranted) {
|
||||
return <Text key={resolved.bundleId} dimColor={true}>{" "}{figures.tick} {resolved.displayName}{" "}<Text dimColor={true}>(already granted)</Text></Text>;
|
||||
}
|
||||
const sentinel = getSentinelCategory(resolved.bundleId);
|
||||
const isChecked = checked.has(resolved.bundleId);
|
||||
return <Box key={resolved.bundleId} flexDirection="column"><Text>{" "}{isChecked ? figures.circleFilled : figures.circle}{" "}{resolved.displayName}</Text>{sentinel ? <Text bold={true}>{" "}{figures.warning} {SENTINEL_WARNING[sentinel]}</Text> : null}</Box>;
|
||||
};
|
||||
$[24] = checked;
|
||||
$[25] = t14;
|
||||
} else {
|
||||
t14 = $[25];
|
||||
system_settings: 'can change system settings',
|
||||
}
|
||||
|
||||
function ComputerUseAppListPanel({
|
||||
request,
|
||||
onDone,
|
||||
}: ComputerUseApprovalProps): React.ReactNode {
|
||||
// Pre-check every resolved, not-yet-granted app. Sentinels stay checked
|
||||
// too — the warning text is the signal, not an unchecked box.
|
||||
// Per-item toggles are a follow-up; for now every resolved app is granted
|
||||
// when the user accepts. `setChecked` is unused until then.
|
||||
const [checked] = useState<ReadonlySet<string>>(
|
||||
() =>
|
||||
new Set(
|
||||
request.apps.flatMap(a =>
|
||||
a.resolved && !a.alreadyGranted ? [a.resolved.bundleId] : [],
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
type FlagKey = keyof typeof DEFAULT_GRANT_FLAGS
|
||||
const ALL_FLAG_KEYS: FlagKey[] = [
|
||||
'clipboardRead',
|
||||
'clipboardWrite',
|
||||
'systemKeyCombos',
|
||||
]
|
||||
const requestedFlagKeys = useMemo(
|
||||
(): FlagKey[] => ALL_FLAG_KEYS.filter(k => request.requestedFlags[k]),
|
||||
[request.requestedFlags],
|
||||
)
|
||||
|
||||
const options = useMemo<OptionWithDescription<AppListOption>[]>(
|
||||
() => [
|
||||
{
|
||||
label: `Allow for this session (${checked.size} ${plural(checked.size, 'app')})`,
|
||||
value: 'allow_all',
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<Text>
|
||||
Deny, and tell Claude what to do differently <Text bold>(esc)</Text>
|
||||
</Text>
|
||||
),
|
||||
value: 'deny',
|
||||
},
|
||||
],
|
||||
[checked.size],
|
||||
)
|
||||
|
||||
function respond(allow: boolean): void {
|
||||
if (!allow) {
|
||||
onDone(DENY_ALL_RESPONSE)
|
||||
return
|
||||
}
|
||||
t13 = request.apps.map(t14);
|
||||
$[21] = checked;
|
||||
$[22] = request.apps;
|
||||
$[23] = t13;
|
||||
} else {
|
||||
t13 = $[23];
|
||||
const now = Date.now()
|
||||
const granted = request.apps.flatMap(a =>
|
||||
a.resolved && checked.has(a.resolved.bundleId)
|
||||
? [
|
||||
{
|
||||
bundleId: a.resolved.bundleId,
|
||||
displayName: a.resolved.displayName,
|
||||
grantedAt: now,
|
||||
},
|
||||
]
|
||||
: [],
|
||||
)
|
||||
const denied = request.apps
|
||||
.filter(a => !a.resolved || !checked.has(a.resolved.bundleId))
|
||||
.map(a => ({
|
||||
bundleId: a.resolved?.bundleId ?? a.requestedName,
|
||||
reason: a.resolved
|
||||
? ('user_denied' as const)
|
||||
: ('not_installed' as const),
|
||||
}))
|
||||
// Grant all requested flags on allow — per-flag toggles are a follow-up.
|
||||
const flags = {
|
||||
...DEFAULT_GRANT_FLAGS,
|
||||
...Object.fromEntries(requestedFlagKeys.map(k => [k, true] as const)),
|
||||
}
|
||||
onDone({ granted, denied, flags })
|
||||
}
|
||||
let t14;
|
||||
if ($[26] !== t13) {
|
||||
t14 = <Box flexDirection="column">{t13}</Box>;
|
||||
$[26] = t13;
|
||||
$[27] = t14;
|
||||
} else {
|
||||
t14 = $[27];
|
||||
}
|
||||
let t15;
|
||||
if ($[28] !== requestedFlagKeys) {
|
||||
t15 = requestedFlagKeys.length > 0 ? <Box flexDirection="column"><Text dimColor={true}>Also requested:</Text>{requestedFlagKeys.map(_temp4)}</Box> : null;
|
||||
$[28] = requestedFlagKeys;
|
||||
$[29] = t15;
|
||||
} else {
|
||||
t15 = $[29];
|
||||
}
|
||||
let t16;
|
||||
if ($[30] !== request.willHide) {
|
||||
t16 = request.willHide && request.willHide.length > 0 ? <Text dimColor={true}>{request.willHide.length} other{" "}{plural(request.willHide.length, "app")} will be hidden while Claude works.</Text> : null;
|
||||
$[30] = request.willHide;
|
||||
$[31] = t16;
|
||||
} else {
|
||||
t16 = $[31];
|
||||
}
|
||||
let t17;
|
||||
let t18;
|
||||
if ($[32] !== respond) {
|
||||
t17 = v => respond(v === "allow_all");
|
||||
t18 = () => respond(false);
|
||||
$[32] = respond;
|
||||
$[33] = t17;
|
||||
$[34] = t18;
|
||||
} else {
|
||||
t17 = $[33];
|
||||
t18 = $[34];
|
||||
}
|
||||
let t19;
|
||||
if ($[35] !== options || $[36] !== t17 || $[37] !== t18) {
|
||||
t19 = <Select options={options} onChange={t17} onCancel={t18} />;
|
||||
$[35] = options;
|
||||
$[36] = t17;
|
||||
$[37] = t18;
|
||||
$[38] = t19;
|
||||
} else {
|
||||
t19 = $[38];
|
||||
}
|
||||
let t20;
|
||||
if ($[39] !== t12 || $[40] !== t14 || $[41] !== t15 || $[42] !== t16 || $[43] !== t19) {
|
||||
t20 = <Box flexDirection="column" paddingX={1} paddingY={1} gap={1}>{t12}{t14}{t15}{t16}{t19}</Box>;
|
||||
$[39] = t12;
|
||||
$[40] = t14;
|
||||
$[41] = t15;
|
||||
$[42] = t16;
|
||||
$[43] = t19;
|
||||
$[44] = t20;
|
||||
} else {
|
||||
t20 = $[44];
|
||||
}
|
||||
let t21;
|
||||
if ($[45] !== t11 || $[46] !== t20) {
|
||||
t21 = <Dialog title="Computer Use wants to control these apps" onCancel={t11}>{t20}</Dialog>;
|
||||
$[45] = t11;
|
||||
$[46] = t20;
|
||||
$[47] = t21;
|
||||
} else {
|
||||
t21 = $[47];
|
||||
}
|
||||
return t21;
|
||||
}
|
||||
function _temp4(flag) {
|
||||
return <Text key={flag} dimColor={true}>{" "}· {flag}</Text>;
|
||||
}
|
||||
function _temp3(k_0) {
|
||||
return [k_0, true] as const;
|
||||
}
|
||||
function _temp2(a_2) {
|
||||
return {
|
||||
bundleId: a_2.resolved?.bundleId ?? a_2.requestedName,
|
||||
reason: a_2.resolved ? "user_denied" as const : "not_installed" as const
|
||||
};
|
||||
}
|
||||
function _temp(a) {
|
||||
return a.resolved && !a.alreadyGranted ? [a.resolved.bundleId] : [];
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
title="Computer Use wants to control these apps"
|
||||
onCancel={() => respond(false)}
|
||||
>
|
||||
<Box flexDirection="column" paddingX={1} paddingY={1} gap={1}>
|
||||
{request.reason ? <Text dimColor>{request.reason}</Text> : null}
|
||||
|
||||
<Box flexDirection="column">
|
||||
{request.apps.map(a => {
|
||||
const resolved = a.resolved
|
||||
if (!resolved) {
|
||||
return (
|
||||
<Text key={a.requestedName} dimColor>
|
||||
{' '}
|
||||
{figures.circle} {a.requestedName}{' '}
|
||||
<Text dimColor>(not installed)</Text>
|
||||
</Text>
|
||||
)
|
||||
}
|
||||
if (a.alreadyGranted) {
|
||||
return (
|
||||
<Text key={resolved.bundleId} dimColor>
|
||||
{' '}
|
||||
{figures.tick} {resolved.displayName}{' '}
|
||||
<Text dimColor>(already granted)</Text>
|
||||
</Text>
|
||||
)
|
||||
}
|
||||
const sentinel = getSentinelCategory(resolved.bundleId)
|
||||
const isChecked = checked.has(resolved.bundleId)
|
||||
return (
|
||||
<Box key={resolved.bundleId} flexDirection="column">
|
||||
<Text>
|
||||
{' '}
|
||||
{isChecked ? figures.circleFilled : figures.circle}{' '}
|
||||
{resolved.displayName}
|
||||
</Text>
|
||||
{sentinel ? (
|
||||
<Text bold>
|
||||
{' '}
|
||||
{figures.warning} {SENTINEL_WARNING[sentinel]}
|
||||
</Text>
|
||||
) : null}
|
||||
</Box>
|
||||
)
|
||||
})}
|
||||
</Box>
|
||||
|
||||
{requestedFlagKeys.length > 0 ? (
|
||||
<Box flexDirection="column">
|
||||
<Text dimColor>Also requested:</Text>
|
||||
{requestedFlagKeys.map(flag => (
|
||||
<Text key={flag} dimColor>
|
||||
{' '}· {flag}
|
||||
</Text>
|
||||
))}
|
||||
</Box>
|
||||
) : null}
|
||||
|
||||
{request.willHide && request.willHide.length > 0 ? (
|
||||
<Text dimColor>
|
||||
{request.willHide.length} other{' '}
|
||||
{plural(request.willHide.length, 'app')} will be hidden while Claude
|
||||
works.
|
||||
</Text>
|
||||
) : null}
|
||||
|
||||
<Select
|
||||
options={options}
|
||||
onChange={v => respond(v === 'allow_all')}
|
||||
onCancel={() => respond(false)}
|
||||
/>
|
||||
</Box>
|
||||
</Dialog>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user