chivgent 0.6.0 → 0.7.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 +35 -8
- package/README.zh-CN.md +32 -8
- package/dist/cli-options.d.ts +8 -0
- package/dist/cli-options.d.ts.map +1 -1
- package/dist/cli-options.js +16 -2
- package/dist/cli-options.js.map +1 -1
- package/dist/cli.js +20 -3
- package/dist/cli.js.map +1 -1
- package/dist/tools/edit-file.d.ts +26 -0
- package/dist/tools/edit-file.d.ts.map +1 -0
- package/dist/tools/edit-file.js +72 -0
- package/dist/tools/edit-file.js.map +1 -0
- package/dist/tools/write-file.d.ts +22 -0
- package/dist/tools/write-file.d.ts.map +1 -0
- package/dist/tools/write-file.js +59 -0
- package/dist/tools/write-file.js.map +1 -0
- package/dist/workspace/ignore.d.ts +6 -0
- package/dist/workspace/ignore.d.ts.map +1 -0
- package/dist/workspace/ignore.js +35 -0
- package/dist/workspace/ignore.js.map +1 -0
- package/dist/workspace/list.d.ts +3 -0
- package/dist/workspace/list.d.ts.map +1 -0
- package/dist/workspace/list.js +63 -0
- package/dist/workspace/list.js.map +1 -0
- package/dist/workspace/paths.d.ts +41 -0
- package/dist/workspace/paths.d.ts.map +1 -0
- package/dist/workspace/paths.js +189 -0
- package/dist/workspace/paths.js.map +1 -0
- package/dist/workspace/read.d.ts +4 -0
- package/dist/workspace/read.d.ts.map +1 -0
- package/dist/workspace/read.js +37 -0
- package/dist/workspace/read.js.map +1 -0
- package/dist/workspace/search.d.ts +3 -0
- package/dist/workspace/search.d.ts.map +1 -0
- package/dist/workspace/search.js +134 -0
- package/dist/workspace/search.js.map +1 -0
- package/dist/workspace/text.d.ts +8 -0
- package/dist/workspace/text.d.ts.map +1 -0
- package/dist/workspace/text.js +87 -0
- package/dist/workspace/text.js.map +1 -0
- package/dist/workspace/types.d.ts +103 -0
- package/dist/workspace/types.d.ts.map +1 -0
- package/dist/workspace/types.js +27 -0
- package/dist/workspace/types.js.map +1 -0
- package/dist/workspace/write.d.ts +4 -0
- package/dist/workspace/write.d.ts.map +1 -0
- package/dist/workspace/write.js +83 -0
- package/dist/workspace/write.js.map +1 -0
- package/dist/workspace.d.ts +16 -64
- package/dist/workspace.d.ts.map +1 -1
- package/dist/workspace.js +39 -486
- package/dist/workspace.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { lstat, readFile } from "node:fs/promises";
|
|
2
|
+
import { MAX_PREVIEW_CHARACTERS, MAX_QUERY_CHARACTERS, WorkspaceError } from "./types.js";
|
|
3
|
+
export async function readUtf8File(absolutePath, displayPath, maxFileBytes) {
|
|
4
|
+
const stats = await lstat(absolutePath);
|
|
5
|
+
if (!stats.isFile()) {
|
|
6
|
+
throw new WorkspaceError("not_a_file", `Path is not a regular file: ${displayPath}`);
|
|
7
|
+
}
|
|
8
|
+
if (stats.size > maxFileBytes) {
|
|
9
|
+
throw new WorkspaceError("too_large", `File exceeds the ${maxFileBytes}-byte limit: ${displayPath}`);
|
|
10
|
+
}
|
|
11
|
+
const contents = await readFile(absolutePath);
|
|
12
|
+
if (contents.byteLength > maxFileBytes) {
|
|
13
|
+
throw new WorkspaceError("too_large", `File exceeds the ${maxFileBytes}-byte limit: ${displayPath}`);
|
|
14
|
+
}
|
|
15
|
+
if (contents.includes(0)) {
|
|
16
|
+
throw new WorkspaceError("binary_file", `File appears to be binary: ${displayPath}`);
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(contents);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
throw new WorkspaceError("invalid_utf8", `File is not valid UTF-8: ${displayPath}`, { cause: error });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export function validateSearchQuery(query) {
|
|
26
|
+
if (typeof query !== "string" ||
|
|
27
|
+
query.length === 0 ||
|
|
28
|
+
[...query].length > MAX_QUERY_CHARACTERS ||
|
|
29
|
+
query.includes("\0") ||
|
|
30
|
+
query.includes("\r") ||
|
|
31
|
+
query.includes("\n")) {
|
|
32
|
+
throw new TypeError("query must contain 1 to 256 characters without NUL or line breaks.");
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export function positiveSafeInteger(value, name) {
|
|
36
|
+
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
37
|
+
throw new TypeError(`${name} must be a positive safe integer.`);
|
|
38
|
+
}
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
export function boundedPositiveInteger(value, name, maximum) {
|
|
42
|
+
const validated = positiveSafeInteger(value, name);
|
|
43
|
+
if (validated > maximum) {
|
|
44
|
+
throw new TypeError(`${name} must be at most ${maximum}.`);
|
|
45
|
+
}
|
|
46
|
+
return validated;
|
|
47
|
+
}
|
|
48
|
+
export function splitLinesPreservingEndings(contents) {
|
|
49
|
+
if (contents.length === 0) {
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
const lines = contents.match(/[^\r\n]*(?:\r\n|\r|\n|$)/g) ?? [];
|
|
53
|
+
if (lines.at(-1) === "") {
|
|
54
|
+
lines.pop();
|
|
55
|
+
}
|
|
56
|
+
return lines;
|
|
57
|
+
}
|
|
58
|
+
export function splitLines(contents) {
|
|
59
|
+
return splitLinesPreservingEndings(contents).map((line) => line.replace(/(?:\r\n|\r|\n)$/, ""));
|
|
60
|
+
}
|
|
61
|
+
export function createMatchPreview(line, query) {
|
|
62
|
+
const characters = [...line];
|
|
63
|
+
if (characters.length <= MAX_PREVIEW_CHARACTERS) {
|
|
64
|
+
return line;
|
|
65
|
+
}
|
|
66
|
+
const matchIndex = line.indexOf(query);
|
|
67
|
+
const prefixCharacters = [...line.slice(0, matchIndex)].length;
|
|
68
|
+
const queryCharacters = [...query].length;
|
|
69
|
+
const initialContext = Math.max(0, MAX_PREVIEW_CHARACTERS - queryCharacters - 2);
|
|
70
|
+
let start = Math.max(0, prefixCharacters - Math.floor(initialContext / 2));
|
|
71
|
+
let hasPrefix = start > 0;
|
|
72
|
+
let hasSuffix = true;
|
|
73
|
+
let contentBudget = MAX_PREVIEW_CHARACTERS - Number(hasPrefix) - Number(hasSuffix);
|
|
74
|
+
let end = Math.min(characters.length, start + contentBudget);
|
|
75
|
+
hasSuffix = end < characters.length;
|
|
76
|
+
contentBudget =
|
|
77
|
+
MAX_PREVIEW_CHARACTERS - Number(hasPrefix) - Number(hasSuffix);
|
|
78
|
+
end = Math.min(characters.length, start + contentBudget);
|
|
79
|
+
if (end === characters.length) {
|
|
80
|
+
start = Math.max(0, end - (MAX_PREVIEW_CHARACTERS - Number(start > 0)));
|
|
81
|
+
hasPrefix = start > 0;
|
|
82
|
+
}
|
|
83
|
+
return `${hasPrefix ? "…" : ""}${characters
|
|
84
|
+
.slice(start, end)
|
|
85
|
+
.join("")}${end < characters.length ? "…" : ""}`;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/workspace/text.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE1F,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,YAAoB,EACpB,WAAmB,EACnB,YAAoB;IAEpB,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,CAAC;IACxC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;QACpB,MAAM,IAAI,cAAc,CACtB,YAAY,EACZ,+BAA+B,WAAW,EAAE,CAC7C,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,GAAG,YAAY,EAAE,CAAC;QAC9B,MAAM,IAAI,cAAc,CACtB,WAAW,EACX,oBAAoB,YAAY,gBAAgB,WAAW,EAAE,CAC9D,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC9C,IAAI,QAAQ,CAAC,UAAU,GAAG,YAAY,EAAE,CAAC;QACvC,MAAM,IAAI,cAAc,CACtB,WAAW,EACX,oBAAoB,YAAY,gBAAgB,WAAW,EAAE,CAC9D,CAAC;IACJ,CAAC;IACD,IAAI,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,cAAc,CACtB,aAAa,EACb,8BAA8B,WAAW,EAAE,CAC5C,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,OAAO,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACpE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,cAAc,CACtB,cAAc,EACd,4BAA4B,WAAW,EAAE,EACzC,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,IACE,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,CAAC,MAAM,KAAK,CAAC;QAClB,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,GAAG,oBAAoB;QACxC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;QACpB,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;QACpB,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EACpB,CAAC;QACD,MAAM,IAAI,SAAS,CACjB,oEAAoE,CACrE,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAa,EAAE,IAAY;IAC7D,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,SAAS,CAAC,GAAG,IAAI,mCAAmC,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,KAAa,EACb,IAAY,EACZ,OAAe;IAEf,MAAM,SAAS,GAAG,mBAAmB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACnD,IAAI,SAAS,GAAG,OAAO,EAAE,CAAC;QACxB,MAAM,IAAI,SAAS,CAAC,GAAG,IAAI,oBAAoB,OAAO,GAAG,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,QAAgB;IAC1D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,2BAA2B,CAAC,IAAI,EAAE,CAAC;IAChE,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;QACxB,KAAK,CAAC,GAAG,EAAE,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,QAAgB;IACzC,OAAO,2BAA2B,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACxD,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CACpC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,KAAa;IAC5D,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;IAC7B,IAAI,UAAU,CAAC,MAAM,IAAI,sBAAsB,EAAE,CAAC;QAChD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,gBAAgB,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC;IAC/D,MAAM,eAAe,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC;IAC1C,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAC7B,CAAC,EACD,sBAAsB,GAAG,eAAe,GAAG,CAAC,CAC7C,CAAC;IACF,IAAI,KAAK,GAAG,IAAI,CAAC,GAAG,CAClB,CAAC,EACD,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,CAAC,CAAC,CAClD,CAAC;IACF,IAAI,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC;IAC1B,IAAI,SAAS,GAAG,IAAI,CAAC;IACrB,IAAI,aAAa,GACf,sBAAsB,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;IACjE,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,EAAE,KAAK,GAAG,aAAa,CAAC,CAAC;IAC7D,SAAS,GAAG,GAAG,GAAG,UAAU,CAAC,MAAM,CAAC;IACpC,aAAa;QACX,sBAAsB,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;IACjE,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,EAAE,KAAK,GAAG,aAAa,CAAC,CAAC;IACzD,IAAI,GAAG,KAAK,UAAU,CAAC,MAAM,EAAE,CAAC;QAC9B,KAAK,GAAG,IAAI,CAAC,GAAG,CACd,CAAC,EACD,GAAG,GAAG,CAAC,sBAAsB,GAAG,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CACnD,CAAC;QACF,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC;IACxB,CAAC;IAED,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,UAAU;SACxC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC;SACjB,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
export declare const DEFAULT_MAX_FILE_BYTES: number;
|
|
2
|
+
export declare const DEFAULT_READ_LINE_COUNT = 200;
|
|
3
|
+
export declare const MAX_READ_LINE_COUNT = 500;
|
|
4
|
+
export declare const DEFAULT_LIST_DEPTH = 4;
|
|
5
|
+
export declare const MAX_LIST_DEPTH = 8;
|
|
6
|
+
export declare const DEFAULT_LIST_ENTRIES = 200;
|
|
7
|
+
export declare const MAX_LIST_ENTRIES = 1000;
|
|
8
|
+
export declare const DEFAULT_SEARCH_RESULTS = 50;
|
|
9
|
+
export declare const MAX_SEARCH_RESULTS = 200;
|
|
10
|
+
export declare const DEFAULT_MAX_SEARCH_FILES = 2000;
|
|
11
|
+
export declare const DEFAULT_MAX_SEARCH_BYTES: number;
|
|
12
|
+
export declare const MAX_QUERY_CHARACTERS = 256;
|
|
13
|
+
export declare const MAX_PREVIEW_CHARACTERS = 300;
|
|
14
|
+
export declare const MAX_RELATIVE_PATH_CHARACTERS = 4096;
|
|
15
|
+
export type WorkspaceErrorCode = "writes_disabled" | "no_match" | "ambiguous_match" | "invalid_path" | "outside_workspace" | "forbidden_path" | "not_found" | "not_a_file" | "not_a_directory" | "too_large" | "binary_file" | "invalid_utf8" | "invalid_range";
|
|
16
|
+
export declare class WorkspaceError extends Error {
|
|
17
|
+
readonly code: WorkspaceErrorCode;
|
|
18
|
+
constructor(code: WorkspaceErrorCode, message: string, options?: ErrorOptions);
|
|
19
|
+
}
|
|
20
|
+
export interface ReadTextFileOptions {
|
|
21
|
+
readonly startLine?: number;
|
|
22
|
+
readonly lineCount?: number;
|
|
23
|
+
}
|
|
24
|
+
export interface TextFileSlice {
|
|
25
|
+
readonly content: string;
|
|
26
|
+
readonly startLine: number;
|
|
27
|
+
readonly endLine: number;
|
|
28
|
+
readonly totalLines: number;
|
|
29
|
+
readonly truncated: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface ListFilesOptions {
|
|
32
|
+
readonly path?: string;
|
|
33
|
+
readonly maxDepth?: number;
|
|
34
|
+
readonly maxEntries?: number;
|
|
35
|
+
}
|
|
36
|
+
export interface WorkspaceEntry {
|
|
37
|
+
readonly path: string;
|
|
38
|
+
readonly type: "file" | "directory";
|
|
39
|
+
}
|
|
40
|
+
export interface ListFilesResult {
|
|
41
|
+
readonly entries: readonly WorkspaceEntry[];
|
|
42
|
+
readonly truncated: boolean;
|
|
43
|
+
}
|
|
44
|
+
export interface SearchTextOptions {
|
|
45
|
+
readonly query: string;
|
|
46
|
+
readonly path?: string;
|
|
47
|
+
readonly maxResults?: number;
|
|
48
|
+
}
|
|
49
|
+
export interface SearchMatch {
|
|
50
|
+
readonly path: string;
|
|
51
|
+
readonly line: number;
|
|
52
|
+
readonly preview: string;
|
|
53
|
+
}
|
|
54
|
+
export interface SearchTextResult {
|
|
55
|
+
readonly matches: readonly SearchMatch[];
|
|
56
|
+
readonly truncated: boolean;
|
|
57
|
+
readonly scannedFiles: number;
|
|
58
|
+
readonly skippedFiles: number;
|
|
59
|
+
}
|
|
60
|
+
/** Configuration every workspace operation needs, passed explicitly. */
|
|
61
|
+
export interface WorkspaceLimits {
|
|
62
|
+
readonly root: string;
|
|
63
|
+
readonly maxFileBytes: number;
|
|
64
|
+
readonly maxSearchFiles: number;
|
|
65
|
+
readonly maxSearchBytes: number;
|
|
66
|
+
}
|
|
67
|
+
export interface WriteTextFileResult {
|
|
68
|
+
readonly path: string;
|
|
69
|
+
/** True when the write created a file that did not exist before. */
|
|
70
|
+
readonly created: boolean;
|
|
71
|
+
readonly bytesWritten: number;
|
|
72
|
+
readonly totalLines: number;
|
|
73
|
+
}
|
|
74
|
+
export interface EditTextFileOptions {
|
|
75
|
+
readonly oldText: string;
|
|
76
|
+
readonly newText: string;
|
|
77
|
+
}
|
|
78
|
+
export interface EditTextFileResult {
|
|
79
|
+
readonly path: string;
|
|
80
|
+
/** One-based line where the replaced text began. */
|
|
81
|
+
readonly line: number;
|
|
82
|
+
readonly bytesWritten: number;
|
|
83
|
+
readonly totalLines: number;
|
|
84
|
+
}
|
|
85
|
+
export interface Workspace {
|
|
86
|
+
readonly root: string;
|
|
87
|
+
readTextFile(relativePath: string, options?: ReadTextFileOptions): Promise<TextFileSlice>;
|
|
88
|
+
listFiles(options?: ListFilesOptions): Promise<ListFilesResult>;
|
|
89
|
+
searchText(options: SearchTextOptions): Promise<SearchTextResult>;
|
|
90
|
+
/** Rejects unless the workspace was constructed with writes enabled. */
|
|
91
|
+
writeTextFile(relativePath: string, contents: string): Promise<WriteTextFileResult>;
|
|
92
|
+
/** Rejects unless the workspace was constructed with writes enabled. */
|
|
93
|
+
editTextFile(relativePath: string, options: EditTextFileOptions): Promise<EditTextFileResult>;
|
|
94
|
+
}
|
|
95
|
+
export interface LocalWorkspaceOptions {
|
|
96
|
+
/** Writes are refused unless this is explicitly true. */
|
|
97
|
+
readonly allowWrites?: boolean;
|
|
98
|
+
readonly maxFileBytes?: number;
|
|
99
|
+
readonly maxSearchFiles?: number;
|
|
100
|
+
readonly maxSearchBytes?: number;
|
|
101
|
+
}
|
|
102
|
+
export declare function invalidRange(relativePath: string, startLine: number, totalLines: number): WorkspaceError;
|
|
103
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/workspace/types.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,sBAAsB,QAAa,CAAC;AACjD,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C,eAAO,MAAM,mBAAmB,MAAM,CAAC;AACvC,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC,eAAO,MAAM,cAAc,IAAI,CAAC;AAChC,eAAO,MAAM,oBAAoB,MAAM,CAAC;AACxC,eAAO,MAAM,gBAAgB,OAAQ,CAAC;AACtC,eAAO,MAAM,sBAAsB,KAAK,CAAC;AACzC,eAAO,MAAM,kBAAkB,MAAM,CAAC;AACtC,eAAO,MAAM,wBAAwB,OAAQ,CAAC;AAC9C,eAAO,MAAM,wBAAwB,QAAmB,CAAC;AACzD,eAAO,MAAM,oBAAoB,MAAM,CAAC;AACxC,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAC1C,eAAO,MAAM,4BAA4B,OAAQ,CAAC;AAElD,MAAM,MAAM,kBAAkB,GAC1B,iBAAiB,GACjB,UAAU,GACV,iBAAiB,GACjB,cAAc,GACd,mBAAmB,GACnB,gBAAgB,GAChB,WAAW,GACX,YAAY,GACZ,iBAAiB,GACjB,WAAW,GACX,aAAa,GACb,cAAc,GACd,eAAe,CAAC;AAEpB,qBAAa,cAAe,SAAQ,KAAK;IAErC,QAAQ,CAAC,IAAI,EAAE,kBAAkB;IADnC,YACW,IAAI,EAAE,kBAAkB,EACjC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,YAAY,EAIvB;CACF;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;CACrC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,CAAC;IAC5C,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;IACzC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oDAAoD;IACpD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,YAAY,CACV,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,aAAa,CAAC,CAAC;IAC1B,SAAS,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAChE,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAClE,wEAAwE;IACxE,aAAa,CACX,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAChC,wEAAwE;IACxE,YAAY,CACV,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,qBAAqB;IACpC,yDAAyD;IACzD,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,wBAAgB,YAAY,CAC1B,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,cAAc,CAKhB"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Shared limits, error types, and the public Workspace contract.
|
|
2
|
+
export const DEFAULT_MAX_FILE_BYTES = 256 * 1024;
|
|
3
|
+
export const DEFAULT_READ_LINE_COUNT = 200;
|
|
4
|
+
export const MAX_READ_LINE_COUNT = 500;
|
|
5
|
+
export const DEFAULT_LIST_DEPTH = 4;
|
|
6
|
+
export const MAX_LIST_DEPTH = 8;
|
|
7
|
+
export const DEFAULT_LIST_ENTRIES = 200;
|
|
8
|
+
export const MAX_LIST_ENTRIES = 1_000;
|
|
9
|
+
export const DEFAULT_SEARCH_RESULTS = 50;
|
|
10
|
+
export const MAX_SEARCH_RESULTS = 200;
|
|
11
|
+
export const DEFAULT_MAX_SEARCH_FILES = 2_000;
|
|
12
|
+
export const DEFAULT_MAX_SEARCH_BYTES = 10 * 1024 * 1024;
|
|
13
|
+
export const MAX_QUERY_CHARACTERS = 256;
|
|
14
|
+
export const MAX_PREVIEW_CHARACTERS = 300;
|
|
15
|
+
export const MAX_RELATIVE_PATH_CHARACTERS = 4_096;
|
|
16
|
+
export class WorkspaceError extends Error {
|
|
17
|
+
code;
|
|
18
|
+
constructor(code, message, options) {
|
|
19
|
+
super(message, options);
|
|
20
|
+
this.code = code;
|
|
21
|
+
this.name = "WorkspaceError";
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export function invalidRange(relativePath, startLine, totalLines) {
|
|
25
|
+
return new WorkspaceError("invalid_range", `start_line ${startLine} is outside ${relativePath}, which has ${totalLines} lines.`);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/workspace/types.ts"],"names":[],"mappings":"AAAA,iEAAiE;AAEjE,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,GAAG,IAAI,CAAC;AACjD,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAC3C,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAC;AACvC,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AACpC,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC;AAChC,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,CAAC;AACxC,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,CAAC;AACtC,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,CAAC;AACzC,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAC;AACtC,MAAM,CAAC,MAAM,wBAAwB,GAAG,KAAK,CAAC;AAC9C,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AACzD,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,CAAC;AACxC,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAC1C,MAAM,CAAC,MAAM,4BAA4B,GAAG,KAAK,CAAC;AAiBlD,MAAM,OAAO,cAAe,SAAQ,KAAK;IAE5B,IAAI;IADf,YACW,IAAwB,EACjC,OAAe,EACf,OAAsB;QAEtB,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;oBAJf,IAAI;QAKb,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AA2GD,MAAM,UAAU,YAAY,CAC1B,YAAoB,EACpB,SAAiB,EACjB,UAAkB;IAElB,OAAO,IAAI,cAAc,CACvB,eAAe,EACf,cAAc,SAAS,eAAe,YAAY,eAAe,UAAU,SAAS,CACrF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type EditTextFileOptions, type EditTextFileResult, type WorkspaceLimits, type WriteTextFileResult } from "./types.js";
|
|
2
|
+
export declare function writeTextFile(limits: WorkspaceLimits, relativePath: string, contents: string): Promise<WriteTextFileResult>;
|
|
3
|
+
export declare function editTextFile(limits: WorkspaceLimits, relativePath: string, options: EditTextFileOptions): Promise<EditTextFileResult>;
|
|
4
|
+
//# sourceMappingURL=write.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../src/workspace/write.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACzB,MAAM,YAAY,CAAC;AAqDpB,wBAAsB,aAAa,CACjC,MAAM,EAAE,eAAe,EACvB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,mBAAmB,CAAC,CAiB9B;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,eAAe,EACvB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,CAoD7B"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { mkdir, rename, unlink, writeFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { WorkspaceError, } from "./types.js";
|
|
4
|
+
import { resolveWritePath } from "./paths.js";
|
|
5
|
+
import { readFullTextFile } from "./read.js";
|
|
6
|
+
import { splitLinesPreservingEndings } from "./text.js";
|
|
7
|
+
/**
|
|
8
|
+
* Writes are staged into a sibling temp file and then renamed over the target.
|
|
9
|
+
* `rename` within one directory is atomic, so a crash midway leaves the
|
|
10
|
+
* original file intact instead of a half-written one.
|
|
11
|
+
*/
|
|
12
|
+
async function writeAtomically(absolutePath, contents) {
|
|
13
|
+
const directory = path.dirname(absolutePath);
|
|
14
|
+
const temporaryPath = path.join(directory, `.${path.basename(absolutePath)}.${process.pid}.${Date.now()}.tmp`);
|
|
15
|
+
await writeFile(temporaryPath, contents, { encoding: "utf8", flag: "wx" });
|
|
16
|
+
try {
|
|
17
|
+
await rename(temporaryPath, absolutePath);
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
await unlink(temporaryPath).catch(() => undefined);
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function validateContents(contents, maxFileBytes, displayPath) {
|
|
25
|
+
if (typeof contents !== "string") {
|
|
26
|
+
throw new TypeError("contents must be a string.");
|
|
27
|
+
}
|
|
28
|
+
if (contents.includes("\0")) {
|
|
29
|
+
throw new WorkspaceError("binary_file", `Refusing to write NUL bytes: ${displayPath}`);
|
|
30
|
+
}
|
|
31
|
+
const bytes = Buffer.byteLength(contents, "utf8");
|
|
32
|
+
if (bytes > maxFileBytes) {
|
|
33
|
+
throw new WorkspaceError("too_large", `Contents exceed the ${maxFileBytes}-byte limit: ${displayPath}`);
|
|
34
|
+
}
|
|
35
|
+
return bytes;
|
|
36
|
+
}
|
|
37
|
+
export async function writeTextFile(limits, relativePath, contents) {
|
|
38
|
+
const bytesWritten = validateContents(contents, limits.maxFileBytes, relativePath);
|
|
39
|
+
const resolved = await resolveWritePath(limits.root, relativePath);
|
|
40
|
+
await mkdir(path.dirname(resolved.lexicalTarget), { recursive: true });
|
|
41
|
+
await writeAtomically(resolved.lexicalTarget, contents);
|
|
42
|
+
return {
|
|
43
|
+
path: resolved.relativePath,
|
|
44
|
+
created: !resolved.exists,
|
|
45
|
+
bytesWritten,
|
|
46
|
+
totalLines: splitLinesPreservingEndings(contents).length,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export async function editTextFile(limits, relativePath, options) {
|
|
50
|
+
const { oldText, newText } = options;
|
|
51
|
+
if (typeof oldText !== "string" || oldText.length === 0) {
|
|
52
|
+
throw new TypeError("old_text must be a non-empty string.");
|
|
53
|
+
}
|
|
54
|
+
if (typeof newText !== "string") {
|
|
55
|
+
throw new TypeError("new_text must be a string.");
|
|
56
|
+
}
|
|
57
|
+
if (oldText === newText) {
|
|
58
|
+
throw new WorkspaceError("invalid_range", "old_text and new_text are identical, so the edit would change nothing.");
|
|
59
|
+
}
|
|
60
|
+
// Reading first proves the file exists, is a regular file, is valid UTF-8,
|
|
61
|
+
// and is within the size limit, reusing the read path's guarantees.
|
|
62
|
+
const original = await readFullTextFile(limits, relativePath);
|
|
63
|
+
const resolved = await resolveWritePath(limits.root, relativePath);
|
|
64
|
+
const firstIndex = original.indexOf(oldText);
|
|
65
|
+
if (firstIndex === -1) {
|
|
66
|
+
throw new WorkspaceError("no_match", `old_text does not appear in ${relativePath}. Read the file again and copy the exact text, including indentation.`);
|
|
67
|
+
}
|
|
68
|
+
if (original.indexOf(oldText, firstIndex + 1) !== -1) {
|
|
69
|
+
throw new WorkspaceError("ambiguous_match", `old_text appears more than once in ${relativePath}. Include enough surrounding context to make it unique.`);
|
|
70
|
+
}
|
|
71
|
+
const updated = original.slice(0, firstIndex) +
|
|
72
|
+
newText +
|
|
73
|
+
original.slice(firstIndex + oldText.length);
|
|
74
|
+
const bytesWritten = validateContents(updated, limits.maxFileBytes, relativePath);
|
|
75
|
+
await writeAtomically(resolved.lexicalTarget, updated);
|
|
76
|
+
return {
|
|
77
|
+
path: resolved.relativePath,
|
|
78
|
+
line: splitLinesPreservingEndings(original.slice(0, firstIndex)).length + 1,
|
|
79
|
+
bytesWritten,
|
|
80
|
+
totalLines: splitLinesPreservingEndings(updated).length,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=write.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write.js","sourceRoot":"","sources":["../../src/workspace/write.ts"],"names":[],"mappings":"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"}
|
package/dist/workspace.d.ts
CHANGED
|
@@ -1,72 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export interface TextFileSlice {
|
|
11
|
-
readonly content: string;
|
|
12
|
-
readonly startLine: number;
|
|
13
|
-
readonly endLine: number;
|
|
14
|
-
readonly totalLines: number;
|
|
15
|
-
readonly truncated: boolean;
|
|
16
|
-
}
|
|
17
|
-
export interface ListFilesOptions {
|
|
18
|
-
readonly path?: string;
|
|
19
|
-
readonly maxDepth?: number;
|
|
20
|
-
readonly maxEntries?: number;
|
|
21
|
-
}
|
|
22
|
-
export interface WorkspaceEntry {
|
|
23
|
-
readonly path: string;
|
|
24
|
-
readonly type: "file" | "directory";
|
|
25
|
-
}
|
|
26
|
-
export interface ListFilesResult {
|
|
27
|
-
readonly entries: readonly WorkspaceEntry[];
|
|
28
|
-
readonly truncated: boolean;
|
|
29
|
-
}
|
|
30
|
-
export interface SearchTextOptions {
|
|
31
|
-
readonly query: string;
|
|
32
|
-
readonly path?: string;
|
|
33
|
-
readonly maxResults?: number;
|
|
34
|
-
}
|
|
35
|
-
export interface SearchMatch {
|
|
36
|
-
readonly path: string;
|
|
37
|
-
readonly line: number;
|
|
38
|
-
readonly preview: string;
|
|
39
|
-
}
|
|
40
|
-
export interface SearchTextResult {
|
|
41
|
-
readonly matches: readonly SearchMatch[];
|
|
42
|
-
readonly truncated: boolean;
|
|
43
|
-
readonly scannedFiles: number;
|
|
44
|
-
readonly skippedFiles: number;
|
|
45
|
-
}
|
|
46
|
-
export interface Workspace {
|
|
47
|
-
readonly root: string;
|
|
48
|
-
readTextFile(relativePath: string, options?: ReadTextFileOptions): Promise<TextFileSlice>;
|
|
49
|
-
listFiles(options?: ListFilesOptions): Promise<ListFilesResult>;
|
|
50
|
-
searchText(options: SearchTextOptions): Promise<SearchTextResult>;
|
|
51
|
-
}
|
|
52
|
-
export interface LocalWorkspaceOptions {
|
|
53
|
-
readonly maxFileBytes?: number;
|
|
54
|
-
readonly maxSearchFiles?: number;
|
|
55
|
-
readonly maxSearchBytes?: number;
|
|
56
|
-
}
|
|
1
|
+
import { type EditTextFileOptions, type EditTextFileResult, type ListFilesOptions, type ListFilesResult, type LocalWorkspaceOptions, type ReadTextFileOptions, type SearchTextOptions, type SearchTextResult, type TextFileSlice, type Workspace, type WriteTextFileResult } from "./workspace/types.js";
|
|
2
|
+
export * from "./workspace/types.js";
|
|
3
|
+
/**
|
|
4
|
+
* A workspace rooted at a single directory.
|
|
5
|
+
*
|
|
6
|
+
* Every operation lives in its own module under `src/workspace/` and receives
|
|
7
|
+
* the resolved limits explicitly; this class only owns configuration and the
|
|
8
|
+
* read-only default.
|
|
9
|
+
*/
|
|
57
10
|
export declare class LocalWorkspace implements Workspace {
|
|
58
11
|
readonly root: string;
|
|
59
|
-
private readonly
|
|
60
|
-
private readonly
|
|
61
|
-
private readonly maxSearchBytes;
|
|
12
|
+
private readonly limits;
|
|
13
|
+
private readonly allowWrites;
|
|
62
14
|
constructor(root: string, options?: LocalWorkspaceOptions);
|
|
15
|
+
/** True when this workspace was constructed with writes enabled. */
|
|
16
|
+
get writable(): boolean;
|
|
63
17
|
readTextFile(relativePath: string, options?: ReadTextFileOptions): Promise<TextFileSlice>;
|
|
64
18
|
listFiles(options?: ListFilesOptions): Promise<ListFilesResult>;
|
|
65
19
|
searchText(options: SearchTextOptions): Promise<SearchTextResult>;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
private
|
|
69
|
-
private rejectExplicitDirectorySymlink;
|
|
70
|
-
private createIgnoreMatcher;
|
|
20
|
+
writeTextFile(relativePath: string, contents: string): Promise<WriteTextFileResult>;
|
|
21
|
+
editTextFile(relativePath: string, options: EditTextFileOptions): Promise<EditTextFileResult>;
|
|
22
|
+
private assertWritesEnabled;
|
|
71
23
|
}
|
|
72
24
|
//# sourceMappingURL=workspace.d.ts.map
|
package/dist/workspace.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,SAAS,EAEd,KAAK,mBAAmB,EACzB,MAAM,sBAAsB,CAAC;AAQ9B,cAAc,sBAAsB,CAAC;AAErC;;;;;;GAMG;AACH,qBAAa,cAAe,YAAW,SAAS;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAU;IAEtC,YAAY,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,EAqB5D;IAED,oEAAoE;IACpE,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAEK,YAAY,CAChB,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,aAAa,CAAC,CAExB;IAEK,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC,CAExE;IAEK,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAEtE;IAEK,aAAa,CACjB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,mBAAmB,CAAC,CAG9B;IAEK,YAAY,CAChB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,CAG7B;IAED,OAAO,CAAC,mBAAmB;CAQ5B"}
|