feat: open useful USER_TYPE-gated features to all users - #644
Conversation
Remove 13 process.env.USER_TYPE === 'ant' gates that restricted useful features to Anthropic employees. These features work without Anthropic infrastructure and are now available to all open-build users. Features opened: - Agent nesting (sub-agents can spawn sub-agents) - Effort 'max' persistence in settings - Plan mode interview phase (controlled by feature flags) - Sandbox disabled commands (via ~/.claude/feature-flags.json) - All tips visible to all users (plan mode, feedback, shift-tab) Simplified: - Fullscreen defaults to off (use /config to enable) - Explore agent always uses haiku model - Plan mode tool uses conservative prompt for all users Continues the USER_TYPE cleanup from Twigpine#637 (dead code) and builds on Twigpine#639 (local feature flags).
There was a problem hiding this comment.
Pull request overview
This PR removes several process.env.USER_TYPE === 'ant' gates to make previously internal-only (but infra-independent) features available to all users, including agent nesting, effort persistence, plan mode behavior, sandbox configuration, and tips.
Changes:
- Removes
USER_TYPE==='ant'gating for plan-mode interview phase, effort'max'persistence, sandbox disabled commands, and various tips. - Enables nested agents by allowing the Agent tool inside sub-agents; standardizes explore agent model to
haiku. - Simplifies defaults by turning off fullscreen-by-default for everyone and using the external plan-mode prompt for all users.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/utils/planModeV2.ts | Removes ant-only always-on behavior for interview phase; relies on env var + feature flag. |
| src/utils/fullscreen.ts | Changes fullscreen default fallback to always off. |
| src/utils/effort.ts | Allows 'max' to be persisted for all users via toPersistableEffort. |
| src/tools/EnterPlanModeTool/prompt.ts | Removes ant-specific prompt path; uses the external prompt for everyone. |
| src/tools/BashTool/shouldUseSandbox.ts | Makes sandbox disabled-commands feature flag apply to all users. |
| src/tools/AgentTool/built-in/exploreAgent.ts | Forces explore agent to always use haiku. |
| src/services/tips/tipRegistry.ts | Removes ant-only tip filtering and drops internal-only tips. |
| src/constants/tools.ts | Allows Agent tool for agents (enables nested sub-agents). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
1. bridgeConfig.ts: ungate bridge override functions — return env vars directly instead of hardcoded undefined 2. bridgeMain.ts + initReplBridge.ts: ungate sessionIngressUrl — read CLAUDE_BRIDGE_SESSION_INGRESS_URL without USER_TYPE check 3. tools.ts: remove dead ConfigTool/TungstenTool imports, narrow eslint-disable scope, stub REPLTool/SuggestBackgroundPRTool to null 4. readOnlyValidation.ts: remove orphaned ANT_ONLY_COMMAND_ALLOWLIST and unused GH_READ_ONLY_COMMANDS import 5. insights.ts: remove entire remote collection plumbing (types, functions, options, display logic) 6. osc.ts: hardcode supportsTabStatus() to false (internal-only feature) 7. state.ts: simplify addSlowOperation/getSlowOperations to no-ops, remove dead constants
1. settings/types.ts: allow 'max' effort level for all users in Zod schema — was still gated behind USER_TYPE=ant, causing 'max' to be silently dropped on settings reload 2. shouldUseSandbox.ts: defensively normalize disabledCommands from feature flag config with Array.isArray() guards
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 17 out of 17 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
1. shouldUseSandbox.ts: validate top-level shape of disabledCommands before accessing properties (handles null/primitive from feature flag) 2. fullscreen.ts: update JSDoc to reflect removal of USER_TYPE default 3. osc.ts: update JSDoc — "Ant-only" → "Currently disabled"
Vasanthdev2004
left a comment
There was a problem hiding this comment.
Review: Open useful USER_TYPE-gated features to all users
Reviewed on head 9b7c0e9. CI green ✅. 17 files, +75/-539.
✅ Scope and philosophy
The PR correctly targets only the 13 USER_TYPE === 'ant' gates that protect features working independently of Anthropic infrastructure. ~260 remaining gates (API-specific fields, telemetry, internal auth routing, classifier settings, model resolution) are intentionally left alone. This is the right boundary.
✅ Key changes verified
Agent nesting (src/constants/tools.ts):
Removing AGENT_TOOL_NAME from ALL_AGENT_DISALLOWED_TOOLS allows sub-agents to spawn their own sub-agents. CUSTOM_AGENT_DISALLOWED_TOOLS spreads from the same set, so it's automatically consistent. AGENT_TOOL_NAME was already in ASYNC_AGENT_ALLOWED_TOOLS (line 108), so async agent paths work too. This is the most impactful change and it's clean.
Effort 'max' persistence (src/utils/effort.ts + src/utils/settings/types.ts):
toPersistableEffort now returns 'max' for all users (not just ants). The Zod schema effortLevel enum is updated to ['low', 'medium', 'high', 'max'] (was conditional). Schema and persistence logic now match. ✅
Sandbox disabled commands (src/tools/BashTool/shouldUseSandbox.ts):
Good runtime validation added for the tengu_sandbox_disabled_commands feature flag value: typeof raw === 'object' && raw !== null guard + Array.isArray() checks on substrings and commands before iteration. Prevents crashes on malformed config. ✅
Plan mode interview (src/utils/planModeV2.ts):
Removed the if (USER_TYPE === 'ant') return true fast-path. Now falls through to the env var / feature flag check, which is the correct behavior — users can enable via CLAUDE_CODE_PLAN_MODE_INTERVIEW_PHASE=1 or the tengu_plan_mode_interview_phase feature flag (available via PR #639's ~/.claude/feature-flags.json).
Fullscreen default (src/utils/fullscreen.ts):
Defaults to false for all users instead of true for ants. JSDoc updated. Users can still enable via /config or CLAUDE_CODE_NO_FLICKER=1. ✅
Tips (src/services/tips/tipRegistry.ts):
Removed USER_TYPE === 'ant' → return false guards from plan-mode, shift-tab, and feedback tips. Removed internal-only tips (important-claudemd, skillify). External tip content now shown uniformly. ✅
OSC tab status (src/ink/termio/osc.ts):
supportsTabStatus() now returns false unconditionally instead of true for ants. JSDoc updated from "Ant-only" to "Currently disabled". This is correct — the spec is unstable and was never intended for external use. ✅
Dead code removal (src/tools.ts):
REPLTool and SuggestBackgroundPRTool set to null instead of being conditionally required. ConfigTool and TungstenTool imports removed entirely (they were ant-only). ✅
Insights remote host collection (src/commands/insights.ts):
Removed ~174 lines of Coder/homespace/SCP remote data collection. This was deeply Anthropic-internal infrastructure (SSH into Coder workspaces, SCP session files). The --homespaces flag and all related plumbing are gone. Clean removal. ✅
Slow operations tracking (src/bootstrap/state.ts):
addSlowOperation is now a no-op, getSlowOperations returns EMPTY_SLOW_OPERATIONS. Callers still work — they just never track anything. This was an internal dev-bar metric, not user-facing. ✅
Bridge config (src/bridge/bridgeConfig.ts, bridgeMain.ts, initReplBridge.ts):
CLAUDE_BRIDGE_OAUTH_TOKEN and CLAUDE_BRIDGE_BASE_URL overrides no longer require USER_TYPE === 'ant. These are dev overrides useful for anyone running local bridge endpoints. ✅
Explore agent (src/tools/AgentTool/built-in/exploreAgent.ts):
Model always 'haiku' — explore is a fast read-only search agent, haiku is the right choice. The ant-specific 'inherit' path used getAgentModel() + a GrowthBook flag, which is internal infrastructure. ✅
BashTool readOnlyValidation (src/tools/BashTool/readOnlyValidation.ts):
Removed ANT_ONLY_COMMAND_ALLOWLIST (66 lines) — gh read-only commands and aki (internal knowledge-base CLI). These are Anthropic-internal tools. ✅
🟡 Nit: dead code in tools.ts
Line 221 still has ...(process.env.USER_TYPE === 'ant' && REPLTool ? [REPLTool] : []) — but REPLTool is now always null, so this is dead code that never executes. The condition short-circuits to false, spreading []. Harmless but could be cleaned up to just ...(REPLTool ? [REPLTool] : []) or removed entirely. Non-blocking.
✅ All 6 Copilot comments resolved
- Zod schema
effortLevelnow includes'max'for all users ✅ Array.isArray()guards onsubstrings/commands✅typeof raw === 'object'guard for malformed config ✅isFullscreenEnvEnabledJSDoc updated ✅supportsTabStatusJSDoc updated ✅- PR description inaccuracy about
feature-flags.json— noted as doc issue, not code ✅
Verdict: Approve-ready ✅
Well-scoped USER_TYPE cleanup that only opens features working independently of Anthropic infrastructure. All Copilot issues addressed with proper runtime validation. Agent nesting is the headline change — clean and correct. One minor dead code nit in tools.ts. Kevin already approved. No blockers.
…pine#637, Twigpine#644) Consolidates PRs Twigpine#637 and Twigpine#644: - Remove ~45 dead USER_TYPE=ant guards across 28+ files (-1200 lines) - Open 13 useful features to all users (agent nesting, effort persistence, plan mode interview, sandbox config, tips visibility) - Key: src/constants/tools.ts — unlocks recursive agent spawning
* feat: open useful USER_TYPE-gated features to all users Remove 13 process.env.USER_TYPE === 'ant' gates that restricted useful features to Anthropic employees. These features work without Anthropic infrastructure and are now available to all open-build users. Features opened: - Agent nesting (sub-agents can spawn sub-agents) - Effort 'max' persistence in settings - Plan mode interview phase (controlled by feature flags) - Sandbox disabled commands (via ~/.claude/feature-flags.json) - All tips visible to all users (plan mode, feedback, shift-tab) Simplified: - Fullscreen defaults to off (use /config to enable) - Explore agent always uses haiku model - Plan mode tool uses conservative prompt for all users Continues the USER_TYPE cleanup from Twigpine#637 (dead code) and builds on Twigpine#639 (local feature flags). * fix: address Copilot review comments — remove residual dead code 1. bridgeConfig.ts: ungate bridge override functions — return env vars directly instead of hardcoded undefined 2. bridgeMain.ts + initReplBridge.ts: ungate sessionIngressUrl — read CLAUDE_BRIDGE_SESSION_INGRESS_URL without USER_TYPE check 3. tools.ts: remove dead ConfigTool/TungstenTool imports, narrow eslint-disable scope, stub REPLTool/SuggestBackgroundPRTool to null 4. readOnlyValidation.ts: remove orphaned ANT_ONLY_COMMAND_ALLOWLIST and unused GH_READ_ONLY_COMMANDS import 5. insights.ts: remove entire remote collection plumbing (types, functions, options, display logic) 6. osc.ts: hardcode supportsTabStatus() to false (internal-only feature) 7. state.ts: simplify addSlowOperation/getSlowOperations to no-ops, remove dead constants * fix: address Copilot review on PR Twigpine#644 1. settings/types.ts: allow 'max' effort level for all users in Zod schema — was still gated behind USER_TYPE=ant, causing 'max' to be silently dropped on settings reload 2. shouldUseSandbox.ts: defensively normalize disabledCommands from feature flag config with Array.isArray() guards * fix: address second round of Copilot review on PR Twigpine#644 1. shouldUseSandbox.ts: validate top-level shape of disabledCommands before accessing properties (handles null/primitive from feature flag) 2. fullscreen.ts: update JSDoc to reflect removal of USER_TYPE default 3. osc.ts: update JSDoc — "Ant-only" → "Currently disabled"
* feat: open useful USER_TYPE-gated features to all users Remove 13 process.env.USER_TYPE === 'ant' gates that restricted useful features to Anthropic employees. These features work without Anthropic infrastructure and are now available to all open-build users. Features opened: - Agent nesting (sub-agents can spawn sub-agents) - Effort 'max' persistence in settings - Plan mode interview phase (controlled by feature flags) - Sandbox disabled commands (via ~/.claude/feature-flags.json) - All tips visible to all users (plan mode, feedback, shift-tab) Simplified: - Fullscreen defaults to off (use /config to enable) - Explore agent always uses haiku model - Plan mode tool uses conservative prompt for all users Continues the USER_TYPE cleanup from Twigpine#637 (dead code) and builds on Twigpine#639 (local feature flags). * fix: address Copilot review comments — remove residual dead code 1. bridgeConfig.ts: ungate bridge override functions — return env vars directly instead of hardcoded undefined 2. bridgeMain.ts + initReplBridge.ts: ungate sessionIngressUrl — read CLAUDE_BRIDGE_SESSION_INGRESS_URL without USER_TYPE check 3. tools.ts: remove dead ConfigTool/TungstenTool imports, narrow eslint-disable scope, stub REPLTool/SuggestBackgroundPRTool to null 4. readOnlyValidation.ts: remove orphaned ANT_ONLY_COMMAND_ALLOWLIST and unused GH_READ_ONLY_COMMANDS import 5. insights.ts: remove entire remote collection plumbing (types, functions, options, display logic) 6. osc.ts: hardcode supportsTabStatus() to false (internal-only feature) 7. state.ts: simplify addSlowOperation/getSlowOperations to no-ops, remove dead constants * fix: address Copilot review on PR Twigpine#644 1. settings/types.ts: allow 'max' effort level for all users in Zod schema — was still gated behind USER_TYPE=ant, causing 'max' to be silently dropped on settings reload 2. shouldUseSandbox.ts: defensively normalize disabledCommands from feature flag config with Array.isArray() guards * fix: address second round of Copilot review on PR Twigpine#644 1. shouldUseSandbox.ts: validate top-level shape of disabledCommands before accessing properties (handles null/primitive from feature flag) 2. fullscreen.ts: update JSDoc to reflect removal of USER_TYPE default 3. osc.ts: update JSDoc — "Ant-only" → "Currently disabled"
* feat: open useful USER_TYPE-gated features to all users Remove 13 process.env.USER_TYPE === 'ant' gates that restricted useful features to Anthropic employees. These features work without Anthropic infrastructure and are now available to all open-build users. Features opened: - Agent nesting (sub-agents can spawn sub-agents) - Effort 'max' persistence in settings - Plan mode interview phase (controlled by feature flags) - Sandbox disabled commands (via ~/.claude/feature-flags.json) - All tips visible to all users (plan mode, feedback, shift-tab) Simplified: - Fullscreen defaults to off (use /config to enable) - Explore agent always uses haiku model - Plan mode tool uses conservative prompt for all users Continues the USER_TYPE cleanup from Twigpine#637 (dead code) and builds on Twigpine#639 (local feature flags). * fix: address Copilot review comments — remove residual dead code 1. bridgeConfig.ts: ungate bridge override functions — return env vars directly instead of hardcoded undefined 2. bridgeMain.ts + initReplBridge.ts: ungate sessionIngressUrl — read CLAUDE_BRIDGE_SESSION_INGRESS_URL without USER_TYPE check 3. tools.ts: remove dead ConfigTool/TungstenTool imports, narrow eslint-disable scope, stub REPLTool/SuggestBackgroundPRTool to null 4. readOnlyValidation.ts: remove orphaned ANT_ONLY_COMMAND_ALLOWLIST and unused GH_READ_ONLY_COMMANDS import 5. insights.ts: remove entire remote collection plumbing (types, functions, options, display logic) 6. osc.ts: hardcode supportsTabStatus() to false (internal-only feature) 7. state.ts: simplify addSlowOperation/getSlowOperations to no-ops, remove dead constants * fix: address Copilot review on PR Twigpine#644 1. settings/types.ts: allow 'max' effort level for all users in Zod schema — was still gated behind USER_TYPE=ant, causing 'max' to be silently dropped on settings reload 2. shouldUseSandbox.ts: defensively normalize disabledCommands from feature flag config with Array.isArray() guards * fix: address second round of Copilot review on PR Twigpine#644 1. shouldUseSandbox.ts: validate top-level shape of disabledCommands before accessing properties (handles null/primitive from feature flag) 2. fullscreen.ts: update JSDoc to reflect removal of USER_TYPE default 3. osc.ts: update JSDoc — "Ant-only" → "Currently disabled"
Summary
Remove 13
process.env.USER_TYPE === 'ant'gates that restricted useful features to Anthropic employees. These features work without Anthropic infrastructure and are now available to all open-build users.Highlight: agent nesting unlocked
The most impactful change is a single line removed in
src/constants/tools.ts:41:This line added
AGENT_TOOL_NAMEto the disallowed tools list for sub-agents, preventing non-ant users from using recursive agent workflows. Removing it unlocks recursive agent spawning: a sub-agent can now spawn its own sub-agents. This enables complex coordination patterns (agent teams, hierarchical delegation) that were previously reserved for Anthropic employees.All changes
Features opened:
src/constants/tools.ts)src/utils/effort.ts)src/utils/planModeV2.ts)~/.claude/feature-flags.json(src/tools/BashTool/shouldUseSandbox.ts)src/services/tips/tipRegistry.ts)Simplified:
/configto enable) (src/utils/fullscreen.ts)src/tools/AgentTool/built-in/exploreAgent.ts)src/tools/EnterPlanModeTool/prompt.ts)Continues the USER_TYPE cleanup from #637 (dead code removal) and builds on #639 (local feature flags).
Test plan
bun run build— compiles successfullybun run smoke— smoke tests passUSER_TYPE=ant