pi-lean-ctx 3.6.0 → 3.6.1
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/README.md +13 -2
- package/extensions/index.ts +30 -13
- package/extensions/mcp-bridge.ts +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -2,14 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
[Pi Coding Agent](https://github.com/badlogic/pi-mono) extension that provides `ctx_`-prefixed tools backed by [lean-ctx](https://leanctx.com) for **60–90% token savings**.
|
|
4
4
|
|
|
5
|
-
- **Default**: CLI-only (no MCP required)
|
|
5
|
+
- **Default**: CLI-only, additive mode (no MCP required, Pi builtins preserved)
|
|
6
6
|
- **Optional**: enable MCP tools (`LEAN_CTX_PI_ENABLE_MCP=1`) or run `lean-ctx init --agent pi --mode mcp`
|
|
7
|
+
- **Optional**: replace mode (`LEAN_CTX_PI_MODE=replace`) disables Pi builtins
|
|
8
|
+
|
|
9
|
+
## Tool Mode
|
|
10
|
+
|
|
11
|
+
By default, pi-lean-ctx runs in **additive mode**: Pi's built-in tools (`read`, `bash`, `ls`, `find`, `grep`) remain available alongside the `ctx_*` tools. Agents can use either set.
|
|
12
|
+
|
|
13
|
+
To switch to **replace mode** (disables Pi builtins, only `ctx_*` tools available):
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
export LEAN_CTX_PI_MODE=replace
|
|
17
|
+
```
|
|
7
18
|
|
|
8
19
|
## What it does
|
|
9
20
|
|
|
10
21
|
### ctx_ Tools (CLI-backed)
|
|
11
22
|
|
|
12
|
-
|
|
23
|
+
Adds `ctx_`-prefixed tools alongside Pi's builtins (or replaces them in `replace` mode):
|
|
13
24
|
|
|
14
25
|
| Tool | Replaces | Compression |
|
|
15
26
|
|------|----------|-------------|
|
package/extensions/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ExtensionAPI } from "@
|
|
1
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import {
|
|
3
3
|
createBashToolDefinition,
|
|
4
4
|
createReadToolDefinition,
|
|
@@ -6,8 +6,8 @@ import {
|
|
|
6
6
|
getLanguageFromPath,
|
|
7
7
|
highlightCode,
|
|
8
8
|
truncateHead,
|
|
9
|
-
} from "@
|
|
10
|
-
import { Text } from "@
|
|
9
|
+
} from "@earendil-works/pi-coding-agent";
|
|
10
|
+
import { Text } from "@earendil-works/pi-tui";
|
|
11
11
|
import { Type } from "@sinclair/typebox";
|
|
12
12
|
import { existsSync, readFileSync } from "node:fs";
|
|
13
13
|
import { readFile, stat } from "node:fs/promises";
|
|
@@ -35,8 +35,12 @@ const IMAGE_EXTENSIONS = new Set([".png", ".jpg", ".jpeg", ".gif", ".webp"]);
|
|
|
35
35
|
const CODE_FULL_READ_MAX_BYTES = 8 * 1024;
|
|
36
36
|
const CODE_SIGNATURES_MIN_BYTES = 96 * 1024;
|
|
37
37
|
|
|
38
|
-
// Pi builtins
|
|
38
|
+
// Pi builtins that can be replaced with ctx_ prefixed versions.
|
|
39
|
+
// LEAN_CTX_PI_MODE controls behavior:
|
|
40
|
+
// "additive" (default) — keep Pi builtins, add ctx_* alongside
|
|
41
|
+
// "replace" — disable Pi builtins, only expose ctx_*
|
|
39
42
|
const DISABLED_BUILTIN_TOOLS = new Set(["read", "bash", "ls", "find", "grep"]);
|
|
43
|
+
const PI_MODE = (process.env.LEAN_CTX_PI_MODE || "additive").toLowerCase();
|
|
40
44
|
// Max bytes constant for truncation warnings (same as Pi's DEFAULT_MAX_BYTES)
|
|
41
45
|
const DEFAULT_MAX_BYTES = 8192;
|
|
42
46
|
|
|
@@ -278,7 +282,7 @@ function isMcpAdapterConfigured(): boolean {
|
|
|
278
282
|
|
|
279
283
|
async function execLeanCtx(pi: ExtensionAPI, args: string[]) {
|
|
280
284
|
const bin = resolveBinary();
|
|
281
|
-
const result = await pi.exec(bin, args, { env: { ...process.env, LEAN_CTX_COMPRESS: "1" } });
|
|
285
|
+
const result = await pi.exec(bin, args, { env: { ...process.env, LEAN_CTX_COMPRESS: "1", LEAN_CTX_SAVINGS_FOOTER: "always" } });
|
|
282
286
|
if (result.code !== 0) {
|
|
283
287
|
const msg = (result.stderr || result.stdout || `lean-ctx failed: ${args.join(" ")}`).trim();
|
|
284
288
|
throw new Error(msg);
|
|
@@ -288,19 +292,22 @@ async function execLeanCtx(pi: ExtensionAPI, args: string[]) {
|
|
|
288
292
|
|
|
289
293
|
export default async function (pi: ExtensionAPI) {
|
|
290
294
|
// Defer setActiveTools to session_start — runtime actions aren't available during extension load
|
|
291
|
-
//
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
pi.
|
|
295
|
-
|
|
295
|
+
// In "replace" mode, disable Pi builtins and only expose ctx_* tools.
|
|
296
|
+
// In "additive" mode (default), keep Pi builtins alongside ctx_* tools.
|
|
297
|
+
if (PI_MODE === "replace") {
|
|
298
|
+
pi.on("session_start", () => {
|
|
299
|
+
const activeTools = pi.getActiveTools().filter((name) => !DISABLED_BUILTIN_TOOLS.has(name));
|
|
300
|
+
pi.setActiveTools(activeTools);
|
|
301
|
+
});
|
|
302
|
+
}
|
|
296
303
|
|
|
297
304
|
const baseBashTool = createBashToolDefinition(process.cwd(), {
|
|
298
305
|
spawnHook: ({ command, cwd, env }) => {
|
|
299
306
|
const bin = resolveBinary();
|
|
300
307
|
return {
|
|
301
|
-
command: `${shellQuote(bin)} -c
|
|
308
|
+
command: `${shellQuote(bin)} -c ${shellQuote(command)}`,
|
|
302
309
|
cwd,
|
|
303
|
-
env: { ...env, LEAN_CTX_COMPRESS: "1" },
|
|
310
|
+
env: { ...env, LEAN_CTX_COMPRESS: "1", LEAN_CTX_SAVINGS_FOOTER: "always" },
|
|
304
311
|
};
|
|
305
312
|
},
|
|
306
313
|
});
|
|
@@ -328,6 +335,16 @@ export default async function (pi: ExtensionAPI) {
|
|
|
328
335
|
"Use ctx_shell only for commands with side effects: build, test, install, git, run scripts.",
|
|
329
336
|
],
|
|
330
337
|
parameters: bashSchemaWithRaw,
|
|
338
|
+
renderCall(args, theme, context) {
|
|
339
|
+
return baseBashTool.renderCall
|
|
340
|
+
? baseBashTool.renderCall(args, theme, context)
|
|
341
|
+
: (context.lastComponent ?? new Text("", 0, 0));
|
|
342
|
+
},
|
|
343
|
+
renderResult(result, options, theme, context) {
|
|
344
|
+
return baseBashTool.renderResult
|
|
345
|
+
? baseBashTool.renderResult(result, options, theme, context)
|
|
346
|
+
: (context.lastComponent ?? new Text("", 0, 0));
|
|
347
|
+
},
|
|
331
348
|
async execute(toolCallId, params, signal, onUpdate, ctx) {
|
|
332
349
|
const isRaw = !!params.raw;
|
|
333
350
|
const toolParams = { command: params.command, timeout: params.timeout };
|
|
@@ -525,7 +542,7 @@ export default async function (pi: ExtensionAPI) {
|
|
|
525
542
|
searchArgs.push(params.pattern, absolutePath);
|
|
526
543
|
|
|
527
544
|
const bin = resolveBinary();
|
|
528
|
-
const result = await pi.exec(bin, ["-c", ...searchArgs], { env: { ...process.env, LEAN_CTX_COMPRESS: "1" } });
|
|
545
|
+
const result = await pi.exec(bin, ["-c", ...searchArgs], { env: { ...process.env, LEAN_CTX_COMPRESS: "1", LEAN_CTX_SAVINGS_FOOTER: "always" } });
|
|
529
546
|
if (result.code >= 2) {
|
|
530
547
|
const msg = (result.stderr || result.stdout || `lean-ctx grep failed: ${params.pattern}`).trim();
|
|
531
548
|
throw new Error(msg);
|
package/extensions/mcp-bridge.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
2
2
|
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
3
|
-
import type { ExtensionAPI } from "@
|
|
3
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
4
4
|
import { Type } from "@sinclair/typebox";
|
|
5
5
|
import type { McpBridgeRetryState, McpBridgeStatus } from "./types.js";
|
|
6
6
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-lean-ctx",
|
|
3
|
-
"version": "3.6.
|
|
3
|
+
"version": "3.6.1",
|
|
4
4
|
"description": "Pi Coding Agent extension (CLI-first) — routes bash/read/grep/find/ls through lean-ctx CLI for strong token savings. Optional MCP bridge can register advanced tools.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"@modelcontextprotocol/sdk": "^1.29.0"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
|
-
"@
|
|
29
|
-
"@
|
|
28
|
+
"@earendil-works/pi-coding-agent": ">=0.50.0",
|
|
29
|
+
"@earendil-works/pi-tui": "*"
|
|
30
30
|
},
|
|
31
31
|
"pi": {
|
|
32
32
|
"extensions": [
|