@nghyane/arcane 0.1.13 → 0.1.15
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/CHANGELOG.md +28 -0
- package/package.json +21 -70
- package/scripts/format-prompts.ts +1 -3
- package/src/cli/args.ts +2 -7
- package/src/cli/config-cli.ts +1 -1
- package/src/cli/plugin-cli.ts +1 -1
- package/src/cli/setup-cli.ts +1 -1
- package/src/cli/update-cli.ts +1 -1
- package/src/cli/web-search-cli.ts +1 -1
- package/src/cli.ts +0 -1
- package/src/commands/config.ts +1 -1
- package/src/commands/grep.ts +1 -1
- package/src/commands/jupyter.ts +1 -1
- package/src/commands/plugin.ts +1 -1
- package/src/commands/setup.ts +1 -1
- package/src/commands/shell.ts +1 -1
- package/src/commands/ssh.ts +1 -1
- package/src/commands/stats.ts +1 -1
- package/src/commands/update.ts +1 -1
- package/src/config/model-registry.ts +3 -4
- package/src/config/model-resolver.ts +36 -9
- package/src/config/prompt-templates.ts +1 -9
- package/src/config/settings-schema.ts +32 -88
- package/src/config/settings.ts +3 -4
- package/src/debug/index.ts +1 -1
- package/src/debug/log-formatting.ts +1 -1
- package/src/debug/log-viewer.ts +2 -2
- package/src/discovery/helpers.ts +13 -3
- package/src/exa/index.ts +1 -35
- package/src/exa/render.ts +30 -190
- package/src/export/html/index.ts +1 -1
- package/src/extensibility/custom-tools/loader.ts +1 -1
- package/src/extensibility/custom-tools/types.ts +5 -1
- package/src/extensibility/custom-tools/wrapper.ts +1 -1
- package/src/extensibility/extensions/runner.ts +1 -1
- package/src/extensibility/extensions/types.ts +1 -1
- package/src/extensibility/extensions/wrapper.ts +7 -15
- package/src/extensibility/hooks/runner.ts +1 -1
- package/src/extensibility/hooks/types.ts +1 -1
- package/src/extensibility/plugins/doctor.ts +1 -1
- package/src/index.ts +13 -13
- package/src/lsp/index.ts +77 -24
- package/src/lsp/render.ts +34 -583
- package/src/lsp/types.ts +3 -3
- package/src/lsp/utils.ts +1 -1
- package/src/main.ts +1 -1
- package/src/mcp/tool-bridge.ts +1 -24
- package/src/modes/components/assistant-message.ts +7 -7
- package/src/modes/components/bash-execution.ts +50 -112
- package/src/modes/components/bordered-loader.ts +1 -1
- package/src/modes/components/branch-summary-message.ts +16 -10
- package/src/modes/components/compaction-summary-message.ts +20 -12
- package/src/modes/components/context-group.ts +106 -0
- package/src/modes/components/custom-message.ts +4 -5
- package/src/modes/components/diff.ts +2 -2
- package/src/modes/components/dynamic-border.ts +1 -1
- package/src/modes/components/extensions/extension-dashboard.ts +1 -1
- package/src/modes/components/extensions/extension-list.ts +1 -1
- package/src/modes/components/extensions/inspector-panel.ts +1 -1
- package/src/modes/components/footer.ts +2 -2
- package/src/modes/components/history-search.ts +1 -1
- package/src/modes/components/hook-editor.ts +1 -1
- package/src/modes/components/hook-input.ts +1 -1
- package/src/modes/components/hook-message.ts +4 -5
- package/src/modes/components/hook-selector.ts +1 -1
- package/src/modes/components/index.ts +0 -2
- package/src/modes/components/keybinding-hints.ts +1 -1
- package/src/modes/components/login-dialog.ts +1 -1
- package/src/modes/components/mcp-add-wizard.ts +1 -1
- package/src/modes/components/model-selector.ts +1 -1
- package/src/modes/components/oauth-selector.ts +1 -1
- package/src/modes/components/plugin-settings.ts +1 -1
- package/src/modes/components/python-execution.ts +51 -91
- package/src/modes/components/queue-mode-selector.ts +1 -1
- package/src/modes/components/session-selector.ts +1 -1
- package/src/modes/components/settings-defs.ts +5 -10
- package/src/modes/components/settings-selector.ts +1 -1
- package/src/modes/components/show-images-selector.ts +1 -1
- package/src/modes/components/skill-message.ts +4 -4
- package/src/modes/components/status-line/segments.ts +2 -2
- package/src/modes/components/status-line/separators.ts +1 -1
- package/src/modes/components/status-line-segment-editor.ts +1 -1
- package/src/modes/components/status-line.ts +1 -1
- package/src/modes/components/theme-selector.ts +1 -1
- package/src/modes/components/thinking-selector.ts +1 -1
- package/src/modes/components/todo-display.ts +2 -4
- package/src/modes/components/todo-reminder.ts +4 -4
- package/src/modes/components/tool-execution.ts +118 -440
- package/src/modes/components/tool-image-display.ts +107 -0
- package/src/modes/components/tree-selector.ts +2 -2
- package/src/modes/components/ttsr-notification.ts +4 -17
- package/src/modes/components/user-message-selector.ts +1 -1
- package/src/modes/components/user-message.ts +9 -10
- package/src/modes/components/welcome.ts +1 -1
- package/src/modes/controllers/command-controller.ts +1 -1
- package/src/modes/controllers/event-controller.ts +58 -187
- package/src/modes/controllers/extension-ui-controller.ts +1 -1
- package/src/modes/controllers/input-controller.ts +3 -1
- package/src/modes/controllers/mcp-command-controller.ts +1 -1
- package/src/modes/controllers/selector-controller.ts +3 -26
- package/src/modes/controllers/ssh-command-controller.ts +1 -1
- package/src/modes/interactive-mode.ts +3 -7
- package/src/modes/print-mode.ts +5 -5
- package/src/modes/rpc/rpc-mode.ts +1 -1
- package/src/modes/types.ts +1 -2
- package/src/modes/utils/ui-helpers.ts +34 -32
- package/src/patch/edit-tool.ts +742 -0
- package/src/patch/index.ts +32 -898
- package/src/patch/schemas.ts +208 -0
- package/src/patch/shared.ts +83 -151
- package/src/prompts/agents/explore.md +22 -37
- package/src/prompts/agents/init.md +1 -1
- package/src/prompts/agents/librarian.md +29 -20
- package/src/prompts/agents/oracle.md +9 -2
- package/src/prompts/agents/reviewer.md +14 -48
- package/src/prompts/agents/task.md +16 -8
- package/src/prompts/compaction/branch-summary.md +4 -1
- package/src/prompts/compaction/compaction-summary.md +4 -1
- package/src/prompts/system/subagent-system-prompt.md +1 -1
- package/src/prompts/system/system-prompt.md +162 -178
- package/src/prompts/system/verification-reminder.md +6 -0
- package/src/sdk.ts +0 -9
- package/src/session/agent-session.ts +244 -1459
- package/src/session/model-controller.ts +406 -0
- package/src/session/retry-utils.ts +71 -0
- package/src/session/session-manager.ts +22 -186
- package/src/session/session-types.ts +312 -0
- package/src/session/stats.ts +387 -0
- package/src/session/streaming-edit.ts +258 -0
- package/src/session/ttsr.ts +213 -0
- package/src/slash-commands/builtin-registry.ts +0 -8
- package/src/stt/recorder.ts +2 -2
- package/src/system-prompt.ts +1 -14
- package/src/task/agents.ts +7 -33
- package/src/task/executor.ts +50 -438
- package/src/task/index.ts +104 -71
- package/src/task/progress-tracker.ts +390 -0
- package/src/task/render.ts +371 -187
- package/src/task/subprocess-tool-registry.ts +1 -1
- package/src/task/types.ts +14 -47
- package/src/tools/ask.ts +31 -42
- package/src/tools/bash-interactive.ts +2 -2
- package/src/tools/bash-interceptor.ts +2 -2
- package/src/tools/bash-normalize.ts +1 -1
- package/src/tools/bash-skill-urls.ts +2 -2
- package/src/tools/bash.ts +87 -136
- package/src/tools/browser.ts +54 -84
- package/src/tools/create-tools.ts +186 -0
- package/src/tools/default-renderer.ts +104 -0
- package/src/tools/explore.ts +11 -10
- package/src/tools/fetch.ts +24 -114
- package/src/tools/find.ts +48 -132
- package/src/tools/gemini-image.ts +5 -15
- package/src/tools/github.ts +450 -0
- package/src/tools/grep.ts +43 -179
- package/src/tools/index.ts +35 -198
- package/src/tools/json-tree.ts +3 -3
- package/src/tools/librarian.ts +18 -18
- package/src/tools/list-limit.ts +2 -2
- package/src/tools/notebook.ts +35 -87
- package/src/tools/oracle.ts +25 -25
- package/src/tools/output-meta.ts +89 -4
- package/src/tools/output-utils.ts +2 -2
- package/src/tools/python.ts +86 -637
- package/src/tools/read.ts +36 -119
- package/src/tools/reviewer-tool.ts +19 -21
- package/src/tools/search-code.ts +128 -0
- package/src/tools/ssh.ts +67 -126
- package/src/tools/subagent-tool.ts +197 -123
- package/src/tools/todo-write.ts +15 -31
- package/src/tools/tool-errors.ts +0 -30
- package/src/tools/undo-edit.ts +30 -67
- package/src/tools/write.ts +78 -127
- package/src/tui/code-cell.ts +4 -4
- package/src/tui/file-list.ts +2 -2
- package/src/tui/output-block.ts +1 -1
- package/src/tui/status-line.ts +1 -1
- package/src/tui/tree-list.ts +2 -2
- package/src/tui/types.ts +1 -1
- package/src/tui/utils.ts +1 -1
- package/src/{tools → ui}/render-utils.ts +87 -126
- package/src/utils/external-editor.ts +4 -4
- package/src/utils/file-mentions.ts +1 -1
- package/src/utils/index.ts +30 -0
- package/src/utils/tools-manager.ts +9 -19
- package/src/web/github-client.ts +290 -0
- package/src/web/scrapers/github.ts +11 -62
- package/src/web/search/auth.ts +1 -3
- package/src/web/search/index.ts +82 -46
- package/src/web/search/provider.ts +11 -16
- package/src/web/search/providers/grep.ts +160 -0
- package/src/web/search/render.ts +48 -235
- package/src/web/search/types.ts +1 -1
- package/src/commands/commit.ts +0 -36
- package/src/commit/agentic/agent.ts +0 -311
- package/src/commit/agentic/fallback.ts +0 -96
- package/src/commit/agentic/index.ts +0 -359
- package/src/commit/agentic/prompts/analyze-file.md +0 -22
- package/src/commit/agentic/prompts/session-user.md +0 -25
- package/src/commit/agentic/prompts/split-confirm.md +0 -1
- package/src/commit/agentic/prompts/system.md +0 -38
- package/src/commit/agentic/state.ts +0 -69
- package/src/commit/agentic/tools/analyze-file.ts +0 -118
- package/src/commit/agentic/tools/git-file-diff.ts +0 -194
- package/src/commit/agentic/tools/git-hunk.ts +0 -50
- package/src/commit/agentic/tools/git-overview.ts +0 -84
- package/src/commit/agentic/tools/index.ts +0 -56
- package/src/commit/agentic/tools/propose-changelog.ts +0 -128
- package/src/commit/agentic/tools/propose-commit.ts +0 -154
- package/src/commit/agentic/tools/recent-commits.ts +0 -81
- package/src/commit/agentic/tools/split-commit.ts +0 -280
- package/src/commit/agentic/topo-sort.ts +0 -44
- package/src/commit/agentic/trivial.ts +0 -51
- package/src/commit/agentic/validation.ts +0 -200
- package/src/commit/analysis/conventional.ts +0 -165
- package/src/commit/analysis/index.ts +0 -4
- package/src/commit/analysis/scope.ts +0 -242
- package/src/commit/analysis/summary.ts +0 -112
- package/src/commit/analysis/validation.ts +0 -66
- package/src/commit/changelog/detect.ts +0 -37
- package/src/commit/changelog/generate.ts +0 -110
- package/src/commit/changelog/index.ts +0 -234
- package/src/commit/changelog/parse.ts +0 -44
- package/src/commit/cli.ts +0 -93
- package/src/commit/git/diff.ts +0 -148
- package/src/commit/git/errors.ts +0 -9
- package/src/commit/git/index.ts +0 -211
- package/src/commit/git/operations.ts +0 -54
- package/src/commit/index.ts +0 -5
- package/src/commit/map-reduce/index.ts +0 -64
- package/src/commit/map-reduce/map-phase.ts +0 -178
- package/src/commit/map-reduce/reduce-phase.ts +0 -145
- package/src/commit/map-reduce/utils.ts +0 -9
- package/src/commit/message.ts +0 -11
- package/src/commit/model-selection.ts +0 -69
- package/src/commit/pipeline.ts +0 -243
- package/src/commit/prompts/analysis-system.md +0 -148
- package/src/commit/prompts/analysis-user.md +0 -38
- package/src/commit/prompts/changelog-system.md +0 -50
- package/src/commit/prompts/changelog-user.md +0 -18
- package/src/commit/prompts/file-observer-system.md +0 -24
- package/src/commit/prompts/file-observer-user.md +0 -8
- package/src/commit/prompts/reduce-system.md +0 -50
- package/src/commit/prompts/reduce-user.md +0 -17
- package/src/commit/prompts/summary-retry.md +0 -3
- package/src/commit/prompts/summary-system.md +0 -38
- package/src/commit/prompts/summary-user.md +0 -13
- package/src/commit/prompts/types-description.md +0 -2
- package/src/commit/types.ts +0 -109
- package/src/commit/utils/exclusions.ts +0 -42
- package/src/mcp/render.ts +0 -123
- package/src/modes/components/agent-dashboard.ts +0 -1130
- package/src/modes/components/codemode-group.ts +0 -369
- package/src/modes/components/read-tool-group.ts +0 -119
- package/src/modes/components/visual-truncate.ts +0 -63
- package/src/prompts/system/subagent-user-prompt.md +0 -8
- package/src/prompts/tools/ask.md +0 -44
- package/src/prompts/tools/bash.md +0 -24
- package/src/prompts/tools/browser.md +0 -33
- package/src/prompts/tools/calculator.md +0 -12
- package/src/prompts/tools/explore.md +0 -29
- package/src/prompts/tools/fetch.md +0 -16
- package/src/prompts/tools/find.md +0 -18
- package/src/prompts/tools/gemini-image.md +0 -23
- package/src/prompts/tools/grep.md +0 -28
- package/src/prompts/tools/hashline.md +0 -232
- package/src/prompts/tools/librarian.md +0 -24
- package/src/prompts/tools/lsp.md +0 -28
- package/src/prompts/tools/oracle.md +0 -26
- package/src/prompts/tools/patch.md +0 -74
- package/src/prompts/tools/python.md +0 -66
- package/src/prompts/tools/read.md +0 -36
- package/src/prompts/tools/replace.md +0 -38
- package/src/prompts/tools/reviewer.md +0 -41
- package/src/prompts/tools/ssh.md +0 -51
- package/src/prompts/tools/task-summary.md +0 -28
- package/src/prompts/tools/task.md +0 -146
- package/src/prompts/tools/todo-write.md +0 -65
- package/src/prompts/tools/undo-edit.md +0 -7
- package/src/prompts/tools/web-search.md +0 -19
- package/src/prompts/tools/write.md +0 -18
- package/src/task/batch.ts +0 -102
- package/src/task/discovery.ts +0 -126
- package/src/task/parallel.ts +0 -84
- package/src/task/template.ts +0 -32
- package/src/tools/calculator.ts +0 -537
- package/src/tools/jtd-to-typescript.ts +0 -198
- package/src/tools/renderers.ts +0 -60
- package/src/tools/tool-result.ts +0 -86
- /package/src/{modes/theme → theme}/dark.json +0 -0
- /package/src/{modes/theme → theme}/defaults/dark-catppuccin.json +0 -0
- /package/src/{modes/theme → theme}/defaults/dark-dracula.json +0 -0
- /package/src/{modes/theme → theme}/defaults/dark-gruvbox.json +0 -0
- /package/src/{modes/theme → theme}/defaults/dark-solarized.json +0 -0
- /package/src/{modes/theme → theme}/defaults/dark-tokyo-night.json +0 -0
- /package/src/{modes/theme → theme}/defaults/index.ts +0 -0
- /package/src/{modes/theme → theme}/defaults/light-catppuccin.json +0 -0
- /package/src/{modes/theme → theme}/defaults/light-github.json +0 -0
- /package/src/{modes/theme → theme}/defaults/light-solarized.json +0 -0
- /package/src/{modes/theme → theme}/light.json +0 -0
- /package/src/{modes/theme → theme}/mermaid-cache.ts +0 -0
- /package/src/{modes/theme → theme}/theme-schema.json +0 -0
- /package/src/{modes/theme → theme}/theme.ts +0 -0
package/src/tools/grep.ts
CHANGED
|
@@ -1,37 +1,33 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
2
|
import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@nghyane/arcane-agent";
|
|
3
|
-
|
|
4
3
|
import { type GrepResult, grep } from "@nghyane/arcane-natives";
|
|
5
4
|
import type { Component } from "@nghyane/arcane-tui";
|
|
6
5
|
import { Text } from "@nghyane/arcane-tui";
|
|
7
6
|
import { untilAborted } from "@nghyane/arcane-utils";
|
|
8
7
|
import { type Static, Type } from "@sinclair/typebox";
|
|
9
|
-
import { renderPromptTemplate } from "../config/prompt-templates";
|
|
10
8
|
import type { RenderResultOptions } from "../extensibility/custom-tools/types";
|
|
11
|
-
import type { Theme } from "../modes/theme/theme";
|
|
12
9
|
import { computeLineHash } from "../patch/hashline";
|
|
13
|
-
import grepDescription from "../prompts/tools/grep.md" with { type: "text" };
|
|
14
10
|
import { DEFAULT_MAX_COLUMN, type TruncationResult, truncateHead } from "../session/streaming-output";
|
|
15
|
-
import
|
|
11
|
+
import type { Theme } from "../theme/theme";
|
|
12
|
+
import { renderStatusLine } from "../tui";
|
|
13
|
+
import { formatCount, formatEmptyMessage, formatErrorMessage } from "../ui/render-utils";
|
|
16
14
|
import { resolveFileDisplayMode } from "../utils/file-display-mode";
|
|
17
15
|
import type { ToolSession } from ".";
|
|
18
|
-
import type
|
|
16
|
+
import { type OutputMeta, toolResult } from "./output-meta";
|
|
19
17
|
import { resolveToCwd } from "./path-utils";
|
|
20
|
-
import { formatCount, formatEmptyMessage, formatErrorMessage, PREVIEW_LIMITS } from "./render-utils";
|
|
21
18
|
import { ToolError } from "./tool-errors";
|
|
22
|
-
import { toolResult } from "./tool-result";
|
|
23
19
|
|
|
24
20
|
const grepSchema = Type.Object({
|
|
25
21
|
pattern: Type.String({ description: "Regex pattern to search for" }),
|
|
26
|
-
path: Type.Optional(Type.String({ description: "
|
|
27
|
-
glob: Type.Optional(Type.String({ description:
|
|
28
|
-
type: Type.Optional(Type.String({ description:
|
|
29
|
-
i: Type.Optional(Type.Boolean({ description: "Case-insensitive search
|
|
30
|
-
pre: Type.Optional(Type.Number({ description: "
|
|
31
|
-
post: Type.Optional(Type.Number({ description: "
|
|
32
|
-
multiline: Type.Optional(Type.Boolean({ description: "Enable multiline matching" })),
|
|
33
|
-
limit: Type.Optional(Type.Number({ description: "
|
|
34
|
-
offset: Type.Optional(Type.Number({ description: "Skip first N
|
|
22
|
+
path: Type.Optional(Type.String({ description: "Directory or file to search (default: cwd)" })),
|
|
23
|
+
glob: Type.Optional(Type.String({ description: 'Glob filter for file paths (e.g. "*.ts")' })),
|
|
24
|
+
type: Type.Optional(Type.String({ description: 'File extension filter without dot (e.g. "ts")' })),
|
|
25
|
+
i: Type.Optional(Type.Boolean({ description: "Case-insensitive search" })),
|
|
26
|
+
pre: Type.Optional(Type.Number({ description: "Context lines before match" })),
|
|
27
|
+
post: Type.Optional(Type.Number({ description: "Context lines after match" })),
|
|
28
|
+
multiline: Type.Optional(Type.Boolean({ description: "Enable multiline regex matching" })),
|
|
29
|
+
limit: Type.Optional(Type.Number({ description: "Max number of matches to return" })),
|
|
30
|
+
offset: Type.Optional(Type.Number({ description: "Skip first N matches" })),
|
|
35
31
|
});
|
|
36
32
|
|
|
37
33
|
export type GrepToolInput = Static<typeof grepSchema>;
|
|
@@ -55,19 +51,13 @@ export interface GrepToolDetails {
|
|
|
55
51
|
|
|
56
52
|
type GrepParams = Static<typeof grepSchema>;
|
|
57
53
|
|
|
58
|
-
export class GrepTool implements AgentTool<typeof grepSchema, GrepToolDetails> {
|
|
54
|
+
export class GrepTool implements AgentTool<typeof grepSchema, GrepToolDetails, Theme> {
|
|
59
55
|
readonly name = "grep";
|
|
60
56
|
readonly label = "Grep";
|
|
61
|
-
|
|
57
|
+
description = "Search file contents with regex";
|
|
62
58
|
readonly parameters = grepSchema;
|
|
63
59
|
|
|
64
|
-
constructor(private readonly session: ToolSession) {
|
|
65
|
-
const displayMode = resolveFileDisplayMode(session);
|
|
66
|
-
this.description = renderPromptTemplate(grepDescription, {
|
|
67
|
-
IS_HASHLINE_MODE: displayMode.hashLines,
|
|
68
|
-
IS_LINE_NUMBER_MODE: !displayMode.hashLines && displayMode.lineNumbers,
|
|
69
|
-
});
|
|
70
|
-
}
|
|
60
|
+
constructor(private readonly session: ToolSession) {}
|
|
71
61
|
|
|
72
62
|
async execute(
|
|
73
63
|
_toolCallId: string,
|
|
@@ -286,29 +276,7 @@ export class GrepTool implements AgentTool<typeof grepSchema, GrepToolDetails> {
|
|
|
286
276
|
return resultBuilder.done();
|
|
287
277
|
});
|
|
288
278
|
}
|
|
289
|
-
}
|
|
290
279
|
|
|
291
|
-
// =============================================================================
|
|
292
|
-
// TUI Renderer
|
|
293
|
-
// =============================================================================
|
|
294
|
-
|
|
295
|
-
interface GrepRenderArgs {
|
|
296
|
-
pattern: string;
|
|
297
|
-
path?: string;
|
|
298
|
-
glob?: string;
|
|
299
|
-
type?: string;
|
|
300
|
-
i?: boolean;
|
|
301
|
-
pre?: number;
|
|
302
|
-
post?: number;
|
|
303
|
-
multiline?: boolean;
|
|
304
|
-
limit?: number;
|
|
305
|
-
offset?: number;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
const COLLAPSED_TEXT_LIMIT = PREVIEW_LIMITS.COLLAPSED_LINES * 2;
|
|
309
|
-
|
|
310
|
-
export const grepToolRenderer = {
|
|
311
|
-
inline: true,
|
|
312
280
|
renderCall(args: GrepRenderArgs, _options: RenderResultOptions, uiTheme: Theme): Component {
|
|
313
281
|
const meta: string[] = [];
|
|
314
282
|
if (args.path) meta.push(`in ${args.path}`);
|
|
@@ -330,11 +298,11 @@ export const grepToolRenderer = {
|
|
|
330
298
|
uiTheme,
|
|
331
299
|
);
|
|
332
300
|
return new Text(text, 0, 0);
|
|
333
|
-
}
|
|
301
|
+
}
|
|
334
302
|
|
|
335
303
|
renderResult(
|
|
336
304
|
result: { content: Array<{ type: string; text?: string }>; details?: GrepToolDetails; isError?: boolean },
|
|
337
|
-
|
|
305
|
+
_options: RenderResultOptions,
|
|
338
306
|
uiTheme: Theme,
|
|
339
307
|
args?: GrepRenderArgs,
|
|
340
308
|
): Component {
|
|
@@ -345,145 +313,41 @@ export const grepToolRenderer = {
|
|
|
345
313
|
return new Text(formatErrorMessage(errorText, uiTheme), 0, 0);
|
|
346
314
|
}
|
|
347
315
|
|
|
348
|
-
const hasDetailedData = details?.matchCount !== undefined || details?.fileCount !== undefined;
|
|
349
|
-
|
|
350
|
-
if (!hasDetailedData) {
|
|
351
|
-
const textContent = result.content?.find(c => c.type === "text")?.text;
|
|
352
|
-
if (!textContent || textContent === "No matches found") {
|
|
353
|
-
return new Text(formatEmptyMessage("No matches found", uiTheme), 0, 0);
|
|
354
|
-
}
|
|
355
|
-
const lines = textContent.split("\n").filter(line => line.trim() !== "");
|
|
356
|
-
const description = args?.pattern ?? undefined;
|
|
357
|
-
const header = renderStatusLine(
|
|
358
|
-
{ icon: "success", title: "Grep", description, meta: [formatCount("item", lines.length)] },
|
|
359
|
-
uiTheme,
|
|
360
|
-
);
|
|
361
|
-
let cached: RenderCache | undefined;
|
|
362
|
-
return {
|
|
363
|
-
render(width: number): string[] {
|
|
364
|
-
const { expanded } = options;
|
|
365
|
-
const key = new Hasher().bool(expanded).u32(width).digest();
|
|
366
|
-
if (cached?.key === key) return cached.lines;
|
|
367
|
-
const listLines = renderTreeList(
|
|
368
|
-
{
|
|
369
|
-
items: lines,
|
|
370
|
-
expanded,
|
|
371
|
-
maxCollapsed: COLLAPSED_TEXT_LIMIT,
|
|
372
|
-
itemType: "item",
|
|
373
|
-
renderItem: line => uiTheme.fg("toolOutput", line),
|
|
374
|
-
},
|
|
375
|
-
uiTheme,
|
|
376
|
-
);
|
|
377
|
-
const result = [header, ...listLines].map(l => truncateToWidth(l, width, Ellipsis.Omit));
|
|
378
|
-
cached = { key, lines: result };
|
|
379
|
-
return result;
|
|
380
|
-
},
|
|
381
|
-
invalidate() {
|
|
382
|
-
cached = undefined;
|
|
383
|
-
},
|
|
384
|
-
};
|
|
385
|
-
}
|
|
386
|
-
|
|
387
316
|
const matchCount = details?.matchCount ?? 0;
|
|
388
317
|
const fileCount = details?.fileCount ?? 0;
|
|
389
|
-
const truncation = details?.meta?.truncation;
|
|
390
|
-
const limits = details?.meta?.limits;
|
|
391
318
|
const truncated = Boolean(
|
|
392
|
-
details?.truncated ||
|
|
319
|
+
details?.truncated ||
|
|
320
|
+
details?.meta?.truncation ||
|
|
321
|
+
details?.meta?.limits?.matchLimit ||
|
|
322
|
+
details?.meta?.limits?.resultLimit ||
|
|
323
|
+
details?.meta?.limits?.columnTruncated,
|
|
393
324
|
);
|
|
394
325
|
|
|
395
326
|
if (matchCount === 0) {
|
|
396
|
-
|
|
397
|
-
{ icon: "warning", title: "Grep", description: args?.pattern, meta: ["0 matches"] },
|
|
398
|
-
uiTheme,
|
|
399
|
-
);
|
|
400
|
-
return new Text([header, formatEmptyMessage("No matches found", uiTheme)].join("\n"), 0, 0);
|
|
327
|
+
return new Text(formatEmptyMessage("No matches found", uiTheme), 0, 0);
|
|
401
328
|
}
|
|
402
329
|
|
|
403
|
-
const
|
|
404
|
-
const meta = [...summaryParts];
|
|
330
|
+
const meta = [formatCount("match", matchCount), formatCount("file", fileCount)];
|
|
405
331
|
if (details?.scopePath) meta.push(`in ${details.scopePath}`);
|
|
406
332
|
if (truncated) meta.push(uiTheme.fg("warning", "truncated"));
|
|
407
|
-
|
|
408
|
-
const
|
|
409
|
-
{ icon: truncated ? "warning" : "success", title: "Grep", description, meta },
|
|
333
|
+
|
|
334
|
+
const text = renderStatusLine(
|
|
335
|
+
{ icon: truncated ? "warning" : "success", title: "Grep", description: args?.pattern, meta },
|
|
410
336
|
uiTheme,
|
|
411
337
|
);
|
|
338
|
+
return new Text(text, 0, 0);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
412
341
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
continue;
|
|
426
|
-
}
|
|
427
|
-
current.push(line);
|
|
428
|
-
}
|
|
429
|
-
if (current.length > 0) matchGroups.push(current);
|
|
430
|
-
} else {
|
|
431
|
-
for (const line of rawLines) {
|
|
432
|
-
if (line.trim().length === 0) continue;
|
|
433
|
-
matchGroups.push([line]);
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
const getCollapsedMatchLimit = (groups: string[][], maxLines: number): number => {
|
|
438
|
-
if (groups.length === 0) return 0;
|
|
439
|
-
let usedLines = 0;
|
|
440
|
-
let count = 0;
|
|
441
|
-
for (const group of groups) {
|
|
442
|
-
if (count > 0 && usedLines + group.length > maxLines) break;
|
|
443
|
-
usedLines += group.length;
|
|
444
|
-
count += 1;
|
|
445
|
-
if (usedLines >= maxLines) break;
|
|
446
|
-
}
|
|
447
|
-
return count;
|
|
448
|
-
};
|
|
449
|
-
|
|
450
|
-
const truncationReasons: string[] = [];
|
|
451
|
-
if (limits?.matchLimit) truncationReasons.push(`limit ${limits.matchLimit.reached} matches`);
|
|
452
|
-
if (limits?.resultLimit) truncationReasons.push(`limit ${limits.resultLimit.reached} results`);
|
|
453
|
-
if (truncation) truncationReasons.push(truncation.truncatedBy === "lines" ? "line limit" : "size limit");
|
|
454
|
-
if (limits?.columnTruncated) truncationReasons.push(`line length ${limits.columnTruncated.maxColumn}`);
|
|
455
|
-
if (truncation?.artifactId) truncationReasons.push(`full output: artifact://${truncation.artifactId}`);
|
|
456
|
-
|
|
457
|
-
const extraLines =
|
|
458
|
-
truncationReasons.length > 0 ? [uiTheme.fg("warning", `truncated: ${truncationReasons.join(", ")}`)] : [];
|
|
459
|
-
|
|
460
|
-
let cached: RenderCache | undefined;
|
|
461
|
-
return {
|
|
462
|
-
render(width: number): string[] {
|
|
463
|
-
const { expanded } = options;
|
|
464
|
-
const key = new Hasher().bool(expanded).u32(width).digest();
|
|
465
|
-
if (cached?.key === key) return cached.lines;
|
|
466
|
-
const maxCollapsed = expanded
|
|
467
|
-
? matchGroups.length
|
|
468
|
-
: getCollapsedMatchLimit(matchGroups, COLLAPSED_TEXT_LIMIT);
|
|
469
|
-
const matchLines = renderTreeList(
|
|
470
|
-
{
|
|
471
|
-
items: matchGroups,
|
|
472
|
-
expanded,
|
|
473
|
-
maxCollapsed,
|
|
474
|
-
itemType: "match",
|
|
475
|
-
renderItem: group => group.map(line => uiTheme.fg("toolOutput", line)),
|
|
476
|
-
},
|
|
477
|
-
uiTheme,
|
|
478
|
-
);
|
|
479
|
-
const result = [header, ...matchLines, ...extraLines].map(l => truncateToWidth(l, width, Ellipsis.Omit));
|
|
480
|
-
cached = { key, lines: result };
|
|
481
|
-
return result;
|
|
482
|
-
},
|
|
483
|
-
invalidate() {
|
|
484
|
-
cached = undefined;
|
|
485
|
-
},
|
|
486
|
-
};
|
|
487
|
-
},
|
|
488
|
-
mergeCallAndResult: true,
|
|
489
|
-
};
|
|
342
|
+
interface GrepRenderArgs {
|
|
343
|
+
pattern: string;
|
|
344
|
+
path?: string;
|
|
345
|
+
glob?: string;
|
|
346
|
+
type?: string;
|
|
347
|
+
i?: boolean;
|
|
348
|
+
pre?: number;
|
|
349
|
+
post?: number;
|
|
350
|
+
multiline?: boolean;
|
|
351
|
+
limit?: number;
|
|
352
|
+
offset?: number;
|
|
353
|
+
}
|
package/src/tools/index.ts
CHANGED
|
@@ -1,44 +1,19 @@
|
|
|
1
1
|
import type { AgentTool } from "@nghyane/arcane-agent";
|
|
2
|
-
import { createCodeTool } from "@nghyane/arcane-codemode";
|
|
3
|
-
import { $env, logger } from "@nghyane/arcane-utils";
|
|
4
2
|
import type { PromptTemplate } from "../config/prompt-templates";
|
|
5
3
|
import type { Settings } from "../config/settings";
|
|
6
4
|
import type { Skill } from "../extensibility/skills";
|
|
7
5
|
import type { InternalUrlRouter } from "../internal-urls";
|
|
8
|
-
import { getPreludeDocs, warmPythonEnvironment } from "../ipy/executor";
|
|
9
|
-
import { checkPythonKernelAvailability } from "../ipy/kernel";
|
|
10
|
-
import { LspTool } from "../lsp";
|
|
11
|
-
import { EditTool } from "../patch";
|
|
12
6
|
import type { ArtifactManager } from "../session/artifacts";
|
|
13
|
-
import { TaskTool } from "../task";
|
|
14
7
|
import type { AgentOutputManager } from "../task/output-manager";
|
|
15
8
|
import type { EventBus } from "../utils/event-bus";
|
|
16
|
-
import { time } from "../utils/timings";
|
|
17
|
-
import { SearchTool } from "../web/search";
|
|
18
|
-
import { AskTool } from "./ask";
|
|
19
|
-
import { BashTool } from "./bash";
|
|
20
|
-
import { BrowserTool } from "./browser";
|
|
21
|
-
import { CalculatorTool } from "./calculator";
|
|
22
|
-
import { ExploreTool } from "./explore";
|
|
23
|
-
import { FetchTool } from "./fetch";
|
|
24
|
-
import { FindTool } from "./find";
|
|
25
|
-
import { GrepTool } from "./grep";
|
|
26
|
-
import { LibrarianTool } from "./librarian";
|
|
27
|
-
import { NotebookTool } from "./notebook";
|
|
28
|
-
import { OracleTool } from "./oracle";
|
|
29
|
-
import { wrapToolWithMetaNotice } from "./output-meta";
|
|
30
|
-
import { PythonTool } from "./python";
|
|
31
|
-
import { ReadTool } from "./read";
|
|
32
|
-
import { ReviewerTool } from "./reviewer-tool";
|
|
33
|
-
import { loadSshTool } from "./ssh";
|
|
34
|
-
import { TodoWriteTool } from "./todo-write";
|
|
35
|
-
import { UndoEditTool } from "./undo-edit";
|
|
36
|
-
import { WriteTool } from "./write";
|
|
37
9
|
|
|
38
10
|
// Exa MCP tools (22 tools)
|
|
39
11
|
|
|
40
|
-
export {
|
|
41
|
-
|
|
12
|
+
export type {
|
|
13
|
+
ExaRenderDetails,
|
|
14
|
+
ExaSearchResponse,
|
|
15
|
+
ExaSearchResult,
|
|
16
|
+
} from "../exa/types";
|
|
42
17
|
export {
|
|
43
18
|
type FileDiagnosticsResult,
|
|
44
19
|
type FileFormatResult,
|
|
@@ -79,21 +54,42 @@ export {
|
|
|
79
54
|
webSearchLinkedinTool,
|
|
80
55
|
} from "../web/search";
|
|
81
56
|
export { AskTool, type AskToolDetails } from "./ask";
|
|
82
|
-
export {
|
|
57
|
+
export {
|
|
58
|
+
BashTool,
|
|
59
|
+
type BashToolDetails,
|
|
60
|
+
type BashToolInput,
|
|
61
|
+
type BashToolOptions,
|
|
62
|
+
} from "./bash";
|
|
83
63
|
export { BrowserTool, type BrowserToolDetails } from "./browser";
|
|
84
|
-
export {
|
|
85
|
-
export { ExploreTool } from "./explore";
|
|
64
|
+
export { exploreConfig } from "./explore";
|
|
86
65
|
export { FetchTool, type FetchToolDetails } from "./fetch";
|
|
87
|
-
export {
|
|
66
|
+
export {
|
|
67
|
+
type FindOperations,
|
|
68
|
+
FindTool,
|
|
69
|
+
type FindToolDetails,
|
|
70
|
+
type FindToolInput,
|
|
71
|
+
type FindToolOptions,
|
|
72
|
+
} from "./find";
|
|
88
73
|
export { setPreferredImageProvider } from "./gemini-image";
|
|
74
|
+
export { GitHubTool, type GitHubToolDetails } from "./github";
|
|
89
75
|
export { GrepTool, type GrepToolDetails, type GrepToolInput } from "./grep";
|
|
90
|
-
export {
|
|
76
|
+
export { librarianConfig } from "./librarian";
|
|
91
77
|
export { NotebookTool, type NotebookToolDetails } from "./notebook";
|
|
92
|
-
export {
|
|
93
|
-
export {
|
|
78
|
+
export { oracleConfig } from "./oracle";
|
|
79
|
+
export {
|
|
80
|
+
PythonTool,
|
|
81
|
+
type PythonToolDetails,
|
|
82
|
+
type PythonToolOptions,
|
|
83
|
+
} from "./python";
|
|
94
84
|
export { ReadTool, type ReadToolDetails, type ReadToolInput } from "./read";
|
|
85
|
+
export { reviewerConfig } from "./reviewer-tool";
|
|
95
86
|
export { loadSshTool, type SSHToolDetails, SshTool } from "./ssh";
|
|
96
|
-
export { type
|
|
87
|
+
export { type SubagentConfig, SubagentTool } from "./subagent-tool";
|
|
88
|
+
export {
|
|
89
|
+
type TodoItem,
|
|
90
|
+
TodoWriteTool,
|
|
91
|
+
type TodoWriteToolDetails,
|
|
92
|
+
} from "./todo-write";
|
|
97
93
|
export { UndoEditTool, type UndoEditToolDetails } from "./undo-edit";
|
|
98
94
|
export { WriteTool, type WriteToolDetails, type WriteToolInput } from "./write";
|
|
99
95
|
|
|
@@ -144,8 +140,6 @@ export interface ToolSession {
|
|
|
144
140
|
artifactManager?: ArtifactManager;
|
|
145
141
|
/** Get artifacts directory for artifact:// URLs and $ARTIFACTS env var */
|
|
146
142
|
getArtifactsDir?: () => string | null;
|
|
147
|
-
/** Get session spawns */
|
|
148
|
-
getSessionSpawns: () => string | null;
|
|
149
143
|
/** Get resolved model string if explicitly set for this session */
|
|
150
144
|
getModelString?: () => string | undefined;
|
|
151
145
|
/** Get the current session model string, regardless of how it was chosen */
|
|
@@ -160,161 +154,4 @@ export interface ToolSession {
|
|
|
160
154
|
settings: Settings;
|
|
161
155
|
}
|
|
162
156
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
export const BUILTIN_TOOLS: Record<string, ToolFactory> = {
|
|
166
|
-
ask: AskTool.createIf,
|
|
167
|
-
bash: s => new BashTool(s),
|
|
168
|
-
python: s => new PythonTool(s),
|
|
169
|
-
calc: s => new CalculatorTool(s),
|
|
170
|
-
ssh: loadSshTool,
|
|
171
|
-
edit: s => new EditTool(s),
|
|
172
|
-
find: s => new FindTool(s),
|
|
173
|
-
explore: s => new ExploreTool(s),
|
|
174
|
-
grep: s => new GrepTool(s),
|
|
175
|
-
librarian: s => new LibrarianTool(s),
|
|
176
|
-
lsp: LspTool.createIf,
|
|
177
|
-
notebook: s => new NotebookTool(s),
|
|
178
|
-
oracle: s => new OracleTool(s),
|
|
179
|
-
read: s => new ReadTool(s),
|
|
180
|
-
browser: s => new BrowserTool(s),
|
|
181
|
-
task: TaskTool.create,
|
|
182
|
-
code_review: s => new ReviewerTool(s),
|
|
183
|
-
todo_write: s => new TodoWriteTool(s),
|
|
184
|
-
undo_edit: s => new UndoEditTool(s),
|
|
185
|
-
fetch: s => new FetchTool(s),
|
|
186
|
-
web_search: s => new SearchTool(s),
|
|
187
|
-
write: s => new WriteTool(s),
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
export type ToolName = keyof typeof BUILTIN_TOOLS;
|
|
191
|
-
|
|
192
|
-
export type PythonToolMode = "ipy-only" | "bash-only" | "both";
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Parse ARCANE_PY environment variable to determine Python tool mode.
|
|
196
|
-
* Returns null if not set or invalid.
|
|
197
|
-
*
|
|
198
|
-
* Values:
|
|
199
|
-
* - "0" or "bash" → bash-only
|
|
200
|
-
* - "1" or "py" → ipy-only
|
|
201
|
-
* - "mix" or "both" → both
|
|
202
|
-
*/
|
|
203
|
-
function getPythonModeFromEnv(): PythonToolMode | null {
|
|
204
|
-
const value = $env.ARCANE_PY?.toLowerCase();
|
|
205
|
-
if (!value) return null;
|
|
206
|
-
|
|
207
|
-
switch (value) {
|
|
208
|
-
case "0":
|
|
209
|
-
case "bash":
|
|
210
|
-
return "bash-only";
|
|
211
|
-
case "1":
|
|
212
|
-
case "py":
|
|
213
|
-
return "ipy-only";
|
|
214
|
-
case "mix":
|
|
215
|
-
case "both":
|
|
216
|
-
return "both";
|
|
217
|
-
default:
|
|
218
|
-
return null;
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* Create tools from BUILTIN_TOOLS registry.
|
|
224
|
-
*/
|
|
225
|
-
export async function createTools(session: ToolSession, toolNames?: string[]): Promise<Tool[]> {
|
|
226
|
-
time("createTools:start");
|
|
227
|
-
const enableLsp = session.enableLsp ?? true;
|
|
228
|
-
const requestedTools = toolNames && toolNames.length > 0 ? [...new Set(toolNames)] : undefined;
|
|
229
|
-
const pythonMode = getPythonModeFromEnv() ?? session.settings.get("python.toolMode");
|
|
230
|
-
const skipPythonPreflight = session.skipPythonPreflight === true;
|
|
231
|
-
let pythonAvailable = true;
|
|
232
|
-
const shouldCheckPython =
|
|
233
|
-
!skipPythonPreflight &&
|
|
234
|
-
pythonMode !== "bash-only" &&
|
|
235
|
-
(requestedTools === undefined || requestedTools.includes("python"));
|
|
236
|
-
const isTestEnv = Bun.env.BUN_ENV === "test" || Bun.env.NODE_ENV === "test";
|
|
237
|
-
const skipPythonWarm = isTestEnv || $env.ARCANE_PYTHON_SKIP_CHECK === "1";
|
|
238
|
-
if (shouldCheckPython) {
|
|
239
|
-
const availability = await checkPythonKernelAvailability(session.cwd);
|
|
240
|
-
time("createTools:pythonCheck");
|
|
241
|
-
pythonAvailable = availability.ok;
|
|
242
|
-
if (!availability.ok) {
|
|
243
|
-
logger.warn("Python kernel unavailable, falling back to bash", {
|
|
244
|
-
reason: availability.reason,
|
|
245
|
-
});
|
|
246
|
-
} else if (!skipPythonWarm && getPreludeDocs().length === 0) {
|
|
247
|
-
const sessionFile = session.getSessionFile?.() ?? undefined;
|
|
248
|
-
const warmSessionId = sessionFile ? `session:${sessionFile}:cwd:${session.cwd}` : `cwd:${session.cwd}`;
|
|
249
|
-
try {
|
|
250
|
-
await warmPythonEnvironment(session.cwd, warmSessionId, session.settings.get("python.sharedGateway"));
|
|
251
|
-
time("createTools:warmPython");
|
|
252
|
-
} catch (err) {
|
|
253
|
-
logger.warn("Failed to warm Python environment", {
|
|
254
|
-
error: err instanceof Error ? err.message : String(err),
|
|
255
|
-
});
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
const effectiveMode = pythonAvailable ? pythonMode : "bash-only";
|
|
261
|
-
const allowBash = effectiveMode !== "ipy-only";
|
|
262
|
-
const allowPython = effectiveMode !== "bash-only";
|
|
263
|
-
if (
|
|
264
|
-
requestedTools &&
|
|
265
|
-
allowBash &&
|
|
266
|
-
!allowPython &&
|
|
267
|
-
requestedTools.includes("python") &&
|
|
268
|
-
!requestedTools.includes("bash")
|
|
269
|
-
) {
|
|
270
|
-
requestedTools.push("bash");
|
|
271
|
-
}
|
|
272
|
-
const allTools: Record<string, ToolFactory> = { ...BUILTIN_TOOLS };
|
|
273
|
-
const isToolAllowed = (name: string) => {
|
|
274
|
-
if (name === "lsp") return enableLsp;
|
|
275
|
-
if (name === "bash") return allowBash;
|
|
276
|
-
if (name === "python") return allowPython;
|
|
277
|
-
if (name === "todo_write") return session.settings.get("todo.enabled");
|
|
278
|
-
if (name === "find") return session.settings.get("find.enabled");
|
|
279
|
-
if (name === "grep") return session.settings.get("grep.enabled");
|
|
280
|
-
if (name === "notebook") return session.settings.get("notebook.enabled");
|
|
281
|
-
if (name === "fetch") return session.settings.get("fetch.enabled");
|
|
282
|
-
if (name === "web_search") return session.settings.get("web_search.enabled");
|
|
283
|
-
if (name === "lsp") return session.settings.get("lsp.enabled");
|
|
284
|
-
if (name === "calc") return session.settings.get("calc.enabled");
|
|
285
|
-
if (name === "browser") return session.settings.get("browser.enabled");
|
|
286
|
-
if (name === "librarian") return session.settings.get("librarian.enabled");
|
|
287
|
-
if (name === "oracle") return session.settings.get("oracle.enabled");
|
|
288
|
-
if (name === "task") {
|
|
289
|
-
return !session.isSubagent;
|
|
290
|
-
}
|
|
291
|
-
return true;
|
|
292
|
-
};
|
|
293
|
-
|
|
294
|
-
const filteredRequestedTools = requestedTools?.filter(name => name in allTools && isToolAllowed(name));
|
|
295
|
-
|
|
296
|
-
const entries =
|
|
297
|
-
filteredRequestedTools !== undefined
|
|
298
|
-
? filteredRequestedTools.map(name => [name, allTools[name]] as const)
|
|
299
|
-
: [...Object.entries(BUILTIN_TOOLS).filter(([name]) => isToolAllowed(name))];
|
|
300
|
-
|
|
301
|
-
const results = await Promise.all(
|
|
302
|
-
entries.map(async ([name, factory]) => {
|
|
303
|
-
if (filteredRequestedTools && !filteredRequestedTools.includes(name)) {
|
|
304
|
-
return null;
|
|
305
|
-
}
|
|
306
|
-
const tool = await factory(session);
|
|
307
|
-
time(`createTools:${name}`);
|
|
308
|
-
return tool ? wrapToolWithMetaNotice(tool) : null;
|
|
309
|
-
}),
|
|
310
|
-
);
|
|
311
|
-
const tools = results.filter((r): r is Tool => r !== null);
|
|
312
|
-
|
|
313
|
-
// Code Mode: wrap all eligible tools into a single "code" tool
|
|
314
|
-
if (session.settings.get("codemode.enabled")) {
|
|
315
|
-
const { codeTool, excludedTools } = createCodeTool(tools);
|
|
316
|
-
return [codeTool as Tool, ...(excludedTools as Tool[])];
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
return tools;
|
|
320
|
-
}
|
|
157
|
+
export { BUILTIN_TOOLS, createTools, type ToolName } from "./create-tools";
|
package/src/tools/json-tree.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* JSON tree rendering utilities shared across tool renderers.
|
|
3
3
|
*/
|
|
4
|
-
import type { Theme } from "../
|
|
5
|
-
import { truncateToWidth } from "
|
|
4
|
+
import type { Theme } from "../theme/theme";
|
|
5
|
+
import { truncateToWidth } from "../ui/render-utils";
|
|
6
6
|
|
|
7
7
|
/** Max depth for JSON tree rendering */
|
|
8
8
|
export const JSON_TREE_MAX_DEPTH_COLLAPSED = 2;
|
|
@@ -15,7 +15,7 @@ export const JSON_TREE_SCALAR_LEN_EXPANDED = 2000;
|
|
|
15
15
|
/**
|
|
16
16
|
* Format a scalar value for inline display.
|
|
17
17
|
*/
|
|
18
|
-
|
|
18
|
+
function formatScalar(value: unknown, maxLen: number): string {
|
|
19
19
|
if (value === null) return "null";
|
|
20
20
|
if (value === undefined) return "undefined";
|
|
21
21
|
if (typeof value === "boolean") return String(value);
|
package/src/tools/librarian.ts
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
import { Type } from "@sinclair/typebox";
|
|
2
|
-
import
|
|
3
|
-
import { createSubagentTool } from "./subagent-tool";
|
|
2
|
+
import type { SubagentConfig } from "./subagent-tool";
|
|
4
3
|
|
|
5
4
|
const schema = Type.Object({
|
|
6
|
-
query: Type.String({
|
|
7
|
-
|
|
8
|
-
"Your question about the codebase or repository. Be specific about what you want to understand or explore.",
|
|
9
|
-
}),
|
|
10
|
-
context: Type.Optional(
|
|
11
|
-
Type.String({
|
|
12
|
-
description: "Background about what you're trying to achieve.",
|
|
13
|
-
}),
|
|
14
|
-
),
|
|
5
|
+
query: Type.String({ description: "What to look up across repositories" }),
|
|
6
|
+
context: Type.Optional(Type.String({ description: "Additional context for the search" })),
|
|
15
7
|
});
|
|
16
8
|
|
|
17
9
|
function buildTask(p: Record<string, unknown>): string {
|
|
18
|
-
|
|
19
|
-
if (p.context)
|
|
20
|
-
return
|
|
10
|
+
const parts: string[] = [p.query as string];
|
|
11
|
+
if (p.context) parts.push(`\nContext: ${p.context}`);
|
|
12
|
+
return parts.join("\n");
|
|
21
13
|
}
|
|
22
14
|
|
|
23
|
-
export const
|
|
15
|
+
export const librarianConfig: SubagentConfig<typeof schema.properties> = {
|
|
24
16
|
name: "librarian",
|
|
25
17
|
label: "Librarian",
|
|
26
18
|
agent: "librarian",
|
|
27
19
|
schema,
|
|
28
|
-
descriptionTemplate: librarianDescription,
|
|
29
20
|
progressText: "Exploring repositories...",
|
|
30
21
|
tmpPrefix: "arc-librarian-",
|
|
31
22
|
buildTask,
|
|
32
|
-
buildDescription: p =>
|
|
33
|
-
|
|
23
|
+
buildDescription: p => String(p.query ?? "").slice(0, 80),
|
|
24
|
+
buildContextLine: p => {
|
|
25
|
+
if (!p.context) return null;
|
|
26
|
+
return `Context: ${String(p.context).split("\n")[0].slice(0, 60)}`;
|
|
27
|
+
},
|
|
28
|
+
toolDescription: [
|
|
29
|
+
"Explore remote GitHub repositories — cross-repo code search, reading files/PRs/issues, tracing commit history, finding implementation examples across public repos.",
|
|
30
|
+
"WHEN TO USE: Cross-repo code search; reading remote files; tracing PRs/issues/commits; finding how other projects solve similar problems.",
|
|
31
|
+
"WHEN NOT TO USE: Local codebase search (use explore/grep); quick single-file/issue lookups (use github directly).",
|
|
32
|
+
].join(" "),
|
|
33
|
+
};
|
package/src/tools/list-limit.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { LimitsMeta } from "./output-meta";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
interface ListLimitResult<T> {
|
|
4
4
|
items: T[];
|
|
5
5
|
limitReached?: number;
|
|
6
6
|
meta: Partial<LimitsMeta>;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
interface ListLimitOptions {
|
|
10
10
|
limit?: number;
|
|
11
11
|
headLimit?: number;
|
|
12
12
|
limitType?: "match" | "result";
|