@mintlify/cli 4.0.1562 → 4.0.1564

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.
@@ -0,0 +1,64 @@
1
+ import { detectAgent, isCI } from '../src/agent.js';
2
+
3
+ const originalIsTTY = process.stdout.isTTY;
4
+
5
+ afterEach(() => {
6
+ process.stdout.isTTY = originalIsTTY;
7
+ });
8
+
9
+ describe('detectAgent', () => {
10
+ it('returns undefined with no agent env', () => {
11
+ expect(detectAgent({})).toBeUndefined();
12
+ });
13
+
14
+ it.each([
15
+ [{ CLAUDECODE: '1' }, 'claude_code'],
16
+ [{ TERM_PROGRAM: 'claude' }, 'claude_code'],
17
+ [{ CLAUDECODE: '1', CLAUDE_CODE_IS_COWORK: '1' }, 'cowork'],
18
+ [{ CODEX_THREAD_ID: 'abc' }, 'codex_cli'],
19
+ [{ GEMINI_CLI: '1' }, 'gemini_cli'],
20
+ [{ CURSOR_AGENT: '1' }, 'cursor-cli'],
21
+ [{ OPENCODE: '1' }, 'open_code'],
22
+ [{ PATH: '/usr/bin:/home/me/.pi/agent/bin' }, 'pi'],
23
+ [{ EDITOR: '/opt/devin/bin/code' }, 'devin'],
24
+ ])('detects %o as %s', (env, expected) => {
25
+ expect(detectAgent(env)).toBe(expected);
26
+ });
27
+
28
+ it('prefers explicit AI_AGENT and AGENT', () => {
29
+ expect(detectAgent({ AI_AGENT: 'Amp', CLAUDECODE: '1' })).toBe('amp');
30
+ expect(detectAgent({ AGENT: 'goose' })).toBe('goose');
31
+ });
32
+
33
+ it('prefers CLI agents over IDE hosts', () => {
34
+ process.stdout.isTTY = false;
35
+ expect(detectAgent({ CLAUDECODE: '1', CURSOR_TRACE_ID: 'x' })).toBe('claude_code');
36
+ expect(detectAgent({ CURSOR_TRACE_ID: 'x' })).toBe('cursor');
37
+ });
38
+
39
+ it('ignores IDE and config markers when a human is at a TTY', () => {
40
+ process.stdout.isTTY = true;
41
+ expect(
42
+ detectAgent({
43
+ CURSOR_TRACE_ID: 'x',
44
+ REPL_ID: 'y',
45
+ TERM_PROGRAM: 'kiro',
46
+ GOOSE_PROVIDER: 'openai',
47
+ COPILOT_MODEL: 'gpt',
48
+ OPENCODE_CLIENT: 'desktop',
49
+ })
50
+ ).toBeUndefined();
51
+ });
52
+ });
53
+
54
+ describe('isCI', () => {
55
+ it.each([
56
+ [{}, false],
57
+ [{ CI: 'true' }, true],
58
+ [{ CI: '1' }, true],
59
+ [{ CI: 'false' }, false],
60
+ [{ CI: '0' }, false],
61
+ ])('%o -> %s', (env, expected) => {
62
+ expect(isCI(env)).toBe(expected);
63
+ });
64
+ });
package/bin/agent.js ADDED
@@ -0,0 +1,42 @@
1
+ import { existsSync } from 'node:fs';
2
+ const set = (...names) => (env) => names.some((name) => Boolean(env[name]));
3
+ const matches = (name, pattern) => (env) => { var _a; return pattern.test((_a = env[name]) !== null && _a !== void 0 ? _a : ''); };
4
+ const noTTY = (check) => (env) => !process.stdout.isTTY && check(env);
5
+ const AGENTS = [
6
+ [
7
+ 'cursor-cli',
8
+ (env) => set('CURSOR_AGENT')(env) || env.CURSOR_EXTENSION_HOST_ROLE === 'agent-exec',
9
+ ],
10
+ ['kimi', set('KIMI_PLUGIN_ROOT')],
11
+ ['grok', set('GROK_PLUGIN_ROOT', 'GROK_PLUGIN_DATA')],
12
+ ['gemini_cli', set('GEMINI_CLI')],
13
+ ['cline', set('CLINE_ACTIVE')],
14
+ [
15
+ 'codex_cli',
16
+ set('CODEX_SANDBOX', 'CODEX_CI', 'CODEX_THREAD_ID', 'CODEX_SANDBOX_NETWORK_DISABLED'),
17
+ ],
18
+ ['antigravity', set('ANTIGRAVITY_AGENT', 'ANTIGRAVITY_CLI_ALIAS')],
19
+ ['augment-cli', set('AUGMENT_AGENT')],
20
+ ['open_code', (env) => set('OPENCODE')(env) || noTTY(set('OPENCODE_CLIENT'))(env)],
21
+ ['goose', noTTY(set('GOOSE_PROVIDER'))],
22
+ ['junie', set('JUNIE_DATA', 'JUNIE_SHIM_PATH')],
23
+ ['pi', matches('PATH', /\.pi[\\/]agent/)],
24
+ ['cowork', (env) => set('CLAUDE_CODE_IS_COWORK')(env) && set('CLAUDECODE', 'CLAUDE_CODE')(env)],
25
+ ['claude_code', (env) => set('CLAUDECODE', 'CLAUDE_CODE')(env) || env.TERM_PROGRAM === 'claude'],
26
+ ['github-copilot', noTTY(set('COPILOT_MODEL', 'COPILOT_ALLOW_ALL'))],
27
+ ['openclaw', set('OPENCLAW_SHELL')],
28
+ ['devin', (env) => matches('EDITOR', /devin/)(env) || existsSync('/opt/.devin')],
29
+ ['replit', noTTY(set('REPL_ID'))],
30
+ ['kiro', noTTY(matches('TERM_PROGRAM', /kiro/))],
31
+ ['cursor', noTTY(set('CURSOR_TRACE_ID'))],
32
+ ];
33
+ export function detectAgent(env = process.env) {
34
+ var _a, _b;
35
+ const explicit = (_a = (env.AI_AGENT || env.AGENT)) === null || _a === void 0 ? void 0 : _a.trim();
36
+ if (explicit)
37
+ return explicit.toLowerCase();
38
+ return (_b = AGENTS.find(([, check]) => check(env))) === null || _b === void 0 ? void 0 : _b[0];
39
+ }
40
+ export function isCI(env = process.env) {
41
+ return Boolean(env.CI && env.CI !== 'false' && env.CI !== '0');
42
+ }
package/bin/helpers.js CHANGED
@@ -23,6 +23,7 @@ import { createRequire } from 'node:module';
23
23
  import { fileURLToPath } from 'node:url';
