@theokit/sdk-tools 0.23.0 → 0.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +51 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +71 -1
- package/dist/index.d.ts +71 -1
- package/dist/index.js +51 -30
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -26,6 +26,11 @@ import { InteractiveProvider } from '@theokit/sdk/interactive';
|
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
28
|
interface CreateApplyPatchToolOptions {
|
|
29
|
+
/** M76 — nome exposto ao modelo. Omitido ⇒ o literal de hoje (aditivo). O nome é contrato: chave
|
|
30
|
+
* de approval, o que o modelo vê e o que o telemetry registra. */
|
|
31
|
+
name?: string;
|
|
32
|
+
/** M76 — descrição exposta ao modelo. Omitida ⇒ o literal de hoje (aditivo). */
|
|
33
|
+
description?: string;
|
|
29
34
|
/** Absolute path to the project root. Every hunk path is gated against this boundary. */
|
|
30
35
|
projectRoot: string;
|
|
31
36
|
}
|
|
@@ -101,6 +106,11 @@ declare function createSessionArtifactStore(options: SessionArtifactStoreOptions
|
|
|
101
106
|
*/
|
|
102
107
|
|
|
103
108
|
interface CreateCurrentTimeToolOptions {
|
|
109
|
+
/** M76 — nome exposto ao modelo. Omitido ⇒ o literal de hoje (aditivo). O nome é contrato: chave
|
|
110
|
+
* de approval, o que o modelo vê e o que o telemetry registra. */
|
|
111
|
+
name?: string;
|
|
112
|
+
/** M76 — descrição exposta ao modelo. Omitida ⇒ o literal de hoje (aditivo). */
|
|
113
|
+
description?: string;
|
|
104
114
|
/** Injectable clock — defaults to `() => new Date()`. Pass a fixed clock for deterministic tests. */
|
|
105
115
|
clock?: () => Date;
|
|
106
116
|
}
|
|
@@ -177,6 +187,11 @@ declare function formatError(message: string, code?: string): string;
|
|
|
177
187
|
*/
|
|
178
188
|
|
|
179
189
|
interface CreateGitDiffToolOptions {
|
|
190
|
+
/** M76 — nome exposto ao modelo. Omitido ⇒ o literal de hoje (aditivo). O nome é contrato: chave
|
|
191
|
+
* de approval, o que o modelo vê e o que o telemetry registra. */
|
|
192
|
+
name?: string;
|
|
193
|
+
/** M76 — descrição exposta ao modelo. Omitida ⇒ o literal de hoje (aditivo). */
|
|
194
|
+
description?: string;
|
|
180
195
|
projectRoot: string;
|
|
181
196
|
timeoutMs?: number;
|
|
182
197
|
maxStdoutBytes?: number;
|
|
@@ -209,6 +224,15 @@ interface CreateGitStatusToolOptions {
|
|
|
209
224
|
timeoutMs?: number;
|
|
210
225
|
/** Cap on captured stdout; excess sets `truncated: true`. Default 5 MB. */
|
|
211
226
|
maxStdoutBytes?: number;
|
|
227
|
+
/**
|
|
228
|
+
* Backend de execução injetado (`@theokit/sdk/sandbox`) — quando presente, `git status` roda via
|
|
229
|
+
* `SandboxBackend.execute`; omitido ⇒ o `git` local (inalterado).
|
|
230
|
+
*
|
|
231
|
+
* Simetria com `createGitDiffTool`, apontada pelo review do M76: sem isto `git_diff` rodaria
|
|
232
|
+
* confinado e `git_status` não, na mesma sessão — e a assimetria seria invisível até alguém
|
|
233
|
+
* perceber que uma das duas escapa do sandbox.
|
|
234
|
+
*/
|
|
235
|
+
sandbox?: SandboxProvider;
|
|
212
236
|
/**
|
|
213
237
|
* M76 — nome exposto ao modelo. Omitido ⇒ `"git_status"` (aditivo).
|
|
214
238
|
*
|
|
@@ -240,6 +264,11 @@ declare function createGitStatusTool(opts: CreateGitStatusToolOptions): CustomTo
|
|
|
240
264
|
*/
|
|
241
265
|
|
|
242
266
|
interface CreateGlobToolOptions {
|
|
267
|
+
/** M76 — nome exposto ao modelo. Omitido ⇒ o literal de hoje (aditivo). O nome é contrato: chave
|
|
268
|
+
* de approval, o que o modelo vê e o que o telemetry registra. */
|
|
269
|
+
name?: string;
|
|
270
|
+
/** M76 — descrição exposta ao modelo. Omitida ⇒ o literal de hoje (aditivo). */
|
|
271
|
+
description?: string;
|
|
243
272
|
/** Absolute path to the project root. */
|
|
244
273
|
projectRoot: string;
|
|
245
274
|
/** Optional injected filesystem (`@theokit/sdk/filesystem`) — when provided, the walk reads through the
|
|
@@ -267,6 +296,11 @@ declare function createGlobTool(opts: CreateGlobToolOptions): CustomTool;
|
|
|
267
296
|
*/
|
|
268
297
|
|
|
269
298
|
interface CreateInteractiveShellToolOptions {
|
|
299
|
+
/** M76 — nome exposto ao modelo. Omitido ⇒ o literal de hoje (aditivo). O nome é contrato: chave
|
|
300
|
+
* de approval, o que o modelo vê e o que o telemetry registra. */
|
|
301
|
+
name?: string;
|
|
302
|
+
/** M76 — descrição exposta ao modelo. Omitida ⇒ o literal de hoje (aditivo). */
|
|
303
|
+
description?: string;
|
|
270
304
|
/** The interactive backend, or a per-request resolver of one (injected — never a direct native dep). */
|
|
271
305
|
interactive: InteractiveProvider<unknown>;
|
|
272
306
|
}
|
|
@@ -662,6 +696,11 @@ interface PlanModeToolWithStore {
|
|
|
662
696
|
* @public
|
|
663
697
|
*/
|
|
664
698
|
interface PlanModeToolOptions {
|
|
699
|
+
/** M76 — nome exposto ao modelo. Omitido ⇒ o literal de hoje (aditivo). O nome é contrato: chave
|
|
700
|
+
* de approval, o que o modelo vê e o que o telemetry registra. */
|
|
701
|
+
name?: string;
|
|
702
|
+
/** M76 — descrição exposta ao modelo. Omitida ⇒ o literal de hoje (aditivo). */
|
|
703
|
+
description?: string;
|
|
665
704
|
/** Store the submitted `plan` is persisted to on `exit`. */
|
|
666
705
|
artifactStore: SessionArtifactStore;
|
|
667
706
|
/** Artifact id under which the plan is stored. Default `"plan"`. */
|
|
@@ -686,7 +725,13 @@ interface QuestionToolOptions {
|
|
|
686
725
|
* `CustomTool.handler` aponta como o problema que `ctx.context` existe para resolver. Este campo
|
|
687
726
|
* permanece como fallback, para quem constrói a tool com um asker fixo (retrocompatível).
|
|
688
727
|
*/
|
|
689
|
-
askUser?: (question: string) => Promise<string>;
|
|
728
|
+
askUser?: (question: string, threadId?: string) => Promise<string>;
|
|
729
|
+
/**
|
|
730
|
+
* Chamado quando a pergunta é ABANDONADA (timeout ou cancelamento da run), para que o lado da UI
|
|
731
|
+
* libere o slot. Sem ele o timeout deixa a pergunta pendente para sempre — a UI segue mostrando
|
|
732
|
+
* um prompt que ninguém aguarda e a próxima pergunta falha com "já há uma pendente".
|
|
733
|
+
*/
|
|
734
|
+
onAbandon?: (threadId?: string) => void;
|
|
690
735
|
/** Maximum time to wait for user response in ms. Default: 300_000 (5 min). */
|
|
691
736
|
timeoutMs?: number;
|
|
692
737
|
/**
|
|
@@ -773,6 +818,11 @@ declare class ReadTracker {
|
|
|
773
818
|
*/
|
|
774
819
|
|
|
775
820
|
interface CreateReadFileToolOptions {
|
|
821
|
+
/** M76 — nome exposto ao modelo. Omitido ⇒ o literal de hoje (aditivo). O nome é contrato: chave
|
|
822
|
+
* de approval, o que o modelo vê e o que o telemetry registra. */
|
|
823
|
+
name?: string;
|
|
824
|
+
/** M76 — descrição exposta ao modelo. Omitida ⇒ o literal de hoje (aditivo). */
|
|
825
|
+
description?: string;
|
|
776
826
|
/** Absolute path to the project root. Every read is gated against this boundary. */
|
|
777
827
|
projectRoot: string;
|
|
778
828
|
/**
|
|
@@ -852,6 +902,11 @@ declare class ReasoningTools {
|
|
|
852
902
|
*/
|
|
853
903
|
|
|
854
904
|
interface CreateRunVitestToolOptions {
|
|
905
|
+
/** M76 — nome exposto ao modelo. Omitido ⇒ o literal de hoje (aditivo). O nome é contrato: chave
|
|
906
|
+
* de approval, o que o modelo vê e o que o telemetry registra. */
|
|
907
|
+
name?: string;
|
|
908
|
+
/** M76 — descrição exposta ao modelo. Omitida ⇒ o literal de hoje (aditivo). */
|
|
909
|
+
description?: string;
|
|
855
910
|
projectRoot: string;
|
|
856
911
|
timeoutMs?: number;
|
|
857
912
|
maxStdoutBytes?: number;
|
|
@@ -1096,6 +1151,11 @@ declare function createUpdatePlanTool(): CustomTool;
|
|
|
1096
1151
|
*/
|
|
1097
1152
|
|
|
1098
1153
|
interface CreateWebFetchToolOptions {
|
|
1154
|
+
/** M76 — nome exposto ao modelo. Omitido ⇒ o literal de hoje (aditivo). O nome é contrato: chave
|
|
1155
|
+
* de approval, o que o modelo vê e o que o telemetry registra. */
|
|
1156
|
+
name?: string;
|
|
1157
|
+
/** M76 — descrição exposta ao modelo. Omitida ⇒ o literal de hoje (aditivo). */
|
|
1158
|
+
description?: string;
|
|
1099
1159
|
/** Default timeout in ms. */
|
|
1100
1160
|
defaultTimeoutMs?: number;
|
|
1101
1161
|
/**
|
|
@@ -1135,6 +1195,11 @@ interface WebSearchResult {
|
|
|
1135
1195
|
}
|
|
1136
1196
|
type WebSearchCallback = (query: string, maxResults: number) => Promise<WebSearchResult[]>;
|
|
1137
1197
|
interface CreateWebSearchToolOptions {
|
|
1198
|
+
/** M76 — nome exposto ao modelo. Omitido ⇒ o literal de hoje (aditivo). O nome é contrato: chave
|
|
1199
|
+
* de approval, o que o modelo vê e o que o telemetry registra. */
|
|
1200
|
+
name?: string;
|
|
1201
|
+
/** M76 — descrição exposta ao modelo. Omitida ⇒ o literal de hoje (aditivo). */
|
|
1202
|
+
description?: string;
|
|
1138
1203
|
/** Search provider callback — consumer injects the implementation. */
|
|
1139
1204
|
search: WebSearchCallback;
|
|
1140
1205
|
/** Default max results if not specified by the LLM. */
|
|
@@ -1224,6 +1289,11 @@ type WriteToolContext = {
|
|
|
1224
1289
|
context?: unknown;
|
|
1225
1290
|
};
|
|
1226
1291
|
interface CreateWriteFileToolOptions {
|
|
1292
|
+
/** M76 — nome exposto ao modelo. Omitido ⇒ o literal de hoje (aditivo). O nome é contrato: chave
|
|
1293
|
+
* de approval, o que o modelo vê e o que o telemetry registra. */
|
|
1294
|
+
name?: string;
|
|
1295
|
+
/** M76 — descrição exposta ao modelo. Omitida ⇒ o literal de hoje (aditivo). */
|
|
1296
|
+
description?: string;
|
|
1227
1297
|
/** Absolute path to the project root. Every write is gated against this boundary. */
|
|
1228
1298
|
projectRoot: string;
|
|
1229
1299
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -26,6 +26,11 @@ import { InteractiveProvider } from '@theokit/sdk/interactive';
|
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
28
|
interface CreateApplyPatchToolOptions {
|
|
29
|
+
/** M76 — nome exposto ao modelo. Omitido ⇒ o literal de hoje (aditivo). O nome é contrato: chave
|
|
30
|
+
* de approval, o que o modelo vê e o que o telemetry registra. */
|
|
31
|
+
name?: string;
|
|
32
|
+
/** M76 — descrição exposta ao modelo. Omitida ⇒ o literal de hoje (aditivo). */
|
|
33
|
+
description?: string;
|
|
29
34
|
/** Absolute path to the project root. Every hunk path is gated against this boundary. */
|
|
30
35
|
projectRoot: string;
|
|
31
36
|
}
|
|
@@ -101,6 +106,11 @@ declare function createSessionArtifactStore(options: SessionArtifactStoreOptions
|
|
|
101
106
|
*/
|
|
102
107
|
|
|
103
108
|
interface CreateCurrentTimeToolOptions {
|
|
109
|
+
/** M76 — nome exposto ao modelo. Omitido ⇒ o literal de hoje (aditivo). O nome é contrato: chave
|
|
110
|
+
* de approval, o que o modelo vê e o que o telemetry registra. */
|
|
111
|
+
name?: string;
|
|
112
|
+
/** M76 — descrição exposta ao modelo. Omitida ⇒ o literal de hoje (aditivo). */
|
|
113
|
+
description?: string;
|
|
104
114
|
/** Injectable clock — defaults to `() => new Date()`. Pass a fixed clock for deterministic tests. */
|
|
105
115
|
clock?: () => Date;
|
|
106
116
|
}
|
|
@@ -177,6 +187,11 @@ declare function formatError(message: string, code?: string): string;
|
|
|
177
187
|
*/
|
|
178
188
|
|
|
179
189
|
interface CreateGitDiffToolOptions {
|
|
190
|
+
/** M76 — nome exposto ao modelo. Omitido ⇒ o literal de hoje (aditivo). O nome é contrato: chave
|
|
191
|
+
* de approval, o que o modelo vê e o que o telemetry registra. */
|
|
192
|
+
name?: string;
|
|
193
|
+
/** M76 — descrição exposta ao modelo. Omitida ⇒ o literal de hoje (aditivo). */
|
|
194
|
+
description?: string;
|
|
180
195
|
projectRoot: string;
|
|
181
196
|
timeoutMs?: number;
|
|
182
197
|
maxStdoutBytes?: number;
|
|
@@ -209,6 +224,15 @@ interface CreateGitStatusToolOptions {
|
|
|
209
224
|
timeoutMs?: number;
|
|
210
225
|
/** Cap on captured stdout; excess sets `truncated: true`. Default 5 MB. */
|
|
211
226
|
maxStdoutBytes?: number;
|
|
227
|
+
/**
|
|
228
|
+
* Backend de execução injetado (`@theokit/sdk/sandbox`) — quando presente, `git status` roda via
|
|
229
|
+
* `SandboxBackend.execute`; omitido ⇒ o `git` local (inalterado).
|
|
230
|
+
*
|
|
231
|
+
* Simetria com `createGitDiffTool`, apontada pelo review do M76: sem isto `git_diff` rodaria
|
|
232
|
+
* confinado e `git_status` não, na mesma sessão — e a assimetria seria invisível até alguém
|
|
233
|
+
* perceber que uma das duas escapa do sandbox.
|
|
234
|
+
*/
|
|
235
|
+
sandbox?: SandboxProvider;
|
|
212
236
|
/**
|
|
213
237
|
* M76 — nome exposto ao modelo. Omitido ⇒ `"git_status"` (aditivo).
|
|
214
238
|
*
|
|
@@ -240,6 +264,11 @@ declare function createGitStatusTool(opts: CreateGitStatusToolOptions): CustomTo
|
|
|
240
264
|
*/
|
|
241
265
|
|
|
242
266
|
interface CreateGlobToolOptions {
|
|
267
|
+
/** M76 — nome exposto ao modelo. Omitido ⇒ o literal de hoje (aditivo). O nome é contrato: chave
|
|
268
|
+
* de approval, o que o modelo vê e o que o telemetry registra. */
|
|
269
|
+
name?: string;
|
|
270
|
+
/** M76 — descrição exposta ao modelo. Omitida ⇒ o literal de hoje (aditivo). */
|
|
271
|
+
description?: string;
|
|
243
272
|
/** Absolute path to the project root. */
|
|
244
273
|
projectRoot: string;
|
|
245
274
|
/** Optional injected filesystem (`@theokit/sdk/filesystem`) — when provided, the walk reads through the
|
|
@@ -267,6 +296,11 @@ declare function createGlobTool(opts: CreateGlobToolOptions): CustomTool;
|
|
|
267
296
|
*/
|
|
268
297
|
|
|
269
298
|
interface CreateInteractiveShellToolOptions {
|
|
299
|
+
/** M76 — nome exposto ao modelo. Omitido ⇒ o literal de hoje (aditivo). O nome é contrato: chave
|
|
300
|
+
* de approval, o que o modelo vê e o que o telemetry registra. */
|
|
301
|
+
name?: string;
|
|
302
|
+
/** M76 — descrição exposta ao modelo. Omitida ⇒ o literal de hoje (aditivo). */
|
|
303
|
+
description?: string;
|
|
270
304
|
/** The interactive backend, or a per-request resolver of one (injected — never a direct native dep). */
|
|
271
305
|
interactive: InteractiveProvider<unknown>;
|
|
272
306
|
}
|
|
@@ -662,6 +696,11 @@ interface PlanModeToolWithStore {
|
|
|
662
696
|
* @public
|
|
663
697
|
*/
|
|
664
698
|
interface PlanModeToolOptions {
|
|
699
|
+
/** M76 — nome exposto ao modelo. Omitido ⇒ o literal de hoje (aditivo). O nome é contrato: chave
|
|
700
|
+
* de approval, o que o modelo vê e o que o telemetry registra. */
|
|
701
|
+
name?: string;
|
|
702
|
+
/** M76 — descrição exposta ao modelo. Omitida ⇒ o literal de hoje (aditivo). */
|
|
703
|
+
description?: string;
|
|
665
704
|
/** Store the submitted `plan` is persisted to on `exit`. */
|
|
666
705
|
artifactStore: SessionArtifactStore;
|
|
667
706
|
/** Artifact id under which the plan is stored. Default `"plan"`. */
|
|
@@ -686,7 +725,13 @@ interface QuestionToolOptions {
|
|
|
686
725
|
* `CustomTool.handler` aponta como o problema que `ctx.context` existe para resolver. Este campo
|
|
687
726
|
* permanece como fallback, para quem constrói a tool com um asker fixo (retrocompatível).
|
|
688
727
|
*/
|
|
689
|
-
askUser?: (question: string) => Promise<string>;
|
|
728
|
+
askUser?: (question: string, threadId?: string) => Promise<string>;
|
|
729
|
+
/**
|
|
730
|
+
* Chamado quando a pergunta é ABANDONADA (timeout ou cancelamento da run), para que o lado da UI
|
|
731
|
+
* libere o slot. Sem ele o timeout deixa a pergunta pendente para sempre — a UI segue mostrando
|
|
732
|
+
* um prompt que ninguém aguarda e a próxima pergunta falha com "já há uma pendente".
|
|
733
|
+
*/
|
|
734
|
+
onAbandon?: (threadId?: string) => void;
|
|
690
735
|
/** Maximum time to wait for user response in ms. Default: 300_000 (5 min). */
|
|
691
736
|
timeoutMs?: number;
|
|
692
737
|
/**
|
|
@@ -773,6 +818,11 @@ declare class ReadTracker {
|
|
|
773
818
|
*/
|
|
774
819
|
|
|
775
820
|
interface CreateReadFileToolOptions {
|
|
821
|
+
/** M76 — nome exposto ao modelo. Omitido ⇒ o literal de hoje (aditivo). O nome é contrato: chave
|
|
822
|
+
* de approval, o que o modelo vê e o que o telemetry registra. */
|
|
823
|
+
name?: string;
|
|
824
|
+
/** M76 — descrição exposta ao modelo. Omitida ⇒ o literal de hoje (aditivo). */
|
|
825
|
+
description?: string;
|
|
776
826
|
/** Absolute path to the project root. Every read is gated against this boundary. */
|
|
777
827
|
projectRoot: string;
|
|
778
828
|
/**
|
|
@@ -852,6 +902,11 @@ declare class ReasoningTools {
|
|
|
852
902
|
*/
|
|
853
903
|
|
|
854
904
|
interface CreateRunVitestToolOptions {
|
|
905
|
+
/** M76 — nome exposto ao modelo. Omitido ⇒ o literal de hoje (aditivo). O nome é contrato: chave
|
|
906
|
+
* de approval, o que o modelo vê e o que o telemetry registra. */
|
|
907
|
+
name?: string;
|
|
908
|
+
/** M76 — descrição exposta ao modelo. Omitida ⇒ o literal de hoje (aditivo). */
|
|
909
|
+
description?: string;
|
|
855
910
|
projectRoot: string;
|
|
856
911
|
timeoutMs?: number;
|
|
857
912
|
maxStdoutBytes?: number;
|
|
@@ -1096,6 +1151,11 @@ declare function createUpdatePlanTool(): CustomTool;
|
|
|
1096
1151
|
*/
|
|
1097
1152
|
|
|
1098
1153
|
interface CreateWebFetchToolOptions {
|
|
1154
|
+
/** M76 — nome exposto ao modelo. Omitido ⇒ o literal de hoje (aditivo). O nome é contrato: chave
|
|
1155
|
+
* de approval, o que o modelo vê e o que o telemetry registra. */
|
|
1156
|
+
name?: string;
|
|
1157
|
+
/** M76 — descrição exposta ao modelo. Omitida ⇒ o literal de hoje (aditivo). */
|
|
1158
|
+
description?: string;
|
|
1099
1159
|
/** Default timeout in ms. */
|
|
1100
1160
|
defaultTimeoutMs?: number;
|
|
1101
1161
|
/**
|
|
@@ -1135,6 +1195,11 @@ interface WebSearchResult {
|
|
|
1135
1195
|
}
|
|
1136
1196
|
type WebSearchCallback = (query: string, maxResults: number) => Promise<WebSearchResult[]>;
|
|
1137
1197
|
interface CreateWebSearchToolOptions {
|
|
1198
|
+
/** M76 — nome exposto ao modelo. Omitido ⇒ o literal de hoje (aditivo). O nome é contrato: chave
|
|
1199
|
+
* de approval, o que o modelo vê e o que o telemetry registra. */
|
|
1200
|
+
name?: string;
|
|
1201
|
+
/** M76 — descrição exposta ao modelo. Omitida ⇒ o literal de hoje (aditivo). */
|
|
1202
|
+
description?: string;
|
|
1138
1203
|
/** Search provider callback — consumer injects the implementation. */
|
|
1139
1204
|
search: WebSearchCallback;
|
|
1140
1205
|
/** Default max results if not specified by the LLM. */
|
|
@@ -1224,6 +1289,11 @@ type WriteToolContext = {
|
|
|
1224
1289
|
context?: unknown;
|
|
1225
1290
|
};
|
|
1226
1291
|
interface CreateWriteFileToolOptions {
|
|
1292
|
+
/** M76 — nome exposto ao modelo. Omitido ⇒ o literal de hoje (aditivo). O nome é contrato: chave
|
|
1293
|
+
* de approval, o que o modelo vê e o que o telemetry registra. */
|
|
1294
|
+
name?: string;
|
|
1295
|
+
/** M76 — descrição exposta ao modelo. Omitida ⇒ o literal de hoje (aditivo). */
|
|
1296
|
+
description?: string;
|
|
1227
1297
|
/** Absolute path to the project root. Every write is gated against this boundary. */
|
|
1228
1298
|
projectRoot: string;
|
|
1229
1299
|
/**
|
package/dist/index.js
CHANGED
|
@@ -225,8 +225,8 @@ ${chunk.oldLines.join("\n")}`
|
|
|
225
225
|
function createApplyPatchTool(opts) {
|
|
226
226
|
const { projectRoot } = opts;
|
|
227
227
|
return Tool.create({
|
|
228
|
-
name: "apply_patch",
|
|
229
|
-
description: "Apply a Codex-style V4A patch. The patch is `*** Begin Patch` \u2026 `*** End Patch` wrapping one or more hunks: `*** Add File: <path>` (then `+`lines), `*** Delete File: <path>`, or `*** Update File: <path>` (optional `*** Move to: <path>`) with `@@`-anchored `+` (add) / `-` (remove) / ` ` (context) lines. Read a file first so your context/removed lines match. Applied atomically \u2014 a mismatch anywhere aborts the whole patch with zero writes; each path is security-checked. Returns { ok, files_patched } or { ok: false, error }.",
|
|
228
|
+
name: opts.name ?? "apply_patch",
|
|
229
|
+
description: opts.description ?? "Apply a Codex-style V4A patch. The patch is `*** Begin Patch` \u2026 `*** End Patch` wrapping one or more hunks: `*** Add File: <path>` (then `+`lines), `*** Delete File: <path>`, or `*** Update File: <path>` (optional `*** Move to: <path>`) with `@@`-anchored `+` (add) / `-` (remove) / ` ` (context) lines. Read a file first so your context/removed lines match. Applied atomically \u2014 a mismatch anywhere aborts the whole patch with zero writes; each path is security-checked. Returns { ok, files_patched } or { ok: false, error }.",
|
|
230
230
|
inputSchema: z.object({
|
|
231
231
|
patch: z.string().min(1).describe("V4A patch: *** Begin Patch \u2026 *** End Patch.")
|
|
232
232
|
}),
|
|
@@ -427,8 +427,8 @@ function formatInTimezone(now, tz) {
|
|
|
427
427
|
function createCurrentTimeTool(opts = {}) {
|
|
428
428
|
const clock = opts.clock ?? (() => /* @__PURE__ */ new Date());
|
|
429
429
|
return Tool.create({
|
|
430
|
-
name: "current_time",
|
|
431
|
-
description: "Get the current date and time. Returns { current_time, iso, timezone } as a JSON string, where current_time is 'YYYY-MM-DD HH:MM:SS <timezone>' and iso is the ISO-8601 instant. Pass an optional IANA timezone (e.g. 'America/Sao_Paulo', 'Europe/Lisbon'); defaults to UTC. Never state the date or time from memory \u2014 always call this. Returns { ok: false, error: 'invalid_timezone' } for an unknown timezone.",
|
|
430
|
+
name: opts.name ?? "current_time",
|
|
431
|
+
description: opts.description ?? "Get the current date and time. Returns { current_time, iso, timezone } as a JSON string, where current_time is 'YYYY-MM-DD HH:MM:SS <timezone>' and iso is the ISO-8601 instant. Pass an optional IANA timezone (e.g. 'America/Sao_Paulo', 'Europe/Lisbon'); defaults to UTC. Never state the date or time from memory \u2014 always call this. Returns { ok: false, error: 'invalid_timezone' } for an unknown timezone.",
|
|
432
432
|
inputSchema: z.object({
|
|
433
433
|
timezone: z.string().optional().describe("IANA timezone, e.g. 'America/Sao_Paulo' or 'Europe/Lisbon'. Defaults to UTC.")
|
|
434
434
|
}),
|
|
@@ -718,6 +718,9 @@ function attachChildSettlers(child, gate, onClose, onError, resolve) {
|
|
|
718
718
|
}
|
|
719
719
|
|
|
720
720
|
// src/internal/git-exec.ts
|
|
721
|
+
function shq(arg) {
|
|
722
|
+
return `'${arg.replaceAll("'", `'\\''`)}'`;
|
|
723
|
+
}
|
|
721
724
|
function formatGitResult(result, timeoutMs) {
|
|
722
725
|
if (result.kind === "timeout") {
|
|
723
726
|
return JSON.stringify({ ok: false, error: "timeout", timeoutMs });
|
|
@@ -799,9 +802,6 @@ function ehProibidoEmQualquerProfundidade(path) {
|
|
|
799
802
|
// src/git-diff.ts
|
|
800
803
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
801
804
|
var DEFAULT_MAX_STDOUT_BYTES = 5 * 1024 * 1024;
|
|
802
|
-
function shq(arg) {
|
|
803
|
-
return `'${arg.replace(/'/g, `'\\''`)}'`;
|
|
804
|
-
}
|
|
805
805
|
async function diffViaSandbox(sandbox, ctx, cached, path, projectRoot, timeoutMs) {
|
|
806
806
|
const scopeCheck = checkPathScope(path, projectRoot);
|
|
807
807
|
if (scopeCheck !== null) return scopeCheck;
|
|
@@ -822,8 +822,8 @@ function createGitDiffTool(opts) {
|
|
|
822
822
|
sandbox
|
|
823
823
|
} = opts;
|
|
824
824
|
return Tool.create({
|
|
825
|
-
name: "git_diff",
|
|
826
|
-
description: "Return the unified diff of the project's working tree (or staged changes when cached=true). Scoped to a single file when 'path' is provided. Requires the project to be a git repository. Returns { ok, diff, truncated? } or { ok: false, error }.",
|
|
825
|
+
name: opts.name ?? "git_diff",
|
|
826
|
+
description: opts.description ?? "Return the unified diff of the project's working tree (or staged changes when cached=true). Scoped to a single file when 'path' is provided. Requires the project to be a git repository. Returns { ok, diff, truncated? } or { ok: false, error }.",
|
|
827
827
|
inputSchema: z.object({
|
|
828
828
|
path: z.string().optional().describe("Optional project-relative file or dir scope."),
|
|
829
829
|
cached: z.boolean().optional().describe("If true, show staged changes (git diff --cached). Default false.")
|
|
@@ -857,27 +857,44 @@ function createGitStatusTool(opts) {
|
|
|
857
857
|
inputSchema: z.object({
|
|
858
858
|
path: z.string().optional().describe("Optional project-relative path to scope the status report.")
|
|
859
859
|
}),
|
|
860
|
-
handler: async ({ path }) => {
|
|
860
|
+
handler: async ({ path }, ctx) => {
|
|
861
861
|
if (!existsSync(join(projectRoot, ".git"))) {
|
|
862
862
|
return JSON.stringify({ ok: false, error: "not_a_repo" });
|
|
863
863
|
}
|
|
864
864
|
const scopeCheck = checkPathScope(path, projectRoot);
|
|
865
865
|
if (scopeCheck !== null) return scopeCheck;
|
|
866
|
-
const args =
|
|
867
|
-
if (opts.
|
|
868
|
-
|
|
866
|
+
const args = montarArgs(path, opts.includeBranch !== false);
|
|
867
|
+
if (opts.sandbox !== void 0) {
|
|
868
|
+
return statusViaSandbox(opts.sandbox, ctx, args, timeoutMs);
|
|
869
|
+
}
|
|
869
870
|
const result = await runGitProcess(projectRoot, args, timeoutMs, maxStdoutBytes);
|
|
870
871
|
return formatGitResult(result, timeoutMs);
|
|
871
872
|
}
|
|
872
873
|
});
|
|
873
874
|
}
|
|
875
|
+
function montarArgs(path, comBranch) {
|
|
876
|
+
const args = ["status", "--porcelain=v1"];
|
|
877
|
+
if (comBranch) args.push("-b");
|
|
878
|
+
if (path !== void 0 && path !== "") args.push("--", path);
|
|
879
|
+
return args;
|
|
880
|
+
}
|
|
881
|
+
async function statusViaSandbox(sandbox, ctx, args, timeoutMs) {
|
|
882
|
+
const command = ["git", ...args].map(shq).join(" ");
|
|
883
|
+
const backend = await resolveSandbox(sandbox, ctx ?? {});
|
|
884
|
+
const r = await backend.execute(command, { timeoutMs });
|
|
885
|
+
if (r.timedOut) return JSON.stringify({ ok: false, error: "timeout", timeoutMs });
|
|
886
|
+
if (r.exitCode !== 0) {
|
|
887
|
+
return /not a git repository/i.test(r.stderr) ? JSON.stringify({ ok: false, error: "not_a_repo" }) : JSON.stringify({ ok: false, error: "git_failed", stderr: r.stderr });
|
|
888
|
+
}
|
|
889
|
+
return JSON.stringify({ ok: true, diff: r.stdout, truncated: false });
|
|
890
|
+
}
|
|
874
891
|
var DEFAULT_EXCLUDES = /* @__PURE__ */ new Set(["node_modules", ".git", "dist", ".theo"]);
|
|
875
892
|
var MAX_BACKEND_WALK_DEPTH = 64;
|
|
876
893
|
function createGlobTool(opts) {
|
|
877
894
|
const { projectRoot, filesystem } = opts;
|
|
878
895
|
return Tool.create({
|
|
879
|
-
name: "glob_files",
|
|
880
|
-
description: "Find files by glob pattern across the project \u2014 fast at any repo size. Use glob_files when you know the filename SHAPE; use search_text when you know the file CONTENT; use read_file when you know the exact path. The pattern supports * and ** wildcards (e.g. '**/*.ts', 'src/**/*.json'); node_modules/.git/dist/.theo are excluded and results are relative paths. Returns { ok, files } or { ok: false, error }.",
|
|
896
|
+
name: opts.name ?? "glob_files",
|
|
897
|
+
description: opts.description ?? "Find files by glob pattern across the project \u2014 fast at any repo size. Use glob_files when you know the filename SHAPE; use search_text when you know the file CONTENT; use read_file when you know the exact path. The pattern supports * and ** wildcards (e.g. '**/*.ts', 'src/**/*.json'); node_modules/.git/dist/.theo are excluded and results are relative paths. Returns { ok, files } or { ok: false, error }.",
|
|
881
898
|
inputSchema: z.object({
|
|
882
899
|
pattern: z.string().min(1).describe("Glob pattern (e.g. '**/*.ts', 'src/**/*.json')."),
|
|
883
900
|
cwd: z.string().optional().describe("Project-relative subdirectory to search from.")
|
|
@@ -996,8 +1013,8 @@ function toErrorJson(err) {
|
|
|
996
1013
|
function createInteractiveShellTool(opts) {
|
|
997
1014
|
const { interactive } = opts;
|
|
998
1015
|
return Tool.create({
|
|
999
|
-
name: "interactive_shell",
|
|
1000
|
-
description: "Start an interactive shell session for a command that PROMPTS for input or is a REPL (python, node, `git rebase -i`, a `read` prompt) \u2014 NOT for one-shot commands (use shell_exec). Returns a session_id; drive it with write_stdin, reading the incremental output each step. Returns { ok, session_id, output } or { ok: false, error }.",
|
|
1016
|
+
name: opts.name ?? "interactive_shell",
|
|
1017
|
+
description: opts.description ?? "Start an interactive shell session for a command that PROMPTS for input or is a REPL (python, node, `git rebase -i`, a `read` prompt) \u2014 NOT for one-shot commands (use shell_exec). Returns a session_id; drive it with write_stdin, reading the incremental output each step. Returns { ok, session_id, output } or { ok: false, error }.",
|
|
1001
1018
|
inputSchema: z.object({
|
|
1002
1019
|
command: z.string().min(1).describe("Command to run interactively, e.g. 'python3' or 'bash -i'."),
|
|
1003
1020
|
yield_time_ms: z.number().int().positive().optional().describe("How long to wait for startup output before returning (clamped by the backend).")
|
|
@@ -1701,8 +1718,8 @@ function createPlanModeTool(options) {
|
|
|
1701
1718
|
}
|
|
1702
1719
|
const { artifactStore, artifactId = "plan" } = options;
|
|
1703
1720
|
return {
|
|
1704
|
-
name: "plan_mode",
|
|
1705
|
-
description: DESCRIPTION,
|
|
1721
|
+
name: options.name ?? "plan_mode",
|
|
1722
|
+
description: options.description ?? DESCRIPTION,
|
|
1706
1723
|
inputSchema: planModeSchema(true),
|
|
1707
1724
|
handler: async (input) => {
|
|
1708
1725
|
if (input.action === "enter") {
|
|
@@ -1760,10 +1777,14 @@ function createQuestionTool(opts) {
|
|
|
1760
1777
|
setTimeout(() => reject(new Error("timeout")), timeoutMs);
|
|
1761
1778
|
});
|
|
1762
1779
|
try {
|
|
1763
|
-
const answer = await Promise.race([
|
|
1780
|
+
const answer = await Promise.race([
|
|
1781
|
+
askUser(String(input.question ?? ""), ctx?.threadId),
|
|
1782
|
+
timeout
|
|
1783
|
+
]);
|
|
1764
1784
|
return JSON.stringify({ ok: true, answer });
|
|
1765
1785
|
} catch (err) {
|
|
1766
1786
|
if (err instanceof Error && err.message === "timeout") {
|
|
1787
|
+
opts.onAbandon?.(ctx?.threadId);
|
|
1767
1788
|
return JSON.stringify({
|
|
1768
1789
|
ok: false,
|
|
1769
1790
|
error: "timeout",
|
|
@@ -1808,8 +1829,8 @@ function createReadFileTool(opts) {
|
|
|
1808
1829
|
const numbered = lineNumbers === true ? " Returns a cat -n numbered view (`<n>\\t<line>`)." : "";
|
|
1809
1830
|
const abs = allowAbsolute === true ? " Absolute paths outside the project are honored." : "";
|
|
1810
1831
|
return Tool.create({
|
|
1811
|
-
name: "read_file",
|
|
1812
|
-
description: "Read a text file as UTF-8. ALWAYS read a file before you edit it (edit_file) or overwrite it (write_file), so your old_string / new content matches the real bytes exactly." + numbered + abs + " By default returns the whole file; use the optional offset (1-based first line) + limit to page through a large file, or search_text to locate a symbol. Refuses sensitive files (.env, .git/, node_modules/, .theo/, lock files) and binary files (null byte in the first 8 KB); caps at 5 MB. Returns { ok, content, size } or { ok: false, error }.",
|
|
1832
|
+
name: opts.name ?? "read_file",
|
|
1833
|
+
description: opts.description ?? "Read a text file as UTF-8. ALWAYS read a file before you edit it (edit_file) or overwrite it (write_file), so your old_string / new content matches the real bytes exactly." + numbered + abs + " By default returns the whole file; use the optional offset (1-based first line) + limit to page through a large file, or search_text to locate a symbol. Refuses sensitive files (.env, .git/, node_modules/, .theo/, lock files) and binary files (null byte in the first 8 KB); caps at 5 MB. Returns { ok, content, size } or { ok: false, error }.",
|
|
1813
1834
|
inputSchema: z.object({
|
|
1814
1835
|
path: z.string().min(1).describe("File path (project-relative; absolute when allowed)."),
|
|
1815
1836
|
offset: z.number().int().min(1).optional().describe("1-based first line to read (default 1)."),
|
|
@@ -1983,8 +2004,8 @@ function createRunVitestTool(opts) {
|
|
|
1983
2004
|
maxStdoutBytes = DEFAULT_MAX_STDOUT_BYTES2
|
|
1984
2005
|
} = opts;
|
|
1985
2006
|
return Tool.create({
|
|
1986
|
-
name: "run_vitest",
|
|
1987
|
-
description: "Run the project's vitest suite, optionally scoped to a file or pattern via 'path'. Returns parsed { ok, summary } or { ok: false, error }. Vitest stdout warnings are stripped \u2014 the parser extracts the trailing JSON report.",
|
|
2007
|
+
name: opts.name ?? "run_vitest",
|
|
2008
|
+
description: opts.description ?? "Run the project's vitest suite, optionally scoped to a file or pattern via 'path'. Returns parsed { ok, summary } or { ok: false, error }. Vitest stdout warnings are stripped \u2014 the parser extracts the trailing JSON report.",
|
|
1988
2009
|
inputSchema: z.object({
|
|
1989
2010
|
path: z.string().optional().describe("Optional vitest pattern or file path (project-relative).")
|
|
1990
2011
|
}),
|
|
@@ -2581,8 +2602,8 @@ function createWebFetchTool(opts) {
|
|
|
2581
2602
|
const fetchImpl = opts?.fetchImpl;
|
|
2582
2603
|
const lookup = opts?.lookup;
|
|
2583
2604
|
return Tool.create({
|
|
2584
|
-
name: "web_fetch",
|
|
2585
|
-
description: "Fetch the contents of a URL via HTTP/HTTPS. Use only for URLs the user provided or that you are confident help with the task; never invent or guess URLs. Rejects non-http(s) URLs and is SSRF-guarded by default (private/loopback/link-local/cloud-metadata hosts are refused with an ssrf_blocked error). The response body is capped at 1 MB. Returns { ok, content, status_code, content_type } or { ok: false, error }.",
|
|
2605
|
+
name: opts?.name ?? "web_fetch",
|
|
2606
|
+
description: opts?.description ?? "Fetch the contents of a URL via HTTP/HTTPS. Use only for URLs the user provided or that you are confident help with the task; never invent or guess URLs. Rejects non-http(s) URLs and is SSRF-guarded by default (private/loopback/link-local/cloud-metadata hosts are refused with an ssrf_blocked error). The response body is capped at 1 MB. Returns { ok, content, status_code, content_type } or { ok: false, error }.",
|
|
2586
2607
|
inputSchema: z.object({
|
|
2587
2608
|
url: z.string().min(1).describe("URL to fetch (http or https only)."),
|
|
2588
2609
|
timeout_ms: z.number().int().positive().optional().describe("Timeout in milliseconds (default 30000).")
|
|
@@ -2668,8 +2689,8 @@ function createWebFetchTool(opts) {
|
|
|
2668
2689
|
function createWebSearchTool(opts) {
|
|
2669
2690
|
const { search, defaultMaxResults = 5 } = opts;
|
|
2670
2691
|
return Tool.create({
|
|
2671
|
-
name: "web_search",
|
|
2672
|
-
description: "Search the web for a query \u2014 use when you need current information beyond the repo or your training cutoff (library docs, an error message, an API). Returns a list of results with title, URL, and snippet; follow up with web_fetch on a promising result to read it in full. The search provider is injected by the consumer. Returns { ok, results } or { ok: false, error }.",
|
|
2692
|
+
name: opts.name ?? "web_search",
|
|
2693
|
+
description: opts.description ?? "Search the web for a query \u2014 use when you need current information beyond the repo or your training cutoff (library docs, an error message, an API). Returns a list of results with title, URL, and snippet; follow up with web_fetch on a promising result to read it in full. The search provider is injected by the consumer. Returns { ok, results } or { ok: false, error }.",
|
|
2673
2694
|
inputSchema: z.object({
|
|
2674
2695
|
query: z.string().min(1).describe("Search query."),
|
|
2675
2696
|
max_results: z.number().int().positive().max(20).optional().describe("Maximum results to return (default 5, max 20).")
|
|
@@ -2755,8 +2776,8 @@ function createWriteFileTool(opts) {
|
|
|
2755
2776
|
}
|
|
2756
2777
|
const guard = opts.requireReadBeforeWrite ? opts.readTracker : void 0;
|
|
2757
2778
|
return Tool.create({
|
|
2758
|
-
name: "write_file",
|
|
2759
|
-
description: "Write UTF-8 content to a project-relative file, creating parent directories as needed. OVERWRITES any existing file at the path. Prefer editing an existing file with edit_file over rewriting it; use write_file to create a NEW file or fully replace a small one. If the file already exists, read_file it first so you do not discard content you have not seen. Refuses paths that escape the write root and sensitive files (.env, .git/, node_modules/, .theo/, lock files); the default local root also refuses binary-file overwrites. Returns { ok, path, bytes } or { ok: false, error }.",
|
|
2779
|
+
name: opts.name ?? "write_file",
|
|
2780
|
+
description: opts.description ?? "Write UTF-8 content to a project-relative file, creating parent directories as needed. OVERWRITES any existing file at the path. Prefer editing an existing file with edit_file over rewriting it; use write_file to create a NEW file or fully replace a small one. If the file already exists, read_file it first so you do not discard content you have not seen. Refuses paths that escape the write root and sensitive files (.env, .git/, node_modules/, .theo/, lock files); the default local root also refuses binary-file overwrites. Returns { ok, path, bytes } or { ok: false, error }.",
|
|
2760
2781
|
inputSchema: z.object({
|
|
2761
2782
|
path: z.string().min(1).describe("Project-relative file path."),
|
|
2762
2783
|
content: z.string().describe("UTF-8 content to write.")
|