@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.
- package/__test__/agent.test.ts +64 -0
- package/bin/agent.js +42 -0
- package/bin/helpers.js +2 -1
- package/bin/telemetry/track.js +18 -11
- package/bin/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +7 -7
- package/src/agent.ts +56 -0
- package/src/helpers.tsx +2 -3
- package/src/telemetry/track.ts +19 -15
|
@@ -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
|
|
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);
|
package/bin/telemetry/track.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
});
|