bingocode 1.1.144 → 1.1.146
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/.claude/settings.local.json +23 -1
- package/package.json +1 -1
- package/scripts/build-auto-mode.ts +86 -0
- package/src/cli/print.ts +3 -3
- package/src/cli/structuredIO.ts +2 -2
- package/src/commands/login/login.tsx +2 -2
- package/src/components/PromptInput/PromptInput.tsx +7 -7
- package/src/components/Settings/Config.tsx +6 -6
- package/src/components/messages/UserToolResultMessage/UserToolSuccessMessage.tsx +3 -3
- package/src/components/permissions/BashPermissionRequest/BashPermissionRequest.tsx +10 -10
- package/src/components/permissions/ExitPlanModePermissionRequest/ExitPlanModePermissionRequest.tsx +10 -10
- package/src/components/permissions/PermissionDecisionDebugInfo.tsx +2 -2
- package/src/components/permissions/PermissionRuleExplanation.tsx +2 -2
- package/src/components/permissions/hooks.ts +2 -2
- package/src/constants/betas.ts +2 -2
- package/src/hooks/notifs/useAutoModeUnavailableNotification.ts +2 -2
- package/src/hooks/toolPermission/PermissionContext.ts +3 -3
- package/src/hooks/toolPermission/handlers/coordinatorHandler.ts +2 -2
- package/src/hooks/toolPermission/handlers/interactiveHandler.ts +6 -6
- package/src/hooks/toolPermission/handlers/swarmWorkerHandler.ts +2 -2
- package/src/hooks/toolPermission/permissionLogging.ts +3 -3
- package/src/hooks/useReplBridge.tsx +2 -2
- package/src/interactiveHelpers.tsx +2 -2
- package/src/main.tsx +8 -8
- package/src/manager/CliMenuManager.tsx +36 -5
- package/src/migrations/resetAutoModeOptInForDefaultOffer.ts +2 -2
- package/src/screens/REPL.tsx +4 -4
- package/src/services/api/claude.ts +4 -4
- package/src/services/api/withRetry.ts +2 -2
- package/src/services/tools/toolExecution.ts +2 -2
- package/src/tools/AgentTool/AgentTool.tsx +3 -3
- package/src/tools/AgentTool/agentToolUtils.ts +3 -3
- package/src/tools/AgentTool/runAgent.ts +2 -2
- package/src/tools/BashTool/bashPermissions.ts +17 -17
- package/src/tools/BashTool/pathValidation.ts +2 -2
- package/src/tools/ConfigTool/supportedSettings.ts +2 -2
- package/src/tools/ExitPlanModeTool/ExitPlanModeV2Tool.ts +5 -5
- package/src/tools/NotebookEditTool/NotebookEditTool.ts +2 -2
- package/src/types/permissions.ts +2 -2
- package/src/utils/attachments.ts +3 -3
- package/src/utils/autoModeDenials.ts +2 -2
- package/src/utils/betas.ts +3 -3
- package/src/utils/classifierApprovals.ts +7 -7
- package/src/utils/messages.ts +2 -2
- package/src/utils/permissions/PermissionMode.ts +2 -2
- package/src/utils/permissions/autoModeState.ts +2 -2
- package/src/utils/permissions/bypassPermissionsKillswitch.ts +2 -2
- package/src/utils/permissions/getNextPermissionMode.ts +2 -2
- package/src/utils/permissions/permissionSetup.ts +13 -13
- package/src/utils/permissions/permissions.ts +6 -6
- package/src/utils/permissions/yoloClassifier.ts +5 -5
- package/src/utils/settings/settings.ts +5 -5
- package/src/utils/settings/types.ts +4 -4
- package/src/utils/swarm/inProcessRunner.ts +2 -2
- package/src/utils/toolResultStorage.ts +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Centralized analytics/telemetry logging for tool permission decisions.
|
|
1
|
+
// Centralized analytics/telemetry logging for tool permission decisions.
|
|
2
2
|
// All permission approve/reject events flow through logPermissionDecision(),
|
|
3
3
|
// which fans out to Statsig analytics, OTel telemetry, and code-edit metrics.
|
|
4
4
|
import { feature } from 'bun:bundle'
|
|
@@ -69,7 +69,7 @@ function sourceToString(
|
|
|
69
69
|
source: PermissionApprovalSource | PermissionRejectionSource,
|
|
70
70
|
): string {
|
|
71
71
|
if (
|
|
72
|
-
(
|
|
72
|
+
(true || true) &&
|
|
73
73
|
source.type === 'classifier'
|
|
74
74
|
) {
|
|
75
75
|
return 'classifier'
|
|
@@ -119,7 +119,7 @@ function logApprovalEvent(
|
|
|
119
119
|
return
|
|
120
120
|
}
|
|
121
121
|
if (
|
|
122
|
-
(
|
|
122
|
+
(true || true) &&
|
|
123
123
|
source.type === 'classifier'
|
|
124
124
|
) {
|
|
125
125
|
logEvent(
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { feature } from 'bun:bundle';
|
|
1
|
+
import { feature } from 'bun:bundle';
|
|
2
2
|
import React, { useCallback, useEffect, useRef } from 'react';
|
|
3
3
|
import { setMainLoopModelOverride } from '../bootstrap/state.js';
|
|
4
4
|
import { type BridgePermissionCallbacks, type BridgePermissionResponse, isBridgePermissionResponse } from '../bridge/bridgePermissionCallbacks.js';
|
|
@@ -438,7 +438,7 @@ export function useReplBridge(messages: Message[], setMessages: (action: React.S
|
|
|
438
438
|
};
|
|
439
439
|
}
|
|
440
440
|
}
|
|
441
|
-
if (
|
|
441
|
+
if (true && mode === 'auto' && !isAutoModeGateEnabled()) {
|
|
442
442
|
const reason = getAutoModeUnavailableReason();
|
|
443
443
|
return {
|
|
444
444
|
ok: false,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { feature } from 'bun:bundle';
|
|
1
|
+
import { feature } from 'bun:bundle';
|
|
2
2
|
import { appendFileSync } from 'fs';
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { logEvent } from 'src/services/analytics/index.js';
|
|
@@ -221,7 +221,7 @@ export async function showSetupScreens(root: Root, permissionMode: PermissionMod
|
|
|
221
221
|
} = await import('./components/BypassPermissionsModeDialog.js');
|
|
222
222
|
await showSetupDialog(root, done => <BypassPermissionsModeDialog onAccept={done} />);
|
|
223
223
|
}
|
|
224
|
-
if (
|
|
224
|
+
if (true) {
|
|
225
225
|
// Only show the opt-in dialog if auto mode actually resolved — if the
|
|
226
226
|
// gate denied it (org not allowlisted, settings disabled), showing
|
|
227
227
|
// consent for an unavailable feature is pointless. The
|
package/src/main.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// These side-effects must run before all other imports:
|
|
1
|
+
// These side-effects must run before all other imports:
|
|
2
2
|
// 1. profileCheckpoint marks entry before heavy module evaluation begins
|
|
3
3
|
// 2. startMdmRawRead fires MDM subprocesses (plutil/reg query) so they run in
|
|
4
4
|
// parallel with the remaining ~135ms of imports below
|
|
@@ -168,7 +168,7 @@ import { plural } from 'src/utils/stringUtils.js';
|
|
|
168
168
|
import { type ChannelEntry, getInitialMainLoopModel, getIsNonInteractiveSession, getSdkBetas, getSessionId, getUserMsgOptIn, setAllowedChannels, setAllowedSettingSources, setChromeFlagOverride, setClientType, setCwdState, setDirectConnectServerUrl, setFlagSettingsPath, setInitialMainLoopModel, setInlinePlugins, setIsInteractive, setKairosActive, setOriginalCwd, setProjectRoot, setQuestionPreviewFormat, setSdkBetas, setSessionBypassPermissionsMode, setSessionPersistenceDisabled, setSessionSource, setUserMsgOptIn, switchSession } from './bootstrap/state.js';
|
|
169
169
|
|
|
170
170
|
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
171
|
-
const autoModeStateModule =
|
|
171
|
+
const autoModeStateModule = true ? require('./utils/permissions/autoModeState.js') as typeof import('./utils/permissions/autoModeState.js') : null;
|
|
172
172
|
|
|
173
173
|
// TeleportRepoMismatchDialog, TeleportResumeWrapper dynamically imported at call sites
|
|
174
174
|
import { migrateAutoUpdatesToSettings } from './migrations/migrateAutoUpdatesToSettings.js';
|
|
@@ -334,7 +334,7 @@ function runMigrations(): void {
|
|
|
334
334
|
migrateSonnet45ToSonnet46();
|
|
335
335
|
migrateOpusToOpus1m();
|
|
336
336
|
migrateReplBridgeEnabledToRemoteControlAtStartup();
|
|
337
|
-
if (
|
|
337
|
+
if (true) {
|
|
338
338
|
resetAutoModeOptInForDefaultOffer();
|
|
339
339
|
}
|
|
340
340
|
if ("external" === 'ant') {
|
|
@@ -1396,7 +1396,7 @@ async function run(): Promise<CommanderCommand> {
|
|
|
1396
1396
|
|
|
1397
1397
|
// Store session bypass permissions mode for trust dialog check
|
|
1398
1398
|
setSessionBypassPermissionsMode(permissionMode === 'bypassPermissions');
|
|
1399
|
-
if (
|
|
1399
|
+
if (true) {
|
|
1400
1400
|
// autoModeFlagCli is the "did the user intend auto this session" signal.
|
|
1401
1401
|
// Set when: --enable-auto-mode, --permission-mode auto, resolved mode
|
|
1402
1402
|
// is auto, OR settings defaultMode is auto but the gate denied it
|
|
@@ -1766,7 +1766,7 @@ async function run(): Promise<CommanderCommand> {
|
|
|
1766
1766
|
}
|
|
1767
1767
|
toolPermissionContext = removeDangerousPermissions(toolPermissionContext, overlyBroadBashPermissions);
|
|
1768
1768
|
}
|
|
1769
|
-
if (
|
|
1769
|
+
if (true && dangerousPermissions.length > 0) {
|
|
1770
1770
|
toolPermissionContext = stripDangerousPermissionsForAutoMode(toolPermissionContext);
|
|
1771
1771
|
}
|
|
1772
1772
|
|
|
@@ -2666,7 +2666,7 @@ async function run(): Promise<CommanderCommand> {
|
|
|
2666
2666
|
|
|
2667
2667
|
// Async check of auto mode gate — corrects state and disables auto if needed.
|
|
2668
2668
|
// Gated on TRANSCRIPT_CLASSIFIER (not USER_TYPE) so GrowthBook kill switch runs for external builds too.
|
|
2669
|
-
if (
|
|
2669
|
+
if (true) {
|
|
2670
2670
|
void verifyAutoModeGateAccess(toolPermissionContext, headlessStore.getState().fastMode).then(({
|
|
2671
2671
|
updateContext
|
|
2672
2672
|
}) => {
|
|
@@ -3832,7 +3832,7 @@ async function run(): Promise<CommanderCommand> {
|
|
|
3832
3832
|
program.addOption(new Option('--tasks [id]', '[ANT-ONLY] Tasks mode: watch for tasks and auto-process them. Optional id is used as both the task list ID and agent ID (defaults to "tasklist").').argParser(String).hideHelp());
|
|
3833
3833
|
program.option('--agent-teams', '[ANT-ONLY] Force Claude to use multi-agent mode for solving problems', () => true);
|
|
3834
3834
|
}
|
|
3835
|
-
if (
|
|
3835
|
+
if (true) {
|
|
3836
3836
|
program.addOption(new Option('--enable-auto-mode', 'Opt in to auto mode').hideHelp());
|
|
3837
3837
|
}
|
|
3838
3838
|
if (feature('PROACTIVE') || feature('KAIROS')) {
|
|
@@ -4288,7 +4288,7 @@ async function run(): Promise<CommanderCommand> {
|
|
|
4288
4288
|
await agentsHandler();
|
|
4289
4289
|
process.exit(0);
|
|
4290
4290
|
});
|
|
4291
|
-
if (
|
|
4291
|
+
if (true) {
|
|
4292
4292
|
// Skip when tengu_auto_mode_config.enabled === 'disabled' (circuit breaker).
|
|
4293
4293
|
// Reads from disk cache — GrowthBook isn't initialized at registration time.
|
|
4294
4294
|
if (getAutoModeEnabledStateIfCached() !== 'disabled') {
|
|
@@ -115,8 +115,11 @@ const i18nMap = {
|
|
|
115
115
|
settingsTitle: '设置',
|
|
116
116
|
langLabel: '语言',
|
|
117
117
|
langPickerTitle: '选择语言',
|
|
118
|
-
settingsHint: '↑/k ↓/j 滚动 · ↩
|
|
118
|
+
settingsHint: '↑/k ↓/j 滚动 · ↩ 切换 · ESC 返回',
|
|
119
119
|
langOptions: LANG_OPTIONS,
|
|
120
|
+
autoModeLabel: 'Auto Mode',
|
|
121
|
+
autoModeOn: '已开启',
|
|
122
|
+
autoModeOff: '已关闭',
|
|
120
123
|
},
|
|
121
124
|
en: {
|
|
122
125
|
menu: {
|
|
@@ -148,8 +151,11 @@ const i18nMap = {
|
|
|
148
151
|
settingsTitle: 'Settings',
|
|
149
152
|
langLabel: 'Language',
|
|
150
153
|
langPickerTitle: 'Select Language',
|
|
151
|
-
settingsHint: '↑/k ↓/j scroll · ↩
|
|
154
|
+
settingsHint: '↑/k ↓/j scroll · ↩ toggle · ESC back',
|
|
152
155
|
langOptions: LANG_OPTIONS,
|
|
156
|
+
autoModeLabel: 'Auto Mode',
|
|
157
|
+
autoModeOn: 'Enabled',
|
|
158
|
+
autoModeOff: 'Disabled',
|
|
153
159
|
},
|
|
154
160
|
ja: {
|
|
155
161
|
menu: {
|
|
@@ -181,8 +187,11 @@ const i18nMap = {
|
|
|
181
187
|
settingsTitle: '設定',
|
|
182
188
|
langLabel: '言語',
|
|
183
189
|
langPickerTitle: '言語を選択',
|
|
184
|
-
settingsHint: '↑/k ↓/j スクロール · ↩
|
|
190
|
+
settingsHint: '↑/k ↓/j スクロール · ↩ 切替 · ESC 戻る',
|
|
185
191
|
langOptions: LANG_OPTIONS,
|
|
192
|
+
autoModeLabel: 'Auto Mode',
|
|
193
|
+
autoModeOn: '有効',
|
|
194
|
+
autoModeOff: '無効',
|
|
186
195
|
},
|
|
187
196
|
};
|
|
188
197
|
|
|
@@ -299,6 +308,9 @@ export const CliMenuManager: React.FC = () => {
|
|
|
299
308
|
}
|
|
300
309
|
if (typeof cfg.uiAnimEnabled === 'boolean') setAnimEnabled(cfg.uiAnimEnabled);
|
|
301
310
|
if (typeof cfg.uiTipsEnabled === 'boolean') setTipsEnabled(cfg.uiTipsEnabled);
|
|
311
|
+
const gbFeatures = cfg.cachedGrowthBookFeatures ?? {};
|
|
312
|
+
const autoModeCfg = gbFeatures['tengu_auto_mode_config'] as { enabled?: string } | undefined;
|
|
313
|
+
setAutoModeEnabled(autoModeCfg?.enabled === 'enabled');
|
|
302
314
|
} catch (e) {
|
|
303
315
|
// Silently fail if config has issues
|
|
304
316
|
}
|
|
@@ -349,6 +361,7 @@ export const CliMenuManager: React.FC = () => {
|
|
|
349
361
|
const [setErr, setSetErr] = useState<string | null>(null);
|
|
350
362
|
const [settingsStage, setSettingsStage] = useState<'list' | 'langPicker'>('list');
|
|
351
363
|
const [settingsCursor, setSettingsCursor] = useState(0);
|
|
364
|
+
const [autoModeEnabled, setAutoModeEnabled] = useState(false);
|
|
352
365
|
|
|
353
366
|
// Top toolbar state
|
|
354
367
|
const [animEnabled, setAnimEnabled] = useState(true);
|
|
@@ -744,7 +757,7 @@ export const CliMenuManager: React.FC = () => {
|
|
|
744
757
|
if (!showHelp && page === 'settings') {
|
|
745
758
|
if (settingsStage === 'list') {
|
|
746
759
|
// +1 for the fixed Language row prepended before settingData entries
|
|
747
|
-
const totalRows =
|
|
760
|
+
const totalRows = 2 + (settingData && typeof settingData === 'object' ? Object.keys(settingData).length : 0);
|
|
748
761
|
const visible = Math.max(1, MID_H - 2);
|
|
749
762
|
if (key.downArrow || input === 'j') {
|
|
750
763
|
setSettingsCursor(c => Math.min(totalRows - 1, c + 1));
|
|
@@ -758,12 +771,29 @@ export const CliMenuManager: React.FC = () => {
|
|
|
758
771
|
// Row 0 is the interactive Language row
|
|
759
772
|
if (settingsCursor === 0) {
|
|
760
773
|
setSettingsStage('langPicker');
|
|
774
|
+
} else if (settingsCursor === 1) {
|
|
775
|
+
// Row 1: toggle Auto Mode, persist to ~/.claude.json
|
|
776
|
+
setAutoModeEnabled(prev => {
|
|
777
|
+
const next = !prev;
|
|
778
|
+
try {
|
|
779
|
+
saveGlobalConfig(current => ({
|
|
780
|
+
...current,
|
|
781
|
+
cachedGrowthBookFeatures: {
|
|
782
|
+
...current.cachedGrowthBookFeatures,
|
|
783
|
+
tengu_auto_mode_config: next
|
|
784
|
+
? { enabled: 'enabled', allowModels: ['*'] }
|
|
785
|
+
: { enabled: 'disabled' },
|
|
786
|
+
},
|
|
787
|
+
}));
|
|
788
|
+
} catch {}
|
|
789
|
+
return next;
|
|
790
|
+
});
|
|
761
791
|
}
|
|
762
792
|
}
|
|
763
793
|
}
|
|
764
794
|
// langPicker stage: ESC handled above; selection via SelectInput onSelect
|
|
765
795
|
}
|
|
766
|
-
}, [menuItems, page, historyMenuStage, historyList, historyHasMore, navIndex, sessionMessages, settingData, MID_H, MSGS_PAGE_SIZE, showHelp, theme, settingsStage, settingsCursor]);
|
|
796
|
+
}, [menuItems, page, historyMenuStage, historyList, historyHasMore, navIndex, sessionMessages, settingData, MID_H, MSGS_PAGE_SIZE, showHelp, theme, settingsStage, settingsCursor, autoModeEnabled]);
|
|
767
797
|
|
|
768
798
|
function cleanText(text: string): string {
|
|
769
799
|
return String(text ?? '').replace(/[\n\r]+/g, ' ').replace(/\u001b\[[0-9;]*m/g, '').trim();
|
|
@@ -1249,6 +1279,7 @@ export const CliMenuManager: React.FC = () => {
|
|
|
1249
1279
|
type SettingRow = { key: string; label: string; value: string; interactive: boolean };
|
|
1250
1280
|
const fixedRows: SettingRow[] = [
|
|
1251
1281
|
{ key: '__lang', label: tS.langLabel, value: currentLangLabel, interactive: true },
|
|
1282
|
+
{ key: '__autoMode', label: tS.autoModeLabel, value: autoModeEnabled ? tS.autoModeOn : tS.autoModeOff, interactive: true },
|
|
1252
1283
|
];
|
|
1253
1284
|
const dataEntries = settingData && typeof settingData === 'object' ? Object.entries(settingData) : [];
|
|
1254
1285
|
const dataRows: SettingRow[] = dataEntries.map(([k, v]) => ({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { feature } from 'bun:bundle'
|
|
1
|
+
import { feature } from 'bun:bundle'
|
|
2
2
|
import { logEvent } from 'src/services/analytics/index.js'
|
|
3
3
|
import { getGlobalConfig, saveGlobalConfig } from '../utils/config.js'
|
|
4
4
|
import { logError } from '../utils/log.js'
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
* 'enabled'), but the guard makes it safe regardless.
|
|
24
24
|
*/
|
|
25
25
|
export function resetAutoModeOptInForDefaultOffer(): void {
|
|
26
|
-
if (
|
|
26
|
+
if (true) {
|
|
27
27
|
const config = getGlobalConfig()
|
|
28
28
|
if (config.hasResetAutoModeOptInForDefaultOffer) return
|
|
29
29
|
if (getAutoModeEnabledState() !== 'enabled') return
|
package/src/screens/REPL.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as _c } from "react/compiler-runtime";
|
|
1
|
+
import { c as _c } from "react/compiler-runtime";
|
|
2
2
|
// biome-ignore-all assist/source/organizeImports: ANT-ONLY import markers must not be reordered
|
|
3
3
|
import { feature } from 'bun:bundle';
|
|
4
4
|
import { spawnSync } from 'child_process';
|
|
@@ -1613,7 +1613,7 @@ export function REPL({
|
|
|
1613
1613
|
// Only shown 3 times total across sessions.
|
|
1614
1614
|
const safeYoloMessageShownRef = useRef(false);
|
|
1615
1615
|
useEffect(() => {
|
|
1616
|
-
if (
|
|
1616
|
+
if (true) {
|
|
1617
1617
|
if (toolPermissionContext.mode !== 'auto') {
|
|
1618
1618
|
safeYoloMessageShownRef.current = false;
|
|
1619
1619
|
return;
|
|
@@ -2769,7 +2769,7 @@ export function REPL({
|
|
|
2769
2769
|
// IMPORTANT: do this after setMessages() above, to avoid UI jank
|
|
2770
2770
|
checkAndDisableBypassPermissionsIfNeeded(toolPermissionContext, setAppState),
|
|
2771
2771
|
// Gated on TRANSCRIPT_CLASSIFIER so GrowthBook kill switch runs wherever auto mode is built in
|
|
2772
|
-
|
|
2772
|
+
true ? checkAndDisableAutoModeIfNeeded(toolPermissionContext, setAppState, store.getState().fastMode) : undefined, getSystemPrompt(freshTools, mainLoopModelParam, Array.from(toolPermissionContext.additionalWorkingDirectories.keys()), freshMcpClients), getUserContext(), getSystemContext()]);
|
|
2773
2773
|
const userContext = {
|
|
2774
2774
|
...baseUserContext,
|
|
2775
2775
|
...getCoordinatorUserContext(freshMcpClients, isScratchpadEnabled() ? getScratchpadDir() : undefined),
|
|
@@ -3066,7 +3066,7 @@ export function REPL({
|
|
|
3066
3066
|
let updatedToolPermissionContext = initialMsg.mode ? applyPermissionUpdates(prev.toolPermissionContext, buildPermissionUpdates(initialMsg.mode, initialMsg.allowedPrompts)) : prev.toolPermissionContext;
|
|
3067
3067
|
// For auto, override the mode (buildPermissionUpdates maps
|
|
3068
3068
|
// it to 'default' via toExternalPermissionMode) and strip dangerous rules
|
|
3069
|
-
if (
|
|
3069
|
+
if (true && initialMsg.mode === 'auto') {
|
|
3070
3070
|
updatedToolPermissionContext = stripDangerousPermissionsForAutoMode({
|
|
3071
3071
|
...updatedToolPermissionContext,
|
|
3072
3072
|
mode: 'auto',
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
2
|
BetaContentBlock,
|
|
3
3
|
BetaContentBlockParam,
|
|
4
4
|
BetaImageBlockParam,
|
|
@@ -102,7 +102,7 @@ import {
|
|
|
102
102
|
import { getAPIContextManagement } from '../compact/apiMicrocompact.js'
|
|
103
103
|
|
|
104
104
|
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
105
|
-
const autoModeStateModule =
|
|
105
|
+
const autoModeStateModule = true
|
|
106
106
|
? (require('../../utils/permissions/autoModeState.js') as typeof import('../../utils/permissions/autoModeState.js'))
|
|
107
107
|
: null
|
|
108
108
|
|
|
@@ -1410,7 +1410,7 @@ async function* queryModel(
|
|
|
1410
1410
|
// per-call so non-agentic queries keep their own stable header set.
|
|
1411
1411
|
|
|
1412
1412
|
let afkHeaderLatched = getAfkModeHeaderLatched() === true
|
|
1413
|
-
if (
|
|
1413
|
+
if (true) {
|
|
1414
1414
|
if (
|
|
1415
1415
|
!afkHeaderLatched &&
|
|
1416
1416
|
isAgenticQuery &&
|
|
@@ -1658,7 +1658,7 @@ async function* queryModel(
|
|
|
1658
1658
|
|
|
1659
1659
|
// AFK mode beta: latched once auto mode is first activated. Still gated
|
|
1660
1660
|
// by isAgenticQuery per-call so classifiers/compaction don't get it.
|
|
1661
|
-
if (
|
|
1661
|
+
if (true) {
|
|
1662
1662
|
if (
|
|
1663
1663
|
afkHeaderLatched &&
|
|
1664
1664
|
shouldIncludeFirstPartyOnlyBetas() &&
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { feature } from 'bun:bundle'
|
|
1
|
+
import { feature } from 'bun:bundle'
|
|
2
2
|
import type Anthropic from '@anthropic-ai/sdk'
|
|
3
3
|
import {
|
|
4
4
|
APIConnectionError,
|
|
@@ -78,7 +78,7 @@ const FOREGROUND_529_RETRY_SOURCES = new Set<QuerySource>([
|
|
|
78
78
|
// type-only). bash_classifier is ant-only; feature-gate so the string
|
|
79
79
|
// tree-shakes out of external builds (excluded-strings.txt).
|
|
80
80
|
'auto_mode',
|
|
81
|
-
...(
|
|
81
|
+
...(true ? (['bash_classifier'] as const) : []),
|
|
82
82
|
])
|
|
83
83
|
|
|
84
84
|
function shouldRetry529(querySource: QuerySource | undefined): boolean {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { feature } from 'bun:bundle'
|
|
1
|
+
import { feature } from 'bun:bundle'
|
|
2
2
|
import type {
|
|
3
3
|
ContentBlockParam,
|
|
4
4
|
ToolResultBlockParam,
|
|
@@ -1073,7 +1073,7 @@ async function checkPermissionsAndCallTool(
|
|
|
1073
1073
|
// Run PermissionDenied hooks for auto mode classifier denials.
|
|
1074
1074
|
// If a hook returns {retry: true}, tell the model it may retry.
|
|
1075
1075
|
if (
|
|
1076
|
-
|
|
1076
|
+
true &&
|
|
1077
1077
|
permissionDecision.decisionReason?.type === 'classifier' &&
|
|
1078
1078
|
permissionDecision.decisionReason.classifier === 'auto-mode'
|
|
1079
1079
|
) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { feature } from 'bun:bundle';
|
|
1
|
+
import { feature } from 'bun:bundle';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { buildTool, type ToolDef, toolMatchesName } from 'src/Tool.js';
|
|
4
4
|
import type { Message as MessageType, NormalizedUserMessage } from 'src/types/message.js';
|
|
@@ -958,7 +958,7 @@ export const AgentTool = buildTool({
|
|
|
958
958
|
|
|
959
959
|
// Extract text from agent result content for the notification
|
|
960
960
|
let finalMessage = extractTextContent(agentResult.content, '\n');
|
|
961
|
-
if (
|
|
961
|
+
if (true) {
|
|
962
962
|
const backgroundedAppState = toolUseContext.getAppState();
|
|
963
963
|
const handoffWarning = await classifyHandoffIfNeeded({
|
|
964
964
|
agentMessages,
|
|
@@ -1233,7 +1233,7 @@ export const AgentTool = buildTool({
|
|
|
1233
1233
|
logForDebugging(`Sync agent recovering from error with ${agentMessages.length} messages`);
|
|
1234
1234
|
}
|
|
1235
1235
|
const agentResult = finalizeAgentTool(agentMessages, syncAgentId, metadata);
|
|
1236
|
-
if (
|
|
1236
|
+
if (true) {
|
|
1237
1237
|
const currentAppState = toolUseContext.getAppState();
|
|
1238
1238
|
const handoffWarning = await classifyHandoffIfNeeded({
|
|
1239
1239
|
agentMessages,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { feature } from 'bun:bundle'
|
|
1
|
+
import { feature } from 'bun:bundle'
|
|
2
2
|
import { z } from 'zod/v4'
|
|
3
3
|
import { clearInvokedSkillsForAgent } from '../../bootstrap/state.js'
|
|
4
4
|
import {
|
|
@@ -401,7 +401,7 @@ export async function classifyHandoffIfNeeded({
|
|
|
401
401
|
subagentType: string
|
|
402
402
|
totalToolUseCount: number
|
|
403
403
|
}): Promise<string | null> {
|
|
404
|
-
if (
|
|
404
|
+
if (true) {
|
|
405
405
|
if (toolPermissionContext.mode !== 'auto') return null
|
|
406
406
|
|
|
407
407
|
const agentTranscript = buildTranscriptForClassifier(agentMessages, tools)
|
|
@@ -604,7 +604,7 @@ export async function runAsyncAgentLifecycle({
|
|
|
604
604
|
|
|
605
605
|
let finalMessage = extractTextContent(agentResult.content, '\n')
|
|
606
606
|
|
|
607
|
-
if (
|
|
607
|
+
if (true) {
|
|
608
608
|
const handoffWarning = await classifyHandoffIfNeeded({
|
|
609
609
|
agentMessages,
|
|
610
610
|
tools: toolUseContext.options.tools,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { feature } from 'bun:bundle'
|
|
1
|
+
import { feature } from 'bun:bundle'
|
|
2
2
|
import type { UUID } from 'crypto'
|
|
3
3
|
import { randomUUID } from 'crypto'
|
|
4
4
|
import uniqBy from 'lodash-es/uniqBy.js'
|
|
@@ -423,7 +423,7 @@ export async function* runAgent({
|
|
|
423
423
|
state.toolPermissionContext.mode !== 'bypassPermissions' &&
|
|
424
424
|
state.toolPermissionContext.mode !== 'acceptEdits' &&
|
|
425
425
|
!(
|
|
426
|
-
|
|
426
|
+
true &&
|
|
427
427
|
state.toolPermissionContext.mode === 'auto'
|
|
428
428
|
)
|
|
429
429
|
) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { feature } from 'bun:bundle'
|
|
1
|
+
import { feature } from 'bun:bundle'
|
|
2
2
|
import { APIUserAbortError } from '@anthropic-ai/sdk'
|
|
3
3
|
import type { z } from 'zod/v4'
|
|
4
4
|
import { getFeatureValue_CACHED_MAY_BE_STALE } from '../../services/analytics/growthbook.js'
|
|
@@ -81,7 +81,7 @@ import { shouldUseSandbox } from './shouldUseSandbox.js'
|
|
|
81
81
|
// DCE cliff: Bun's feature() evaluator has a per-function complexity budget.
|
|
82
82
|
// bashToolHasPermission is right at the limit. `import { X as Y }` aliases
|
|
83
83
|
// inside the import block count toward this budget; when they push it over
|
|
84
|
-
// the threshold Bun can no longer prove
|
|
84
|
+
// the threshold Bun can no longer prove true is a
|
|
85
85
|
// constant and silently evaluates the ternaries to `false`, dropping every
|
|
86
86
|
// pendingClassifierCheck spread. Keep aliases as top-level const rebindings
|
|
87
87
|
// instead. (See also the comment on checkSemanticsDeny below.)
|
|
@@ -628,7 +628,7 @@ const TIMEOUT_FLAG_VALUE_RE = /^[A-Za-z0-9_.+-]+$/
|
|
|
628
628
|
*
|
|
629
629
|
* Extracted from stripWrappersFromArgv to keep bashToolHasPermission under
|
|
630
630
|
* Bun's feature() DCE complexity threshold — inlining this breaks
|
|
631
|
-
*
|
|
631
|
+
* true evaluation in classifier tests.
|
|
632
632
|
*/
|
|
633
633
|
function skipTimeoutFlags(a: readonly string[]): number {
|
|
634
634
|
let i = 1
|
|
@@ -1426,7 +1426,7 @@ function checkEarlyExitDeny(
|
|
|
1426
1426
|
* Separate helper (not folded into checkEarlyExitDeny or inlined at the call
|
|
1427
1427
|
* site) because bashToolHasPermission is tight against Bun's feature() DCE
|
|
1428
1428
|
* complexity threshold — adding even ~5 lines there breaks
|
|
1429
|
-
*
|
|
1429
|
+
* true evaluation and drops pendingClassifierCheck.
|
|
1430
1430
|
*/
|
|
1431
1431
|
function checkSemanticsDeny(
|
|
1432
1432
|
input: z.infer<typeof BashTool.inputSchema>,
|
|
@@ -1464,7 +1464,7 @@ function buildPendingClassifierCheck(
|
|
|
1464
1464
|
return undefined
|
|
1465
1465
|
}
|
|
1466
1466
|
// Skip in auto mode - auto mode classifier handles all permission decisions
|
|
1467
|
-
if (
|
|
1467
|
+
if (true && toolPermissionContext.mode === 'auto')
|
|
1468
1468
|
return undefined
|
|
1469
1469
|
if (toolPermissionContext.mode === 'bypassPermissions') return undefined
|
|
1470
1470
|
|
|
@@ -1502,7 +1502,7 @@ export function startSpeculativeClassifierCheck(
|
|
|
1502
1502
|
): boolean {
|
|
1503
1503
|
// Same guards as buildPendingClassifierCheck
|
|
1504
1504
|
if (!isClassifierPermissionsEnabled()) return false
|
|
1505
|
-
if (
|
|
1505
|
+
if (true && toolPermissionContext.mode === 'auto')
|
|
1506
1506
|
return false
|
|
1507
1507
|
if (toolPermissionContext.mode === 'bypassPermissions') return false
|
|
1508
1508
|
const allowDescriptions = getBashPromptAllowDescriptions(
|
|
@@ -1573,7 +1573,7 @@ export async function awaitClassifierAutoApproval(
|
|
|
1573
1573
|
logClassifierResultForAnts(command, 'allow', descriptions, classifierResult)
|
|
1574
1574
|
|
|
1575
1575
|
if (
|
|
1576
|
-
|
|
1576
|
+
true &&
|
|
1577
1577
|
classifierResult.matches &&
|
|
1578
1578
|
classifierResult.confidence === 'high'
|
|
1579
1579
|
) {
|
|
@@ -1642,7 +1642,7 @@ export async function executeAsyncClassifierCheck(
|
|
|
1642
1642
|
if (!callbacks.shouldContinue()) return
|
|
1643
1643
|
|
|
1644
1644
|
if (
|
|
1645
|
-
|
|
1645
|
+
true &&
|
|
1646
1646
|
classifierResult.matches &&
|
|
1647
1647
|
classifierResult.confidence === 'high'
|
|
1648
1648
|
) {
|
|
@@ -1757,7 +1757,7 @@ export async function bashToolHasPermission(
|
|
|
1757
1757
|
decisionReason,
|
|
1758
1758
|
message: createPermissionRequestMessage(BashTool.name, decisionReason),
|
|
1759
1759
|
suggestions: [],
|
|
1760
|
-
...(
|
|
1760
|
+
...(true
|
|
1761
1761
|
? {
|
|
1762
1762
|
pendingClassifierCheck: buildPendingClassifierCheck(
|
|
1763
1763
|
input.command,
|
|
@@ -1859,7 +1859,7 @@ export async function bashToolHasPermission(
|
|
|
1859
1859
|
if (
|
|
1860
1860
|
isClassifierPermissionsEnabled() &&
|
|
1861
1861
|
!(
|
|
1862
|
-
|
|
1862
|
+
true &&
|
|
1863
1863
|
appState.toolPermissionContext.mode === 'auto'
|
|
1864
1864
|
)
|
|
1865
1865
|
) {
|
|
@@ -1957,7 +1957,7 @@ export async function bashToolHasPermission(
|
|
|
1957
1957
|
reason: `Required by Bash prompt rule: "${askResult.matchedDescription}"`,
|
|
1958
1958
|
},
|
|
1959
1959
|
suggestions,
|
|
1960
|
-
...(
|
|
1960
|
+
...(true
|
|
1961
1961
|
? {
|
|
1962
1962
|
pendingClassifierCheck: buildPendingClassifierCheck(
|
|
1963
1963
|
input.command,
|
|
@@ -2024,7 +2024,7 @@ export async function bashToolHasPermission(
|
|
|
2024
2024
|
safetyResult.message ??
|
|
2025
2025
|
'Command contains patterns that require approval',
|
|
2026
2026
|
},
|
|
2027
|
-
...(
|
|
2027
|
+
...(true
|
|
2028
2028
|
? {
|
|
2029
2029
|
pendingClassifierCheck: buildPendingClassifierCheck(
|
|
2030
2030
|
input.command,
|
|
@@ -2061,7 +2061,7 @@ export async function bashToolHasPermission(
|
|
|
2061
2061
|
appState = context.getAppState()
|
|
2062
2062
|
return {
|
|
2063
2063
|
...commandOperatorResult,
|
|
2064
|
-
...(
|
|
2064
|
+
...(true
|
|
2065
2065
|
? {
|
|
2066
2066
|
pendingClassifierCheck: buildPendingClassifierCheck(
|
|
2067
2067
|
input.command,
|
|
@@ -2128,7 +2128,7 @@ export async function bashToolHasPermission(
|
|
|
2128
2128
|
),
|
|
2129
2129
|
decisionReason,
|
|
2130
2130
|
suggestions: [], // Don't suggest saving a potentially dangerous command
|
|
2131
|
-
...(
|
|
2131
|
+
...(true
|
|
2132
2132
|
? {
|
|
2133
2133
|
pendingClassifierCheck: buildPendingClassifierCheck(
|
|
2134
2134
|
input.command,
|
|
@@ -2319,7 +2319,7 @@ export async function bashToolHasPermission(
|
|
|
2319
2319
|
if (askSubresult !== undefined && nonAllowCount === 1) {
|
|
2320
2320
|
return {
|
|
2321
2321
|
...askSubresult,
|
|
2322
|
-
...(
|
|
2322
|
+
...(true
|
|
2323
2323
|
? {
|
|
2324
2324
|
pendingClassifierCheck: buildPendingClassifierCheck(
|
|
2325
2325
|
input.command,
|
|
@@ -2418,7 +2418,7 @@ export async function bashToolHasPermission(
|
|
|
2418
2418
|
if (result.behavior === 'ask' || result.behavior === 'passthrough') {
|
|
2419
2419
|
return {
|
|
2420
2420
|
...result,
|
|
2421
|
-
...(
|
|
2421
|
+
...(true
|
|
2422
2422
|
? {
|
|
2423
2423
|
pendingClassifierCheck: buildPendingClassifierCheck(
|
|
2424
2424
|
input.command,
|
|
@@ -2545,7 +2545,7 @@ export async function bashToolHasPermission(
|
|
|
2545
2545
|
message: createPermissionRequestMessage(BashTool.name, decisionReason),
|
|
2546
2546
|
decisionReason,
|
|
2547
2547
|
suggestions: suggestedUpdates,
|
|
2548
|
-
...(
|
|
2548
|
+
...(true
|
|
2549
2549
|
? {
|
|
2550
2550
|
pendingClassifierCheck: buildPendingClassifierCheck(
|
|
2551
2551
|
input.command,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { homedir } from 'os'
|
|
1
|
+
import { homedir } from 'os'
|
|
2
2
|
import { isAbsolute, resolve } from 'path'
|
|
3
3
|
import type { z } from 'zod/v4'
|
|
4
4
|
import type { ToolPermissionContext } from '../../Tool.js'
|
|
@@ -1156,7 +1156,7 @@ function astRedirectsToOutputRedirections(redirects: Redirect[]): {
|
|
|
1156
1156
|
// exports an older narrower copy (timeout/nice-n-N only) that is DEAD CODE
|
|
1157
1157
|
// — no prod consumer — but CANNOT be removed: bashPermissions.ts is right
|
|
1158
1158
|
// at Bun's feature() DCE complexity threshold, and deleting ~80 lines from
|
|
1159
|
-
// that module silently breaks
|
|
1159
|
+
// that module silently breaks true evaluation (drops
|
|
1160
1160
|
// every pendingClassifierCheck spread). Verified in PR #21503 round 3:
|
|
1161
1161
|
// baseline classifier tests 30/30 pass, after deletion 22/30 fail. See
|
|
1162
1162
|
// team memory: bun-feature-dce-cliff.md. Hit 3× in PR #21075 + twice in
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { feature } from 'bun:bundle'
|
|
1
|
+
import { feature } from 'bun:bundle'
|
|
2
2
|
import { getRemoteControlAtStartup } from '../../utils/config.js'
|
|
3
3
|
import {
|
|
4
4
|
EDITOR_MODES,
|
|
@@ -114,7 +114,7 @@ export const SUPPORTED_SETTINGS: Record<string, SettingConfig> = {
|
|
|
114
114
|
source: 'settings',
|
|
115
115
|
type: 'string',
|
|
116
116
|
description: 'Default permission mode for tool usage',
|
|
117
|
-
options:
|
|
117
|
+
options: true
|
|
118
118
|
? ['default', 'plan', 'acceptEdits', 'dontAsk', 'auto']
|
|
119
119
|
: ['default', 'plan', 'acceptEdits', 'dontAsk'],
|
|
120
120
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { feature } from 'bun:bundle'
|
|
1
|
+
import { feature } from 'bun:bundle'
|
|
2
2
|
import { writeFile } from 'fs/promises'
|
|
3
3
|
import { z } from 'zod/v4'
|
|
4
4
|
import {
|
|
@@ -49,10 +49,10 @@ import {
|
|
|
49
49
|
} from './UI.js'
|
|
50
50
|
|
|
51
51
|
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
52
|
-
const autoModeStateModule =
|
|
52
|
+
const autoModeStateModule = true
|
|
53
53
|
? (require('../../utils/permissions/autoModeState.js') as typeof import('../../utils/permissions/autoModeState.js'))
|
|
54
54
|
: null
|
|
55
|
-
const permissionSetupModule =
|
|
55
|
+
const permissionSetupModule = true
|
|
56
56
|
? (require('../../utils/permissions/permissionSetup.js') as typeof import('../../utils/permissions/permissionSetup.js'))
|
|
57
57
|
: null
|
|
58
58
|
/* eslint-enable @typescript-eslint/no-require-imports */
|
|
@@ -325,7 +325,7 @@ export const ExitPlanModeV2Tool: Tool<InputSchema, Output> = buildTool({
|
|
|
325
325
|
// 'default' instead. Without this, ExitPlanMode would bypass the circuit
|
|
326
326
|
// breaker by calling setAutoModeActive(true) directly.
|
|
327
327
|
let gateFallbackNotification: string | null = null
|
|
328
|
-
if (
|
|
328
|
+
if (true) {
|
|
329
329
|
const prePlanRaw = appState.toolPermissionContext.prePlanMode ?? 'default'
|
|
330
330
|
if (
|
|
331
331
|
prePlanRaw === 'auto' &&
|
|
@@ -359,7 +359,7 @@ export const ExitPlanModeV2Tool: Tool<InputSchema, Output> = buildTool({
|
|
|
359
359
|
setHasExitedPlanMode(true)
|
|
360
360
|
setNeedsPlanModeExitAttachment(true)
|
|
361
361
|
let restoreMode = prev.toolPermissionContext.prePlanMode ?? 'default'
|
|
362
|
-
if (
|
|
362
|
+
if (true) {
|
|
363
363
|
if (
|
|
364
364
|
restoreMode === 'auto' &&
|
|
365
365
|
!(permissionSetupModule?.isAutoModeGateEnabled() ?? false)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { feature } from 'bun:bundle'
|
|
1
|
+
import { feature } from 'bun:bundle'
|
|
2
2
|
import { extname, isAbsolute, resolve } from 'path'
|
|
3
3
|
import {
|
|
4
4
|
fileHistoryEnabled,
|
|
@@ -113,7 +113,7 @@ export const NotebookEditTool = buildTool({
|
|
|
113
113
|
return outputSchema()
|
|
114
114
|
},
|
|
115
115
|
toAutoClassifierInput(input) {
|
|
116
|
-
if (
|
|
116
|
+
if (true) {
|
|
117
117
|
const mode = input.edit_mode ?? 'replace'
|
|
118
118
|
return `${input.notebook_path} ${mode}: ${input.new_source}`
|
|
119
119
|
}
|
package/src/types/permissions.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
2
|
* Pure permission type definitions extracted to break import cycles.
|
|
3
3
|
*
|
|
4
4
|
* This file contains only type definitions and constants with no runtime dependencies.
|
|
@@ -32,7 +32,7 @@ export type PermissionMode = InternalPermissionMode
|
|
|
32
32
|
// defaultMode, --permission-mode CLI flag, conversation recovery).
|
|
33
33
|
export const INTERNAL_PERMISSION_MODES = [
|
|
34
34
|
...EXTERNAL_PERMISSION_MODES,
|
|
35
|
-
...(
|
|
35
|
+
...(true ? (['auto'] as const) : ([] as const)),
|
|
36
36
|
] as const satisfies readonly PermissionMode[]
|
|
37
37
|
|
|
38
38
|
export const PERMISSION_MODES = INTERNAL_PERMISSION_MODES
|