context-lens 0.7.3 ā 0.8.0
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/dist/cli-utils.d.ts +6 -5
- package/dist/cli-utils.d.ts.map +1 -1
- package/dist/cli-utils.js +25 -22
- package/dist/cli-utils.js.map +1 -1
- package/dist/cli.js +133 -50
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +28 -0
- package/dist/config.js.map +1 -1
- package/dist/core/conversation.d.ts +3 -2
- package/dist/core/conversation.d.ts.map +1 -1
- package/dist/core/conversation.js +9 -3
- package/dist/core/conversation.js.map +1 -1
- package/dist/core/parse.d.ts.map +1 -1
- package/dist/core/parse.js +57 -5
- package/dist/core/parse.js.map +1 -1
- package/dist/core/security.d.ts.map +1 -1
- package/dist/core/security.js +15 -1
- package/dist/core/security.js.map +1 -1
- package/dist/importers/claude-code.d.ts +19 -0
- package/dist/importers/claude-code.d.ts.map +1 -0
- package/dist/importers/claude-code.js +166 -0
- package/dist/importers/claude-code.js.map +1 -0
- package/dist/importers/codex.d.ts +22 -0
- package/dist/importers/codex.d.ts.map +1 -0
- package/dist/importers/codex.js +172 -0
- package/dist/importers/codex.js.map +1 -0
- package/dist/importers/index.d.ts +12 -0
- package/dist/importers/index.d.ts.map +1 -0
- package/dist/importers/index.js +153 -0
- package/dist/importers/index.js.map +1 -0
- package/dist/importers/types.d.ts +51 -0
- package/dist/importers/types.d.ts.map +1 -0
- package/dist/importers/types.js +8 -0
- package/dist/importers/types.js.map +1 -0
- package/dist/lhar/composition.d.ts.map +1 -1
- package/dist/lhar/composition.js +13 -0
- package/dist/lhar/composition.js.map +1 -1
- package/dist/lhar/response.d.ts.map +1 -1
- package/dist/lhar/response.js +17 -1
- package/dist/lhar/response.js.map +1 -1
- package/dist/server/api.d.ts.map +1 -1
- package/dist/server/api.js +72 -0
- package/dist/server/api.js.map +1 -1
- package/dist/server/store.d.ts +3 -0
- package/dist/server/store.d.ts.map +1 -1
- package/dist/server/store.js +12 -2
- package/dist/server/store.js.map +1 -1
- package/dist/types.d.ts +16 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/version.generated.d.ts +1 -1
- package/dist/version.generated.js +1 -1
- package/mitm_addon.py +107 -4
- package/package.json +4 -4
- package/ui/dist/assets/index-BlAdJWw0.css +1 -0
- package/ui/dist/assets/index-DO3TMDY3.js +58 -0
- package/ui/dist/index.html +2 -2
- package/ui/dist/assets/index-CZq91bC_.js +0 -52
- package/ui/dist/assets/index-DSyD9xgM.css +0 -1
package/dist/cli-utils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ToolConfig } from "./types.js";
|
|
1
|
+
import type { MitmConfig, ToolConfig } from "./types.js";
|
|
2
2
|
declare const KNOWN_REDACT_PRESETS: readonly ["secrets", "pii", "strict"];
|
|
3
3
|
type RedactPreset = (typeof KNOWN_REDACT_PRESETS)[number];
|
|
4
4
|
export interface ParsedCliArgs {
|
|
@@ -20,14 +20,15 @@ export declare function resolveCommandAlias(commandName: string): string;
|
|
|
20
20
|
export declare function parseCliArgs(args: string[]): ParsedCliArgs;
|
|
21
21
|
export declare function formatHelpText(): string;
|
|
22
22
|
export declare const CLI_CONSTANTS: {
|
|
23
|
-
readonly PROXY_URL:
|
|
24
|
-
readonly
|
|
25
|
-
readonly
|
|
23
|
+
readonly PROXY_URL: string;
|
|
24
|
+
readonly PROXY_PORT: number;
|
|
25
|
+
readonly UI_PORT: number;
|
|
26
|
+
readonly UI_URL: string;
|
|
26
27
|
readonly PI_AGENT_DIR_PREFIX: "/tmp/context-lens-pi-agent-";
|
|
27
28
|
readonly BRYTI_DATA_DIR_PREFIX: "/tmp/context-lens-bryti-";
|
|
28
29
|
readonly COMMAND_ALIASES: Record<string, string>;
|
|
29
30
|
readonly KNOWN_PRIVACY_LEVELS: readonly ["minimal", "standard", "full"];
|
|
30
|
-
readonly MITM_ADDON_PATH: string;
|
|
31
31
|
};
|
|
32
|
+
export declare function getMitmConfig(): MitmConfig;
|
|
32
33
|
export {};
|
|
33
34
|
//# sourceMappingURL=cli-utils.d.ts.map
|
package/dist/cli-utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-utils.d.ts","sourceRoot":"","sources":["../src/cli-utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli-utils.d.ts","sourceRoot":"","sources":["../src/cli-utils.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA2BzD,QAAA,MAAM,oBAAoB,uCAAwC,CAAC;AACnE,KAAK,YAAY,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAM1D,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,aAAa,EAAE,OAAO,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA2GD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAY1D;AAED,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CA0J1D;AAED,wBAAgB,cAAc,IAAI,MAAM,CAyEvC;AAGD,eAAO,MAAM,aAAa;;;;;;;;;CAShB,CAAC;AACX,wBAAgB,aAAa,IAAI,UAAU,CAU1C"}
|
package/dist/cli-utils.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { dirname, join } from "node:path";
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { loadConfig } from "./config.js";
|
|
3
4
|
import { VERSION } from "./version.generated.js";
|
|
4
5
|
const __filename = fileURLToPath(import.meta.url);
|
|
5
6
|
const __dirname = dirname(__filename);
|
|
6
7
|
// Known tool config: env vars for the child process, extra CLI args, server env vars, and whether mitmproxy is needed
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
8
|
+
const config = loadConfig();
|
|
9
|
+
const PROXY_PORT = Number.isNaN(config.proxy.port) ? 4040 : config.proxy.port;
|
|
10
|
+
const PROXY_URL = `http://localhost:${PROXY_PORT}`;
|
|
11
|
+
const UI_PORT = Number.isNaN(config.ui.port) ? 4041 : config.ui.port;
|
|
12
|
+
const UI_URL = `http://localhost:${UI_PORT}`;
|
|
10
13
|
const PI_AGENT_DIR_PREFIX = "/tmp/context-lens-pi-agent-";
|
|
11
14
|
const BRYTI_DATA_DIR_PREFIX = "/tmp/context-lens-bryti-";
|
|
12
15
|
const COMMAND_ALIASES = {
|
|
@@ -38,10 +41,7 @@ const TOOL_CONFIG = {
|
|
|
38
41
|
// We use mitmproxy as a forward HTTPS proxy to intercept traffic.
|
|
39
42
|
// The mitmproxy addon captures requests and POSTs them to the
|
|
40
43
|
// analysis server's ingest API.
|
|
41
|
-
childEnv: {
|
|
42
|
-
https_proxy: MITM_PROXY_URL,
|
|
43
|
-
SSL_CERT_FILE: "", // filled in by cli.ts with mitmproxy CA cert path
|
|
44
|
-
},
|
|
44
|
+
childEnv: {},
|
|
45
45
|
extraArgs: [],
|
|
46
46
|
serverEnv: {},
|
|
47
47
|
needsMitm: true,
|
|
@@ -54,11 +54,7 @@ const TOOL_CONFIG = {
|
|
|
54
54
|
//
|
|
55
55
|
// Cline is a Node.js process. Node ignores SSL_CERT_FILE and requires
|
|
56
56
|
// NODE_EXTRA_CA_CERTS to trust the mitmproxy CA certificate.
|
|
57
|
-
childEnv: {
|
|
58
|
-
https_proxy: MITM_PROXY_URL,
|
|
59
|
-
SSL_CERT_FILE: "", // for any native/curl components
|
|
60
|
-
NODE_EXTRA_CA_CERTS: "", // filled in by cli.ts with mitmproxy CA cert path
|
|
61
|
-
},
|
|
57
|
+
childEnv: {},
|
|
62
58
|
extraArgs: [],
|
|
63
59
|
serverEnv: {},
|
|
64
60
|
needsMitm: true,
|
|
@@ -90,10 +86,7 @@ const TOOL_CONFIG = {
|
|
|
90
86
|
// and cannot be redirected via base URL env vars alone when using multiple
|
|
91
87
|
// providers simultaneously. We use mitmproxy as a forward HTTPS proxy so
|
|
92
88
|
// all provider traffic is captured regardless of which model is active.
|
|
93
|
-
childEnv: {
|
|
94
|
-
https_proxy: MITM_PROXY_URL,
|
|
95
|
-
SSL_CERT_FILE: "", // filled in by cli.ts with mitmproxy CA cert path
|
|
96
|
-
},
|
|
89
|
+
childEnv: {},
|
|
97
90
|
extraArgs: [],
|
|
98
91
|
serverEnv: {},
|
|
99
92
|
needsMitm: true,
|
|
@@ -329,10 +322,10 @@ export function formatHelpText() {
|
|
|
329
322
|
" -h, --help Show this help text",
|
|
330
323
|
" -v, --version Show version",
|
|
331
324
|
" --privacy <level> Set privacy level: minimal|standard|full",
|
|
332
|
-
|
|
325
|
+
` --no-open Don't auto-open ${UI_URL}`,
|
|
333
326
|
" --no-ui Run proxy only (no analysis/web UI server)",
|
|
334
327
|
" --no-update-check Skip npm update check for this run",
|
|
335
|
-
" --mitm Use mitmproxy for interception instead of base URL override (
|
|
328
|
+
" --mitm Use mitmproxy for interception instead of base URL override (only recommend forcing for Pi)",
|
|
336
329
|
" --redact[=preset] Strip sensitive data before capture (experimental). Preset: secrets|pii|strict (default: secrets)",
|
|
337
330
|
" --rehydrate With --redact: restore original values in responses (off by default)",
|
|
338
331
|
"",
|
|
@@ -372,13 +365,23 @@ export function formatHelpText() {
|
|
|
372
365
|
// Exported for tests (and to keep cli.ts smaller).
|
|
373
366
|
export const CLI_CONSTANTS = {
|
|
374
367
|
PROXY_URL,
|
|
375
|
-
|
|
376
|
-
|
|
368
|
+
PROXY_PORT,
|
|
369
|
+
UI_PORT,
|
|
370
|
+
UI_URL,
|
|
377
371
|
PI_AGENT_DIR_PREFIX,
|
|
378
372
|
BRYTI_DATA_DIR_PREFIX,
|
|
379
373
|
COMMAND_ALIASES,
|
|
380
374
|
KNOWN_PRIVACY_LEVELS,
|
|
381
|
-
// Resolved relative to compiled output (dist/ or dist-test/), matching cli.ts behavior.
|
|
382
|
-
MITM_ADDON_PATH: join(__dirname, "..", "mitm_addon.py"),
|
|
383
375
|
};
|
|
376
|
+
export function getMitmConfig() {
|
|
377
|
+
const port = Number.isNaN(config.mitm.port) ? 8080 : config.mitm.port;
|
|
378
|
+
return {
|
|
379
|
+
port,
|
|
380
|
+
proxyUrl: `http://localhost:${port}`,
|
|
381
|
+
extraArgs: config.mitm.extraArgs,
|
|
382
|
+
addonPath: join(__dirname, "..", "mitm_addon.py"),
|
|
383
|
+
lensSource: config.mitm.lensSource,
|
|
384
|
+
lensSessionId: config.mitm.lensSessionId,
|
|
385
|
+
};
|
|
386
|
+
}
|
|
384
387
|
//# sourceMappingURL=cli-utils.js.map
|
package/dist/cli-utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-utils.js","sourceRoot":"","sources":["../src/cli-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"cli-utils.js","sourceRoot":"","sources":["../src/cli-utils.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -8,13 +8,27 @@ import net from "node:net";
|
|
|
8
8
|
import { homedir, platform, tmpdir } from "node:os";
|
|
9
9
|
import { dirname, isAbsolute, join, resolve } from "node:path";
|
|
10
10
|
import { fileURLToPath } from "node:url";
|
|
11
|
-
import { CLI_CONSTANTS, formatHelpText, getToolConfig, parseCliArgs, } from "./cli-utils.js";
|
|
11
|
+
import { CLI_CONSTANTS, formatHelpText, getMitmConfig, getToolConfig, parseCliArgs, } from "./cli-utils.js";
|
|
12
12
|
import { loadConfig } from "./config.js";
|
|
13
13
|
import { VERSION } from "./version.generated.js";
|
|
14
14
|
const __filename = fileURLToPath(import.meta.url);
|
|
15
15
|
const __dirname = dirname(__filename);
|
|
16
16
|
// Known tool config: env vars for the child process, extra CLI args, server env vars, and whether mitmproxy is needed
|
|
17
17
|
// Note: actual tool config lives in cli-utils.ts so it can be unit-tested without importing this entrypoint.
|
|
18
|
+
function resolveLensSource(setting, commandName) {
|
|
19
|
+
if (setting === "commandName")
|
|
20
|
+
return commandName;
|
|
21
|
+
if (setting === "auto")
|
|
22
|
+
return "";
|
|
23
|
+
return setting; // fixed string
|
|
24
|
+
}
|
|
25
|
+
function resolveLensSessionId(setting) {
|
|
26
|
+
if (setting === "random")
|
|
27
|
+
return randomBytes(4).toString("hex");
|
|
28
|
+
if (setting === "none")
|
|
29
|
+
return "";
|
|
30
|
+
return setting; // fixed string
|
|
31
|
+
}
|
|
18
32
|
const LOCKFILE = "/tmp/context-lens.lock";
|
|
19
33
|
const rawArgs = process.argv.slice(2);
|
|
20
34
|
const parsedArgs = parseCliArgs(rawArgs);
|
|
@@ -32,17 +46,24 @@ if (parsedArgs.showVersion) {
|
|
|
32
46
|
}
|
|
33
47
|
// Load user config ā CLI flags take precedence over config file values
|
|
34
48
|
const userConfig = loadConfig();
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
49
|
+
const envKeyToValue = {
|
|
50
|
+
CONTEXT_LENS_PROXY_PORT: String(CLI_CONSTANTS.PROXY_PORT),
|
|
51
|
+
CONTEXT_LENS_ANALYSIS_PORT: String(CLI_CONSTANTS.UI_PORT),
|
|
52
|
+
CONTEXT_LENS_ANALYSIS_URL: CLI_CONSTANTS.UI_URL,
|
|
53
|
+
CONTEXT_LENS_INGEST_URL: CLI_CONSTANTS.UI_URL + "/api/ingest",
|
|
54
|
+
};
|
|
55
|
+
for (const [key, value] of Object.entries(envKeyToValue)) {
|
|
56
|
+
if (!process.env[key])
|
|
57
|
+
process.env[key] = value;
|
|
42
58
|
}
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
59
|
+
const envOverrides = {
|
|
60
|
+
CONTEXT_LENS_PRIVACY: parsedArgs.privacyLevel ?? userConfig.privacy.level,
|
|
61
|
+
CONTEXT_LENS_REDACT: parsedArgs.redactPreset ?? userConfig.proxy.redact,
|
|
62
|
+
CONTEXT_LENS_REHYDRATE: (parsedArgs.rehydrate ?? userConfig.proxy.rehydrate) ? "1" : undefined,
|
|
63
|
+
};
|
|
64
|
+
for (const [key, value] of Object.entries(envOverrides)) {
|
|
65
|
+
if (value !== undefined)
|
|
66
|
+
process.env[key] = value;
|
|
46
67
|
}
|
|
47
68
|
if (!parsedArgs.noUpdateCheck &&
|
|
48
69
|
process.env.CONTEXT_LENS_NO_UPDATE_CHECK !== "1") {
|
|
@@ -60,7 +81,15 @@ else if (parsedArgs.commandName === "stop") {
|
|
|
60
81
|
else if (parsedArgs.commandName === "background") {
|
|
61
82
|
void runBackgroundCommand(parsedArgs.commandArguments, parsedArgs.noUi).then((exitCode) => process.exit(exitCode));
|
|
62
83
|
}
|
|
63
|
-
else if (!parsedArgs.commandName) {
|
|
84
|
+
else if (!parsedArgs.commandName && !parsedArgs.useMitm) {
|
|
85
|
+
// Warn if PI_CODING_AGENT_DIR is set in the environment but no command was
|
|
86
|
+
// given. The user likely expected this to launch pi ā point them to the
|
|
87
|
+
// correct invocation before dropping into standalone mode.
|
|
88
|
+
if (process.env.PI_CODING_AGENT_DIR) {
|
|
89
|
+
console.error("Warning: PI_CODING_AGENT_DIR is set but no command was given.");
|
|
90
|
+
console.error("To capture pi traffic, run: context-lens pi [pi-args...]");
|
|
91
|
+
console.error("Starting standalone mode (proxy + analysis server) instead.");
|
|
92
|
+
}
|
|
64
93
|
if (parsedArgs.noUi) {
|
|
65
94
|
// Standalone mode (no UI): start proxy only
|
|
66
95
|
const proxyPath = join(__dirname, "proxy", "server.js");
|
|
@@ -86,7 +115,7 @@ else if (!parsedArgs.commandName) {
|
|
|
86
115
|
stdio: "inherit",
|
|
87
116
|
env: {
|
|
88
117
|
...process.env,
|
|
89
|
-
CONTEXT_LENS_ANALYSIS_URL:
|
|
118
|
+
CONTEXT_LENS_ANALYSIS_URL: CLI_CONSTANTS.UI_URL,
|
|
90
119
|
},
|
|
91
120
|
});
|
|
92
121
|
const analysis = spawn("node", [analysisPath], {
|
|
@@ -109,31 +138,38 @@ else if (!parsedArgs.commandName) {
|
|
|
109
138
|
}
|
|
110
139
|
}
|
|
111
140
|
else {
|
|
112
|
-
const commandName = parsedArgs.commandName;
|
|
141
|
+
const commandName = parsedArgs.commandName ?? "";
|
|
113
142
|
const commandArguments = parsedArgs.commandArguments;
|
|
114
143
|
const noOpen = parsedArgs.noOpen || userConfig.ui.noOpen;
|
|
115
144
|
const noUi = parsedArgs.noUi;
|
|
116
145
|
const useMitm = parsedArgs.useMitm;
|
|
117
|
-
|
|
146
|
+
const mitmConfig = getMitmConfig();
|
|
118
147
|
let toolConfig = getToolConfig(commandName);
|
|
119
|
-
if (useMitm
|
|
148
|
+
if (useMitm || toolConfig.needsMitm) {
|
|
149
|
+
// if mitm is specified on the CLI or the tool always requires mitm we replace the normal reverse_proxy/forced provider urls with forward proxy redirection.
|
|
120
150
|
toolConfig = {
|
|
121
151
|
...toolConfig,
|
|
122
152
|
childEnv: {
|
|
123
|
-
https_proxy:
|
|
124
|
-
|
|
153
|
+
https_proxy: mitmConfig.proxyUrl,
|
|
154
|
+
NPM_CONFIG_HTTPS_PROXY: mitmConfig.proxyUrl,
|
|
155
|
+
WSS_PROXY: mitmConfig.proxyUrl,
|
|
156
|
+
NODE_USE_ENV_PROXY: "1",
|
|
157
|
+
//these are all filled in with the CA cert path
|
|
158
|
+
SSL_CERT_FILE: "[CA_CERT_PATH]",
|
|
159
|
+
NODE_EXTRA_CA_CERTS: "[CA_CERT_PATH]",
|
|
160
|
+
REQUESTS_CA_BUNDLE: "[CA_CERT_PATH]",
|
|
125
161
|
},
|
|
126
162
|
needsMitm: true,
|
|
127
163
|
};
|
|
128
164
|
}
|
|
129
165
|
if (noUi && toolConfig.needsMitm) {
|
|
130
|
-
console.error(
|
|
166
|
+
console.error(`Error: --no-ui is not supported for this command because mitm capture requires the analysis ingest API on :${CLI_CONSTANTS.UI_PORT}.`);
|
|
131
167
|
process.exit(1);
|
|
132
168
|
}
|
|
133
169
|
// Check if proxy is already running
|
|
134
170
|
function isProxyRunning() {
|
|
135
171
|
return new Promise((resolve) => {
|
|
136
|
-
const socket = net.connect({ port:
|
|
172
|
+
const socket = net.connect({ port: CLI_CONSTANTS.PROXY_PORT, host: "localhost" }, () => {
|
|
137
173
|
socket.end();
|
|
138
174
|
resolve(true);
|
|
139
175
|
});
|
|
@@ -210,7 +246,7 @@ else {
|
|
|
210
246
|
// Check if analysis server is already running
|
|
211
247
|
function isAnalysisRunning() {
|
|
212
248
|
return new Promise((resolve) => {
|
|
213
|
-
const socket = net.connect({ port:
|
|
249
|
+
const socket = net.connect({ port: CLI_CONSTANTS.UI_PORT, host: "localhost" }, () => {
|
|
214
250
|
socket.end();
|
|
215
251
|
resolve(true);
|
|
216
252
|
});
|
|
@@ -247,7 +283,7 @@ else {
|
|
|
247
283
|
...toolConfig.serverEnv,
|
|
248
284
|
...process.env,
|
|
249
285
|
CONTEXT_LENS_CLI: "1",
|
|
250
|
-
CONTEXT_LENS_ANALYSIS_URL:
|
|
286
|
+
CONTEXT_LENS_ANALYSIS_URL: CLI_CONSTANTS.UI_URL,
|
|
251
287
|
};
|
|
252
288
|
// Start proxy
|
|
253
289
|
if (proxyAlreadyRunning) {
|
|
@@ -332,7 +368,7 @@ else {
|
|
|
332
368
|
// Open browser after a short delay (only when starting new servers)
|
|
333
369
|
if (!noOpen && requiresAnalysis) {
|
|
334
370
|
setTimeout(() => {
|
|
335
|
-
openBrowser(
|
|
371
|
+
openBrowser(CLI_CONSTANTS.UI_URL);
|
|
336
372
|
}, 1000);
|
|
337
373
|
}
|
|
338
374
|
// If both were already ready (mixed scenario), check now
|
|
@@ -345,22 +381,49 @@ else {
|
|
|
345
381
|
startChild();
|
|
346
382
|
return;
|
|
347
383
|
}
|
|
348
|
-
|
|
384
|
+
// Pre-flight: check if the mitm port is already in use.
|
|
385
|
+
// Without this, mitmproxy exits silently and the poll loop connects
|
|
386
|
+
// to whatever is already on that port, falsely reporting success.
|
|
387
|
+
const probe = net.connect({ port: mitmConfig.port, host: "localhost" }, () => {
|
|
388
|
+
probe.end();
|
|
389
|
+
console.error(`\nError: port ${mitmConfig.port} is already in use (mitmproxy cannot bind).`);
|
|
390
|
+
console.error(`Set a different port in ~/.context-lens/config.toml:\n\n [mitm]\n port = 8082\n`);
|
|
391
|
+
cleanup(1);
|
|
392
|
+
});
|
|
393
|
+
probe.on("error", () => {
|
|
394
|
+
// Port is free, proceed
|
|
395
|
+
startMitm();
|
|
396
|
+
});
|
|
397
|
+
probe.setTimeout(500, () => {
|
|
398
|
+
probe.destroy();
|
|
399
|
+
startMitm();
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
function startMitm() {
|
|
403
|
+
const addonPath = mitmConfig.addonPath;
|
|
349
404
|
console.log("š Starting mitmproxy (forward proxy for HTTPS interception)...");
|
|
350
405
|
mitmProcess = spawn("mitmdump", [
|
|
351
406
|
"-s",
|
|
352
407
|
addonPath,
|
|
353
408
|
"--quiet",
|
|
354
409
|
"--listen-port",
|
|
355
|
-
String(
|
|
410
|
+
String(mitmConfig.port),
|
|
411
|
+
...mitmConfig.extraArgs,
|
|
356
412
|
], {
|
|
357
413
|
stdio: ["ignore", "pipe", "pipe"],
|
|
358
414
|
env: {
|
|
359
415
|
...process.env,
|
|
360
|
-
CONTEXT_LENS_SOURCE: commandName,
|
|
361
|
-
CONTEXT_LENS_SESSION_ID:
|
|
416
|
+
CONTEXT_LENS_SOURCE: resolveLensSource(mitmConfig.lensSource, commandName),
|
|
417
|
+
CONTEXT_LENS_SESSION_ID: resolveLensSessionId(mitmConfig.lensSessionId),
|
|
362
418
|
},
|
|
363
419
|
});
|
|
420
|
+
// Capture stderr so binding errors ("address already in use") are visible.
|
|
421
|
+
let mitmStderr = "";
|
|
422
|
+
if (mitmProcess.stderr) {
|
|
423
|
+
mitmProcess.stderr.on("data", (chunk) => {
|
|
424
|
+
mitmStderr += chunk.toString();
|
|
425
|
+
});
|
|
426
|
+
}
|
|
364
427
|
mitmProcess.on("error", (err) => {
|
|
365
428
|
console.error("Failed to start mitmproxy:", err.message);
|
|
366
429
|
console.error("Install it: pipx install mitmproxy");
|
|
@@ -368,18 +431,24 @@ else {
|
|
|
368
431
|
});
|
|
369
432
|
mitmProcess.on("exit", (code) => {
|
|
370
433
|
if (!mitmReady) {
|
|
371
|
-
|
|
434
|
+
const detail = mitmStderr.trim();
|
|
435
|
+
if (detail) {
|
|
436
|
+
console.error(`mitmproxy failed to start:\n${detail}`);
|
|
437
|
+
}
|
|
438
|
+
else {
|
|
439
|
+
console.error("mitmproxy exited unexpectedly");
|
|
440
|
+
}
|
|
372
441
|
cleanup(code || 1);
|
|
373
442
|
}
|
|
374
443
|
});
|
|
375
444
|
// Poll until mitmproxy is accepting connections
|
|
376
445
|
const pollMitm = setInterval(() => {
|
|
377
|
-
const socket = net.connect({ port:
|
|
446
|
+
const socket = net.connect({ port: mitmConfig.port, host: "localhost" }, () => {
|
|
378
447
|
socket.end();
|
|
379
448
|
if (!mitmReady) {
|
|
380
449
|
mitmReady = true;
|
|
381
450
|
clearInterval(pollMitm);
|
|
382
|
-
console.log(`š mitmproxy listening on port ${
|
|
451
|
+
console.log(`š mitmproxy listening on port ${mitmConfig.port}`);
|
|
383
452
|
startChild();
|
|
384
453
|
}
|
|
385
454
|
});
|
|
@@ -391,7 +460,9 @@ else {
|
|
|
391
460
|
function startChild() {
|
|
392
461
|
// Inject extra args (e.g. codex -c chatgpt_base_url=...) before user args
|
|
393
462
|
const allArgs = [...toolConfig.extraArgs, ...commandArguments];
|
|
394
|
-
|
|
463
|
+
if (commandName) {
|
|
464
|
+
console.log(`\nš Launching: ${commandName} ${allArgs.join(" ")}\n`);
|
|
465
|
+
}
|
|
395
466
|
const childEnv = {
|
|
396
467
|
...process.env,
|
|
397
468
|
...toolConfig.childEnv,
|
|
@@ -421,7 +492,7 @@ else {
|
|
|
421
492
|
if (typeof val !== "string")
|
|
422
493
|
continue;
|
|
423
494
|
// Match any value that points at our proxy and ends with /<source> or /<source>/
|
|
424
|
-
const proxyBase =
|
|
495
|
+
const proxyBase = `${CLI_CONSTANTS.PROXY_URL}/`;
|
|
425
496
|
if (!val.startsWith(proxyBase))
|
|
426
497
|
continue;
|
|
427
498
|
const hadTrailingSlash = val.endsWith("/");
|
|
@@ -434,15 +505,14 @@ else {
|
|
|
434
505
|
}
|
|
435
506
|
}
|
|
436
507
|
// Fill in mitmproxy CA cert path for tools that need HTTPS interception.
|
|
437
|
-
//
|
|
438
|
-
// NODE_EXTRA_CA_CERTS is used by Node.js processes (e.g. Cline).
|
|
508
|
+
// Any childEnv value set to "[CA_CERT_PATH]" is replaced with the actual path.
|
|
439
509
|
if (toolConfig.needsMitm) {
|
|
440
510
|
const certPath = join(homedir(), ".mitmproxy", "mitmproxy-ca-cert.pem");
|
|
441
511
|
if (fs.existsSync(certPath)) {
|
|
442
|
-
|
|
443
|
-
childEnv
|
|
444
|
-
|
|
445
|
-
|
|
512
|
+
for (const key of Object.keys(childEnv)) {
|
|
513
|
+
if (childEnv[key] === "[CA_CERT_PATH]")
|
|
514
|
+
childEnv[key] = certPath;
|
|
515
|
+
}
|
|
446
516
|
// On macOS, Codex is compiled with rustls + native-roots, which reads
|
|
447
517
|
// the system Keychain and ignores SSL_CERT_FILE entirely. If the cert
|
|
448
518
|
// is not trusted in the Keychain, Codex cannot connect through mitmproxy.
|
|
@@ -457,6 +527,13 @@ else {
|
|
|
457
527
|
if (commandName === "pi" && !useMitm) {
|
|
458
528
|
childEnv.PI_CODING_AGENT_DIR = preparePiAgentDir(childEnv.PI_CODING_AGENT_DIR, sessionTag);
|
|
459
529
|
}
|
|
530
|
+
if (!commandName) {
|
|
531
|
+
//we only get here when the user wants mitm but didn't specify a command
|
|
532
|
+
console.log("Press Ctrl+C to stop.");
|
|
533
|
+
process.on("SIGINT", () => cleanup(0));
|
|
534
|
+
process.on("SIGTERM", () => cleanup(0));
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
460
537
|
// For bryti: if dist/cli.js exists in cwd, use it directly (dev mode).
|
|
461
538
|
// Otherwise fall back to the globally installed bryti binary.
|
|
462
539
|
let spawnCommand = commandName;
|
|
@@ -475,8 +552,14 @@ else {
|
|
|
475
552
|
childProcess.on("error", (err) => {
|
|
476
553
|
if (err.code === "ENOENT") {
|
|
477
554
|
console.error(`\nFailed to start '${commandName}': command not found.`);
|
|
478
|
-
|
|
479
|
-
|
|
555
|
+
if (commandName === "pi") {
|
|
556
|
+
console.error("Install pi: npm install -g @mariozechner/pi-coding-agent");
|
|
557
|
+
console.error("Or run from its directory: context-lens -- node dist/cli.js");
|
|
558
|
+
}
|
|
559
|
+
else {
|
|
560
|
+
console.error("Try a known tool (claude, codex, gemini, aider, pi) or use:");
|
|
561
|
+
console.error(" context-lens -- <your-command> [args...]");
|
|
562
|
+
}
|
|
480
563
|
cleanup(127);
|
|
481
564
|
return;
|
|
482
565
|
}
|
|
@@ -493,7 +576,7 @@ else {
|
|
|
493
576
|
setTimeout(() => {
|
|
494
577
|
if (cleanupDidRun)
|
|
495
578
|
return;
|
|
496
|
-
const req = http.get(
|
|
579
|
+
const req = http.get(`${CLI_CONSTANTS.UI_URL}/api/requests?summary=true`, { timeout: 2000 }, (res) => {
|
|
497
580
|
let body = "";
|
|
498
581
|
res.setEncoding("utf8");
|
|
499
582
|
res.on("data", (chunk) => {
|
|
@@ -506,10 +589,10 @@ else {
|
|
|
506
589
|
data.conversations.length === 0) {
|
|
507
590
|
console.error("\nā ļø No API traffic captured yet. If the tool is running, it may not be routing through the proxy.");
|
|
508
591
|
if (toolConfig.needsMitm) {
|
|
509
|
-
console.error(` Check that ${commandName} is routing through mitmproxy (https_proxy
|
|
592
|
+
console.error(` Check that ${commandName} is routing through mitmproxy (https_proxy=${mitmConfig.proxyUrl}).\n`);
|
|
510
593
|
}
|
|
511
594
|
else {
|
|
512
|
-
console.error(` Check that ${commandName} is using the proxy URL (
|
|
595
|
+
console.error(` Check that ${commandName} is using the proxy URL (${CLI_CONSTANTS.PROXY_URL}).\n`);
|
|
513
596
|
}
|
|
514
597
|
}
|
|
515
598
|
}
|
|
@@ -1036,7 +1119,7 @@ async function backgroundStart(noUi) {
|
|
|
1036
1119
|
const proxyEnv = {
|
|
1037
1120
|
...process.env,
|
|
1038
1121
|
CONTEXT_LENS_CLI: "1",
|
|
1039
|
-
...(noUi ? {} : { CONTEXT_LENS_ANALYSIS_URL:
|
|
1122
|
+
...(noUi ? {} : { CONTEXT_LENS_ANALYSIS_URL: CLI_CONSTANTS.UI_URL }),
|
|
1040
1123
|
};
|
|
1041
1124
|
const proxy = spawn("node", [proxyPath], {
|
|
1042
1125
|
stdio: "ignore",
|
|
@@ -1077,9 +1160,9 @@ async function backgroundStart(noUi) {
|
|
|
1077
1160
|
startedAt: new Date().toISOString(),
|
|
1078
1161
|
});
|
|
1079
1162
|
console.log("Background services started.");
|
|
1080
|
-
console.log(` proxy:
|
|
1163
|
+
console.log(` proxy: ${CLI_CONSTANTS.PROXY_URL} (pid ${proxyPid})`);
|
|
1081
1164
|
if (analysisPid != null) {
|
|
1082
|
-
console.log(` analysis/web UI:
|
|
1165
|
+
console.log(` analysis/web UI: ${CLI_CONSTANTS.UI_URL} (pid ${analysisPid})`);
|
|
1083
1166
|
}
|
|
1084
1167
|
else {
|
|
1085
1168
|
console.log(" analysis/web UI: disabled (--no-ui)");
|
|
@@ -1222,10 +1305,10 @@ async function runDoctor() {
|
|
|
1222
1305
|
}
|
|
1223
1306
|
console.log(`Context Lens doctor v${VERSION}`);
|
|
1224
1307
|
report("node", true, process.version);
|
|
1225
|
-
const proxyListening = await isPortListening(
|
|
1226
|
-
report(
|
|
1227
|
-
const analysisListening = await isPortListening(
|
|
1228
|
-
report(
|
|
1308
|
+
const proxyListening = await isPortListening(CLI_CONSTANTS.PROXY_PORT);
|
|
1309
|
+
report(`proxy port :${CLI_CONSTANTS.PROXY_PORT}`, true, proxyListening ? "already running" : "available/not running");
|
|
1310
|
+
const analysisListening = await isPortListening(CLI_CONSTANTS.UI_PORT);
|
|
1311
|
+
report(`analysis port :${CLI_CONSTANTS.UI_PORT}`, true, analysisListening ? "already running" : "available/not running");
|
|
1229
1312
|
// mitmproxy is only needed for Codex subscription mode, so report as
|
|
1230
1313
|
// informational rather than a hard failure.
|
|
1231
1314
|
const mitmdumpPath = findBinaryOnPath("mitmdump");
|