@modelrelay/sdk 4.0.0 → 5.3.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/README.md +19 -64
- package/dist/api-7TVb2cnl.d.cts +5319 -0
- package/dist/api-7TVb2cnl.d.ts +5319 -0
- package/dist/{api-CzFaWgs_.d.cts → api-B9x3HA3Z.d.cts} +10 -13
- package/dist/{api-CzFaWgs_.d.ts → api-B9x3HA3Z.d.ts} +10 -13
- package/dist/api-BRAJe_xm.d.cts +5315 -0
- package/dist/api-BRAJe_xm.d.ts +5315 -0
- package/dist/{api-jqOwvH6O.d.cts → api-HVh8Lusf.d.cts} +2650 -2111
- package/dist/{api-jqOwvH6O.d.ts → api-HVh8Lusf.d.ts} +2650 -2111
- package/dist/billing/index.d.cts +1 -1
- package/dist/billing/index.d.ts +1 -1
- package/dist/{chunk-EMQKOEF3.js → chunk-BL7GWXRZ.js} +1 -1
- package/dist/{chunk-ADQ74R7T.js → chunk-G5H7EY4F.js} +16 -14
- package/dist/{chunk-LW6SC7NQ.js → chunk-HLJAMT7F.js} +1 -1
- package/dist/{chunk-ZBQKY2W2.js → chunk-LZDGY24E.js} +2 -63
- package/dist/chunk-OJFVI3QJ.js +1133 -0
- package/dist/chunk-Z6R4G2TU.js +1133 -0
- package/dist/index.cjs +192 -504
- package/dist/index.d.cts +179 -623
- package/dist/index.d.ts +179 -623
- package/dist/index.js +185 -496
- package/dist/node.cjs +155 -2
- package/dist/node.d.cts +9 -0
- package/dist/node.d.ts +9 -0
- package/dist/node.js +155 -2
- package/dist/{tools-DAqAFZ8F.d.ts → tools-Db-F5rIL.d.cts} +6 -9
- package/dist/{tools-DAqAFZ8F.d.cts → tools-Db-F5rIL.d.ts} +6 -9
- package/package.json +1 -1
- package/dist/tools-Cnl2MgVa.d.cts +0 -1174
- package/dist/tools-Cnl2MgVa.d.ts +0 -1174
package/dist/node.cjs
CHANGED
|
@@ -52,7 +52,7 @@ var import_child_process = require("child_process");
|
|
|
52
52
|
// package.json
|
|
53
53
|
var package_default = {
|
|
54
54
|
name: "@modelrelay/sdk",
|
|
55
|
-
version: "
|
|
55
|
+
version: "5.3.0",
|
|
56
56
|
description: "TypeScript SDK for the ModelRelay API",
|
|
57
57
|
type: "module",
|
|
58
58
|
main: "dist/index.cjs",
|
|
@@ -293,7 +293,8 @@ var ToolRegistry = class {
|
|
|
293
293
|
var ToolNames = {
|
|
294
294
|
FS_READ_FILE: "fs.read_file",
|
|
295
295
|
FS_LIST_FILES: "fs.list_files",
|
|
296
|
-
FS_SEARCH: "fs.search"
|
|
296
|
+
FS_SEARCH: "fs.search",
|
|
297
|
+
FS_EDIT: "fs.edit"
|
|
297
298
|
};
|
|
298
299
|
var FSDefaults = {
|
|
299
300
|
MAX_READ_BYTES: 64e3,
|
|
@@ -411,6 +412,36 @@ var LocalFSToolPack = class {
|
|
|
411
412
|
required: ["query"]
|
|
412
413
|
}
|
|
413
414
|
}
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
type: "function",
|
|
418
|
+
function: {
|
|
419
|
+
name: ToolNames.FS_EDIT,
|
|
420
|
+
description: "Replace exact string matches in a file. Returns a confirmation with affected line numbers.",
|
|
421
|
+
parameters: {
|
|
422
|
+
type: "object",
|
|
423
|
+
properties: {
|
|
424
|
+
path: {
|
|
425
|
+
type: "string",
|
|
426
|
+
description: "Workspace-relative path to the file (e.g., 'src/index.ts')"
|
|
427
|
+
},
|
|
428
|
+
old_string: {
|
|
429
|
+
type: "string",
|
|
430
|
+
description: "Exact string to find and replace"
|
|
431
|
+
},
|
|
432
|
+
new_string: {
|
|
433
|
+
type: "string",
|
|
434
|
+
description: "Replacement string (may be empty)"
|
|
435
|
+
},
|
|
436
|
+
replace_all: {
|
|
437
|
+
type: "boolean",
|
|
438
|
+
default: false,
|
|
439
|
+
description: "Replace all occurrences (default: replace first only)"
|
|
440
|
+
}
|
|
441
|
+
},
|
|
442
|
+
required: ["path", "old_string", "new_string"]
|
|
443
|
+
}
|
|
444
|
+
}
|
|
414
445
|
}
|
|
415
446
|
];
|
|
416
447
|
}
|
|
@@ -423,6 +454,7 @@ var LocalFSToolPack = class {
|
|
|
423
454
|
registry.register(ToolNames.FS_READ_FILE, this.readFile.bind(this));
|
|
424
455
|
registry.register(ToolNames.FS_LIST_FILES, this.listFiles.bind(this));
|
|
425
456
|
registry.register(ToolNames.FS_SEARCH, this.search.bind(this));
|
|
457
|
+
registry.register(ToolNames.FS_EDIT, this.editFile.bind(this));
|
|
426
458
|
return registry;
|
|
427
459
|
}
|
|
428
460
|
/**
|
|
@@ -542,6 +574,41 @@ var LocalFSToolPack = class {
|
|
|
542
574
|
}
|
|
543
575
|
return this.searchWithJS(query, absPath, maxMatches, call);
|
|
544
576
|
}
|
|
577
|
+
async editFile(_args, call) {
|
|
578
|
+
const args = this.parseArgs(call, [
|
|
579
|
+
"path",
|
|
580
|
+
"old_string"
|
|
581
|
+
]);
|
|
582
|
+
const func = call.function;
|
|
583
|
+
const relPath = this.requireString(args, "path", call);
|
|
584
|
+
const oldString = this.requireString(args, "old_string", call);
|
|
585
|
+
const newString = this.requireStringAllowEmpty(args, "new_string", call);
|
|
586
|
+
const replaceAll = this.optionalBoolean(args, "replace_all", call) ?? false;
|
|
587
|
+
const absPath = await this.resolveAndValidatePath(relPath, call);
|
|
588
|
+
const stat = await import_fs.promises.stat(absPath);
|
|
589
|
+
if (stat.isDirectory()) {
|
|
590
|
+
throw new Error(`fs.edit: path is a directory: ${relPath}`);
|
|
591
|
+
}
|
|
592
|
+
const data = await import_fs.promises.readFile(absPath);
|
|
593
|
+
if (!this.isValidUtf8(data)) {
|
|
594
|
+
throw new Error(`fs.edit: file is not valid UTF-8: ${relPath}`);
|
|
595
|
+
}
|
|
596
|
+
const contents = data.toString("utf-8");
|
|
597
|
+
const matches = this.findOccurrences(contents, oldString);
|
|
598
|
+
if (matches.length === 0) {
|
|
599
|
+
throw new Error("fs.edit: old_string not found");
|
|
600
|
+
}
|
|
601
|
+
if (!replaceAll && matches.length > 1) {
|
|
602
|
+
throw new Error("fs.edit: old_string appears multiple times");
|
|
603
|
+
}
|
|
604
|
+
const appliedMatches = replaceAll ? matches : matches.slice(0, 1);
|
|
605
|
+
const updated = replaceAll ? contents.split(oldString).join(newString) : contents.replace(oldString, newString);
|
|
606
|
+
await import_fs.promises.writeFile(absPath, updated);
|
|
607
|
+
const lineSpec = this.formatLineRanges(
|
|
608
|
+
this.buildLineRanges(contents, appliedMatches, oldString.length)
|
|
609
|
+
);
|
|
610
|
+
return `Edited ${relPath} (replacements=${appliedMatches.length}, lines ${lineSpec})`;
|
|
611
|
+
}
|
|
545
612
|
// ========================================================================
|
|
546
613
|
// Path Safety
|
|
547
614
|
// ========================================================================
|
|
@@ -821,6 +888,16 @@ var LocalFSToolPack = class {
|
|
|
821
888
|
}
|
|
822
889
|
return value;
|
|
823
890
|
}
|
|
891
|
+
requireStringAllowEmpty(args, key, call) {
|
|
892
|
+
const value = args[key];
|
|
893
|
+
if (value === void 0 || value === null) {
|
|
894
|
+
this.toolArgumentError(call, `${key} is required`);
|
|
895
|
+
}
|
|
896
|
+
if (typeof value !== "string") {
|
|
897
|
+
this.toolArgumentError(call, `${key} must be a string`);
|
|
898
|
+
}
|
|
899
|
+
return value;
|
|
900
|
+
}
|
|
824
901
|
optionalString(args, key, call) {
|
|
825
902
|
const value = args[key];
|
|
826
903
|
if (value === void 0 || value === null) {
|
|
@@ -848,6 +925,82 @@ var LocalFSToolPack = class {
|
|
|
848
925
|
}
|
|
849
926
|
return value;
|
|
850
927
|
}
|
|
928
|
+
optionalBoolean(args, key, call) {
|
|
929
|
+
const value = args[key];
|
|
930
|
+
if (value === void 0 || value === null) {
|
|
931
|
+
return void 0;
|
|
932
|
+
}
|
|
933
|
+
if (typeof value !== "boolean") {
|
|
934
|
+
this.toolArgumentError(call, `${key} must be a boolean`);
|
|
935
|
+
}
|
|
936
|
+
return value;
|
|
937
|
+
}
|
|
938
|
+
findOccurrences(haystack, needle) {
|
|
939
|
+
if (needle.length === 0) {
|
|
940
|
+
return [];
|
|
941
|
+
}
|
|
942
|
+
const out = [];
|
|
943
|
+
let idx = 0;
|
|
944
|
+
for (; ; ) {
|
|
945
|
+
const found = haystack.indexOf(needle, idx);
|
|
946
|
+
if (found === -1) {
|
|
947
|
+
break;
|
|
948
|
+
}
|
|
949
|
+
out.push(found);
|
|
950
|
+
idx = found + needle.length;
|
|
951
|
+
}
|
|
952
|
+
return out;
|
|
953
|
+
}
|
|
954
|
+
buildLineRanges(source, offsets, needleLength) {
|
|
955
|
+
if (offsets.length === 0) {
|
|
956
|
+
return [];
|
|
957
|
+
}
|
|
958
|
+
const newlineOffsets = [];
|
|
959
|
+
for (let i = 0; i < source.length; i++) {
|
|
960
|
+
if (source.charCodeAt(i) === 10) {
|
|
961
|
+
newlineOffsets.push(i);
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
return offsets.map((startIdx) => {
|
|
965
|
+
const endIdx = startIdx + Math.max(needleLength, 1) - 1;
|
|
966
|
+
return {
|
|
967
|
+
start: this.lineNumberAt(newlineOffsets, startIdx),
|
|
968
|
+
end: this.lineNumberAt(newlineOffsets, endIdx)
|
|
969
|
+
};
|
|
970
|
+
});
|
|
971
|
+
}
|
|
972
|
+
lineNumberAt(newlineOffsets, index) {
|
|
973
|
+
let lo = 0;
|
|
974
|
+
let hi = newlineOffsets.length;
|
|
975
|
+
while (lo < hi) {
|
|
976
|
+
const mid = lo + hi >> 1;
|
|
977
|
+
if (newlineOffsets[mid] < index) {
|
|
978
|
+
lo = mid + 1;
|
|
979
|
+
} else {
|
|
980
|
+
hi = mid;
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
return lo + 1;
|
|
984
|
+
}
|
|
985
|
+
formatLineRanges(ranges) {
|
|
986
|
+
if (ranges.length === 0) {
|
|
987
|
+
return "";
|
|
988
|
+
}
|
|
989
|
+
const merged = [];
|
|
990
|
+
for (const range of ranges) {
|
|
991
|
+
const last = merged[merged.length - 1];
|
|
992
|
+
if (!last || range.start > last.end + 1) {
|
|
993
|
+
merged.push({ ...range });
|
|
994
|
+
continue;
|
|
995
|
+
}
|
|
996
|
+
if (range.end > last.end) {
|
|
997
|
+
last.end = range.end;
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
return merged.map(
|
|
1001
|
+
(range) => range.start === range.end ? `${range.start}` : `${range.start}-${range.end}`
|
|
1002
|
+
).join(",");
|
|
1003
|
+
}
|
|
851
1004
|
isValidUtf8(buffer) {
|
|
852
1005
|
try {
|
|
853
1006
|
const text = buffer.toString("utf-8");
|
package/dist/node.d.cts
CHANGED
|
@@ -7,6 +7,7 @@ import { e as Tool, k as ToolRegistry } from './tools-bCt1QwNk.cjs';
|
|
|
7
7
|
* - fs.read_file - Read workspace-relative files
|
|
8
8
|
* - fs.list_files - List files recursively
|
|
9
9
|
* - fs.search - Regex search (ripgrep or JS fallback)
|
|
10
|
+
* - fs.edit - Replace exact string matches in a file
|
|
10
11
|
*
|
|
11
12
|
* Safety features:
|
|
12
13
|
* - Root sandbox with symlink resolution
|
|
@@ -23,6 +24,7 @@ declare const ToolNames: {
|
|
|
23
24
|
readonly FS_READ_FILE: "fs.read_file";
|
|
24
25
|
readonly FS_LIST_FILES: "fs.list_files";
|
|
25
26
|
readonly FS_SEARCH: "fs.search";
|
|
27
|
+
readonly FS_EDIT: "fs.edit";
|
|
26
28
|
};
|
|
27
29
|
/** Default size limits and caps from wire contract. */
|
|
28
30
|
declare const FSDefaults: {
|
|
@@ -103,6 +105,7 @@ declare class LocalFSToolPack {
|
|
|
103
105
|
private readFile;
|
|
104
106
|
private listFiles;
|
|
105
107
|
private search;
|
|
108
|
+
private editFile;
|
|
106
109
|
/**
|
|
107
110
|
* Resolves a workspace-relative path and validates it stays within the sandbox.
|
|
108
111
|
* @throws {ToolArgumentError} if path is invalid
|
|
@@ -116,8 +119,14 @@ declare class LocalFSToolPack {
|
|
|
116
119
|
private parseArgs;
|
|
117
120
|
private toolArgumentError;
|
|
118
121
|
private requireString;
|
|
122
|
+
private requireStringAllowEmpty;
|
|
119
123
|
private optionalString;
|
|
120
124
|
private optionalPositiveInt;
|
|
125
|
+
private optionalBoolean;
|
|
126
|
+
private findOccurrences;
|
|
127
|
+
private buildLineRanges;
|
|
128
|
+
private lineNumberAt;
|
|
129
|
+
private formatLineRanges;
|
|
121
130
|
private isValidUtf8;
|
|
122
131
|
/**
|
|
123
132
|
* Recursively walks a directory, calling visitor for each entry.
|
package/dist/node.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { e as Tool, k as ToolRegistry } from './tools-bCt1QwNk.js';
|
|
|
7
7
|
* - fs.read_file - Read workspace-relative files
|
|
8
8
|
* - fs.list_files - List files recursively
|
|
9
9
|
* - fs.search - Regex search (ripgrep or JS fallback)
|
|
10
|
+
* - fs.edit - Replace exact string matches in a file
|
|
10
11
|
*
|
|
11
12
|
* Safety features:
|
|
12
13
|
* - Root sandbox with symlink resolution
|
|
@@ -23,6 +24,7 @@ declare const ToolNames: {
|
|
|
23
24
|
readonly FS_READ_FILE: "fs.read_file";
|
|
24
25
|
readonly FS_LIST_FILES: "fs.list_files";
|
|
25
26
|
readonly FS_SEARCH: "fs.search";
|
|
27
|
+
readonly FS_EDIT: "fs.edit";
|
|
26
28
|
};
|
|
27
29
|
/** Default size limits and caps from wire contract. */
|
|
28
30
|
declare const FSDefaults: {
|
|
@@ -103,6 +105,7 @@ declare class LocalFSToolPack {
|
|
|
103
105
|
private readFile;
|
|
104
106
|
private listFiles;
|
|
105
107
|
private search;
|
|
108
|
+
private editFile;
|
|
106
109
|
/**
|
|
107
110
|
* Resolves a workspace-relative path and validates it stays within the sandbox.
|
|
108
111
|
* @throws {ToolArgumentError} if path is invalid
|
|
@@ -116,8 +119,14 @@ declare class LocalFSToolPack {
|
|
|
116
119
|
private parseArgs;
|
|
117
120
|
private toolArgumentError;
|
|
118
121
|
private requireString;
|
|
122
|
+
private requireStringAllowEmpty;
|
|
119
123
|
private optionalString;
|
|
120
124
|
private optionalPositiveInt;
|
|
125
|
+
private optionalBoolean;
|
|
126
|
+
private findOccurrences;
|
|
127
|
+
private buildLineRanges;
|
|
128
|
+
private lineNumberAt;
|
|
129
|
+
private formatLineRanges;
|
|
121
130
|
private isValidUtf8;
|
|
122
131
|
/**
|
|
123
132
|
* Recursively walks a directory, calling visitor for each entry.
|
package/dist/node.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
ToolArgumentError,
|
|
4
4
|
ToolRegistry,
|
|
5
5
|
ToolTypes
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-LZDGY24E.js";
|
|
7
7
|
import "./chunk-MLKGABMK.js";
|
|
8
8
|
|
|
9
9
|
// src/tools_local_fs.ts
|
|
@@ -13,7 +13,8 @@ import { spawn } from "child_process";
|
|
|
13
13
|
var ToolNames = {
|
|
14
14
|
FS_READ_FILE: "fs.read_file",
|
|
15
15
|
FS_LIST_FILES: "fs.list_files",
|
|
16
|
-
FS_SEARCH: "fs.search"
|
|
16
|
+
FS_SEARCH: "fs.search",
|
|
17
|
+
FS_EDIT: "fs.edit"
|
|
17
18
|
};
|
|
18
19
|
var FSDefaults = {
|
|
19
20
|
MAX_READ_BYTES: 64e3,
|
|
@@ -131,6 +132,36 @@ var LocalFSToolPack = class {
|
|
|
131
132
|
required: ["query"]
|
|
132
133
|
}
|
|
133
134
|
}
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
type: "function",
|
|
138
|
+
function: {
|
|
139
|
+
name: ToolNames.FS_EDIT,
|
|
140
|
+
description: "Replace exact string matches in a file. Returns a confirmation with affected line numbers.",
|
|
141
|
+
parameters: {
|
|
142
|
+
type: "object",
|
|
143
|
+
properties: {
|
|
144
|
+
path: {
|
|
145
|
+
type: "string",
|
|
146
|
+
description: "Workspace-relative path to the file (e.g., 'src/index.ts')"
|
|
147
|
+
},
|
|
148
|
+
old_string: {
|
|
149
|
+
type: "string",
|
|
150
|
+
description: "Exact string to find and replace"
|
|
151
|
+
},
|
|
152
|
+
new_string: {
|
|
153
|
+
type: "string",
|
|
154
|
+
description: "Replacement string (may be empty)"
|
|
155
|
+
},
|
|
156
|
+
replace_all: {
|
|
157
|
+
type: "boolean",
|
|
158
|
+
default: false,
|
|
159
|
+
description: "Replace all occurrences (default: replace first only)"
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
required: ["path", "old_string", "new_string"]
|
|
163
|
+
}
|
|
164
|
+
}
|
|
134
165
|
}
|
|
135
166
|
];
|
|
136
167
|
}
|
|
@@ -143,6 +174,7 @@ var LocalFSToolPack = class {
|
|
|
143
174
|
registry.register(ToolNames.FS_READ_FILE, this.readFile.bind(this));
|
|
144
175
|
registry.register(ToolNames.FS_LIST_FILES, this.listFiles.bind(this));
|
|
145
176
|
registry.register(ToolNames.FS_SEARCH, this.search.bind(this));
|
|
177
|
+
registry.register(ToolNames.FS_EDIT, this.editFile.bind(this));
|
|
146
178
|
return registry;
|
|
147
179
|
}
|
|
148
180
|
/**
|
|
@@ -262,6 +294,41 @@ var LocalFSToolPack = class {
|
|
|
262
294
|
}
|
|
263
295
|
return this.searchWithJS(query, absPath, maxMatches, call);
|
|
264
296
|
}
|
|
297
|
+
async editFile(_args, call) {
|
|
298
|
+
const args = this.parseArgs(call, [
|
|
299
|
+
"path",
|
|
300
|
+
"old_string"
|
|
301
|
+
]);
|
|
302
|
+
const func = call.function;
|
|
303
|
+
const relPath = this.requireString(args, "path", call);
|
|
304
|
+
const oldString = this.requireString(args, "old_string", call);
|
|
305
|
+
const newString = this.requireStringAllowEmpty(args, "new_string", call);
|
|
306
|
+
const replaceAll = this.optionalBoolean(args, "replace_all", call) ?? false;
|
|
307
|
+
const absPath = await this.resolveAndValidatePath(relPath, call);
|
|
308
|
+
const stat = await fs.stat(absPath);
|
|
309
|
+
if (stat.isDirectory()) {
|
|
310
|
+
throw new Error(`fs.edit: path is a directory: ${relPath}`);
|
|
311
|
+
}
|
|
312
|
+
const data = await fs.readFile(absPath);
|
|
313
|
+
if (!this.isValidUtf8(data)) {
|
|
314
|
+
throw new Error(`fs.edit: file is not valid UTF-8: ${relPath}`);
|
|
315
|
+
}
|
|
316
|
+
const contents = data.toString("utf-8");
|
|
317
|
+
const matches = this.findOccurrences(contents, oldString);
|
|
318
|
+
if (matches.length === 0) {
|
|
319
|
+
throw new Error("fs.edit: old_string not found");
|
|
320
|
+
}
|
|
321
|
+
if (!replaceAll && matches.length > 1) {
|
|
322
|
+
throw new Error("fs.edit: old_string appears multiple times");
|
|
323
|
+
}
|
|
324
|
+
const appliedMatches = replaceAll ? matches : matches.slice(0, 1);
|
|
325
|
+
const updated = replaceAll ? contents.split(oldString).join(newString) : contents.replace(oldString, newString);
|
|
326
|
+
await fs.writeFile(absPath, updated);
|
|
327
|
+
const lineSpec = this.formatLineRanges(
|
|
328
|
+
this.buildLineRanges(contents, appliedMatches, oldString.length)
|
|
329
|
+
);
|
|
330
|
+
return `Edited ${relPath} (replacements=${appliedMatches.length}, lines ${lineSpec})`;
|
|
331
|
+
}
|
|
265
332
|
// ========================================================================
|
|
266
333
|
// Path Safety
|
|
267
334
|
// ========================================================================
|
|
@@ -541,6 +608,16 @@ var LocalFSToolPack = class {
|
|
|
541
608
|
}
|
|
542
609
|
return value;
|
|
543
610
|
}
|
|
611
|
+
requireStringAllowEmpty(args, key, call) {
|
|
612
|
+
const value = args[key];
|
|
613
|
+
if (value === void 0 || value === null) {
|
|
614
|
+
this.toolArgumentError(call, `${key} is required`);
|
|
615
|
+
}
|
|
616
|
+
if (typeof value !== "string") {
|
|
617
|
+
this.toolArgumentError(call, `${key} must be a string`);
|
|
618
|
+
}
|
|
619
|
+
return value;
|
|
620
|
+
}
|
|
544
621
|
optionalString(args, key, call) {
|
|
545
622
|
const value = args[key];
|
|
546
623
|
if (value === void 0 || value === null) {
|
|
@@ -568,6 +645,82 @@ var LocalFSToolPack = class {
|
|
|
568
645
|
}
|
|
569
646
|
return value;
|
|
570
647
|
}
|
|
648
|
+
optionalBoolean(args, key, call) {
|
|
649
|
+
const value = args[key];
|
|
650
|
+
if (value === void 0 || value === null) {
|
|
651
|
+
return void 0;
|
|
652
|
+
}
|
|
653
|
+
if (typeof value !== "boolean") {
|
|
654
|
+
this.toolArgumentError(call, `${key} must be a boolean`);
|
|
655
|
+
}
|
|
656
|
+
return value;
|
|
657
|
+
}
|
|
658
|
+
findOccurrences(haystack, needle) {
|
|
659
|
+
if (needle.length === 0) {
|
|
660
|
+
return [];
|
|
661
|
+
}
|
|
662
|
+
const out = [];
|
|
663
|
+
let idx = 0;
|
|
664
|
+
for (; ; ) {
|
|
665
|
+
const found = haystack.indexOf(needle, idx);
|
|
666
|
+
if (found === -1) {
|
|
667
|
+
break;
|
|
668
|
+
}
|
|
669
|
+
out.push(found);
|
|
670
|
+
idx = found + needle.length;
|
|
671
|
+
}
|
|
672
|
+
return out;
|
|
673
|
+
}
|
|
674
|
+
buildLineRanges(source, offsets, needleLength) {
|
|
675
|
+
if (offsets.length === 0) {
|
|
676
|
+
return [];
|
|
677
|
+
}
|
|
678
|
+
const newlineOffsets = [];
|
|
679
|
+
for (let i = 0; i < source.length; i++) {
|
|
680
|
+
if (source.charCodeAt(i) === 10) {
|
|
681
|
+
newlineOffsets.push(i);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
return offsets.map((startIdx) => {
|
|
685
|
+
const endIdx = startIdx + Math.max(needleLength, 1) - 1;
|
|
686
|
+
return {
|
|
687
|
+
start: this.lineNumberAt(newlineOffsets, startIdx),
|
|
688
|
+
end: this.lineNumberAt(newlineOffsets, endIdx)
|
|
689
|
+
};
|
|
690
|
+
});
|
|
691
|
+
}
|
|
692
|
+
lineNumberAt(newlineOffsets, index) {
|
|
693
|
+
let lo = 0;
|
|
694
|
+
let hi = newlineOffsets.length;
|
|
695
|
+
while (lo < hi) {
|
|
696
|
+
const mid = lo + hi >> 1;
|
|
697
|
+
if (newlineOffsets[mid] < index) {
|
|
698
|
+
lo = mid + 1;
|
|
699
|
+
} else {
|
|
700
|
+
hi = mid;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
return lo + 1;
|
|
704
|
+
}
|
|
705
|
+
formatLineRanges(ranges) {
|
|
706
|
+
if (ranges.length === 0) {
|
|
707
|
+
return "";
|
|
708
|
+
}
|
|
709
|
+
const merged = [];
|
|
710
|
+
for (const range of ranges) {
|
|
711
|
+
const last = merged[merged.length - 1];
|
|
712
|
+
if (!last || range.start > last.end + 1) {
|
|
713
|
+
merged.push({ ...range });
|
|
714
|
+
continue;
|
|
715
|
+
}
|
|
716
|
+
if (range.end > last.end) {
|
|
717
|
+
last.end = range.end;
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
return merged.map(
|
|
721
|
+
(range) => range.start === range.end ? `${range.start}` : `${range.start}-${range.end}`
|
|
722
|
+
).join(",");
|
|
723
|
+
}
|
|
571
724
|
isValidUtf8(buffer) {
|
|
572
725
|
try {
|
|
573
726
|
const text = buffer.toString("utf-8");
|
|
@@ -272,10 +272,8 @@ interface FrontendToken {
|
|
|
272
272
|
customerId: string;
|
|
273
273
|
/** The external customer ID provided by the application. */
|
|
274
274
|
customerExternalId: string;
|
|
275
|
-
/** The tier code for the customer (e.g., "free", "pro", "enterprise").
|
|
276
|
-
|
|
277
|
-
*/
|
|
278
|
-
tierCode?: string;
|
|
275
|
+
/** The tier code for the customer (e.g., "free", "pro", "enterprise"). */
|
|
276
|
+
tierCode: string;
|
|
279
277
|
/**
|
|
280
278
|
* Publishable key used for issuance. Added client-side for caching.
|
|
281
279
|
*/
|
|
@@ -306,8 +304,7 @@ interface CustomerToken {
|
|
|
306
304
|
projectId: string;
|
|
307
305
|
customerId: string;
|
|
308
306
|
customerExternalId: string;
|
|
309
|
-
|
|
310
|
-
tierCode?: string;
|
|
307
|
+
tierCode: string;
|
|
311
308
|
}
|
|
312
309
|
interface OIDCExchangeRequest {
|
|
313
310
|
idToken: string;
|
|
@@ -359,8 +356,8 @@ interface DeviceTokenResponse {
|
|
|
359
356
|
customerId: string;
|
|
360
357
|
/** The external customer ID */
|
|
361
358
|
customerExternalId: string;
|
|
362
|
-
/** The tier code for the customer
|
|
363
|
-
tierCode
|
|
359
|
+
/** The tier code for the customer */
|
|
360
|
+
tierCode: string;
|
|
364
361
|
}
|
|
365
362
|
/**
|
|
366
363
|
* Pending response from polling device token endpoint.
|
|
@@ -706,7 +703,7 @@ interface APIFrontendToken {
|
|
|
706
703
|
project_id: string;
|
|
707
704
|
customer_id: string;
|
|
708
705
|
customer_external_id: string;
|
|
709
|
-
tier_code
|
|
706
|
+
tier_code: string;
|
|
710
707
|
}
|
|
711
708
|
interface APICustomerRef {
|
|
712
709
|
id: string;
|
|
@@ -272,10 +272,8 @@ interface FrontendToken {
|
|
|
272
272
|
customerId: string;
|
|
273
273
|
/** The external customer ID provided by the application. */
|
|
274
274
|
customerExternalId: string;
|
|
275
|
-
/** The tier code for the customer (e.g., "free", "pro", "enterprise").
|
|
276
|
-
|
|
277
|
-
*/
|
|
278
|
-
tierCode?: string;
|
|
275
|
+
/** The tier code for the customer (e.g., "free", "pro", "enterprise"). */
|
|
276
|
+
tierCode: string;
|
|
279
277
|
/**
|
|
280
278
|
* Publishable key used for issuance. Added client-side for caching.
|
|
281
279
|
*/
|
|
@@ -306,8 +304,7 @@ interface CustomerToken {
|
|
|
306
304
|
projectId: string;
|
|
307
305
|
customerId: string;
|
|
308
306
|
customerExternalId: string;
|
|
309
|
-
|
|
310
|
-
tierCode?: string;
|
|
307
|
+
tierCode: string;
|
|
311
308
|
}
|
|
312
309
|
interface OIDCExchangeRequest {
|
|
313
310
|
idToken: string;
|
|
@@ -359,8 +356,8 @@ interface DeviceTokenResponse {
|
|
|
359
356
|
customerId: string;
|
|
360
357
|
/** The external customer ID */
|
|
361
358
|
customerExternalId: string;
|
|
362
|
-
/** The tier code for the customer
|
|
363
|
-
tierCode
|
|
359
|
+
/** The tier code for the customer */
|
|
360
|
+
tierCode: string;
|
|
364
361
|
}
|
|
365
362
|
/**
|
|
366
363
|
* Pending response from polling device token endpoint.
|
|
@@ -706,7 +703,7 @@ interface APIFrontendToken {
|
|
|
706
703
|
project_id: string;
|
|
707
704
|
customer_id: string;
|
|
708
705
|
customer_external_id: string;
|
|
709
|
-
tier_code
|
|
706
|
+
tier_code: string;
|
|
710
707
|
}
|
|
711
708
|
interface APICustomerRef {
|
|
712
709
|
id: string;
|