@fabric-harness/sdk 2.4.1 → 2.5.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/approval.d.ts +26 -0
- package/dist/approval.d.ts.map +1 -0
- package/dist/approval.js +138 -0
- package/dist/approval.js.map +1 -0
- package/dist/events.d.ts +43 -42
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js.map +1 -1
- package/dist/index.d.ts +141 -140
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +72 -71
- package/dist/index.js.map +1 -1
- package/dist/session.d.ts +11 -10
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +664 -303
- package/dist/session.js.map +1 -1
- package/dist/store.d.ts +2 -2
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +141 -54
- package/dist/store.js.map +1 -1
- package/dist/strict.d.ts +135 -134
- package/dist/strict.d.ts.map +1 -1
- package/dist/strict.js +70 -69
- package/dist/strict.js.map +1 -1
- package/dist/tools.d.ts +13 -9
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +248 -92
- package/dist/tools.js.map +1 -1
- package/dist/types.d.ts +54 -31
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
package/dist/tools.d.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import type { FileStat, SandboxEnv } from
|
|
2
|
-
import type { JsonObject, PackagedSkillDirectory, ResultValidator, ShellResult } from
|
|
1
|
+
import type { FileStat, SandboxEnv } from "./sandbox.js";
|
|
2
|
+
import type { ApprovalGrant, JsonObject, PackagedSkillDirectory, ResultValidator, ShellResult } from "./types.js";
|
|
3
3
|
export interface ToolContext {
|
|
4
4
|
sandbox: SandboxEnv;
|
|
5
|
+
/** Stable identity of the logical call, preserved across durable retries. */
|
|
6
|
+
toolCallId?: string;
|
|
5
7
|
/** Cancels provider work when the owning prompt, task, or submission is aborted. */
|
|
6
8
|
signal?: AbortSignal;
|
|
9
|
+
/** Present only when this logical tool operation passed an approval gate. */
|
|
10
|
+
approval?: ApprovalGrant;
|
|
7
11
|
}
|
|
8
12
|
export interface ToolCall<TInput = unknown> {
|
|
9
13
|
tool: string;
|
|
@@ -17,7 +21,7 @@ export interface ToolCallResult<TOutput = unknown> {
|
|
|
17
21
|
error?: string;
|
|
18
22
|
id?: string;
|
|
19
23
|
}
|
|
20
|
-
export type ToolEffect =
|
|
24
|
+
export type ToolEffect = "read" | "write" | "execute" | "none";
|
|
21
25
|
export interface ToolDef<TInput = unknown, TOutput = unknown> {
|
|
22
26
|
name: string;
|
|
23
27
|
/** Canonical policy identity when this public name is an alias (for example `save_file` -> `write`). */
|
|
@@ -30,7 +34,7 @@ export interface ToolDef<TInput = unknown, TOutput = unknown> {
|
|
|
30
34
|
execute?(input: TInput, context?: ToolContext): Promise<TOutput> | TOutput;
|
|
31
35
|
}
|
|
32
36
|
export interface SecretRef {
|
|
33
|
-
kind:
|
|
37
|
+
kind: "secret";
|
|
34
38
|
name: string;
|
|
35
39
|
}
|
|
36
40
|
export type CommandEnvValue = string | SecretRef | undefined;
|
|
@@ -53,7 +57,7 @@ export interface CommandToolInput {
|
|
|
53
57
|
export interface CommandToolOptions {
|
|
54
58
|
resolveSecret?: (ref: SecretRef) => string | undefined | Promise<string | undefined>;
|
|
55
59
|
/** Defaults to fail: command secrets are runtime-only and must not be silently omitted. */
|
|
56
|
-
onMissingSecret?:
|
|
60
|
+
onMissingSecret?: "fail";
|
|
57
61
|
}
|
|
58
62
|
export interface ReadFileInput {
|
|
59
63
|
path: string;
|
|
@@ -115,7 +119,7 @@ export interface ActivateSkillInput {
|
|
|
115
119
|
name: string;
|
|
116
120
|
}
|
|
117
121
|
export declare function secret(name: string): SecretRef;
|
|
118
|
-
export declare function defineCommand<TInput = CommandToolInput>(name: string, options?: Omit<Command<TInput>,
|
|
122
|
+
export declare function defineCommand<TInput = CommandToolInput>(name: string, options?: Omit<Command<TInput>, "name">): Command<TInput>;
|
|
119
123
|
export declare function defineTool<TInput = unknown, TOutput = unknown>(tool: ToolDef<TInput, TOutput>): ToolDef<TInput, TOutput>;
|
|
120
124
|
export type BuiltinTool = ToolDef<ReadFileInput, string> | ToolDef<ReadFileBufferInput, Uint8Array> | ToolDef<WriteFileInput, void> | ToolDef<EditInput, void> | ToolDef<StatInput, FileStat> | ToolDef<ReaddirInput, string[]> | ToolDef<ExistsInput, boolean> | ToolDef<MkdirInput, void> | ToolDef<RmInput, void> | ToolDef<BashInput, ShellResult> | ToolDef<GrepInput, GrepMatch[]> | ToolDef<GlobInput, string[]>;
|
|
121
125
|
export type BuiltinFileTool = Exclude<BuiltinTool, ToolDef<BashInput, ShellResult> | ToolDef<GrepInput, GrepMatch[]> | ToolDef<GlobInput, string[]>>;
|
|
@@ -136,12 +140,12 @@ export declare function grepTool(sandbox?: SandboxEnv): ToolDef<GrepInput, GrepM
|
|
|
136
140
|
export declare function globTool(sandbox?: SandboxEnv): ToolDef<GlobInput, string[]>;
|
|
137
141
|
export declare function createActivateSkillTool(skillNames: string[], activate: (name: string) => Promise<string>): ToolDef<ActivateSkillInput, string>;
|
|
138
142
|
export type ResultOutcome<TResult> = {
|
|
139
|
-
type:
|
|
143
|
+
type: "pending";
|
|
140
144
|
} | {
|
|
141
|
-
type:
|
|
145
|
+
type: "finished";
|
|
142
146
|
value: TResult;
|
|
143
147
|
} | {
|
|
144
|
-
type:
|
|
148
|
+
type: "gave_up";
|
|
145
149
|
reason: string;
|
|
146
150
|
};
|
|
147
151
|
export interface ResultToolBundle<TResult> {
|
package/dist/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAEzD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAEzD,OAAO,KAAK,EACV,aAAa,EACb,UAAU,EACV,sBAAsB,EACtB,eAAe,EACf,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,UAAU,CAAC;IACpB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oFAAoF;IACpF,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAED,MAAM,WAAW,QAAQ,CAAC,MAAM,GAAG,OAAO;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,cAAc,CAAC,OAAO,GAAG,OAAO;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAE/D,MAAM,WAAW,OAAO,CAAC,MAAM,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,wGAAwG;IACxG,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,UAAU,GAAG;QAAE,MAAM,CAAC,EAAE,UAAU,CAAA;KAAE,CAAC;IAChD,OAAO,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;CAC5E;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;AAE7D,MAAM,WAAW,OAAO,CAAC,MAAM,GAAG,gBAAgB;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;IACxC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACtC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,UAAU,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACrF,2FAA2F;IAC3F,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;CACd;AACD,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;CACd;AACD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,UAAU,CAAC;CAC9B;AACD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;CACd;AACD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;CACd;AACD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;CACd;AACD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AACD,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AACD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AACD,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AACD,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AACD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AACD,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AACD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAE9C;AAED,wBAAgB,aAAa,CAAC,MAAM,GAAG,gBAAgB,EACrD,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAM,GAC1C,OAAO,CAAC,MAAM,CAAC,CAEjB;AAED,wBAAgB,UAAU,CAAC,MAAM,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO,EAC5D,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAE1B;AAgBD,MAAM,MAAM,WAAW,GACnB,OAAO,CAAC,aAAa,EAAE,MAAM,CAAC,GAC9B,OAAO,CAAC,mBAAmB,EAAE,UAAU,CAAC,GACxC,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,GAC7B,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,GACxB,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,GAC5B,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC,GAC/B,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,GAC7B,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,GACzB,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,GACtB,OAAO,CAAC,SAAS,EAAE,WAAW,CAAC,GAC/B,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC,GAC/B,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;AAEjC,MAAM,MAAM,eAAe,GAAG,OAAO,CACnC,WAAW,EACX,OAAO,CAAC,SAAS,EAAE,WAAW,CAAC,GAAG,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC,GAAG,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,CACjG,CAAC;AAEF,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,gBAAgB,EAAE,WAAW,CAAC,EAAE,CAuC1C;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,UAAU,EACnB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,GACtD,WAAW,EAAE,CAOf;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,UAAU,EACnB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,GACtD,eAAe,EAAE,CAYnB;AAED,wBAAgB,YAAY,CAC1B,OAAO,CAAC,EAAE,UAAU,EACpB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,GACtD,OAAO,CAAC,aAAa,EAAE,MAAM,CAAC,CAiBhC;AACD,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,mBAAmB,EAAE,UAAU,CAAC,CAUjG;AACD,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,CAejF;AACD,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CA4B3E;AACD,wBAAgB,QAAQ,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAU3E;AACD,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC,CAUjF;AACD,wBAAgB,UAAU,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAU9E;AACD,wBAAgB,SAAS,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAiBzE;AACD,wBAAgB,MAAM,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAsBnE;AAED,wBAAgB,QAAQ,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,EAAE,WAAW,CAAC,CAwB9E;AAED,wBAAgB,QAAQ,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC,CA6C9E;AAED,wBAAgB,QAAQ,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,CAuB3E;AAED,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,EAAE,EACpB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAC1C,OAAO,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAqBrC;AA8CD,MAAM,MAAM,aAAa,CAAC,OAAO,IAC7B;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAExC,MAAM,WAAW,gBAAgB,CAAC,OAAO;IACvC,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,UAAU,IAAI,aAAa,CAAC,OAAO,CAAC,CAAC;CACtC;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EACvC,SAAS,EAAE,eAAe,CAAC,OAAO,CAAC,GAClC,gBAAgB,CAAC,OAAO,CAAC,CAkF3B;AAUD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGhD"}
|
package/dist/tools.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import path from
|
|
2
|
-
import { readPackagedSkillFile, isPackagedSkillPath } from
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { readPackagedSkillFile, isPackagedSkillPath } from "./skills.js";
|
|
3
3
|
export function secret(name) {
|
|
4
|
-
return { kind:
|
|
4
|
+
return { kind: "secret", name };
|
|
5
5
|
}
|
|
6
6
|
export function defineCommand(name, options = {}) {
|
|
7
7
|
return { name, ...options };
|
|
@@ -10,11 +10,16 @@ export function defineTool(tool) {
|
|
|
10
10
|
return tool;
|
|
11
11
|
}
|
|
12
12
|
function pathInputSchema(description) {
|
|
13
|
-
return {
|
|
13
|
+
return {
|
|
14
|
+
type: "object",
|
|
15
|
+
additionalProperties: false,
|
|
16
|
+
properties: { path: { type: "string", description } },
|
|
17
|
+
required: ["path"],
|
|
18
|
+
};
|
|
14
19
|
}
|
|
15
20
|
function requireSandbox(sandbox) {
|
|
16
21
|
if (!sandbox)
|
|
17
|
-
throw new Error(
|
|
22
|
+
throw new Error("A SandboxEnv is required to execute this tool.");
|
|
18
23
|
return sandbox;
|
|
19
24
|
}
|
|
20
25
|
export function createCommandTools(commands, options = {}) {
|
|
@@ -22,20 +27,28 @@ export function createCommandTools(commands, options = {}) {
|
|
|
22
27
|
name: command.name,
|
|
23
28
|
description: command.description ?? `Run the scoped ${command.name} command in the session sandbox.`,
|
|
24
29
|
inputSchema: command.argsSchema ?? {
|
|
25
|
-
type:
|
|
30
|
+
type: "object",
|
|
26
31
|
additionalProperties: false,
|
|
27
32
|
properties: {
|
|
28
|
-
args: { type:
|
|
29
|
-
cwd: { type:
|
|
30
|
-
timeout: { type:
|
|
33
|
+
args: { type: "array", items: { type: "string" }, description: "Command arguments." },
|
|
34
|
+
cwd: { type: "string", description: "Working directory inside the sandbox." },
|
|
35
|
+
timeout: { type: "number", description: "Timeout in milliseconds." },
|
|
31
36
|
},
|
|
32
37
|
},
|
|
33
|
-
metadata: {
|
|
38
|
+
metadata: {
|
|
39
|
+
kind: "command",
|
|
40
|
+
effect: "execute",
|
|
41
|
+
command: command.name,
|
|
42
|
+
executable: command.executable ?? command.name,
|
|
43
|
+
envKeys: Object.keys(command.env ?? {}),
|
|
44
|
+
},
|
|
34
45
|
async execute(input, context) {
|
|
35
46
|
const env = requireSandbox(context?.sandbox);
|
|
36
|
-
const builtArgs = command.buildArgs
|
|
47
|
+
const builtArgs = command.buildArgs
|
|
48
|
+
? command.buildArgs(input)
|
|
49
|
+
: [...(command.args ?? []), ...(input.args ?? [])];
|
|
37
50
|
const executable = command.executable ?? command.name;
|
|
38
|
-
const shellCommand = [executable, ...builtArgs.map(shellQuote)].join(
|
|
51
|
+
const shellCommand = [executable, ...builtArgs.map(shellQuote)].join(" ");
|
|
39
52
|
const execOptions = {};
|
|
40
53
|
const scopedEnv = await resolveCommandEnv(command.env, options);
|
|
41
54
|
const cwd = input.cwd ?? command.cwd;
|
|
@@ -50,17 +63,32 @@ export function createCommandTools(commands, options = {}) {
|
|
|
50
63
|
}));
|
|
51
64
|
}
|
|
52
65
|
export function createBuiltinTools(sandbox, packagedSkills) {
|
|
53
|
-
return [
|
|
66
|
+
return [
|
|
67
|
+
...createFileTools(sandbox, packagedSkills),
|
|
68
|
+
bashTool(sandbox),
|
|
69
|
+
grepTool(sandbox),
|
|
70
|
+
globTool(sandbox),
|
|
71
|
+
];
|
|
54
72
|
}
|
|
55
73
|
export function createFileTools(sandbox, packagedSkills) {
|
|
56
|
-
return [
|
|
74
|
+
return [
|
|
75
|
+
readFileTool(sandbox, packagedSkills),
|
|
76
|
+
readFileBufferTool(sandbox),
|
|
77
|
+
writeFileTool(sandbox),
|
|
78
|
+
editFileTool(sandbox),
|
|
79
|
+
statTool(sandbox),
|
|
80
|
+
readdirTool(sandbox),
|
|
81
|
+
existsTool(sandbox),
|
|
82
|
+
mkdirTool(sandbox),
|
|
83
|
+
rmTool(sandbox),
|
|
84
|
+
];
|
|
57
85
|
}
|
|
58
86
|
export function readFileTool(sandbox, packagedSkills) {
|
|
59
87
|
return defineTool({
|
|
60
|
-
name:
|
|
61
|
-
description:
|
|
62
|
-
inputSchema: pathInputSchema(
|
|
63
|
-
metadata: { effect:
|
|
88
|
+
name: "read",
|
|
89
|
+
description: "Read a UTF-8 text file from the session sandbox.",
|
|
90
|
+
inputSchema: pathInputSchema("File path to read."),
|
|
91
|
+
metadata: { effect: "read" },
|
|
64
92
|
async execute(input, context) {
|
|
65
93
|
if (packagedSkills && Object.keys(packagedSkills).length > 0) {
|
|
66
94
|
const packaged = readPackagedSkillFile(packagedSkills, input.path);
|
|
@@ -75,53 +103,152 @@ export function readFileTool(sandbox, packagedSkills) {
|
|
|
75
103
|
});
|
|
76
104
|
}
|
|
77
105
|
export function readFileBufferTool(sandbox) {
|
|
78
|
-
return defineTool({
|
|
106
|
+
return defineTool({
|
|
107
|
+
name: "read_buffer",
|
|
108
|
+
description: "Read a binary file from the session sandbox.",
|
|
109
|
+
inputSchema: pathInputSchema("File path to read."),
|
|
110
|
+
metadata: { effect: "read" },
|
|
111
|
+
async execute(input, context) {
|
|
112
|
+
return requireSandbox(sandbox ?? context?.sandbox).readFileBuffer(input.path);
|
|
113
|
+
},
|
|
114
|
+
});
|
|
79
115
|
}
|
|
80
116
|
export function writeFileTool(sandbox) {
|
|
81
|
-
return defineTool({
|
|
117
|
+
return defineTool({
|
|
118
|
+
name: "write",
|
|
119
|
+
description: "Write a text or binary file into the session sandbox.",
|
|
120
|
+
inputSchema: {
|
|
121
|
+
type: "object",
|
|
122
|
+
additionalProperties: false,
|
|
123
|
+
properties: { path: { type: "string" }, content: { type: "string" } },
|
|
124
|
+
required: ["path", "content"],
|
|
125
|
+
},
|
|
126
|
+
metadata: { effect: "write" },
|
|
127
|
+
async execute(input, context) {
|
|
128
|
+
return requireSandbox(sandbox ?? context?.sandbox).writeFile(input.path, input.content);
|
|
129
|
+
},
|
|
130
|
+
});
|
|
82
131
|
}
|
|
83
132
|
export function editFileTool(sandbox) {
|
|
84
133
|
return defineTool({
|
|
85
|
-
name:
|
|
86
|
-
description:
|
|
87
|
-
inputSchema: {
|
|
88
|
-
|
|
134
|
+
name: "edit",
|
|
135
|
+
description: "Replace exactly one text block in a sandbox file.",
|
|
136
|
+
inputSchema: {
|
|
137
|
+
type: "object",
|
|
138
|
+
additionalProperties: false,
|
|
139
|
+
properties: {
|
|
140
|
+
path: { type: "string" },
|
|
141
|
+
oldText: { type: "string" },
|
|
142
|
+
newText: { type: "string" },
|
|
143
|
+
},
|
|
144
|
+
required: ["path", "oldText", "newText"],
|
|
145
|
+
},
|
|
146
|
+
metadata: { effect: "write" },
|
|
89
147
|
async execute(input, context) {
|
|
90
148
|
const env = requireSandbox(sandbox ?? context?.sandbox);
|
|
91
149
|
const original = await env.readFile(input.path);
|
|
92
150
|
const first = original.indexOf(input.oldText);
|
|
93
151
|
if (first === -1)
|
|
94
|
-
throw new Error(
|
|
152
|
+
throw new Error("oldText was not found in the target file.");
|
|
95
153
|
if (original.indexOf(input.oldText, first + input.oldText.length) !== -1)
|
|
96
|
-
throw new Error(
|
|
154
|
+
throw new Error("oldText must match exactly one location in the target file.");
|
|
97
155
|
await env.writeFile(input.path, `${original.slice(0, first)}${input.newText}${original.slice(first + input.oldText.length)}`);
|
|
98
156
|
},
|
|
99
157
|
});
|
|
100
158
|
}
|
|
101
159
|
export function statTool(sandbox) {
|
|
102
|
-
return defineTool({
|
|
160
|
+
return defineTool({
|
|
161
|
+
name: "stat",
|
|
162
|
+
description: "Stat a sandbox path.",
|
|
163
|
+
inputSchema: pathInputSchema("Path to stat."),
|
|
164
|
+
metadata: { effect: "read" },
|
|
165
|
+
async execute(input, context) {
|
|
166
|
+
return requireSandbox(sandbox ?? context?.sandbox).stat(input.path);
|
|
167
|
+
},
|
|
168
|
+
});
|
|
103
169
|
}
|
|
104
170
|
export function readdirTool(sandbox) {
|
|
105
|
-
return defineTool({
|
|
171
|
+
return defineTool({
|
|
172
|
+
name: "readdir",
|
|
173
|
+
description: "List entries in a sandbox directory.",
|
|
174
|
+
inputSchema: pathInputSchema("Directory path to list."),
|
|
175
|
+
metadata: { effect: "read" },
|
|
176
|
+
async execute(input, context) {
|
|
177
|
+
return requireSandbox(sandbox ?? context?.sandbox).readdir(input.path);
|
|
178
|
+
},
|
|
179
|
+
});
|
|
106
180
|
}
|
|
107
181
|
export function existsTool(sandbox) {
|
|
108
|
-
return defineTool({
|
|
182
|
+
return defineTool({
|
|
183
|
+
name: "exists",
|
|
184
|
+
description: "Check whether a sandbox path exists.",
|
|
185
|
+
inputSchema: pathInputSchema("Path to check."),
|
|
186
|
+
metadata: { effect: "read" },
|
|
187
|
+
async execute(input, context) {
|
|
188
|
+
return requireSandbox(sandbox ?? context?.sandbox).exists(input.path);
|
|
189
|
+
},
|
|
190
|
+
});
|
|
109
191
|
}
|
|
110
192
|
export function mkdirTool(sandbox) {
|
|
111
|
-
return defineTool({
|
|
112
|
-
|
|
193
|
+
return defineTool({
|
|
194
|
+
name: "mkdir",
|
|
195
|
+
description: "Create a directory in the session sandbox.",
|
|
196
|
+
inputSchema: {
|
|
197
|
+
type: "object",
|
|
198
|
+
additionalProperties: false,
|
|
199
|
+
properties: { path: { type: "string" }, recursive: { type: "boolean" } },
|
|
200
|
+
required: ["path"],
|
|
201
|
+
},
|
|
202
|
+
metadata: { effect: "write" },
|
|
203
|
+
async execute(input, context) {
|
|
204
|
+
const options = {};
|
|
205
|
+
if (input.recursive !== undefined)
|
|
206
|
+
options.recursive = input.recursive;
|
|
207
|
+
return requireSandbox(sandbox ?? context?.sandbox).mkdir(input.path, options);
|
|
208
|
+
},
|
|
209
|
+
});
|
|
113
210
|
}
|
|
114
211
|
export function rmTool(sandbox) {
|
|
115
|
-
return defineTool({
|
|
116
|
-
|
|
117
|
-
|
|
212
|
+
return defineTool({
|
|
213
|
+
name: "rm",
|
|
214
|
+
description: "Remove a file or directory from the session sandbox.",
|
|
215
|
+
inputSchema: {
|
|
216
|
+
type: "object",
|
|
217
|
+
additionalProperties: false,
|
|
218
|
+
properties: {
|
|
219
|
+
path: { type: "string" },
|
|
220
|
+
recursive: { type: "boolean" },
|
|
221
|
+
force: { type: "boolean" },
|
|
222
|
+
},
|
|
223
|
+
required: ["path"],
|
|
224
|
+
},
|
|
225
|
+
metadata: { effect: "write" },
|
|
226
|
+
async execute(input, context) {
|
|
227
|
+
const options = {};
|
|
228
|
+
if (input.recursive !== undefined)
|
|
229
|
+
options.recursive = input.recursive;
|
|
230
|
+
if (input.force !== undefined)
|
|
231
|
+
options.force = input.force;
|
|
232
|
+
return requireSandbox(sandbox ?? context?.sandbox).rm(input.path, options);
|
|
233
|
+
},
|
|
234
|
+
});
|
|
118
235
|
}
|
|
119
236
|
export function bashTool(sandbox) {
|
|
120
237
|
return defineTool({
|
|
121
|
-
name:
|
|
122
|
-
description:
|
|
123
|
-
inputSchema: {
|
|
124
|
-
|
|
238
|
+
name: "bash",
|
|
239
|
+
description: "Execute a shell command through the session sandbox.",
|
|
240
|
+
inputSchema: {
|
|
241
|
+
type: "object",
|
|
242
|
+
additionalProperties: false,
|
|
243
|
+
properties: {
|
|
244
|
+
command: { type: "string" },
|
|
245
|
+
cwd: { type: "string" },
|
|
246
|
+
env: { type: "object", additionalProperties: { type: "string" } },
|
|
247
|
+
timeout: { type: "number" },
|
|
248
|
+
},
|
|
249
|
+
required: ["command"],
|
|
250
|
+
},
|
|
251
|
+
metadata: { effect: "execute" },
|
|
125
252
|
async execute(input, context) {
|
|
126
253
|
const options = {};
|
|
127
254
|
if (input.cwd !== undefined)
|
|
@@ -136,15 +263,26 @@ export function bashTool(sandbox) {
|
|
|
136
263
|
}
|
|
137
264
|
export function grepTool(sandbox) {
|
|
138
265
|
return defineTool({
|
|
139
|
-
name:
|
|
140
|
-
description:
|
|
141
|
-
inputSchema: {
|
|
142
|
-
|
|
266
|
+
name: "grep",
|
|
267
|
+
description: "Search text files in the session sandbox.",
|
|
268
|
+
inputSchema: {
|
|
269
|
+
type: "object",
|
|
270
|
+
additionalProperties: false,
|
|
271
|
+
properties: {
|
|
272
|
+
pattern: { type: "string" },
|
|
273
|
+
path: { type: "string" },
|
|
274
|
+
ignoreCase: { type: "boolean" },
|
|
275
|
+
literal: { type: "boolean" },
|
|
276
|
+
maxMatches: { type: "number" },
|
|
277
|
+
},
|
|
278
|
+
required: ["pattern"],
|
|
279
|
+
},
|
|
280
|
+
metadata: { effect: "read" },
|
|
143
281
|
async execute(input, context) {
|
|
144
282
|
const env = requireSandbox(sandbox ?? context?.sandbox);
|
|
145
|
-
const root = input.path ??
|
|
283
|
+
const root = input.path ?? ".";
|
|
146
284
|
const files = await listFiles(env, root);
|
|
147
|
-
const flags = input.ignoreCase ?
|
|
285
|
+
const flags = input.ignoreCase ? "i" : "";
|
|
148
286
|
const regex = input.literal ? undefined : new RegExp(input.pattern, flags);
|
|
149
287
|
const needle = input.ignoreCase ? input.pattern.toLowerCase() : input.pattern;
|
|
150
288
|
const matches = [];
|
|
@@ -158,7 +296,7 @@ export function grepTool(sandbox) {
|
|
|
158
296
|
}
|
|
159
297
|
const lines = text.split(/\r?\n/);
|
|
160
298
|
for (let index = 0; index < lines.length; index += 1) {
|
|
161
|
-
const line = lines[index] ??
|
|
299
|
+
const line = lines[index] ?? "";
|
|
162
300
|
const haystack = input.ignoreCase ? line.toLowerCase() : line;
|
|
163
301
|
if (regex ? regex.test(line) : haystack.includes(needle)) {
|
|
164
302
|
matches.push({ path: file, line: index + 1, text: line });
|
|
@@ -173,13 +311,22 @@ export function grepTool(sandbox) {
|
|
|
173
311
|
}
|
|
174
312
|
export function globTool(sandbox) {
|
|
175
313
|
return defineTool({
|
|
176
|
-
name:
|
|
177
|
-
description:
|
|
178
|
-
inputSchema: {
|
|
179
|
-
|
|
314
|
+
name: "glob",
|
|
315
|
+
description: "Find files by glob pattern in the session sandbox.",
|
|
316
|
+
inputSchema: {
|
|
317
|
+
type: "object",
|
|
318
|
+
additionalProperties: false,
|
|
319
|
+
properties: {
|
|
320
|
+
pattern: { type: "string" },
|
|
321
|
+
cwd: { type: "string" },
|
|
322
|
+
maxMatches: { type: "number" },
|
|
323
|
+
},
|
|
324
|
+
required: ["pattern"],
|
|
325
|
+
},
|
|
326
|
+
metadata: { effect: "read" },
|
|
180
327
|
async execute(input, context) {
|
|
181
328
|
const env = requireSandbox(sandbox ?? context?.sandbox);
|
|
182
|
-
const cwd = input.cwd ??
|
|
329
|
+
const cwd = input.cwd ?? ".";
|
|
183
330
|
const files = await listFiles(env, cwd);
|
|
184
331
|
const regex = globToRegex(input.pattern);
|
|
185
332
|
return files.filter((file) => regex.test(file)).slice(0, input.maxMatches ?? 1000);
|
|
@@ -188,21 +335,21 @@ export function globTool(sandbox) {
|
|
|
188
335
|
}
|
|
189
336
|
export function createActivateSkillTool(skillNames, activate) {
|
|
190
337
|
return defineTool({
|
|
191
|
-
name:
|
|
192
|
-
description: `Load the full instructions for one available skill before performing work that matches its description. Available skills: ${skillNames.join(
|
|
338
|
+
name: "activate_skill",
|
|
339
|
+
description: `Load the full instructions for one available skill before performing work that matches its description. Available skills: ${skillNames.join(", ")}.`,
|
|
193
340
|
inputSchema: {
|
|
194
|
-
type:
|
|
341
|
+
type: "object",
|
|
195
342
|
additionalProperties: false,
|
|
196
343
|
properties: {
|
|
197
344
|
name: {
|
|
198
|
-
type:
|
|
199
|
-
description:
|
|
345
|
+
type: "string",
|
|
346
|
+
description: "Name of the skill to activate.",
|
|
200
347
|
enum: skillNames,
|
|
201
348
|
},
|
|
202
349
|
},
|
|
203
|
-
required: [
|
|
350
|
+
required: ["name"],
|
|
204
351
|
},
|
|
205
|
-
metadata: { effect:
|
|
352
|
+
metadata: { effect: "none" },
|
|
206
353
|
async execute(input) {
|
|
207
354
|
return activate(input.name);
|
|
208
355
|
},
|
|
@@ -214,17 +361,17 @@ async function listFiles(env, dir) {
|
|
|
214
361
|
for (const entry of entries) {
|
|
215
362
|
const child = path.posix.join(dir, entry);
|
|
216
363
|
const stat = await env.stat(child);
|
|
217
|
-
if (stat.type ===
|
|
364
|
+
if (stat.type === "directory")
|
|
218
365
|
out.push(...(await listFiles(env, child)));
|
|
219
|
-
if (stat.type ===
|
|
220
|
-
out.push(child.replace(/^\.\//,
|
|
366
|
+
if (stat.type === "file")
|
|
367
|
+
out.push(child.replace(/^\.\//, ""));
|
|
221
368
|
}
|
|
222
369
|
return out;
|
|
223
370
|
}
|
|
224
371
|
async function resolveCommandEnv(input, options) {
|
|
225
372
|
const output = {};
|
|
226
373
|
for (const [key, value] of Object.entries(input ?? {})) {
|
|
227
|
-
if (typeof value ===
|
|
374
|
+
if (typeof value === "string")
|
|
228
375
|
output[key] = value;
|
|
229
376
|
if (isSecretRef(value)) {
|
|
230
377
|
const resolved = await options.resolveSecret?.(value);
|
|
@@ -239,7 +386,10 @@ async function resolveCommandEnv(input, options) {
|
|
|
239
386
|
return output;
|
|
240
387
|
}
|
|
241
388
|
function isSecretRef(value) {
|
|
242
|
-
return typeof value ===
|
|
389
|
+
return (typeof value === "object" &&
|
|
390
|
+
value !== null &&
|
|
391
|
+
value.kind === "secret" &&
|
|
392
|
+
typeof value.name === "string");
|
|
243
393
|
}
|
|
244
394
|
/**
|
|
245
395
|
* Produce the per-call `finish` and `give_up` tool pair for a given ResultValidator.
|
|
@@ -252,20 +402,20 @@ function isSecretRef(value) {
|
|
|
252
402
|
* natural.
|
|
253
403
|
*/
|
|
254
404
|
export function createResultTools(validator) {
|
|
255
|
-
let outcome = { type:
|
|
405
|
+
let outcome = { type: "pending" };
|
|
256
406
|
const finishDescription = "Call this tool when the task is complete. Provide your final answer as the arguments. " +
|
|
257
407
|
"The arguments are validated against the required schema; if validation fails you will " +
|
|
258
408
|
"receive an error message and may try again. " +
|
|
259
|
-
"The first successful
|
|
409
|
+
"The first successful `finish` call wins — once the task is finished, do not call `finish` again.";
|
|
260
410
|
const giveUpDescription = "Call this tool only if you have determined that you cannot complete the task or " +
|
|
261
|
-
"cannot produce a result that conforms to the required schema. Provide a clear
|
|
411
|
+
"cannot produce a result that conforms to the required schema. Provide a clear `reason`. " +
|
|
262
412
|
"This ends the task with a failure.";
|
|
263
413
|
const finishTool = {
|
|
264
|
-
name:
|
|
414
|
+
name: "finish",
|
|
265
415
|
description: finishDescription,
|
|
266
|
-
inputSchema: { type:
|
|
416
|
+
inputSchema: { type: "object", properties: {}, additionalProperties: true },
|
|
267
417
|
async execute(input) {
|
|
268
|
-
if (outcome.type !==
|
|
418
|
+
if (outcome.type !== "pending") {
|
|
269
419
|
return alreadyDoneToolResult(outcome);
|
|
270
420
|
}
|
|
271
421
|
let parsed;
|
|
@@ -288,33 +438,39 @@ export function createResultTools(validator) {
|
|
|
288
438
|
}
|
|
289
439
|
catch (error) {
|
|
290
440
|
const message = error instanceof Error ? error.message : String(error);
|
|
291
|
-
return {
|
|
441
|
+
return {
|
|
442
|
+
error: `Result does not match the required schema: ${message}. Please call \`finish\` again with a corrected payload.`,
|
|
443
|
+
};
|
|
292
444
|
}
|
|
293
|
-
outcome = { type:
|
|
294
|
-
return { output:
|
|
445
|
+
outcome = { type: "finished", value: parsed };
|
|
446
|
+
return { output: "Result accepted. The task is complete." };
|
|
295
447
|
},
|
|
296
448
|
};
|
|
297
449
|
const giveUpTool = {
|
|
298
|
-
name:
|
|
450
|
+
name: "give_up",
|
|
299
451
|
description: giveUpDescription,
|
|
300
452
|
inputSchema: {
|
|
301
|
-
type:
|
|
453
|
+
type: "object",
|
|
302
454
|
additionalProperties: false,
|
|
303
455
|
properties: {
|
|
304
|
-
reason: {
|
|
456
|
+
reason: {
|
|
457
|
+
type: "string",
|
|
458
|
+
minLength: 1,
|
|
459
|
+
description: "A clear explanation of why the task cannot be completed.",
|
|
460
|
+
},
|
|
305
461
|
},
|
|
306
|
-
required: [
|
|
462
|
+
required: ["reason"],
|
|
307
463
|
},
|
|
308
464
|
async execute(input) {
|
|
309
|
-
if (outcome.type !==
|
|
465
|
+
if (outcome.type !== "pending") {
|
|
310
466
|
return alreadyDoneToolResult(outcome);
|
|
311
467
|
}
|
|
312
468
|
const reason = input.reason;
|
|
313
|
-
if (typeof reason !==
|
|
314
|
-
return { error: "
|
|
469
|
+
if (typeof reason !== "string" || reason.trim().length === 0) {
|
|
470
|
+
return { error: "`give_up` requires a non-empty `reason` string." };
|
|
315
471
|
}
|
|
316
|
-
outcome = { type:
|
|
317
|
-
return { output:
|
|
472
|
+
outcome = { type: "gave_up", reason };
|
|
473
|
+
return { output: "Acknowledged." };
|
|
318
474
|
},
|
|
319
475
|
};
|
|
320
476
|
return {
|
|
@@ -323,9 +479,9 @@ export function createResultTools(validator) {
|
|
|
323
479
|
};
|
|
324
480
|
}
|
|
325
481
|
function alreadyDoneToolResult(outcome) {
|
|
326
|
-
const detail = outcome.type ===
|
|
327
|
-
?
|
|
328
|
-
:
|
|
482
|
+
const detail = outcome.type === "finished"
|
|
483
|
+
? "A result was already submitted; the task is complete."
|
|
484
|
+
: "The task was already given up; it cannot be resumed.";
|
|
329
485
|
return { error: `${detail} Do not call this tool again.` };
|
|
330
486
|
}
|
|
331
487
|
export function shellQuote(value) {
|
|
@@ -334,28 +490,28 @@ export function shellQuote(value) {
|
|
|
334
490
|
return `'${value.replaceAll("'", "'\\''")}'`;
|
|
335
491
|
}
|
|
336
492
|
function globToRegex(pattern) {
|
|
337
|
-
let source =
|
|
493
|
+
let source = "^";
|
|
338
494
|
for (let index = 0; index < pattern.length; index += 1) {
|
|
339
495
|
const char = pattern[index];
|
|
340
496
|
const next = pattern[index + 1];
|
|
341
|
-
if (char ===
|
|
342
|
-
source +=
|
|
497
|
+
if (char === "*" && next === "*") {
|
|
498
|
+
source += ".*";
|
|
343
499
|
index += 1;
|
|
344
500
|
continue;
|
|
345
501
|
}
|
|
346
|
-
if (char ===
|
|
347
|
-
source +=
|
|
502
|
+
if (char === "*") {
|
|
503
|
+
source += "[^/]*";
|
|
348
504
|
continue;
|
|
349
505
|
}
|
|
350
|
-
if (char ===
|
|
351
|
-
source +=
|
|
506
|
+
if (char === "?") {
|
|
507
|
+
source += "[^/]";
|
|
352
508
|
continue;
|
|
353
509
|
}
|
|
354
|
-
source += escapeRegex(char ??
|
|
510
|
+
source += escapeRegex(char ?? "");
|
|
355
511
|
}
|
|
356
512
|
return new RegExp(`${source}$`);
|
|
357
513
|
}
|
|
358
514
|
function escapeRegex(value) {
|
|
359
|
-
return value.replace(/[|\\{}()[\]^$+*?.]/g,
|
|
515
|
+
return value.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&");
|
|
360
516
|
}
|
|
361
517
|
//# sourceMappingURL=tools.js.map
|