@f5-sales-demo/xcsh 21.47.2 → 21.49.2
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 +14 -10
- package/src/commands/login.ts +13 -3
- package/src/extensibility/extensions/bundled/native-lifecycle-control.ts +40 -5
- package/src/extensibility/extensions/runner.ts +2 -0
- package/src/internal-urls/api-catalog-index.generated.ts +26396 -26396
- package/src/internal-urls/api-catalog-preflight.ts +2 -1
- package/src/internal-urls/api-catalog-qmd-index.generated.ts +4 -4
- package/src/internal-urls/api-spec-index.generated.ts +2 -2
- package/src/internal-urls/build-info.generated.ts +8 -8
- package/src/internal-urls/docs-index.generated.ts +1 -1
- package/src/internal-urls/documentation-assets.generated.ts +3 -0
- package/src/internal-urls/documentation-repository.ts +357 -0
- package/src/internal-urls/documentation-resolve.ts +196 -0
- package/src/internal-urls/documentation-snapshot.ts +934 -0
- package/src/internal-urls/index.ts +3 -0
- package/src/internal-urls/types.ts +13 -3
- package/src/internal-urls/xcsh-protocol.ts +34 -0
- package/src/lifecycle/native-acceptance-driver.ts +10 -4
- package/src/lifecycle/native-acceptance.ts +22 -2
- package/src/prompts/rules/llms-search.md +13 -3
- package/src/prompts/system/system-prompt.md +18 -11
- package/src/qmd-smoke.ts +27 -0
- package/src/session/agent-session.ts +5 -0
- package/src/tools/grep.ts +3 -0
- package/src/tools/read.ts +24 -1
- package/src/utils/image-convert.ts +7 -0
- package/src/utils/svg-convert.ts +25 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@f5-sales-demo/xcsh",
|
|
4
|
-
"version": "21.
|
|
4
|
+
"version": "21.49.2",
|
|
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",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
},
|
|
33
33
|
"scripts": {
|
|
34
34
|
"prebuild": "bun ../../scripts/check-installed-dependencies.ts",
|
|
35
|
-
"build": "bun
|
|
35
|
+
"build": "bun scripts/build-package.ts",
|
|
36
36
|
"precheck": "bun ../../scripts/check-installed-dependencies.ts",
|
|
37
37
|
"check": "biome check . && bun run format-prompts -- --check && bun run audit:tui-readability && bun run check:types",
|
|
38
38
|
"audit:tui-readability": "bun scripts/audit-tui-readability.ts --check",
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"generate-docs-index": "bun scripts/generate-docs-index.ts",
|
|
54
54
|
"generate-api-spec-index": "bun scripts/generate-api-spec-index.ts",
|
|
55
55
|
"generate-api-catalog-qmd-index": "bun scripts/generate-api-catalog-qmd-index.ts",
|
|
56
|
+
"generate-documentation-index": "bun scripts/generate-documentation-index.ts",
|
|
56
57
|
"generate-branding-index": "bun scripts/generate-branding-index.ts",
|
|
57
58
|
"generate-sitecli-index": "bun scripts/generate-sitecli-index.ts",
|
|
58
59
|
"generate-build-info": "bun scripts/generate-build-info.ts",
|
|
@@ -66,16 +67,16 @@
|
|
|
66
67
|
},
|
|
67
68
|
"dependencies": {
|
|
68
69
|
"@agentclientprotocol/sdk": "1.4.0",
|
|
69
|
-
"@f5-sales-demo/pi-agent-core": "21.
|
|
70
|
-
"@f5-sales-demo/pi-ai": "21.
|
|
71
|
-
"@f5-sales-demo/pi-natives": "21.
|
|
72
|
-
"@f5-sales-demo/pi-resource-management": "21.
|
|
73
|
-
"@f5-sales-demo/pi-tui": "21.
|
|
74
|
-
"@f5-sales-demo/pi-utils": "21.
|
|
75
|
-
"@f5-sales-demo/xcsh-stats": "21.
|
|
70
|
+
"@f5-sales-demo/pi-agent-core": "21.49.2",
|
|
71
|
+
"@f5-sales-demo/pi-ai": "21.49.2",
|
|
72
|
+
"@f5-sales-demo/pi-natives": "21.49.2",
|
|
73
|
+
"@f5-sales-demo/pi-resource-management": "21.49.2",
|
|
74
|
+
"@f5-sales-demo/pi-tui": "21.49.2",
|
|
75
|
+
"@f5-sales-demo/pi-utils": "21.49.2",
|
|
76
|
+
"@f5-sales-demo/xcsh-stats": "21.49.2",
|
|
76
77
|
"@mozilla/readability": "^0.6",
|
|
78
|
+
"@resvg/resvg-wasm": "2.6.2",
|
|
77
79
|
"@sinclair/typebox": "0.34.52",
|
|
78
|
-
"@tobilu/qmd": "2.8.3",
|
|
79
80
|
"@xterm/headless": "^6.0",
|
|
80
81
|
"ajv": "^8.20",
|
|
81
82
|
"chalk": "6.0.0",
|
|
@@ -86,10 +87,13 @@
|
|
|
86
87
|
"lru-cache": "11.5.2",
|
|
87
88
|
"markit-ai": "0.5.3",
|
|
88
89
|
"puppeteer": "25.10.0",
|
|
90
|
+
"tar-stream": "3.1.7",
|
|
89
91
|
"yaml": "2.9.0"
|
|
90
92
|
},
|
|
91
93
|
"devDependencies": {
|
|
92
94
|
"@types/bun": "1.4.2",
|
|
95
|
+
"@types/tar-stream": "3.1.4",
|
|
96
|
+
"@tobilu/qmd": "2.8.3",
|
|
93
97
|
"@xterm/addon-unicode11": "0.9.0",
|
|
94
98
|
"handlebars": "^4.7"
|
|
95
99
|
},
|
package/src/commands/login.ts
CHANGED
|
@@ -1,17 +1,27 @@
|
|
|
1
|
-
import { Command, Flags } from "@f5-sales-demo/pi-utils/cli";
|
|
1
|
+
import { Args, Command, Flags } from "@f5-sales-demo/pi-utils/cli";
|
|
2
2
|
import { runOpenAIDeviceAuthLogin } from "../cli/openai-device-auth";
|
|
3
3
|
|
|
4
4
|
/** Authenticate ChatGPT through a device-code flow suitable for SSH and headless terminals. */
|
|
5
5
|
export default class Login extends Command {
|
|
6
6
|
static description = "Authenticate ChatGPT using a device code";
|
|
7
|
+
static args = {
|
|
8
|
+
provider: Args.string({
|
|
9
|
+
description: "Provider to authenticate (openai)",
|
|
10
|
+
required: true,
|
|
11
|
+
options: ["openai"],
|
|
12
|
+
}),
|
|
13
|
+
};
|
|
7
14
|
static flags = {
|
|
8
15
|
"device-auth": Flags.boolean({ description: "Use ChatGPT device-code authentication", default: false }),
|
|
9
16
|
};
|
|
10
17
|
|
|
11
18
|
async run(): Promise<void> {
|
|
12
|
-
const { flags } = await this.parse(Login);
|
|
19
|
+
const { args, flags } = await this.parse(Login);
|
|
20
|
+
if (args.provider !== "openai") {
|
|
21
|
+
throw new Error("Device-code authentication is available only for the openai provider.");
|
|
22
|
+
}
|
|
13
23
|
if (!flags["device-auth"]) {
|
|
14
|
-
throw new Error("Use xcsh login --device-auth to authenticate ChatGPT with a device code.");
|
|
24
|
+
throw new Error("Use xcsh login openai --device-auth to authenticate ChatGPT with a device code.");
|
|
15
25
|
}
|
|
16
26
|
await runOpenAIDeviceAuthLogin();
|
|
17
27
|
}
|
|
@@ -1,10 +1,27 @@
|
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
2
|
+
import * as path from "node:path";
|
|
1
3
|
import { postmortem } from "@f5-sales-demo/pi-utils";
|
|
2
4
|
import type { ExtensionAPI, ExtensionContext } from "@f5-sales-demo/xcsh";
|
|
3
5
|
|
|
4
6
|
export const NATIVE_LIFECYCLE_CONTROL_FLAG = "--native-lifecycle-control";
|
|
5
7
|
export const NATIVE_LIFECYCLE_CONTINUATION_TITLE = "Native lifecycle continuation";
|
|
8
|
+
export const NATIVE_LIFECYCLE_CONTROL_VALUES = ["await_user_v1", "local_operation_failure_v1"] as const;
|
|
6
9
|
|
|
7
|
-
type NativeLifecycleControl =
|
|
10
|
+
type NativeLifecycleControl = (typeof NATIVE_LIFECYCLE_CONTROL_VALUES)[number];
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Fatal only for the explicit local-operation acceptance control. Extension
|
|
14
|
+
* errors are normally isolated; the runner recognizes this type so the actual
|
|
15
|
+
* failed operation settles the ordinary AgentSession turn as failed.
|
|
16
|
+
*/
|
|
17
|
+
export class NativeLifecycleLocalOperationError extends Error {
|
|
18
|
+
readonly code = "ENOENT";
|
|
19
|
+
|
|
20
|
+
constructor(cause: Error) {
|
|
21
|
+
super("Native lifecycle owned local read failed with ENOENT", { cause });
|
|
22
|
+
this.name = "NativeLifecycleLocalOperationError";
|
|
23
|
+
}
|
|
24
|
+
}
|
|
8
25
|
|
|
9
26
|
let activeManagedCancellation: ((reason: string) => void) | undefined;
|
|
10
27
|
|
|
@@ -22,7 +39,23 @@ export function requestNativeLifecycleCancellation(reason: string): boolean {
|
|
|
22
39
|
|
|
23
40
|
function configuredControl(pi: ExtensionAPI): NativeLifecycleControl | undefined {
|
|
24
41
|
const value = pi.getFlag(NATIVE_LIFECYCLE_CONTROL_FLAG);
|
|
25
|
-
|
|
42
|
+
// Preserve the version-2 spelling for already published acceptance callers.
|
|
43
|
+
if (value === "await-user") return "await_user_v1";
|
|
44
|
+
return NATIVE_LIFECYCLE_CONTROL_VALUES.find(control => control === value);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function failOwnedLocalOperation(cwd: string): Promise<never> {
|
|
48
|
+
const ownedDirectory = await fs.mkdtemp(path.join(cwd, ".xcsh-native-lifecycle-operation-"));
|
|
49
|
+
await fs.chmod(ownedDirectory, 0o700);
|
|
50
|
+
try {
|
|
51
|
+
await fs.readFile(path.join(ownedDirectory, "intentionally-missing"));
|
|
52
|
+
throw new Error("Native lifecycle missing-file read unexpectedly succeeded");
|
|
53
|
+
} catch (error) {
|
|
54
|
+
if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") throw error;
|
|
55
|
+
throw new NativeLifecycleLocalOperationError(error);
|
|
56
|
+
} finally {
|
|
57
|
+
await fs.rm(ownedDirectory, { recursive: true, force: true });
|
|
58
|
+
}
|
|
26
59
|
}
|
|
27
60
|
|
|
28
61
|
/**
|
|
@@ -37,7 +70,7 @@ function configuredControl(pi: ExtensionAPI): NativeLifecycleControl | undefined
|
|
|
37
70
|
export default function nativeLifecycleControl(pi: ExtensionAPI): void {
|
|
38
71
|
pi.registerFlag(NATIVE_LIFECYCLE_CONTROL_FLAG, {
|
|
39
72
|
type: "string",
|
|
40
|
-
description:
|
|
73
|
+
description: `Acceptance-only native lifecycle control (supported: ${NATIVE_LIFECYCLE_CONTROL_VALUES.join(", ")})`,
|
|
41
74
|
});
|
|
42
75
|
|
|
43
76
|
let activeController: AbortController | undefined;
|
|
@@ -50,10 +83,12 @@ export default function nativeLifecycleControl(pi: ExtensionAPI): void {
|
|
|
50
83
|
};
|
|
51
84
|
|
|
52
85
|
pi.on("before_agent_start", async (_event, ctx) => {
|
|
53
|
-
|
|
86
|
+
const control = configuredControl(pi);
|
|
87
|
+
if (!control) return;
|
|
88
|
+
if (control === "local_operation_failure_v1") return failOwnedLocalOperation(ctx.cwd);
|
|
54
89
|
if (!ctx.hasUI) {
|
|
55
90
|
ctx.abort();
|
|
56
|
-
throw new Error("--native-lifecycle-control
|
|
91
|
+
throw new Error("--native-lifecycle-control await_user_v1 requires interactive mode");
|
|
57
92
|
}
|
|
58
93
|
|
|
59
94
|
const controller = new AbortController();
|
|
@@ -11,6 +11,7 @@ import type { IntegrationHandle } from "../../integrations/types";
|
|
|
11
11
|
import { type Theme, theme } from "../../modes/theme/theme";
|
|
12
12
|
import { personProfileService } from "../../person-profile/service";
|
|
13
13
|
import type { SessionManager } from "../../session/session-manager";
|
|
14
|
+
import { NativeLifecycleLocalOperationError } from "./bundled/native-lifecycle-control";
|
|
14
15
|
import type {
|
|
15
16
|
BeforeAgentStartEvent,
|
|
16
17
|
BeforeAgentStartEventResult,
|
|
@@ -599,6 +600,7 @@ export class ExtensionRunner {
|
|
|
599
600
|
result = handlerResult as SessionCompactingResult;
|
|
600
601
|
}
|
|
601
602
|
} catch (err) {
|
|
603
|
+
if (err instanceof NativeLifecycleLocalOperationError) throw err;
|
|
602
604
|
const message = err instanceof Error ? err.message : String(err);
|
|
603
605
|
const stack = err instanceof Error ? err.stack : undefined;
|
|
604
606
|
this.emitError({
|