surgent 0.7.1-alpha.0 → 0.10.7

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.
Files changed (111) hide show
  1. package/README.md +2 -2
  2. package/bin/build.mjs +53 -0
  3. package/bin/surgent.js +15 -13
  4. package/dist/optimizer/README.md +12 -4
  5. package/dist/optimizer/index.js +1361 -891
  6. package/dist/optimizer/index.js.map +4 -4
  7. package/dist/optimizer/package.json +2 -2
  8. package/package.json +14 -13
  9. package/src/agent/built-in/documenter.md +58 -55
  10. package/src/agent/built-in/general.md +71 -71
  11. package/src/agent/built-in/planner.md +63 -52
  12. package/src/agent/built-in/scout.md +41 -77
  13. package/src/agent/command.ts +76 -44
  14. package/src/agent/config.ts +167 -0
  15. package/src/agent/helpers.ts +44 -39
  16. package/src/agent/index.ts +85 -2
  17. package/src/agent/storage.ts +98 -190
  18. package/src/agent/types.ts +6 -0
  19. package/src/checkpoint/git.ts +12 -8
  20. package/src/checkpoint/index.ts +88 -21
  21. package/src/checkpoint/snapshot.ts +1 -1
  22. package/src/checkpoint/stage.ts +4 -2
  23. package/src/checkpoint/store.ts +6 -13
  24. package/src/cleanup/index.ts +1 -3
  25. package/src/commands/helpers.ts +30 -27
  26. package/src/commands/index.ts +4 -3
  27. package/src/commands/render.ts +14 -15
  28. package/src/optimizer/README.md +12 -4
  29. package/src/optimizer/deduplicator/index.ts +23 -13
  30. package/src/optimizer/deduplicator/resources.ts +35 -63
  31. package/src/optimizer/deduplicator/state.ts +48 -106
  32. package/src/optimizer/entries.ts +20 -99
  33. package/src/optimizer/index.ts +6 -7
  34. package/src/optimizer/inspector/helpers.ts +1 -19
  35. package/src/optimizer/inspector/index.ts +6 -7
  36. package/src/optimizer/inspector/inspect.ts +3 -14
  37. package/src/optimizer/languages/symbols.ts +2 -10
  38. package/src/optimizer/languages/types.ts +0 -4
  39. package/src/optimizer/languages/typescript.ts +6 -0
  40. package/src/optimizer/mapper/files.ts +60 -67
  41. package/src/optimizer/mapper/index.ts +91 -99
  42. package/src/optimizer/pruner/cleanup.ts +0 -89
  43. package/src/optimizer/pruner/index.ts +42 -33
  44. package/src/optimizer/reducer/bash.ts +100 -0
  45. package/src/optimizer/reducer/grep.ts +104 -0
  46. package/src/optimizer/reducer/index.ts +81 -0
  47. package/src/permission/command.ts +2 -20
  48. package/src/permission/components/prompt.ts +18 -21
  49. package/src/permission/components/rules-list.ts +8 -15
  50. package/src/permission/constants.ts +3 -3
  51. package/src/permission/helpers.ts +36 -37
  52. package/src/permission/index.ts +66 -107
  53. package/src/permission/pattern.ts +12 -14
  54. package/src/permission/piignore.ts +53 -90
  55. package/src/permission/precedence.ts +67 -33
  56. package/src/permission/resolution.ts +134 -75
  57. package/src/permission/storage.ts +57 -8
  58. package/src/permission/types.ts +40 -13
  59. package/src/questionnaire/component.ts +21 -12
  60. package/src/questionnaire/helpers.ts +11 -67
  61. package/src/questionnaire/index.ts +64 -57
  62. package/src/questionnaire/schemas.ts +12 -8
  63. package/src/questionnaire/types.ts +3 -3
  64. package/src/redactor/index.ts +30 -15
  65. package/src/redactor/patterns.ts +6 -6
  66. package/src/redactor/results.ts +156 -0
  67. package/src/redactor/secrets.ts +20 -64
  68. package/src/state.ts +66 -0
  69. package/src/subagent/helpers.ts +19 -47
  70. package/src/subagent/index.ts +59 -29
  71. package/src/subagent/sdk.ts +130 -0
  72. package/src/subagent/storage.ts +1 -2
  73. package/src/subagent/subsession.ts +54 -99
  74. package/src/subagent/types.ts +16 -7
  75. package/src/subagent/validation.ts +11 -54
  76. package/src/ui/components/bash-mode.ts +20 -12
  77. package/src/ui/components/frame.ts +4 -0
  78. package/src/ui/components/scrollable-view.ts +23 -7
  79. package/src/utils.ts +16 -6
  80. package/src/web-tools/providers/brave.ts +7 -2
  81. package/src/web-tools/providers/firecrawl.ts +47 -15
  82. package/src/web-tools/providers/index.ts +2 -2
  83. package/src/web-tools/providers/jina.ts +2 -1
  84. package/src/web-tools/providers/native.ts +2 -1
  85. package/src/web-tools/providers/tavily.ts +43 -22
  86. package/src/web-tools/web-fetch/index.ts +10 -11
  87. package/src/web-tools/web-fetch/storage.ts +17 -2
  88. package/src/web-tools/web-login/index.ts +10 -9
  89. package/src/web-tools/web-login/input.ts +55 -0
  90. package/src/web-tools/web-search/index.ts +3 -3
  91. package/src/cleanup/helpers.ts +0 -24
  92. package/src/cleanup/permission.ts +0 -74
  93. package/src/mcp-client/call-tool.ts +0 -143
  94. package/src/mcp-client/client.ts +0 -90
  95. package/src/mcp-client/command.ts +0 -257
  96. package/src/mcp-client/helpers.ts +0 -153
  97. package/src/mcp-client/index.ts +0 -21
  98. package/src/mcp-client/list-tools.ts +0 -84
  99. package/src/mcp-client/storage.ts +0 -190
  100. package/src/mcp-client/types.ts +0 -34
  101. package/src/mcp-client/validation.ts +0 -115
  102. package/src/optimizer/compactor/bash.ts +0 -141
  103. package/src/optimizer/compactor/grep.ts +0 -141
  104. package/src/optimizer/compactor/index.ts +0 -147
  105. package/src/optimizer/deduplicator/helpers.ts +0 -75
  106. package/src/optimizer/deduplicator/types.ts +0 -14
  107. package/src/optimizer/inspector/types.ts +0 -7
  108. package/src/optimizer/mapper/types.ts +0 -6
  109. package/src/optimizer/pruner/context.ts +0 -46
  110. package/src/optimizer/pruner/session.ts +0 -34
  111. package/src/optimizer/pruner/types.ts +0 -18
