scoutline 0.2.0 → 0.6.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 +240 -18
- package/dist/capabilities/diagnostics.d.ts +70 -32
- package/dist/capabilities/diagnostics.d.ts.map +1 -1
- package/dist/capabilities/diagnostics.js +97 -46
- package/dist/capabilities/diagnostics.js.map +1 -1
- package/dist/capabilities/reader.d.ts +227 -0
- package/dist/capabilities/reader.d.ts.map +1 -0
- package/dist/capabilities/reader.js +100 -0
- package/dist/capabilities/reader.js.map +1 -0
- package/dist/capabilities/repository.d.ts +221 -0
- package/dist/capabilities/repository.d.ts.map +1 -0
- package/dist/capabilities/repository.js +172 -0
- package/dist/capabilities/repository.js.map +1 -0
- package/dist/commands/cache.d.ts +106 -0
- package/dist/commands/cache.d.ts.map +1 -0
- package/dist/commands/cache.js +203 -0
- package/dist/commands/cache.js.map +1 -0
- package/dist/commands/doctor.d.ts +17 -6
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +42 -17
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/read.d.ts +74 -14
- package/dist/commands/read.d.ts.map +1 -1
- package/dist/commands/read.js +257 -117
- package/dist/commands/read.js.map +1 -1
- package/dist/commands/repo.d.ts +53 -7
- package/dist/commands/repo.d.ts.map +1 -1
- package/dist/commands/repo.js +104 -123
- package/dist/commands/repo.js.map +1 -1
- package/dist/commands/repository-explorer.d.ts +147 -0
- package/dist/commands/repository-explorer.d.ts.map +1 -0
- package/dist/commands/repository-explorer.js +550 -0
- package/dist/commands/repository-explorer.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +209 -34
- package/dist/index.js.map +1 -1
- package/dist/lib/cache.d.ts +123 -18
- package/dist/lib/cache.d.ts.map +1 -1
- package/dist/lib/cache.js +324 -49
- package/dist/lib/cache.js.map +1 -1
- package/dist/lib/errors.d.ts +24 -1
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +33 -2
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/execution.d.ts +119 -5
- package/dist/lib/execution.d.ts.map +1 -1
- package/dist/lib/execution.js +216 -10
- package/dist/lib/execution.js.map +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +1 -1
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/mcp-client.d.ts +29 -5
- package/dist/lib/mcp-client.d.ts.map +1 -1
- package/dist/lib/mcp-client.js +88 -88
- package/dist/lib/mcp-client.js.map +1 -1
- package/dist/lib/tool-cache.d.ts +86 -0
- package/dist/lib/tool-cache.d.ts.map +1 -0
- package/dist/lib/tool-cache.js +123 -0
- package/dist/lib/tool-cache.js.map +1 -0
- package/dist/providers/minimax/adapter.d.ts +6 -4
- package/dist/providers/minimax/adapter.d.ts.map +1 -1
- package/dist/providers/minimax/adapter.js +64 -57
- package/dist/providers/minimax/adapter.js.map +1 -1
- package/dist/providers/minimax/coding-plan-client.d.ts +60 -0
- package/dist/providers/minimax/coding-plan-client.d.ts.map +1 -0
- package/dist/providers/minimax/coding-plan-client.js +204 -0
- package/dist/providers/minimax/coding-plan-client.js.map +1 -0
- package/dist/providers/minimax/media.d.ts +60 -6
- package/dist/providers/minimax/media.d.ts.map +1 -1
- package/dist/providers/minimax/media.js +147 -7
- package/dist/providers/minimax/media.js.map +1 -1
- package/dist/providers/minimax/quota-client.d.ts +13 -6
- package/dist/providers/minimax/quota-client.d.ts.map +1 -1
- package/dist/providers/minimax/quota-client.js +5 -0
- package/dist/providers/minimax/quota-client.js.map +1 -1
- package/dist/providers/minimax/vision-attestations.d.ts +23 -0
- package/dist/providers/minimax/vision-attestations.d.ts.map +1 -1
- package/dist/providers/minimax/vision-attestations.js +35 -10
- package/dist/providers/minimax/vision-attestations.js.map +1 -1
- package/dist/providers/minimax/vision-conformance.d.ts +8 -6
- package/dist/providers/minimax/vision-conformance.d.ts.map +1 -1
- package/dist/providers/minimax/vision-conformance.js +8 -6
- package/dist/providers/minimax/vision-conformance.js.map +1 -1
- package/dist/providers/minimax/vision-revisions.d.ts +8 -1
- package/dist/providers/minimax/vision-revisions.d.ts.map +1 -1
- package/dist/providers/minimax/vision-revisions.js +13 -6
- package/dist/providers/minimax/vision-revisions.js.map +1 -1
- package/dist/providers/selection.d.ts +3 -3
- package/dist/providers/selection.js +3 -3
- package/dist/providers/types.d.ts +66 -32
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/providers/types.js.map +1 -1
- package/dist/providers/zai/adapter.d.ts.map +1 -1
- package/dist/providers/zai/adapter.js +71 -5
- package/dist/providers/zai/adapter.js.map +1 -1
- package/dist/providers/zai/encoded-error.d.ts +90 -0
- package/dist/providers/zai/encoded-error.d.ts.map +1 -0
- package/dist/providers/zai/encoded-error.js +169 -0
- package/dist/providers/zai/encoded-error.js.map +1 -0
- package/dist/providers/zai/reader.d.ts +82 -0
- package/dist/providers/zai/reader.d.ts.map +1 -0
- package/dist/providers/zai/reader.js +490 -0
- package/dist/providers/zai/reader.js.map +1 -0
- package/dist/providers/zai/repository.d.ts +76 -0
- package/dist/providers/zai/repository.d.ts.map +1 -0
- package/dist/providers/zai/repository.js +715 -0
- package/dist/providers/zai/repository.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,550 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider-neutral Repository Explorer (P6-05, DESIGN.md §18, §11,
|
|
3
|
+
* PRD FR-081, FR-083–FR-086, FR-088, FR-091; NFR-004, NFR-005, NFR-007).
|
|
4
|
+
*
|
|
5
|
+
* The Explorer is the single non-Adapter consumer of the Repository
|
|
6
|
+
* Capability contract. It owns canonical repository-path handling,
|
|
7
|
+
* deterministic breadth-first traversal, duplicate-directory
|
|
8
|
+
* protection, and local Search/File `--max-chars` projection. It
|
|
9
|
+
* constructs canonical Capability requests, hands them to shared
|
|
10
|
+
* execution, and projects the normalized results.
|
|
11
|
+
*
|
|
12
|
+
* Boundary rules (ARCHITECTURE.md §2, NFR-004):
|
|
13
|
+
* - Imports ONLY provider-neutral Repository Capability types and
|
|
14
|
+
* shared `executeRepositoryOperation` / `ExecutionDependencies`,
|
|
15
|
+
* plus the normalized `ValidationError`.
|
|
16
|
+
* - Imports NO concrete Provider Adapter, MCP/UTCP client, raw tool
|
|
17
|
+
* name, or Provider response type. Provider-specific facts (ZRead
|
|
18
|
+
* grammar, credentials, transports) remain Adapter-internal.
|
|
19
|
+
* - Owns canonicalization, BFS, and projection; never owns
|
|
20
|
+
* transport, credentials, Provider selection, or command
|
|
21
|
+
* presentation.
|
|
22
|
+
*
|
|
23
|
+
* Fixed ordering (DESIGN.md §18):
|
|
24
|
+
* 1. Apply Explorer-level defaults (Search `language`, Tree
|
|
25
|
+
* `depth`) and canonicalize paths.
|
|
26
|
+
* 2. Validate `repository` (at-least-one-slash), `query`
|
|
27
|
+
* (non-whitespace), `language`, and `depth`.
|
|
28
|
+
* 3. Construct the canonical Capability request.
|
|
29
|
+
* 4. Delegate to `executeRepositoryOperation`, which runs
|
|
30
|
+
* `operation.validate`, `operation.cacheIdentity`, the
|
|
31
|
+
* provider-partitioned cache read, ordered legacy candidates,
|
|
32
|
+
* retry-wrapped invoke, and the normalized cache write.
|
|
33
|
+
* 5. Apply post-execution `--max-chars` projection (Search/File
|
|
34
|
+
* only). Tree is never character-limited.
|
|
35
|
+
*
|
|
36
|
+
* `--max-chars` is post-execution projection. It never appears in
|
|
37
|
+
* the canonical request, the cache identity, or the cache itself.
|
|
38
|
+
*/
|
|
39
|
+
import { executeRepositoryOperation, } from "../lib/execution.js";
|
|
40
|
+
import { ValidationError } from "../lib/errors.js";
|
|
41
|
+
/**
|
|
42
|
+
* Canonicalize a repository-relative POSIX path.
|
|
43
|
+
*
|
|
44
|
+
* Rules (DESIGN.md §18, technical plan):
|
|
45
|
+
* - Backslashes (`\\`) and ASCII control characters (C0 plus DEL,
|
|
46
|
+
* code points 0–31 and 127) always throw `ValidationError`.
|
|
47
|
+
* - Whole-string root aliases (`undefined`, `""`, `"/"`, `"."`)
|
|
48
|
+
* map to root (`""`). For File (`kind: "file"`), root is
|
|
49
|
+
* invalid and throws.
|
|
50
|
+
* - File accepts a single leading `./` and any leading `/` as
|
|
51
|
+
* convenience; both are stripped. Directory does NOT get the
|
|
52
|
+
* leading `./` convenience (a leading `.` segment is unsafe and
|
|
53
|
+
* is rejected below); leading `/` is naturally stripped by the
|
|
54
|
+
* empty-segment collapse.
|
|
55
|
+
* - Repeated `/` collapses and trailing `/` is removed via the
|
|
56
|
+
* empty-segment skip.
|
|
57
|
+
* - Actual `.` or `..` segments at any position throw.
|
|
58
|
+
* - Percent escapes are never decoded.
|
|
59
|
+
*
|
|
60
|
+
* Returns the canonical repository-relative POSIX path. `""` is the
|
|
61
|
+
* repository root.
|
|
62
|
+
*/
|
|
63
|
+
export function canonicalizeRepositoryPath(input, kind) {
|
|
64
|
+
// 1. `undefined` is the canonical "omitted" value. For File this
|
|
65
|
+
// is invalid because File requires a non-root path; for
|
|
66
|
+
// Directory/Tree it is the root.
|
|
67
|
+
if (input === undefined) {
|
|
68
|
+
if (kind === "file") {
|
|
69
|
+
throw new ValidationError("File path is required");
|
|
70
|
+
}
|
|
71
|
+
return "";
|
|
72
|
+
}
|
|
73
|
+
if (typeof input !== "string") {
|
|
74
|
+
throw new ValidationError("Repository path must be a string");
|
|
75
|
+
}
|
|
76
|
+
// 2. Reject backslashes and ASCII control characters (C0 + DEL).
|
|
77
|
+
// Percent escapes are never decoded, so `%2e` and similar are
|
|
78
|
+
// preserved as literal three-character sequences.
|
|
79
|
+
for (let i = 0; i < input.length; i += 1) {
|
|
80
|
+
const code = input.charCodeAt(i);
|
|
81
|
+
if (code === 92 /* backslash */) {
|
|
82
|
+
throw new ValidationError("Repository path must not contain backslashes");
|
|
83
|
+
}
|
|
84
|
+
if (code < 32 || code === 127) {
|
|
85
|
+
throw new ValidationError("Repository path must not contain ASCII control characters");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// 3. Whole-string root aliases. `""`, `"/"`, and `"."` all map
|
|
89
|
+
// to root. For File, root is invalid.
|
|
90
|
+
if (input === "" || input === "/" || input === ".") {
|
|
91
|
+
if (kind === "file") {
|
|
92
|
+
throw new ValidationError("File path must not be the repository root");
|
|
93
|
+
}
|
|
94
|
+
return "";
|
|
95
|
+
}
|
|
96
|
+
// 4. File-only leading `./` convenience. Directory does not get
|
|
97
|
+
// this: a leading `.` segment is unsafe and is rejected below.
|
|
98
|
+
// Leading `/` is naturally stripped by the empty-segment
|
|
99
|
+
// collapse for both kinds.
|
|
100
|
+
let work = input;
|
|
101
|
+
if (kind === "file" && work.startsWith("./")) {
|
|
102
|
+
work = work.slice(2);
|
|
103
|
+
}
|
|
104
|
+
// 5. Split, collapse empty segments (handles leading/trailing/
|
|
105
|
+
// repeated `/`), and reject any actual `.` or `..` segment.
|
|
106
|
+
const segments = [];
|
|
107
|
+
for (const segment of work.split("/")) {
|
|
108
|
+
if (segment === "")
|
|
109
|
+
continue;
|
|
110
|
+
if (segment === "." || segment === "..") {
|
|
111
|
+
throw new ValidationError(`Repository path must not contain a "${segment}" segment`);
|
|
112
|
+
}
|
|
113
|
+
segments.push(segment);
|
|
114
|
+
}
|
|
115
|
+
const canonical = segments.join("/");
|
|
116
|
+
if (canonical === "") {
|
|
117
|
+
// The input reduced to nothing (e.g., `"///"` or `"./"`). For
|
|
118
|
+
// File, this is root and invalid; for Directory/Tree, this is
|
|
119
|
+
// root.
|
|
120
|
+
if (kind === "file") {
|
|
121
|
+
throw new ValidationError("File path must not be the repository root");
|
|
122
|
+
}
|
|
123
|
+
return "";
|
|
124
|
+
}
|
|
125
|
+
return canonical;
|
|
126
|
+
}
|
|
127
|
+
// ---------------------------------------------------------------------------
|
|
128
|
+
// Defaults and Explorer-level pre-validation.
|
|
129
|
+
//
|
|
130
|
+
// Defaults and canonicalization happen BEFORE
|
|
131
|
+
// `operation.validate` / `operation.cacheIdentity`. The Explorer's
|
|
132
|
+
// pre-validation is provider-neutral (slash in repository,
|
|
133
|
+
// non-whitespace query, language in `{en, zh}`, finite positive
|
|
134
|
+
// integer depth); the Adapter's `operation.validate` runs after,
|
|
135
|
+
// as a defensive backstop with Provider-specific messaging.
|
|
136
|
+
// ---------------------------------------------------------------------------
|
|
137
|
+
/**
|
|
138
|
+
* Normalize a Search language value. `undefined` defaults to `"en"`;
|
|
139
|
+
* `"en"` and `"zh"` are passed through; any other value throws
|
|
140
|
+
* `ValidationError`.
|
|
141
|
+
*/
|
|
142
|
+
function normalizeSearchLanguage(language) {
|
|
143
|
+
if (language === undefined)
|
|
144
|
+
return "en";
|
|
145
|
+
if (language === "en" || language === "zh")
|
|
146
|
+
return language;
|
|
147
|
+
throw new ValidationError('Search language must be "en" or "zh"');
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Project a Tree depth value. `undefined` defaults to 1. Finite
|
|
151
|
+
* positive values are floored to an integer; non-finite or
|
|
152
|
+
* non-positive values throw `ValidationError`. Matches the
|
|
153
|
+
* existing shipped behaviour.
|
|
154
|
+
*/
|
|
155
|
+
function projectTreeDepth(depth) {
|
|
156
|
+
if (depth === undefined)
|
|
157
|
+
return 1;
|
|
158
|
+
const n = Number(depth);
|
|
159
|
+
if (!Number.isFinite(n) || n < 1) {
|
|
160
|
+
throw new ValidationError("Tree depth must be a finite positive integer");
|
|
161
|
+
}
|
|
162
|
+
return Math.floor(n);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Assert that `repository` is a string containing at least one `/`.
|
|
166
|
+
* The check is provider-neutral and preserves the existing
|
|
167
|
+
* at-least-one-slash rule. The exact repository text is preserved.
|
|
168
|
+
*/
|
|
169
|
+
function assertRepositoryString(repository) {
|
|
170
|
+
if (typeof repository !== "string") {
|
|
171
|
+
throw new ValidationError("Repository must be a string");
|
|
172
|
+
}
|
|
173
|
+
let hasSlash = false;
|
|
174
|
+
for (let i = 0; i < repository.length; i += 1) {
|
|
175
|
+
if (repository.charCodeAt(i) === 47 /* "/" */) {
|
|
176
|
+
hasSlash = true;
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (!hasSlash) {
|
|
181
|
+
throw new ValidationError(`Invalid repository format: "${repository}". Use "owner/repo" format (e.g., "facebook/react")`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Assert that `query` is a string containing at least one
|
|
186
|
+
* non-whitespace character. The exact query text is preserved.
|
|
187
|
+
*/
|
|
188
|
+
function assertSearchQuery(query) {
|
|
189
|
+
if (typeof query !== "string" || query.trim().length === 0) {
|
|
190
|
+
throw new ValidationError("Search query must contain at least one non-whitespace character");
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
// ---------------------------------------------------------------------------
|
|
194
|
+
// Provider-derived listing validation (DESIGN.md §18).
|
|
195
|
+
//
|
|
196
|
+
// Every Provider-returned listing and child is validated BEFORE
|
|
197
|
+
// snapshot/enqueue. The validator binds the listing to the exact
|
|
198
|
+
// canonical request and requires every entry to be the immediate
|
|
199
|
+
// child of the listing's path. Unsafe, inconsistent, or
|
|
200
|
+
// non-immediate children fail the whole tree; partial success is
|
|
201
|
+
// never returned. The validation is read-only and never mutates
|
|
202
|
+
// the Adapter result.
|
|
203
|
+
// ---------------------------------------------------------------------------
|
|
204
|
+
function isPlainObject(value) {
|
|
205
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Assert that `name` is a valid single path segment: a non-empty
|
|
209
|
+
* string with no `/`, no backslash, no ASCII control characters
|
|
210
|
+
* (C0 + DEL), and not equal to `.` or `..`. Percent escapes remain
|
|
211
|
+
* literal (`%2e` is three characters, not `.`).
|
|
212
|
+
*
|
|
213
|
+
* A directory entry name supplies exactly one path segment, so the
|
|
214
|
+
* segment-level rules are stricter than the full-path rules: a `/`
|
|
215
|
+
* in a name would split it into multiple segments and is therefore
|
|
216
|
+
* rejected here rather than collapsed.
|
|
217
|
+
*/
|
|
218
|
+
function assertValidEntryName(name) {
|
|
219
|
+
if (typeof name !== "string" || name.length === 0) {
|
|
220
|
+
throw new ValidationError("Provider-derived directory entry name must be a non-empty string");
|
|
221
|
+
}
|
|
222
|
+
for (let i = 0; i < name.length; i += 1) {
|
|
223
|
+
const code = name.charCodeAt(i);
|
|
224
|
+
if (code === 47 /* "/" */) {
|
|
225
|
+
throw new ValidationError("Provider-derived directory entry name must not contain '/'");
|
|
226
|
+
}
|
|
227
|
+
if (code === 92 /* backslash */) {
|
|
228
|
+
throw new ValidationError("Provider-derived directory entry name must not contain backslashes");
|
|
229
|
+
}
|
|
230
|
+
if (code < 32 || code === 127) {
|
|
231
|
+
throw new ValidationError("Provider-derived directory entry name must not contain ASCII control characters");
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
if (name === "." || name === "..") {
|
|
235
|
+
throw new ValidationError(`Provider-derived directory entry name must not be "${name}"`);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Assert that `entry` is a structurally valid
|
|
240
|
+
* {@link RepositoryEntry} that is the IMMEDIATE child of
|
|
241
|
+
* `listingPath` under the canonical request.
|
|
242
|
+
*
|
|
243
|
+
* The entry's `name` must be a valid single segment, and the
|
|
244
|
+
* entry's `path` must equal the immediate-child path constructed
|
|
245
|
+
* from `listingPath` and `name`:
|
|
246
|
+
*
|
|
247
|
+
* expectedPath = listingPath === "" ? name : listingPath + "/" + name
|
|
248
|
+
*
|
|
249
|
+
* `entry.path` MUST equal `expectedPath` exactly. The expectedPath
|
|
250
|
+
* is then canonicalized through the shared canonicalizer under the
|
|
251
|
+
* entry's kind to reject any non-canonical residue. Because
|
|
252
|
+
* `listingPath` arrived canonical (either the Explorer-canonical
|
|
253
|
+
* starting path or a previously validated immediate-child path) and
|
|
254
|
+
* `entry.name` is a validated single segment, the canonical form
|
|
255
|
+
* should equal the expected form; this final canonicalize call is
|
|
256
|
+
* defensive against any future regression.
|
|
257
|
+
*
|
|
258
|
+
* DESIGN §18: `entry.name` is the final path segment and the
|
|
259
|
+
* DirectoryListing holds the requested directory's immediate
|
|
260
|
+
* entries.
|
|
261
|
+
*/
|
|
262
|
+
function assertValidRepositoryEntry(entry, listingPath) {
|
|
263
|
+
if (!isPlainObject(entry)) {
|
|
264
|
+
throw new ValidationError("Provider-derived directory entry must be an object");
|
|
265
|
+
}
|
|
266
|
+
assertValidEntryName(entry.name);
|
|
267
|
+
if (entry.kind !== "file" && entry.kind !== "directory") {
|
|
268
|
+
throw new ValidationError("Provider-derived directory entry kind must be 'file' or 'directory'");
|
|
269
|
+
}
|
|
270
|
+
if (typeof entry.path !== "string" || entry.path.length === 0) {
|
|
271
|
+
throw new ValidationError("Provider-derived directory entry path must be a non-empty string");
|
|
272
|
+
}
|
|
273
|
+
// Compute the expected immediate-child path. listingPath is
|
|
274
|
+
// already canonical; entry.name supplies one validated segment.
|
|
275
|
+
const expectedPath = listingPath === "" ? entry.name : `${listingPath}/${entry.name}`;
|
|
276
|
+
if (entry.path !== expectedPath) {
|
|
277
|
+
throw new ValidationError(`Provider-derived directory entry path "${entry.path}" must equal the immediate-child path "${expectedPath}"`);
|
|
278
|
+
}
|
|
279
|
+
// Canonical-safety: canonicalize the expectedPath under the
|
|
280
|
+
// entry's kind to reject any non-canonical residue. Files use the
|
|
281
|
+
// File canonicalizer (root invalid); directories use the
|
|
282
|
+
// Directory canonicalizer (root allowed). A root child is
|
|
283
|
+
// structurally impossible for a non-root listing but is defended
|
|
284
|
+
// against here all the same.
|
|
285
|
+
const canonical = canonicalizeRepositoryPath(expectedPath, entry.kind);
|
|
286
|
+
if (canonical !== expectedPath) {
|
|
287
|
+
throw new ValidationError(`Provider-derived directory entry path is not canonical: "${expectedPath}"`);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Assert that `listing` is a structurally valid
|
|
292
|
+
* {@link RepositoryDirectoryListing} BOUND to the canonical
|
|
293
|
+
* {@link RepositoryDirectoryRequest}. The listing's `repository`
|
|
294
|
+
* MUST equal `request.repository` and the listing's `path` MUST
|
|
295
|
+
* equal `request.path`. Every entry MUST be a valid immediate
|
|
296
|
+
* child of the listing's path.
|
|
297
|
+
*
|
|
298
|
+
* Without this binding a fake or buggy Adapter could return a
|
|
299
|
+
* listing for a different repository or a different directory than
|
|
300
|
+
* the one requested, and the BFS would snapshot or enqueue the
|
|
301
|
+
* wrong subtree. Binding the listing to the request closes that
|
|
302
|
+
* gap.
|
|
303
|
+
*/
|
|
304
|
+
function assertValidRepositoryDirectoryListing(listing, request) {
|
|
305
|
+
if (!isPlainObject(listing)) {
|
|
306
|
+
throw new ValidationError("Provider-derived directory listing must be an object");
|
|
307
|
+
}
|
|
308
|
+
if (typeof listing.repository !== "string") {
|
|
309
|
+
throw new ValidationError("Provider-derived directory listing repository must be a string");
|
|
310
|
+
}
|
|
311
|
+
if (listing.repository !== request.repository) {
|
|
312
|
+
throw new ValidationError("Provider-derived directory listing repository must match the request repository");
|
|
313
|
+
}
|
|
314
|
+
if (typeof listing.path !== "string") {
|
|
315
|
+
throw new ValidationError("Provider-derived directory listing path must be a string");
|
|
316
|
+
}
|
|
317
|
+
if (listing.path !== request.path) {
|
|
318
|
+
throw new ValidationError("Provider-derived directory listing path must match the request path");
|
|
319
|
+
}
|
|
320
|
+
if (!Array.isArray(listing.entries)) {
|
|
321
|
+
throw new ValidationError("Provider-derived directory listing entries must be an array");
|
|
322
|
+
}
|
|
323
|
+
for (const entry of listing.entries) {
|
|
324
|
+
assertValidRepositoryEntry(entry, listing.path);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
// ---------------------------------------------------------------------------
|
|
328
|
+
// Local `--max-chars` projection (DESIGN.md §18, technical plan).
|
|
329
|
+
//
|
|
330
|
+
// Projection is post-execution: it runs on the normalized result
|
|
331
|
+
// returned by shared execution. It is the only step that consumes
|
|
332
|
+
// `--max-chars`. `--max-chars` never enters the canonical request,
|
|
333
|
+
// the cache identity, or the cache itself. Tree is never
|
|
334
|
+
// character-limited.
|
|
335
|
+
// ---------------------------------------------------------------------------
|
|
336
|
+
/**
|
|
337
|
+
* Apply the Search `--max-chars` budget. The budget is a single
|
|
338
|
+
* total character count consumed by `excerpts[].text` in Provider
|
|
339
|
+
* order. Absent, `NaN`, zero, or negative means no truncation
|
|
340
|
+
* (matches the shipped `!max || max <= 0` rule). `Infinity` is
|
|
341
|
+
* naturally unlimited (the loop fits every excerpt). Whole
|
|
342
|
+
* excerpts are kept while they fit; the final retained excerpt is
|
|
343
|
+
* truncated with the existing rule
|
|
344
|
+
* `text.slice(0, remaining - 1).trimEnd() + "…"`; later excerpts
|
|
345
|
+
* are omitted. Metadata (`repository`, `query`, `language`,
|
|
346
|
+
* `originalTextLength`) is outside the budget. `originalTextLength`
|
|
347
|
+
* reports the full pre-projection value; `truncated` is set if the
|
|
348
|
+
* projection omitted or truncated any excerpt, OR if the Provider
|
|
349
|
+
* flagged its own truncation.
|
|
350
|
+
*
|
|
351
|
+
* The input result is never mutated.
|
|
352
|
+
*/
|
|
353
|
+
function projectSearchResult(result, maxChars) {
|
|
354
|
+
if (!maxChars || maxChars <= 0) {
|
|
355
|
+
return result;
|
|
356
|
+
}
|
|
357
|
+
let remaining = maxChars;
|
|
358
|
+
const projectedExcerpts = [];
|
|
359
|
+
let projectionTruncated = false;
|
|
360
|
+
for (const excerpt of result.excerpts) {
|
|
361
|
+
if (remaining <= 0) {
|
|
362
|
+
projectionTruncated = true;
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
365
|
+
if (excerpt.text.length <= remaining) {
|
|
366
|
+
projectedExcerpts.push({ text: excerpt.text });
|
|
367
|
+
remaining -= excerpt.text.length;
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
const truncatedText = excerpt.text.slice(0, remaining - 1).trimEnd() + "…";
|
|
371
|
+
projectedExcerpts.push({ text: truncatedText });
|
|
372
|
+
remaining = 0;
|
|
373
|
+
projectionTruncated = true;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
if (!projectionTruncated) {
|
|
377
|
+
return result;
|
|
378
|
+
}
|
|
379
|
+
return {
|
|
380
|
+
schemaVersion: 1,
|
|
381
|
+
repository: result.repository,
|
|
382
|
+
query: result.query,
|
|
383
|
+
language: result.language,
|
|
384
|
+
excerpts: projectedExcerpts,
|
|
385
|
+
truncated: true,
|
|
386
|
+
originalTextLength: result.originalTextLength,
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Apply the File `--max-chars` budget to `content`. Absent, `NaN`,
|
|
391
|
+
* zero, or negative means no truncation (matches the shipped
|
|
392
|
+
* `!max || max <= 0` rule). `Infinity` is naturally unlimited.
|
|
393
|
+
* Content shorter than or equal to the budget is returned
|
|
394
|
+
* unchanged. Otherwise the content is truncated with the existing
|
|
395
|
+
* rule `content.slice(0, max - 1).trimEnd() + "…"`. `truncated` is
|
|
396
|
+
* set if the projection truncated the content or if the Provider
|
|
397
|
+
* flagged its own truncation. `originalContentLength` reports the
|
|
398
|
+
* full pre-projection value.
|
|
399
|
+
*
|
|
400
|
+
* The input result is never mutated.
|
|
401
|
+
*/
|
|
402
|
+
function projectFileResult(result, maxChars) {
|
|
403
|
+
if (!maxChars || maxChars <= 0) {
|
|
404
|
+
return result;
|
|
405
|
+
}
|
|
406
|
+
if (result.content.length <= maxChars) {
|
|
407
|
+
return result;
|
|
408
|
+
}
|
|
409
|
+
const truncatedContent = result.content.slice(0, maxChars - 1).trimEnd() + "…";
|
|
410
|
+
return {
|
|
411
|
+
schemaVersion: 1,
|
|
412
|
+
repository: result.repository,
|
|
413
|
+
path: result.path,
|
|
414
|
+
content: truncatedContent,
|
|
415
|
+
truncated: true,
|
|
416
|
+
originalContentLength: result.originalContentLength,
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
// ---------------------------------------------------------------------------
|
|
420
|
+
// Breadth-first traversal (DESIGN.md §18).
|
|
421
|
+
//
|
|
422
|
+
// Deterministic BFS that preserves Provider sibling order,
|
|
423
|
+
// snapshots breadth-first, requests each canonical directory at
|
|
424
|
+
// most once, expands only directories while `level < depth`, and
|
|
425
|
+
// never returns partial success after a directory failure.
|
|
426
|
+
// ---------------------------------------------------------------------------
|
|
427
|
+
/**
|
|
428
|
+
* Collect directory snapshots via deterministic breadth-first
|
|
429
|
+
* traversal.
|
|
430
|
+
*
|
|
431
|
+
* Rules:
|
|
432
|
+
* - BFS starts at level 1 with the canonical starting path. The
|
|
433
|
+
* starting directory is requested exactly once and snapshotted
|
|
434
|
+
* even at depth 1.
|
|
435
|
+
* - Children are snapshot/enqueued in Provider sibling order.
|
|
436
|
+
* Only `kind: "directory"` children are enqueued, and only
|
|
437
|
+
* while `level < depth`.
|
|
438
|
+
* - Each canonical directory path is requested at most once.
|
|
439
|
+
* Duplicate encounters (a directory reachable from multiple
|
|
440
|
+
* parents) preserve first-encounter order and are not
|
|
441
|
+
* re-requested.
|
|
442
|
+
* - Every Provider-derived listing and entry is validated before
|
|
443
|
+
* snapshot/enqueue. Unsafe or inconsistent children fail the
|
|
444
|
+
* whole tree; partial success is never returned.
|
|
445
|
+
*
|
|
446
|
+
* `executeRepositoryOperation` is the single transport-touching
|
|
447
|
+
* call per directory; it owns validate/cache-identity/cache/retry.
|
|
448
|
+
* The Explorer never invokes the Adapter directly.
|
|
449
|
+
*/
|
|
450
|
+
async function collectTreeSnapshots(capability, canonicalRequest, depth, options, dependencies) {
|
|
451
|
+
const snapshots = [];
|
|
452
|
+
const visited = new Set();
|
|
453
|
+
// Queue entries: { request, level }. The starting path is
|
|
454
|
+
// enqueued at level 1. The visited set is populated at enqueue
|
|
455
|
+
// time so a directory reachable from multiple parents is
|
|
456
|
+
// requested exactly once and appears in first-encounter order.
|
|
457
|
+
const queue = [
|
|
458
|
+
{ request: canonicalRequest, level: 1 },
|
|
459
|
+
];
|
|
460
|
+
visited.add(canonicalRequest.path);
|
|
461
|
+
while (queue.length > 0) {
|
|
462
|
+
const { request, level } = queue.shift();
|
|
463
|
+
const listing = await executeRepositoryOperation(capability.listDirectory, request, options, dependencies);
|
|
464
|
+
// Validate the Adapter result before snapshot/enqueue. Bind the
|
|
465
|
+
// listing to the canonical request so a fake or buggy Adapter
|
|
466
|
+
// cannot snapshot or enqueue a different repository, a different
|
|
467
|
+
// directory, or non-immediate children.
|
|
468
|
+
assertValidRepositoryDirectoryListing(listing, request);
|
|
469
|
+
snapshots.push(listing);
|
|
470
|
+
if (level >= depth)
|
|
471
|
+
continue;
|
|
472
|
+
for (const entry of listing.entries) {
|
|
473
|
+
if (entry.kind !== "directory")
|
|
474
|
+
continue;
|
|
475
|
+
if (visited.has(entry.path))
|
|
476
|
+
continue;
|
|
477
|
+
visited.add(entry.path);
|
|
478
|
+
queue.push({
|
|
479
|
+
request: { repository: request.repository, path: entry.path },
|
|
480
|
+
level: level + 1,
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
return snapshots;
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Provider-neutral Repository Search (DESIGN.md §18, PRD FR-081,
|
|
488
|
+
* FR-083). Applies the `language` default, validates `repository`
|
|
489
|
+
* (at-least-one-slash) and `query` (non-whitespace), constructs the
|
|
490
|
+
* canonical request, delegates to shared execution, and applies the
|
|
491
|
+
* `--max-chars` budget to `excerpts[].text` only.
|
|
492
|
+
*
|
|
493
|
+
* Defaults and canonicalization precede `operation.validate` /
|
|
494
|
+
* `operation.cacheIdentity`. The Provider sees the canonical
|
|
495
|
+
* request; the Explorer never widens into Provider-specific fields.
|
|
496
|
+
*/
|
|
497
|
+
export async function explorerSearch(capability, request, options, dependencies) {
|
|
498
|
+
assertRepositoryString(request.repository);
|
|
499
|
+
assertSearchQuery(request.query);
|
|
500
|
+
const language = normalizeSearchLanguage(request.language);
|
|
501
|
+
const canonicalRequest = {
|
|
502
|
+
repository: request.repository,
|
|
503
|
+
query: request.query,
|
|
504
|
+
language,
|
|
505
|
+
};
|
|
506
|
+
const result = await executeRepositoryOperation(capability.search, canonicalRequest, { noCache: options.noCache, retryPolicy: options.retryPolicy }, dependencies);
|
|
507
|
+
return projectSearchResult(result, options.maxChars);
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* Provider-neutral Repository File read (DESIGN.md §18, PRD FR-086).
|
|
511
|
+
* Canonicalizes the File path (root rejected, leading `./` and `/`
|
|
512
|
+
* stripped, unsafe segments throw), delegates to shared execution,
|
|
513
|
+
* and applies the `--max-chars` budget to `content` only.
|
|
514
|
+
*/
|
|
515
|
+
export async function explorerReadFile(capability, request, options, dependencies) {
|
|
516
|
+
assertRepositoryString(request.repository);
|
|
517
|
+
const canonicalPath = canonicalizeRepositoryPath(request.path, "file");
|
|
518
|
+
const canonicalRequest = {
|
|
519
|
+
repository: request.repository,
|
|
520
|
+
path: canonicalPath,
|
|
521
|
+
};
|
|
522
|
+
const result = await executeRepositoryOperation(capability.readFile, canonicalRequest, { noCache: options.noCache, retryPolicy: options.retryPolicy }, dependencies);
|
|
523
|
+
return projectFileResult(result, options.maxChars);
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Provider-neutral Repository Tree (DESIGN.md §18, PRD FR-088).
|
|
527
|
+
* Canonicalizes the starting path (root allowed), projects depth
|
|
528
|
+
* (default 1, finite positive integer), and drives a deterministic
|
|
529
|
+
* breadth-first traversal that preserves Provider sibling order,
|
|
530
|
+
* requests each canonical directory at most once, and never returns
|
|
531
|
+
* partial success. Tree is never character-limited.
|
|
532
|
+
*/
|
|
533
|
+
export async function explorerTree(capability, request, options, dependencies) {
|
|
534
|
+
assertRepositoryString(request.repository);
|
|
535
|
+
const canonicalPath = canonicalizeRepositoryPath(request.path, "directory");
|
|
536
|
+
const depth = projectTreeDepth(request.depth);
|
|
537
|
+
const canonicalRequest = {
|
|
538
|
+
repository: request.repository,
|
|
539
|
+
path: canonicalPath,
|
|
540
|
+
};
|
|
541
|
+
const snapshots = await collectTreeSnapshots(capability, canonicalRequest, depth, { noCache: options.noCache, retryPolicy: options.retryPolicy }, dependencies);
|
|
542
|
+
return {
|
|
543
|
+
schemaVersion: 1,
|
|
544
|
+
repository: request.repository,
|
|
545
|
+
path: canonicalPath,
|
|
546
|
+
depth,
|
|
547
|
+
snapshots,
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
//# sourceMappingURL=repository-explorer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository-explorer.js","sourceRoot":"","sources":["../../src/commands/repository-explorer.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -41,6 +41,26 @@ export interface MainDependencies {
|
|
|
41
41
|
readonly searchCache?: ResponseCache;
|
|
42
42
|
readonly searchSleep?: (ms: number) => Promise<void>;
|
|
43
43
|
readonly searchRandom?: () => number;
|
|
44
|
+
/**
|
|
45
|
+
* Injectable shared-Repository execution dependencies (P6-07).
|
|
46
|
+
* Production defaults to the same on-disk cache and real sleep/random
|
|
47
|
+
* as Search; tests inject in-memory doubles so Repository dispatch
|
|
48
|
+
* tests stay isolated from Search state. These are NOT a rename of
|
|
49
|
+
* the Search seams.
|
|
50
|
+
*/
|
|
51
|
+
readonly repositoryCache?: ResponseCache;
|
|
52
|
+
readonly repositorySleep?: (ms: number) => Promise<void>;
|
|
53
|
+
readonly repositoryRandom?: () => number;
|
|
54
|
+
/**
|
|
55
|
+
* Injectable shared-Reader execution dependencies (Reader Migration
|
|
56
|
+
* Ticket 04). Production defaults to the same on-disk cache and real
|
|
57
|
+
* sleep/random as Search/Repository; tests inject in-memory doubles
|
|
58
|
+
* so Reader dispatch tests stay isolated from Search/Repository
|
|
59
|
+
* state. NOT a rename of either prior seam.
|
|
60
|
+
*/
|
|
61
|
+
readonly readerCache?: ResponseCache;
|
|
62
|
+
readonly readerSleep?: (ms: number) => Promise<void>;
|
|
63
|
+
readonly readerRandom?: () => number;
|
|
44
64
|
}
|
|
45
65
|
export declare function main(args: readonly string[], dependencies: MainDependencies): Promise<number>;
|
|
46
66
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmCH,OAAO,EAAiB,KAAK,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACvF,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAI1E,OAAO,KAAK,EAAE,kBAAkB,EAAc,MAAM,sBAAsB,CAAC;AA8Z3E;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAuBtE;AAuoBD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,UAAU,EAAE,wBAAwB,CAAC;IAC9C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IAChC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC7D;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,aAAa,CAAC;IACrC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,MAAM,CAAC;IACrC;;;;;;OAMG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,aAAa,CAAC;IACzC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,MAAM,CAAC;IACzC;;;;;;OAMG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,aAAa,CAAC;IACrC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,MAAM,CAAC;CACtC;AAID,wBAAsB,IAAI,CACxB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,YAAY,EAAE,gBAAgB,GAC7B,OAAO,CAAC,MAAM,CAAC,CA4HjB"}
|