@f5-sales-demo/xcsh 20.13.2 → 20.14.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/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@f5-sales-demo/xcsh",
|
|
4
|
-
"version": "20.
|
|
4
|
+
"version": "20.14.0",
|
|
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",
|
|
@@ -61,13 +61,13 @@
|
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
63
|
"@agentclientprotocol/sdk": "1.3.0",
|
|
64
|
-
"@f5-sales-demo/pi-agent-core": "20.
|
|
65
|
-
"@f5-sales-demo/pi-ai": "20.
|
|
66
|
-
"@f5-sales-demo/pi-natives": "20.
|
|
67
|
-
"@f5-sales-demo/pi-resource-management": "20.
|
|
68
|
-
"@f5-sales-demo/pi-tui": "20.
|
|
69
|
-
"@f5-sales-demo/pi-utils": "20.
|
|
70
|
-
"@f5-sales-demo/xcsh-stats": "20.
|
|
64
|
+
"@f5-sales-demo/pi-agent-core": "20.14.0",
|
|
65
|
+
"@f5-sales-demo/pi-ai": "20.14.0",
|
|
66
|
+
"@f5-sales-demo/pi-natives": "20.14.0",
|
|
67
|
+
"@f5-sales-demo/pi-resource-management": "20.14.0",
|
|
68
|
+
"@f5-sales-demo/pi-tui": "20.14.0",
|
|
69
|
+
"@f5-sales-demo/pi-utils": "20.14.0",
|
|
70
|
+
"@f5-sales-demo/xcsh-stats": "20.14.0",
|
|
71
71
|
"@mozilla/readability": "^0.6",
|
|
72
72
|
"@sinclair/typebox": "^0.34",
|
|
73
73
|
"@xterm/headless": "^6.0",
|
|
@@ -17,17 +17,17 @@ export interface BuildInfo {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export const BUILD_INFO: BuildInfo = {
|
|
20
|
-
"version": "20.
|
|
21
|
-
"commit": "
|
|
22
|
-
"shortCommit": "
|
|
20
|
+
"version": "20.14.0",
|
|
21
|
+
"commit": "97c02a788b722cbc3aec14d92b37a4c721454687",
|
|
22
|
+
"shortCommit": "97c02a7",
|
|
23
23
|
"branch": "main",
|
|
24
|
-
"tag": "v20.
|
|
25
|
-
"commitDate": "2026-08-
|
|
26
|
-
"buildDate": "2026-08-
|
|
24
|
+
"tag": "v20.14.0",
|
|
25
|
+
"commitDate": "2026-08-11T21:58:20Z",
|
|
26
|
+
"buildDate": "2026-08-12T08:05:53.700Z",
|
|
27
27
|
"dirty": true,
|
|
28
28
|
"prNumber": "",
|
|
29
29
|
"repoUrl": "https://github.com/f5-sales-demo/xcsh",
|
|
30
30
|
"repoSlug": "f5-sales-demo/xcsh",
|
|
31
|
-
"commitUrl": "https://github.com/f5-sales-demo/xcsh/commit/
|
|
32
|
-
"releaseUrl": "https://github.com/f5-sales-demo/xcsh/releases/tag/v20.
|
|
31
|
+
"commitUrl": "https://github.com/f5-sales-demo/xcsh/commit/97c02a788b722cbc3aec14d92b37a4c721454687",
|
|
32
|
+
"releaseUrl": "https://github.com/f5-sales-demo/xcsh/releases/tag/v20.14.0"
|
|
33
33
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Auto-generated by scripts/generate-docs-index.ts - DO NOT EDIT
|
|
2
2
|
|
|
3
|
-
export const EMBEDDED_DOC_FILENAMES: readonly string[] = ["SYSTEM_PROMPT_GUIDE.md","ar/configuration/blob-artifact-architecture.md","ar/configuration/config-usage.md","ar/configuration/environment-variables.md","ar/configuration/fs-scan-cache-architecture.md","ar/configuration/hooks.md","ar/configuration/porting-from-pi-mono.md","ar/configuration/rpc.md","ar/configuration/sdk.md","ar/configuration/secrets.md","ar/extensions/extension-loading.md","ar/extensions/extensions.md","ar/extensions/gemini-manifest-extensions.md","ar/extensions/marketplace.md","ar/extensions/plugin-manager-installer-plumbing.md","ar/extensions/rulebook-matching-pipeline.md","ar/extensions/skills.md","ar/index.md","ar/mcp/mcp-config.md","ar/mcp/mcp-protocol-transports.md","ar/mcp/mcp-runtime-lifecycle.md","ar/mcp/mcp-server-tool-authoring.md","ar/natives/natives-addon-loader-runtime.md","ar/natives/natives-architecture.md","ar/natives/natives-binding-contract.md","ar/natives/natives-build-release-debugging.md","ar/natives/natives-media-system-utils.md","ar/natives/natives-rust-task-cancellation.md","ar/natives/natives-shell-pty-process.md","ar/natives/natives-text-search-pipeline.md","ar/natives/porting-to-natives.md","ar/providers/models.md","ar/providers/provider-streaming-internals.md","ar/providers/python-repl.md","ar/runtime-tools/bash-tool-runtime.md","ar/runtime-tools/context-command.md","ar/runtime-tools/custom-tools.md","ar/runtime-tools/notebook-tool-runtime.md","ar/runtime-tools/resolve-tool-runtime.md","ar/runtime-tools/slash-command-internals.md","ar/runtime-tools/task-agent-discovery.md","ar/sessions/compaction.md","ar/sessions/handoff-generation-pipeline.md","ar/sessions/memory.md","ar/sessions/non-compaction-retry-policy.md","ar/sessions/session-operations-export-share-fork-resume.md","ar/sessions/session-switching-and-recent-listing.md","ar/sessions/session-tree-plan.md","ar/sessions/session.md","ar/sessions/ttsr-injection-lifecycle.md","ar/tui/theme.md","ar/tui/tree.md","ar/tui/tui-runtime-internals.md","ar/tui/tui.md","de/configuration/blob-artifact-architecture.md","de/configuration/config-usage.md","de/configuration/environment-variables.md","de/configuration/fs-scan-cache-architecture.md","de/configuration/hooks.md","de/configuration/porting-from-pi-mono.md","de/configuration/rpc.md","de/configuration/sdk.md","de/configuration/secrets.md","de/extensions/extension-loading.md","de/extensions/extensions.md","de/extensions/gemini-manifest-extensions.md","de/extensions/marketplace.md","de/extensions/plugin-manager-installer-plumbing.md","de/extensions/rulebook-matching-pipeline.md","de/extensions/skills.md","de/index.md","de/mcp/mcp-config.md","de/mcp/mcp-protocol-transports.md","de/mcp/mcp-runtime-lifecycle.md","de/mcp/mcp-server-tool-authoring.md","de/natives/natives-addon-loader-runtime.md","de/natives/natives-architecture.md","de/natives/natives-binding-contract.md","de/natives/natives-build-release-debugging.md","de/natives/natives-media-system-utils.md","de/natives/natives-rust-task-cancellation.md","de/natives/natives-shell-pty-process.md","de/natives/natives-text-search-pipeline.md","de/natives/porting-to-natives.md","de/providers/models.md","de/providers/provider-streaming-internals.md","de/providers/python-repl.md","de/runtime-tools/bash-tool-runtime.md","de/runtime-tools/context-command.md","de/runtime-tools/custom-tools.md","de/runtime-tools/notebook-tool-runtime.md","de/runtime-tools/resolve-tool-runtime.md","de/runtime-tools/slash-command-internals.md","de/runtime-tools/task-agent-discovery.md","de/sessions/compaction.md","de/sessions/handoff-generation-pipeline.md","de/sessions/memory.md","de/sessions/non-compaction-retry-policy.md","de/sessions/session-operations-export-share-fork-resume.md","de/sessions/session-switching-and-recent-listing.md","de/sessions/session-tree-plan.md","de/sessions/session.md","de/sessions/ttsr-injection-lifecycle.md","de/tui/theme.md","de/tui/tree.md","de/tui/tui-runtime-internals.md","de/tui/tui.md","en/configuration/blob-artifact-architecture.md","en/configuration/config-usage.md","en/configuration/environment-variables.md","en/configuration/fs-scan-cache-architecture.md","en/configuration/hooks.md","en/configuration/porting-from-pi-mono.md","en/configuration/rpc.md","en/configuration/sdk.md","en/configuration/secrets.md","en/extensions/extension-loading.md","en/extensions/extensions.md","en/extensions/gemini-manifest-extensions.md","en/extensions/marketplace.md","en/extensions/plugin-manager-installer-plumbing.md","en/extensions/rulebook-matching-pipeline.md","en/extensions/skills.md","en/index.md","en/mcp/mcp-config.md","en/mcp/mcp-protocol-transports.md","en/mcp/mcp-runtime-lifecycle.md","en/mcp/mcp-server-tool-authoring.md","en/natives/natives-addon-loader-runtime.md","en/natives/natives-architecture.md","en/natives/natives-binding-contract.md","en/natives/natives-build-release-debugging.md","en/natives/natives-media-system-utils.md","en/natives/natives-rust-task-cancellation.md","en/natives/natives-shell-pty-process.md","en/natives/natives-text-search-pipeline.md","en/natives/porting-to-natives.md","en/providers/models.md","en/providers/provider-streaming-internals.md","en/providers/python-repl.md","en/runtime-tools/bash-tool-runtime.md","en/runtime-tools/context-command.md","en/runtime-tools/custom-tools.md","en/runtime-tools/notebook-tool-runtime.md","en/runtime-tools/resolve-tool-runtime.md","en/runtime-tools/slash-command-internals.md","en/runtime-tools/task-agent-discovery.md","en/sessions/compaction.md","en/sessions/handoff-generation-pipeline.md","en/sessions/memory.md","en/sessions/non-compaction-retry-policy.md","en/sessions/session-operations-export-share-fork-resume.md","en/sessions/session-switching-and-recent-listing.md","en/sessions/session-tree-plan.md","en/sessions/session.md","en/sessions/ttsr-injection-lifecycle.md","en/tui/theme.md","en/tui/tree.md","en/tui/tui-runtime-internals.md","en/tui/tui.md","es/configuration/blob-artifact-architecture.md","es/configuration/config-usage.md","es/configuration/environment-variables.md","es/configuration/fs-scan-cache-architecture.md","es/configuration/hooks.md","es/configuration/porting-from-pi-mono.md","es/configuration/rpc.md","es/configuration/sdk.md","es/configuration/secrets.md","es/extensions/extension-loading.md","es/extensions/extensions.md","es/extensions/gemini-manifest-extensions.md","es/extensions/marketplace.md","es/extensions/plugin-manager-installer-plumbing.md","es/extensions/rulebook-matching-pipeline.md","es/extensions/skills.md","es/index.md","es/mcp/mcp-config.md","es/mcp/mcp-protocol-transports.md","es/mcp/mcp-runtime-lifecycle.md","es/mcp/mcp-server-tool-authoring.md","es/natives/natives-addon-loader-runtime.md","es/natives/natives-architecture.md","es/natives/natives-binding-contract.md","es/natives/natives-build-release-debugging.md","es/natives/natives-media-system-utils.md","es/natives/natives-rust-task-cancellation.md","es/natives/natives-shell-pty-process.md","es/natives/natives-text-search-pipeline.md","es/natives/porting-to-natives.md","es/providers/models.md","es/providers/provider-streaming-internals.md","es/providers/python-repl.md","es/runtime-tools/bash-tool-runtime.md","es/runtime-tools/context-command.md","es/runtime-tools/custom-tools.md","es/runtime-tools/notebook-tool-runtime.md","es/runtime-tools/resolve-tool-runtime.md","es/runtime-tools/slash-command-internals.md","es/runtime-tools/task-agent-discovery.md","es/sessions/compaction.md","es/sessions/handoff-generation-pipeline.md","es/sessions/memory.md","es/sessions/non-compaction-retry-policy.md","es/sessions/session-operations-export-share-fork-resume.md","es/sessions/session-switching-and-recent-listing.md","es/sessions/session-tree-plan.md","es/sessions/session.md","es/sessions/ttsr-injection-lifecycle.md","es/tui/theme.md","es/tui/tree.md","es/tui/tui-runtime-internals.md","es/tui/tui.md","fr/configuration/blob-artifact-architecture.md","fr/configuration/config-usage.md","fr/configuration/environment-variables.md","fr/configuration/fs-scan-cache-architecture.md","fr/configuration/hooks.md","fr/configuration/porting-from-pi-mono.md","fr/configuration/rpc.md","fr/configuration/sdk.md","fr/configuration/secrets.md","fr/extensions/extension-loading.md","fr/extensions/extensions.md","fr/extensions/gemini-manifest-extensions.md","fr/extensions/marketplace.md","fr/extensions/plugin-manager-installer-plumbing.md","fr/extensions/rulebook-matching-pipeline.md","fr/extensions/skills.md","fr/index.md","fr/mcp/mcp-config.md","fr/mcp/mcp-protocol-transports.md","fr/mcp/mcp-runtime-lifecycle.md","fr/mcp/mcp-server-tool-authoring.md","fr/natives/natives-addon-loader-runtime.md","fr/natives/natives-architecture.md","fr/natives/natives-binding-contract.md","fr/natives/natives-build-release-debugging.md","fr/natives/natives-media-system-utils.md","fr/natives/natives-rust-task-cancellation.md","fr/natives/natives-shell-pty-process.md","fr/natives/natives-text-search-pipeline.md","fr/natives/porting-to-natives.md","fr/providers/models.md","fr/providers/provider-streaming-internals.md","fr/providers/python-repl.md","fr/runtime-tools/bash-tool-runtime.md","fr/runtime-tools/context-command.md","fr/runtime-tools/custom-tools.md","fr/runtime-tools/notebook-tool-runtime.md","fr/runtime-tools/resolve-tool-runtime.md","fr/runtime-tools/slash-command-internals.md","fr/runtime-tools/task-agent-discovery.md","fr/sessions/compaction.md","fr/sessions/handoff-generation-pipeline.md","fr/sessions/memory.md","fr/sessions/non-compaction-retry-policy.md","fr/sessions/session-operations-export-share-fork-resume.md","fr/sessions/session-switching-and-recent-listing.md","fr/sessions/session-tree-plan.md","fr/sessions/session.md","fr/sessions/ttsr-injection-lifecycle.md","fr/tui/theme.md","fr/tui/tree.md","fr/tui/tui-runtime-internals.md","fr/tui/tui.md","hi/configuration/blob-artifact-architecture.md","hi/configuration/config-usage.md","hi/configuration/environment-variables.md","hi/configuration/fs-scan-cache-architecture.md","hi/configuration/hooks.md","hi/configuration/porting-from-pi-mono.md","hi/configuration/rpc.md","hi/configuration/sdk.md","hi/configuration/secrets.md","hi/extensions/extension-loading.md","hi/extensions/extensions.md","hi/extensions/gemini-manifest-extensions.md","hi/extensions/marketplace.md","hi/extensions/plugin-manager-installer-plumbing.md","hi/extensions/rulebook-matching-pipeline.md","hi/extensions/skills.md","hi/index.md","hi/mcp/mcp-config.md","hi/mcp/mcp-protocol-transports.md","hi/mcp/mcp-runtime-lifecycle.md","hi/mcp/mcp-server-tool-authoring.md","hi/natives/natives-addon-loader-runtime.md","hi/natives/natives-architecture.md","hi/natives/natives-binding-contract.md","hi/natives/natives-build-release-debugging.md","hi/natives/natives-media-system-utils.md","hi/natives/natives-rust-task-cancellation.md","hi/natives/natives-shell-pty-process.md","hi/natives/natives-text-search-pipeline.md","hi/natives/porting-to-natives.md","hi/providers/models.md","hi/providers/provider-streaming-internals.md","hi/providers/python-repl.md","hi/runtime-tools/bash-tool-runtime.md","hi/runtime-tools/context-command.md","hi/runtime-tools/custom-tools.md","hi/runtime-tools/notebook-tool-runtime.md","hi/runtime-tools/resolve-tool-runtime.md","hi/runtime-tools/slash-command-internals.md","hi/runtime-tools/task-agent-discovery.md","hi/sessions/compaction.md","hi/sessions/handoff-generation-pipeline.md","hi/sessions/memory.md","hi/sessions/non-compaction-retry-policy.md","hi/sessions/session-operations-export-share-fork-resume.md","hi/sessions/session-switching-and-recent-listing.md","hi/sessions/session-tree-plan.md","hi/sessions/session.md","hi/sessions/ttsr-injection-lifecycle.md","hi/tui/theme.md","hi/tui/tree.md","hi/tui/tui-runtime-internals.md","hi/tui/tui.md","it/configuration/blob-artifact-architecture.md","it/configuration/config-usage.md","it/configuration/environment-variables.md","it/configuration/fs-scan-cache-architecture.md","it/configuration/hooks.md","it/configuration/porting-from-pi-mono.md","it/configuration/rpc.md","it/configuration/sdk.md","it/configuration/secrets.md","it/extensions/extension-loading.md","it/extensions/extensions.md","it/extensions/gemini-manifest-extensions.md","it/extensions/marketplace.md","it/extensions/plugin-manager-installer-plumbing.md","it/extensions/rulebook-matching-pipeline.md","it/extensions/skills.md","it/index.md","it/mcp/mcp-config.md","it/mcp/mcp-protocol-transports.md","it/mcp/mcp-runtime-lifecycle.md","it/mcp/mcp-server-tool-authoring.md","it/natives/natives-addon-loader-runtime.md","it/natives/natives-architecture.md","it/natives/natives-binding-contract.md","it/natives/natives-build-release-debugging.md","it/natives/natives-media-system-utils.md","it/natives/natives-rust-task-cancellation.md","it/natives/natives-shell-pty-process.md","it/natives/natives-text-search-pipeline.md","it/natives/porting-to-natives.md","it/providers/models.md","it/providers/provider-streaming-internals.md","it/providers/python-repl.md","it/runtime-tools/bash-tool-runtime.md","it/runtime-tools/context-command.md","it/runtime-tools/custom-tools.md","it/runtime-tools/notebook-tool-runtime.md","it/runtime-tools/resolve-tool-runtime.md","it/runtime-tools/slash-command-internals.md","it/runtime-tools/task-agent-discovery.md","it/sessions/compaction.md","it/sessions/handoff-generation-pipeline.md","it/sessions/memory.md","it/sessions/non-compaction-retry-policy.md","it/sessions/session-operations-export-share-fork-resume.md","it/sessions/session-switching-and-recent-listing.md","it/sessions/session-tree-plan.md","it/sessions/session.md","it/sessions/ttsr-injection-lifecycle.md","it/tui/theme.md","it/tui/tree.md","it/tui/tui-runtime-internals.md","it/tui/tui.md","ja/configuration/blob-artifact-architecture.md","ja/configuration/config-usage.md","ja/configuration/environment-variables.md","ja/configuration/fs-scan-cache-architecture.md","ja/configuration/hooks.md","ja/configuration/porting-from-pi-mono.md","ja/configuration/rpc.md","ja/configuration/sdk.md","ja/configuration/secrets.md","ja/extensions/extension-loading.md","ja/extensions/extensions.md","ja/extensions/gemini-manifest-extensions.md","ja/extensions/marketplace.md","ja/extensions/plugin-manager-installer-plumbing.md","ja/extensions/rulebook-matching-pipeline.md","ja/extensions/skills.md","ja/index.md","ja/mcp/mcp-config.md","ja/mcp/mcp-protocol-transports.md","ja/mcp/mcp-runtime-lifecycle.md","ja/mcp/mcp-server-tool-authoring.md","ja/natives/natives-addon-loader-runtime.md","ja/natives/natives-architecture.md","ja/natives/natives-binding-contract.md","ja/natives/natives-build-release-debugging.md","ja/natives/natives-media-system-utils.md","ja/natives/natives-rust-task-cancellation.md","ja/natives/natives-shell-pty-process.md","ja/natives/natives-text-search-pipeline.md","ja/natives/porting-to-natives.md","ja/providers/models.md","ja/providers/provider-streaming-internals.md","ja/providers/python-repl.md","ja/runtime-tools/bash-tool-runtime.md","ja/runtime-tools/context-command.md","ja/runtime-tools/custom-tools.md","ja/runtime-tools/notebook-tool-runtime.md","ja/runtime-tools/resolve-tool-runtime.md","ja/runtime-tools/slash-command-internals.md","ja/runtime-tools/task-agent-discovery.md","ja/sessions/compaction.md","ja/sessions/handoff-generation-pipeline.md","ja/sessions/memory.md","ja/sessions/non-compaction-retry-policy.md","ja/sessions/session-operations-export-share-fork-resume.md","ja/sessions/session-switching-and-recent-listing.md","ja/sessions/session-tree-plan.md","ja/sessions/session.md","ja/sessions/ttsr-injection-lifecycle.md","ja/tui/theme.md","ja/tui/tree.md","ja/tui/tui-runtime-internals.md","ja/tui/tui.md","ko/configuration/blob-artifact-architecture.md","ko/configuration/config-usage.md","ko/configuration/environment-variables.md","ko/configuration/fs-scan-cache-architecture.md","ko/configuration/hooks.md","ko/configuration/porting-from-pi-mono.md","ko/configuration/rpc.md","ko/configuration/sdk.md","ko/configuration/secrets.md","ko/extensions/extension-loading.md","ko/extensions/extensions.md","ko/extensions/gemini-manifest-extensions.md","ko/extensions/marketplace.md","ko/extensions/plugin-manager-installer-plumbing.md","ko/extensions/rulebook-matching-pipeline.md","ko/extensions/skills.md","ko/index.md","ko/mcp/mcp-config.md","ko/mcp/mcp-protocol-transports.md","ko/mcp/mcp-runtime-lifecycle.md","ko/mcp/mcp-server-tool-authoring.md","ko/natives/natives-addon-loader-runtime.md","ko/natives/natives-architecture.md","ko/natives/natives-binding-contract.md","ko/natives/natives-build-release-debugging.md","ko/natives/natives-media-system-utils.md","ko/natives/natives-rust-task-cancellation.md","ko/natives/natives-shell-pty-process.md","ko/natives/natives-text-search-pipeline.md","ko/natives/porting-to-natives.md","ko/providers/models.md","ko/providers/provider-streaming-internals.md","ko/providers/python-repl.md","ko/runtime-tools/bash-tool-runtime.md","ko/runtime-tools/context-command.md","ko/runtime-tools/custom-tools.md","ko/runtime-tools/notebook-tool-runtime.md","ko/runtime-tools/resolve-tool-runtime.md","ko/runtime-tools/slash-command-internals.md","ko/runtime-tools/task-agent-discovery.md","ko/sessions/compaction.md","ko/sessions/handoff-generation-pipeline.md","ko/sessions/memory.md","ko/sessions/non-compaction-retry-policy.md","ko/sessions/session-operations-export-share-fork-resume.md","ko/sessions/session-switching-and-recent-listing.md","ko/sessions/session-tree-plan.md","ko/sessions/session.md","ko/sessions/ttsr-injection-lifecycle.md","ko/tui/theme.md","ko/tui/tree.md","ko/tui/tui-runtime-internals.md","ko/tui/tui.md","plans/provider-agnostic-dynamic-model-routing.md","pt-br/configuration/blob-artifact-architecture.md","pt-br/configuration/config-usage.md","pt-br/configuration/environment-variables.md","pt-br/configuration/fs-scan-cache-architecture.md","pt-br/configuration/hooks.md","pt-br/configuration/porting-from-pi-mono.md","pt-br/configuration/rpc.md","pt-br/configuration/sdk.md","pt-br/configuration/secrets.md","pt-br/extensions/extension-loading.md","pt-br/extensions/extensions.md","pt-br/extensions/gemini-manifest-extensions.md","pt-br/extensions/marketplace.md","pt-br/extensions/plugin-manager-installer-plumbing.md","pt-br/extensions/rulebook-matching-pipeline.md","pt-br/extensions/skills.md","pt-br/index.md","pt-br/mcp/mcp-config.md","pt-br/mcp/mcp-protocol-transports.md","pt-br/mcp/mcp-runtime-lifecycle.md","pt-br/mcp/mcp-server-tool-authoring.md","pt-br/natives/natives-addon-loader-runtime.md","pt-br/natives/natives-architecture.md","pt-br/natives/natives-binding-contract.md","pt-br/natives/natives-build-release-debugging.md","pt-br/natives/natives-media-system-utils.md","pt-br/natives/natives-rust-task-cancellation.md","pt-br/natives/natives-shell-pty-process.md","pt-br/natives/natives-text-search-pipeline.md","pt-br/natives/porting-to-natives.md","pt-br/providers/models.md","pt-br/providers/provider-streaming-internals.md","pt-br/providers/python-repl.md","pt-br/runtime-tools/bash-tool-runtime.md","pt-br/runtime-tools/context-command.md","pt-br/runtime-tools/custom-tools.md","pt-br/runtime-tools/notebook-tool-runtime.md","pt-br/runtime-tools/resolve-tool-runtime.md","pt-br/runtime-tools/slash-command-internals.md","pt-br/runtime-tools/task-agent-discovery.md","pt-br/sessions/compaction.md","pt-br/sessions/handoff-generation-pipeline.md","pt-br/sessions/memory.md","pt-br/sessions/non-compaction-retry-policy.md","pt-br/sessions/session-operations-export-share-fork-resume.md","pt-br/sessions/session-switching-and-recent-listing.md","pt-br/sessions/session-tree-plan.md","pt-br/sessions/session.md","pt-br/sessions/ttsr-injection-lifecycle.md","pt-br/tui/theme.md","pt-br/tui/tree.md","pt-br/tui/tui-runtime-internals.md","pt-br/tui/tui.md","th/configuration/blob-artifact-architecture.md","th/configuration/config-usage.md","th/configuration/environment-variables.md","th/configuration/fs-scan-cache-architecture.md","th/configuration/hooks.md","th/configuration/porting-from-pi-mono.md","th/configuration/rpc.md","th/configuration/sdk.md","th/configuration/secrets.md","th/extensions/extension-loading.md","th/extensions/extensions.md","th/extensions/gemini-manifest-extensions.md","th/extensions/marketplace.md","th/extensions/plugin-manager-installer-plumbing.md","th/extensions/rulebook-matching-pipeline.md","th/extensions/skills.md","th/index.md","th/mcp/mcp-config.md","th/mcp/mcp-protocol-transports.md","th/mcp/mcp-runtime-lifecycle.md","th/mcp/mcp-server-tool-authoring.md","th/natives/natives-addon-loader-runtime.md","th/natives/natives-architecture.md","th/natives/natives-binding-contract.md","th/natives/natives-build-release-debugging.md","th/natives/natives-media-system-utils.md","th/natives/natives-rust-task-cancellation.md","th/natives/natives-shell-pty-process.md","th/natives/natives-text-search-pipeline.md","th/natives/porting-to-natives.md","th/providers/models.md","th/providers/provider-streaming-internals.md","th/providers/python-repl.md","th/runtime-tools/bash-tool-runtime.md","th/runtime-tools/context-command.md","th/runtime-tools/custom-tools.md","th/runtime-tools/notebook-tool-runtime.md","th/runtime-tools/resolve-tool-runtime.md","th/runtime-tools/slash-command-internals.md","th/runtime-tools/task-agent-discovery.md","th/sessions/compaction.md","th/sessions/handoff-generation-pipeline.md","th/sessions/memory.md","th/sessions/non-compaction-retry-policy.md","th/sessions/session-operations-export-share-fork-resume.md","th/sessions/session-switching-and-recent-listing.md","th/sessions/session-tree-plan.md","th/sessions/session.md","th/sessions/ttsr-injection-lifecycle.md","th/tui/theme.md","th/tui/tree.md","th/tui/tui-runtime-internals.md","th/tui/tui.md","zh-cn/configuration/blob-artifact-architecture.md","zh-cn/configuration/config-usage.md","zh-cn/configuration/environment-variables.md","zh-cn/configuration/fs-scan-cache-architecture.md","zh-cn/configuration/hooks.md","zh-cn/configuration/porting-from-pi-mono.md","zh-cn/configuration/rpc.md","zh-cn/configuration/sdk.md","zh-cn/configuration/secrets.md","zh-cn/extensions/extension-loading.md","zh-cn/extensions/extensions.md","zh-cn/extensions/gemini-manifest-extensions.md","zh-cn/extensions/marketplace.md","zh-cn/extensions/plugin-manager-installer-plumbing.md","zh-cn/extensions/rulebook-matching-pipeline.md","zh-cn/extensions/skills.md","zh-cn/index.md","zh-cn/mcp/mcp-config.md","zh-cn/mcp/mcp-protocol-transports.md","zh-cn/mcp/mcp-runtime-lifecycle.md","zh-cn/mcp/mcp-server-tool-authoring.md","zh-cn/natives/natives-addon-loader-runtime.md","zh-cn/natives/natives-architecture.md","zh-cn/natives/natives-binding-contract.md","zh-cn/natives/natives-build-release-debugging.md","zh-cn/natives/natives-media-system-utils.md","zh-cn/natives/natives-rust-task-cancellation.md","zh-cn/natives/natives-shell-pty-process.md","zh-cn/natives/natives-text-search-pipeline.md","zh-cn/natives/porting-to-natives.md","zh-cn/providers/models.md","zh-cn/providers/provider-streaming-internals.md","zh-cn/providers/python-repl.md","zh-cn/runtime-tools/bash-tool-runtime.md","zh-cn/runtime-tools/context-command.md","zh-cn/runtime-tools/custom-tools.md","zh-cn/runtime-tools/notebook-tool-runtime.md","zh-cn/runtime-tools/resolve-tool-runtime.md","zh-cn/runtime-tools/slash-command-internals.md","zh-cn/runtime-tools/task-agent-discovery.md","zh-cn/sessions/compaction.md","zh-cn/sessions/handoff-generation-pipeline.md","zh-cn/sessions/memory.md","zh-cn/sessions/non-compaction-retry-policy.md","zh-cn/sessions/session-operations-export-share-fork-resume.md","zh-cn/sessions/session-switching-and-recent-listing.md","zh-cn/sessions/session-tree-plan.md","zh-cn/sessions/session.md","zh-cn/sessions/ttsr-injection-lifecycle.md","zh-cn/tui/theme.md","zh-cn/tui/tree.md","zh-cn/tui/tui-runtime-internals.md","zh-cn/tui/tui.md","zh-tw/configuration/blob-artifact-architecture.md","zh-tw/configuration/config-usage.md","zh-tw/configuration/environment-variables.md","zh-tw/configuration/fs-scan-cache-architecture.md","zh-tw/configuration/hooks.md","zh-tw/configuration/porting-from-pi-mono.md","zh-tw/configuration/rpc.md","zh-tw/configuration/sdk.md","zh-tw/configuration/secrets.md","zh-tw/extensions/extension-loading.md","zh-tw/extensions/extensions.md","zh-tw/extensions/gemini-manifest-extensions.md","zh-tw/extensions/marketplace.md","zh-tw/extensions/plugin-manager-installer-plumbing.md","zh-tw/extensions/rulebook-matching-pipeline.md","zh-tw/extensions/skills.md","zh-tw/index.md","zh-tw/mcp/mcp-config.md","zh-tw/mcp/mcp-protocol-transports.md","zh-tw/mcp/mcp-runtime-lifecycle.md","zh-tw/mcp/mcp-server-tool-authoring.md","zh-tw/natives/natives-addon-loader-runtime.md","zh-tw/natives/natives-architecture.md","zh-tw/natives/natives-binding-contract.md","zh-tw/natives/natives-build-release-debugging.md","zh-tw/natives/natives-media-system-utils.md","zh-tw/natives/natives-rust-task-cancellation.md","zh-tw/natives/natives-shell-pty-process.md","zh-tw/natives/natives-text-search-pipeline.md","zh-tw/natives/porting-to-natives.md","zh-tw/providers/models.md","zh-tw/providers/provider-streaming-internals.md","zh-tw/providers/python-repl.md","zh-tw/runtime-tools/bash-tool-runtime.md","zh-tw/runtime-tools/context-command.md","zh-tw/runtime-tools/custom-tools.md","zh-tw/runtime-tools/notebook-tool-runtime.md","zh-tw/runtime-tools/resolve-tool-runtime.md","zh-tw/runtime-tools/slash-command-internals.md","zh-tw/runtime-tools/task-agent-discovery.md","zh-tw/sessions/compaction.md","zh-tw/sessions/handoff-generation-pipeline.md","zh-tw/sessions/memory.md","zh-tw/sessions/non-compaction-retry-policy.md","zh-tw/sessions/session-operations-export-share-fork-resume.md","zh-tw/sessions/session-switching-and-recent-listing.md","zh-tw/sessions/session-tree-plan.md","zh-tw/sessions/session.md","zh-tw/sessions/ttsr-injection-lifecycle.md","zh-tw/tui/theme.md","zh-tw/tui/tree.md","zh-tw/tui/tui-runtime-internals.md","zh-tw/tui/tui.md"];
|
|
3
|
+
export const EMBEDDED_DOC_FILENAMES: readonly string[] = ["SYSTEM_PROMPT_GUIDE.md","ar/configuration/blob-artifact-architecture.md","ar/configuration/config-usage.md","ar/configuration/environment-variables.md","ar/configuration/fs-scan-cache-architecture.md","ar/configuration/hooks.md","ar/configuration/porting-from-pi-mono.md","ar/configuration/rpc.md","ar/configuration/sdk.md","ar/configuration/secrets.md","ar/extensions/extension-loading.md","ar/extensions/extensions.md","ar/extensions/gemini-manifest-extensions.md","ar/extensions/marketplace.md","ar/extensions/plugin-manager-installer-plumbing.md","ar/extensions/rulebook-matching-pipeline.md","ar/extensions/skills.md","ar/index.md","ar/mcp/mcp-config.md","ar/mcp/mcp-protocol-transports.md","ar/mcp/mcp-runtime-lifecycle.md","ar/mcp/mcp-server-tool-authoring.md","ar/natives/natives-addon-loader-runtime.md","ar/natives/natives-architecture.md","ar/natives/natives-binding-contract.md","ar/natives/natives-build-release-debugging.md","ar/natives/natives-media-system-utils.md","ar/natives/natives-rust-task-cancellation.md","ar/natives/natives-shell-pty-process.md","ar/natives/natives-text-search-pipeline.md","ar/natives/porting-to-natives.md","ar/providers/models.md","ar/providers/provider-streaming-internals.md","ar/providers/python-repl.md","ar/runtime-tools/bash-tool-runtime.md","ar/runtime-tools/context-command.md","ar/runtime-tools/custom-tools.md","ar/runtime-tools/notebook-tool-runtime.md","ar/runtime-tools/resolve-tool-runtime.md","ar/runtime-tools/slash-command-internals.md","ar/runtime-tools/task-agent-discovery.md","ar/sessions/compaction.md","ar/sessions/handoff-generation-pipeline.md","ar/sessions/memory.md","ar/sessions/non-compaction-retry-policy.md","ar/sessions/session-operations-export-share-fork-resume.md","ar/sessions/session-switching-and-recent-listing.md","ar/sessions/session-tree-plan.md","ar/sessions/session.md","ar/sessions/ttsr-injection-lifecycle.md","ar/tui/theme.md","ar/tui/tree.md","ar/tui/tui-runtime-internals.md","ar/tui/tui.md","de/configuration/blob-artifact-architecture.md","de/configuration/config-usage.md","de/configuration/environment-variables.md","de/configuration/fs-scan-cache-architecture.md","de/configuration/hooks.md","de/configuration/porting-from-pi-mono.md","de/configuration/rpc.md","de/configuration/sdk.md","de/configuration/secrets.md","de/extensions/extension-loading.md","de/extensions/extensions.md","de/extensions/gemini-manifest-extensions.md","de/extensions/marketplace.md","de/extensions/plugin-manager-installer-plumbing.md","de/extensions/rulebook-matching-pipeline.md","de/extensions/skills.md","de/index.md","de/mcp/mcp-config.md","de/mcp/mcp-protocol-transports.md","de/mcp/mcp-runtime-lifecycle.md","de/mcp/mcp-server-tool-authoring.md","de/natives/natives-addon-loader-runtime.md","de/natives/natives-architecture.md","de/natives/natives-binding-contract.md","de/natives/natives-build-release-debugging.md","de/natives/natives-media-system-utils.md","de/natives/natives-rust-task-cancellation.md","de/natives/natives-shell-pty-process.md","de/natives/natives-text-search-pipeline.md","de/natives/porting-to-natives.md","de/providers/models.md","de/providers/provider-streaming-internals.md","de/providers/python-repl.md","de/runtime-tools/bash-tool-runtime.md","de/runtime-tools/context-command.md","de/runtime-tools/custom-tools.md","de/runtime-tools/notebook-tool-runtime.md","de/runtime-tools/resolve-tool-runtime.md","de/runtime-tools/slash-command-internals.md","de/runtime-tools/task-agent-discovery.md","de/sessions/compaction.md","de/sessions/handoff-generation-pipeline.md","de/sessions/memory.md","de/sessions/non-compaction-retry-policy.md","de/sessions/session-operations-export-share-fork-resume.md","de/sessions/session-switching-and-recent-listing.md","de/sessions/session-tree-plan.md","de/sessions/session.md","de/sessions/ttsr-injection-lifecycle.md","de/tui/theme.md","de/tui/tree.md","de/tui/tui-runtime-internals.md","de/tui/tui.md","en/configuration/blob-artifact-architecture.md","en/configuration/config-usage.md","en/configuration/environment-variables.md","en/configuration/fs-scan-cache-architecture.md","en/configuration/hooks.md","en/configuration/porting-from-pi-mono.md","en/configuration/rpc.md","en/configuration/sdk.md","en/configuration/secrets.md","en/container/alpine-deployment.md","en/extensions/extension-loading.md","en/extensions/extensions.md","en/extensions/gemini-manifest-extensions.md","en/extensions/marketplace.md","en/extensions/plugin-manager-installer-plumbing.md","en/extensions/rulebook-matching-pipeline.md","en/extensions/skills.md","en/index.md","en/mcp/mcp-config.md","en/mcp/mcp-protocol-transports.md","en/mcp/mcp-runtime-lifecycle.md","en/mcp/mcp-server-tool-authoring.md","en/natives/natives-addon-loader-runtime.md","en/natives/natives-architecture.md","en/natives/natives-binding-contract.md","en/natives/natives-build-release-debugging.md","en/natives/natives-media-system-utils.md","en/natives/natives-rust-task-cancellation.md","en/natives/natives-shell-pty-process.md","en/natives/natives-text-search-pipeline.md","en/natives/porting-to-natives.md","en/providers/models.md","en/providers/provider-streaming-internals.md","en/providers/python-repl.md","en/runtime-tools/bash-tool-runtime.md","en/runtime-tools/context-command.md","en/runtime-tools/custom-tools.md","en/runtime-tools/notebook-tool-runtime.md","en/runtime-tools/resolve-tool-runtime.md","en/runtime-tools/slash-command-internals.md","en/runtime-tools/task-agent-discovery.md","en/sessions/compaction.md","en/sessions/handoff-generation-pipeline.md","en/sessions/memory.md","en/sessions/non-compaction-retry-policy.md","en/sessions/session-operations-export-share-fork-resume.md","en/sessions/session-switching-and-recent-listing.md","en/sessions/session-tree-plan.md","en/sessions/session.md","en/sessions/ttsr-injection-lifecycle.md","en/tui/theme.md","en/tui/tree.md","en/tui/tui-runtime-internals.md","en/tui/tui.md","es/configuration/blob-artifact-architecture.md","es/configuration/config-usage.md","es/configuration/environment-variables.md","es/configuration/fs-scan-cache-architecture.md","es/configuration/hooks.md","es/configuration/porting-from-pi-mono.md","es/configuration/rpc.md","es/configuration/sdk.md","es/configuration/secrets.md","es/extensions/extension-loading.md","es/extensions/extensions.md","es/extensions/gemini-manifest-extensions.md","es/extensions/marketplace.md","es/extensions/plugin-manager-installer-plumbing.md","es/extensions/rulebook-matching-pipeline.md","es/extensions/skills.md","es/index.md","es/mcp/mcp-config.md","es/mcp/mcp-protocol-transports.md","es/mcp/mcp-runtime-lifecycle.md","es/mcp/mcp-server-tool-authoring.md","es/natives/natives-addon-loader-runtime.md","es/natives/natives-architecture.md","es/natives/natives-binding-contract.md","es/natives/natives-build-release-debugging.md","es/natives/natives-media-system-utils.md","es/natives/natives-rust-task-cancellation.md","es/natives/natives-shell-pty-process.md","es/natives/natives-text-search-pipeline.md","es/natives/porting-to-natives.md","es/providers/models.md","es/providers/provider-streaming-internals.md","es/providers/python-repl.md","es/runtime-tools/bash-tool-runtime.md","es/runtime-tools/context-command.md","es/runtime-tools/custom-tools.md","es/runtime-tools/notebook-tool-runtime.md","es/runtime-tools/resolve-tool-runtime.md","es/runtime-tools/slash-command-internals.md","es/runtime-tools/task-agent-discovery.md","es/sessions/compaction.md","es/sessions/handoff-generation-pipeline.md","es/sessions/memory.md","es/sessions/non-compaction-retry-policy.md","es/sessions/session-operations-export-share-fork-resume.md","es/sessions/session-switching-and-recent-listing.md","es/sessions/session-tree-plan.md","es/sessions/session.md","es/sessions/ttsr-injection-lifecycle.md","es/tui/theme.md","es/tui/tree.md","es/tui/tui-runtime-internals.md","es/tui/tui.md","fr/configuration/blob-artifact-architecture.md","fr/configuration/config-usage.md","fr/configuration/environment-variables.md","fr/configuration/fs-scan-cache-architecture.md","fr/configuration/hooks.md","fr/configuration/porting-from-pi-mono.md","fr/configuration/rpc.md","fr/configuration/sdk.md","fr/configuration/secrets.md","fr/extensions/extension-loading.md","fr/extensions/extensions.md","fr/extensions/gemini-manifest-extensions.md","fr/extensions/marketplace.md","fr/extensions/plugin-manager-installer-plumbing.md","fr/extensions/rulebook-matching-pipeline.md","fr/extensions/skills.md","fr/index.md","fr/mcp/mcp-config.md","fr/mcp/mcp-protocol-transports.md","fr/mcp/mcp-runtime-lifecycle.md","fr/mcp/mcp-server-tool-authoring.md","fr/natives/natives-addon-loader-runtime.md","fr/natives/natives-architecture.md","fr/natives/natives-binding-contract.md","fr/natives/natives-build-release-debugging.md","fr/natives/natives-media-system-utils.md","fr/natives/natives-rust-task-cancellation.md","fr/natives/natives-shell-pty-process.md","fr/natives/natives-text-search-pipeline.md","fr/natives/porting-to-natives.md","fr/providers/models.md","fr/providers/provider-streaming-internals.md","fr/providers/python-repl.md","fr/runtime-tools/bash-tool-runtime.md","fr/runtime-tools/context-command.md","fr/runtime-tools/custom-tools.md","fr/runtime-tools/notebook-tool-runtime.md","fr/runtime-tools/resolve-tool-runtime.md","fr/runtime-tools/slash-command-internals.md","fr/runtime-tools/task-agent-discovery.md","fr/sessions/compaction.md","fr/sessions/handoff-generation-pipeline.md","fr/sessions/memory.md","fr/sessions/non-compaction-retry-policy.md","fr/sessions/session-operations-export-share-fork-resume.md","fr/sessions/session-switching-and-recent-listing.md","fr/sessions/session-tree-plan.md","fr/sessions/session.md","fr/sessions/ttsr-injection-lifecycle.md","fr/tui/theme.md","fr/tui/tree.md","fr/tui/tui-runtime-internals.md","fr/tui/tui.md","hi/configuration/blob-artifact-architecture.md","hi/configuration/config-usage.md","hi/configuration/environment-variables.md","hi/configuration/fs-scan-cache-architecture.md","hi/configuration/hooks.md","hi/configuration/porting-from-pi-mono.md","hi/configuration/rpc.md","hi/configuration/sdk.md","hi/configuration/secrets.md","hi/extensions/extension-loading.md","hi/extensions/extensions.md","hi/extensions/gemini-manifest-extensions.md","hi/extensions/marketplace.md","hi/extensions/plugin-manager-installer-plumbing.md","hi/extensions/rulebook-matching-pipeline.md","hi/extensions/skills.md","hi/index.md","hi/mcp/mcp-config.md","hi/mcp/mcp-protocol-transports.md","hi/mcp/mcp-runtime-lifecycle.md","hi/mcp/mcp-server-tool-authoring.md","hi/natives/natives-addon-loader-runtime.md","hi/natives/natives-architecture.md","hi/natives/natives-binding-contract.md","hi/natives/natives-build-release-debugging.md","hi/natives/natives-media-system-utils.md","hi/natives/natives-rust-task-cancellation.md","hi/natives/natives-shell-pty-process.md","hi/natives/natives-text-search-pipeline.md","hi/natives/porting-to-natives.md","hi/providers/models.md","hi/providers/provider-streaming-internals.md","hi/providers/python-repl.md","hi/runtime-tools/bash-tool-runtime.md","hi/runtime-tools/context-command.md","hi/runtime-tools/custom-tools.md","hi/runtime-tools/notebook-tool-runtime.md","hi/runtime-tools/resolve-tool-runtime.md","hi/runtime-tools/slash-command-internals.md","hi/runtime-tools/task-agent-discovery.md","hi/sessions/compaction.md","hi/sessions/handoff-generation-pipeline.md","hi/sessions/memory.md","hi/sessions/non-compaction-retry-policy.md","hi/sessions/session-operations-export-share-fork-resume.md","hi/sessions/session-switching-and-recent-listing.md","hi/sessions/session-tree-plan.md","hi/sessions/session.md","hi/sessions/ttsr-injection-lifecycle.md","hi/tui/theme.md","hi/tui/tree.md","hi/tui/tui-runtime-internals.md","hi/tui/tui.md","it/configuration/blob-artifact-architecture.md","it/configuration/config-usage.md","it/configuration/environment-variables.md","it/configuration/fs-scan-cache-architecture.md","it/configuration/hooks.md","it/configuration/porting-from-pi-mono.md","it/configuration/rpc.md","it/configuration/sdk.md","it/configuration/secrets.md","it/extensions/extension-loading.md","it/extensions/extensions.md","it/extensions/gemini-manifest-extensions.md","it/extensions/marketplace.md","it/extensions/plugin-manager-installer-plumbing.md","it/extensions/rulebook-matching-pipeline.md","it/extensions/skills.md","it/index.md","it/mcp/mcp-config.md","it/mcp/mcp-protocol-transports.md","it/mcp/mcp-runtime-lifecycle.md","it/mcp/mcp-server-tool-authoring.md","it/natives/natives-addon-loader-runtime.md","it/natives/natives-architecture.md","it/natives/natives-binding-contract.md","it/natives/natives-build-release-debugging.md","it/natives/natives-media-system-utils.md","it/natives/natives-rust-task-cancellation.md","it/natives/natives-shell-pty-process.md","it/natives/natives-text-search-pipeline.md","it/natives/porting-to-natives.md","it/providers/models.md","it/providers/provider-streaming-internals.md","it/providers/python-repl.md","it/runtime-tools/bash-tool-runtime.md","it/runtime-tools/context-command.md","it/runtime-tools/custom-tools.md","it/runtime-tools/notebook-tool-runtime.md","it/runtime-tools/resolve-tool-runtime.md","it/runtime-tools/slash-command-internals.md","it/runtime-tools/task-agent-discovery.md","it/sessions/compaction.md","it/sessions/handoff-generation-pipeline.md","it/sessions/memory.md","it/sessions/non-compaction-retry-policy.md","it/sessions/session-operations-export-share-fork-resume.md","it/sessions/session-switching-and-recent-listing.md","it/sessions/session-tree-plan.md","it/sessions/session.md","it/sessions/ttsr-injection-lifecycle.md","it/tui/theme.md","it/tui/tree.md","it/tui/tui-runtime-internals.md","it/tui/tui.md","ja/configuration/blob-artifact-architecture.md","ja/configuration/config-usage.md","ja/configuration/environment-variables.md","ja/configuration/fs-scan-cache-architecture.md","ja/configuration/hooks.md","ja/configuration/porting-from-pi-mono.md","ja/configuration/rpc.md","ja/configuration/sdk.md","ja/configuration/secrets.md","ja/extensions/extension-loading.md","ja/extensions/extensions.md","ja/extensions/gemini-manifest-extensions.md","ja/extensions/marketplace.md","ja/extensions/plugin-manager-installer-plumbing.md","ja/extensions/rulebook-matching-pipeline.md","ja/extensions/skills.md","ja/index.md","ja/mcp/mcp-config.md","ja/mcp/mcp-protocol-transports.md","ja/mcp/mcp-runtime-lifecycle.md","ja/mcp/mcp-server-tool-authoring.md","ja/natives/natives-addon-loader-runtime.md","ja/natives/natives-architecture.md","ja/natives/natives-binding-contract.md","ja/natives/natives-build-release-debugging.md","ja/natives/natives-media-system-utils.md","ja/natives/natives-rust-task-cancellation.md","ja/natives/natives-shell-pty-process.md","ja/natives/natives-text-search-pipeline.md","ja/natives/porting-to-natives.md","ja/providers/models.md","ja/providers/provider-streaming-internals.md","ja/providers/python-repl.md","ja/runtime-tools/bash-tool-runtime.md","ja/runtime-tools/context-command.md","ja/runtime-tools/custom-tools.md","ja/runtime-tools/notebook-tool-runtime.md","ja/runtime-tools/resolve-tool-runtime.md","ja/runtime-tools/slash-command-internals.md","ja/runtime-tools/task-agent-discovery.md","ja/sessions/compaction.md","ja/sessions/handoff-generation-pipeline.md","ja/sessions/memory.md","ja/sessions/non-compaction-retry-policy.md","ja/sessions/session-operations-export-share-fork-resume.md","ja/sessions/session-switching-and-recent-listing.md","ja/sessions/session-tree-plan.md","ja/sessions/session.md","ja/sessions/ttsr-injection-lifecycle.md","ja/tui/theme.md","ja/tui/tree.md","ja/tui/tui-runtime-internals.md","ja/tui/tui.md","ko/configuration/blob-artifact-architecture.md","ko/configuration/config-usage.md","ko/configuration/environment-variables.md","ko/configuration/fs-scan-cache-architecture.md","ko/configuration/hooks.md","ko/configuration/porting-from-pi-mono.md","ko/configuration/rpc.md","ko/configuration/sdk.md","ko/configuration/secrets.md","ko/extensions/extension-loading.md","ko/extensions/extensions.md","ko/extensions/gemini-manifest-extensions.md","ko/extensions/marketplace.md","ko/extensions/plugin-manager-installer-plumbing.md","ko/extensions/rulebook-matching-pipeline.md","ko/extensions/skills.md","ko/index.md","ko/mcp/mcp-config.md","ko/mcp/mcp-protocol-transports.md","ko/mcp/mcp-runtime-lifecycle.md","ko/mcp/mcp-server-tool-authoring.md","ko/natives/natives-addon-loader-runtime.md","ko/natives/natives-architecture.md","ko/natives/natives-binding-contract.md","ko/natives/natives-build-release-debugging.md","ko/natives/natives-media-system-utils.md","ko/natives/natives-rust-task-cancellation.md","ko/natives/natives-shell-pty-process.md","ko/natives/natives-text-search-pipeline.md","ko/natives/porting-to-natives.md","ko/providers/models.md","ko/providers/provider-streaming-internals.md","ko/providers/python-repl.md","ko/runtime-tools/bash-tool-runtime.md","ko/runtime-tools/context-command.md","ko/runtime-tools/custom-tools.md","ko/runtime-tools/notebook-tool-runtime.md","ko/runtime-tools/resolve-tool-runtime.md","ko/runtime-tools/slash-command-internals.md","ko/runtime-tools/task-agent-discovery.md","ko/sessions/compaction.md","ko/sessions/handoff-generation-pipeline.md","ko/sessions/memory.md","ko/sessions/non-compaction-retry-policy.md","ko/sessions/session-operations-export-share-fork-resume.md","ko/sessions/session-switching-and-recent-listing.md","ko/sessions/session-tree-plan.md","ko/sessions/session.md","ko/sessions/ttsr-injection-lifecycle.md","ko/tui/theme.md","ko/tui/tree.md","ko/tui/tui-runtime-internals.md","ko/tui/tui.md","plans/provider-agnostic-dynamic-model-routing.md","pt-br/configuration/blob-artifact-architecture.md","pt-br/configuration/config-usage.md","pt-br/configuration/environment-variables.md","pt-br/configuration/fs-scan-cache-architecture.md","pt-br/configuration/hooks.md","pt-br/configuration/porting-from-pi-mono.md","pt-br/configuration/rpc.md","pt-br/configuration/sdk.md","pt-br/configuration/secrets.md","pt-br/extensions/extension-loading.md","pt-br/extensions/extensions.md","pt-br/extensions/gemini-manifest-extensions.md","pt-br/extensions/marketplace.md","pt-br/extensions/plugin-manager-installer-plumbing.md","pt-br/extensions/rulebook-matching-pipeline.md","pt-br/extensions/skills.md","pt-br/index.md","pt-br/mcp/mcp-config.md","pt-br/mcp/mcp-protocol-transports.md","pt-br/mcp/mcp-runtime-lifecycle.md","pt-br/mcp/mcp-server-tool-authoring.md","pt-br/natives/natives-addon-loader-runtime.md","pt-br/natives/natives-architecture.md","pt-br/natives/natives-binding-contract.md","pt-br/natives/natives-build-release-debugging.md","pt-br/natives/natives-media-system-utils.md","pt-br/natives/natives-rust-task-cancellation.md","pt-br/natives/natives-shell-pty-process.md","pt-br/natives/natives-text-search-pipeline.md","pt-br/natives/porting-to-natives.md","pt-br/providers/models.md","pt-br/providers/provider-streaming-internals.md","pt-br/providers/python-repl.md","pt-br/runtime-tools/bash-tool-runtime.md","pt-br/runtime-tools/context-command.md","pt-br/runtime-tools/custom-tools.md","pt-br/runtime-tools/notebook-tool-runtime.md","pt-br/runtime-tools/resolve-tool-runtime.md","pt-br/runtime-tools/slash-command-internals.md","pt-br/runtime-tools/task-agent-discovery.md","pt-br/sessions/compaction.md","pt-br/sessions/handoff-generation-pipeline.md","pt-br/sessions/memory.md","pt-br/sessions/non-compaction-retry-policy.md","pt-br/sessions/session-operations-export-share-fork-resume.md","pt-br/sessions/session-switching-and-recent-listing.md","pt-br/sessions/session-tree-plan.md","pt-br/sessions/session.md","pt-br/sessions/ttsr-injection-lifecycle.md","pt-br/tui/theme.md","pt-br/tui/tree.md","pt-br/tui/tui-runtime-internals.md","pt-br/tui/tui.md","th/configuration/blob-artifact-architecture.md","th/configuration/config-usage.md","th/configuration/environment-variables.md","th/configuration/fs-scan-cache-architecture.md","th/configuration/hooks.md","th/configuration/porting-from-pi-mono.md","th/configuration/rpc.md","th/configuration/sdk.md","th/configuration/secrets.md","th/extensions/extension-loading.md","th/extensions/extensions.md","th/extensions/gemini-manifest-extensions.md","th/extensions/marketplace.md","th/extensions/plugin-manager-installer-plumbing.md","th/extensions/rulebook-matching-pipeline.md","th/extensions/skills.md","th/index.md","th/mcp/mcp-config.md","th/mcp/mcp-protocol-transports.md","th/mcp/mcp-runtime-lifecycle.md","th/mcp/mcp-server-tool-authoring.md","th/natives/natives-addon-loader-runtime.md","th/natives/natives-architecture.md","th/natives/natives-binding-contract.md","th/natives/natives-build-release-debugging.md","th/natives/natives-media-system-utils.md","th/natives/natives-rust-task-cancellation.md","th/natives/natives-shell-pty-process.md","th/natives/natives-text-search-pipeline.md","th/natives/porting-to-natives.md","th/providers/models.md","th/providers/provider-streaming-internals.md","th/providers/python-repl.md","th/runtime-tools/bash-tool-runtime.md","th/runtime-tools/context-command.md","th/runtime-tools/custom-tools.md","th/runtime-tools/notebook-tool-runtime.md","th/runtime-tools/resolve-tool-runtime.md","th/runtime-tools/slash-command-internals.md","th/runtime-tools/task-agent-discovery.md","th/sessions/compaction.md","th/sessions/handoff-generation-pipeline.md","th/sessions/memory.md","th/sessions/non-compaction-retry-policy.md","th/sessions/session-operations-export-share-fork-resume.md","th/sessions/session-switching-and-recent-listing.md","th/sessions/session-tree-plan.md","th/sessions/session.md","th/sessions/ttsr-injection-lifecycle.md","th/tui/theme.md","th/tui/tree.md","th/tui/tui-runtime-internals.md","th/tui/tui.md","zh-cn/configuration/blob-artifact-architecture.md","zh-cn/configuration/config-usage.md","zh-cn/configuration/environment-variables.md","zh-cn/configuration/fs-scan-cache-architecture.md","zh-cn/configuration/hooks.md","zh-cn/configuration/porting-from-pi-mono.md","zh-cn/configuration/rpc.md","zh-cn/configuration/sdk.md","zh-cn/configuration/secrets.md","zh-cn/extensions/extension-loading.md","zh-cn/extensions/extensions.md","zh-cn/extensions/gemini-manifest-extensions.md","zh-cn/extensions/marketplace.md","zh-cn/extensions/plugin-manager-installer-plumbing.md","zh-cn/extensions/rulebook-matching-pipeline.md","zh-cn/extensions/skills.md","zh-cn/index.md","zh-cn/mcp/mcp-config.md","zh-cn/mcp/mcp-protocol-transports.md","zh-cn/mcp/mcp-runtime-lifecycle.md","zh-cn/mcp/mcp-server-tool-authoring.md","zh-cn/natives/natives-addon-loader-runtime.md","zh-cn/natives/natives-architecture.md","zh-cn/natives/natives-binding-contract.md","zh-cn/natives/natives-build-release-debugging.md","zh-cn/natives/natives-media-system-utils.md","zh-cn/natives/natives-rust-task-cancellation.md","zh-cn/natives/natives-shell-pty-process.md","zh-cn/natives/natives-text-search-pipeline.md","zh-cn/natives/porting-to-natives.md","zh-cn/providers/models.md","zh-cn/providers/provider-streaming-internals.md","zh-cn/providers/python-repl.md","zh-cn/runtime-tools/bash-tool-runtime.md","zh-cn/runtime-tools/context-command.md","zh-cn/runtime-tools/custom-tools.md","zh-cn/runtime-tools/notebook-tool-runtime.md","zh-cn/runtime-tools/resolve-tool-runtime.md","zh-cn/runtime-tools/slash-command-internals.md","zh-cn/runtime-tools/task-agent-discovery.md","zh-cn/sessions/compaction.md","zh-cn/sessions/handoff-generation-pipeline.md","zh-cn/sessions/memory.md","zh-cn/sessions/non-compaction-retry-policy.md","zh-cn/sessions/session-operations-export-share-fork-resume.md","zh-cn/sessions/session-switching-and-recent-listing.md","zh-cn/sessions/session-tree-plan.md","zh-cn/sessions/session.md","zh-cn/sessions/ttsr-injection-lifecycle.md","zh-cn/tui/theme.md","zh-cn/tui/tree.md","zh-cn/tui/tui-runtime-internals.md","zh-cn/tui/tui.md","zh-tw/configuration/blob-artifact-architecture.md","zh-tw/configuration/config-usage.md","zh-tw/configuration/environment-variables.md","zh-tw/configuration/fs-scan-cache-architecture.md","zh-tw/configuration/hooks.md","zh-tw/configuration/porting-from-pi-mono.md","zh-tw/configuration/rpc.md","zh-tw/configuration/sdk.md","zh-tw/configuration/secrets.md","zh-tw/extensions/extension-loading.md","zh-tw/extensions/extensions.md","zh-tw/extensions/gemini-manifest-extensions.md","zh-tw/extensions/marketplace.md","zh-tw/extensions/plugin-manager-installer-plumbing.md","zh-tw/extensions/rulebook-matching-pipeline.md","zh-tw/extensions/skills.md","zh-tw/index.md","zh-tw/mcp/mcp-config.md","zh-tw/mcp/mcp-protocol-transports.md","zh-tw/mcp/mcp-runtime-lifecycle.md","zh-tw/mcp/mcp-server-tool-authoring.md","zh-tw/natives/natives-addon-loader-runtime.md","zh-tw/natives/natives-architecture.md","zh-tw/natives/natives-binding-contract.md","zh-tw/natives/natives-build-release-debugging.md","zh-tw/natives/natives-media-system-utils.md","zh-tw/natives/natives-rust-task-cancellation.md","zh-tw/natives/natives-shell-pty-process.md","zh-tw/natives/natives-text-search-pipeline.md","zh-tw/natives/porting-to-natives.md","zh-tw/providers/models.md","zh-tw/providers/provider-streaming-internals.md","zh-tw/providers/python-repl.md","zh-tw/runtime-tools/bash-tool-runtime.md","zh-tw/runtime-tools/context-command.md","zh-tw/runtime-tools/custom-tools.md","zh-tw/runtime-tools/notebook-tool-runtime.md","zh-tw/runtime-tools/resolve-tool-runtime.md","zh-tw/runtime-tools/slash-command-internals.md","zh-tw/runtime-tools/task-agent-discovery.md","zh-tw/sessions/compaction.md","zh-tw/sessions/handoff-generation-pipeline.md","zh-tw/sessions/memory.md","zh-tw/sessions/non-compaction-retry-policy.md","zh-tw/sessions/session-operations-export-share-fork-resume.md","zh-tw/sessions/session-switching-and-recent-listing.md","zh-tw/sessions/session-tree-plan.md","zh-tw/sessions/session.md","zh-tw/sessions/ttsr-injection-lifecycle.md","zh-tw/tui/theme.md","zh-tw/tui/tree.md","zh-tw/tui/tui-runtime-internals.md","zh-tw/tui/tui.md"];
|
|
4
4
|
|
|
5
5
|
export const EMBEDDED_DOCS: Readonly<Record<string, string>> = {
|
|
6
6
|
"SYSTEM_PROMPT_GUIDE.md": "# Anthropic System Prompting Best Practices Standard\n\nThis document defines the authoritative engineering standard for authoring, refactoring, and maintaining system prompts, agent instructions, and skills across all f5-sales-demo repositories and xcsh AI assistant plugins.\n\nAll system prompts and agent instructions must strictly adhere to this 8-point checklist.\n\n---\n\n## The 8-Point System Prompt Checklist\n\n### 1. XML Tag Hierarchy & Semantic Framing\n- **Standard**: Wrap logical prompt sections in clean, explicit XML tags (`<role>`, `<defensive_scope>`, `<governance>`, `<operational_standards>`, `<execution_protocol>`, `<examples>`, `<structured_reporting>`).\n- **Rationale**: Claude models are optimized to recognize XML tags as deterministic structural boundaries. Using XML tags prevents context confusion, isolates directives, and ensures consistent rule adherence.\n\n### 2. Affirmative Guidance over Negative Prohibitions\n- **Standard**: Frame all operational boundaries, rules, and workflows using positive, action-oriented directives (*what TO do*). Eliminate negative panic keywords (`HALT immediately`, `STOP`, `DON'T`, `NEVER`, `PROHIBITED`).\n- **Rationale**: Negative prohibition language induces cognitive friction and model freezing, causing the assistant to become overly hesitant or refuse valid execution paths. Affirmative guidance provides a clear forward direction.\n\n### 3. Actionable Rationale (\"Why\" Explanations)\n- **Standard**: Pair every guideline, constraint, or workflow step with an explicit explanation of *why* the rule exists and what outcome it guarantees.\n- **Rationale**: Providing rationale equips the model with the underlying engineering intent. This allows Claude to reason safely and adapt flexibly in novel edge cases rather than failing when encountering unexpected inputs.\n\n### 4. Progressive Context Loading & Modular Hierarchy\n- **Standard**: Keep top-level system prompts concise and focused on core persona, scope, and high-level routing. Place granular tool schemas, raw API curl specs, and detailed multi-step SOPs into dynamically loaded skills or specialized subagents.\n- **Rationale**: Progressive context loading prevents prompt bloat, reduces token overhead, avoids recency bias degradation, and maximizes model attention on the immediate task.\n\n### 5. Expert Persona & Professional Confidence\n- **Standard**: Anchor the assistant or agent with an authoritative, expert persona (*\"You are the GitHub Operations Expert agent...\"*) that approaches tasks with professional confidence, precision, and mastery.\n- **Rationale**: An expert persona establishes domain authority, enhances task execution precision, and encourages autonomous problem-solving within safety boundaries.\n\n### 6. Constructive Fallback Paths (Forward Progress)\n- **Standard**: Provide constructive forward-progress actions for handling missing parameters, ambiguous inputs, or transient API errors instead of halting or throwing panic errors.\n- **Rationale**: Forward progress logic guarantees continuous execution, prompting the caller or retrieving missing context proactively.\n\n### 7. Canonical Few-Shot Examples\n- **Standard**: For complex output structures, status reports, or reasoning patterns, provide clean, canonical few-shot examples wrapped in `<examples>` tags, using `<thinking>` blocks when demonstrating multi-step reasoning.\n- **Rationale**: Few-shot examples ground the model's output formatting far more effectively than abstract rules alone.\n\n### 8. Security Guardrails as High-Rigor Engineering Standards\n- **Standard**: Frame security guardrails (credential protection, input sanitization, worktree isolation, commit history integrity) as standard software craftsmanship and high-rigor engineering practices.\n- **Rationale**: Framing safeguards as standard professional practices integrates security seamlessly without triggering timid refusal behavior.\n\n---\n\n## Verification & Audit Standard\n\nPrior to merging any new or updated prompt file (`*.md` agents, system prompts, or skills), verify compliance against the 8-point checklist above.\n",
|
|
@@ -119,6 +119,7 @@ export const EMBEDDED_DOCS: Readonly<Record<string, string>> = {
|
|
|
119
119
|
"en/configuration/rpc.md": "---\ntitle: RPC Protocol Reference\ndescription: JSON-RPC protocol reference for inter-process communication between xcsh components.\nsidebar:\n order: 5\n label: RPC protocol\n---\n\n# RPC Protocol Reference\n\nRPC mode runs the coding agent as a newline-delimited JSON protocol over stdio.\n\n- **stdin**: commands (`RpcCommand`) and extension UI responses\n- **stdout**: command responses (`RpcResponse`), session/agent events, extension UI requests\n\nPrimary implementation:\n\n- `src/modes/rpc/rpc-mode.ts`\n- `src/modes/rpc/rpc-types.ts`\n- `src/session/agent-session.ts`\n- `packages/agent/src/agent.ts`\n- `packages/agent/src/agent-loop.ts`\n\n## Startup\n\n```bash\nxcsh --mode rpc [regular CLI options]\n```\n\nBehavior notes:\n\n- `@file` CLI arguments are rejected in RPC mode.\n- RPC mode disables automatic session title generation by default to avoid an extra model call.\n- RPC mode resets workflow-altering `todo.*`, `task.*`, and `async.*` settings to their built-in defaults instead of inheriting user overrides.\n- The process reads stdin as JSONL (`readJsonl(Bun.stdin.stream())`).\n- When stdin closes, the process exits with code `0`.\n- Responses/events are written as one JSON object per line.\n\n## Transport and Framing\n\nEach frame is a single JSON object followed by `\\n`.\n\nThere is no envelope beyond the object shape itself.\n\n### Outbound frame categories (stdout)\n\n1. `RpcResponse` (`{ type: \"response\", ... }`)\n2. `AgentSessionEvent` objects (`agent_start`, `message_update`, etc.)\n3. `RpcExtensionUIRequest` (`{ type: \"extension_ui_request\", ... }`)\n4. Extension errors (`{ type: \"extension_error\", extensionPath, event, error }`)\n\n### Inbound frame categories (stdin)\n\n1. `RpcCommand`\n2. `RpcExtensionUIResponse` (`{ type: \"extension_ui_response\", ... }`)\n\n## Request/Response Correlation\n\nAll commands accept optional `id?: string`.\n\n- If provided, normal command responses echo the same `id`.\n- `RpcClient` relies on this for pending-request resolution.\n\nImportant edge behavior from runtime:\n\n- Unknown command responses are emitted with `id: undefined` (even if the request had an `id`).\n- Parse/handler exceptions in the input loop emit `command: \"parse\"` with `id: undefined`.\n- `prompt` and `abort_and_prompt` return immediate success, then may emit a later error response with the **same** id if async prompt scheduling fails.\n\n## Command Schema (canonical)\n\n`RpcCommand` is defined in `src/modes/rpc/rpc-types.ts`:\n\n### Prompting\n\n- `{ id?, type: \"prompt\", message: string, images?: ImageContent[], streamingBehavior?: \"steer\" | \"followUp\" }`\n- `{ id?, type: \"steer\", message: string, images?: ImageContent[] }`\n- `{ id?, type: \"follow_up\", message: string, images?: ImageContent[] }`\n- `{ id?, type: \"abort\" }`\n- `{ id?, type: \"abort_and_prompt\", message: string, images?: ImageContent[] }`\n- `{ id?, type: \"new_session\", parentSession?: string }`\n\n### State\n\n- `{ id?, type: \"get_state\" }`\n- `{ id?, type: \"set_todos\", phases: TodoPhase[] }`\n- `{ id?, type: \"set_host_tools\", tools: RpcHostToolDefinition[] }`\n\n### Model\n\n- `{ id?, type: \"set_model\", provider: string, modelId: string }`\n- `{ id?, type: \"cycle_model\" }`\n- `{ id?, type: \"get_available_models\" }`\n\n### Thinking\n\n- `{ id?, type: \"set_thinking_level\", level: ThinkingLevel }`\n- `{ id?, type: \"cycle_thinking_level\" }`\n\n### Queue modes\n\n- `{ id?, type: \"set_steering_mode\", mode: \"all\" | \"one-at-a-time\" }`\n- `{ id?, type: \"set_follow_up_mode\", mode: \"all\" | \"one-at-a-time\" }`\n- `{ id?, type: \"set_interrupt_mode\", mode: \"immediate\" | \"wait\" }`\n\n### Compaction\n\n- `{ id?, type: \"compact\", customInstructions?: string }`\n- `{ id?, type: \"set_auto_compaction\", enabled: boolean }`\n\n### Retry\n\n- `{ id?, type: \"set_auto_retry\", enabled: boolean }`\n- `{ id?, type: \"abort_retry\" }`\n\n### Bash\n\n- `{ id?, type: \"bash\", command: string }`\n- `{ id?, type: \"abort_bash\" }`\n\n### Session\n\n- `{ id?, type: \"get_session_stats\" }`\n- `{ id?, type: \"export_html\", outputPath?: string }`\n- `{ id?, type: \"switch_session\", sessionPath: string }`\n- `{ id?, type: \"branch\", entryId: string }`\n- `{ id?, type: \"get_branch_messages\" }`\n- `{ id?, type: \"get_last_assistant_text\" }`\n- `{ id?, type: \"set_session_name\", name: string }`\n\n### Messages\n\n- `{ id?, type: \"get_messages\" }`\n\n## Response Schema\n\nAll command results use `RpcResponse`:\n\n- Success: `{ id?, type: \"response\", command: <command>, success: true, data?: ... }`\n- Failure: `{ id?, type: \"response\", command: string, success: false, error: string }`\n\nData payloads are command-specific and defined in `rpc-types.ts`.\n\n### `get_state` payload\n\n```json\n{\n \"model\": { \"provider\": \"...\", \"id\": \"...\" },\n \"thinkingLevel\": \"off|minimal|low|medium|high|xhigh\",\n \"isStreaming\": false,\n \"isCompacting\": false,\n \"steeringMode\": \"all|one-at-a-time\",\n \"followUpMode\": \"all|one-at-a-time\",\n \"interruptMode\": \"immediate|wait\",\n \"sessionFile\": \"...\",\n \"sessionId\": \"...\",\n \"sessionName\": \"...\",\n \"autoCompactionEnabled\": true,\n \"messageCount\": 0,\n \"queuedMessageCount\": 0,\n \"todoPhases\": [\n {\n \"id\": \"phase-1\",\n \"name\": \"Todos\",\n \"tasks\": [\n {\n \"id\": \"task-1\",\n \"content\": \"Map the tool surface\",\n \"status\": \"in_progress\"\n }\n ]\n }\n ]\n}\n```\n\n### `set_todos` payload\n\nReplaces the in-memory todo state for the current session and returns the normalized phase list:\n\n```json\n{\n \"id\": \"req_2\",\n \"type\": \"set_todos\",\n \"phases\": [\n {\n \"id\": \"phase-1\",\n \"name\": \"Evaluation\",\n \"tasks\": [\n {\n \"id\": \"task-1\",\n \"content\": \"Map the read tool surface\",\n \"status\": \"in_progress\"\n },\n {\n \"id\": \"task-2\",\n \"content\": \"Exercise edit operations\",\n \"status\": \"pending\"\n }\n ]\n }\n ]\n}\n```\n\nThis is useful for hosts that want to pre-seed a plan before the first prompt.\n\n### `set_host_tools` payload\n\nReplaces the current set of host-owned tools that the RPC server may call back\ninto over stdio:\n\n```json\n{\n \"id\": \"req_3\",\n \"type\": \"set_host_tools\",\n \"tools\": [\n {\n \"name\": \"echo_host\",\n \"label\": \"Echo Host\",\n \"description\": \"Echo a value from the embedding host\",\n \"parameters\": {\n \"type\": \"object\",\n \"properties\": {\n \"message\": { \"type\": \"string\" }\n },\n \"required\": [\"message\"],\n \"additionalProperties\": false\n }\n }\n ]\n}\n```\n\nThe response payload is:\n\n```json\n{\n \"toolNames\": [\"echo_host\"]\n}\n```\n\nThese tools are added to the active session tool registry before the next model\ncall. Re-sending `set_host_tools` replaces the previous host-owned set.\n\n## Event Stream Schema\n\nRPC mode forwards `AgentSessionEvent` objects from `AgentSession.subscribe(...)`.\n\nCommon event types:\n\n- `agent_start`, `agent_end`\n- `turn_start`, `turn_end`\n- `message_start`, `message_update`, `message_end`\n- `tool_execution_start`, `tool_execution_update`, `tool_execution_end`\n- `auto_compaction_start`, `auto_compaction_end`\n- `auto_retry_start`, `auto_retry_end`\n- `ttsr_triggered`\n- `todo_reminder`\n- `todo_auto_clear`\n\nExtension runner errors are emitted separately as:\n\n```json\n{ \"type\": \"extension_error\", \"extensionPath\": \"...\", \"event\": \"...\", \"error\": \"...\" }\n```\n\n`message_update` includes streaming deltas in `assistantMessageEvent` (text/thinking/toolcall deltas).\n\n## Prompt/Queue Concurrency and Ordering\n\nThis is the most important operational behavior.\n\n### Immediate ack vs completion\n\n`prompt` and `abort_and_prompt` are **acknowledged immediately**:\n\n```json\n{ \"id\": \"req_1\", \"type\": \"response\", \"command\": \"prompt\", \"success\": true }\n```\n\nThat means:\n\n- command acceptance != run completion\n- final completion is observed via `agent_end`\n\n### While streaming\n\n`AgentSession.prompt()` requires `streamingBehavior` during active streaming:\n\n- `\"steer\"` => queued steering message (interrupt path)\n- `\"followUp\"` => queued follow-up message (post-turn path)\n\nIf omitted during streaming, prompt fails.\n\n### Queue defaults\n\nFrom the coding-agent settings schema (`packages/coding-agent/src/config/settings-schema.ts`):\n\n- `steeringMode`: `\"one-at-a-time\"`\n- `followUpMode`: `\"one-at-a-time\"`\n- `interruptMode`: `\"wait\"`\n\n### Mode semantics\n\n- `set_steering_mode` / `set_follow_up_mode`\n - `\"one-at-a-time\"`: dequeue one queued message per turn\n - `\"all\"`: dequeue entire queue at once\n- `set_interrupt_mode`\n - `\"immediate\"`: tool execution checks steering between tool calls; pending steering can abort remaining tool calls in the turn\n - `\"wait\"`: defer steering until turn completion\n\n## Extension UI Sub-Protocol\n\nExtensions in RPC mode use request/response UI frames.\n\n### Outbound request\n\n`RpcExtensionUIRequest` (`type: \"extension_ui_request\"`) methods:\n\n- `select`, `confirm`, `input`, `editor`\n- `notify`, `setStatus`, `setWidget`, `setTitle`, `set_editor_text`\n\nRuntime note:\n\n- Automatic session title generation is disabled in RPC mode, and `setTitle` UI\n requests are also suppressed by default because most hosts do not have a\n meaningful terminal-title surface. Set `PI_RPC_EMIT_TITLE=1` to opt back in to\n the UI event only.\n\nExample:\n\n```json\n{ \"type\": \"extension_ui_request\", \"id\": \"123\", \"method\": \"confirm\", \"title\": \"Confirm\", \"message\": \"Continue?\", \"timeout\": 30000 }\n```\n\n### Inbound response\n\n`RpcExtensionUIResponse` (`type: \"extension_ui_response\"`):\n\n- `{ type: \"extension_ui_response\", id: string, value: string }`\n- `{ type: \"extension_ui_response\", id: string, confirmed: boolean }`\n- `{ type: \"extension_ui_response\", id: string, cancelled: true }`\n\nIf a dialog has a timeout, RPC mode resolves to a default value when timeout/abort fires.\n\n## Host Tool Sub-Protocol\n\nRPC hosts can expose custom tools to the agent by sending `set_host_tools`, then\nserving execution requests over the same transport.\n\n### Outbound request\n\nWhen the agent wants the host to execute one of those tools, RPC mode emits:\n\n```json\n{\n \"type\": \"host_tool_call\",\n \"id\": \"host_1\",\n \"toolCallId\": \"toolu_123\",\n \"toolName\": \"echo_host\",\n \"arguments\": { \"message\": \"hello\" }\n}\n```\n\nIf the tool execution is later aborted, RPC mode emits:\n\n```json\n{\n \"type\": \"host_tool_cancel\",\n \"id\": \"host_cancel_1\",\n \"targetId\": \"host_1\"\n}\n```\n\n### Inbound updates and completion\n\nHosts can optionally stream progress:\n\n```json\n{\n \"type\": \"host_tool_update\",\n \"id\": \"host_1\",\n \"partialResult\": {\n \"content\": [{ \"type\": \"text\", \"text\": \"working\" }]\n }\n}\n```\n\nCompletion uses:\n\n```json\n{\n \"type\": \"host_tool_result\",\n \"id\": \"host_1\",\n \"result\": {\n \"content\": [{ \"type\": \"text\", \"text\": \"done\" }]\n }\n}\n```\n\nSet `isError: true` on `host_tool_result` to surface the returned content as a\ntool error.\n\n## Error Model and Recoverability\n\n### Command-level failures\n\nFailures are `success: false` with string `error`.\n\n```json\n{ \"id\": \"req_2\", \"type\": \"response\", \"command\": \"set_model\", \"success\": false, \"error\": \"Model not found: provider/model\" }\n```\n\n### Recoverability expectations\n\n- Most command failures are recoverable; process remains alive.\n- Malformed JSONL / parse-loop exceptions emit a `parse` error response and continue reading subsequent lines.\n- Empty `set_session_name` is rejected (`Session name cannot be empty`).\n- Extension UI responses with unknown `id` are ignored.\n- Process termination conditions are stdin close or explicit extension-triggered shutdown.\n\n## Compact Command Flows\n\n### 1) Prompt and stream\n\nstdin:\n\n```json\n{ \"id\": \"req_1\", \"type\": \"prompt\", \"message\": \"Summarize this repo\" }\n```\n\nstdout sequence (typical):\n\n```json\n{ \"id\": \"req_1\", \"type\": \"response\", \"command\": \"prompt\", \"success\": true }\n{ \"type\": \"agent_start\" }\n{ \"type\": \"message_update\", \"assistantMessageEvent\": { \"type\": \"text_delta\", \"delta\": \"...\" }, \"message\": { \"role\": \"assistant\", \"content\": [] } }\n{ \"type\": \"agent_end\", \"messages\": [] }\n```\n\n### 2) Prompt during streaming with explicit queue policy\n\nstdin:\n\n```json\n{ \"id\": \"req_2\", \"type\": \"prompt\", \"message\": \"Also include risks\", \"streamingBehavior\": \"followUp\" }\n```\n\n### 3) Inspect and tune queue behavior\n\nstdin:\n\n```json\n{ \"id\": \"q1\", \"type\": \"get_state\" }\n{ \"id\": \"q2\", \"type\": \"set_steering_mode\", \"mode\": \"all\" }\n{ \"id\": \"q3\", \"type\": \"set_interrupt_mode\", \"mode\": \"wait\" }\n```\n\n### 4) Extension UI round trip\n\nstdout:\n\n```json\n{ \"type\": \"extension_ui_request\", \"id\": \"ui_7\", \"method\": \"input\", \"title\": \"Branch name\", \"placeholder\": \"feature/...\" }\n```\n\nstdin:\n\n```json\n{ \"type\": \"extension_ui_response\", \"id\": \"ui_7\", \"value\": \"feature/rpc-host\" }\n```\n\n## Notes on `RpcClient` helper\n\n`src/modes/rpc/rpc-client.ts` is a convenience wrapper, not the protocol definition.\n\nCurrent helper characteristics:\n\n- Spawns `bun <cliPath> --mode rpc`\n- Correlates responses by generated `req_<n>` ids\n- Dispatches only recognized `AgentEvent` types to listeners\n- Supports host-owned custom tools via `setCustomTools()` and automatic handling of `host_tool_call` / `host_tool_cancel`\n- Does **not** expose helper methods for every protocol command (for example, `set_interrupt_mode` and `set_session_name` are in protocol types but not wrapped as dedicated methods)\n\nUse raw protocol frames if you need complete surface coverage.\n",
|
|
120
120
|
"en/configuration/sdk.md": "---\ntitle: SDK\ndescription: SDK for building custom agents and integrations on top of the xcsh coding agent runtime.\nsidebar:\n order: 6\n label: SDK\n---\n\n# SDK\n\nThe SDK is the in-process integration surface for `@f5-sales-demo/xcsh`.\nUse it when you want direct access to agent state, event streaming, tool wiring, and session control from your own Bun/Node process.\n\nIf you need cross-language/process isolation, use RPC mode instead.\n\n## Installation\n\n```bash\nbun add @f5-sales-demo/xcsh\n```\n\n## Entry points\n\n`@f5-sales-demo/xcsh` exports the SDK APIs from the package root.\n\nCore exports for embedders:\n\n- `createAgentSession`\n- `SessionManager`\n- `Settings`\n- `AuthStorage`\n- `ModelRegistry`\n- `discoverAuthStorage`\n- Discovery helpers (`discoverExtensions`, `discoverSkills`, `discoverContextFiles`, `discoverPromptTemplates`, `discoverSlashCommands`, `discoverCustomTSCommands`, `discoverMCPServers`)\n- Tool factory surface (`createTools`, `BUILTIN_TOOLS`, tool classes)\n\n## Quick start (auto-discovery defaults)\n\n```ts\nimport { createAgentSession } from \"@f5-sales-demo/xcsh\";\n\nconst { session, modelFallbackMessage } = await createAgentSession();\n\nif (modelFallbackMessage) {\n process.stderr.write(`${modelFallbackMessage}\\n`);\n}\n\nconst unsubscribe = session.subscribe(event => {\n if (event.type === \"message_update\" && event.assistantMessageEvent.type === \"text_delta\") {\n process.stdout.write(event.assistantMessageEvent.delta);\n }\n});\n\nawait session.prompt(\"Summarize this repository in 3 bullets.\");\nunsubscribe();\nawait session.dispose();\n```\n\n## What `createAgentSession()` discovers by default\n\n`createAgentSession()` follows “provide to override, omit to discover”.\n\nIf omitted, it resolves:\n\n- `cwd`: `getProjectDir()`\n- `agentDir`: `~/.xcsh/agent` (via `getAgentDir()`)\n- `authStorage`: `discoverAuthStorage(agentDir)`\n- `modelRegistry`: `new ModelRegistry(authStorage)` + `await refresh()`\n- `settings`: `await Settings.init({ cwd, agentDir })`\n- `sessionManager`: `SessionManager.create(cwd)` (file-backed)\n- skills/context files/prompt templates/slash commands/extensions/custom TS commands\n- built-in tools via `createTools(...)`\n- MCP tools (enabled by default)\n- LSP integration (enabled by default)\n\n### Required vs optional inputs\n\nTypically you must provide only what you want to control:\n\n- **Must provide**: nothing for a minimal session\n- **Usually provide explicitly** in embedders:\n - `sessionManager` (if you need in-memory or custom location)\n - `authStorage` + `modelRegistry` (if you own credential/model lifecycle)\n - `model` or `modelPattern` (if deterministic model selection matters)\n - `settings` (if you need isolated/test config)\n\n## Session manager behavior (persistent vs in-memory)\n\n`AgentSession` always uses a `SessionManager`; behavior depends on which factory you use.\n\n### File-backed (default)\n\n```ts\nimport { createAgentSession, SessionManager } from \"@f5-sales-demo/xcsh\";\n\nconst { session } = await createAgentSession({\n sessionManager: SessionManager.create(process.cwd()),\n});\n\nconsole.log(session.sessionFile); // absolute .jsonl path\n```\n\n- Persists conversation/messages/state deltas to session files.\n- Supports resume/open/list/fork workflows.\n- `session.sessionFile` is defined.\n\n### In-memory\n\n```ts\nimport { createAgentSession, SessionManager } from \"@f5-sales-demo/xcsh\";\n\nconst { session } = await createAgentSession({\n sessionManager: SessionManager.inMemory(),\n});\n\nconsole.log(session.sessionFile); // undefined\n```\n\n- No filesystem persistence.\n- Useful for tests, ephemeral workers, request-scoped agents.\n- Session methods still work, but persistence-specific behaviors (file resume/fork paths) are naturally limited.\n\n### Resume/open/list helpers\n\n```ts\nimport { SessionManager } from \"@f5-sales-demo/xcsh\";\n\nconst recent = await SessionManager.continueRecent(process.cwd());\nconst listed = await SessionManager.list(process.cwd());\nconst opened = listed[0] ? await SessionManager.open(listed[0].path) : null;\n```\n\n## Model and auth wiring\n\n`createAgentSession()` uses `ModelRegistry` + `AuthStorage` for model selection and API key resolution.\n\n### Explicit wiring\n\n```ts\nimport {\n createAgentSession,\n discoverAuthStorage,\n ModelRegistry,\n SessionManager,\n} from \"@f5-sales-demo/xcsh\";\n\nconst authStorage = await discoverAuthStorage();\nconst modelRegistry = new ModelRegistry(authStorage);\nawait modelRegistry.refresh();\n\nconst available = modelRegistry.getAvailable();\nif (available.length === 0) throw new Error(\"No authenticated models available\");\n\nconst { session } = await createAgentSession({\n authStorage,\n modelRegistry,\n model: available[0],\n thinkingLevel: \"medium\",\n sessionManager: SessionManager.inMemory(),\n});\n```\n\n### Selection order when `model` is omitted\n\nWhen no explicit `model`/`modelPattern` is provided:\n\n1. restore model from existing session (if restorable + key available)\n2. settings default model role (`default`)\n3. first available model with valid auth\n\nIf restore fails, `modelFallbackMessage` explains fallback.\n\n### Auth priority\n\n`AuthStorage.getApiKey(...)` resolves in this order:\n\n1. runtime override (`setRuntimeApiKey`)\n2. stored credentials in `agent.db`\n3. provider environment variables\n4. custom-provider resolver fallback (if configured)\n\n## Event subscription model\n\nSubscribe with `session.subscribe(listener)`; it returns an unsubscribe function.\n\n```ts\nconst unsubscribe = session.subscribe(event => {\n switch (event.type) {\n case \"agent_start\":\n case \"turn_start\":\n case \"tool_execution_start\":\n break;\n case \"message_update\":\n if (event.assistantMessageEvent.type === \"text_delta\") {\n process.stdout.write(event.assistantMessageEvent.delta);\n }\n break;\n }\n});\n```\n\n`AgentSessionEvent` includes core `AgentEvent` plus session-level events:\n\n- `auto_compaction_start` / `auto_compaction_end`\n- `auto_retry_start` / `auto_retry_end`\n- `ttsr_triggered`\n- `todo_reminder`\n\n## Prompt lifecycle\n\n`session.prompt(text, options?)` is the primary entry point.\n\nBehavior:\n\n1. optional command/template expansion (`/` commands, custom commands, file slash commands, prompt templates)\n2. if currently streaming:\n - requires `streamingBehavior: \"steer\" | \"followUp\"`\n - queues instead of throwing work away\n3. if idle:\n - validates model + API key\n - appends user message\n - starts agent turn\n\nRelated APIs:\n\n- `sendUserMessage(content, { deliverAs? })`\n- `steer(text, images?)`\n- `followUp(text, images?)`\n- `sendCustomMessage({ customType, content, ... }, { deliverAs?, triggerTurn? })`\n- `abort()`\n\n## Tools and extension integration\n\n### Built-ins and filtering\n\n- Built-ins come from `createTools(...)` and `BUILTIN_TOOLS`.\n- `toolNames` acts as an allowlist for built-ins.\n- `customTools` and extension-registered tools are still included.\n- Hidden tools (for example `submit_result`) are opt-in unless required by options.\n\n```ts\nconst { session } = await createAgentSession({\n toolNames: [\"read\", \"grep\", \"find\", \"write\"],\n requireSubmitResultTool: true,\n});\n```\n\n### Extensions\n\n- `extensions`: inline `ExtensionFactory[]`\n- `additionalExtensionPaths`: load extra extension files\n- `disableExtensionDiscovery`: disable automatic extension scanning\n- `preloadedExtensions`: reuse already loaded extension set\n\n### Runtime tool set changes\n\n`AgentSession` supports runtime activation updates:\n\n- `getActiveToolNames()`\n- `getAllToolNames()`\n- `setActiveToolsByName(names)`\n- `refreshMCPTools(mcpTools)`\n\nSystem prompt is rebuilt to reflect active tool changes.\n\n## Discovery helpers\n\nUse these when you want partial control without recreating internal discovery logic:\n\n- `discoverAuthStorage(agentDir?)`\n- `discoverExtensions(cwd?)`\n- `discoverSkills(cwd?, _agentDir?, settings?)`\n- `discoverContextFiles(cwd?, _agentDir?)`\n- `discoverPromptTemplates(cwd?, agentDir?)`\n- `discoverSlashCommands(cwd?)`\n- `discoverCustomTSCommands(cwd?, agentDir?)`\n- `discoverMCPServers(cwd?)`\n- `buildSystemPrompt(options?)`\n\n## Subagent-oriented options\n\nFor SDK consumers building orchestrators (similar to task executor flow):\n\n- `outputSchema`: passes structured output expectation into tool context\n- `requireSubmitResultTool`: forces `submit_result` tool inclusion\n- `taskDepth`: recursion-depth context for nested task sessions\n- `parentTaskPrefix`: artifact naming prefix for nested task outputs\n\nThese are optional for normal single-agent embedding.\n\n## `createAgentSession()` return value\n\n```ts\ntype CreateAgentSessionResult = {\n session: AgentSession;\n extensionsResult: LoadExtensionsResult;\n setToolUIContext: (uiContext: ExtensionUIContext, hasUI: boolean) => void;\n mcpManager?: MCPManager;\n modelFallbackMessage?: string;\n lspServers?: Array<{ name: string; status: \"ready\" | \"error\"; fileTypes: string[]; error?: string }>;\n};\n```\n\nUse `setToolUIContext(...)` only if your embedder provides UI capabilities that tools/extensions should call into.\n\n## Minimal controlled embed example\n\n```ts\nimport {\n createAgentSession,\n discoverAuthStorage,\n ModelRegistry,\n SessionManager,\n Settings,\n} from \"@f5-sales-demo/xcsh\";\n\nconst authStorage = await discoverAuthStorage();\nconst modelRegistry = new ModelRegistry(authStorage);\nawait modelRegistry.refresh();\n\nconst settings = Settings.isolated({\n \"compaction.enabled\": true,\n \"retry.enabled\": true,\n});\n\nconst { session } = await createAgentSession({\n authStorage,\n modelRegistry,\n settings,\n sessionManager: SessionManager.inMemory(),\n toolNames: [\"read\", \"grep\", \"find\", \"edit\", \"write\"],\n enableMCP: false,\n enableLsp: true,\n});\n\nsession.subscribe(event => {\n if (event.type === \"message_update\" && event.assistantMessageEvent.type === \"text_delta\") {\n process.stdout.write(event.assistantMessageEvent.delta);\n }\n});\n\nawait session.prompt(\"Find all TODO comments in this repo and propose fixes.\");\nawait session.dispose();\n```\n",
|
|
121
121
|
"en/configuration/secrets.md": "---\ntitle: Secret Obfuscation\ndescription: Secret obfuscation pipeline that redacts sensitive values from session logs and outputs.\nsidebar:\n order: 3\n label: Secrets\n---\n\n# Secret Obfuscation\n\nPrevents sensitive values (API keys, tokens, passwords) from being sent to LLM providers. When enabled, secrets are replaced with deterministic placeholders before leaving the process, and restored in tool call arguments returned by the model.\n\n## Enabling\n\nEnabled by default. Toggle via `/settings` UI or directly in `config.yml`:\n\n```yaml\nsecrets:\n enabled: false\n```\n\n## How it works\n\n1. On session startup, secrets are collected from two sources:\n - **Environment variables** matching common secret patterns (`*_KEY`, `*_SECRET`, `*_TOKEN`, `*_PASSWORD`, etc.) with values >= 8 characters\n - **`secrets.yml` files** (see below)\n\n2. Outbound messages to the LLM have all secret values replaced with placeholders like `<<$env:S0>>`, `<<$env:S1>>`, etc.\n\n3. Tool call arguments returned by the model are deep-walked and placeholders are restored to original values before execution.\n\nTwo modes control what happens to each secret:\n\n| Mode | Behavior | Reversible |\n|---|---|---|\n| `obfuscate` (default) | Replaced with indexed placeholder `<<$env:SN>>` | Yes (deobfuscated in tool args) |\n| `replace` | Replaced with deterministic same-length string | No (one-way) |\n\n## secrets.yml\n\nDefine custom secret entries in YAML. Two locations are checked:\n\n| Level | Path | Purpose |\n|---|---|---|\n| Global | `~/.xcsh/agent/secrets.yml` | Secrets across all projects |\n| Project | `<cwd>/.xcsh/secrets.yml` | Project-specific secrets |\n\nProject entries override global entries with matching `content`.\n\n### Schema\n\nEach entry in the array has these fields:\n\n| Field | Type | Required | Description |\n|---|---|---|---|\n| `type` | `\"plain\"` or `\"regex\"` | Yes | Match strategy |\n| `content` | string | Yes | The secret value (plain) or regex pattern (regex) |\n| `mode` | `\"obfuscate\"` or `\"replace\"` | No | Default: `\"obfuscate\"` |\n| `replacement` | string | No | Custom replacement (replace mode only) |\n| `flags` | string | No | Regex flags (regex type only) |\n\n### Examples\n\n#### Plain secrets\n\n```yaml\n# Obfuscate a specific API key (default mode)\n- type: plain\n content: sk-proj-abc123def456\n\n# Replace a database password with a fixed string\n- type: plain\n content: hunter2\n mode: replace\n replacement: \"********\"\n```\n\n#### Regex secrets\n\n```yaml\n# Obfuscate any AWS-style key\n- type: regex\n content: \"AKIA[0-9A-Z]{16}\"\n\n# Case-insensitive match with explicit flags\n- type: regex\n content: \"api[_-]?key\\\\s*=\\\\s*\\\\w+\"\n flags: \"i\"\n\n# Regex literal syntax (pattern and flags in one string)\n- type: regex\n content: \"/bearer\\\\s+[a-zA-Z0-9._~+\\\\/=-]+/i\"\n```\n\nRegex entries always scan globally (the `g` flag is enforced automatically). The regex literal syntax `/pattern/flags` is supported as an alternative to separate `content` + `flags` fields. Escaped slashes within the pattern (`\\\\/`) are handled correctly.\n\n#### Replace mode with regex\n\n```yaml\n# One-way replace connection strings (not reversible)\n- type: regex\n content: \"postgres://[^\\\\s]+\"\n mode: replace\n replacement: \"postgres://***\"\n```\n\n## Interaction with env var detection\n\nEnvironment variables are always collected first. File-defined entries are appended after, so file entries can cover secrets that don't live in env vars (config files, hardcoded values, etc.). If the same value appears in both, the file entry's mode takes precedence.\n\n## Key files\n\n- `src/secrets/index.ts` -- loading, merging, env var collection\n- `src/secrets/obfuscator.ts` -- `SecretObfuscator` class, placeholder generation, message obfuscation\n- `src/secrets/regex.ts` -- regex literal parsing and compilation\n- `src/config/settings-schema.ts` -- `secrets.enabled` setting definition\n",
|
|
122
|
+
"en/container/alpine-deployment.md": "---\ntitle: Run xcsh in an Alpine container\ndescription: Build or run the non-root xcsh Alpine image and optionally verify mounted cloud CLI sessions.\n---\n\nTagged xcsh releases publish an image to GitHub Container Registry (GHCR) as\n`ghcr.io/f5-sales-demo/xcsh`. The first package becomes available when a `v*`\nrelease tag runs the container workflow from the default branch. The image runs\nas the unprivileged `xcsh` user and includes the xcsh, Google Cloud, Azure,\nAmazon Web Services (AWS), GitHub, Salesforce, Bun, and Zig command-line\ninterfaces (CLIs).\n\nThe image currently supports `linux/amd64` hosts.\n\n## Prerequisites\n\nBefore you begin, install Docker Engine with the Compose plugin. To run the\noptional live tests, authenticate the Google Cloud and Azure CLIs on your host.\nUse only F5-owned labs or customer demo environments covered by an engagement.\n\nAllow about 10 minutes for the first local build. The cloud CLIs make the image\nsubstantially larger than a minimal xcsh-only runtime.\n\n## Pull a release image\n\nAfter a tagged release finishes, pull the most recent stable image:\n\n```bash\ndocker pull ghcr.io/f5-sales-demo/xcsh:latest\n```\n\nReleases also publish immutable `vX.Y.Z` tags and moving `X.Y` tags. Prefer a\npublished immutable tag when reproducibility matters, for example\n`ghcr.io/f5-sales-demo/xcsh:vX.Y.Z` after replacing `X.Y.Z` with a release\nversion.\n\nRun a non-interactive command through the image entrypoint:\n\n```bash\ndocker run --rm ghcr.io/f5-sales-demo/xcsh:latest --version\ndocker run --rm ghcr.io/f5-sales-demo/xcsh:latest --help\n```\n\nOverride the entrypoint when you need a shell:\n\n```bash\ndocker run --rm -it \\\n --entrypoint /bin/bash \\\n ghcr.io/f5-sales-demo/xcsh:latest\n```\n\n## Build the development service\n\nFrom an xcsh repository checkout, build and start the hardened development\nservice:\n\n```bash\ndocker compose -f docker-compose.dev.yml up -d --build\n```\n\nThe service idles without invoking xcsh, mounts the checkout read-only at\n`/workspace`, and lets you run commands explicitly:\n\n```bash\ndocker compose -f docker-compose.dev.yml exec xcsh-dev xcsh --help\ndocker compose -f docker-compose.dev.yml exec xcsh-dev bash\n```\n\nThe Compose service applies these controls:\n\n- User and group IDs default to `1000`.\n- All Linux capabilities are dropped.\n- `no-new-privileges` blocks privilege escalation.\n- The image filesystem and source checkout are read-only. The `/tmp`, xcsh,\n and Salesforce state paths use writable, ephemeral temporary filesystems.\n The xcsh state mount permits executable mappings because xcsh extracts its\n embedded native module there.\n- The Docker socket and static service-account keys are not mounted.\n- Host CLI configuration directories are mounted read-only under `*-host` paths.\n\nRead-only credentials can still be read by processes in the container. Mount\nthem only into images and source trees you trust.\n\n## Configure the environment\n\nThe development and live user acceptance testing (UAT) scripts use these\nvariables:\n\n| Variable | Default | Purpose |\n| --- | --- | --- |\n| `UID` | `1000` | Runtime user ID used by Compose. |\n| `GID` | `1000` | Runtime group ID used by Compose. |\n| `GEMINI_MODEL` | `gemini-3.1-pro-preview` | Vertex AI model tested by live UAT. |\n| `VERTEX_AI_PROJECT` | Active gcloud project | Vertex AI project tested by live UAT. |\n| `VERTEX_AI_LOCATION` | `us-central1` | Vertex AI location tested by live UAT. |\n| `AZURE_CONFIG_DIR` | `/tmp/xcsh-azure` | Writable Azure CLI session directory inside Compose. |\n| `CLOUDSDK_CONFIG` | `/tmp/xcsh-gcloud` | Writable Google Cloud CLI session directory inside Compose. |\n\nCompose mounts host configuration into these read-only source paths:\n\n| CLI | Host path | Container source path |\n| --- | --- | --- |\n| Google Cloud | `~/.config/gcloud` | `/home/xcsh/.config/gcloud-host` |\n| Azure | `~/.azure` | `/home/xcsh/.azure-host` |\n| AWS | `~/.aws` | `/home/xcsh/.aws-host` |\n| GitHub | `~/.config/gh` | `/home/xcsh/.config/gh-host` |\n| Salesforce | `~/.sfdx` | `/home/xcsh/.sfdx-host` |\n\nThe live tests copy only the required Google Cloud and Azure configuration into\nprivate temporary directories. They delete those copies on exit and never write\nsession state into the host mounts.\n\n## Run verification\n\nRun the deterministic end-to-end test without cloud credentials:\n\n```bash\n./scripts/e2e-user-install-test.sh\n```\n\nThis path builds the image, verifies the non-root identity and hardening\nsettings, checks every bundled CLI, and tears down the service. It does not call\nAzure or Vertex AI.\n\nTo test already-authorized F5 lab credentials, opt in explicitly:\n\n```bash\n./scripts/e2e-user-install-test.sh --live\n```\n\nThe live path verifies Azure CLI and Vertex AI access. It reports only pass or\nfail status; it does not print tokens, account identities, tenant or subscription\nnames, project IDs, prompts, or model responses.\n\n## Verify\n\nInspect the running service directly when troubleshooting:\n\n```bash\ndocker compose -f docker-compose.dev.yml exec xcsh-dev id\ndocker compose -f docker-compose.dev.yml exec xcsh-dev xcsh --version\ndocker compose -f docker-compose.dev.yml exec xcsh-dev gcloud --version\ndocker compose -f docker-compose.dev.yml exec xcsh-dev az version\n```\n\nThe identity output must show user and group ID `1000`. The xcsh and cloud CLI\ncommands must exit successfully.\n\n## Clean up\n\nRemove the development service and network:\n\n```bash\ndocker compose -f docker-compose.dev.yml down --remove-orphans\n```\n\nThe test scripts perform the same teardown automatically on success, failure,\nor interruption.\n\n## Localized documentation\n\nAuthor container documentation in English under `docs/en/`. Localized files are\nmanaged automation output and are refreshed only for an eligible major release\nunless an exceptional translation run is explicitly requested. Expected locale\ndrift during ordinary English development is not a blocking failure.\n",
|
|
122
123
|
"en/extensions/extension-loading.md": "---\ntitle: Extension Loading (TypeScript/JavaScript Modules)\ndescription: TypeScript and JavaScript module loading pipeline for extensions with resolution, validation, and caching.\nsidebar:\n order: 2\n label: Extension loading\n---\n\n# Extension Loading (TypeScript/JavaScript Modules)\n\nThis document covers how the coding agent discovers and loads **extension modules** (`.ts`/`.js`) at startup.\n\nIt does **not** cover `gemini-extension.json` manifest extensions (documented separately).\n\n## What this subsystem does\n\nExtension loading builds a list of module entry files, imports each module with Bun, executes its factory, and returns:\n\n- loaded extension definitions\n- per-path load errors (without aborting the whole load)\n- a shared extension runtime object used later by `ExtensionRunner`\n\n## Primary implementation files\n\n- `src/extensibility/extensions/loader.ts` — path discovery + import/execution\n- `src/extensibility/extensions/index.ts` — public exports\n- `src/extensibility/extensions/runner.ts` — runtime/event execution after load\n- `src/discovery/builtin.ts` — native auto-discovery provider for extension modules\n- `src/config/settings.ts` — loads merged `extensions` / `disabledExtensions` settings\n\n---\n\n## Inputs to extension loading\n\n### 1) Auto-discovered native extension modules\n\n`discoverAndLoadExtensions()` first asks discovery providers for `extension-module` capability items, then keeps only provider `native` items.\n\nEffective native locations:\n\n- Project: `<cwd>/.xcsh/extensions`\n- User: `~/.xcsh/agent/extensions`\n\nPath roots come from the native provider (`SOURCE_PATHS.native`).\n\nNotes:\n\n- Native auto-discovery is currently `.xcsh` based.\n- Legacy `.pi` is still accepted in `package.json` manifest keys (`pi.extensions`), but not as a native root here.\n\n### 2) Explicitly configured paths\n\nAfter auto-discovery, configured paths are appended and resolved.\n\nConfigured path sources in the main session startup path (`sdk.ts`):\n\n1. CLI-provided paths (`--extension/-e`, and `--hook` is also treated as an extension path)\n2. Settings `extensions` array (merged global + project settings)\n\nGlobal settings file:\n\n- `~/.xcsh/agent/config.yml` (or custom agent dir via `PI_CODING_AGENT_DIR`)\n\nProject settings file:\n\n- `<cwd>/.xcsh/settings.json`\n\nExamples:\n\n```yaml\n# ~/.xcsh/agent/config.yml\nextensions:\n - ~/my-exts/safety.ts\n - ./local/ext-pack\n```\n\n```json\n{\n \"extensions\": [\"./.xcsh/extensions/my-extra\"]\n}\n```\n\n---\n\n## Enable/disable controls\n\n### Disable discovery\n\n- CLI: `--no-extensions`\n- SDK option: `disableExtensionDiscovery`\n\nBehavior split:\n\n- SDK: when `disableExtensionDiscovery=true`, it still loads `additionalExtensionPaths` via `loadExtensions()`.\n- CLI path building (`main.ts`) currently clears CLI extension paths when `--no-extensions` is set, so explicit `-e/--hook` are not forwarded in that mode.\n\n### Disable specific extension modules\n\n`disabledExtensions` setting filters by extension id format:\n\n- `extension-module:<derivedName>`\n\n`derivedName` is based on entry path (`getExtensionNameFromPath`), for example:\n\n- `/x/foo.ts` -> `foo`\n- `/x/bar/index.ts` -> `bar`\n\nExample:\n\n```yaml\ndisabledExtensions:\n - extension-module:foo\n```\n\n---\n\n## Path and entry resolution\n\n### Path normalization\n\nFor configured paths:\n\n1. Normalize unicode spaces\n2. Expand `~`\n3. If relative, resolve against current `cwd`\n\n### If configured path is a file\n\nIt is used directly as a module entry candidate.\n\n### If configured path is a directory\n\nResolution order:\n\n1. `package.json` in that directory with `xcsh.extensions` (or legacy `pi.extensions`) -> use declared entries\n2. `index.ts`\n3. `index.js`\n4. Otherwise scan one level for extension entries:\n - direct `*.ts` / `*.js`\n - subdir `index.ts` / `index.js`\n - subdir `package.json` with `xcsh.extensions` / `pi.extensions`\n\nRules and constraints:\n\n- no recursive discovery beyond one subdirectory level\n- declared `extensions` manifest entries are resolved relative to that package directory\n- declared entries are included only if file exists/access is allowed\n- in `*/index.{ts,js}` pairs, TypeScript is preferred over JavaScript\n- symlinks are treated as eligible files/directories\n\n### Ignore behavior differs by source\n\n- Native auto-discovery (`discoverExtensionModulePaths` in discovery helpers) uses native glob with `gitignore: true` and `hidden: false`.\n- Explicit configured directory scanning in `loader.ts` uses `readdir` rules and does **not** apply gitignore filtering.\n\n---\n\n## Load order and precedence\n\n`discoverAndLoadExtensions()` builds one ordered list and then calls `loadExtensions()`.\n\nOrder:\n\n1. Native auto-discovered modules\n2. Explicit configured paths (in provided order)\n\nIn `sdk.ts`, configured order is:\n\n1. CLI additional paths\n2. Settings `extensions`\n\nDe-duplication:\n\n- absolute path based\n- first seen path wins\n- later duplicates are ignored\n\nImplication: if the same module path is both auto-discovered and explicitly configured, it is loaded once at the first position (auto-discovered stage).\n\n---\n\n## Module import and factory contract\n\nEach candidate path is loaded with dynamic import:\n\n- `await import(resolvedPath)`\n- factory is `module.default ?? module`\n- factory must be a function (`ExtensionFactory`)\n\nIf export is not a function, that path fails with a structured error and loading continues.\n\n---\n\n## Failure handling and isolation\n\n### During loading\n\nPer extension path, failures are captured as `{ path, error }` and do not stop other paths from loading.\n\nCommon cases:\n\n- import failure / missing file\n- invalid factory export (non-function)\n- exception thrown while executing factory\n\n### Runtime isolation model\n\n- Extensions are **not sandboxed** (same process/runtime).\n- They share one `EventBus` and one `ExtensionRuntime` instance.\n- During load, runtime action methods intentionally throw `ExtensionRuntimeNotInitializedError`; action wiring happens later in `ExtensionRunner.initialize()`.\n\n### After loading\n\nWhen events run through `ExtensionRunner`, handler exceptions are caught and emitted as extension errors instead of crashing the runner loop.\n\n---\n\n## Minimal user/project layout examples\n\n### User-level\n\n```text\n~/.xcsh/agent/\n config.yml\n extensions/\n guardrails.ts\n audit/\n index.ts\n```\n\n### Project-level\n\n```text\n<repo>/\n .xcsh/\n settings.json\n extensions/\n checks/\n package.json\n lint-gates.ts\n```\n\n`checks/package.json`:\n\n```json\n{\n \"xcsh\": {\n \"extensions\": [\"./src/check-a.ts\", \"./src/check-b.js\"]\n }\n}\n```\n\nLegacy manifest key still accepted:\n\n```json\n{\n \"pi\": {\n \"extensions\": [\"./index.ts\"]\n }\n}\n```\n",
|
|
123
124
|
"en/extensions/extensions.md": "---\ntitle: Extensions\ndescription: Extension runtime overview covering types, runner lifecycle, registration, and discovery.\nsidebar:\n order: 1\n label: Overview\n---\n\n# Extensions\n\nPrimary guide for authoring runtime extensions in `packages/coding-agent`.\n\nThis document covers the current extension runtime in:\n\n- `src/extensibility/extensions/types.ts`\n- `src/extensibility/extensions/runner.ts`\n- `src/extensibility/extensions/wrapper.ts`\n- `src/extensibility/extensions/index.ts`\n- `src/modes/controllers/extension-ui-controller.ts`\n\nFor discovery paths and filesystem loading rules, see `docs/extension-loading.md`.\n\n## What an extension is\n\nAn extension is a TS/JS module exporting a default factory:\n\n```ts\nimport type { ExtensionAPI } from \"@f5-sales-demo/xcsh\";\n\nexport default function myExtension(pi: ExtensionAPI) {\n // register handlers/tools/commands/renderers\n}\n```\n\nExtensions can combine all of the following in one module:\n\n- event handlers (`pi.on(...)`)\n- LLM-callable tools (`pi.registerTool(...)`)\n- slash commands (`pi.registerCommand(...)`)\n- keyboard shortcuts and flags\n- custom message rendering\n- session/message injection APIs (`sendMessage`, `sendUserMessage`, `appendEntry`)\n\n## Runtime model\n\n1. Extensions are imported and their factory functions run.\n2. During that load phase, registration methods are valid; runtime action methods are not yet initialized.\n3. `ExtensionRunner.initialize(...)` wires live actions/contexts for the active mode.\n4. Session/agent/tool lifecycle events are emitted to handlers.\n5. Every tool execution is wrapped with extension interception (`tool_call` / `tool_result`).\n\n```text\nExtension lifecycle (simplified)\n\nload paths\n │\n ▼\nimport module + run factory (registration only)\n │\n ▼\nExtensionRunner.initialize(mode/session/tool registry)\n │\n ├─ emit session/agent events to handlers\n ├─ wrap tool execution (tool_call/tool_result)\n └─ expose runtime actions (sendMessage, setActiveTools, ...)\n```\n\nImportant constraint from `loader.ts`:\n\n- calling action methods like `pi.sendMessage()` during extension load throws `ExtensionRuntimeNotInitializedError`\n- register first; perform runtime behavior from events/commands/tools\n\n## Quick start\n\n```ts\nimport type { ExtensionAPI } from \"@f5-sales-demo/xcsh\";\nimport { Type } from \"@sinclair/typebox\";\n\nexport default function (pi: ExtensionAPI) {\n pi.setLabel(\"Safety + Utilities\");\n\n pi.on(\"session_start\", async (_event, ctx) => {\n ctx.ui.notify(`Extension loaded in ${ctx.cwd}`, \"info\");\n });\n\n pi.on(\"tool_call\", async (event) => {\n if (event.toolName === \"bash\" && event.input.command?.includes(\"rm -rf\")) {\n return { block: true, reason: \"Blocked by extension policy\" };\n }\n });\n\n pi.registerTool({\n name: \"hello_extension\",\n label: \"Hello Extension\",\n description: \"Return a greeting\",\n parameters: Type.Object({ name: Type.String() }),\n async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {\n return {\n content: [{ type: \"text\", text: `Hello, ${params.name}` }],\n details: { greeted: params.name },\n };\n },\n });\n\n pi.registerCommand(\"hello-ext\", {\n description: \"Show queue state\",\n handler: async (_args, ctx) => {\n ctx.ui.notify(`pending=${ctx.hasPendingMessages()}`, \"info\");\n },\n });\n}\n```\n\n## Extension API surfaces\n\n## 1) Registration and actions (`ExtensionAPI`)\n\nCore methods:\n\n- `on(event, handler)`\n- `registerTool`, `registerCommand`, `registerShortcut`, `registerFlag`\n- `registerMessageRenderer`\n- `sendMessage`, `sendUserMessage`, `appendEntry`\n- `getActiveTools`, `getAllTools`, `setActiveTools`\n- `getSessionName`, `setSessionName`\n- `setModel`, `getThinkingLevel`, `setThinkingLevel`\n- `registerProvider`\n- `events` (shared event bus)\n\nIn interactive mode, `input` handlers run before the built-in first-message auto-title check. Extensions that call `await pi.setSessionName(...)` from `input` can set the persisted session name and prevent the default auto-generated title from running for that session.\n\nAlso exposed:\n\n- `pi.logger`\n- `pi.typebox`\n- `pi.pi` (package exports)\n\n### Message delivery semantics\n\n`pi.sendMessage(message, options)` supports:\n\n- `deliverAs: \"steer\"` (default) — interrupts current run\n- `deliverAs: \"followUp\"` — queued to run after current run\n- `deliverAs: \"nextTurn\"` — stored and injected on the next user prompt\n- `triggerTurn: true` — starts a turn when idle (`nextTurn` ignores this)\n\n`pi.sendUserMessage(content, { deliverAs })` always goes through prompt flow; while streaming it queues as steer/follow-up.\n\n## 2) Handler context (`ExtensionContext`)\n\nHandlers and tool `execute` receive `ctx` with:\n\n- `ui`\n- `hasUI`\n- `cwd`\n- `sessionManager` (read-only)\n- `modelRegistry`, `model`\n- `getContextUsage()`\n- `compact(...)`\n- `isIdle()`, `hasPendingMessages()`, `abort()`\n- `shutdown()`\n- `getSystemPrompt()`\n\n## 3) Command context (`ExtensionCommandContext`)\n\nCommand handlers additionally get:\n\n- `waitForIdle()`\n- `newSession(...)`\n- `switchSession(...)`\n- `branch(entryId)`\n- `navigateTree(targetId, { summarize })`\n- `reload()`\n\nUse command context for session-control flows; these methods are intentionally separated from general event handlers.\n\n## Event surface (current names and behavior)\n\nCanonical event unions and payload types are in `types.ts`.\n\n### Session lifecycle\n\n- `session_start`\n- `session_before_switch` / `session_switch`\n- `session_before_branch` / `session_branch`\n- `session_before_compact` / `session.compacting` / `session_compact`\n- `session_before_tree` / `session_tree`\n- `session_shutdown`\n\nCancelable pre-events:\n\n- `session_before_switch` → `{ cancel?: boolean }`\n- `session_before_branch` → `{ cancel?: boolean; skipConversationRestore?: boolean }`\n- `session_before_compact` → `{ cancel?: boolean; compaction?: CompactionResult }`\n- `session_before_tree` → `{ cancel?: boolean; summary?: { summary: string; details?: unknown } }`\n\n### Prompt and turn lifecycle\n\n- `input`\n- `before_agent_start`\n- `context`\n- `agent_start` / `agent_end`\n- `turn_start` / `turn_end`\n- `message_start` / `message_update` / `message_end`\n\n### Tool lifecycle\n\n- `tool_call` (pre-exec, may block)\n- `tool_result` (post-exec, may patch content/details/isError)\n- `tool_execution_start` / `tool_execution_update` / `tool_execution_end` (observability)\n\n`tool_result` is middleware-style: handlers run in extension order and each sees prior modifications.\n\n### Reliability/runtime signals\n\n- `auto_compaction_start` / `auto_compaction_end`\n- `auto_retry_start` / `auto_retry_end`\n- `ttsr_triggered`\n- `todo_reminder`\n\n### User command interception\n\n- `user_bash` (override with `{ result }`)\n- `user_python` (override with `{ result }`)\n\n### `resources_discover`\n\n`resources_discover` exists in extension types and `ExtensionRunner`.\nCurrent runtime note: `ExtensionRunner.emitResourcesDiscover(...)` is implemented, but there are no `AgentSession` callsites invoking it in the current codebase.\n\n## Tool authoring details\n\n`registerTool` uses `ToolDefinition` from `types.ts`.\n\nCurrent `execute` signature:\n\n```ts\nexecute(\n toolCallId,\n params,\n signal,\n onUpdate,\n ctx,\n): Promise<AgentToolResult>\n```\n\nTemplate:\n\n```ts\npi.registerTool({\n name: \"my_tool\",\n label: \"My Tool\",\n description: \"...\",\n parameters: Type.Object({}),\n async execute(_id, _params, signal, onUpdate, ctx) {\n if (signal?.aborted) {\n return { content: [{ type: \"text\", text: \"Cancelled\" }] };\n }\n onUpdate?.({ content: [{ type: \"text\", text: \"Working...\" }] });\n return { content: [{ type: \"text\", text: \"Done\" }], details: {} };\n },\n onSession(event, ctx) {\n // reason: start|switch|branch|tree|shutdown\n },\n renderCall(args, theme) {\n // optional TUI render\n },\n renderResult(result, options, theme, args) {\n // optional TUI render\n },\n});\n```\n\n`tool_call`/`tool_result` intercept all tools once the registry is wrapped in `sdk.ts`, including built-ins and extension/custom tools.\n\n## UI integration points\n\n`ctx.ui` implements the `ExtensionUIContext` interface. Support differs by mode.\n\n### Interactive mode (`extension-ui-controller.ts`)\n\nSupported:\n\n- dialogs: `select`, `confirm`, `input`, `editor`\n- notifications/status/editor text/terminal input/custom overlays\n- theme listing/loading by name (`setTheme` supports string names)\n- tools expanded toggle\n\nCurrent no-op methods in this controller:\n\n- `setFooter`\n- `setHeader`\n- `setEditorComponent`\n\nAlso note: `setWidget` currently routes to status-line text via `setHookWidget(...)`.\n\n### RPC mode (`rpc-mode.ts`)\n\n`ctx.ui` is backed by RPC `extension_ui_request` events:\n\n- dialog methods (`select`, `confirm`, `input`, `editor`) round-trip to client responses\n- fire-and-forget methods emit requests (`notify`, `setStatus`, `setWidget` for string arrays, `setTitle`, `setEditorText`)\n\nUnsupported/no-op in RPC implementation:\n\n- `onTerminalInput`\n- `custom`\n- `setFooter`, `setHeader`, `setEditorComponent`\n- `setWorkingMessage`\n- theme switching/loading (`setTheme` returns failure)\n- tool expansion controls are inert\n\n### Print/headless/subagent paths\n\nWhen no UI context is supplied to runner init, `ctx.hasUI` is `false` and methods are no-op/default-returning.\n\n### Background interactive mode\n\nBackground mode installs a non-interactive UI context object. In current implementation, `ctx.hasUI` may still be `true` while interactive dialogs return defaults/no-op behavior.\n\n## Session and state patterns\n\nFor durable extension state:\n\n1. Persist with `pi.appendEntry(customType, data)`.\n2. Rebuild state from `ctx.sessionManager.getBranch()` on `session_start`, `session_branch`, `session_tree`.\n3. Keep tool result `details` structured when state should be visible/reconstructible from tool result history.\n\nExample reconstruction pattern:\n\n```ts\npi.on(\"session_start\", async (_event, ctx) => {\n let latest;\n for (const entry of ctx.sessionManager.getBranch()) {\n if (entry.type === \"custom\" && entry.customType === \"my-state\") {\n latest = entry.data;\n }\n }\n // restore from latest\n});\n```\n\n## Rendering extension points\n\n## Custom message renderer\n\n```ts\npi.registerMessageRenderer(\"my-type\", (message, { expanded }, theme) => {\n // return pi-tui Component\n});\n```\n\nUsed by interactive rendering when custom messages are displayed.\n\n## Tool call/result renderer\n\nProvide `renderCall` / `renderResult` on `registerTool` definitions for custom tool visualization in TUI.\n\n## Constraints and pitfalls\n\n- Runtime actions are unavailable during extension load.\n- `tool_call` errors block execution (fail-closed).\n- Command name conflicts with built-ins are skipped with diagnostics.\n- Reserved shortcuts are ignored (`ctrl+c`, `ctrl+d`, `ctrl+z`, `ctrl+k`, `ctrl+p`, `ctrl+l`, `ctrl+o`, `ctrl+t`, `ctrl+g`, `shift+tab`, `shift+ctrl+p`, `alt+enter`, `escape`, `enter`).\n- Treat `ctx.reload()` as terminal for the current command handler frame.\n\n## Extensions vs hooks vs custom-tools\n\nUse the right surface:\n\n- **Extensions** (`src/extensibility/extensions/*`): unified system (events + tools + commands + renderers + provider registration).\n- **Hooks** (`src/extensibility/hooks/*`): separate legacy event API.\n- **Custom-tools** (`src/extensibility/custom-tools/*`): tool-focused modules; when loaded alongside extensions they are adapted and still pass through extension interception wrappers.\n\nIf you need one package that owns policy, tools, command UX, and rendering together, use extensions.\n",
|
|
124
125
|
"en/extensions/gemini-manifest-extensions.md": "---\ntitle: Gemini Manifest Extensions\ndescription: Gemini manifest extension format for cross-platform skill and agent compatibility.\nsidebar:\n order: 7\n label: Gemini manifest\n---\n\n# Gemini Manifest Extensions (`gemini-extension.json`)\n\nThis document covers how the coding-agent discovers and parses Gemini-style manifest extensions (`gemini-extension.json`) into the `extensions` capability.\n\nIt does **not** cover TypeScript/JavaScript extension module loading (`extensions/*.ts`, `index.ts`, `package.json xcsh.extensions`), which is documented in `extension-loading.md`.\n\n## Implementation files\n\n- [`../src/discovery/gemini.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/discovery/gemini.ts)\n- [`../src/discovery/builtin.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/discovery/builtin.ts)\n- [`../src/discovery/helpers.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/discovery/helpers.ts)\n- [`../src/capability/extension.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/capability/extension.ts)\n- [`../src/capability/index.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/capability/index.ts)\n- [`../src/extensibility/extensions/loader.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/extensibility/extensions/loader.ts)\n\n---\n\n## What gets discovered\n\nThe Gemini provider (`id: gemini`, priority `60`) registers an `extensions` loader that scans two fixed roots:\n\n- User: `~/.gemini/extensions`\n- Project: `<cwd>/.gemini/extensions`\n\nPath resolution is direct from `ctx.home` and `ctx.cwd` via `getUserPath()` / `getProjectPath()`.\n\nImportant scope rule: project lookup is **cwd-only**. It does not walk parent directories.\n\n---\n\n## Directory scan rules\n\nFor each root (`~/.gemini/extensions` and `<cwd>/.gemini/extensions`), discovery does:\n\n1. `readDirEntries(root)`\n2. keep only direct child directories (`entry.isDirectory()`)\n3. for each child `<name>`, attempt to read exactly:\n - `<root>/<name>/gemini-extension.json`\n\nThere is no recursive scan beyond one directory level.\n\n### Hidden directories\n\nGemini manifest discovery does **not** filter out dot-prefixed directory names. If a hidden child directory exists and contains `gemini-extension.json`, it is considered.\n\n### Missing/unreadable files\n\nIf `gemini-extension.json` is missing or unreadable, that directory is skipped silently (no warning).\n\n---\n\n## Manifest shape (as implemented)\n\nThe capability type defines this manifest shape:\n\n```ts\ninterface ExtensionManifest {\n name?: string;\n description?: string;\n mcpServers?: Record<string, Omit<MCPServer, \"name\" | \"_source\">>;\n tools?: unknown[];\n context?: unknown;\n}\n```\n\nDiscovery-time behavior is intentionally loose:\n\n- JSON parse success is required.\n- There is no runtime schema validation for field types/content beyond JSON syntax.\n- The parsed object is stored as `manifest` on the capability item.\n\n### Name normalization\n\n`Extension.name` is set to:\n\n1. `manifest.name` if it is not `null`/`undefined`\n2. otherwise the extension directory name\n\nNo string-type enforcement is applied here.\n\n---\n\n## Materialization into capability items\n\nA valid parsed manifest creates one `Extension` capability item:\n\n```ts\n{\n name: manifest.name ?? <directory-name>,\n path: <extension-directory>,\n manifest: <parsed-json>,\n level: \"user\" | \"project\",\n _source: {\n provider: \"gemini\",\n providerName: \"Gemini CLI\" // attached by capability registry\n path: <absolute-manifest-path>,\n level: \"user\" | \"project\"\n }\n}\n```\n\nNotes:\n\n- `_source.path` is normalized to an absolute path by `createSourceMeta()`.\n- Registry-level capability validation for `extensions` only checks presence of `name` and `path`.\n- Manifest internals (`mcpServers`, `tools`, `context`) are not validated during discovery.\n\n---\n\n## Error handling and warning semantics\n\n### Warned\n\n- Invalid JSON in a manifest file:\n - warning format: `Invalid JSON in <manifestPath>`\n\n### Not warned (silent skip)\n\n- `extensions` directory missing\n- child directory has no `gemini-extension.json`\n- unreadable manifest file\n- manifest JSON is syntactically valid but semantically odd/incomplete\n\nThis means partial validity is accepted: only syntactic JSON failure emits a warning.\n\n---\n\n## Precedence and deduplication with other sources\n\n`extensions` capability is aggregated across providers by the capability registry.\n\nCurrent providers for this capability:\n\n- `native` (`packages/coding-agent/src/discovery/builtin.ts`) priority `100`\n- `gemini` (`packages/coding-agent/src/discovery/gemini.ts`) priority `60`\n\nDedup key is `ext.name` (`extensionCapability.key = ext => ext.name`).\n\n### Cross-provider precedence\n\nHigher-priority provider wins on duplicate extension names.\n\n- If `native` and `gemini` both emit extension name `foo`, the native item is kept.\n- Lower-priority duplicate is retained only in `result.all` with `_shadowed = true`.\n\n### Intra-provider order effects\n\nBecause dedup is “first seen wins”, provider-local item order matters.\n\n- Gemini loader appends **user first**, then **project**.\n- Therefore, duplicate names between `~/.gemini/extensions` and `<cwd>/.gemini/extensions` keep the user entry and shadow the project entry.\n\nBy contrast, native provider builds config dir order differently (`project` then `user` in `getConfigDirs()`), so native intra-provider shadowing is the opposite direction.\n\n---\n\n## User vs project behavior summary\n\nFor Gemini manifests specifically:\n\n- Both user and project roots are scanned every load.\n- Project root is fixed to `<cwd>/.gemini/extensions` (no ancestor walk).\n- Duplicate names inside Gemini source resolve to user-first.\n- Duplicate names against higher-priority providers (notably native) lose by priority.\n\n---\n\n## Boundary: discovery metadata vs runtime extension loading\n\n`gemini-extension.json` discovery currently feeds capability metadata (`Extension` items). It does **not** directly load runnable TS/JS extension modules.\n\nRuntime module loading (`discoverAndLoadExtensions()` / `loadExtensions()`) uses `extension-modules` and explicit paths, and currently filters auto-discovered modules to provider `native` only.\n\nPractical implication:\n\n- Gemini manifest extensions are discoverable as capability records.\n- They are not, by themselves, executed as runtime extension modules by the extension loader pipeline.\n\nThis boundary is intentional in current implementation and explains why manifest discovery and executable module loading can diverge.\n",
|
|
@@ -126,7 +127,7 @@ export const EMBEDDED_DOCS: Readonly<Record<string, string>> = {
|
|
|
126
127
|
"en/extensions/plugin-manager-installer-plumbing.md": "---\ntitle: Plugin Manager and Installer Plumbing\ndescription: Plugin manager internals covering installation, validation, dependency resolution, and lifecycle management.\nsidebar:\n order: 5\n label: Plugin manager\n---\n\n# Plugin manager and installer plumbing\n\nThis document describes how `xcsh plugin` operations mutate plugin state on disk and how installed plugins become runtime capabilities (tools today, hooks/commands path resolution available).\n\n## Scope and architecture\n\nThere are two plugin-management implementations in the codebase:\n\n1. **Active path used by CLI commands**: `PluginManager` (`src/extensibility/plugins/manager.ts`)\n2. **Legacy helper module**: installer functions (`src/extensibility/plugins/installer.ts`)\n\n`xcsh plugin ...` command execution goes through `PluginManager`.\n\n`installer.ts` still documents important safety checks and filesystem behavior, but it is not the path used by `src/commands/plugin.ts` + `src/cli/plugin-cli.ts`.\n\n## Lifecycle: from CLI invocation to runtime availability\n\n```text\nxcsh plugin <action> ...\n -> src/commands/plugin.ts\n -> runPluginCommand(...) in src/cli/plugin-cli.ts\n -> PluginManager method (install/list/uninstall/link/...) \n -> mutate ~/.xcsh/plugins/{package.json,node_modules,xcsh-plugins.lock.json}\n -> runtime discovery: discoverAndLoadCustomTools(...)\n -> getAllPluginToolPaths(cwd)\n -> custom tool loader imports tool modules\n```\n\n### Command entrypoints\n\n- `src/commands/plugin.ts` defines command/flags and forwards to `runPluginCommand`.\n- `src/cli/plugin-cli.ts` maps subcommands to `PluginManager` methods:\n - `install`, `uninstall`, `list`, `link`, `doctor`, `features`, `config`, `enable`, `disable`\n- No explicit `update` action exists; update is done by re-running `install` with a new package/version spec.\n\n## On-disk model\n\nGlobal plugin state lives under `~/.xcsh/plugins`:\n\n- `package.json` — dependency manifest used by `bun install`/`bun uninstall`\n- `node_modules/` — installed plugin packages or symlinks\n- `xcsh-plugins.lock.json` — runtime state:\n - enabled/disabled per plugin\n - selected feature set per plugin\n - persisted plugin settings\n\nProject-local overrides live at:\n\n- `<cwd>/.xcsh/plugin-overrides.json`\n\nOverrides are read-only from manager/loader perspective (no write path here) and can disable plugins or override features/settings for this project.\n\n## Plugin spec parsing and metadata interpretation\n\n## Install spec grammar\n\n`parsePluginSpec` (`parser.ts`) supports:\n\n- `pkg` -> `features: null` (defaults behavior)\n- `pkg[*]` -> enable all manifest features\n- `pkg[]` -> enable no optional features\n- `pkg[a,b]` -> enable named features\n- `@scope/pkg@1.2.3[feat]` -> scoped + versioned package with explicit feature selection\n\n`extractPackageName` strips version suffix for on-disk path lookup after install.\n\n## Manifest source and required fields\n\nManifest is resolved as:\n\n1. `package.json.xcsh`\n2. fallback `package.json.pi`\n3. fallback `{ version: package.version }`\n\nImplications:\n\n- There is no strict schema validation in manager/loader.\n- A package missing `xcsh`/`pi` is still installable and listable.\n- Runtime plugin loading (`getEnabledPlugins`) skips packages without `xcsh`/`pi` manifest.\n- `manifest.version` is always overwritten from package `version`.\n\nMalformed `package.json` JSON is a hard failure at read time; malformed manifest shape may fail later only when specific fields are consumed.\n\n## Install/update flow (`PluginManager.install`)\n\n1. Parse feature bracket syntax from install spec.\n2. Validate package name against regex + shell-metacharacter denylist.\n3. Ensure plugin `package.json` exists (`xcsh-plugins`, private dependencies map).\n4. Run `bun install <packageSpec>` in `~/.xcsh/plugins`.\n5. Read installed package `node_modules/<name>/package.json`.\n6. Resolve manifest and compute `enabledFeatures`:\n - `[*]`: all declared features (or `null` if no feature map)\n - `[a,b]`: validates each feature exists in manifest features map\n - `[]`: empty feature list\n - bare spec: `null` (use defaults policy later in loader)\n7. Upsert lockfile runtime state: `{ version, enabledFeatures, enabled: true }`.\n\n### Update semantics\n\nBecause update is install-driven:\n\n- `xcsh plugin install pkg@newVersion` updates dependency and lockfile version.\n- Existing settings are preserved; state entry is overwritten for version/features/enabled.\n- No separate “check updates” or transactional migration logic exists.\n\n## Remove flow (`PluginManager.uninstall`)\n\n1. Validate package name.\n2. Run `bun uninstall <name>` in plugin dir.\n3. Remove plugin runtime state from lockfile:\n - `config.plugins[name]`\n - `config.settings[name]`\n\nIf uninstall command fails, runtime state is not changed.\n\n## List flow (`PluginManager.list`)\n\n1. Read plugin dependency map from `~/.xcsh/plugins/package.json`.\n2. Load lockfile runtime config (missing file -> empty defaults).\n3. Load project overrides (`<cwd>/.xcsh/plugin-overrides.json`, parse/read errors -> empty object with warning).\n4. For each dependency with a resolvable package.json:\n - build `InstalledPlugin` record\n - merge feature/enable state:\n - base from lockfile (or defaults)\n - project overrides can replace feature selection\n - project `disabled` list masks plugin as disabled\n\nThis is the effective state used by CLI status output and settings/features operations.\n\n## Link flow (`PluginManager.link`)\n\n`link` supports local plugin development by symlinking a local package into `~/.xcsh/plugins/node_modules/<pkg.name>`.\n\nBehavior:\n\n1. Resolve `localPath` against manager cwd.\n2. Require local `package.json` and `name` field.\n3. Ensure plugin dirs exist.\n4. For scoped names, create scope directory.\n5. Remove existing path at target link location.\n6. Create symlink.\n7. Add runtime lockfile entry enabled with default features (`null`).\n\nCaveat: current `PluginManager.link` does not enforce the `cwd` path-boundary check present in legacy `installer.ts` (`normalizedPath.startsWith(normalizedCwd)`), so trust is the caller’s responsibility.\n\n## Runtime loading: from installed plugin to callable capabilities\n\n## Discovery gate\n\n`getEnabledPlugins(cwd)` (`plugins/loader.ts`) reads:\n\n- plugin dependency manifest (`package.json`)\n- lockfile runtime state\n- project overrides via `getConfigDirPaths(\"plugin-overrides.json\", { user: false, cwd })`\n\nFiltering:\n\n- skip if no plugin package.json\n- skip if manifest (`xcsh`/`pi`) absent\n- skip if globally disabled in lockfile\n- skip if project-disabled\n\n## Capability path resolution\n\nFor each enabled plugin:\n\n- `resolvePluginToolPaths(plugin)`\n- `resolvePluginHookPaths(plugin)`\n- `resolvePluginCommandPaths(plugin)`\n\nEach resolver includes base entries plus feature entries:\n\n- explicit feature list -> only selected features\n- `enabledFeatures === null` -> enable features marked `default: true`\n\nMissing files are silently skipped (`existsSync` guard).\n\n## Current runtime wiring differences\n\n- **Tools are wired into runtime today** via `discoverAndLoadCustomTools` (`custom-tools/loader.ts`), which calls `getAllPluginToolPaths(cwd)`.\n- Paths are de-duplicated by resolved absolute path in custom tool discovery (`seen` set, first path wins).\n- **Hooks/commands resolvers exist** and are exported, but this code path does not currently wire them into a runtime registry in the same way tools are wired.\n\n## Lock/state management details\n\n`PluginManager` caches runtime config in memory per instance (`#runtimeConfig`) and lazily loads once.\n\nLoad behavior:\n\n- lockfile missing -> `{ plugins: {}, settings: {} }`\n- lockfile read/parse failure -> warning + same empty defaults\n\nSave behavior:\n\n- writes full lockfile JSON pretty-printed each mutation\n\nNo cross-process locking or merge strategy exists; concurrent writers can overwrite each other.\n\n## Safety checks and trust boundaries\n\n## Input/package validation\n\nActive manager path enforces package-name validation:\n\n- regex for scoped/unscoped package specs (optionally with version)\n- explicit shell metacharacter denylist (`[;&|`$(){}[]<>\\\\]`)\n\nThis limits command-injection risk when invoking `bun install/uninstall`.\n\n## Filesystem trust boundary\n\n- Plugin code executes in-process when custom tool modules are imported; no sandboxing.\n- Manifest relative paths are joined against plugin package directory and only existence-checked.\n- The plugin package itself is trusted code once installed.\n\n## Legacy installer-only checks\n\n`installer.ts` includes additional link-time checks not mirrored in `PluginManager.link`:\n\n- local path must resolve inside project cwd\n- extra package name/path traversal guards for symlink target naming\n\nBecause CLI uses `PluginManager`, these stricter link guards are not currently on the main path.\n\n## Failure, partial success, and rollback behavior\n\nThe plugin manager is not transactional.\n\n| Operation stage | Failure behavior | Rollback |\n| --- | --- | --- |\n| `bun install` fails | install aborts with stderr | N/A (no state writes yet) |\n| Install succeeds, then manifest/feature validation fails | command fails | No uninstall rollback; dependency may remain in `node_modules`/`package.json` |\n| Install succeeds, then lockfile write fails | command fails | No rollback of installed package |\n| `bun uninstall` succeeds, lockfile write fails | command fails | Package removed, stale runtime state may remain |\n| `link` removes old target then symlink creation fails | command fails | No restoration of previous link/dir |\n\nOperationally, `doctor --fix` can repair some drift (`bun install`, orphaned config cleanup, invalid-feature cleanup), but it is best-effort.\n\n## Malformed/missing manifest behavior summary\n\n- Missing `xcsh`/`pi` field:\n - install/list: tolerated (minimal manifest)\n - runtime enabled-plugin discovery: skipped as non-plugin\n- Missing feature referenced by install spec or `features --set/--enable`: hard error with available feature list\n- Invalid `plugin-overrides.json`: ignored with fallback to `{}` in both manager and loader paths\n- Missing tool/hook/command file paths referenced by manifest: silently ignored during resolver expansion; flagged as errors only by `doctor`\n\n## Mode differences and precedence\n\n- `--dry-run` (install): returns synthetic install result, no filesystem/network/state writes.\n- `--json`: output formatting only, no behavior change.\n- Project overrides always take precedence over global lockfile for feature/settings view.\n- Effective enablement is `runtimeEnabled && !projectDisabled`.\n\n## Implementation files\n\n- [`src/commands/plugin.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/commands/plugin.ts) — CLI command declaration and flag mapping\n- [`src/cli/plugin-cli.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/cli/plugin-cli.ts) — action dispatch, user-facing command handlers\n- [`src/extensibility/plugins/manager.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/extensibility/plugins/manager.ts) — active install/remove/list/link/state/doctor implementation\n- [`src/extensibility/plugins/installer.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/extensibility/plugins/installer.ts) — legacy installer helpers and additional link safety checks\n- [`src/extensibility/plugins/loader.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/extensibility/plugins/loader.ts) — enabled-plugin discovery and tool/hook/command path resolution\n- [`src/extensibility/plugins/parser.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/extensibility/plugins/parser.ts) — install spec and package-name parsing helpers\n- [`src/extensibility/plugins/types.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/extensibility/plugins/types.ts) — manifest/runtime/override type contracts\n- [`src/extensibility/custom-tools/loader.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/extensibility/custom-tools/loader.ts) — runtime wiring for plugin-provided tool modules\n",
|
|
127
128
|
"en/extensions/rulebook-matching-pipeline.md": "---\ntitle: Rulebook Matching Pipeline\ndescription: Rulebook matching pipeline for selecting and applying context-specific instruction sets to agent sessions.\nsidebar:\n order: 6\n label: Rulebook matching\n---\n\n# Rulebook Matching Pipeline\n\nThis document describes how coding-agent discovers rules from supported config formats, normalizes them into a single `Rule` shape, resolves precedence conflicts, and splits the result into:\n\n- **Rulebook rules** (available to the model via system prompt + `rule://` URLs)\n- **TTSR rules** (time-travel stream interruption rules)\n\nIt reflects the current implementation, including partial semantics and metadata that is parsed but not enforced.\n\n## Implementation files\n\n- [`../src/capability/rule.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/capability/rule.ts)\n- [`../src/capability/index.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/capability/index.ts)\n- [`../src/discovery/index.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/discovery/index.ts)\n- [`../src/discovery/helpers.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/discovery/helpers.ts)\n- [`../src/discovery/builtin.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/discovery/builtin.ts)\n- [`../src/discovery/cursor.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/discovery/cursor.ts)\n- [`../src/discovery/windsurf.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/discovery/windsurf.ts)\n- [`../src/discovery/cline.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/discovery/cline.ts)\n- [`../src/sdk.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/sdk.ts)\n- [`../src/system-prompt.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/system-prompt.ts)\n- [`../src/internal-urls/rule-protocol.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/internal-urls/rule-protocol.ts)\n- [`../src/utils/frontmatter.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/utils/frontmatter.ts)\n\n## 1. Canonical rule shape\n\nAll providers normalize source files into `Rule`:\n\n```ts\ninterface Rule {\n name: string;\n path: string;\n content: string;\n globs?: string[];\n alwaysApply?: boolean;\n description?: string;\n ttsrTrigger?: string;\n _source: SourceMeta;\n}\n```\n\nCapability identity is `rule.name` (`ruleCapability.key = rule => rule.name`).\n\nConsequence: precedence and deduplication are **name-based only**. Two different files with the same `name` are considered the same logical rule.\n\n## 2. Discovery sources and normalization\n\n`src/discovery/index.ts` auto-registers providers. For `rules`, current providers are:\n\n- `native` (priority `100`)\n- `cursor` (priority `50`)\n- `windsurf` (priority `50`)\n- `cline` (priority `40`)\n\n### Native provider (`builtin.ts`)\n\nLoads `.xcsh` rules from:\n\n- project: `<cwd>/.xcsh/rules/*.{md,mdc}`\n- user: `~/.xcsh/agent/rules/*.{md,mdc}`\n\nNormalization:\n\n- `name` = filename without `.md`/`.mdc`\n- frontmatter parsed via `parseFrontmatter`\n- `content` = body (frontmatter stripped)\n- `globs`, `alwaysApply`, `description`, `ttsr_trigger` mapped directly\n\nImportant caveat: `globs` is cast as `string[] | undefined` with no element filtering in this provider.\n\n### Cursor provider (`cursor.ts`)\n\nLoads from:\n\n- user: `~/.cursor/rules/*.{mdc,md}`\n- project: `<cwd>/.cursor/rules/*.{mdc,md}`\n\nNormalization (`transformMDCRule`):\n\n- `description`: kept only if string\n- `alwaysApply`: only `true` is preserved (`false` becomes `undefined`)\n- `globs`: accepts array (string elements only) or single string\n- `ttsr_trigger`: string only\n- `name` from filename without extension\n\n### Windsurf provider (`windsurf.ts`)\n\nLoads from:\n\n- user: `~/.codeium/windsurf/memories/global_rules.md` (fixed rule name `global_rules`)\n- project: `<cwd>/.windsurf/rules/*.md`\n\nNormalization:\n\n- `globs`: array-of-string or single string\n- `alwaysApply`, `description` cast from frontmatter\n- `ttsr_trigger`: string only\n- `name` from filename for project rules\n\n### Cline provider (`cline.ts`)\n\nSearches upward from `cwd` for nearest `.clinerules`:\n\n- if directory: loads `*.md` inside it\n- if file: loads single file as rule named `clinerules`\n\nNormalization:\n\n- `globs`: array-of-string or single string\n- `alwaysApply`: only if boolean\n- `description`: string only\n- `ttsr_trigger`: string only\n\n## 3. Frontmatter parsing behavior and ambiguity\n\nAll providers use `parseFrontmatter` (`utils/frontmatter.ts`) with these semantics:\n\n1. Frontmatter is parsed only when content starts with `---` and has a closing `\\n---`.\n2. Body is trimmed after frontmatter extraction.\n3. If YAML parse fails:\n - warning is logged,\n - parser falls back to simple `key: value` line parsing (`^(\\w+):\\s*(.*)$`).\n\nAmbiguity consequences:\n\n- Fallback parser does not support arrays, nested objects, quoting rules, or hyphenated keys.\n- Fallback values become strings (for example `alwaysApply: true` becomes string `\"true\"`), so providers requiring boolean/string types may drop metadata.\n- `ttsr_trigger` works in fallback (underscore key); keys like `thinking-level` would not.\n- Files without valid frontmatter still load as rules with empty metadata and full content body.\n\n## 4. Provider precedence and deduplication\n\n`loadCapability(\"rules\")` (`capability/index.ts`) merges provider outputs and then deduplicates by `rule.name`.\n\n### Precedence model\n\n- Providers are ordered by priority descending.\n- Equal priority keeps registration order (`cursor` before `windsurf` from `discovery/index.ts`).\n- Dedup is first-wins: first encountered rule name is kept; later same-name items are marked `_shadowed` in `all` and excluded from `items`.\n\nEffective rule provider order is currently:\n\n1. `native` (100)\n2. `cursor` (50)\n3. `windsurf` (50)\n4. `cline` (40)\n\n### Intra-provider ordering caveat\n\nWithin a provider, item order comes from `loadFilesFromDir` glob result ordering plus explicit push order. This is deterministic enough for normal use but not explicitly sorted in code.\n\nNotable source-order differences:\n\n- `native` appends project then user config dirs.\n- `cursor` appends user then project results.\n- `windsurf` appends user `global_rules` first, then project rules.\n- `cline` loads only nearest `.clinerules` source.\n\n## 5. Split into Rulebook, Always-Apply, and TTSR buckets\n\nAfter rule discovery in `createAgentSession` (`sdk.ts`):\n\n1. All discovered rules are scanned.\n2. Rules with `condition` (frontmatter key; `ttsr_trigger` / `ttsrTrigger` accepted as fallback) are registered into `TtsrManager`.\n3. A separate `rulebookRules` list is built with this predicate:\n\n```ts\n!registeredTtsrRuleNames.has(rule.name) && !rule.alwaysApply && !!rule.description\n```\n\n4. An `alwaysApplyRules` list is built:\n\n```ts\n!registeredTtsrRuleNames.has(rule.name) && rule.alwaysApply === true\n```\n\n### Bucket behavior\n\n- **TTSR bucket**: any rule with `condition` (description not required). Takes priority over other buckets.\n- **Always-apply bucket**: `alwaysApply === true`, not TTSR. Full content injected into system prompt. Resolvable via `rule://`.\n- **Rulebook bucket**: must have description, must not be TTSR, must not be `alwaysApply`. Listed in system prompt by name+description; content read on demand via `rule://`.\n- A rule with both `condition` and `alwaysApply` goes to TTSR only (TTSR takes priority).\n- A rule with both `alwaysApply` and `description` goes to always-apply only (not rulebook).\n\n## 6. How metadata affects runtime surfaces\n\n### `description`\n\n- Required for inclusion in rulebook.\n- Rendered in system prompt `<rules>` block.\n- Missing description means rule is not available via `rule://` and not listed in system prompt rules.\n\n### `globs`\n\n- Carried through on `Rule`.\n- Rendered as `<glob>...</glob>` entries in the system prompt rules block.\n- Exposed in rules UI state (`extensions` mode list).\n- **Not enforced for automatic matching in this pipeline.** There is no runtime glob matcher selecting rules by current file/tool target.\n\n### `alwaysApply`\n\n- Parsed and preserved by providers.\n- Used in UI display (`\"always\"` trigger label in extensions state manager).\n- Used as an exclusion condition from `rulebookRules`.\n- **Full rule content is auto-injected into the system prompt** (before the rulebook rules section).\n- Rule is also addressable via `rule://<name>` for re-reading.\n\n### `ttsr_trigger`\n\n- Mapped to `rule.ttsrTrigger`.\n- If present, rule is routed to TTSR manager, not rulebook.\n\n## 7. System prompt inclusion path\n\n`buildSystemPromptInternal` receives both `rules` (rulebook) and `alwaysApplyRules`.\n\nAlways-apply rules are rendered first, injecting their raw content directly into the prompt.\n\nRulebook rules are rendered in a `# Rules` section with:\n\n- `Read rule://<name> when working in matching domain`\n- Each rule's `name`, `description`, and optional `<glob>` list\n\nThis is advisory/contextual: prompt text asks the model to read applicable rules, but code does not enforce glob applicability.\n\n## 8. `rule://` internal URL behavior\n\n`RuleProtocolHandler` is registered with:\n\n```ts\nnew RuleProtocolHandler({ getRules: () => [...rulebookRules, ...alwaysApplyRules] })\n```\n\nImplications:\n\n- `rule://<name>` resolves against both **rulebookRules** and **alwaysApplyRules**.\n- TTSR-only rules and rules with no description and no `alwaysApply` are not addressable via `rule://`.\n- Resolution is exact name match.\n- Unknown names return error listing available rule names.\n- Returned content is raw `rule.content` (frontmatter stripped), content type `text/markdown`.\n\n## 9. Known partial / non-enforced semantics\n\n1. Provider descriptions mention legacy files (`.cursorrules`, `.windsurfrules`), but current loader code paths do not actually read those files.\n2. `globs` metadata is surfaced to prompt/UI but not enforced by rule selection logic.\n3. Rule selection for `rule://` includes rulebook and always-apply rules, but not TTSR-only rules.\n4. Discovery warnings (`loadCapability(\"rules\").warnings`) are produced but `createAgentSession` does not currently surface/log them in this path.\n",
|
|
128
129
|
"en/extensions/skills.md": "---\ntitle: Skills\ndescription: Skills system for registering, discovering, and invoking specialized capabilities in the coding agent.\nsidebar:\n order: 3\n label: Skills\n---\n\n# Skills\n\nSkills are file-backed capability packs discovered at startup and exposed to the model as:\n\n- lightweight metadata in the system prompt (name + description)\n- on-demand content via `read skill://...`\n- optional interactive `/skill:<name>` commands\n\nThis document covers current runtime behavior in `src/extensibility/skills.ts`, `src/discovery/builtin.ts`, `src/internal-urls/skill-protocol.ts`, and `src/discovery/agents-md.ts`.\n\n## What a skill is in this codebase\n\nA discovered skill is represented as:\n\n- `name`\n- `description`\n- `filePath` (the `SKILL.md` path)\n- `baseDir` (skill directory)\n- source metadata (`provider`, `level`, path)\n\nThe runtime only requires `name` and `path` for validity. In practice, matching quality depends on `description` being meaningful.\n\n## Required layout and SKILL.md expectations\n\n### Directory layout\n\nFor provider-based discovery (native/Claude/Codex/Agents/plugin providers), skills are discovered as **one level under `skills/`**:\n\n- `<skills-root>/<skill-name>/SKILL.md`\n\nNested patterns like `<skills-root>/group/<skill>/SKILL.md` are not discovered by provider loaders.\n\nFor `skills.customDirectories`, scanning uses the same non-recursive layout (`*/SKILL.md`).\n\n```text\nProvider-discovered layout (non-recursive under skills/):\n\n<root>/skills/\n ├─ postgres/\n │ └─ SKILL.md ✅ discovered\n ├─ pdf/\n │ └─ SKILL.md ✅ discovered\n └─ team/\n └─ internal/\n └─ SKILL.md ❌ not discovered by provider loaders\n\nCustom-directory scanning is also non-recursive, so nested paths are ignored unless you point `customDirectories` at that nested parent.\n```\n\n### `SKILL.md` frontmatter\n\nSupported frontmatter fields on the skill type:\n\n- `name?: string`\n- `description?: string`\n- `globs?: string[]`\n- `alwaysApply?: boolean`\n- additional keys are preserved as unknown metadata\n\nCurrent runtime behavior:\n\n- `name` defaults to the skill directory name\n- `description` is required for:\n - native `.xcsh` provider skill discovery (`requireDescription: true`)\n - `skills.customDirectories` scans via `scanSkillsFromDir` in `src/discovery/helpers.ts` (non-recursive)\n- non-native providers can load skills without description\n\n## Discovery pipeline\n\n`discoverSkills()` in `src/extensibility/skills.ts` does two passes:\n\n1. **Capability providers** via `loadCapability(\"skills\")`\n2. **Custom directories** via `scanSkillsFromDir(..., { requireDescription: true })` (one-level directory enumeration)\n\nIf `skills.enabled` is `false`, discovery returns no skills.\n\n### Built-in skill providers and precedence\n\nProvider ordering is priority-first (higher wins), then registration order for ties.\n\nCurrent registered skill providers:\n\n1. `native` (priority 100) — `.xcsh` user/project skills via `src/discovery/builtin.ts`\n2. `claude` (priority 80)\n3. priority 70 group (in registration order):\n - `claude-plugins`\n - `agents`\n - `codex`\n\nDedup key is skill name. First item with a given name wins.\n\n### Source toggles and filtering\n\n`discoverSkills()` applies these controls:\n\n- source toggles: `enableCodexUser`, `enableClaudeUser`, `enableClaudeProject`, `enablePiUser`, `enablePiProject`\n- glob filters on skill name:\n - `ignoredSkills` (exclude)\n - `includeSkills` (include allowlist; empty means include all)\n\nFilter order is:\n\n1. source enabled\n2. not ignored\n3. included (if include list present)\n\nFor providers other than codex/claude/native (for example `agents`, `claude-plugins`), enablement currently falls back to: enabled if **any** built-in source toggle is enabled.\n\n### Collision and duplicate handling\n\n- Capability dedup already keeps first skill per name (highest-precedence provider)\n- `extensibility/skills.ts` additionally:\n - de-duplicates identical files by `realpath` (symlink-safe)\n - emits collision warnings when a later skill name conflicts\n - keeps the convenience `discoverSkillsFromDir({ dir, source })` API as a thin adapter over `scanSkillsFromDir`\n- Custom-directory skills are merged after provider skills and follow the same collision behavior\n\n## Runtime usage behavior\n\n### System prompt exposure\n\nSystem prompt construction (`src/system-prompt.ts`) uses discovered skills as follows:\n\n- if `read` tool is available:\n - include discovered skills list in prompt\n- otherwise:\n - omit discovered list\n\nTask tool subagents receive the session's discovered/provided skills list via normal session creation; there is no per-task skill pinning override.\n\n### Interactive `/skill:<name>` commands\n\nIf `skills.enableSkillCommands` is true, interactive mode registers one slash command per discovered skill.\n\n`/skill:<name> [args]` behavior:\n\n- reads the skill file directly from `filePath`\n- strips frontmatter\n- injects skill body as a follow-up custom message\n- appends metadata (`Skill: <path>`, optional `User: <args>`)\n\n## `skill://` URL behavior\n\n`src/internal-urls/skill-protocol.ts` supports:\n\n- `skill://<name>` → resolves to that skill's `SKILL.md`\n- `skill://<name>/<relative-path>` → resolves inside that skill directory\n\n```text\nskill:// URL resolution\n\nskill://pdf\n -> <pdf-base>/SKILL.md\n\nskill://pdf/references/tables.md\n -> <pdf-base>/references/tables.md\n\nGuards:\n- reject absolute paths\n- reject `..` traversal\n- reject any resolved path escaping <pdf-base>\n```\n\nResolution details:\n\n- skill name must match exactly\n- relative paths are URL-decoded\n- absolute paths are rejected\n- path traversal (`..`) is rejected\n- resolved path must remain within `baseDir`\n- missing files return an explicit `File not found` error\n\nContent type:\n\n- `.md` => `text/markdown`\n- everything else => `text/plain`\n\nNo fallback search is performed for missing assets.\n\n## Skills vs XCSH.md, commands, tools, hooks\n\n### Skills vs XCSH.md\n\n- **Skills**: named, optional capability packs selected by task context or explicitly requested\n- **XCSH.md/context files**: persistent instruction files loaded as context-file capability and merged by level/depth rules\n\n`src/discovery/agents-md.ts` specifically walks ancestor directories from `cwd` to discover standalone `XCSH.md` files (up to depth 20), excluding hidden-directory segments.\n\n### Skills vs slash commands\n\n- **Skills**: model-readable knowledge/workflow content\n- **Slash commands**: user-invoked command entry points\n- `/skill:<name>` is a convenience wrapper that injects skill text; it does not change skill discovery semantics\n\n### Skills vs custom tools\n\n- **Skills**: documentation/workflow content loaded through prompt context and `read`\n- **Custom tools**: executable tool APIs callable by the model with schemas and runtime side effects\n\n### Skills vs hooks\n\n- **Skills**: passive content\n- **Hooks**: event-driven runtime interceptors that can block/modify behavior during execution\n\n## Practical authoring guidance tied to discovery logic\n\n- Put each skill in its own directory: `<skills-root>/<skill-name>/SKILL.md`\n- Always include explicit `name` and `description` frontmatter\n- Keep referenced assets under the same skill directory and access with `skill://<name>/...`\n- For nested taxonomy (`team/domain/skill`), point `skills.customDirectories` to the nested parent directory; scanning itself remains non-recursive\n- Avoid duplicate skill names across sources; first match wins by provider precedence\n",
|
|
129
|
-
"en/index.md": "---\ntitle: xcsh Documentation\ndescription: AI-powered development CLI with TypeScript coding agent and Rust native layer for long-lived sessions, MCP support, and platform packaging.\nsidebar:\n order: 0\n label: Overview\n---\n\nxcsh is an AI-powered development CLI with a TypeScript coding agent and a\nRust native layer (`pi-natives`). It extends the open-source\n[`badlogic/pi-mono`](https://github.com/badlogic/pi-mono) line with a\nhardened runtime, long-lived sessions with tree navigation and compaction,\na Python IPython tool, full MCP support, a skills system, and platform\npackaging targeting Linux, macOS, and Windows.\n\n## Where to start\n\n- **[F5 XC Contexts](runtime-tools/context-command)** — connect to F5 Distributed Cloud\n tenants. Create contexts, switch between them, manage namespaces and credentials.\n- **Configuration** — how xcsh discovers, resolves, and layers configuration.\n- **Runtime & Tools** — the bash / notebook / resolve tool runtimes and the\n slash-command surface.\n- **Sessions** — append-only entry log, tree navigation, compaction, and the\n autonomous memory system.\n- **Natives (Rust)** — architecture of the `pi-natives` N-API addon that\n powers shell / PTY / media / search.\n- **MCP** — configuration, protocol internals, runtime lifecycle, and how to\n author servers and tools.\n- **Extensions, Skills & Plugins** — authoring, loading, matching rules, the\n marketplace, and the plugin installer.\n- **Providers & Models** — model configuration, streaming internals, and the\n Python / IPython runtime.\n- **TUI** — theming, the `/tree` command, and integration hooks for\n extensions and custom tools.\n\n## How this doc set is organized\n\nEach top-level group in the sidebar maps to a subsystem of the agent. Within\na group, pages run from \"overview\" to \"internals\" so you can stop reading\nwhen you have enough context for the task at hand.\n",
|
|
130
|
+
"en/index.md": "---\ntitle: xcsh Documentation\ndescription: AI-powered development CLI with TypeScript coding agent and Rust native layer for long-lived sessions, MCP support, and platform packaging.\nsidebar:\n order: 0\n label: Overview\n---\n\nxcsh is an AI-powered development CLI with a TypeScript coding agent and a\nRust native layer (`pi-natives`). It extends the open-source\n[`badlogic/pi-mono`](https://github.com/badlogic/pi-mono) line with a\nhardened runtime, long-lived sessions with tree navigation and compaction,\na Python IPython tool, full MCP support, a skills system, and platform\npackaging targeting Linux, macOS, and Windows.\n\n## Where to start\n\n- **[F5 XC Contexts](runtime-tools/context-command)** — connect to F5 Distributed Cloud\n tenants. Create contexts, switch between them, manage namespaces and credentials.\n- **[Alpine Container Deployment](container/alpine-deployment)** — run `xcsh` inside security-hardened Alpine containers with multi-cloud CLI tool integration.\n- **Configuration** — how xcsh discovers, resolves, and layers configuration.\n- **Runtime & Tools** — the bash / notebook / resolve tool runtimes and the\n slash-command surface.\n- **Sessions** — append-only entry log, tree navigation, compaction, and the\n autonomous memory system.\n- **Natives (Rust)** — architecture of the `pi-natives` N-API addon that\n powers shell / PTY / media / search.\n- **MCP** — configuration, protocol internals, runtime lifecycle, and how to\n author servers and tools.\n- **Extensions, Skills & Plugins** — authoring, loading, matching rules, the\n marketplace, and the plugin installer.\n- **Providers & Models** — model configuration, streaming internals, and the\n Python / IPython runtime.\n- **TUI** — theming, the `/tree` command, and integration hooks for\n extensions and custom tools.\n\n## How this doc set is organized\n\nEach top-level group in the sidebar maps to a subsystem of the agent. Within\na group, pages run from \"overview\" to \"internals\" so you can stop reading\nwhen you have enough context for the task at hand.\n",
|
|
130
131
|
"en/mcp/mcp-config.md": "---\ntitle: MCP Configuration\ndescription: MCP server configuration, validation, and management for the coding agent runtime.\nsidebar:\n order: 1\n label: Configuration\n---\n\n# MCP configuration in OMP\n\nThis guide explains how to add, edit, and validate MCP servers for the OMP coding agent.\n\nSource of truth in code:\n\n- Runtime config types: `packages/coding-agent/src/mcp/types.ts`\n- Config writer: `packages/coding-agent/src/mcp/config-writer.ts`\n- Loader + validation: `packages/coding-agent/src/mcp/config.ts`\n- Standalone `mcp.json` discovery: `packages/coding-agent/src/discovery/mcp-json.ts`\n- Schema: `packages/coding-agent/src/config/mcp-schema.json`\n\n## Preferred config locations\n\nOMP can discover MCP servers from multiple tools (`.claude/`, `.cursor/`, `.vscode/`, `opencode.json`, and more), but for OMP-native configuration you should usually use one of these files:\n\n- Project: `.xcsh/mcp.json`\n- User: `~/.xcsh/mcp.json`\n\nOMP also accepts fallback standalone files in the project root:\n\n- `mcp.json`\n- `.mcp.json`\n\nUse `.xcsh/mcp.json` when you want OMP to own the configuration. Use root `mcp.json` / `.mcp.json` only when you want a portable fallback file that other MCP clients may also read.\n\n## Add a schema reference\n\nAdd this line at the top of the file for editor autocomplete and validation:\n\n```json\n{\n \"$schema\": \"https://raw.githubusercontent.com/f5-sales-demo/xcsh/main/packages/coding-agent/src/config/mcp-schema.json\",\n \"mcpServers\": {}\n}\n```\n\nOMP now writes this automatically when `/mcp add`, `/mcp enable`, `/mcp disable`, `/mcp reauth`, or other config-writing flows create or update an OMP-managed MCP file.\n\n## File shape\n\nOMP supports this top-level structure:\n\n```json\n{\n \"$schema\": \"https://raw.githubusercontent.com/f5-sales-demo/xcsh/main/packages/coding-agent/src/config/mcp-schema.json\",\n \"mcpServers\": {\n \"server-name\": {\n \"type\": \"stdio\",\n \"command\": \"npx\",\n \"args\": [\"-y\", \"some-mcp-server\"]\n }\n },\n \"disabledServers\": [\"server-name\"]\n}\n```\n\nTop-level keys:\n\n- `$schema` — optional JSON Schema URL for tooling\n- `mcpServers` — map of server name to server config\n- `disabledServers` — user-level denylist used to turn off discovered servers by name\n\nServer names must match `^[a-zA-Z0-9_.-]{1,100}$`.\n\n## Supported server fields\n\nShared fields for every transport:\n\n- `enabled?: boolean` — skip this server when `false`\n- `timeout?: number` — connection timeout in milliseconds\n- `auth?: { ... }` — auth metadata used by OMP for OAuth/API-key flows\n- `oauth?: { ... }` — explicit OAuth client settings used during auth/reauth\n\n### `stdio` transport\n\n`stdio` is the default when `type` is omitted.\n\nRequired:\n\n- `command: string`\n\nOptional:\n\n- `type?: \"stdio\"`\n- `args?: string[]`\n- `env?: Record<string, string>`\n- `cwd?: string`\n\nExample:\n\n```json\n{\n \"$schema\": \"https://raw.githubusercontent.com/f5-sales-demo/xcsh/main/packages/coding-agent/src/config/mcp-schema.json\",\n \"mcpServers\": {\n \"filesystem\": {\n \"command\": \"npx\",\n \"args\": [\n \"-y\",\n \"@modelcontextprotocol/server-filesystem\",\n \"/Users/alice/projects\",\n \"/Users/alice/Documents\"\n ]\n }\n }\n}\n```\n\nThis follows the official Filesystem MCP server package (`@modelcontextprotocol/server-filesystem`).\n\n### `http` transport\n\nRequired:\n\n- `type: \"http\"`\n- `url: string`\n\nOptional:\n\n- `headers?: Record<string, string>`\n\nExample:\n\n```json\n{\n \"$schema\": \"https://raw.githubusercontent.com/f5-sales-demo/xcsh/main/packages/coding-agent/src/config/mcp-schema.json\",\n \"mcpServers\": {\n \"github\": {\n \"type\": \"http\",\n \"url\": \"https://api.githubcopilot.com/mcp/\"\n }\n }\n}\n```\n\nThis matches GitHub's hosted GitHub MCP server endpoint.\n\n### `sse` transport\n\nRequired:\n\n- `type: \"sse\"`\n- `url: string`\n\nOptional:\n\n- `headers?: Record<string, string>`\n\nExample:\n\n```json\n{\n \"$schema\": \"https://raw.githubusercontent.com/f5-sales-demo/xcsh/main/packages/coding-agent/src/config/mcp-schema.json\",\n \"mcpServers\": {\n \"legacy-remote\": {\n \"type\": \"sse\",\n \"url\": \"https://example.com/mcp/sse\"\n }\n }\n}\n```\n\n`sse` is still supported for compatibility, but the MCP spec now prefers Streamable HTTP (`type: \"http\"`) for new servers.\n\n## Auth fields\n\nOMP understands two auth-related objects.\n\n### `auth`\n\n```json\n{\n \"type\": \"oauth\" | \"apikey\",\n \"credentialId\": \"optional-stored-credential-id\",\n \"tokenUrl\": \"optional-token-endpoint\",\n \"clientId\": \"optional-client-id\",\n \"clientSecret\": \"optional-client-secret\"\n}\n```\n\nUse this when OMP should remember how to rehydrate credentials for a server.\n\n### `oauth`\n\n```json\n{\n \"clientId\": \"...\",\n \"clientSecret\": \"...\",\n \"redirectUri\": \"...\",\n \"callbackPort\": 3334,\n \"callbackPath\": \"/oauth/callback\"\n}\n```\n\nUse this when the MCP server requires explicit OAuth client settings.\n\nSlack is the clearest current example. Slack's MCP server is hosted at `https://mcp.slack.com/mcp`, uses Streamable HTTP, and requires confidential OAuth with your Slack app's client credentials.\n\nExample:\n\n```json\n{\n \"$schema\": \"https://raw.githubusercontent.com/f5-sales-demo/xcsh/main/packages/coding-agent/src/config/mcp-schema.json\",\n \"mcpServers\": {\n \"slack\": {\n \"type\": \"http\",\n \"url\": \"https://mcp.slack.com/mcp\",\n \"oauth\": {\n \"clientId\": \"YOUR_SLACK_CLIENT_ID\",\n \"clientSecret\": \"YOUR_SLACK_CLIENT_SECRET\"\n },\n \"auth\": {\n \"type\": \"oauth\",\n \"tokenUrl\": \"https://slack.com/api/oauth.v2.user.access\",\n \"clientId\": \"YOUR_SLACK_CLIENT_ID\",\n \"clientSecret\": \"YOUR_SLACK_CLIENT_SECRET\"\n }\n }\n }\n}\n```\n\nRelevant Slack endpoints from Slack's docs:\n\n- MCP endpoint: `https://mcp.slack.com/mcp`\n- Authorization endpoint: `https://slack.com/oauth/v2_user/authorize`\n- Token endpoint: `https://slack.com/api/oauth.v2.user.access`\n\n## Common copy-paste examples\n\n### Filesystem server via stdio\n\n```json\n{\n \"$schema\": \"https://raw.githubusercontent.com/f5-sales-demo/xcsh/main/packages/coding-agent/src/config/mcp-schema.json\",\n \"mcpServers\": {\n \"filesystem\": {\n \"command\": \"npx\",\n \"args\": [\n \"-y\",\n \"@modelcontextprotocol/server-filesystem\",\n \"/absolute/path/one\",\n \"/absolute/path/two\"\n ]\n }\n }\n}\n```\n\n### GitHub hosted server via HTTP\n\n```json\n{\n \"$schema\": \"https://raw.githubusercontent.com/f5-sales-demo/xcsh/main/packages/coding-agent/src/config/mcp-schema.json\",\n \"mcpServers\": {\n \"github\": {\n \"type\": \"http\",\n \"url\": \"https://api.githubcopilot.com/mcp/\"\n }\n }\n}\n```\n\n### GitHub local server via Docker\n\n```json\n{\n \"$schema\": \"https://raw.githubusercontent.com/f5-sales-demo/xcsh/main/packages/coding-agent/src/config/mcp-schema.json\",\n \"mcpServers\": {\n \"github\": {\n \"command\": \"docker\",\n \"args\": [\n \"run\",\n \"-i\",\n \"--rm\",\n \"-e\",\n \"GITHUB_PERSONAL_ACCESS_TOKEN\",\n \"ghcr.io/github/github-mcp-server\"\n ],\n \"env\": {\n \"GITHUB_PERSONAL_ACCESS_TOKEN\": \"GITHUB_PERSONAL_ACCESS_TOKEN\"\n }\n }\n }\n}\n```\n\nThis matches GitHub's official local Docker image `ghcr.io/github/github-mcp-server`.\n\n### Slack hosted server via OAuth\n\n```json\n{\n \"$schema\": \"https://raw.githubusercontent.com/f5-sales-demo/xcsh/main/packages/coding-agent/src/config/mcp-schema.json\",\n \"mcpServers\": {\n \"slack\": {\n \"type\": \"http\",\n \"url\": \"https://mcp.slack.com/mcp\",\n \"oauth\": {\n \"clientId\": \"YOUR_SLACK_CLIENT_ID\",\n \"clientSecret\": \"YOUR_SLACK_CLIENT_SECRET\"\n },\n \"auth\": {\n \"type\": \"oauth\",\n \"tokenUrl\": \"https://slack.com/api/oauth.v2.user.access\",\n \"clientId\": \"YOUR_SLACK_CLIENT_ID\",\n \"clientSecret\": \"YOUR_SLACK_CLIENT_SECRET\"\n }\n }\n }\n}\n```\n\n## Secrets and variable resolution\n\nThis is the part that usually trips people up.\n\n### In `.xcsh/mcp.json` and `~/.xcsh/mcp.json`\n\nBefore OMP launches a server or makes an HTTP request, it resolves `env` and `headers` values like this:\n\n1. If a value starts with `!`, OMP runs it as a shell command and uses trimmed stdout.\n2. Otherwise OMP first checks whether the value matches an environment variable name.\n3. If that environment variable is not set, OMP uses the string literally.\n\nExamples:\n\n```json\n{\n \"env\": {\n \"GITHUB_PERSONAL_ACCESS_TOKEN\": \"GITHUB_PERSONAL_ACCESS_TOKEN\"\n },\n \"headers\": {\n \"X-MCP-Insiders\": \"true\"\n }\n}\n```\n\nThat means this is valid and convenient for local secrets:\n\n- `\"GITHUB_PERSONAL_ACCESS_TOKEN\": \"GITHUB_PERSONAL_ACCESS_TOKEN\"` → copy from the current shell environment\n- `\"Authorization\": \"Bearer hardcoded-token\"` → use the literal value\n- `\"Authorization\": \"!printf 'Bearer %s' \\\"$GITHUB_TOKEN\\\"\"` → build the header from a command\n\n### In root `mcp.json` and `.mcp.json`\n\nThe standalone fallback loader also expands `${VAR}` and `${VAR:-default}` inside strings during discovery.\n\nExample:\n\n```json\n{\n \"mcpServers\": {\n \"github\": {\n \"type\": \"http\",\n \"url\": \"https://api.githubcopilot.com/mcp/\",\n \"headers\": {\n \"Authorization\": \"Bearer ${GITHUB_TOKEN}\"\n }\n }\n }\n}\n```\n\nIf you want the least surprising OMP behavior, prefer `.xcsh/mcp.json` and use explicit env/header values.\n\n## `disabledServers`\n\n`disabledServers` is mainly useful in the user config file (`~/.xcsh/mcp.json`) when a server is discovered from some other source and you want OMP to ignore it without editing that other tool's config.\n\nExample:\n\n```json\n{\n \"$schema\": \"https://raw.githubusercontent.com/f5-sales-demo/xcsh/main/packages/coding-agent/src/config/mcp-schema.json\",\n \"disabledServers\": [\"github\", \"slack\"]\n}\n```\n\n## `/mcp add` vs editing JSON directly\n\nUse `/mcp add` when you want guided setup.\n\nUse direct JSON editing when:\n\n- you need a transport or auth option the wizard does not prompt for yet\n- you want to paste a server definition from another MCP client\n- you want schema-backed validation in your editor\n\nAfter editing, use:\n\n- `/mcp reload` to rediscover and reconnect servers in the current session\n- `/mcp list` to see which config file a server came from\n- `/mcp test <name>` to test a single server\n\n## Validation rules OMP enforces\n\nFrom `validateServerConfig()` in `packages/coding-agent/src/mcp/config.ts`:\n\n- `stdio` requires `command`\n- `http` and `sse` require `url`\n- a server cannot set both `command` and `url`\n- unknown `type` values are rejected\n\nPractical implications:\n\n- Omitting `type` means `stdio`\n- If you paste a remote server config and forget `\"type\": \"http\"`, OMP will treat it as `stdio` and complain that `command` is missing\n- `sse` remains valid for compatibility, but new hosted servers should usually be configured as `http`\n\n## Discovery and precedence\n\nOMP does not merge duplicate server definitions across files. Discovery providers are prioritized, and the higher-priority definition wins.\n\nIn practice:\n\n- prefer `.xcsh/mcp.json` or `~/.xcsh/mcp.json` when you want an OMP-specific override\n- keep server names unique across tools when possible\n- use `disabledServers` in the user config when a third-party config keeps reintroducing a server you do not want\n\n## Troubleshooting\n\n### `Server \"name\": stdio server requires \"command\" field`\n\nYou probably omitted `type: \"http\"` on a remote server.\n\n### `Server \"name\": both \"command\" and \"url\" are set`\n\nPick one transport. OMP treats `command` as stdio and `url` as http/sse.\n\n### `/mcp add` worked but the server still does not connect\n\nThe JSON is valid, but the server may still be unreachable. Use `/mcp test <name>` and check whether:\n\n- the binary or Docker image exists\n- required environment variables are set\n- the remote URL is reachable\n- the OAuth or API token is valid\n\n### The server exists in another tool's config but not in OMP\n\nRun `/mcp list`. OMP discovers many third-party MCP files, but project-level loading can also be disabled via the `mcp.enableProjectConfig` setting.\n\n## References\n\n- MCP transport spec: <https://modelcontextprotocol.io/specification/2025-03-26/basic/transports>\n- Filesystem server package: <https://www.npmjs.com/package/@modelcontextprotocol/server-filesystem>\n- GitHub MCP server: <https://github.com/github/github-mcp-server>\n- Slack MCP server docs: <https://docs.slack.dev/ai/slack-mcp-server/>\n",
|
|
131
132
|
"en/mcp/mcp-protocol-transports.md": "---\ntitle: MCP Protocol and Transport Internals\ndescription: MCP protocol implementation with stdio, SSE, and streamable HTTP transport layers.\nsidebar:\n order: 2\n label: Protocol & transports\n---\n\n# MCP Protocol and Transport Internals\n\nThis document describes how coding-agent implements MCP JSON-RPC messaging and how protocol concerns are split from transport concerns.\n\n## Scope\n\nCovers:\n\n- JSON-RPC request/response and notification flow\n- Request correlation and lifecycle for stdio and HTTP/SSE transports\n- Timeout and cancellation behavior\n- Error propagation and malformed payload handling\n- Transport selection boundaries (`stdio` vs `http`/`sse`)\n- Which reconnect/retry responsibilities are transport-level vs manager-level\n\nDoes not cover extension authoring UX or command UI.\n\n## Implementation files\n\n- [`src/mcp/types.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/mcp/types.ts)\n- [`src/mcp/transports/stdio.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/mcp/transports/stdio.ts)\n- [`src/mcp/transports/http.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/mcp/transports/http.ts)\n- [`src/mcp/transports/index.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/mcp/transports/index.ts)\n- [`src/mcp/json-rpc.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/mcp/json-rpc.ts)\n- [`src/mcp/client.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/mcp/client.ts)\n- [`src/mcp/manager.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/mcp/manager.ts)\n\n## Layer boundaries\n\n### Protocol layer (JSON-RPC + MCP methods)\n\n- Message shapes are defined in `types.ts` (`JsonRpcRequest`, `JsonRpcNotification`, `JsonRpcResponse`, `JsonRpcMessage`).\n- MCP client logic (`client.ts`) decides method order and session handshake:\n 1. `initialize` request\n 2. `notifications/initialized` notification\n 3. method calls like `tools/list`, `tools/call`\n\n### Transport layer (`MCPTransport`)\n\n`MCPTransport` abstracts delivery and lifecycle:\n\n- `request(method, params, options?) -> Promise<T>`\n- `notify(method, params?) -> Promise<void>`\n- `close()`\n- `connected`\n- optional callbacks: `onClose`, `onError`, `onNotification`\n\nTransport implementations own framing and I/O details:\n\n- `StdioTransport`: newline-delimited JSON over subprocess stdio\n- `HttpTransport`: JSON-RPC over HTTP POST, with optional SSE responses/listening\n\n### Important current caveat\n\nTransport callbacks (`onClose`, `onError`, `onNotification`) are implemented, but current `MCPClient`/`MCPManager` flows do not wire reconnection logic to these callbacks. Notifications are only consumed if caller registers handlers.\n\n## Transport selection\n\n`client.ts:createTransport()` chooses transport from config:\n\n- `type` omitted or `\"stdio\"` -> `createStdioTransport`\n- `\"http\"` or `\"sse\"` -> `createHttpTransport`\n\n`\"sse\"` is treated as an HTTP transport variant (same class), not a separate transport implementation.\n\n## JSON-RPC message flow and correlation\n\n## Request IDs\n\nEach transport generates per-request IDs (`Math.random` + timestamp string). IDs are transport-local correlation tokens.\n\n## Stdio correlation path\n\n- Outbound request is serialized as one JSON object + `\\n`.\n- `#pendingRequests: Map<id, {resolve,reject}>` stores in-flight requests.\n- Read loop parses JSONL from stdout and calls `#handleMessage`.\n- If inbound message has matching `id`, request resolves/rejects.\n- If inbound message has `method` and no `id`, treated as notification and sent to `onNotification`.\n\nUnknown IDs are ignored (no rejection, no error callback).\n\n## HTTP correlation path\n\n- Outbound request is HTTP `POST` with JSON body and generated `id`.\n- Non-SSE response path: parse one JSON-RPC response and return `result`/throw on `error`.\n- SSE response path (`Content-Type: text/event-stream`): stream events, return first message whose `id` matches expected request ID and has `result` or `error`.\n- SSE messages with `method` and no `id` are treated as notifications.\n\nIf SSE stream ends before matching response, request fails with `No response received for request ID ...`.\n\n## Notifications\n\nClient emits JSON-RPC notifications via `transport.notify(...)`.\n\n- Stdio: writes notification frame to stdin (`jsonrpc`, `method`, optional `params`) plus newline.\n- HTTP: sends POST body without `id`; success accepts `2xx` or `202 Accepted`.\n\nServer-initiated notifications are only surfaced through transport `onNotification`; there is no default global subscriber in manager/client.\n\n## Stdio transport internals\n\n## Lifecycle and state transitions\n\n- Initial: `connected=false`, `process=null`, pending map empty\n- `connect()`:\n - spawn subprocess with configured command/args/env/cwd\n - mark connected\n - start stdout read loop (`readJsonl`)\n - start stderr loop (read/discard; currently silent)\n- `close()`:\n - mark disconnected\n - reject all pending requests (`Transport closed`)\n - kill subprocess\n - await read loop shutdown\n - emit `onClose`\n\nIf read loop exits unexpectedly, `finally` triggers `#handleClose()` which performs the same pending-request rejection and close callback.\n\n## Timeout and cancellation\n\nPer request:\n\n- timeout defaults to `config.timeout ?? 30000`\n- optional `AbortSignal` from caller\n- abort and timeout both reject the pending promise and clean map entry\n\nCancellation is local only: transport does not send protocol-level cancellation notification to the server.\n\n## Malformed payload handling\n\nIn read loop:\n\n- each parsed JSONL line is passed to `#handleMessage` in `try/catch`\n- malformed/invalid message handling exceptions are dropped (`Skip malformed lines` comment)\n- loop continues, so one bad message does not kill the connection\n\nIf the underlying stream parser throws, `onError` is invoked (when still connected), then connection closes.\n\n## Disconnect/failure behavior\n\nWhen process exits or stream closes:\n\n- all in-flight requests are rejected with `Transport closed`\n- no automatic restart or reconnect\n- higher layers must reconnect by creating a new transport\n\n## Backpressure/streaming notes\n\n- Outbound writes use `stdin.write()` + `flush()` without awaiting drain semantics.\n- There is no explicit queue or high-watermark management in transport.\n- Inbound processing is stream-driven (`for await` over `readJsonl`), one parsed message at a time.\n\n## HTTP/SSE transport internals\n\n## Lifecycle and connection semantics\n\nHTTP transport has logical connection state, but request path is stateless per HTTP call:\n\n- `connect()` sets `connected=true` (no socket/session handshake)\n- optional server session tracking via `Mcp-Session-Id` header\n- `close()` optionally sends `DELETE` with `Mcp-Session-Id`, aborts SSE listener, emits `onClose`\n\nSo `connected` means \"transport usable\", not \"persistent stream established\".\n\n## Session header behavior\n\n- On POST response, if `Mcp-Session-Id` header is present, transport stores it.\n- Subsequent requests/notifications include `Mcp-Session-Id`.\n- `close()` tries to terminate server session with HTTP DELETE; termination failures are ignored.\n\n## Timeout and cancellation\n\nFor both `request()` and `notify()`:\n\n- timeout uses `AbortController` (`config.timeout ?? 30000`)\n- external signal, if provided, is merged via `AbortSignal.any([...])`\n- AbortError handling distinguishes caller abort vs timeout\n\nErrors thrown:\n\n- timeout: `Request timeout after ...ms` (or `SSE response timeout ...`, `Notify timeout ...`)\n- caller abort: original AbortError is rethrown when external signal is already aborted\n\n## HTTP error propagation\n\nOn non-OK response:\n\n- response text is included in thrown error (`HTTP <status>: <text>`)\n- if present, auth hints from `WWW-Authenticate` and `Mcp-Auth-Server` are appended\n\nOn JSON-RPC error object:\n\n- throws `MCP error <code>: <message>`\n\nMalformed JSON body (`response.json()` failure) propagates as parse exception.\n\n## SSE behavior and modes\n\nTwo SSE paths exist:\n\n1. **Per-request SSE response** (`#parseSSEResponse`)\n - used when POST response content type is `text/event-stream`\n - consumes stream until matching response id found\n - can process interleaved notifications during same stream\n\n2. **Background SSE listener** (`startSSEListener()`)\n - optional GET listener for server-initiated notifications\n - currently not automatically started by MCP manager/client\n - if GET returns `405`, listener silently disables itself (server does not support this mode)\n\n## Malformed payload and disconnect handling\n\nSSE JSON parsing errors bubble out of `readSseJson` and reject request/listener.\n\n- Request SSE parse errors reject the active request.\n- Background listener errors trigger `onError` (except AbortError).\n- No auto-reconnect for background listener.\n\n## `json-rpc.ts` utility vs transport abstraction\n\n`src/mcp/json-rpc.ts` provides `callMCP()` and `parseSSE()` helpers for direct HTTP MCP calls (used by Exa integration), not the `MCPTransport` abstraction used by `MCPClient`/`MCPManager`.\n\nNotable differences from `HttpTransport`:\n\n- parses entire response text first, then extracts first `data:` line (`parseSSE`), with JSON fallback\n- no request timeout management, no abort API, no session-id handling, no transport lifecycle\n- returns raw JSON-RPC envelope object\n\nThis path is lightweight but less robust than full transport implementation.\n\n## Retry/reconnect responsibilities\n\n## Transport-level\n\nCurrent transport implementations do **not**:\n\n- retry failed requests\n- reconnect after stdio process exit\n- reconnect SSE listeners\n- resend in-flight requests after disconnect\n\nThey fail fast and propagate errors.\n\n## Manager/client-level\n\n`MCPManager` handles discovery/initial connection orchestration and can reconnect only by running connect flows again (`connectToServer`/`discoverAndConnect` paths). It does not auto-heal an already connected transport on runtime failure callbacks.\n\n`MCPManager` does have startup fallback behavior for slow servers (deferred tools from cache), but that is tool availability fallback, not transport retry.\n\n## Failure scenarios summary\n\n- **Malformed stdio message line**: dropped; stream continues.\n- **Stdio stream/process ends**: transport closes; pending requests rejected as `Transport closed`.\n- **HTTP non-2xx**: request/notify throws HTTP error.\n- **Invalid JSON response**: parse exception propagated.\n- **SSE ends without matching id**: request fails with `No response received for request ID ...`.\n- **Timeout**: transport-specific timeout error.\n- **Caller abort**: AbortError/reason propagated from caller signal.\n\n## Practical boundary rule\n\nIf the concern is message shape, id correlation, or MCP method ordering, it belongs to protocol/client logic.\n\nIf the concern is framing (JSONL vs HTTP/SSE), stream parsing, fetch/spawn lifecycle, timeout clocks, or connection teardown, it belongs to transport implementation.\n",
|
|
132
133
|
"en/mcp/mcp-runtime-lifecycle.md": "---\ntitle: MCP Runtime Lifecycle\ndescription: MCP server process lifecycle from initialization through tool registration, health monitoring, and shutdown.\nsidebar:\n order: 3\n label: Runtime lifecycle\n---\n\n# MCP runtime lifecycle\n\nThis document describes how MCP servers are discovered, connected, exposed as tools, refreshed, and torn down in the coding-agent runtime.\n\n## Lifecycle at a glance\n\n1. **SDK startup** calls `discoverAndLoadMCPTools()` (unless MCP is disabled).\n2. **Discovery** (`loadAllMCPConfigs`) resolves MCP server configs from capability sources, filters disabled/project/Exa entries, and preserves source metadata.\n3. **Manager connect phase** (`MCPManager.connectServers`) starts per-server connect + `tools/list` in parallel.\n4. **Fast startup gate** waits up to 250ms, then may return:\n - fully loaded `MCPTool`s,\n - failures per server,\n - or cached `DeferredMCPTool`s for still-pending servers.\n5. **SDK wiring** merges MCP tools into runtime tool registry for the session.\n6. **Live session** can refresh MCP tools via `/mcp` flows (`disconnectAll` + rediscover + `session.refreshMCPTools`).\n7. **Teardown** happens when callers invoke `disconnectServer`/`disconnectAll`; manager also clears MCP tool registrations for disconnected servers.\n\n## Discovery and load phase\n\n### Entry path from SDK\n\n`createAgentSession()` in `src/sdk.ts` performs MCP startup when `enableMCP` is true (default):\n\n- calls `discoverAndLoadMCPTools(cwd, { ... })`,\n- passes `authStorage`, cache storage, and `mcp.enableProjectConfig` setting,\n- always sets `filterExa: true`,\n- logs per-server load/connect errors,\n- stores returned manager in `toolSession.mcpManager` and session result.\n\nIf `enableMCP` is false, MCP discovery is skipped entirely.\n\n### Config discovery and filtering\n\n`loadAllMCPConfigs()` (`src/mcp/config.ts`) loads canonical MCP server items through capability discovery, then converts to legacy `MCPServerConfig`.\n\nFiltering behavior:\n\n- `enableProjectConfig: false` removes project-level entries (`_source.level === \"project\"`).\n- `enabled: false` servers are skipped before connect attempts.\n- Exa servers are filtered out by default and API keys are extracted for native Exa tool integration.\n\nResult includes both `configs` and `sources` (metadata used later for provider labeling).\n\n### Discovery-level failure behavior\n\n`discoverAndLoadMCPTools()` distinguishes two failure classes:\n\n- **Discovery hard failure** (exception from `manager.discoverAndConnect`, typically from config discovery): returns an empty tool set and one synthetic error `{ path: \".mcp.json\", error }`.\n- **Per-server runtime/connect failure**: manager returns partial success with `errors` map; other servers continue.\n\nSo startup does not fail the whole agent session when individual MCP servers fail.\n\n## Manager state model\n\n`MCPManager` tracks runtime lifecycle with separate registries:\n\n- `#connections: Map<string, MCPServerConnection>` — fully connected servers.\n- `#pendingConnections: Map<string, Promise<MCPServerConnection>>` — handshake in progress.\n- `#pendingToolLoads: Map<string, Promise<{ connection, serverTools }>>` — connected but tools still loading.\n- `#tools: CustomTool[]` — current MCP tool view exposed to callers.\n- `#sources: Map<string, SourceMeta>` — provider/source metadata even before connect completes.\n\n`getConnectionStatus(name)` derives status from these maps:\n\n- `connected` if in `#connections`,\n- `connecting` if pending connect or pending tool load,\n- `disconnected` otherwise.\n\n## Connection establishment and startup timing\n\n## Per-server connect pipeline\n\nFor each discovered server in `connectServers()`:\n\n1. store/update source metadata,\n2. skip if already connected/pending,\n3. validate transport fields (`validateServerConfig`),\n4. resolve auth/shell substitutions (`#resolveAuthConfig`),\n5. call `connectToServer(name, resolvedConfig)`,\n6. call `listTools(connection)`,\n7. cache tool definitions (`MCPToolCache.set`) best-effort.\n\n`connectToServer()` behavior (`src/mcp/client.ts`):\n\n- creates stdio or HTTP/SSE transport,\n- performs MCP `initialize` + `notifications/initialized`,\n- uses timeout (`config.timeout` or 30s default),\n- closes transport on init failure.\n\n### Fast startup gate + deferred fallback\n\n`connectServers()` waits on a race between:\n\n- all connect/tool-load tasks settled, and\n- `STARTUP_TIMEOUT_MS = 250`.\n\nAfter 250ms:\n\n- fulfilled tasks become live `MCPTool`s,\n- rejected tasks produce per-server errors,\n- still-pending tasks:\n - use cached tool definitions if available (`MCPToolCache.get`) to create `DeferredMCPTool`s,\n - otherwise block until those pending tasks settle.\n\nThis is a hybrid startup model: fast return when cache is available, correctness wait when cache is not.\n\n### Background completion behavior\n\nEach pending `toolsPromise` also has a background continuation that eventually:\n\n- replaces that server’s tool slice in manager state via `#replaceServerTools`,\n- writes cache,\n- logs late failures only after startup (`allowBackgroundLogging`).\n\n## Tool exposure and live-session availability\n\n### Startup registration\n\n`discoverAndLoadMCPTools()` converts manager tools into `LoadedCustomTool[]` and decorates paths (`mcp:<server> via <providerName>` when known).\n\n`createAgentSession()` then pushes these tools into `customTools`, which are wrapped and added to the runtime tool registry with names like `mcp_<server>_<tool>`.\n\n### Tool calls\n\n- `MCPTool` calls tools through an already connected `MCPServerConnection`.\n- `DeferredMCPTool` waits for `waitForConnection(server)` before calling; this allows cached tools to exist before connection is ready.\n\nBoth return structured tool output and convert transport/tool errors into `MCP error: ...` tool content (abort remains abort).\n\n## Refresh/reload paths (startup vs live reload)\n\n### Initial startup path\n\n- one-time discovery/load in `sdk.ts`,\n- tools are registered in initial session tool registry.\n\n### Interactive reload path\n\n`/mcp reload` path (`src/modes/controllers/mcp-command-controller.ts`) does:\n\n1. `mcpManager.disconnectAll()`,\n2. `mcpManager.discoverAndConnect()`,\n3. `session.refreshMCPTools(mcpManager.getTools())`.\n\n`session.refreshMCPTools()` (`src/session/agent-session.ts`) removes all `mcp_` tools, re-wraps latest MCP tools, and re-activates tool set so MCP changes apply without restarting session.\n\nThere is also a follow-up path for late connections: after waiting for a specific server, if status becomes `connected`, it re-runs `session.refreshMCPTools(...)` so newly available tools are rebound in-session.\n\n## Health, reconnect, and partial failure behavior\n\nCurrent runtime behavior is intentionally minimal:\n\n- **No autonomous health monitor** in manager/client.\n- **No automatic reconnect loop** when a transport drops.\n- Manager does not subscribe to transport `onClose`/`onError`; status is registry-driven.\n- Reconnect is explicit: reload flow or direct `connectServers()` invocation.\n\nOperationally:\n\n- one server failing does not remove tools from healthy servers,\n- connect/list failures are isolated per server,\n- tool cache and background updates are best-effort (warnings/errors logged, no hard stop).\n\n## Teardown semantics\n\n### Server-level teardown\n\n`disconnectServer(name)`:\n\n- removes pending entries/source metadata,\n- closes transport if connected,\n- removes that server’s `mcp_` tools from manager state.\n\n### Global teardown\n\n`disconnectAll()`:\n\n- closes all active transports with `Promise.allSettled`,\n- clears pending maps, sources, connections, and manager tool list.\n\nIn current wiring, explicit teardown is used in MCP command flows (for reload/remove/disable). There is no separate automatic manager disposal hook in the startup path itself; callers are responsible for invoking manager disconnect methods when they need deterministic MCP shutdown.\n\n## Failure modes and guarantees\n\n| Scenario | Behavior | Hard fail vs best-effort |\n| --- | --- | --- |\n| Discovery throws (capability/config load path) | Loader returns empty tools + synthetic `.mcp.json` error | Best-effort session startup |\n| Invalid server config | Server skipped with validation error entry | Best-effort per server |\n| Connect timeout/init failure | Server error recorded; others continue | Best-effort per server |\n| `tools/list` still pending at startup with cache hit | Deferred tools returned immediately | Best-effort fast startup |\n| `tools/list` still pending at startup without cache | Startup waits for pending to settle | Hard wait for correctness |\n| Late background tool-load failure | Logged after startup gate | Best-effort logging |\n| Runtime dropped transport | No automatic reconnect; future calls fail until reconnect/reload | Best-effort recovery via manual action |\n\n## Public API surface\n\n`src/mcp/index.ts` re-exports loader/manager/client APIs for external callers. `src/sdk.ts` exposes `discoverMCPServers()` as a convenience wrapper returning the same loader result shape.\n\n## Implementation files\n\n- [`src/mcp/loader.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/mcp/loader.ts) — loader facade, discovery error normalization, `LoadedCustomTool` conversion.\n- [`src/mcp/manager.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/mcp/manager.ts) — lifecycle state registries, parallel connect/list flow, refresh/disconnect.\n- [`src/mcp/client.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/mcp/client.ts) — transport setup, initialize handshake, list/call/disconnect.\n- [`src/mcp/index.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/mcp/index.ts) — MCP module API exports.\n- [`src/sdk.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/sdk.ts) — startup wiring into session/tool registry.\n- [`src/mcp/config.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/mcp/config.ts) — config discovery/filtering/validation used by manager.\n- [`src/mcp/tool-bridge.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/mcp/tool-bridge.ts) — `MCPTool` and `DeferredMCPTool` runtime behavior.\n- [`src/session/agent-session.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/session/agent-session.ts) — `refreshMCPTools` live rebinding.\n- [`src/modes/controllers/mcp-command-controller.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/modes/controllers/mcp-command-controller.ts) — interactive reload/reconnect flows.\n- [`src/task/executor.ts`](https://github.com/f5-sales-demo/xcsh/blob/main/packages/coding-agent/src/task/executor.ts) — subagent MCP proxying via parent manager connections.\n",
|