package/README.md CHANGED
@@ -223,7 +223,7 @@ Use `Ctrl+Alt+B` to cycle persistently between prompt input, context-included sh
223
223
  | ----------------------- | ------------------------------------------------------------- |
224
224
  | `/init` | Create or update repository-specific `AGENTS.md` instructions |
225
225
  | `/plan [request]` | Start, refine, save, or resume an isolated planning session |
226
- | `/agent` | Select, create, edit, or remove agent profiles |
226
+ | `/agents` | Select, create, edit, or remove agent profiles |
227
227
  | `/permissions` | View and manage file, shell, web, and MCP permission rules |
228
228
  | `/mcp` | Add, edit, enable, disable, or remove MCP servers |
229
229
  | `/web-login [provider]` | Configure credentials for web search and fetch providers |
@@ -237,7 +237,7 @@ The bundled agent profiles cover these common roles:
237
237
  | `scout` | Read-only codebase research and execution tracing |
238
238
  | `documenter` | User-facing Markdown and project documentation |
239
239
 
240
- Use `/agent` to start a new session with a specialist or create a project-specific or global profile. Profiles can constrain tools, files, shell commands, MCP servers, models, and thinking levels.
240
+ Use `/agents` to start a new session with a specialist or create a project-specific or global profile. Profiles can constrain tools, files, shell commands, MCP servers, models, and thinking levels.
241
241
 
242
242
  ## Command-line essentials
243
243
 
