Remove internal-only tooling from the external build (#352)

* Remove internal-only tooling without changing external runtime contracts

This trims the lowest-risk internal-only surfaces first: deleted internal
modules are replaced by build-time no-op stubs, the bundled stuck skill is
removed, and the insights S3 upload path now stays local-only. The privacy
verifier is expanded and the remaining bundled internal Slack/Artifactory
strings are neutralized without broad repo-wide renames.

Constraint: Keep the first PR deletion-heavy and avoid mass rewrites of USER_TYPE, tengu, or claude_code identifiers
Rejected: One-shot DMCA cleanup branch | too much semantic risk for a first PR
Confidence: medium
Scope-risk: moderate
Reversibility: clean
Directive: Treat full-repo typecheck as a baseline issue on this upstream snapshot; do not claim this commit introduced the existing non-Phase-A errors without isolating them first
Tested: bun run build
Tested: bun run smoke
Tested: bun run verify:privacy
Not-tested: Full repo typecheck (currently fails on widespread pre-existing upstream errors outside this change set)

* Keep minimal source shims so CI can import Phase A cleanup paths

The first PR removed internal-only source files entirely, but CI provider
and context tests import those modules directly from source rather than
through the build-time no-telemetry stubs. This restores tiny no-op source
shims so tests and local source imports resolve while preserving the same
external runtime behavior.

Constraint: GitHub Actions runs source-level tests in addition to bundled build/privacy checks
Rejected: Revert the entire deletion pass | unnecessary once the import contract is satisfied by small shims
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: For later cleanup phases, treat build-time stubs and source-test imports as separate compatibility surfaces
Tested: bun run build
Tested: bun run smoke
Tested: bun run verify:privacy
Tested: bun run test:provider
Tested: bun run test:provider-recommendation
Not-tested: Full repo typecheck (still noisy on this upstream snapshot)

---------

Co-authored-by: anandh8x <test@example.com>
This commit is contained in:
Anandan
2026-04-04 23:04:34 +05:30
committed by GitHub
parent 75d2543854
commit 9e84d2fddc
17 changed files with 148 additions and 1729 deletions

View File

@@ -1390,6 +1390,12 @@ const detectHostIP = memoize(
)
async function installFromArtifactory(command: string): Promise<string> {
const artifactoryBaseUrl =
process.env.CLAUDE_CODE_INTERNAL_ARTIFACTORY_BASE_URL
if (!artifactoryBaseUrl) {
throw new Error('Internal artifactory base URL is not configured')
}
const npmrcAuthPrefix = `//${artifactoryBaseUrl.replace(/^https?:\/\//, '')}/api/npm/npm-all/:_authToken=`
// Read auth token from ~/.npmrc
const npmrcPath = join(os.homedir(), '.npmrc')
let authToken: string | null = null
@@ -1402,11 +1408,8 @@ async function installFromArtifactory(command: string): Promise<string> {
const lines = npmrcContent.split('\n')
for (const line of lines) {
// Look for the artifactory auth token line
const match = line.match(
/\/\/artifactory\.infra\.ant\.dev\/artifactory\/api\/npm\/npm-all\/:_authToken=(.+)/,
)
if (match && match[1]) {
authToken = match[1].trim()
if (line.startsWith(npmrcAuthPrefix)) {
authToken = line.slice(npmrcAuthPrefix.length).trim()
break
}
}
@@ -1420,8 +1423,7 @@ async function installFromArtifactory(command: string): Promise<string> {
}
// Fetch the version from artifactory
const versionUrl =
'https://artifactory.infra.ant.dev/artifactory/armorcode-claude-code-internal/claude-vscode-releases/stable'
const versionUrl = `${artifactoryBaseUrl}/armorcode-claude-code-internal/claude-vscode-releases/stable`
try {
const versionResponse = await axios.get(versionUrl, {
@@ -1436,7 +1438,7 @@ async function installFromArtifactory(command: string): Promise<string> {
}
// Download the .vsix file from artifactory
const vsixUrl = `https://artifactory.infra.ant.dev/artifactory/armorcode-claude-code-internal/claude-vscode-releases/${version}/claude-code.vsix`
const vsixUrl = `${artifactoryBaseUrl}/armorcode-claude-code-internal/claude-vscode-releases/${version}/claude-code.vsix`
const tempVsixPath = join(
os.tmpdir(),
`claude-code-${version}-${Date.now()}.vsix`,

View File

@@ -25,11 +25,14 @@ import { getBinaryName, getPlatform } from './installer.js'
const GCS_BUCKET_URL =
'https://storage.googleapis.com/claude-code-dist-86c565f3-f756-42ad-8dfa-d59b1c096819/claude-code-releases'
export const ARTIFACTORY_REGISTRY_URL =
'https://artifactory.infra.ant.dev/artifactory/api/npm/npm-all/'
process.env.CLAUDE_CODE_INTERNAL_ARTIFACTORY_REGISTRY_URL ?? ''
export async function getLatestVersionFromArtifactory(
tag: string = 'latest',
): Promise<string> {
if (!ARTIFACTORY_REGISTRY_URL) {
throw new Error('Internal artifactory registry URL is not configured')
}
const startTime = Date.now()
const { stdout, code, stderr } = await execFileNoThrowWithCwd(
'npm',
@@ -152,6 +155,9 @@ export async function downloadVersionFromArtifactory(
version: string,
stagingPath: string,
) {
if (!ARTIFACTORY_REGISTRY_URL) {
throw new Error('Internal artifactory registry URL is not configured')
}
const fs = getFsImplementation()
// If we get here, we own the lock and can delete a partial download

View File

@@ -1059,9 +1059,7 @@ export function getAutoModeUnavailableNotification(
base = 'auto mode unavailable for this model'
break
}
return process.env.USER_TYPE === 'ant'
? `${base} · #claude-code-feedback`
: base
return base
}
/**

View File

@@ -1,89 +1,11 @@
/**
* Undercover mode — safety utilities for contributing to public/open-source repos.
*
* When active, Claude Code adds safety instructions to commit/PR prompts and
* strips all attribution to avoid leaking internal model codenames, project
* names, or other Anthropic-internal information. The model is not told what
* model it is.
*
* Activation:
* - CLAUDE_CODE_UNDERCOVER=1 — force ON (even in internal repos)
* - Otherwise AUTO: active UNLESS the repo remote matches the internal
* allowlist (INTERNAL_MODEL_REPOS in commitAttribution.ts). Safe default
* is ON — Claude may push to public remotes from a CWD that isn't itself
* a git checkout (e.g. /tmp crash repro).
* - There is NO force-OFF. This guards against model codename leaks — if
* we're not confident we're in an internal repo, we stay undercover.
*
* All code paths are gated on process.env.USER_TYPE === 'ant'. Since USER_TYPE is
* a build-time --define, the bundler constant-folds these checks and dead-code-
* eliminates the ant-only branches from external builds. In external builds every
* function in this file reduces to a trivial return.
*/
import { getRepoClassCached } from './commitAttribution.js'
import { getGlobalConfig } from './config.js'
import { isEnvTruthy } from './envUtils.js'
export function isUndercover(): boolean {
if (process.env.USER_TYPE === 'ant') {
if (isEnvTruthy(process.env.CLAUDE_CODE_UNDERCOVER)) return true
// Auto: active unless we've positively confirmed we're in an allowlisted
// internal repo. 'external', 'none', and null (check not yet run) all
// resolve to ON. The check is primed in setup.ts; only 'internal' → OFF.
return getRepoClassCached() !== 'internal'
}
return false
}
export function getUndercoverInstructions(): string {
if (process.env.USER_TYPE === 'ant') {
return `## UNDERCOVER MODE — CRITICAL
You are operating UNDERCOVER in a PUBLIC/OPEN-SOURCE repository. Your commit
messages, PR titles, and PR bodies MUST NOT contain ANY Anthropic-internal
information. Do not blow your cover.
NEVER include in commit messages or PR descriptions:
- Internal model codenames (animal names like Capybara, Tengu, etc.)
- Unreleased model version numbers (e.g., opus-4-7, sonnet-4-8)
- Internal repo or project names (e.g., claude-cli-internal, anthropics/…)
- Internal tooling, Slack channels, or short links (e.g., go/cc, #claude-code-…)
- The phrase "Claude Code" or any mention that you are an AI
- Any hint of what model or version you are
- Co-Authored-By lines or any other attribution
Write commit messages as a human developer would — describe only what the code
change does.
GOOD:
- "Fix race condition in file watcher initialization"
- "Add support for custom key bindings"
- "Refactor parser for better error messages"
BAD (never write these):
- "Fix bug found while testing with Claude Capybara"
- "1-shotted by claude-opus-4-6"
- "Generated with Claude Code"
- "Co-Authored-By: Claude Opus 4.6 <…>"
`
}
return ''
}
/**
* Check whether to show the one-time explainer dialog for auto-undercover.
* True when: undercover is active via auto-detection (not forced via env),
* and the user hasn't seen the notice before. Pure — the component marks the
* flag on mount.
*/
export function shouldShowUndercoverAutoNotice(): boolean {
if (process.env.USER_TYPE === 'ant') {
// If forced via env, user already knows; don't nag.
if (isEnvTruthy(process.env.CLAUDE_CODE_UNDERCOVER)) return false
if (!isUndercover()) return false
if (getGlobalConfig().hasSeenUndercoverAutoNotice) return false
return true
}
return false
}