indusagi 0.12.34 → 0.13.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/agent.js +1247 -184
- package/dist/ai.js +72 -4
- package/dist/capabilities.js +69 -2
- package/dist/cli.js +83 -13
- package/dist/connectors-saas.js +66 -0
- package/dist/index.js +83 -13
- package/dist/interop.js +66 -0
- package/dist/mcp.js +270 -363
- package/dist/react-ink.js +15 -11
- package/dist/shell-app.js +83 -13
- package/dist/smithy.js +69 -2
- package/dist/swarm.js +69 -2
- package/dist/types/capabilities/backends/node-backends.d.ts +3 -1
- package/dist/types/capabilities/files/read-state-gate.d.ts +69 -0
- package/dist/types/capabilities/files/read-state-gate.test.d.ts +14 -0
- package/dist/types/capabilities/kernel/context.d.ts +4 -0
- package/dist/types/capabilities/kernel/index.d.ts +2 -2
- package/dist/types/capabilities/kernel/spec.d.ts +55 -0
- package/dist/types/facade/bot/actions/bash.d.ts +15 -0
- package/dist/types/facade/bot/actions/bash.test.d.ts +1 -0
- package/dist/types/facade/bot/actions/checkpoint.d.ts +49 -0
- package/dist/types/facade/bot/actions/checkpoint.test.d.ts +1 -0
- package/dist/types/facade/bot/actions/edit-utils.d.ts +86 -0
- package/dist/types/facade/bot/actions/edit.d.ts +18 -0
- package/dist/types/facade/bot/actions/edit.test.d.ts +1 -0
- package/dist/types/facade/bot/actions/find.d.ts +2 -0
- package/dist/types/facade/bot/actions/find.test.d.ts +1 -0
- package/dist/types/facade/bot/actions/grep.d.ts +10 -0
- package/dist/types/facade/bot/actions/grep.test.d.ts +1 -0
- package/dist/types/facade/bot/actions/index.d.ts +16 -0
- package/dist/types/facade/bot/actions/read-state.d.ts +83 -0
- package/dist/types/facade/bot/actions/read-state.test.d.ts +1 -0
- package/dist/types/facade/bot/actions/read.d.ts +7 -0
- package/dist/types/facade/bot/actions/read.test.d.ts +1 -0
- package/dist/types/facade/bot/actions/sandbox-backend.d.ts +99 -0
- package/dist/types/facade/bot/actions/sandbox-backend.test.d.ts +1 -0
- package/dist/types/facade/bot/actions/websearch.d.ts +5 -2
- package/dist/types/facade/bot/actions/websearch.test.d.ts +1 -0
- package/dist/types/facade/bot/actions/write.d.ts +15 -0
- package/dist/types/facade/bot/agent-loop.d.ts +10 -0
- package/dist/types/facade/bot/agent-loop.test.d.ts +1 -0
- package/dist/types/facade/bot/agent.d.ts +9 -1
- package/dist/types/facade/bot/permission-gate.test.d.ts +1 -0
- package/dist/types/facade/bot/types.d.ts +60 -0
- package/dist/types/facade/mcp-core/client.d.ts +71 -15
- package/dist/types/facade/mcp-core/client.test.d.ts +18 -0
- package/dist/types/facade/mcp-core/types.d.ts +10 -0
- package/dist/types/facade/ml/adapters/anthropic-retry.test.d.ts +1 -0
- package/dist/types/facade/ml/adapters/anthropic.d.ts +17 -0
- package/dist/types/facade/ml/adapters/simple-options.d.ts +13 -0
- package/dist/types/facade/ml/adapters/simple-options.test.d.ts +1 -0
- package/dist/types/react-ink/components/StatusLine.d.ts +10 -1
- package/dist/types/react-ink/components/ToolEventBlock.d.ts +2 -1
- package/dist/types/react-ink/components/ToolEventBlock.test.d.ts +1 -0
- package/package.json +1 -1
|
@@ -40,12 +40,63 @@ export interface ToolResult {
|
|
|
40
40
|
readonly content: ToolContentBlock[];
|
|
41
41
|
readonly isError?: boolean;
|
|
42
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* The per-session record a {@link ReadStateHandle} keeps for one file.
|
|
45
|
+
*
|
|
46
|
+
* It captures just enough to detect that a file has drifted on disk since it was
|
|
47
|
+
* last read: the floored modification time and byte size at read time, an
|
|
48
|
+
* optional content hash for a future exact-match fallback, and the wall-clock
|
|
49
|
+
* moment the read happened. The handle keys these by absolute path.
|
|
50
|
+
*/
|
|
51
|
+
export interface ReadStateRecord {
|
|
52
|
+
/** Last-modified time at read, epoch milliseconds (floored). */
|
|
53
|
+
readonly mtimeMs: number;
|
|
54
|
+
/** Byte size at read time. */
|
|
55
|
+
readonly size: number;
|
|
56
|
+
/** Optional content hash for an exact-equality fallback; absent today. */
|
|
57
|
+
readonly contentHash?: string;
|
|
58
|
+
/** Wall-clock moment the read was recorded, epoch milliseconds. */
|
|
59
|
+
readonly readAt: number;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The minimal, duck-typed handle a host may stash on {@link ToolContext.framework}
|
|
63
|
+
* under {@link READ_STATE_HANDLE_KEY} to enable the read-before-edit gate.
|
|
64
|
+
*
|
|
65
|
+
* Deliberately tiny — `get` / `set` / `has` keyed by absolute path — so the
|
|
66
|
+
* framework consumer and the product injector can agree on the *shape* without a
|
|
67
|
+
* cross-package type import. The product supplies a concrete store; the framework
|
|
68
|
+
* only ever reads/writes through these three methods.
|
|
69
|
+
*/
|
|
70
|
+
export interface ReadStateHandle {
|
|
71
|
+
/** The recorded state for a path, or undefined if it was never read. */
|
|
72
|
+
get(absPath: string): ReadStateRecord | undefined;
|
|
73
|
+
/** Record (or refresh) the state for a path. */
|
|
74
|
+
set(absPath: string, record: ReadStateRecord): void;
|
|
75
|
+
/** Whether a path has any recorded read state this session. */
|
|
76
|
+
has(absPath: string): boolean;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The string-literal key under which a {@link ReadStateHandle} lives on
|
|
80
|
+
* {@link ToolContext.framework}.
|
|
81
|
+
*
|
|
82
|
+
* Mirrors the existing `DELEGATE_HANDLE_KEY = "delegate"` /
|
|
83
|
+
* `MEMORY_HANDLE_KEY = "memoryStore"` convention: a shared literal both the
|
|
84
|
+
* framework consumer and the product injector reference so they agree without a
|
|
85
|
+
* cross-package type import.
|
|
86
|
+
*/
|
|
87
|
+
export declare const READ_STATE_HANDLE_KEY: "readState";
|
|
43
88
|
/**
|
|
44
89
|
* Everything a tool's `run` is handed besides its own parsed input.
|
|
45
90
|
*
|
|
46
91
|
* It carries the working directory, the two coarse I/O backends, a cancellation
|
|
47
92
|
* `signal`, and the default {@link OutputBudget} a tool should apply when its
|
|
48
93
|
* output risks overflowing the model's window.
|
|
94
|
+
*
|
|
95
|
+
* `framework` is an open bag of optional host-injected handles, keyed by string
|
|
96
|
+
* literals (e.g. {@link READ_STATE_HANDLE_KEY}). It is the additive seam through
|
|
97
|
+
* which a host can opt a session into behaviors like the read-before-edit gate
|
|
98
|
+
* without changing any tool signature; when a handle is absent the tools behave
|
|
99
|
+
* exactly as they did before.
|
|
49
100
|
*/
|
|
50
101
|
export interface ToolContext {
|
|
51
102
|
readonly cwd: string;
|
|
@@ -53,6 +104,10 @@ export interface ToolContext {
|
|
|
53
104
|
readonly shell: Shell;
|
|
54
105
|
readonly signal: AbortSignal;
|
|
55
106
|
readonly budget: OutputBudget;
|
|
107
|
+
/** Open record of optional, host-injected framework handles. */
|
|
108
|
+
readonly framework?: {
|
|
109
|
+
readonly [key: string]: unknown;
|
|
110
|
+
};
|
|
56
111
|
}
|
|
57
112
|
/**
|
|
58
113
|
* The declarative description of one tool.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AgentTool } from "../types.js";
|
|
2
2
|
import type { HookRunner } from "./kit/hook-runner.js";
|
|
3
|
+
import { type SandboxConfig } from "./sandbox-backend.js";
|
|
3
4
|
import { type TruncationResult } from "./truncate.js";
|
|
4
5
|
export interface BashSecurityConfig {
|
|
5
6
|
/** Patterns that, when matched, stop a command from running. */
|
|
@@ -44,8 +45,22 @@ export interface BashToolOptions {
|
|
|
44
45
|
hookRunner?: HookRunner;
|
|
45
46
|
/** Settings that decide which commands are allowed to run. */
|
|
46
47
|
security?: BashSecurityConfig;
|
|
48
|
+
/**
|
|
49
|
+
* OPT-IN OS sandbox. OFF by default: when omitted or `enabled` is false the
|
|
50
|
+
* bash tool spawns exactly as before. When enabled, each command is wrapped
|
|
51
|
+
* in the platform's OS sandbox (macOS `sandbox-exec`, Linux `bwrap`); if no
|
|
52
|
+
* sandbox tool is available the command runs un-sandboxed and a note is
|
|
53
|
+
* recorded via `onSandboxNote` rather than silently claiming sandboxing.
|
|
54
|
+
*/
|
|
55
|
+
sandbox?: SandboxConfig;
|
|
56
|
+
/** Receives an honest note describing whether the sandbox was applied or skipped. */
|
|
57
|
+
onSandboxNote?: (note: string) => void;
|
|
47
58
|
/** Optional log that collects the commands as they are issued. */
|
|
48
59
|
commandHistory?: string[];
|
|
60
|
+
/** Time budget, in seconds, applied when the model omits `timeout`. Defaults to 120s. */
|
|
61
|
+
defaultTimeoutSeconds?: number;
|
|
62
|
+
/** Hard ceiling, in seconds, that any supplied `timeout` is clamped to. Defaults to 600s (and is never lower than the default). */
|
|
63
|
+
maxTimeoutSeconds?: number;
|
|
49
64
|
}
|
|
50
65
|
export declare function createBashTool(cwd: string, options?: BashToolOptions): AgentTool<typeof bashSchema>;
|
|
51
66
|
/** Ready-made bash tool bound to the process working directory. */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File-checkpoint hook for the WIRED facade tool layer.
|
|
3
|
+
*
|
|
4
|
+
* This is the framework half of the rewind feature. The product (the coding
|
|
5
|
+
* agent) constructs a `CheckpointStore`, exposes a small duck-typed
|
|
6
|
+
* {@link CheckpointHandle} on the shared `ctx.framework` bag under the literal
|
|
7
|
+
* key `'checkpoint'`, and passes it into the `write` / `edit` factories — the
|
|
8
|
+
* same place the read-before-edit gate's `readState` handle is wired. When a
|
|
9
|
+
* handle is present, every mutating file tool captures the file's pre-mutation
|
|
10
|
+
* on-disk content EXACTLY ONCE per mutated path, so a later rewind can roll the
|
|
11
|
+
* working tree back to that snapshot.
|
|
12
|
+
*
|
|
13
|
+
* Like the read-edit gate, the whole mechanism is *additive*: with no handle
|
|
14
|
+
* present every helper here is a no-op and the tools behave exactly as they did
|
|
15
|
+
* before. The handle is duck-typed so the host and these factories agree on
|
|
16
|
+
* shape without a cross-package type import.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Duck-typed sink the host injects to receive pre-mutation snapshots.
|
|
20
|
+
*
|
|
21
|
+
* `record` is called once per mutated path, before the write lands, with the
|
|
22
|
+
* file's OLD on-disk content — or `null` when the file did not exist on disk
|
|
23
|
+
* before this mutation (so a rewind that visits this snapshot knows to DELETE
|
|
24
|
+
* the file rather than restore stale bytes).
|
|
25
|
+
*/
|
|
26
|
+
export interface CheckpointHandle {
|
|
27
|
+
/**
|
|
28
|
+
* Capture the pre-mutation state of `absPath`.
|
|
29
|
+
*
|
|
30
|
+
* @param absPath Absolute path of the file about to be written.
|
|
31
|
+
* @param previous The file's content before this mutation, or `null` if the
|
|
32
|
+
* file did not exist on disk beforehand.
|
|
33
|
+
*/
|
|
34
|
+
record(absPath: string, previous: string | null): void;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Read the CURRENT on-disk content of `absPath` and hand it to the checkpoint
|
|
38
|
+
* handle, capturing the PRE-mutation state.
|
|
39
|
+
*
|
|
40
|
+
* This MUST be invoked synchronously-ordered immediately before the write so the
|
|
41
|
+
* captured snapshot is the OLD content (no read/write race). When the file does
|
|
42
|
+
* not exist on disk, `null` is recorded so a rewind knows to delete it.
|
|
43
|
+
*
|
|
44
|
+
* No-op when no handle is present. A read/stat failure that is NOT a plain
|
|
45
|
+
* "missing file" is swallowed: checkpointing is best-effort and must never mask
|
|
46
|
+
* the real operation's outcome. (A genuine ENOENT is reported as `null`, the
|
|
47
|
+
* meaningful "file absent" snapshot.)
|
|
48
|
+
*/
|
|
49
|
+
export declare function recordCheckpoint(handle: CheckpointHandle | undefined, absPath: string): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Precision helpers for the edit tool. None of these change the default
|
|
3
|
+
* behaviour of an edit — they kick in only on the recovery / preservation
|
|
4
|
+
* paths:
|
|
5
|
+
*
|
|
6
|
+
* - {@link preserveQuoteStyle} re-applies a file's curly-quote typography to
|
|
7
|
+
* replacement text when the match was found only after folding curly quotes
|
|
8
|
+
* to straight ones, so an edit doesn't quietly downgrade `"` → `“`.
|
|
9
|
+
* - {@link desanitizeMatchString} repairs the handful of tag tokens an API
|
|
10
|
+
* transport may mangle (`<o>` → `<output>`, `\n\nH:` → `\n\nHuman:`, …) so a
|
|
11
|
+
* snippet that lost its angle-bracket words can still be located. It is only
|
|
12
|
+
* ever used as a *fallback* (try the literal text first) because several of
|
|
13
|
+
* the rules collide with ordinary code.
|
|
14
|
+
* - {@link findSimilarFile} and {@link suggestPathUnderCwd} build the "did you
|
|
15
|
+
* mean …?" hint when a path doesn't resolve.
|
|
16
|
+
* - {@link replaceAllLiteral} swaps every non-overlapping literal occurrence of
|
|
17
|
+
* a needle, used for the `replaceAll` edit mode.
|
|
18
|
+
*
|
|
19
|
+
* Everything here is pure / node-fs only and carries no dependency on the rest
|
|
20
|
+
* of the edit pipeline.
|
|
21
|
+
*/
|
|
22
|
+
export declare const LEFT_SINGLE_CURLY_QUOTE = "\u2018";
|
|
23
|
+
export declare const RIGHT_SINGLE_CURLY_QUOTE = "\u2019";
|
|
24
|
+
export declare const LEFT_DOUBLE_CURLY_QUOTE = "\u201C";
|
|
25
|
+
export declare const RIGHT_DOUBLE_CURLY_QUOTE = "\u201D";
|
|
26
|
+
/**
|
|
27
|
+
* When `oldText` only matched the file after curly quotes were folded to
|
|
28
|
+
* straight quotes, re-apply the file's curly typography to `newString` so the
|
|
29
|
+
* edit preserves the original quote style. A no-op when `oldString` already
|
|
30
|
+
* equals the matched text (no folding happened) or when the matched text holds
|
|
31
|
+
* no curly quotes.
|
|
32
|
+
*
|
|
33
|
+
* @param oldString The text the model supplied (straight quotes).
|
|
34
|
+
* @param actualOldString The text actually located in the file (may be curly).
|
|
35
|
+
* @param newString The replacement text the model supplied (straight quotes).
|
|
36
|
+
*/
|
|
37
|
+
export declare function preserveQuoteStyle(oldString: string, actualOldString: string, newString: string): string;
|
|
38
|
+
/**
|
|
39
|
+
* Tag tokens an API transport sometimes mangles, mapped back to their full
|
|
40
|
+
* form. Several of these (`<n>`, `\n\nH:`) appear in ordinary source, so the
|
|
41
|
+
* table must only ever be consulted as a *fallback* after a literal match
|
|
42
|
+
* misses — never preemptively.
|
|
43
|
+
*/
|
|
44
|
+
export declare const DESANITIZATIONS: Record<string, string>;
|
|
45
|
+
/**
|
|
46
|
+
* Expand any mangled tag tokens in `matchString`, reporting which replacements
|
|
47
|
+
* fired so the caller can mirror them onto the replacement text.
|
|
48
|
+
*/
|
|
49
|
+
export declare function desanitizeMatchString(matchString: string): {
|
|
50
|
+
result: string;
|
|
51
|
+
appliedReplacements: Array<{
|
|
52
|
+
from: string;
|
|
53
|
+
to: string;
|
|
54
|
+
}>;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Look in `filePath`'s directory for a file that shares its base name but has a
|
|
58
|
+
* different extension (e.g. `foo.ts` when `foo.js` was requested). Returns the
|
|
59
|
+
* sibling's bare filename, or `undefined` when there is no such neighbour.
|
|
60
|
+
*/
|
|
61
|
+
export declare function findSimilarFile(filePath: string): string | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* Marker embedded in file-not-found messages that carry a cwd note. A UI
|
|
64
|
+
* renderer can key off this to collapse the long message into a short
|
|
65
|
+
* "File not found" badge.
|
|
66
|
+
*/
|
|
67
|
+
export declare const FILE_NOT_FOUND_CWD_NOTE = "Note: your current working directory is";
|
|
68
|
+
/**
|
|
69
|
+
* Suggest a corrected path under `cwd` when an absolute path doesn't resolve.
|
|
70
|
+
* Catches the "dropped repo folder" pattern: the model builds an absolute path
|
|
71
|
+
* that sits beside the repo rather than inside it.
|
|
72
|
+
*
|
|
73
|
+
* cwd = /Users/x/src/currentRepo
|
|
74
|
+
* requestedPath = /Users/x/src/foobar (missing)
|
|
75
|
+
* returns /Users/x/src/currentRepo/foobar (when it exists)
|
|
76
|
+
*
|
|
77
|
+
* @param requestedPath The absolute path that was not found.
|
|
78
|
+
* @param cwd The working directory to re-root the suggestion under.
|
|
79
|
+
*/
|
|
80
|
+
export declare function suggestPathUnderCwd(requestedPath: string, cwd: string): Promise<string | undefined>;
|
|
81
|
+
/**
|
|
82
|
+
* Replace every non-overlapping literal occurrence of `needle` in `haystack`
|
|
83
|
+
* with `value`. Ported verbatim from the kernel `edit` capability so the
|
|
84
|
+
* `replaceAll` edit mode shares one definition of "replace all".
|
|
85
|
+
*/
|
|
86
|
+
export declare function replaceAllLiteral(haystack: string, needle: string, value: string): string;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { AgentTool } from "../types.js";
|
|
2
2
|
import { fuzzyFindText } from "./edit-diff.js";
|
|
3
|
+
import { type CheckpointHandle } from "./checkpoint.js";
|
|
4
|
+
import { type ReadStateHandle } from "./read-state.js";
|
|
3
5
|
export interface MatchingStrategy {
|
|
4
6
|
find(content: string, oldText: string): ReturnType<typeof fuzzyFindText>;
|
|
5
7
|
}
|
|
@@ -7,6 +9,7 @@ declare const editSchema: import("@sinclair/typebox").TObject<{
|
|
|
7
9
|
path: import("@sinclair/typebox").TString;
|
|
8
10
|
oldText: import("@sinclair/typebox").TString;
|
|
9
11
|
newText: import("@sinclair/typebox").TString;
|
|
12
|
+
replaceAll: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
10
13
|
}>;
|
|
11
14
|
export interface EditToolDetails {
|
|
12
15
|
/** Formatted diff showing what changed. */
|
|
@@ -30,6 +33,20 @@ export interface EditToolOptions {
|
|
|
30
33
|
/** Swap out the filesystem callbacks; the local disk is used by default. */
|
|
31
34
|
operations?: EditOperations;
|
|
32
35
|
matchingStrategy?: MatchingStrategy;
|
|
36
|
+
/**
|
|
37
|
+
* Optional read-before-edit gate store. When present, the edit is refused
|
|
38
|
+
* unless the file was read this session and has not drifted on disk since.
|
|
39
|
+
* Absent → no gate (no-op), preserving the prior behaviour exactly.
|
|
40
|
+
*/
|
|
41
|
+
readState?: ReadStateHandle;
|
|
42
|
+
/**
|
|
43
|
+
* Optional file-checkpoint sink. When present, the file's ORIGINAL
|
|
44
|
+
* pre-edit on-disk content is captured exactly once before the edit is
|
|
45
|
+
* applied, so a later rewind can roll the working tree back. The edit tool
|
|
46
|
+
* only ever targets an existing file, so the snapshot is its old bytes (never
|
|
47
|
+
* `null`). Absent → no snapshot (no-op).
|
|
48
|
+
*/
|
|
49
|
+
checkpoint?: CheckpointHandle;
|
|
33
50
|
}
|
|
34
51
|
export declare function createEditTool(cwd: string, options?: EditToolOptions): AgentTool<typeof editSchema>;
|
|
35
52
|
/** Ready-to-use edit tool bound to the current working directory. */
|
|
@@ -37,5 +54,6 @@ export declare const editTool: AgentTool<import("@sinclair/typebox").TObject<{
|
|
|
37
54
|
path: import("@sinclair/typebox").TString;
|
|
38
55
|
oldText: import("@sinclair/typebox").TString;
|
|
39
56
|
newText: import("@sinclair/typebox").TString;
|
|
57
|
+
replaceAll: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
40
58
|
}>, any>;
|
|
41
59
|
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -3,6 +3,7 @@ import { type TruncationResult } from "./truncate.js";
|
|
|
3
3
|
declare const findSchema: import("@sinclair/typebox").TObject<{
|
|
4
4
|
pattern: import("@sinclair/typebox").TString;
|
|
5
5
|
path: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
6
|
+
type: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
6
7
|
limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
7
8
|
}>;
|
|
8
9
|
export interface FindToolDetails {
|
|
@@ -20,6 +21,7 @@ export declare function createFindTool(cwd: string, options?: FindToolOptions):
|
|
|
20
21
|
export declare const findTool: AgentTool<import("@sinclair/typebox").TObject<{
|
|
21
22
|
pattern: import("@sinclair/typebox").TString;
|
|
22
23
|
path: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
24
|
+
type: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
23
25
|
limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
24
26
|
}>, any>;
|
|
25
27
|
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -6,6 +6,11 @@ declare const grepSchema: import("@sinclair/typebox").TObject<{
|
|
|
6
6
|
ignoreCase: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
7
7
|
literal: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
8
8
|
context: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
9
|
+
before: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
10
|
+
after: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
11
|
+
output_mode: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"content">, import("@sinclair/typebox").TLiteral<"files_with_matches">, import("@sinclair/typebox").TLiteral<"count">]>>;
|
|
12
|
+
glob: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
13
|
+
type: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
9
14
|
limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
10
15
|
}>;
|
|
11
16
|
export interface GrepToolDetails {
|
|
@@ -38,6 +43,11 @@ export declare const grepTool: AgentTool<import("@sinclair/typebox").TObject<{
|
|
|
38
43
|
ignoreCase: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
39
44
|
literal: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
40
45
|
context: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
46
|
+
before: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
47
|
+
after: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
48
|
+
output_mode: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"content">, import("@sinclair/typebox").TLiteral<"files_with_matches">, import("@sinclair/typebox").TLiteral<"count">]>>;
|
|
49
|
+
glob: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
50
|
+
type: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
41
51
|
limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
42
52
|
}>, any>;
|
|
43
53
|
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -3,6 +3,7 @@ export { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, truncateHead, truncat
|
|
|
3
3
|
export { expandPath, resolveReadPath, resolveToCwd } from "./path-utils.js";
|
|
4
4
|
export { createReadTool, readTool, type ReadOperations, type ReadToolOptions, type ReadToolDetails, } from "./read.js";
|
|
5
5
|
export { createBashTool, bashTool, type BashOperations, type BashToolOptions, type BashToolDetails, } from "./bash.js";
|
|
6
|
+
export { buildSeatbeltProfile, buildSeatbeltArgv, buildBwrapArgv, buildSandboxArgv, argvToCommandString, sandboxAvailability, createSandboxedBashOperations, type SandboxConfig, type SandboxAvailability, type SandboxedOperationsOptions, } from "./sandbox-backend.js";
|
|
6
7
|
export { createEditTool, editTool, type EditOperations, type EditToolOptions, type EditToolDetails, } from "./edit.js";
|
|
7
8
|
export { createWriteTool, writeTool, type WriteOperations, type WriteToolOptions, } from "./write.js";
|
|
8
9
|
export { createGrepTool, grepTool, type GrepOperations, type GrepToolOptions, type GrepToolDetails, } from "./grep.js";
|
|
@@ -15,6 +16,7 @@ export { createWebSearchTool, webSearchTool, type WebSearchToolOptions, type Web
|
|
|
15
16
|
export { createWebFetchTool, webFetchTool, type WebFetchToolOptions, type WebFetchToolDetails, } from "./webfetch.js";
|
|
16
17
|
export * from "./composio/index.js";
|
|
17
18
|
export { computeEditDiff, generateDiffString } from "./edit-diff.js";
|
|
19
|
+
export { DESANITIZATIONS, desanitizeMatchString, FILE_NOT_FOUND_CWD_NOTE, findSimilarFile, preserveQuoteStyle, replaceAllLiteral, suggestPathUnderCwd, } from "./edit-utils.js";
|
|
18
20
|
export { ToolFactory, ToolRegistry, type ToolMetadata, type ToolCategory } from "./registry.js";
|
|
19
21
|
export * from "./crew/index.js";
|
|
20
22
|
export declare const TOOL_METADATA: Record<string, ToolMetadata>;
|
|
@@ -26,6 +28,7 @@ export declare const codingTools: (import("../types.js").AgentTool<import("@sinc
|
|
|
26
28
|
path: import("@sinclair/typebox").TString;
|
|
27
29
|
oldText: import("@sinclair/typebox").TString;
|
|
28
30
|
newText: import("@sinclair/typebox").TString;
|
|
31
|
+
replaceAll: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
29
32
|
}>, any> | import("../types.js").AgentTool<import("@sinclair/typebox").TObject<{
|
|
30
33
|
search: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
31
34
|
toolkits: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
@@ -101,6 +104,7 @@ export declare const codingTools: (import("../types.js").AgentTool<import("@sinc
|
|
|
101
104
|
export declare const readOnlyTools: (import("../types.js").AgentTool<import("@sinclair/typebox").TObject<{
|
|
102
105
|
pattern: import("@sinclair/typebox").TString;
|
|
103
106
|
path: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
107
|
+
type: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
104
108
|
limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
105
109
|
}>, any> | import("../types.js").AgentTool<import("@sinclair/typebox").TObject<{
|
|
106
110
|
pattern: import("@sinclair/typebox").TString;
|
|
@@ -108,6 +112,11 @@ export declare const readOnlyTools: (import("../types.js").AgentTool<import("@si
|
|
|
108
112
|
ignoreCase: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
109
113
|
literal: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
110
114
|
context: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
115
|
+
before: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
116
|
+
after: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
117
|
+
output_mode: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"content">, import("@sinclair/typebox").TLiteral<"files_with_matches">, import("@sinclair/typebox").TLiteral<"count">]>>;
|
|
118
|
+
glob: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
119
|
+
type: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
111
120
|
limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
112
121
|
}>, any> | import("../types.js").AgentTool<import("@sinclair/typebox").TObject<{
|
|
113
122
|
path: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
@@ -162,6 +171,7 @@ export declare const allTools: {
|
|
|
162
171
|
path: import("@sinclair/typebox").TString;
|
|
163
172
|
oldText: import("@sinclair/typebox").TString;
|
|
164
173
|
newText: import("@sinclair/typebox").TString;
|
|
174
|
+
replaceAll: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
165
175
|
}>, any>;
|
|
166
176
|
readonly write: import("../types.js").AgentTool<import("@sinclair/typebox").TObject<{
|
|
167
177
|
path: import("@sinclair/typebox").TString;
|
|
@@ -173,11 +183,17 @@ export declare const allTools: {
|
|
|
173
183
|
ignoreCase: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
174
184
|
literal: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
175
185
|
context: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
186
|
+
before: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
187
|
+
after: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
188
|
+
output_mode: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"content">, import("@sinclair/typebox").TLiteral<"files_with_matches">, import("@sinclair/typebox").TLiteral<"count">]>>;
|
|
189
|
+
glob: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
190
|
+
type: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
176
191
|
limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
177
192
|
}>, any>;
|
|
178
193
|
readonly find: import("../types.js").AgentTool<import("@sinclair/typebox").TObject<{
|
|
179
194
|
pattern: import("@sinclair/typebox").TString;
|
|
180
195
|
path: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
196
|
+
type: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
181
197
|
limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
182
198
|
}>, any>;
|
|
183
199
|
readonly ls: import("../types.js").AgentTool<import("@sinclair/typebox").TObject<{
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read-before-edit gate for the WIRED facade tool layer.
|
|
3
|
+
*
|
|
4
|
+
* This is the product-side half of the read-edit-gate feature. The framework's
|
|
5
|
+
* `capabilities/files/read-state-gate.ts` carries the same discipline, but the
|
|
6
|
+
* product wires the `read` / `edit` / `write` factories exported from
|
|
7
|
+
* `indusagi/agent` (i.e. these `facade/bot/actions/` factories), so the gate had
|
|
8
|
+
* to live here too to actually take effect.
|
|
9
|
+
*
|
|
10
|
+
* When — and ONLY when — a host passes a {@link ReadStateHandle} via the tool's
|
|
11
|
+
* options bag, the file tools enforce a small discipline borrowed from
|
|
12
|
+
* interactive coding agents:
|
|
13
|
+
*
|
|
14
|
+
* 1. A file may not be edited or overwritten until it has been *read* in this
|
|
15
|
+
* session (so the model is never blindly clobbering content it has not
|
|
16
|
+
* seen). Brand-new files (those that do not yet exist on disk) are exempt
|
|
17
|
+
* from the write tool's gate.
|
|
18
|
+
* 2. A file may not be mutated if it has drifted on disk since that read — its
|
|
19
|
+
* modification time or byte size advanced past what was recorded — because
|
|
20
|
+
* that usually means a human or a linter changed it underneath us.
|
|
21
|
+
*
|
|
22
|
+
* After every successful read (and every successful mutation) the recorded state
|
|
23
|
+
* is refreshed from the fresh on-disk stat, so the next gate check compares
|
|
24
|
+
* against the latest known-good snapshot.
|
|
25
|
+
*
|
|
26
|
+
* The whole mechanism is *additive*: with no handle present, every helper here
|
|
27
|
+
* is a no-op and the tools behave exactly as they did before. The handle is
|
|
28
|
+
* duck-typed so the host and these factories agree on shape without a
|
|
29
|
+
* cross-package type import.
|
|
30
|
+
*/
|
|
31
|
+
/** A single recorded read: the on-disk shape captured at read time. */
|
|
32
|
+
export interface ReadStateRecord {
|
|
33
|
+
/** File modification time in ms, floored to a whole millisecond. */
|
|
34
|
+
mtimeMs: number;
|
|
35
|
+
/** File byte size at read time. */
|
|
36
|
+
size: number;
|
|
37
|
+
/** Optional content hash; unused by the default gate but reserved for hosts. */
|
|
38
|
+
contentHash?: string;
|
|
39
|
+
/** When the read was recorded; the gate mirrors this to `mtimeMs`. */
|
|
40
|
+
readAt: number;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Duck-typed store the host injects to drive the gate. Any object exposing this
|
|
44
|
+
* shape (e.g. a `Map`-backed wrapper) works; nothing is imported across packages.
|
|
45
|
+
*/
|
|
46
|
+
export interface ReadStateHandle {
|
|
47
|
+
get(path: string): ReadStateRecord | undefined;
|
|
48
|
+
set(path: string, rec: ReadStateRecord): void;
|
|
49
|
+
has(path: string): boolean;
|
|
50
|
+
}
|
|
51
|
+
/** The two byte-stable refusal messages the gate emits. */
|
|
52
|
+
export declare const READ_BEFORE_EDIT_MESSAGE = "File has not been read yet. Read it first before writing to it.";
|
|
53
|
+
export declare const MODIFIED_SINCE_READ_MESSAGE = "File has been modified since read, either by the user or by a linter. Read it again before attempting to write it.";
|
|
54
|
+
/**
|
|
55
|
+
* Record (or refresh) the read state for `absPath` from a fresh stat.
|
|
56
|
+
*
|
|
57
|
+
* No-op when no handle is present. The mtime is floored to a whole millisecond
|
|
58
|
+
* so a sub-ms clock skew between read and a later compare can never spuriously
|
|
59
|
+
* trip the staleness check. `readAt` mirrors the floored mtime — no wall-clock
|
|
60
|
+
* call is made. A failed stat is swallowed: state-keeping is best-effort and
|
|
61
|
+
* must never mask the real operation's outcome.
|
|
62
|
+
*/
|
|
63
|
+
export declare function recordReadState(handle: ReadStateHandle | undefined, absPath: string): void;
|
|
64
|
+
/** Outcome of a gate check: either cleared, or refused with a message. */
|
|
65
|
+
export type GateOutcome = {
|
|
66
|
+
ok: true;
|
|
67
|
+
} | {
|
|
68
|
+
ok: false;
|
|
69
|
+
message: string;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Enforce the read-before-edit + staleness gate ahead of a mutation.
|
|
73
|
+
*
|
|
74
|
+
* With no handle present this always clears (the gate is opt-in). With a handle:
|
|
75
|
+
* - refuse when `absPath` has no recorded read this session;
|
|
76
|
+
* - refuse when the on-disk modification time or byte size has advanced past
|
|
77
|
+
* the recorded read.
|
|
78
|
+
*
|
|
79
|
+
* The on-disk mtime is floored the same way the recorded mtime is, so the
|
|
80
|
+
* comparison is apples-to-apples. A stat failure (e.g. the file vanished) clears
|
|
81
|
+
* the gate so the underlying tool can surface its own, more specific error.
|
|
82
|
+
*/
|
|
83
|
+
export declare function enforceReadGate(handle: ReadStateHandle | undefined, absPath: string): GateOutcome;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AgentTool } from "../types.js";
|
|
2
|
+
import { type ReadStateHandle } from "./read-state.js";
|
|
2
3
|
import { type TruncationResult } from "./truncate.js";
|
|
3
4
|
declare const readSchema: import("@sinclair/typebox").TObject<{
|
|
4
5
|
path: import("@sinclair/typebox").TString;
|
|
@@ -25,6 +26,12 @@ export interface ReadToolOptions {
|
|
|
25
26
|
autoResizeImages?: boolean;
|
|
26
27
|
/** Swap out the filesystem callbacks; the local disk is used by default. */
|
|
27
28
|
operations?: ReadOperations;
|
|
29
|
+
/**
|
|
30
|
+
* Optional read-before-edit gate store. When present, a successful read
|
|
31
|
+
* records the file's on-disk stat so a later edit/write can verify it was
|
|
32
|
+
* read first and has not drifted. Absent → no gate bookkeeping (no-op).
|
|
33
|
+
*/
|
|
34
|
+
readState?: ReadStateHandle;
|
|
28
35
|
}
|
|
29
36
|
export declare function createReadTool(cwd: string, options?: ReadToolOptions): AgentTool<typeof readSchema>;
|
|
30
37
|
/** Ready-to-use read tool bound to the current working directory. */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { BashOperations } from "./bash.js";
|
|
2
|
+
/** Configuration for the OPT-IN OS sandbox applied to bash command execution. */
|
|
3
|
+
export interface SandboxConfig {
|
|
4
|
+
/** Master switch. When false/undefined the sandbox seam is a pure no-op. */
|
|
5
|
+
enabled?: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* When true, the sandbox permits outbound network access. When false (the
|
|
8
|
+
* default) all network traffic is denied at the OS level.
|
|
9
|
+
*/
|
|
10
|
+
allowNetwork?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Extra absolute paths the command is allowed to write to, in addition to the
|
|
13
|
+
* working directory and the OS temp directory which are always writable.
|
|
14
|
+
*/
|
|
15
|
+
writableRoots?: string[];
|
|
16
|
+
/**
|
|
17
|
+
* Override for the temp directory treated as writable. Defaults to the OS
|
|
18
|
+
* temp directory. Exposed mainly so tests can pin a deterministic value.
|
|
19
|
+
*/
|
|
20
|
+
tmpDir?: string;
|
|
21
|
+
}
|
|
22
|
+
/** A platform/availability probe result for the OS sandbox tooling. */
|
|
23
|
+
export interface SandboxAvailability {
|
|
24
|
+
platform: "macos" | "linux" | "unsupported";
|
|
25
|
+
/** The sandbox launcher binary for this platform, if one exists. */
|
|
26
|
+
binary: "sandbox-exec" | "bwrap" | null;
|
|
27
|
+
/** True only when the launcher binary is actually present on PATH. */
|
|
28
|
+
binaryPresent: boolean;
|
|
29
|
+
/** Human-readable explanation when the sandbox cannot be applied. */
|
|
30
|
+
reason?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Build a Seatbelt profile string for `sandbox-exec -p`.
|
|
34
|
+
*
|
|
35
|
+
* Policy: deny by default, allow process exec + read everywhere, allow write
|
|
36
|
+
* only under the resolved writable roots (cwd + tmp + extras), and deny network
|
|
37
|
+
* unless `allowNetwork` is set. This is a PURE function — no I/O, no spawning —
|
|
38
|
+
* so the generated text is unit-testable on any platform.
|
|
39
|
+
*/
|
|
40
|
+
export declare function buildSeatbeltProfile(config: SandboxConfig, cwd: string): string;
|
|
41
|
+
/**
|
|
42
|
+
* Build the `sandbox-exec` argv that runs `command` under the generated
|
|
43
|
+
* profile. PURE: returns the argv vector without spawning anything.
|
|
44
|
+
*
|
|
45
|
+
* Shape: `sandbox-exec -p <profile> /bin/sh -c <command>`.
|
|
46
|
+
*/
|
|
47
|
+
export declare function buildSeatbeltArgv(config: SandboxConfig, cwd: string, command: string): string[];
|
|
48
|
+
/**
|
|
49
|
+
* Build the `bwrap` argv that runs `command` with the writable roots bind
|
|
50
|
+
* mounted read-write over an otherwise read-only root. PURE: no spawning.
|
|
51
|
+
*
|
|
52
|
+
* Shape: `bwrap --ro-bind / / [--bind <root> <root> ...] [--unshare-net]
|
|
53
|
+
* --dev /dev --proc /proc /bin/sh -c <command>`.
|
|
54
|
+
*
|
|
55
|
+
* Network is denied by unsharing the network namespace unless `allowNetwork`.
|
|
56
|
+
*/
|
|
57
|
+
export declare function buildBwrapArgv(config: SandboxConfig, cwd: string, command: string): string[];
|
|
58
|
+
/**
|
|
59
|
+
* Probe the current platform for OS-sandbox support. Never throws and never
|
|
60
|
+
* spawns the sandbox itself — it only checks for the launcher binary so callers
|
|
61
|
+
* can decide between sandboxed execution and an honest passthrough fallback.
|
|
62
|
+
*
|
|
63
|
+
* The optional `platform`/`probe` parameters are seams for unit tests so the
|
|
64
|
+
* pure decision logic can be exercised without depending on the host OS.
|
|
65
|
+
*/
|
|
66
|
+
export declare function sandboxAvailability(platform?: NodeJS.Platform, probe?: (binary: string) => boolean): SandboxAvailability;
|
|
67
|
+
/**
|
|
68
|
+
* Build the platform-appropriate sandbox argv for `command`, or `null` when no
|
|
69
|
+
* sandbox can be applied. PURE with respect to the OS: callers pass an
|
|
70
|
+
* availability result (or rely on the live probe) and get back either the
|
|
71
|
+
* wrapped argv or `null`, never a spawn.
|
|
72
|
+
*/
|
|
73
|
+
export declare function buildSandboxArgv(config: SandboxConfig, cwd: string, command: string, availability?: SandboxAvailability): string[] | null;
|
|
74
|
+
/** Renders an argv vector into a single `sh -c`-safe command string. */
|
|
75
|
+
export declare function argvToCommandString(argv: string[]): string;
|
|
76
|
+
/** Optional reporting hook so callers can surface sandbox status honestly. */
|
|
77
|
+
export interface SandboxedOperationsOptions {
|
|
78
|
+
/** Underlying backend that actually spawns. Defaults are supplied by bash.ts. */
|
|
79
|
+
base: BashOperations;
|
|
80
|
+
/** Availability probe override (mainly for tests). */
|
|
81
|
+
availability?: SandboxAvailability;
|
|
82
|
+
/**
|
|
83
|
+
* Called once per exec with a human-readable note describing whether the
|
|
84
|
+
* sandbox was applied or why it was skipped. Lets the caller record the
|
|
85
|
+
* truth instead of the wrapper silently claiming sandboxing.
|
|
86
|
+
*/
|
|
87
|
+
onNote?: (note: string) => void;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Wrap a `BashOperations` backend so each command is executed inside the OS
|
|
91
|
+
* sandbox when one is available. When the sandbox tool is missing or the
|
|
92
|
+
* platform is unsupported, the command is passed through UNCHANGED and an
|
|
93
|
+
* honest note is emitted via `onNote` — we never pretend a command was
|
|
94
|
+
* sandboxed when it was not.
|
|
95
|
+
*
|
|
96
|
+
* When `config.enabled` is falsy this returns the base operations unchanged so
|
|
97
|
+
* the seam is a guaranteed no-op for the default (off) path.
|
|
98
|
+
*/
|
|
99
|
+
export declare function createSandboxedBashOperations(config: SandboxConfig, options: SandboxedOperationsOptions): BashOperations;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Web Search Tool
|
|
3
3
|
*
|
|
4
|
-
* Performs real-time web searches
|
|
5
|
-
*
|
|
4
|
+
* Performs real-time web searches by scraping DuckDuckGo's lightweight HTML
|
|
5
|
+
* results endpoint. Each organic hit is distilled to the three fields a model
|
|
6
|
+
* reasons over — title, destination URL, and a short snippet — and rendered as a
|
|
7
|
+
* compact numbered list. Provides up-to-date information for current events and
|
|
8
|
+
* recent data.
|
|
6
9
|
*/
|
|
7
10
|
import type { AgentTool } from "../types.js";
|
|
8
11
|
declare const webSearchSchema: import("@sinclair/typebox").TObject<{
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|