package/bin/build.mjs ADDED
@@ -0,0 +1,53 @@
1
+ import { build } from "esbuild";
2
+ import { copyFile, mkdir, readFile, rm, writeFile } from "node:fs/promises";
3
+ import { dirname, resolve } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+
6
+ const scriptDir = dirname(fileURLToPath(import.meta.url));
7
+ const projectRoot = resolve(scriptDir, "..");
8
+ const optimizerDir = resolve(projectRoot, "dist", "optimizer");
9
+ const rootPackage = JSON.parse(await readFile(resolve(projectRoot, "package.json"), "utf8"));
10
+
11
+ await rm(optimizerDir, { recursive: true, force: true });
12
+ await mkdir(optimizerDir, { recursive: true });
13
+ await build({
14
+ entryPoints: [resolve(projectRoot, "src", "optimizer", "index.ts")],
15
+ outfile: resolve(optimizerDir, "index.js"),
16
+ bundle: true,
17
+ format: "esm",
18
+ packages: "external",
19
+ platform: "node",
20
+ sourcemap: true,
21
+ target: "node22",
22
+ });
23
+
24
+ const optimizerPackage = {
25
+ name: "pi-optimizer",
26
+ version: rootPackage.version,
27
+ description: "Context optimization tools for pi coding agent",
28
+ type: "module",
29
+ main: "./index.js",
30
+ exports: "./index.js",
31
+ engines: rootPackage.engines,
32
+ license: rootPackage.license,
33
+ keywords: ["pi-package", "pi-coding-agent", "context-optimization"],
34
+ pi: { extensions: ["./index.js"] },
35
+ dependencies: {
36
+ picomatch: rootPackage.dependencies.picomatch,
37
+ "tree-sitter": rootPackage.dependencies["tree-sitter"],
38
+ },
39
+ peerDependencies: {
40
+ "@earendil-works/pi-coding-agent": "*",
41
+ "@earendil-works/pi-tui": "*",
42
+ typebox: "*",
43
+ },
44
+ };
45
+
46
+ await Promise.all([
47
+ writeFile(resolve(optimizerDir, "package.json"), `${JSON.stringify(optimizerPackage, null, 2)}\n`),
48
+ copyFile(resolve(projectRoot, "LICENSE"), resolve(optimizerDir, "LICENSE")),
49
+ copyFile(
50
+ resolve(projectRoot, "src", "optimizer", "README.md"),
51
+ resolve(optimizerDir, "README.md"),
52
+ ),
53
+ ]);
package/bin/surgent.js CHANGED
@@ -11,19 +11,22 @@ import { fileURLToPath } from "node:url";
11
11
  process.title = "surgent";
12
12
  const args = process.argv.slice(2);
13
13
 
14
+ const GLOBAL_PI_DIR = resolve(homedir(), ".pi", "agent");
14
15
  const PACKAGE_DIR = resolve(dirname(fileURLToPath(import.meta.url)), "..");
15
16
  const AGENT_ENTRY_URL = import.meta.resolve("@earendil-works/pi-coding-agent");
16
17
  const LOCAL_PI_SUBDIRS = ["agents", "plans"];
18
+ const GLOBAL_PI_SUBDIRS = ["agents", "grammars"];
19
+ const BASE_TOOLS = ["ls", "find", "grep", "code_map", "inspect", "read"];
17
20
  const BUILT_IN_META = {
18
21
  documenter: {
19
- tools: ["code_map", "inspect", "read", "find", "grep", "ls", "edit", "write", "questionnaire"],
22
+ tools: BASE_TOOLS.concat(["edit", "write", "questionnaire"]),
20
23
  "files.write": ["**/*.md"],
21
24
  },
22
25
  planner: {
23
- tools: ["read", "grep", "find", "ls", "web_fetch", "web_search", "questionnaire"],
26
+ tools: BASE_TOOLS.concat(["web_fetch", "web_search", "questionnaire"]),
24
27
  },
25
28
  scout: {
26
- tools: ["ls", "find", "grep", "code_map", "inspect", "read", "web_fetch", "web_search"],
29
+ tools: BASE_TOOLS.concat(["web_fetch", "web_search"]),
27
30
  },
28
31
  };
29
32
 
@@ -32,9 +35,8 @@ function isMissingFileError(error) {
32
35
  }
33
36
 
