@f5-sales-demo/xcsh 23.1.0 → 23.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@f5-sales-demo/xcsh",
4
- "version": "23.1.0",
4
+ "version": "23.2.1",
5
5
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
6
6
  "homepage": "https://github.com/f5-sales-demo/xcsh",
7
7
  "author": "Can Boluk",
@@ -68,13 +68,13 @@
68
68
  },
69
69
  "dependencies": {
70
70
  "@agentclientprotocol/sdk": "1.4.0",
71
- "@f5-sales-demo/pi-agent-core": "23.1.0",
72
- "@f5-sales-demo/pi-ai": "23.1.0",
73
- "@f5-sales-demo/pi-natives": "23.1.0",
74
- "@f5-sales-demo/pi-resource-management": "23.1.0",
75
- "@f5-sales-demo/pi-tui": "23.1.0",
76
- "@f5-sales-demo/pi-utils": "23.1.0",
77
- "@f5-sales-demo/xcsh-stats": "23.1.0",
71
+ "@f5-sales-demo/pi-agent-core": "23.2.1",
72
+ "@f5-sales-demo/pi-ai": "23.2.1",
73
+ "@f5-sales-demo/pi-natives": "23.2.1",
74
+ "@f5-sales-demo/pi-resource-management": "23.2.1",
75
+ "@f5-sales-demo/pi-tui": "23.2.1",
76
+ "@f5-sales-demo/pi-utils": "23.2.1",
77
+ "@f5-sales-demo/xcsh-stats": "23.2.1",
78
78
  "@mozilla/readability": "^0.6",
79
79
  "@resvg/resvg-wasm": "2.6.2",
80
80
  "@sinclair/typebox": "0.34.52",
package/src/cli.ts CHANGED
@@ -231,6 +231,17 @@ if (process.env.XCSH_SMOKE_TEST_QMD === "1") {
231
231
  }
232
232
  }
233
233
 
234
+ if (process.env.XCSH_MEASURE_CORPUS_REQUESTS) {
235
+ try {
236
+ const { runCorpusMeasurement } = await import("./corpus-measurement");
237
+ process.stdout.write(`${await runCorpusMeasurement(process.env.XCSH_MEASURE_CORPUS_REQUESTS)}\n`);
238
+ process.exit(0);
239
+ } catch (error) {
240
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
241
+ process.exit(1);
242
+ }
243
+ }
244
+
234
245
  if (process.env.XCSH_MEASURE_DOCUMENTATION_REQUESTS) {
235
246
  try {
236
247
  const { runDocumentationMeasurement } = await import("./documentation-measurement");
@@ -0,0 +1,65 @@
1
+ import { createHash } from "node:crypto";
2
+ import { readFile } from "node:fs/promises";
3
+ import { BUILD_INFO } from "./internal-urls/build-info.generated";
4
+ import { parseInternalUrl } from "./internal-urls/parse";
5
+ import { PUBLIC_CITATION_SOURCES } from "./internal-urls/public-citation-destinations.generated";
6
+
7
+ export function validateCorpusMeasurementRequests(input: unknown): string[] {
8
+ if (!Array.isArray(input) || !input.length || input.length > 10000 || input.some(uri => typeof uri !== "string"))
9
+ throw new Error("Corpus measurement requires one to 10000 offline corpus URIs");
10
+ for (const uri of input) {
11
+ const parsed = parseInternalUrl(uri);
12
+ if (
13
+ parsed.protocol !== "xcsh:" ||
14
+ !["documentation", "terraform-documentation", "api-spec", "api-catalog"].includes(parsed.rawHost) ||
15
+ parsed.username ||
16
+ parsed.password
17
+ )
18
+ throw new Error("Corpus measurement requires offline corpus URIs");
19
+ }
20
+ return input;
21
+ }
22
+ export async function measureCorpusRequests(input: unknown, read: (uri: string) => Promise<{ content: unknown }>) {
23
+ const results = [];
24
+ for (const request of validateCorpusMeasurementRequests(input)) {
25
+ let response = "",
26
+ error: string | null = null,
27
+ digest = "";
28
+ const times: number[] = [];
29
+ for (let repetition = 0; repetition < 5; repetition++) {
30
+ const start = performance.now();
31
+ try {
32
+ response = JSON.stringify((await read(request)).content);
33
+ error = null;
34
+ } catch (failure) {
35
+ response = "";
36
+ error = failure instanceof Error ? failure.message : String(failure);
37
+ }
38
+ times.push(performance.now() - start);
39
+ const current = createHash("sha256").update(JSON.stringify({ response, error })).digest("hex");
40
+ if (repetition && digest !== current) throw new Error("Non-deterministic installed corpus response");
41
+ digest = current;
42
+ }
43
+ results.push({ request, response_sha256: digest, error, times_ms: times });
44
+ }
45
+ return results;
46
+ }
47
+ export async function runCorpusMeasurement(file: string): Promise<string> {
48
+ const input = await readFile(file);
49
+ if (input.length > 4 * 1024 * 1024) throw new Error("Corpus measurement requests exceed 4 MiB");
50
+ const { InternalDocsProtocolHandler } = await import("./internal-urls/xcsh-protocol");
51
+ const handler = new InternalDocsProtocolHandler();
52
+ const results = await measureCorpusRequests(JSON.parse(input.toString("utf8")), uri =>
53
+ handler.resolve(parseInternalUrl(uri)),
54
+ );
55
+ return JSON.stringify({
56
+ schema_version: 1,
57
+ regression_only: true,
58
+ installed_resolver: true,
59
+ build: BUILD_INFO,
60
+ corpora: PUBLIC_CITATION_SOURCES,
61
+ repetitions: 5,
62
+ request_sha256: createHash("sha256").update(input).digest("hex"),
63
+ results,
64
+ });
65
+ }