24
24
  import { promisify } from 'node:util';
25
25
  import path from 'path';
26
+ import { detectAgent } from './agent.js';
26
27
  import { shutdownPostHog } from './telemetry/client.js';
27
28
  export const CMD_EXEC_PATH = process.cwd();
28
29
  export const checkPort = (argv) => __awaiter(void 0, void 0, void 0, function* () {
@@ -217,7 +218,7 @@ export const terminate = (code) => __awaiter(void 0, void 0, void 0, function* (
217
218
  });
218
219
  export const execFileAsync = promisify(execFile);
219
220
  export function isAI() {
220
- return (!process.stdin.isTTY || process.env.CLAUDECODE === '1' || process.env.TERM_PROGRAM === 'claude');
221
+ return !process.stdin.isTTY || detectAgent() !== undefined;
221
222
  }
222
223
  export const detectPackageManager = (_a) => __awaiter(void 0, [_a], void 0, function* ({ packageName }) {
223
224
  assertValidPackageName(packageName);
@@ -8,13 +8,26 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import os from 'os';
11
+ import { detectAgent, isCI } from '../agent.js';
11
12
  import { isTelemetryEnabled } from '../config.js';
12
13
  import { TELEMETRY_ASYNC_TIMEOUT_MS, TELEMETRY_IDENTITY_TIMEOUT_MS } from '../constants.js';
13
- import { getVersions, isAI } from '../helpers.js';
14
+ import { getVersions } from '../helpers.js';
14
15
  import { getAccessToken, getUserEmail, storeUserEmail } from '../keyring.js';
15
16
  import { fetchCliStatus } from '../status.js';
16
17
  import { deferShutdownUntil, getPostHogClient } from './client.js';
17
18
  import { getDistinctId } from './distinctId.js';
19
+ function getEnvironmentProperties() {
20
+ const agent = detectAgent();
21
+ return {
22
+ os: os.platform(),
23
+ arch: os.arch(),
24
+ node_version: process.version,
25
+ is_ai_agent: agent !== undefined,
26
+ ai_agent: agent,
27
+ is_ci: isCI(),
28
+ is_tty: Boolean(process.stdin.isTTY),
29
+ };
30
+ }
18
31
  function captureWithTimeout(event, properties) {
19
32
  return __awaiter(this, void 0, void 0, function* () {
20
33
  yield Promise.race([
@@ -59,7 +72,7 @@ export function trackCommand(_a) {
59
72
  const work = (() => __awaiter(this, void 0, void 0, function* () {
60
73
  try {
61
74
  const email = yield getAuthenticatedUserEmail();
62
- yield captureWithTimeout('cli.command.executed', Object.assign({ command, cli_version: cliVersion, os: os.platform(), arch: os.arch(), node_version: process.version, is_ai_agent: isAI(), subdomain }, (email ? { email, $set: { email } } : {})));
75
+ yield captureWithTimeout('cli.command.executed', Object.assign(Object.assign(Object.assign({ command, cli_version: cliVersion }, getEnvironmentProperties()), { subdomain }), (email ? { email, $set: { email } } : {})));
63
76
  }
64
77
  catch (_a) { }
65
78
  }))();
@@ -73,7 +86,7 @@ function trackLoginEvent(event, extra) {
73
86
  return;
74
87
  try {
75
88
  const { cli: cliVersion } = getVersions();
76
- yield captureWithTimeout(event, Object.assign(Object.assign({}, extra), { cli_version: cliVersion, os: os.platform(), arch: os.arch(), node_version: process.version }));
89
+ yield captureWithTimeout(event, Object.assign(Object.assign(Object.assign({}, extra), { cli_version: cliVersion }), getEnvironmentProperties()));
77
90
  }
78
91
  catch (_a) { }
79
92
  });
@@ -99,7 +112,7 @@ export function trackEvent(event, properties) {
99
112
  return;
100
113
  try {
101
114
  const { cli: cliVersion } = getVersions();
102
- yield captureWithTimeout(event, Object.assign(Object.assign({}, properties), { cli_version: cliVersion, os: os.platform(), arch: os.arch(), node_version: process.version, is_ai_agent: isAI() }));
115
+ yield captureWithTimeout(event, Object.assign(Object.assign(Object.assign({}, properties), { cli_version: cliVersion }), getEnvironmentProperties()));
103
116
  }
104
117
  catch (_a) { }
105
118
  });
@@ -110,13 +123,7 @@ export function trackTelemetryPreferenceChange(options) {
110
123
  return;
111
124
  try {
112
125
  const { cli: cliVersion } = getVersions();
113
- yield captureWithTimeout('cli.telemetry.preference_changed', {
114
- enabled: options.enabled,
115
- cli_version: cliVersion,
116
- os: os.platform(),
117
- arch: os.arch(),
118
- node_version: process.version,
119
- });
126
+ yield captureWithTimeout('cli.telemetry.preference_changed', Object.assign({ enabled: options.enabled, cli_version: cliVersion }, getEnvironmentProperties()));
120
127
  }
121
128
  catch (_a) { }
122
129
  });