34
37
  async function initBuiltInMeta() {
35
- const settingsPath = resolve(homedir(), ".pi", "agent", "settings.json");
38
+ const settingsPath = resolve(GLOBAL_PI_DIR, "settings.json");
36
39
  let settings;
37
-
38
40
  try {
39
41
  settings = JSON.parse(await readFile(settingsPath, "utf8"));
40
42
  } catch (error) {
@@ -128,7 +130,7 @@ async function syncPiIgnore(cwd) {
128
130
  return;
129
131
  }
130
132
 
131
- await writeFile(piIgnorePath, gitIgnoreContents);
133
+ await writeFile(piIgnorePath, `.pi\n\n${gitIgnoreContents}`);
132
134
  }
133
135
 
134
136
  function isJsonModeActive(args) {
@@ -194,16 +196,16 @@ if (args.includes("--help") || args.includes("-h")) {
194
196
  await runRewrittenHelp(args);
195
197
  } else {
196
198
  const cwd = process.cwd();
199
+ const srcDir = resolve(PACKAGE_DIR, "src");
197
200
  if (!isJsonModeActive(args)) {
198
- await ensurePiExcluded(cwd);
199
- await syncPiIgnore(cwd);
200
- }
201
- for (const localPiSubdir of LOCAL_PI_SUBDIRS) {
202
- await mkdir(resolve(cwd, ".pi", localPiSubdir), { recursive: true });
201
+ await Promise.all([ensurePiExcluded(cwd), syncPiIgnore(cwd)]);
203
202
  }
203
+ const [entries] = await Promise.all([
204
+ readdir(srcDir, { withFileTypes: true }),
205
+ ...LOCAL_PI_SUBDIRS.map((dir) => mkdir(resolve(cwd, ".pi", dir), { recursive: true })),
206
+ ...GLOBAL_PI_SUBDIRS.map((dir) => mkdir(resolve(GLOBAL_PI_DIR, dir), { recursive: true })),
207
+ ]);
204
208
 
205
- const srcDir = resolve(PACKAGE_DIR, "src");
206
- const entries = await readdir(srcDir, { withFileTypes: true });
207
209
  const extensionArgs = entries
208
210
  .filter((entry) => entry.isDirectory())
209
211
  .flatMap((entry) => ["--extension", resolve(srcDir, entry.name)]);
@@ -13,13 +13,21 @@ Long coding sessions accumulate large tool results, repeated file content, and o
13
13
  - Adds `code_map`, which uses Tree-sitter to index symbols and declarations before files are read in full.
14
14
  - Adds `inspect`, which returns one selected symbol body for targeted code reading and edits.
15
15
  - Supports TypeScript, JavaScript, Python, Go, Java, and Rust code navigation.
16
- - Compacts Bash output by stripping terminal control sequences and collapsing repeated or similar lines.
17
- - Formats grep results by grouping matches under file paths and stores smaller summaries in session history.
18
- - Removes older `read` and `inspect` results when newer results fully cover same content.
19
- - Prunes empty tool results and superseded tool calls from model context and persisted sessions.
16
+ - Losslessly compresses consecutive Bash lines with at most one varying alphanumeric token: `status {204, 404, 500}`. Order, duplicates, and raw bytes remain recoverable; `{{` / `}}` escape literal braces. Compression applies only when shorter. Bash output limits still apply.
17
+ - Reduces grep output during execution by grouping matches under file paths.
18
+ - Filters older eligible `inspect` exchanges and pre-write `read`/`inspect` exchanges from model requests using a session-start snapshot.
19
+ - Persistently prunes eligible error and empty tool results, together with their tool calls, through append-only context edits.
20
20
 
21
21
  These changes reduce context growth, improve prompt-cache reuse, and leave more room for requirements, code, and reasoning.
22
22
 
23
+ ## Context filtering
24
+
25
+ At `session_start`, optimizer snapshots the current branch. For model requests only, it hides older eligible `inspect` exchanges for the same normalized file path and exact returned symbol, and older same-file `read`/`inspect` exchanges superseded by a successful `write`. Both tool calls and results are hidden. There is no general `read` deduplication, and edits or shell commands do not invalidate earlier results.
26
+
27
+ Changes after startup are deferred until the next session start. Session tree navigation clears the snapshot. This transient filtering leaves raw history, the TUI, exports, and Pi's canonical context for native compaction unchanged.
28
+
29
+ Separately, when the agent settles after successful completion, eligible error results (except Bash errors) and recognized empty `ls`/`find` results are pruned with their tool calls through persistent, append-only context edits. These change future model context without rewriting raw history.
30
+
23
31
  ## Requirements
24
32
 
25
33
  - Node.js 22.19 or newer